2 * Sone - Matchers.java - Copyright © 2013 David Roden
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package net.pterodactylus.sone;
20 import static java.util.regex.Pattern.compile;
22 import java.io.IOException;
23 import java.io.InputStream;
25 import net.pterodactylus.sone.data.Album;
26 import net.pterodactylus.sone.data.Image;
27 import net.pterodactylus.sone.data.Post;
28 import net.pterodactylus.sone.data.PostReply;
30 import com.google.common.base.Objects;
31 import com.google.common.base.Optional;
32 import org.hamcrest.Description;
33 import org.hamcrest.Matcher;
34 import org.hamcrest.TypeSafeDiagnosingMatcher;
35 import org.hamcrest.TypeSafeMatcher;
38 * Matchers used throughout the tests.
40 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
42 public class Matchers {
44 public static Matcher<String> matchesRegex(final String regex) {
45 return new TypeSafeMatcher<String>() {
47 protected boolean matchesSafely(String item) {
48 return compile(regex).matcher(item).matches();
52 public void describeTo(Description description) {
53 description.appendText("matches: ").appendValue(regex);
58 public static Matcher<InputStream> delivers(final byte[] data) {
59 return new TypeSafeMatcher<InputStream>() {
60 byte[] readData = new byte[data.length];
63 protected boolean matchesSafely(InputStream inputStream) {
67 int r = inputStream.read();
69 return offset == data.length;
71 if (offset == data.length) {
74 if (data[offset] != (readData[offset] = (byte) r)) {
79 } catch (IOException ioe1) {
85 public void describeTo(Description description) {
86 description.appendValue(data);
90 protected void describeMismatchSafely(InputStream item,
91 Description mismatchDescription) {
92 mismatchDescription.appendValue(readData);
97 public static class IncompletePostMatcher extends TypeSafeDiagnosingMatcher<Post> {
100 private String sender;
101 private boolean checkRecipient;
102 private String recipient;
106 private IncompletePostMatcher() {
109 public static IncompletePostMatcher matches() {
110 return new IncompletePostMatcher();
113 public IncompletePostMatcher id(String id) {
118 public IncompletePostMatcher sender(String sender) {
119 this.sender = sender;
123 public IncompletePostMatcher recipient(String recipient) {
124 this.checkRecipient = true;
125 this.recipient = recipient;
129 public IncompletePostMatcher time(long time) {
134 public IncompletePostMatcher text(String text) {
140 protected boolean matchesSafely(Post post, Description mismatchDescription) {
141 if ((id != null) && !id.matches(post.getId())) {
142 mismatchDescription.appendText("ID is ").appendValue(post.getId());
145 if ((sender != null) && !sender.matches(post.getSone().getId())) {
146 mismatchDescription.appendText("sender is ").appendValue(post.getSone().getId());
149 if (checkRecipient && !Objects.equal(recipient, post.getRecipientId().orNull())) {
150 mismatchDescription.appendText("recipient is ").appendValue(post.getRecipientId().orNull());
153 if ((time != 0) && (time != post.getTime())) {
154 mismatchDescription.appendText("time is ").appendValue(post.getTime());
157 if ((text != null) && !text.equals(post.getText())) {
158 mismatchDescription.appendText("text is ").appendValue(post.getText());
165 public void describeTo(Description description) {
166 description.appendText("is post");
168 description.appendText(" with ID ").appendValue(id);
170 if (sender != null) {
171 description.appendText(" with sender ").appendValue(sender);
173 if (checkRecipient) {
174 description.appendText(" with recipient ").appendValue(recipient);
177 description.appendText(" with time ").appendValue(time);
180 description.appendText(" with text ").appendValue(text);
187 public static Matcher<Post> isPost(String postId, long time,
188 String text, Optional<String> recipient) {
189 return IncompletePostMatcher.matches().id(postId).time(time).text(text).recipient(recipient.orNull());
192 public static Matcher<Post> isPostWithId(String postId) {
193 return IncompletePostMatcher.matches().id(postId);
196 public static Matcher<PostReply> isPostReply(String postReplyId,
197 String postId, long time, String text) {
198 return new PostReplyMatcher(postReplyId, postId, time, text);
201 public static Matcher<Album> isAlbum(final String albumId,
202 final String parentAlbumId,
203 final String title, final String albumDescription,
204 final String imageId) {
205 return new TypeSafeDiagnosingMatcher<Album>() {
207 protected boolean matchesSafely(Album album,
208 Description mismatchDescription) {
209 if (!album.getId().equals(albumId)) {
210 mismatchDescription.appendText("ID is ")
211 .appendValue(album.getId());
214 if (parentAlbumId == null) {
215 if (album.getParent() != null) {
216 mismatchDescription.appendText("has parent album");
220 if (album.getParent() == null) {
221 mismatchDescription.appendText("has no parent album");
224 if (!album.getParent().getId().equals(parentAlbumId)) {
225 mismatchDescription.appendText("parent album is ")
226 .appendValue(album.getParent().getId());
230 if (!title.equals(album.getTitle())) {
231 mismatchDescription.appendText("has title ")
232 .appendValue(album.getTitle());
235 if (!albumDescription.equals(album.getDescription())) {
236 mismatchDescription.appendText("has description ")
237 .appendValue(album.getDescription());
240 if (imageId == null) {
241 if (album.getAlbumImage() != null) {
242 mismatchDescription.appendText("has album image");
246 if (album.getAlbumImage() == null) {
247 mismatchDescription.appendText("has no album image");
250 if (!album.getAlbumImage().getId().equals(imageId)) {
251 mismatchDescription.appendText("has album image ")
252 .appendValue(album.getAlbumImage().getId());
260 public void describeTo(Description description) {
261 description.appendText("is album ").appendValue(albumId);
262 if (parentAlbumId == null) {
263 description.appendText(", has no parent");
265 description.appendText(", has parent ")
266 .appendValue(parentAlbumId);
268 description.appendText(", has title ").appendValue(title);
269 description.appendText(", has description ")
270 .appendValue(albumDescription);
271 if (imageId == null) {
272 description.appendText(", has no album image");
274 description.appendText(", has album image ")
275 .appendValue(imageId);
281 public static Matcher<Image> isImage(final String id,
282 final long creationTime,
283 final String key, final String title,
284 final String imageDescription,
285 final int width, final int height) {
286 return new TypeSafeDiagnosingMatcher<Image>() {
288 protected boolean matchesSafely(Image image,
289 Description mismatchDescription) {
290 if (!image.getId().equals(id)) {
291 mismatchDescription.appendText("ID is ")
292 .appendValue(image.getId());
295 if (image.getCreationTime() != creationTime) {
296 mismatchDescription.appendText("created at @")
297 .appendValue(image.getCreationTime());
300 if (!image.getKey().equals(key)) {
301 mismatchDescription.appendText("key is ")
302 .appendValue(image.getKey());
305 if (!image.getTitle().equals(title)) {
306 mismatchDescription.appendText("title is ")
307 .appendValue(image.getTitle());
310 if (!image.getDescription().equals(imageDescription)) {
311 mismatchDescription.appendText("description is ")
312 .appendValue(image.getDescription());
315 if (image.getWidth() != width) {
316 mismatchDescription.appendText("width is ")
317 .appendValue(image.getWidth());
320 if (image.getHeight() != height) {
321 mismatchDescription.appendText("height is ")
322 .appendValue(image.getHeight());
329 public void describeTo(Description description) {
330 description.appendText("image with ID ").appendValue(id);
331 description.appendText(", created at @")
332 .appendValue(creationTime);
333 description.appendText(", has key ").appendValue(key);
334 description.appendText(", has title ").appendValue(title);
335 description.appendText(", has description ")
336 .appendValue(imageDescription);
337 description.appendText(", has width ").appendValue(width);
338 description.appendText(", has height ").appendValue(height);
343 private static class PostReplyMatcher
344 extends TypeSafeDiagnosingMatcher<PostReply> {
346 private final String postReplyId;
347 private final String postId;
348 private final long time;
349 private final String text;
351 private PostReplyMatcher(String postReplyId, String postId, long time,
353 this.postReplyId = postReplyId;
354 this.postId = postId;
360 protected boolean matchesSafely(PostReply postReply,
361 Description mismatchDescription) {
362 if (!postReply.getId().equals(postReplyId)) {
363 mismatchDescription.appendText("is post reply ")
364 .appendValue(postReply.getId());
367 if (!postReply.getPostId().equals(postId)) {
368 mismatchDescription.appendText("is reply to ")
369 .appendValue(postReply.getPostId());
372 if (postReply.getTime() != time) {
373 mismatchDescription.appendText("is created at @").appendValue(
374 postReply.getTime());
377 if (!postReply.getText().equals(text)) {
378 mismatchDescription.appendText("says ")
379 .appendValue(postReply.getText());
386 public void describeTo(Description description) {
387 description.appendText("is post reply ").appendValue(postReplyId);
388 description.appendText(", replies to post ").appendValue(postId);
389 description.appendText(", is created at @").appendValue(time);
390 description.appendText(", says ").appendValue(text);