+++ /dev/null
-/*
- * Sone - Matchers.java - Copyright © 2013–2016 David Roden
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-package net.pterodactylus.sone;
-
-import static java.util.regex.Pattern.compile;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import net.pterodactylus.sone.data.Album;
-import net.pterodactylus.sone.data.Image;
-import net.pterodactylus.sone.data.Post;
-import net.pterodactylus.sone.data.PostReply;
-
-import com.google.common.base.Optional;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.TypeSafeDiagnosingMatcher;
-import org.hamcrest.TypeSafeMatcher;
-
-/**
- * Matchers used throughout the tests.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class Matchers {
-
- public static Matcher<String> matchesRegex(final String regex) {
- return new TypeSafeMatcher<String>() {
- @Override
- protected boolean matchesSafely(String item) {
- return compile(regex).matcher(item).matches();
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("matches: ").appendValue(regex);
- }
- };
- }
-
- public static Matcher<InputStream> delivers(final byte[] data) {
- return new TypeSafeMatcher<InputStream>() {
- byte[] readData = new byte[data.length];
-
- @Override
- protected boolean matchesSafely(InputStream inputStream) {
- int offset = 0;
- try {
- while (true) {
- int r = inputStream.read();
- if (r == -1) {
- return offset == data.length;
- }
- if (offset == data.length) {
- return false;
- }
- if (data[offset] != (readData[offset] = (byte) r)) {
- return false;
- }
- offset++;
- }
- } catch (IOException ioe1) {
- return false;
- }
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendValue(data);
- }
-
- @Override
- protected void describeMismatchSafely(InputStream item,
- Description mismatchDescription) {
- mismatchDescription.appendValue(readData);
- }
- };
- }
-
- public static Matcher<Post> isPost(String postId, long time,
- String text, Optional<String> recipient) {
- return new PostMatcher(postId, time, text, recipient);
- }
-
- public static Matcher<Post> isPostWithId(String postId) {
- return new PostIdMatcher(postId);
- }
-
- public static Matcher<PostReply> isPostReply(String postReplyId,
- String postId, long time, String text) {
- return new PostReplyMatcher(postReplyId, postId, time, text);
- }
-
- public static Matcher<Album> isAlbum(final String albumId,
- final String parentAlbumId,
- final String title, final String albumDescription) {
- return new TypeSafeDiagnosingMatcher<Album>() {
- @Override
- protected boolean matchesSafely(Album album,
- Description mismatchDescription) {
- if (!album.getId().equals(albumId)) {
- mismatchDescription.appendText("ID is ")
- .appendValue(album.getId());
- return false;
- }
- if (parentAlbumId == null) {
- if (album.getParent() != null) {
- mismatchDescription.appendText("has parent album");
- return false;
- }
- } else {
- if (album.getParent() == null) {
- mismatchDescription.appendText("has no parent album");
- return false;
- }
- if (!album.getParent().getId().equals(parentAlbumId)) {
- mismatchDescription.appendText("parent album is ")
- .appendValue(album.getParent().getId());
- return false;
- }
- }
- if (!title.equals(album.getTitle())) {
- mismatchDescription.appendText("has title ")
- .appendValue(album.getTitle());
- return false;
- }
- if (!albumDescription.equals(album.getDescription())) {
- mismatchDescription.appendText("has description ")
- .appendValue(album.getDescription());
- return false;
- }
- return true;
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("is album ").appendValue(albumId);
- if (parentAlbumId == null) {
- description.appendText(", has no parent");
- } else {
- description.appendText(", has parent ")
- .appendValue(parentAlbumId);
- }
- description.appendText(", has title ").appendValue(title);
- description.appendText(", has description ")
- .appendValue(albumDescription);
- }
- };
- }
-
- public static Matcher<Image> isImage(final String id,
- final long creationTime,
- final String key, final String title,
- final String imageDescription,
- final int width, final int height) {
- return new TypeSafeDiagnosingMatcher<Image>() {
- @Override
- protected boolean matchesSafely(Image image,
- Description mismatchDescription) {
- if (!image.getId().equals(id)) {
- mismatchDescription.appendText("ID is ")
- .appendValue(image.getId());
- return false;
- }
- if (image.getCreationTime() != creationTime) {
- mismatchDescription.appendText("created at @")
- .appendValue(image.getCreationTime());
- return false;
- }
- if (!image.getKey().equals(key)) {
- mismatchDescription.appendText("key is ")
- .appendValue(image.getKey());
- return false;
- }
- if (!image.getTitle().equals(title)) {
- mismatchDescription.appendText("title is ")
- .appendValue(image.getTitle());
- return false;
- }
- if (!image.getDescription().equals(imageDescription)) {
- mismatchDescription.appendText("description is ")
- .appendValue(image.getDescription());
- return false;
- }
- if (image.getWidth() != width) {
- mismatchDescription.appendText("width is ")
- .appendValue(image.getWidth());
- return false;
- }
- if (image.getHeight() != height) {
- mismatchDescription.appendText("height is ")
- .appendValue(image.getHeight());
- return false;
- }
- return true;
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("image with ID ").appendValue(id);
- description.appendText(", created at @")
- .appendValue(creationTime);
- description.appendText(", has key ").appendValue(key);
- description.appendText(", has title ").appendValue(title);
- description.appendText(", has description ")
- .appendValue(imageDescription);
- description.appendText(", has width ").appendValue(width);
- description.appendText(", has height ").appendValue(height);
- }
- };
- }
-
- private static class PostMatcher extends TypeSafeDiagnosingMatcher<Post> {
-
- private final String postId;
- private final long time;
- private final String text;
- private final Optional<String> recipient;
-
- private PostMatcher(String postId, long time, String text,
- Optional<String> recipient) {
- this.postId = postId;
- this.time = time;
- this.text = text;
- this.recipient = recipient;
- }
-
- @Override
- protected boolean matchesSafely(Post post,
- Description mismatchDescription) {
- if (!post.getId().equals(postId)) {
- mismatchDescription.appendText("ID is not ")
- .appendValue(postId);
- return false;
- }
- if (post.getTime() != time) {
- mismatchDescription.appendText("Time is not @")
- .appendValue(time);
- return false;
- }
- if (!post.getText().equals(text)) {
- mismatchDescription.appendText("Text is not ")
- .appendValue(text);
- return false;
- }
- if (recipient.isPresent()) {
- if (!post.getRecipientId().isPresent()) {
- mismatchDescription.appendText(
- "Recipient not present");
- return false;
- }
- if (!post.getRecipientId().get().equals(recipient.get())) {
- mismatchDescription.appendText("Recipient is not ")
- .appendValue(recipient.get());
- return false;
- }
- } else {
- if (post.getRecipientId().isPresent()) {
- mismatchDescription.appendText("Recipient is present");
- return false;
- }
- }
- return true;
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("is post with ID ")
- .appendValue(postId);
- description.appendText(", created at @").appendValue(time);
- description.appendText(", text ").appendValue(text);
- if (recipient.isPresent()) {
- description.appendText(", directed at ")
- .appendValue(recipient.get());
- }
- }
-
- }
-
- private static class PostIdMatcher extends TypeSafeDiagnosingMatcher<Post> {
-
- private final String id;
-
- private PostIdMatcher(String id) {
- this.id = id;
- }
-
- @Override
- protected boolean matchesSafely(Post item,
- Description mismatchDescription) {
- if (!item.getId().equals(id)) {
- mismatchDescription.appendText("post has ID ").appendValue(item.getId());
- return false;
- }
- return true;
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("post with ID ").appendValue(id);
- }
-
- }
-
- private static class PostReplyMatcher
- extends TypeSafeDiagnosingMatcher<PostReply> {
-
- private final String postReplyId;
- private final String postId;
- private final long time;
- private final String text;
-
- private PostReplyMatcher(String postReplyId, String postId, long time,
- String text) {
- this.postReplyId = postReplyId;
- this.postId = postId;
- this.time = time;
- this.text = text;
- }
-
- @Override
- protected boolean matchesSafely(PostReply postReply,
- Description mismatchDescription) {
- if (!postReply.getId().equals(postReplyId)) {
- mismatchDescription.appendText("is post reply ")
- .appendValue(postReply.getId());
- return false;
- }
- if (!postReply.getPostId().equals(postId)) {
- mismatchDescription.appendText("is reply to ")
- .appendValue(postReply.getPostId());
- return false;
- }
- if (postReply.getTime() != time) {
- mismatchDescription.appendText("is created at @").appendValue(
- postReply.getTime());
- return false;
- }
- if (!postReply.getText().equals(text)) {
- mismatchDescription.appendText("says ")
- .appendValue(postReply.getText());
- return false;
- }
- return true;
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("is post reply ").appendValue(postReplyId);
- description.appendText(", replies to post ").appendValue(postId);
- description.appendText(", is created at @").appendValue(time);
- description.appendText(", says ").appendValue(text);
- }
-
- }
-
-}
+++ /dev/null
-package net.pterodactylus.sone;
-
-import static java.util.UUID.randomUUID;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import net.pterodactylus.sone.data.Album;
-import net.pterodactylus.sone.data.Album.Modifier;
-import net.pterodactylus.sone.data.Image;
-import net.pterodactylus.sone.data.Sone;
-import net.pterodactylus.sone.database.AlbumBuilder;
-
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-/**
- * {@link AlbumBuilder} that returns a mocked {@link Album}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class TestAlbumBuilder implements AlbumBuilder {
-
- private final Album album = mock(Album.class);
- private final List<Album> albums = new ArrayList<Album>();
- private final List<Image> images = new ArrayList<Image>();
- private Album parentAlbum;
- private String title;
- private String description;
- private String imageId;
-
- public TestAlbumBuilder() {
- when(album.getTitle()).thenAnswer(new Answer<String>() {
- @Override
- public String answer(InvocationOnMock invocation) {
- return title;
- }
- });
- when(album.getDescription()).thenAnswer(new Answer<String>() {
- @Override
- public String answer(InvocationOnMock invocation) {
- return description;
- }
- });
- when(album.getAlbums()).thenReturn(albums);
- when(album.getImages()).thenReturn(images);
- doAnswer(new Answer<Void>() {
- @Override
- public Void answer(InvocationOnMock invocation) {
- albums.add((Album) invocation.getArguments()[0]);
- ((Album) invocation.getArguments()[0]).setParent(album);
- return null;
- }
- }).when(album).addAlbum(any(Album.class));
- doAnswer(new Answer<Void>() {
- @Override
- public Void answer(InvocationOnMock invocation) {
- images.add((Image) invocation.getArguments()[0]);
- return null;
- }
- }).when(album).addImage(any(Image.class));
- doAnswer(new Answer<Void>() {
- @Override
- public Void answer(InvocationOnMock invocation) {
- parentAlbum = (Album) invocation.getArguments()[0];
- return null;
- }
- }).when(album).setParent(any(Album.class));
- when(album.getParent()).thenAnswer(new Answer<Album>() {
- @Override
- public Album answer(InvocationOnMock invocation) {
- return parentAlbum;
- }
- });
- when(album.modify()).thenReturn(new Modifier() {
- @Override
- public Modifier setTitle(String title) {
- TestAlbumBuilder.this.title = title;
- return this;
- }
-
- @Override
- public Modifier setDescription(String description) {
- TestAlbumBuilder.this.description = description;
- return this;
- }
-
- @Override
- public Album update() throws IllegalStateException {
- return album;
- }
- });
- }
-
- @Override
- public AlbumBuilder randomId() {
- when(album.getId()).thenReturn(randomUUID().toString());
- return this;
- }
-
- @Override
- public AlbumBuilder withId(String id) {
- when(album.getId()).thenReturn(id);
- return this;
- }
-
- @Override
- public AlbumBuilder by(Sone sone) {
- when(album.getSone()).thenReturn(sone);
- return this;
- }
-
- @Override
- public Album build() throws IllegalStateException {
- return album;
- }
-
-}
+++ /dev/null
-package net.pterodactylus.sone;
-
-import static java.util.UUID.randomUUID;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import net.pterodactylus.sone.data.Image;
-import net.pterodactylus.sone.data.Sone;
-import net.pterodactylus.sone.database.ImageBuilder;
-
-/**
- * {@link ImageBuilder} implementation that returns a mocked {@link Image}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class TestImageBuilder implements ImageBuilder {
-
- private final Image image;
-
- public TestImageBuilder() {
- image = mock(Image.class);
- Image.Modifier imageModifier = new Image.Modifier() {
- private Sone sone = image.getSone();
- private long creationTime = image.getCreationTime();
- private String key = image.getKey();
- private String title = image.getTitle();
- private String description = image.getDescription();
- private int width = image.getWidth();
- private int height = image.getHeight();
-
- @Override
- public Image.Modifier setSone(Sone sone) {
- this.sone = sone;
- return this;
- }
-
- @Override
- public Image.Modifier setCreationTime(long creationTime) {
- this.creationTime = creationTime;
- return this;
- }
-
- @Override
- public Image.Modifier setKey(String key) {
- this.key = key;
- return this;
- }
-
- @Override
- public Image.Modifier setTitle(String title) {
- this.title = title;
- return this;
- }
-
- @Override
- public Image.Modifier setDescription(String description) {
- this.description = description;
- return this;
- }
-
- @Override
- public Image.Modifier setWidth(int width) {
- this.width = width;
- return this;
- }
-
- @Override
- public Image.Modifier setHeight(int height) {
- this.height = height;
- return this;
- }
-
- @Override
- public Image update() throws IllegalStateException {
- when(image.getSone()).thenReturn(sone);
- when(image.getCreationTime()).thenReturn(creationTime);
- when(image.getKey()).thenReturn(key);
- when(image.getTitle()).thenReturn(title);
- when(image.getDescription()).thenReturn(description);
- when(image.getWidth()).thenReturn(width);
- when(image.getHeight()).thenReturn(height);
- return image;
- }
- };
- when(image.modify()).thenReturn(imageModifier);
- }
-
- @Override
- public ImageBuilder randomId() {
- when(image.getId()).thenReturn(randomUUID().toString());
- return this;
- }
-
- @Override
- public ImageBuilder withId(String id) {
- when(image.getId()).thenReturn(id);
- return this;
- }
-
- @Override
- public Image build() throws IllegalStateException {
- return image;
- }
-
-}
+++ /dev/null
-package net.pterodactylus.sone;
-
-import static com.google.common.base.Optional.fromNullable;
-import static java.lang.System.currentTimeMillis;
-import static java.util.UUID.randomUUID;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import net.pterodactylus.sone.data.Post;
-import net.pterodactylus.sone.data.Sone;
-import net.pterodactylus.sone.database.PostBuilder;
-
-/**
- * {@link PostBuilder} implementation that returns a mocked {@link Post}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class TestPostBuilder implements PostBuilder {
-
- private final Post post = mock(Post.class);
- private String recipientId = null;
-
- @Override
- public PostBuilder copyPost(Post post) throws NullPointerException {
- return this;
- }
-
- @Override
- public PostBuilder from(String senderId) {
- final Sone sone = mock(Sone.class);
- when(sone.getId()).thenReturn(senderId);
- when(post.getSone()).thenReturn(sone);
- return this;
- }
-
- @Override
- public PostBuilder randomId() {
- when(post.getId()).thenReturn(randomUUID().toString());
- return this;
- }
-
- @Override
- public PostBuilder withId(String id) {
- when(post.getId()).thenReturn(id);
- return this;
- }
-
- @Override
- public PostBuilder currentTime() {
- when(post.getTime()).thenReturn(currentTimeMillis());
- return this;
- }
-
- @Override
- public PostBuilder withTime(long time) {
- when(post.getTime()).thenReturn(time);
- return this;
- }
-
- @Override
- public PostBuilder withText(String text) {
- when(post.getText()).thenReturn(text);
- return this;
- }
-
- @Override
- public PostBuilder to(String recipientId) {
- this.recipientId = recipientId;
- return this;
- }
-
- @Override
- public Post build() throws IllegalStateException {
- when(post.getRecipientId()).thenReturn(fromNullable(recipientId));
- return post;
- }
-
-}
+++ /dev/null
-package net.pterodactylus.sone;
-
-import static java.lang.System.currentTimeMillis;
-import static java.util.UUID.randomUUID;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import net.pterodactylus.sone.data.PostReply;
-import net.pterodactylus.sone.data.Sone;
-import net.pterodactylus.sone.database.PostReplyBuilder;
-
-/**
- * {@link PostReplyBuilder} that returns a mocked {@link PostReply}.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class TestPostReplyBuilder implements PostReplyBuilder {
-
- private final PostReply postReply = mock(PostReply.class);
-
- @Override
- public PostReplyBuilder to(String postId) {
- when(postReply.getPostId()).thenReturn(postId);
- return this;
- }
-
- @Override
- public PostReply build() throws IllegalStateException {
- return postReply;
- }
-
- @Override
- public PostReplyBuilder randomId() {
- when(postReply.getId()).thenReturn(randomUUID().toString());
- return this;
- }
-
- @Override
- public PostReplyBuilder withId(String id) {
- when(postReply.getId()).thenReturn(id);
- return this;
- }
-
- @Override
- public PostReplyBuilder from(String senderId) {
- Sone sone = mock(Sone.class);
- when(sone.getId()).thenReturn(senderId);
- when(postReply.getSone()).thenReturn(sone);
- return this;
- }
-
- @Override
- public PostReplyBuilder currentTime() {
- when(postReply.getTime()).thenReturn(currentTimeMillis());
- return this;
- }
-
- @Override
- public PostReplyBuilder withTime(long time) {
- when(postReply.getTime()).thenReturn(time);
- return this;
- }
-
- @Override
- public PostReplyBuilder withText(String text) {
- when(postReply.getText()).thenReturn(text);
- return this;
- }
-
-}
+++ /dev/null
-package net.pterodactylus.sone;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-/**
- * Utilities for testing.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class TestUtil {
-
- public static void setFinalField(Object object, String fieldName, Object value) {
- try {
- Field clientCoreField = object.getClass().getField(fieldName);
- clientCoreField.setAccessible(true);
- Field modifiersField = Field.class.getDeclaredField("modifiers");
- modifiersField.setAccessible(true);
- modifiersField.setInt(clientCoreField, clientCoreField.getModifiers() & ~Modifier.FINAL);
- clientCoreField.set(object, value);
- } catch (NoSuchFieldException e) {
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static <T> T getPrivateField(Object object, String fieldName) {
- try {
- Field field = object.getClass().getDeclaredField(fieldName);
- field.setAccessible(true);
- return (T) field.get(object);
- } catch (NoSuchFieldException e) {
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static <T> T callPrivateMethod(Object object, String methodName) {
- try {
- Method method = object.getClass().getDeclaredMethod(methodName, new Class[0]);
- method.setAccessible(true);
- return (T) method.invoke(object);
- } catch (NoSuchMethodException e) {
- throw new RuntimeException(e);
- } catch (InvocationTargetException e) {
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
-
-}
+++ /dev/null
-package net.pterodactylus.sone;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-import net.pterodactylus.util.config.ConfigurationException;
-import net.pterodactylus.util.config.Value;
-
-import com.google.common.base.Objects;
-
-/**
- * Simple {@link Value} implementation.
- *
- * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
- */
-public class TestValue<T> implements Value<T> {
-
- private final AtomicReference<T> value = new AtomicReference<T>();
-
- public TestValue(T originalValue) {
- value.set(originalValue);
- }
-
- @Override
- public T getValue() throws ConfigurationException {
- return value.get();
- }
-
- @Override
- public T getValue(T defaultValue) {
- final T realValue = value.get();
- return (realValue != null) ? realValue : defaultValue;
- }
-
- @Override
- public void setValue(T newValue) throws ConfigurationException {
- value.set(newValue);
- }
-
- @Override
- public int hashCode() {
- return value.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- return (obj instanceof TestValue) && Objects.equal(value.get(),
- ((TestValue) obj).value.get());
- }
-
- @Override
- public String toString() {
- return String.valueOf(value.get());
- }
-
- public static <T> Value<T> from(T value) {
- return new TestValue<T>(value);
- }
-
-}
package net.pterodactylus.sone.core;
import static com.google.common.base.Optional.of;
-import static net.pterodactylus.sone.Matchers.isAlbum;
-import static net.pterodactylus.sone.Matchers.isImage;
-import static net.pterodactylus.sone.Matchers.isPost;
-import static net.pterodactylus.sone.Matchers.isPostReply;
+import static net.pterodactylus.sone.test.Matchers.isAlbum;
+import static net.pterodactylus.sone.test.Matchers.isImage;
+import static net.pterodactylus.sone.test.Matchers.isPost;
+import static net.pterodactylus.sone.test.Matchers.isPostReply;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import java.util.Map;
import java.util.Set;
-import net.pterodactylus.sone.TestAlbumBuilder;
-import net.pterodactylus.sone.TestImageBuilder;
-import net.pterodactylus.sone.TestPostBuilder;
-import net.pterodactylus.sone.TestPostReplyBuilder;
-import net.pterodactylus.sone.TestValue;
import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidAlbumFound;
import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidImageFound;
import net.pterodactylus.sone.core.ConfigurationSoneParser.InvalidParentAlbumFound;
import net.pterodactylus.sone.database.PostBuilderFactory;
import net.pterodactylus.sone.database.PostReplyBuilder;
import net.pterodactylus.sone.database.PostReplyBuilderFactory;
+import net.pterodactylus.sone.test.TestAlbumBuilder;
+import net.pterodactylus.sone.test.TestImageBuilder;
+import net.pterodactylus.sone.test.TestPostBuilder;
+import net.pterodactylus.sone.test.TestPostReplyBuilder;
+import net.pterodactylus.sone.test.TestValue;
import net.pterodactylus.util.config.Configuration;
import com.google.common.base.Optional;
import static freenet.keys.InsertableClientSSK.createRandom;
import static freenet.node.RequestStarter.INTERACTIVE_PRIORITY_CLASS;
import static freenet.node.RequestStarter.PREFETCH_PRIORITY_CLASS;
-import static net.pterodactylus.sone.Matchers.delivers;
-import static net.pterodactylus.sone.TestUtil.setFinalField;
+import static net.pterodactylus.sone.test.Matchers.delivers;
+import static net.pterodactylus.sone.test.TestUtil.setFinalField;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import java.net.MalformedURLException;
import java.util.HashMap;
-import net.pterodactylus.sone.TestUtil;
import net.pterodactylus.sone.core.FreenetInterface.BackgroundFetchCallback;
import net.pterodactylus.sone.core.FreenetInterface.Callback;
import net.pterodactylus.sone.core.FreenetInterface.Fetched;
import net.pterodactylus.sone.data.Sone;
import net.pterodactylus.sone.data.TemporaryImage;
import net.pterodactylus.sone.data.impl.ImageImpl;
+import net.pterodactylus.sone.test.TestUtil;
import freenet.client.ClientMetadata;
import freenet.client.FetchContext;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import net.pterodactylus.sone.TestValue;
+import net.pterodactylus.sone.test.TestValue;
import net.pterodactylus.util.config.Configuration;
import com.google.common.eventbus.EventBus;
import java.util.HashSet;
import java.util.Set;
-import net.pterodactylus.sone.TestValue;
+import net.pterodactylus.sone.test.TestValue;
import net.pterodactylus.util.config.Configuration;
import net.pterodactylus.util.config.ConfigurationException;
import net.pterodactylus.util.config.Value;
package net.pterodactylus.sone.database.memory;
import static com.google.common.base.Optional.fromNullable;
-import static net.pterodactylus.sone.Matchers.isPostWithId;
+import static net.pterodactylus.sone.test.Matchers.isPostWithId;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.is;
import static com.google.common.base.Optional.of;
import static java.util.Arrays.asList;
import static java.util.UUID.randomUUID;
-import static net.pterodactylus.sone.Matchers.isAlbum;
-import static net.pterodactylus.sone.Matchers.isImage;
-import static net.pterodactylus.sone.Matchers.isPost;
-import static net.pterodactylus.sone.Matchers.isPostReply;
+import static net.pterodactylus.sone.test.Matchers.isAlbum;
+import static net.pterodactylus.sone.test.Matchers.isImage;
+import static net.pterodactylus.sone.test.Matchers.isPost;
+import static net.pterodactylus.sone.test.Matchers.isPostReply;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import java.util.Map;
import java.util.Set;
-import net.pterodactylus.sone.TestAlbumBuilder;
-import net.pterodactylus.sone.TestImageBuilder;
-import net.pterodactylus.sone.TestPostBuilder;
-import net.pterodactylus.sone.TestPostReplyBuilder;
-import net.pterodactylus.sone.TestValue;
import net.pterodactylus.sone.data.Album;
-import net.pterodactylus.sone.data.impl.AlbumImpl;
import net.pterodactylus.sone.data.Image;
import net.pterodactylus.sone.data.Post;
import net.pterodactylus.sone.data.PostReply;
import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.data.impl.AlbumImpl;
+import net.pterodactylus.sone.test.TestAlbumBuilder;
+import net.pterodactylus.sone.test.TestImageBuilder;
+import net.pterodactylus.sone.test.TestPostBuilder;
+import net.pterodactylus.sone.test.TestPostReplyBuilder;
+import net.pterodactylus.sone.test.TestValue;
import net.pterodactylus.util.config.Configuration;
import net.pterodactylus.util.config.Value;
import static com.google.common.collect.ImmutableMap.of;
import static java.util.Arrays.asList;
-import static net.pterodactylus.sone.Matchers.matchesRegex;
+import static net.pterodactylus.sone.test.Matchers.matchesRegex;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.empty;
import java.util.Collections;
import java.util.List;
-import net.pterodactylus.sone.TestUtil;
import net.pterodactylus.sone.data.Album;
import net.pterodactylus.sone.data.Image;
import net.pterodactylus.sone.data.Profile;
import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.test.TestUtil;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
--- /dev/null
+/*
+ * Sone - Matchers.java - Copyright © 2013–2016 David Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.sone.test;
+
+import static java.util.regex.Pattern.compile;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import net.pterodactylus.sone.data.Album;
+import net.pterodactylus.sone.data.Image;
+import net.pterodactylus.sone.data.Post;
+import net.pterodactylus.sone.data.PostReply;
+
+import com.google.common.base.Optional;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * Matchers used throughout the tests.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class Matchers {
+
+ public static Matcher<String> matchesRegex(final String regex) {
+ return new TypeSafeMatcher<String>() {
+ @Override
+ protected boolean matchesSafely(String item) {
+ return compile(regex).matcher(item).matches();
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("matches: ").appendValue(regex);
+ }
+ };
+ }
+
+ public static Matcher<InputStream> delivers(final byte[] data) {
+ return new TypeSafeMatcher<InputStream>() {
+ byte[] readData = new byte[data.length];
+
+ @Override
+ protected boolean matchesSafely(InputStream inputStream) {
+ int offset = 0;
+ try {
+ while (true) {
+ int r = inputStream.read();
+ if (r == -1) {
+ return offset == data.length;
+ }
+ if (offset == data.length) {
+ return false;
+ }
+ if (data[offset] != (readData[offset] = (byte) r)) {
+ return false;
+ }
+ offset++;
+ }
+ } catch (IOException ioe1) {
+ return false;
+ }
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendValue(data);
+ }
+
+ @Override
+ protected void describeMismatchSafely(InputStream item,
+ Description mismatchDescription) {
+ mismatchDescription.appendValue(readData);
+ }
+ };
+ }
+
+ public static Matcher<Post> isPost(String postId, long time,
+ String text, Optional<String> recipient) {
+ return new PostMatcher(postId, time, text, recipient);
+ }
+
+ public static Matcher<Post> isPostWithId(String postId) {
+ return new PostIdMatcher(postId);
+ }
+
+ public static Matcher<PostReply> isPostReply(String postReplyId,
+ String postId, long time, String text) {
+ return new PostReplyMatcher(postReplyId, postId, time, text);
+ }
+
+ public static Matcher<Album> isAlbum(final String albumId,
+ final String parentAlbumId,
+ final String title, final String albumDescription) {
+ return new TypeSafeDiagnosingMatcher<Album>() {
+ @Override
+ protected boolean matchesSafely(Album album,
+ Description mismatchDescription) {
+ if (!album.getId().equals(albumId)) {
+ mismatchDescription.appendText("ID is ")
+ .appendValue(album.getId());
+ return false;
+ }
+ if (parentAlbumId == null) {
+ if (album.getParent() != null) {
+ mismatchDescription.appendText("has parent album");
+ return false;
+ }
+ } else {
+ if (album.getParent() == null) {
+ mismatchDescription.appendText("has no parent album");
+ return false;
+ }
+ if (!album.getParent().getId().equals(parentAlbumId)) {
+ mismatchDescription.appendText("parent album is ")
+ .appendValue(album.getParent().getId());
+ return false;
+ }
+ }
+ if (!title.equals(album.getTitle())) {
+ mismatchDescription.appendText("has title ")
+ .appendValue(album.getTitle());
+ return false;
+ }
+ if (!albumDescription.equals(album.getDescription())) {
+ mismatchDescription.appendText("has description ")
+ .appendValue(album.getDescription());
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("is album ").appendValue(albumId);
+ if (parentAlbumId == null) {
+ description.appendText(", has no parent");
+ } else {
+ description.appendText(", has parent ")
+ .appendValue(parentAlbumId);
+ }
+ description.appendText(", has title ").appendValue(title);
+ description.appendText(", has description ")
+ .appendValue(albumDescription);
+ }
+ };
+ }
+
+ public static Matcher<Image> isImage(final String id,
+ final long creationTime,
+ final String key, final String title,
+ final String imageDescription,
+ final int width, final int height) {
+ return new TypeSafeDiagnosingMatcher<Image>() {
+ @Override
+ protected boolean matchesSafely(Image image,
+ Description mismatchDescription) {
+ if (!image.getId().equals(id)) {
+ mismatchDescription.appendText("ID is ")
+ .appendValue(image.getId());
+ return false;
+ }
+ if (image.getCreationTime() != creationTime) {
+ mismatchDescription.appendText("created at @")
+ .appendValue(image.getCreationTime());
+ return false;
+ }
+ if (!image.getKey().equals(key)) {
+ mismatchDescription.appendText("key is ")
+ .appendValue(image.getKey());
+ return false;
+ }
+ if (!image.getTitle().equals(title)) {
+ mismatchDescription.appendText("title is ")
+ .appendValue(image.getTitle());
+ return false;
+ }
+ if (!image.getDescription().equals(imageDescription)) {
+ mismatchDescription.appendText("description is ")
+ .appendValue(image.getDescription());
+ return false;
+ }
+ if (image.getWidth() != width) {
+ mismatchDescription.appendText("width is ")
+ .appendValue(image.getWidth());
+ return false;
+ }
+ if (image.getHeight() != height) {
+ mismatchDescription.appendText("height is ")
+ .appendValue(image.getHeight());
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("image with ID ").appendValue(id);
+ description.appendText(", created at @")
+ .appendValue(creationTime);
+ description.appendText(", has key ").appendValue(key);
+ description.appendText(", has title ").appendValue(title);
+ description.appendText(", has description ")
+ .appendValue(imageDescription);
+ description.appendText(", has width ").appendValue(width);
+ description.appendText(", has height ").appendValue(height);
+ }
+ };
+ }
+
+ private static class PostMatcher extends TypeSafeDiagnosingMatcher<Post> {
+
+ private final String postId;
+ private final long time;
+ private final String text;
+ private final Optional<String> recipient;
+
+ private PostMatcher(String postId, long time, String text,
+ Optional<String> recipient) {
+ this.postId = postId;
+ this.time = time;
+ this.text = text;
+ this.recipient = recipient;
+ }
+
+ @Override
+ protected boolean matchesSafely(Post post,
+ Description mismatchDescription) {
+ if (!post.getId().equals(postId)) {
+ mismatchDescription.appendText("ID is not ")
+ .appendValue(postId);
+ return false;
+ }
+ if (post.getTime() != time) {
+ mismatchDescription.appendText("Time is not @")
+ .appendValue(time);
+ return false;
+ }
+ if (!post.getText().equals(text)) {
+ mismatchDescription.appendText("Text is not ")
+ .appendValue(text);
+ return false;
+ }
+ if (recipient.isPresent()) {
+ if (!post.getRecipientId().isPresent()) {
+ mismatchDescription.appendText(
+ "Recipient not present");
+ return false;
+ }
+ if (!post.getRecipientId().get().equals(recipient.get())) {
+ mismatchDescription.appendText("Recipient is not ")
+ .appendValue(recipient.get());
+ return false;
+ }
+ } else {
+ if (post.getRecipientId().isPresent()) {
+ mismatchDescription.appendText("Recipient is present");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("is post with ID ")
+ .appendValue(postId);
+ description.appendText(", created at @").appendValue(time);
+ description.appendText(", text ").appendValue(text);
+ if (recipient.isPresent()) {
+ description.appendText(", directed at ")
+ .appendValue(recipient.get());
+ }
+ }
+
+ }
+
+ private static class PostIdMatcher extends TypeSafeDiagnosingMatcher<Post> {
+
+ private final String id;
+
+ private PostIdMatcher(String id) {
+ this.id = id;
+ }
+
+ @Override
+ protected boolean matchesSafely(Post item,
+ Description mismatchDescription) {
+ if (!item.getId().equals(id)) {
+ mismatchDescription.appendText("post has ID ").appendValue(item.getId());
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("post with ID ").appendValue(id);
+ }
+
+ }
+
+ private static class PostReplyMatcher
+ extends TypeSafeDiagnosingMatcher<PostReply> {
+
+ private final String postReplyId;
+ private final String postId;
+ private final long time;
+ private final String text;
+
+ private PostReplyMatcher(String postReplyId, String postId, long time,
+ String text) {
+ this.postReplyId = postReplyId;
+ this.postId = postId;
+ this.time = time;
+ this.text = text;
+ }
+
+ @Override
+ protected boolean matchesSafely(PostReply postReply,
+ Description mismatchDescription) {
+ if (!postReply.getId().equals(postReplyId)) {
+ mismatchDescription.appendText("is post reply ")
+ .appendValue(postReply.getId());
+ return false;
+ }
+ if (!postReply.getPostId().equals(postId)) {
+ mismatchDescription.appendText("is reply to ")
+ .appendValue(postReply.getPostId());
+ return false;
+ }
+ if (postReply.getTime() != time) {
+ mismatchDescription.appendText("is created at @").appendValue(
+ postReply.getTime());
+ return false;
+ }
+ if (!postReply.getText().equals(text)) {
+ mismatchDescription.appendText("says ")
+ .appendValue(postReply.getText());
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("is post reply ").appendValue(postReplyId);
+ description.appendText(", replies to post ").appendValue(postId);
+ description.appendText(", is created at @").appendValue(time);
+ description.appendText(", says ").appendValue(text);
+ }
+
+ }
+
+}
--- /dev/null
+package net.pterodactylus.sone.test;
+
+import static java.util.UUID.randomUUID;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.pterodactylus.sone.data.Album;
+import net.pterodactylus.sone.data.Album.Modifier;
+import net.pterodactylus.sone.data.Image;
+import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.database.AlbumBuilder;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+/**
+ * {@link AlbumBuilder} that returns a mocked {@link Album}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class TestAlbumBuilder implements AlbumBuilder {
+
+ private final Album album = mock(Album.class);
+ private final List<Album> albums = new ArrayList<Album>();
+ private final List<Image> images = new ArrayList<Image>();
+ private Album parentAlbum;
+ private String title;
+ private String description;
+ private String imageId;
+
+ public TestAlbumBuilder() {
+ when(album.getTitle()).thenAnswer(new Answer<String>() {
+ @Override
+ public String answer(InvocationOnMock invocation) {
+ return title;
+ }
+ });
+ when(album.getDescription()).thenAnswer(new Answer<String>() {
+ @Override
+ public String answer(InvocationOnMock invocation) {
+ return description;
+ }
+ });
+ when(album.getAlbums()).thenReturn(albums);
+ when(album.getImages()).thenReturn(images);
+ doAnswer(new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ albums.add((Album) invocation.getArguments()[0]);
+ ((Album) invocation.getArguments()[0]).setParent(album);
+ return null;
+ }
+ }).when(album).addAlbum(any(Album.class));
+ doAnswer(new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ images.add((Image) invocation.getArguments()[0]);
+ return null;
+ }
+ }).when(album).addImage(any(Image.class));
+ doAnswer(new Answer<Void>() {
+ @Override
+ public Void answer(InvocationOnMock invocation) {
+ parentAlbum = (Album) invocation.getArguments()[0];
+ return null;
+ }
+ }).when(album).setParent(any(Album.class));
+ when(album.getParent()).thenAnswer(new Answer<Album>() {
+ @Override
+ public Album answer(InvocationOnMock invocation) {
+ return parentAlbum;
+ }
+ });
+ when(album.modify()).thenReturn(new Modifier() {
+ @Override
+ public Modifier setTitle(String title) {
+ TestAlbumBuilder.this.title = title;
+ return this;
+ }
+
+ @Override
+ public Modifier setDescription(String description) {
+ TestAlbumBuilder.this.description = description;
+ return this;
+ }
+
+ @Override
+ public Album update() throws IllegalStateException {
+ return album;
+ }
+ });
+ }
+
+ @Override
+ public AlbumBuilder randomId() {
+ when(album.getId()).thenReturn(randomUUID().toString());
+ return this;
+ }
+
+ @Override
+ public AlbumBuilder withId(String id) {
+ when(album.getId()).thenReturn(id);
+ return this;
+ }
+
+ @Override
+ public AlbumBuilder by(Sone sone) {
+ when(album.getSone()).thenReturn(sone);
+ return this;
+ }
+
+ @Override
+ public Album build() throws IllegalStateException {
+ return album;
+ }
+
+}
--- /dev/null
+package net.pterodactylus.sone.test;
+
+import static java.util.UUID.randomUUID;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import net.pterodactylus.sone.data.Image;
+import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.database.ImageBuilder;
+
+/**
+ * {@link ImageBuilder} implementation that returns a mocked {@link Image}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class TestImageBuilder implements ImageBuilder {
+
+ private final Image image;
+
+ public TestImageBuilder() {
+ image = mock(Image.class);
+ Image.Modifier imageModifier = new Image.Modifier() {
+ private Sone sone = image.getSone();
+ private long creationTime = image.getCreationTime();
+ private String key = image.getKey();
+ private String title = image.getTitle();
+ private String description = image.getDescription();
+ private int width = image.getWidth();
+ private int height = image.getHeight();
+
+ @Override
+ public Image.Modifier setSone(Sone sone) {
+ this.sone = sone;
+ return this;
+ }
+
+ @Override
+ public Image.Modifier setCreationTime(long creationTime) {
+ this.creationTime = creationTime;
+ return this;
+ }
+
+ @Override
+ public Image.Modifier setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+ @Override
+ public Image.Modifier setTitle(String title) {
+ this.title = title;
+ return this;
+ }
+
+ @Override
+ public Image.Modifier setDescription(String description) {
+ this.description = description;
+ return this;
+ }
+
+ @Override
+ public Image.Modifier setWidth(int width) {
+ this.width = width;
+ return this;
+ }
+
+ @Override
+ public Image.Modifier setHeight(int height) {
+ this.height = height;
+ return this;
+ }
+
+ @Override
+ public Image update() throws IllegalStateException {
+ when(image.getSone()).thenReturn(sone);
+ when(image.getCreationTime()).thenReturn(creationTime);
+ when(image.getKey()).thenReturn(key);
+ when(image.getTitle()).thenReturn(title);
+ when(image.getDescription()).thenReturn(description);
+ when(image.getWidth()).thenReturn(width);
+ when(image.getHeight()).thenReturn(height);
+ return image;
+ }
+ };
+ when(image.modify()).thenReturn(imageModifier);
+ }
+
+ @Override
+ public ImageBuilder randomId() {
+ when(image.getId()).thenReturn(randomUUID().toString());
+ return this;
+ }
+
+ @Override
+ public ImageBuilder withId(String id) {
+ when(image.getId()).thenReturn(id);
+ return this;
+ }
+
+ @Override
+ public Image build() throws IllegalStateException {
+ return image;
+ }
+
+}
--- /dev/null
+package net.pterodactylus.sone.test;
+
+import static com.google.common.base.Optional.fromNullable;
+import static java.lang.System.currentTimeMillis;
+import static java.util.UUID.randomUUID;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import net.pterodactylus.sone.data.Post;
+import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.database.PostBuilder;
+
+/**
+ * {@link PostBuilder} implementation that returns a mocked {@link Post}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class TestPostBuilder implements PostBuilder {
+
+ private final Post post = mock(Post.class);
+ private String recipientId = null;
+
+ @Override
+ public PostBuilder copyPost(Post post) throws NullPointerException {
+ return this;
+ }
+
+ @Override
+ public PostBuilder from(String senderId) {
+ final Sone sone = mock(Sone.class);
+ when(sone.getId()).thenReturn(senderId);
+ when(post.getSone()).thenReturn(sone);
+ return this;
+ }
+
+ @Override
+ public PostBuilder randomId() {
+ when(post.getId()).thenReturn(randomUUID().toString());
+ return this;
+ }
+
+ @Override
+ public PostBuilder withId(String id) {
+ when(post.getId()).thenReturn(id);
+ return this;
+ }
+
+ @Override
+ public PostBuilder currentTime() {
+ when(post.getTime()).thenReturn(currentTimeMillis());
+ return this;
+ }
+
+ @Override
+ public PostBuilder withTime(long time) {
+ when(post.getTime()).thenReturn(time);
+ return this;
+ }
+
+ @Override
+ public PostBuilder withText(String text) {
+ when(post.getText()).thenReturn(text);
+ return this;
+ }
+
+ @Override
+ public PostBuilder to(String recipientId) {
+ this.recipientId = recipientId;
+ return this;
+ }
+
+ @Override
+ public Post build() throws IllegalStateException {
+ when(post.getRecipientId()).thenReturn(fromNullable(recipientId));
+ return post;
+ }
+
+}
--- /dev/null
+package net.pterodactylus.sone.test;
+
+import static java.lang.System.currentTimeMillis;
+import static java.util.UUID.randomUUID;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import net.pterodactylus.sone.data.PostReply;
+import net.pterodactylus.sone.data.Sone;
+import net.pterodactylus.sone.database.PostReplyBuilder;
+
+/**
+ * {@link PostReplyBuilder} that returns a mocked {@link PostReply}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class TestPostReplyBuilder implements PostReplyBuilder {
+
+ private final PostReply postReply = mock(PostReply.class);
+
+ @Override
+ public PostReplyBuilder to(String postId) {
+ when(postReply.getPostId()).thenReturn(postId);
+ return this;
+ }
+
+ @Override
+ public PostReply build() throws IllegalStateException {
+ return postReply;
+ }
+
+ @Override
+ public PostReplyBuilder randomId() {
+ when(postReply.getId()).thenReturn(randomUUID().toString());
+ return this;
+ }
+
+ @Override
+ public PostReplyBuilder withId(String id) {
+ when(postReply.getId()).thenReturn(id);
+ return this;
+ }
+
+ @Override
+ public PostReplyBuilder from(String senderId) {
+ Sone sone = mock(Sone.class);
+ when(sone.getId()).thenReturn(senderId);
+ when(postReply.getSone()).thenReturn(sone);
+ return this;
+ }
+
+ @Override
+ public PostReplyBuilder currentTime() {
+ when(postReply.getTime()).thenReturn(currentTimeMillis());
+ return this;
+ }
+
+ @Override
+ public PostReplyBuilder withTime(long time) {
+ when(postReply.getTime()).thenReturn(time);
+ return this;
+ }
+
+ @Override
+ public PostReplyBuilder withText(String text) {
+ when(postReply.getText()).thenReturn(text);
+ return this;
+ }
+
+}
--- /dev/null
+package net.pterodactylus.sone.test;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * Utilities for testing.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class TestUtil {
+
+ public static void setFinalField(Object object, String fieldName, Object value) {
+ try {
+ Field clientCoreField = object.getClass().getField(fieldName);
+ clientCoreField.setAccessible(true);
+ Field modifiersField = Field.class.getDeclaredField("modifiers");
+ modifiersField.setAccessible(true);
+ modifiersField.setInt(clientCoreField, clientCoreField.getModifiers() & ~Modifier.FINAL);
+ clientCoreField.set(object, value);
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static <T> T getPrivateField(Object object, String fieldName) {
+ try {
+ Field field = object.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
+ return (T) field.get(object);
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static <T> T callPrivateMethod(Object object, String methodName) {
+ try {
+ Method method = object.getClass().getDeclaredMethod(methodName, new Class[0]);
+ method.setAccessible(true);
+ return (T) method.invoke(object);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
--- /dev/null
+package net.pterodactylus.sone.test;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import net.pterodactylus.util.config.ConfigurationException;
+import net.pterodactylus.util.config.Value;
+
+import com.google.common.base.Objects;
+
+/**
+ * Simple {@link Value} implementation.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class TestValue<T> implements Value<T> {
+
+ private final AtomicReference<T> value = new AtomicReference<T>();
+
+ public TestValue(T originalValue) {
+ value.set(originalValue);
+ }
+
+ @Override
+ public T getValue() throws ConfigurationException {
+ return value.get();
+ }
+
+ @Override
+ public T getValue(T defaultValue) {
+ final T realValue = value.get();
+ return (realValue != null) ? realValue : defaultValue;
+ }
+
+ @Override
+ public void setValue(T newValue) throws ConfigurationException {
+ value.set(newValue);
+ }
+
+ @Override
+ public int hashCode() {
+ return value.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return (obj instanceof TestValue) && Objects.equal(value.get(),
+ ((TestValue) obj).value.get());
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value.get());
+ }
+
+ public static <T> Value<T> from(T value) {
+ return new TestValue<T>(value);
+ }
+
+}
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
-import net.pterodactylus.sone.TestUtil;
+import net.pterodactylus.sone.test.TestUtil;
import org.junit.Test;
+++ /dev/null
-package net.pterodactylus.sone
-
-import org.hamcrest.Description
-import org.hamcrest.TypeSafeDiagnosingMatcher
-
-class OneByOneMatcher<A> : TypeSafeDiagnosingMatcher<A>() {
- private data class Matcher<in A, out V>(val expected: V, val actual: (A) -> V, val description: String)
-
- private val matchers = mutableListOf<Matcher<A, *>>()
-
- fun <V> expect(description: String, expected: V, actual: (A) -> V) {
- matchers += Matcher<A, V>(expected, actual, description)
- }
-
- override fun describeTo(description: Description) {
- matchers.forEachIndexed { index, matcher ->
- if (index > 0) {
- description.appendText(", ")
- }
- description.appendText("${matcher.description} is ").appendValue(matcher.expected)
- }
- }
-
- override fun matchesSafely(item: A, mismatchDescription: Description) =
- matchers.all {
- if (it.expected != it.actual(item)) {
- mismatchDescription.appendText("${it.description} is ").appendValue(it.actual(item))
- false
- } else {
- true
- }
- }
-}
import com.google.common.base.Optional
import com.google.common.base.Optional.absent
import freenet.support.SimpleFieldSet
-import net.pterodactylus.sone.OneByOneMatcher
import net.pterodactylus.sone.core.Core
import net.pterodactylus.sone.data.Post
import net.pterodactylus.sone.data.PostReply
import net.pterodactylus.sone.data.Sone
import net.pterodactylus.sone.freenet.fcp.FcpException
import net.pterodactylus.sone.template.SoneAccessor
+import net.pterodactylus.sone.test.OneByOneMatcher
import net.pterodactylus.sone.test.asOptional
import net.pterodactylus.sone.test.mock
import net.pterodactylus.sone.test.whenever
package net.pterodactylus.sone.template
import freenet.support.api.HTTPRequest
-import net.pterodactylus.sone.Matchers.matchesRegex
+import net.pterodactylus.sone.test.Matchers.matchesRegex
import net.pterodactylus.sone.test.mock
import net.pterodactylus.sone.test.whenever
import net.pterodactylus.sone.web.page.FreenetRequest
--- /dev/null
+package net.pterodactylus.sone.test
+
+import org.hamcrest.Description
+import org.hamcrest.TypeSafeDiagnosingMatcher
+
+class OneByOneMatcher<A> : TypeSafeDiagnosingMatcher<A>() {
+ private data class Matcher<in A, out V>(val expected: V, val actual: (A) -> V, val description: String)
+
+ private val matchers = mutableListOf<Matcher<A, *>>()
+
+ fun <V> expect(description: String, expected: V, actual: (A) -> V) {
+ matchers += Matcher<A, V>(expected, actual, description)
+ }
+
+ override fun describeTo(description: Description) {
+ matchers.forEachIndexed { index, matcher ->
+ if (index > 0) {
+ description.appendText(", ")
+ }
+ description.appendText("${matcher.description} is ").appendValue(matcher.expected)
+ }
+ }
+
+ override fun matchesSafely(item: A, mismatchDescription: Description) =
+ matchers.all {
+ if (it.expected != it.actual(item)) {
+ mismatchDescription.appendText("${it.description} is ").appendValue(it.actual(item))
+ false
+ } else {
+ true
+ }
+ }
+}