Merge branch 'release/0.9-rc1'
[Sone.git] / src / test / java / net / pterodactylus / sone / Matchers.java
1 /*
2  * Sone - Matchers.java - Copyright © 2013 David Roden
3  *
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.
8  *
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.
13  *
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/>.
16  */
17
18 package net.pterodactylus.sone;
19
20 import static java.util.regex.Pattern.compile;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24
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;
29
30 import com.google.common.base.Optional;
31 import org.hamcrest.Description;
32 import org.hamcrest.Matcher;
33 import org.hamcrest.TypeSafeDiagnosingMatcher;
34 import org.hamcrest.TypeSafeMatcher;
35
36 /**
37  * Matchers used throughout the tests.
38  *
39  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
40  */
41 public class Matchers {
42
43         public static Matcher<String> matchesRegex(final String regex) {
44                 return new TypeSafeMatcher<String>() {
45                         @Override
46                         protected boolean matchesSafely(String item) {
47                                 return compile(regex).matcher(item).matches();
48                         }
49
50                         @Override
51                         public void describeTo(Description description) {
52                                 description.appendText("matches: ").appendValue(regex);
53                         }
54                 };
55         }
56
57         public static Matcher<InputStream> delivers(final byte[] data) {
58                 return new TypeSafeMatcher<InputStream>() {
59                         byte[] readData = new byte[data.length];
60
61                         @Override
62                         protected boolean matchesSafely(InputStream inputStream) {
63                                 int offset = 0;
64                                 try {
65                                         while (true) {
66                                                 int r = inputStream.read();
67                                                 if (r == -1) {
68                                                         return offset == data.length;
69                                                 }
70                                                 if (offset == data.length) {
71                                                         return false;
72                                                 }
73                                                 if (data[offset] != (readData[offset] = (byte) r)) {
74                                                         return false;
75                                                 }
76                                                 offset++;
77                                         }
78                                 } catch (IOException ioe1) {
79                                         return false;
80                                 }
81                         }
82
83                         @Override
84                         public void describeTo(Description description) {
85                                 description.appendValue(data);
86                         }
87
88                         @Override
89                         protected void describeMismatchSafely(InputStream item,
90                                         Description mismatchDescription) {
91                                 mismatchDescription.appendValue(readData);
92                         }
93                 };
94         }
95
96         public static Matcher<Post> isPost(String postId, long time,
97                         String text, Optional<String> recipient) {
98                 return new PostMatcher(postId, time, text, recipient);
99         }
100
101         public static Matcher<Post> isPostWithId(String postId) {
102                 return new PostIdMatcher(postId);
103         }
104
105         public static Matcher<PostReply> isPostReply(String postReplyId,
106                         String postId, long time, String text) {
107                 return new PostReplyMatcher(postReplyId, postId, time, text);
108         }
109
110         public static Matcher<Album> isAlbum(final String albumId,
111                         final String parentAlbumId,
112                         final String title, final String albumDescription,
113                         final String imageId) {
114                 return new TypeSafeDiagnosingMatcher<Album>() {
115                         @Override
116                         protected boolean matchesSafely(Album album,
117                                         Description mismatchDescription) {
118                                 if (!album.getId().equals(albumId)) {
119                                         mismatchDescription.appendText("ID is ")
120                                                         .appendValue(album.getId());
121                                         return false;
122                                 }
123                                 if (parentAlbumId == null) {
124                                         if (album.getParent() != null) {
125                                                 mismatchDescription.appendText("has parent album");
126                                                 return false;
127                                         }
128                                 } else {
129                                         if (album.getParent() == null) {
130                                                 mismatchDescription.appendText("has no parent album");
131                                                 return false;
132                                         }
133                                         if (!album.getParent().getId().equals(parentAlbumId)) {
134                                                 mismatchDescription.appendText("parent album is ")
135                                                                 .appendValue(album.getParent().getId());
136                                                 return false;
137                                         }
138                                 }
139                                 if (!title.equals(album.getTitle())) {
140                                         mismatchDescription.appendText("has title ")
141                                                         .appendValue(album.getTitle());
142                                         return false;
143                                 }
144                                 if (!albumDescription.equals(album.getDescription())) {
145                                         mismatchDescription.appendText("has description ")
146                                                         .appendValue(album.getDescription());
147                                         return false;
148                                 }
149                                 if (imageId == null) {
150                                         if (album.getAlbumImage() != null) {
151                                                 mismatchDescription.appendText("has album image");
152                                                 return false;
153                                         }
154                                 } else {
155                                         if (album.getAlbumImage() == null) {
156                                                 mismatchDescription.appendText("has no album image");
157                                                 return false;
158                                         }
159                                         if (!album.getAlbumImage().getId().equals(imageId)) {
160                                                 mismatchDescription.appendText("has album image ")
161                                                                 .appendValue(album.getAlbumImage().getId());
162                                                 return false;
163                                         }
164                                 }
165                                 return true;
166                         }
167
168                         @Override
169                         public void describeTo(Description description) {
170                                 description.appendText("is album ").appendValue(albumId);
171                                 if (parentAlbumId == null) {
172                                         description.appendText(", has no parent");
173                                 } else {
174                                         description.appendText(", has parent ")
175                                                         .appendValue(parentAlbumId);
176                                 }
177                                 description.appendText(", has title ").appendValue(title);
178                                 description.appendText(", has description ")
179                                                 .appendValue(albumDescription);
180                                 if (imageId == null) {
181                                         description.appendText(", has no album image");
182                                 } else {
183                                         description.appendText(", has album image ")
184                                                         .appendValue(imageId);
185                                 }
186                         }
187                 };
188         }
189
190         public static Matcher<Image> isImage(final String id,
191                         final long creationTime,
192                         final String key, final String title,
193                         final String imageDescription,
194                         final int width, final int height) {
195                 return new TypeSafeDiagnosingMatcher<Image>() {
196                         @Override
197                         protected boolean matchesSafely(Image image,
198                                         Description mismatchDescription) {
199                                 if (!image.getId().equals(id)) {
200                                         mismatchDescription.appendText("ID is ")
201                                                         .appendValue(image.getId());
202                                         return false;
203                                 }
204                                 if (image.getCreationTime() != creationTime) {
205                                         mismatchDescription.appendText("created at @")
206                                                         .appendValue(image.getCreationTime());
207                                         return false;
208                                 }
209                                 if (!image.getKey().equals(key)) {
210                                         mismatchDescription.appendText("key is ")
211                                                         .appendValue(image.getKey());
212                                         return false;
213                                 }
214                                 if (!image.getTitle().equals(title)) {
215                                         mismatchDescription.appendText("title is ")
216                                                         .appendValue(image.getTitle());
217                                         return false;
218                                 }
219                                 if (!image.getDescription().equals(imageDescription)) {
220                                         mismatchDescription.appendText("description is ")
221                                                         .appendValue(image.getDescription());
222                                         return false;
223                                 }
224                                 if (image.getWidth() != width) {
225                                         mismatchDescription.appendText("width is ")
226                                                         .appendValue(image.getWidth());
227                                         return false;
228                                 }
229                                 if (image.getHeight() != height) {
230                                         mismatchDescription.appendText("height is ")
231                                                         .appendValue(image.getHeight());
232                                         return false;
233                                 }
234                                 return true;
235                         }
236
237                         @Override
238                         public void describeTo(Description description) {
239                                 description.appendText("image with ID ").appendValue(id);
240                                 description.appendText(", created at @")
241                                                 .appendValue(creationTime);
242                                 description.appendText(", has key ").appendValue(key);
243                                 description.appendText(", has title ").appendValue(title);
244                                 description.appendText(", has description ")
245                                                 .appendValue(imageDescription);
246                                 description.appendText(", has width ").appendValue(width);
247                                 description.appendText(", has height ").appendValue(height);
248                         }
249                 };
250         }
251
252         private static class PostMatcher extends TypeSafeDiagnosingMatcher<Post> {
253
254                 private final String postId;
255                 private final long time;
256                 private final String text;
257                 private final Optional<String> recipient;
258
259                 private PostMatcher(String postId, long time, String text,
260                                 Optional<String> recipient) {
261                         this.postId = postId;
262                         this.time = time;
263                         this.text = text;
264                         this.recipient = recipient;
265                 }
266
267                 @Override
268                 protected boolean matchesSafely(Post post,
269                                 Description mismatchDescription) {
270                         if (!post.getId().equals(postId)) {
271                                 mismatchDescription.appendText("ID is not ")
272                                                 .appendValue(postId);
273                                 return false;
274                         }
275                         if (post.getTime() != time) {
276                                 mismatchDescription.appendText("Time is not @")
277                                                 .appendValue(time);
278                                 return false;
279                         }
280                         if (!post.getText().equals(text)) {
281                                 mismatchDescription.appendText("Text is not ")
282                                                 .appendValue(text);
283                                 return false;
284                         }
285                         if (recipient.isPresent()) {
286                                 if (!post.getRecipientId().isPresent()) {
287                                         mismatchDescription.appendText(
288                                                         "Recipient not present");
289                                         return false;
290                                 }
291                                 if (!post.getRecipientId().get().equals(recipient.get())) {
292                                         mismatchDescription.appendText("Recipient is not ")
293                                                         .appendValue(recipient.get());
294                                         return false;
295                                 }
296                         } else {
297                                 if (post.getRecipientId().isPresent()) {
298                                         mismatchDescription.appendText("Recipient is present");
299                                         return false;
300                                 }
301                         }
302                         return true;
303                 }
304
305                 @Override
306                 public void describeTo(Description description) {
307                         description.appendText("is post with ID ")
308                                         .appendValue(postId);
309                         description.appendText(", created at @").appendValue(time);
310                         description.appendText(", text ").appendValue(text);
311                         if (recipient.isPresent()) {
312                                 description.appendText(", directed at ")
313                                                 .appendValue(recipient.get());
314                         }
315                 }
316
317         }
318
319         private static class PostIdMatcher extends TypeSafeDiagnosingMatcher<Post> {
320
321                 private final String id;
322
323                 private PostIdMatcher(String id) {
324                         this.id = id;
325                 }
326
327                 @Override
328                 protected boolean matchesSafely(Post item,
329                                 Description mismatchDescription) {
330                         if (!item.getId().equals(id)) {
331                                 mismatchDescription.appendText("post has ID ").appendValue(item.getId());
332                                 return false;
333                         }
334                         return true;
335                 }
336
337                 @Override
338                 public void describeTo(Description description) {
339                         description.appendText("post with ID ").appendValue(id);
340                 }
341
342         }
343
344         private static class PostReplyMatcher
345                         extends TypeSafeDiagnosingMatcher<PostReply> {
346
347                 private final String postReplyId;
348                 private final String postId;
349                 private final long time;
350                 private final String text;
351
352                 private PostReplyMatcher(String postReplyId, String postId, long time,
353                                 String text) {
354                         this.postReplyId = postReplyId;
355                         this.postId = postId;
356                         this.time = time;
357                         this.text = text;
358                 }
359
360                 @Override
361                 protected boolean matchesSafely(PostReply postReply,
362                                 Description mismatchDescription) {
363                         if (!postReply.getId().equals(postReplyId)) {
364                                 mismatchDescription.appendText("is post reply ")
365                                                 .appendValue(postReply.getId());
366                                 return false;
367                         }
368                         if (!postReply.getPostId().equals(postId)) {
369                                 mismatchDescription.appendText("is reply to ")
370                                                 .appendValue(postReply.getPostId());
371                                 return false;
372                         }
373                         if (postReply.getTime() != time) {
374                                 mismatchDescription.appendText("is created at @").appendValue(
375                                                 postReply.getTime());
376                                 return false;
377                         }
378                         if (!postReply.getText().equals(text)) {
379                                 mismatchDescription.appendText("says ")
380                                                 .appendValue(postReply.getText());
381                                 return false;
382                         }
383                         return true;
384                 }
385
386                 @Override
387                 public void describeTo(Description description) {
388                         description.appendText("is post reply ").appendValue(postReplyId);
389                         description.appendText(", replies to post ").appendValue(postId);
390                         description.appendText(", is created at @").appendValue(time);
391                         description.appendText(", says ").appendValue(text);
392                 }
393
394         }
395
396 }