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