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.Post;
27 import net.pterodactylus.sone.data.PostReply;
29 import com.google.common.base.Optional;
30 import org.hamcrest.Description;
31 import org.hamcrest.Matcher;
32 import org.hamcrest.TypeSafeDiagnosingMatcher;
33 import org.hamcrest.TypeSafeMatcher;
36 * Matchers used throughout the tests.
38 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
40 public class Matchers {
42 public static Matcher<String> matchesRegex(final String regex) {
43 return new TypeSafeMatcher<String>() {
45 protected boolean matchesSafely(String item) {
46 return compile(regex).matcher(item).matches();
50 public void describeTo(Description description) {
51 description.appendText("matches: ").appendValue(regex);
56 public static Matcher<InputStream> delivers(final byte[] data) {
57 return new TypeSafeMatcher<InputStream>() {
58 byte[] readData = new byte[data.length];
61 protected boolean matchesSafely(InputStream inputStream) {
65 int r = inputStream.read();
67 return offset == data.length;
69 if (offset == data.length) {
72 if (data[offset] != (readData[offset] = (byte) r)) {
77 } catch (IOException ioe1) {
83 public void describeTo(Description description) {
84 description.appendValue(data);
88 protected void describeMismatchSafely(InputStream item,
89 Description mismatchDescription) {
90 mismatchDescription.appendValue(readData);
95 public static Matcher<Post> isPost(String postId, long time,
96 String text, Optional<String> recipient) {
97 return new PostMatcher(postId, time, text, recipient);
100 public static Matcher<PostReply> isPostReply(String postReplyId,
101 String postId, long time, String text) {
102 return new PostReplyMatcher(postReplyId, postId, time, text);
105 public static Matcher<Album> isAlbum(final String albumId,
106 final String parentAlbumId,
107 final String title, final String albumDescription,
108 final String imageId) {
109 return new TypeSafeDiagnosingMatcher<Album>() {
111 protected boolean matchesSafely(Album album,
112 Description mismatchDescription) {
113 if (!album.getId().equals(albumId)) {
114 mismatchDescription.appendText("ID is ")
115 .appendValue(album.getId());
118 if (parentAlbumId == null) {
119 if (album.getParent() != null) {
120 mismatchDescription.appendText("has parent album");
124 if (album.getParent() == null) {
125 mismatchDescription.appendText("has no parent album");
128 if (!album.getParent().getId().equals(parentAlbumId)) {
129 mismatchDescription.appendText("parent album is ")
130 .appendValue(album.getParent().getId());
134 if (!title.equals(album.getTitle())) {
135 mismatchDescription.appendText("has title ")
136 .appendValue(album.getTitle());
139 if (!albumDescription.equals(album.getDescription())) {
140 mismatchDescription.appendText("has description ")
141 .appendValue(album.getDescription());
144 if (imageId == null) {
145 if (album.getAlbumImage() != null) {
146 mismatchDescription.appendText("has album image");
150 if (album.getAlbumImage() == null) {
151 mismatchDescription.appendText("has no album image");
154 if (!album.getAlbumImage().getId().equals(imageId)) {
155 mismatchDescription.appendText("has album image ")
156 .appendValue(album.getAlbumImage().getId());
164 public void describeTo(Description description) {
165 description.appendText("is album ").appendValue(albumId);
166 if (parentAlbumId == null) {
167 description.appendText(", has no parent");
169 description.appendText(", has parent ")
170 .appendValue(parentAlbumId);
172 description.appendText(", has title ").appendValue(title);
173 description.appendText(", has description ")
174 .appendValue(albumDescription);
175 if (imageId == null) {
176 description.appendText(", has no album image");
178 description.appendText(", has album image ")
179 .appendValue(imageId);
185 private static class PostMatcher extends TypeSafeDiagnosingMatcher<Post> {
187 private final String postId;
188 private final long time;
189 private final String text;
190 private final Optional<String> recipient;
192 private PostMatcher(String postId, long time, String text,
193 Optional<String> recipient) {
194 this.postId = postId;
197 this.recipient = recipient;
201 protected boolean matchesSafely(Post post,
202 Description mismatchDescription) {
203 if (!post.getId().equals(postId)) {
204 mismatchDescription.appendText("ID is not ")
205 .appendValue(postId);
208 if (post.getTime() != time) {
209 mismatchDescription.appendText("Time is not @")
213 if (!post.getText().equals(text)) {
214 mismatchDescription.appendText("Text is not ")
218 if (recipient.isPresent()) {
219 if (!post.getRecipientId().isPresent()) {
220 mismatchDescription.appendText(
221 "Recipient not present");
224 if (!post.getRecipientId().get().equals(recipient.get())) {
225 mismatchDescription.appendText("Recipient is not ")
226 .appendValue(recipient.get());
230 if (post.getRecipientId().isPresent()) {
231 mismatchDescription.appendText("Recipient is present");
239 public void describeTo(Description description) {
240 description.appendText("is post with ID ")
241 .appendValue(postId);
242 description.appendText(", created at @").appendValue(time);
243 description.appendText(", text ").appendValue(text);
244 if (recipient.isPresent()) {
245 description.appendText(", directed at ")
246 .appendValue(recipient.get());
252 private static class PostReplyMatcher
253 extends TypeSafeDiagnosingMatcher<PostReply> {
255 private final String postReplyId;
256 private final String postId;
257 private final long time;
258 private final String text;
260 private PostReplyMatcher(String postReplyId, String postId, long time,
262 this.postReplyId = postReplyId;
263 this.postId = postId;
269 protected boolean matchesSafely(PostReply postReply,
270 Description mismatchDescription) {
271 if (!postReply.getId().equals(postReplyId)) {
272 mismatchDescription.appendText("is post reply ")
273 .appendValue(postReply.getId());
276 if (!postReply.getPostId().equals(postId)) {
277 mismatchDescription.appendText("is reply to ")
278 .appendValue(postReply.getPostId());
281 if (postReply.getTime() != time) {
282 mismatchDescription.appendText("is created at @").appendValue(
283 postReply.getTime());
286 if (!postReply.getText().equals(text)) {
287 mismatchDescription.appendText("says ")
288 .appendValue(postReply.getText());
295 public void describeTo(Description description) {
296 description.appendText("is post reply ").appendValue(postReplyId);
297 description.appendText(", replies to post ").appendValue(postId);
298 description.appendText(", is created at @").appendValue(time);
299 description.appendText(", says ").appendValue(text);