From 885d5bb7dd9db505a5c70a8aca8583caae684d52 Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sat, 12 Dec 2015 20:13:25 +0100 Subject: [PATCH 01/10] Add proper unit tests for event-aggregator pattern --- event-aggregator/pom.xml | 5 + .../event/aggregator/EventEmitterTest.java | 133 ++++++++++++++++++ .../iluwatar/event/aggregator/EventTest.java | 27 ++++ .../event/aggregator/KingJoffreyTest.java | 67 +++++++++ .../event/aggregator/KingsHandTest.java | 48 +++++++ .../event/aggregator/LordBaelishTest.java | 17 +++ .../event/aggregator/LordVarysTest.java | 17 +++ .../iluwatar/event/aggregator/ScoutTest.java | 17 +++ .../event/aggregator/WeekdayTest.java | 24 ++++ 9 files changed, 355 insertions(+) create mode 100644 event-aggregator/src/test/java/com/iluwatar/event/aggregator/EventEmitterTest.java create mode 100644 event-aggregator/src/test/java/com/iluwatar/event/aggregator/EventTest.java create mode 100644 event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingJoffreyTest.java create mode 100644 event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingsHandTest.java create mode 100644 event-aggregator/src/test/java/com/iluwatar/event/aggregator/LordBaelishTest.java create mode 100644 event-aggregator/src/test/java/com/iluwatar/event/aggregator/LordVarysTest.java create mode 100644 event-aggregator/src/test/java/com/iluwatar/event/aggregator/ScoutTest.java create mode 100644 event-aggregator/src/test/java/com/iluwatar/event/aggregator/WeekdayTest.java diff --git a/event-aggregator/pom.xml b/event-aggregator/pom.xml index 62c6adf14..94873472f 100644 --- a/event-aggregator/pom.xml +++ b/event-aggregator/pom.xml @@ -13,5 +13,10 @@ junit test + + org.mockito + mockito-core + test + diff --git a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/EventEmitterTest.java b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/EventEmitterTest.java new file mode 100644 index 000000000..09acf7442 --- /dev/null +++ b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/EventEmitterTest.java @@ -0,0 +1,133 @@ +package com.iluwatar.event.aggregator; + +import org.junit.Test; + +import java.util.Objects; +import java.util.function.Function; +import java.util.function.Supplier; + +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Date: 12/12/15 - 10:58 PM + * + * @author Jeroen Meulemeester + */ +public abstract class EventEmitterTest { + + /** + * Factory used to create a new instance of the test object with a default observer + */ + private final Function factoryWithDefaultObserver; + + /** + * Factory used to create a new instance of the test object without passing a default observer + */ + private final Supplier factoryWithoutDefaultObserver; + + /** + * The day of the week an event is expected + */ + private final Weekday specialDay; + + /** + * The expected event, emitted on the special day + */ + private final Event event; + + /** + * Create a new event emitter test, using the given test object factories, special day and event + */ + EventEmitterTest(final Weekday specialDay, final Event event, + final Function factoryWithDefaultObserver, + final Supplier factoryWithoutDefaultObserver) { + + this.specialDay = specialDay; + this.event = event; + this.factoryWithDefaultObserver = Objects.requireNonNull(factoryWithDefaultObserver); + this.factoryWithoutDefaultObserver = Objects.requireNonNull(factoryWithoutDefaultObserver); + } + + /** + * Go over every day of the month, and check if the event is emitted on the given day. This test + * is executed twice, once without a default emitter and once with + */ + @Test + public void testAllDays() { + testAllDaysWithoutDefaultObserver(specialDay, event); + testAllDaysWithDefaultObserver(specialDay, event); + } + + /** + * Go over every day of the month, and check if the event is emitted on the given day. Use an + * event emitter without a default observer + * + * @param specialDay The special day on which an event is emitted + * @param event The expected event emitted by the test object + */ + private void testAllDaysWithoutDefaultObserver(final Weekday specialDay, final Event event) { + final EventObserver observer1 = mock(EventObserver.class); + final EventObserver observer2 = mock(EventObserver.class); + + final E emitter = this.factoryWithoutDefaultObserver.get(); + emitter.registerObserver(observer1); + emitter.registerObserver(observer2); + + testAllDays(specialDay, event, emitter, observer1, observer2); + } + + /** + * Go over every day of the month, and check if the event is emitted on the given day. + * + * @param specialDay The special day on which an event is emitted + * @param event The expected event emitted by the test object + */ + private void testAllDaysWithDefaultObserver(final Weekday specialDay, final Event event) { + final EventObserver defaultObserver = mock(EventObserver.class); + final EventObserver observer1 = mock(EventObserver.class); + final EventObserver observer2 = mock(EventObserver.class); + + final E emitter = this.factoryWithDefaultObserver.apply(defaultObserver); + emitter.registerObserver(observer1); + emitter.registerObserver(observer2); + + testAllDays(specialDay, event, emitter, defaultObserver, observer1, observer2); + } + + /** + * Pass each week of the day, day by day to the event emitter and verify of the given observers + * received the correct event on the special day. + * + * @param specialDay The special day on which an event is emitted + * @param event The expected event emitted by the test object + * @param emitter The event emitter + * @param observers The registered observer mocks + */ + private void testAllDays(final Weekday specialDay, final Event event, final E emitter, + final EventObserver... observers) { + + for (final Weekday weekday : Weekday.values()) { + // Pass each week of the day, day by day to the event emitter + emitter.timePasses(weekday); + + if (weekday == specialDay) { + // On a special day, every observer should have received the event + for (final EventObserver observer : observers) { + verify(observer, times(1)).onEvent(eq(event)); + } + } else { + // On any other normal day, the observers should have received nothing at all + verifyZeroInteractions(observers); + } + } + + // The observers should not have received any additional events after the week + verifyNoMoreInteractions(observers); + } + +} diff --git a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/EventTest.java b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/EventTest.java new file mode 100644 index 000000000..3f2cdb0fe --- /dev/null +++ b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/EventTest.java @@ -0,0 +1,27 @@ +package com.iluwatar.event.aggregator; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +/** + * Date: 12/12/15 - 2:52 PM + * + * @author Jeroen Meulemeester + */ +public class EventTest { + + /** + * Verify if every event has a non-null, non-empty description + */ + @Test + public void testToString() { + for (final Event event : Event.values()) { + final String toString = event.toString(); + assertNotNull(toString); + assertFalse(toString.trim().isEmpty()); + } + } + +} \ No newline at end of file diff --git a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingJoffreyTest.java b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingJoffreyTest.java new file mode 100644 index 000000000..1dd4e5c63 --- /dev/null +++ b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingJoffreyTest.java @@ -0,0 +1,67 @@ +package com.iluwatar.event.aggregator; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.PrintStream; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Date: 12/12/15 - 3:04 PM + * + * @author Jeroen Meulemeester + */ +public class KingJoffreyTest { + + /** + * The mocked standard out {@link PrintStream}, required since {@link KingJoffrey} does nothing + * except for writing to std-out using {@link System#out} + */ + private final PrintStream stdOutMock = mock(PrintStream.class); + + /** + * Keep the original std-out so it can be restored after the test + */ + private final PrintStream stdOutOrig = System.out; + + /** + * Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test + */ + @Before + public void setUp() { + System.setOut(this.stdOutMock); + } + + /** + * Removed the mocked std-out {@link PrintStream} again from the {@link System} class + */ + @After + public void tearDown() { + System.setOut(this.stdOutOrig); + } + + /** + * Test if {@link KingJoffrey} tells us what event he received + */ + @Test + public void testOnEvent() { + final KingJoffrey kingJoffrey = new KingJoffrey(); + + for (final Event event : Event.values()) { + verifyZeroInteractions(this.stdOutMock); + kingJoffrey.onEvent(event); + + final String expectedMessage = "Received event from the King's Hand: " + event.toString(); + verify(this.stdOutMock, times(1)).println(expectedMessage); + verifyNoMoreInteractions(this.stdOutMock); + } + + } + +} \ No newline at end of file diff --git a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingsHandTest.java b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingsHandTest.java new file mode 100644 index 000000000..992ee4cf5 --- /dev/null +++ b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/KingsHandTest.java @@ -0,0 +1,48 @@ +package com.iluwatar.event.aggregator; + +import org.junit.Test; + +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Date: 12/12/15 - 10:57 AM + * + * @author Jeroen Meulemeester + */ +public class KingsHandTest extends EventEmitterTest { + + /** + * Create a new test instance, using the correct object factory + */ + public KingsHandTest() { + super(null, null, KingsHand::new, KingsHand::new); + } + + /** + * The {@link KingsHand} is both an {@EventEmitter} as an {@link EventObserver} so verify if every + * event received is passed up to it's superior, in most cases {@link KingJoffrey} but now just a + * mocked observer. + */ + @Test + public void testPassThrough() throws Exception { + final EventObserver observer = mock(EventObserver.class); + final KingsHand kingsHand = new KingsHand(observer); + + // The kings hand should not pass any events before he received one + verifyZeroInteractions(observer); + + // Verify if each event is passed on to the observer, nothing less, nothing more. + for (final Event event : Event.values()) { + kingsHand.onEvent(event); + verify(observer, times(1)).onEvent(eq(event)); + verifyNoMoreInteractions(observer); + } + + } + +} \ No newline at end of file diff --git a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/LordBaelishTest.java b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/LordBaelishTest.java new file mode 100644 index 000000000..dbc867859 --- /dev/null +++ b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/LordBaelishTest.java @@ -0,0 +1,17 @@ +package com.iluwatar.event.aggregator; + +/** + * Date: 12/12/15 - 10:57 AM + * + * @author Jeroen Meulemeester + */ +public class LordBaelishTest extends EventEmitterTest { + + /** + * Create a new test instance, using the correct object factory + */ + public LordBaelishTest() { + super(Weekday.FRIDAY, Event.STARK_SIGHTED, LordBaelish::new, LordBaelish::new); + } + +} \ No newline at end of file diff --git a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/LordVarysTest.java b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/LordVarysTest.java new file mode 100644 index 000000000..050af5576 --- /dev/null +++ b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/LordVarysTest.java @@ -0,0 +1,17 @@ +package com.iluwatar.event.aggregator; + +/** + * Date: 12/12/15 - 10:57 AM + * + * @author Jeroen Meulemeester + */ +public class LordVarysTest extends EventEmitterTest { + + /** + * Create a new test instance, using the correct object factory + */ + public LordVarysTest() { + super(Weekday.SATURDAY, Event.TRAITOR_DETECTED, LordVarys::new, LordVarys::new); + } + +} \ No newline at end of file diff --git a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/ScoutTest.java b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/ScoutTest.java new file mode 100644 index 000000000..435e07821 --- /dev/null +++ b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/ScoutTest.java @@ -0,0 +1,17 @@ +package com.iluwatar.event.aggregator; + +/** + * Date: 12/12/15 - 10:57 AM + * + * @author Jeroen Meulemeester + */ +public class ScoutTest extends EventEmitterTest { + + /** + * Create a new test instance, using the correct object factory + */ + public ScoutTest() { + super(Weekday.TUESDAY, Event.WARSHIPS_APPROACHING, Scout::new, Scout::new); + } + +} \ No newline at end of file diff --git a/event-aggregator/src/test/java/com/iluwatar/event/aggregator/WeekdayTest.java b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/WeekdayTest.java new file mode 100644 index 000000000..37b300851 --- /dev/null +++ b/event-aggregator/src/test/java/com/iluwatar/event/aggregator/WeekdayTest.java @@ -0,0 +1,24 @@ +package com.iluwatar.event.aggregator; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Date: 12/12/15 - 2:12 PM + * + * @author Jeroen Meulemeester + */ +public class WeekdayTest { + + @Test + public void testToString() throws Exception { + for (final Weekday weekday : Weekday.values()) { + final String toString = weekday.toString(); + assertNotNull(toString); + assertEquals(weekday.name(), toString.toUpperCase()); + } + } + +} \ No newline at end of file From df69a8f9869346d528a8fd189b2e8acb43ab6188 Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sat, 12 Dec 2015 20:14:59 +0100 Subject: [PATCH 02/10] Add proper tests for execute-around pattern --- .../execute/around/SimpleFileWriterTest.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 execute-around/src/test/java/com/iluwatar/execute/around/SimpleFileWriterTest.java diff --git a/execute-around/src/test/java/com/iluwatar/execute/around/SimpleFileWriterTest.java b/execute-around/src/test/java/com/iluwatar/execute/around/SimpleFileWriterTest.java new file mode 100644 index 000000000..168026b65 --- /dev/null +++ b/execute-around/src/test/java/com/iluwatar/execute/around/SimpleFileWriterTest.java @@ -0,0 +1,75 @@ +package com.iluwatar.execute.around; + +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * Date: 12/12/15 - 3:21 PM + * + * @author Jeroen Meulemeester + */ +public class SimpleFileWriterTest { + + /** + * Create a temporary folder, used to generate files in during this test + */ + @Rule + public final TemporaryFolder testFolder = new TemporaryFolder(); + + /** + * Verify if the given writer is not 'null' + */ + @Test + public void testWriterNotNull() throws Exception { + final File temporaryFile = this.testFolder.newFile(); + new SimpleFileWriter(temporaryFile.getPath(), Assert::assertNotNull); + } + + /** + * Test if the {@link SimpleFileWriter} creates a file if it doesn't exist + */ + @Test + public void testNonExistentFile() throws Exception { + final File nonExistingFile = new File(this.testFolder.getRoot(), "non-existing-file"); + assertFalse(nonExistingFile.exists()); + + new SimpleFileWriter(nonExistingFile.getPath(), Assert::assertNotNull); + assertTrue(nonExistingFile.exists()); + } + + /** + * Test if the data written to the file writer actually gets in the file + */ + @Test + public void testActualWrite() throws Exception { + final String testMessage = "Test message"; + + final File temporaryFile = this.testFolder.newFile(); + assertTrue(temporaryFile.exists()); + + new SimpleFileWriter(temporaryFile.getPath(), writer -> writer.write(testMessage)); + assertTrue(Files.lines(temporaryFile.toPath()).allMatch(testMessage::equals)); + } + + /** + * Verify if an {@link IOException} during the write ripples through + */ + @Test(expected = IOException.class) + public void testIOException() throws Exception { + final File temporaryFile = this.testFolder.newFile(); + new SimpleFileWriter(temporaryFile.getPath(), writer -> { + throw new IOException(""); + }); + } + +} From 4181514c6520aee1437ba27d08ef665d0f1a9b4d Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sat, 12 Dec 2015 20:16:10 +0100 Subject: [PATCH 03/10] Add proper tests for fluent-interface pattern and fixed a little bug --- fluentinterface/pom.xml | 5 + .../lazy/LazyFluentIterable.java | 2 +- .../fluentiterable/FluentIterableTest.java | 180 ++++++++++++++++++ .../lazy/LazyFluentIterableTest.java | 18 ++ .../simple/SimpleFluentIterableTest.java | 18 ++ 5 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterableTest.java create mode 100644 fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterableTest.java create mode 100644 fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterableTest.java diff --git a/fluentinterface/pom.xml b/fluentinterface/pom.xml index d549d5216..ff10a3814 100644 --- a/fluentinterface/pom.xml +++ b/fluentinterface/pom.xml @@ -16,5 +16,10 @@ junit test + + org.mockito + mockito-core + test + \ No newline at end of file diff --git a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java index 560b10189..44f095289 100644 --- a/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java +++ b/fluentinterface/src/main/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterable.java @@ -215,7 +215,7 @@ public class LazyFluentIterable implements FluentIterable { return new DecoratingIterator(iterable.iterator()) { @Override public TYPE computeNext() { - return fromIterator.next(); + return fromIterator.hasNext() ? fromIterator.next() : null; } }; } diff --git a/fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterableTest.java b/fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterableTest.java new file mode 100644 index 000000000..7d4cb0530 --- /dev/null +++ b/fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/FluentIterableTest.java @@ -0,0 +1,180 @@ +package com.iluwatar.fluentinterface.fluentiterable; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.Spliterator; +import java.util.function.Consumer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +/** + * Date: 12/12/15 - 7:00 PM + * + * @author Jeroen Meulemeester + */ +public abstract class FluentIterableTest { + + /** + * Create a new {@link FluentIterable} from the given integers + * + * @param integers The integers + * @return The new iterable, use for testing + */ + protected abstract FluentIterable createFluentIterable(final Iterable integers); + + @Test + public void testFirst() throws Exception { + final List integers = Arrays.asList(1, 2, 3, 10, 9, 8); + final Optional first = createFluentIterable(integers).first(); + assertNotNull(first); + assertTrue(first.isPresent()); + assertEquals(integers.get(0), first.get()); + } + + @Test + public void testFirstEmptyCollection() throws Exception { + final List integers = Collections.emptyList(); + final Optional first = createFluentIterable(integers).first(); + assertNotNull(first); + assertFalse(first.isPresent()); + } + + @Test + public void testFirstCount() throws Exception { + final List integers = Arrays.asList(1, 2, 3, 10, 9, 8); + final List first4 = createFluentIterable(integers) + .first(4) + .asList(); + + assertNotNull(first4); + assertEquals(4, first4.size()); + + assertEquals(integers.get(0), first4.get(0)); + assertEquals(integers.get(1), first4.get(1)); + assertEquals(integers.get(2), first4.get(2)); + assertEquals(integers.get(3), first4.get(3)); + } + + @Test + public void testFirstCountLessItems() throws Exception { + final List integers = Arrays.asList(1, 2, 3); + final List first4 = createFluentIterable(integers) + .first(4) + .asList(); + + assertNotNull(first4); + assertEquals(3, first4.size()); + + assertEquals(integers.get(0), first4.get(0)); + assertEquals(integers.get(1), first4.get(1)); + assertEquals(integers.get(2), first4.get(2)); + } + + @Test + public void testLast() throws Exception { + final List integers = Arrays.asList(1, 2, 3, 10, 9, 8); + final Optional last = createFluentIterable(integers).last(); + assertNotNull(last); + assertTrue(last.isPresent()); + assertEquals(integers.get(integers.size() - 1), last.get()); + } + + @Test + public void testLastEmptyCollection() throws Exception { + final List integers = Collections.emptyList(); + final Optional last = createFluentIterable(integers).last(); + assertNotNull(last); + assertFalse(last.isPresent()); + } + + @Test + public void testLastCount() throws Exception { + final List integers = Arrays.asList(1, 2, 3, 10, 9, 8); + final List last4 = createFluentIterable(integers) + .last(4) + .asList(); + + assertNotNull(last4); + assertEquals(4, last4.size()); + assertEquals(Integer.valueOf(3), last4.get(0)); + assertEquals(Integer.valueOf(10), last4.get(1)); + assertEquals(Integer.valueOf(9), last4.get(2)); + assertEquals(Integer.valueOf(8), last4.get(3)); + } + + @Test + public void testLastCountLessItems() throws Exception { + final List integers = Arrays.asList(1, 2, 3); + final List last4 = createFluentIterable(integers) + .last(4) + .asList(); + + assertNotNull(last4); + assertEquals(3, last4.size()); + + assertEquals(Integer.valueOf(1), last4.get(0)); + assertEquals(Integer.valueOf(2), last4.get(1)); + assertEquals(Integer.valueOf(3), last4.get(2)); + } + + @Test + public void testFilter() throws Exception { + final List integers = Arrays.asList(1, 2, 3, 10, 9, 8); + final List evenItems = createFluentIterable(integers) + .filter(i -> i % 2 == 0) + .asList(); + + assertNotNull(evenItems); + assertEquals(3, evenItems.size()); + assertEquals(Integer.valueOf(2), evenItems.get(0)); + assertEquals(Integer.valueOf(10), evenItems.get(1)); + assertEquals(Integer.valueOf(8), evenItems.get(2)); + } + + @Test + public void testMap() throws Exception { + final List integers = Arrays.asList(1, 2, 3); + final List longs = createFluentIterable(integers) + .map(Integer::longValue) + .asList(); + + assertNotNull(longs); + assertEquals(integers.size(), longs.size()); + assertEquals(Long.valueOf(1), longs.get(0)); + assertEquals(Long.valueOf(2), longs.get(1)); + assertEquals(Long.valueOf(3), longs.get(2)); + } + + @Test + public void testForEach() throws Exception { + final List integers = Arrays.asList(1, 2, 3); + + final Consumer consumer = mock(Consumer.class); + createFluentIterable(integers).forEach(consumer); + + verify(consumer, times(1)).accept(Integer.valueOf(1)); + verify(consumer, times(1)).accept(Integer.valueOf(2)); + verify(consumer, times(1)).accept(Integer.valueOf(3)); + verifyNoMoreInteractions(consumer); + + } + + @Test + public void testSpliterator() throws Exception { + final List integers = Arrays.asList(1, 2, 3); + final Spliterator split = createFluentIterable(integers).spliterator(); + assertNotNull(split); + } + +} \ No newline at end of file diff --git a/fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterableTest.java b/fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterableTest.java new file mode 100644 index 000000000..aa51327e3 --- /dev/null +++ b/fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/lazy/LazyFluentIterableTest.java @@ -0,0 +1,18 @@ +package com.iluwatar.fluentinterface.fluentiterable.lazy; + +import com.iluwatar.fluentinterface.fluentiterable.FluentIterable; +import com.iluwatar.fluentinterface.fluentiterable.FluentIterableTest; + +/** + * Date: 12/12/15 - 7:56 PM + * + * @author Jeroen Meulemeester + */ +public class LazyFluentIterableTest extends FluentIterableTest { + + @Override + protected FluentIterable createFluentIterable(Iterable integers) { + return LazyFluentIterable.from(integers); + } + +} diff --git a/fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterableTest.java b/fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterableTest.java new file mode 100644 index 000000000..360d6e222 --- /dev/null +++ b/fluentinterface/src/test/java/com/iluwatar/fluentinterface/fluentiterable/simple/SimpleFluentIterableTest.java @@ -0,0 +1,18 @@ +package com.iluwatar.fluentinterface.fluentiterable.simple; + +import com.iluwatar.fluentinterface.fluentiterable.FluentIterable; +import com.iluwatar.fluentinterface.fluentiterable.FluentIterableTest; + +/** + * Date: 12/12/15 - 7:56 PM + * + * @author Jeroen Meulemeester + */ +public class SimpleFluentIterableTest extends FluentIterableTest { + + @Override + protected FluentIterable createFluentIterable(Iterable integers) { + return SimpleFluentIterable.fromCopyOf(integers); + } + +} From 3dc370e2d17677419b3c7f824210876ecb22fce4 Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sat, 12 Dec 2015 22:43:47 +0100 Subject: [PATCH 04/10] Add proper tests for flux pattern --- flux/pom.xml | 5 + .../com/iluwatar/flux/action/ContentTest.java | 24 +++++ .../iluwatar/flux/action/MenuItemTest.java | 24 +++++ .../flux/dispatcher/DispatcherTest.java | 92 +++++++++++++++++++ .../iluwatar/flux/store/ContentStoreTest.java | 47 ++++++++++ .../iluwatar/flux/store/MenuStoreTest.java | 47 ++++++++++ .../iluwatar/flux/view/ContentViewTest.java | 33 +++++++ .../com/iluwatar/flux/view/MenuViewTest.java | 50 ++++++++++ 8 files changed, 322 insertions(+) create mode 100644 flux/src/test/java/com/iluwatar/flux/action/ContentTest.java create mode 100644 flux/src/test/java/com/iluwatar/flux/action/MenuItemTest.java create mode 100644 flux/src/test/java/com/iluwatar/flux/dispatcher/DispatcherTest.java create mode 100644 flux/src/test/java/com/iluwatar/flux/store/ContentStoreTest.java create mode 100644 flux/src/test/java/com/iluwatar/flux/store/MenuStoreTest.java create mode 100644 flux/src/test/java/com/iluwatar/flux/view/ContentViewTest.java create mode 100644 flux/src/test/java/com/iluwatar/flux/view/MenuViewTest.java diff --git a/flux/pom.xml b/flux/pom.xml index 3b06d299c..7b0afd626 100644 --- a/flux/pom.xml +++ b/flux/pom.xml @@ -14,5 +14,10 @@ junit test + + org.mockito + mockito-core + test + diff --git a/flux/src/test/java/com/iluwatar/flux/action/ContentTest.java b/flux/src/test/java/com/iluwatar/flux/action/ContentTest.java new file mode 100644 index 000000000..7781c1d90 --- /dev/null +++ b/flux/src/test/java/com/iluwatar/flux/action/ContentTest.java @@ -0,0 +1,24 @@ +package com.iluwatar.flux.action; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +/** + * Date: 12/12/15 - 10:11 PM + * + * @author Jeroen Meulemeester + */ +public class ContentTest { + + @Test + public void testToString() throws Exception { + for (final Content content : Content.values()) { + final String toString = content.toString(); + assertNotNull(toString); + assertFalse(toString.trim().isEmpty()); + } + } + +} diff --git a/flux/src/test/java/com/iluwatar/flux/action/MenuItemTest.java b/flux/src/test/java/com/iluwatar/flux/action/MenuItemTest.java new file mode 100644 index 000000000..02fa781e6 --- /dev/null +++ b/flux/src/test/java/com/iluwatar/flux/action/MenuItemTest.java @@ -0,0 +1,24 @@ +package com.iluwatar.flux.action; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +/** + * Date: 12/12/15 - 10:15 PM + * + * @author Jeroen Meulemeester + */ +public class MenuItemTest { + + @Test + public void testToString() throws Exception { + for (final MenuItem menuItem : MenuItem.values()) { + final String toString = menuItem.toString(); + assertNotNull(toString); + assertFalse(toString.trim().isEmpty()); + } + } + +} diff --git a/flux/src/test/java/com/iluwatar/flux/dispatcher/DispatcherTest.java b/flux/src/test/java/com/iluwatar/flux/dispatcher/DispatcherTest.java new file mode 100644 index 000000000..8e1977dd8 --- /dev/null +++ b/flux/src/test/java/com/iluwatar/flux/dispatcher/DispatcherTest.java @@ -0,0 +1,92 @@ +package com.iluwatar.flux.dispatcher; + +import com.iluwatar.flux.action.Action; +import com.iluwatar.flux.action.ActionType; +import com.iluwatar.flux.action.Content; +import com.iluwatar.flux.action.ContentAction; +import com.iluwatar.flux.action.MenuAction; +import com.iluwatar.flux.action.MenuItem; +import com.iluwatar.flux.store.Store; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.util.List; +import java.util.stream.Collectors; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; + +/** + * Date: 12/12/15 - 8:22 PM + * + * @author Jeroen Meulemeester + */ +public class DispatcherTest { + + /** + * Dispatcher is a singleton with no way to reset it's internal state back to the beginning. + * Replace the instance with a fresh one before each test to make sure test cases have no + * influence on each other. + */ + @Before + public void setUp() throws Exception { + final Constructor constructor; + constructor = Dispatcher.class.getDeclaredConstructor(); + constructor.setAccessible(true); + + final Field field = Dispatcher.class.getDeclaredField("instance"); + field.setAccessible(true); + field.set(Dispatcher.getInstance(), constructor.newInstance()); + } + + @Test + public void testGetInstance() throws Exception { + assertNotNull(Dispatcher.getInstance()); + assertSame(Dispatcher.getInstance(), Dispatcher.getInstance()); + } + + @Test + public void testMenuItemSelected() throws Exception { + final Dispatcher dispatcher = Dispatcher.getInstance(); + + final Store store = mock(Store.class); + dispatcher.registerStore(store); + dispatcher.menuItemSelected(MenuItem.HOME); + dispatcher.menuItemSelected(MenuItem.COMPANY); + + // We expect 4 events, 2 menu selections and 2 content change actions + final ArgumentCaptor actionCaptor = ArgumentCaptor.forClass(Action.class); + verify(store, times(4)).onAction(actionCaptor.capture()); + verifyNoMoreInteractions(store); + + final List actions = actionCaptor.getAllValues(); + final List menuActions = actions.stream() + .filter(a -> a.getType().equals(ActionType.MENU_ITEM_SELECTED)) + .map(a -> (MenuAction) a) + .collect(Collectors.toList()); + + final List contentActions = actions.stream() + .filter(a -> a.getType().equals(ActionType.CONTENT_CHANGED)) + .map(a -> (ContentAction) a) + .collect(Collectors.toList()); + + assertEquals(2, menuActions.size()); + assertEquals(1, menuActions.stream().map(MenuAction::getMenuItem).filter(MenuItem.HOME::equals).count()); + assertEquals(1, menuActions.stream().map(MenuAction::getMenuItem).filter(MenuItem.COMPANY::equals).count()); + + assertEquals(2, contentActions.size()); + assertEquals(1, contentActions.stream().map(ContentAction::getContent).filter(Content.PRODUCTS::equals).count()); + assertEquals(1, contentActions.stream().map(ContentAction::getContent).filter(Content.COMPANY::equals).count()); + + } + +} diff --git a/flux/src/test/java/com/iluwatar/flux/store/ContentStoreTest.java b/flux/src/test/java/com/iluwatar/flux/store/ContentStoreTest.java new file mode 100644 index 000000000..7c9ce0a69 --- /dev/null +++ b/flux/src/test/java/com/iluwatar/flux/store/ContentStoreTest.java @@ -0,0 +1,47 @@ +package com.iluwatar.flux.store; + +import com.iluwatar.flux.action.Content; +import com.iluwatar.flux.action.ContentAction; +import com.iluwatar.flux.action.MenuAction; +import com.iluwatar.flux.action.MenuItem; +import com.iluwatar.flux.view.View; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Date: 12/12/15 - 10:18 PM + * + * @author Jeroen Meulemeester + */ +public class ContentStoreTest { + + @Test + public void testOnAction() throws Exception { + final ContentStore contentStore = new ContentStore(); + + final View view = mock(View.class); + contentStore.registerView(view); + + verifyZeroInteractions(view); + + // Content should not react on menu action ... + contentStore.onAction(new MenuAction(MenuItem.PRODUCTS)); + verifyZeroInteractions(view); + + // ... but it should react on a content action + contentStore.onAction(new ContentAction(Content.COMPANY)); + verify(view, times(1)).storeChanged(eq(contentStore)); + verifyNoMoreInteractions(view); + assertEquals(Content.COMPANY, contentStore.getContent()); + + } + +} diff --git a/flux/src/test/java/com/iluwatar/flux/store/MenuStoreTest.java b/flux/src/test/java/com/iluwatar/flux/store/MenuStoreTest.java new file mode 100644 index 000000000..2e7f80590 --- /dev/null +++ b/flux/src/test/java/com/iluwatar/flux/store/MenuStoreTest.java @@ -0,0 +1,47 @@ +package com.iluwatar.flux.store; + +import com.iluwatar.flux.action.Content; +import com.iluwatar.flux.action.ContentAction; +import com.iluwatar.flux.action.MenuAction; +import com.iluwatar.flux.action.MenuItem; +import com.iluwatar.flux.view.View; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Date: 12/12/15 - 10:18 PM + * + * @author Jeroen Meulemeester + */ +public class MenuStoreTest { + + @Test + public void testOnAction() throws Exception { + final MenuStore menuStore = new MenuStore(); + + final View view = mock(View.class); + menuStore.registerView(view); + + verifyZeroInteractions(view); + + // Menu should not react on content action ... + menuStore.onAction(new ContentAction(Content.COMPANY)); + verifyZeroInteractions(view); + + // ... but it should react on a menu action + menuStore.onAction(new MenuAction(MenuItem.PRODUCTS)); + verify(view, times(1)).storeChanged(eq(menuStore)); + verifyNoMoreInteractions(view); + assertEquals(MenuItem.PRODUCTS, menuStore.getSelected()); + + } + +} diff --git a/flux/src/test/java/com/iluwatar/flux/view/ContentViewTest.java b/flux/src/test/java/com/iluwatar/flux/view/ContentViewTest.java new file mode 100644 index 000000000..49cecd24a --- /dev/null +++ b/flux/src/test/java/com/iluwatar/flux/view/ContentViewTest.java @@ -0,0 +1,33 @@ +package com.iluwatar.flux.view; + +import com.iluwatar.flux.action.Content; +import com.iluwatar.flux.store.ContentStore; + +import org.junit.Test; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +/** + * Date: 12/12/15 - 10:31 PM + * + * @author Jeroen Meulemeester + */ +public class ContentViewTest { + + @Test + public void testStoreChanged() throws Exception { + final ContentStore store = mock(ContentStore.class); + when(store.getContent()).thenReturn(Content.PRODUCTS); + + final ContentView view = new ContentView(); + view.storeChanged(store); + + verify(store, times(1)).getContent(); + verifyNoMoreInteractions(store); + } + +} diff --git a/flux/src/test/java/com/iluwatar/flux/view/MenuViewTest.java b/flux/src/test/java/com/iluwatar/flux/view/MenuViewTest.java new file mode 100644 index 000000000..2534515b0 --- /dev/null +++ b/flux/src/test/java/com/iluwatar/flux/view/MenuViewTest.java @@ -0,0 +1,50 @@ +package com.iluwatar.flux.view; + +import com.iluwatar.flux.action.Action; +import com.iluwatar.flux.action.MenuItem; +import com.iluwatar.flux.dispatcher.Dispatcher; +import com.iluwatar.flux.store.MenuStore; +import com.iluwatar.flux.store.Store; + +import org.junit.Test; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +/** + * Date: 12/12/15 - 10:31 PM + * + * @author Jeroen Meulemeester + */ +public class MenuViewTest { + + @Test + public void testStoreChanged() throws Exception { + final MenuStore store = mock(MenuStore.class); + when(store.getSelected()).thenReturn(MenuItem.HOME); + + final MenuView view = new MenuView(); + view.storeChanged(store); + + verify(store, times(1)).getSelected(); + verifyNoMoreInteractions(store); + } + + @Test + public void testItemClicked() throws Exception { + final Store store = mock(Store.class); + Dispatcher.getInstance().registerStore(store); + + final MenuView view = new MenuView(); + view.itemClicked(MenuItem.PRODUCTS); + + // We should receive a menu click action and a content changed action + verify(store, times(2)).onAction(any(Action.class)); + + } + +} From ca14e8ddad2cf84224ad740d86e1b0f34a4fc228 Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sun, 13 Dec 2015 11:42:25 +0100 Subject: [PATCH 05/10] Add proper tests for flyweight pattern --- .../com/iluwatar/flyweight/AlchemistShop.java | 19 +++++++++ .../iluwatar/flyweight/AlchemistShopTest.java | 40 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 flyweight/src/test/java/com/iluwatar/flyweight/AlchemistShopTest.java diff --git a/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java b/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java index 15206a84a..a48abbcb0 100644 --- a/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java +++ b/flyweight/src/main/java/com/iluwatar/flyweight/AlchemistShop.java @@ -1,6 +1,7 @@ package com.iluwatar.flyweight; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -39,6 +40,24 @@ public class AlchemistShop { bottomShelf.add(factory.createPotion(PotionType.HOLY_WATER)); } + /** + * Get a read-only list of all the items on the top shelf + * + * @return The top shelf potions + */ + public final List getTopShelf() { + return Collections.unmodifiableList(this.topShelf); + } + + /** + * Get a read-only list of all the items on the bottom shelf + * + * @return The bottom shelf potions + */ + public final List getBottomShelf() { + return Collections.unmodifiableList(this.bottomShelf); + } + public void enumerate() { System.out.println("Enumerating top shelf potions\n"); diff --git a/flyweight/src/test/java/com/iluwatar/flyweight/AlchemistShopTest.java b/flyweight/src/test/java/com/iluwatar/flyweight/AlchemistShopTest.java new file mode 100644 index 000000000..d99a98cf9 --- /dev/null +++ b/flyweight/src/test/java/com/iluwatar/flyweight/AlchemistShopTest.java @@ -0,0 +1,40 @@ +package com.iluwatar.flyweight; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Date: 12/12/15 - 10:54 PM + * + * @author Jeroen Meulemeester + */ +public class AlchemistShopTest { + + @Test + public void testShop() throws Exception { + final AlchemistShop shop = new AlchemistShop(); + + final List bottomShelf = shop.getBottomShelf(); + assertNotNull(bottomShelf); + assertEquals(5, bottomShelf.size()); + + final List topShelf = shop.getTopShelf(); + assertNotNull(topShelf); + assertEquals(8, topShelf.size()); + + final List allPotions = new ArrayList<>(); + allPotions.addAll(topShelf); + allPotions.addAll(bottomShelf); + + // There are 13 potion instances, but only 5 unique instance types + assertEquals(13, allPotions.size()); + assertEquals(5, allPotions.stream().map(System::identityHashCode).distinct().count()); + + } + +} From dbca06a9e7bdcddafbc842ddef3f2b0b9b760b59 Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sun, 13 Dec 2015 12:55:13 +0100 Subject: [PATCH 06/10] Added proper tests for half-sync-half-async --- half-sync-half-async/pom.xml | 5 ++ .../AsynchronousService.java | 1 + .../AsynchronousServiceTest.java | 79 +++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 half-sync-half-async/src/test/java/com/iluwatar/halfsynchalfasync/AsynchronousServiceTest.java diff --git a/half-sync-half-async/pom.xml b/half-sync-half-async/pom.xml index 2490e9214..ce8689cee 100644 --- a/half-sync-half-async/pom.xml +++ b/half-sync-half-async/pom.xml @@ -14,5 +14,10 @@ junit test + + org.mockito + mockito-core + test + diff --git a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java index 457dffa20..3be340c02 100644 --- a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java +++ b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java @@ -50,6 +50,7 @@ public class AsynchronousService { task.onPreCall(); } catch (Exception e) { task.onError(e); + return; } service.submit(new FutureTask(task) { diff --git a/half-sync-half-async/src/test/java/com/iluwatar/halfsynchalfasync/AsynchronousServiceTest.java b/half-sync-half-async/src/test/java/com/iluwatar/halfsynchalfasync/AsynchronousServiceTest.java new file mode 100644 index 000000000..01c905039 --- /dev/null +++ b/half-sync-half-async/src/test/java/com/iluwatar/halfsynchalfasync/AsynchronousServiceTest.java @@ -0,0 +1,79 @@ +package com.iluwatar.halfsynchalfasync; + +import org.junit.Test; +import org.mockito.InOrder; + +import java.io.IOException; +import java.util.concurrent.LinkedBlockingQueue; + +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +/** + * Date: 12/12/15 - 11:15 PM + * + * @author Jeroen Meulemeester + */ +public class AsynchronousServiceTest { + + @Test + public void testPerfectExecution() throws Exception { + final AsynchronousService service = new AsynchronousService(new LinkedBlockingQueue<>()); + final AsyncTask task = mock(AsyncTask.class); + final Object result = new Object(); + when(task.call()).thenReturn(result); + service.execute(task); + + verify(task, timeout(2000)).onPostCall(eq(result)); + + final InOrder inOrder = inOrder(task); + inOrder.verify(task, times(1)).onPreCall(); + inOrder.verify(task, times(1)).call(); + inOrder.verify(task, times(1)).onPostCall(eq(result)); + + verifyNoMoreInteractions(task); + } + + @Test + public void testCallException() throws Exception { + final AsynchronousService service = new AsynchronousService(new LinkedBlockingQueue<>()); + final AsyncTask task = mock(AsyncTask.class); + final IOException exception = new IOException(); + when(task.call()).thenThrow(exception); + service.execute(task); + + verify(task, timeout(2000)).onError(eq(exception)); + + final InOrder inOrder = inOrder(task); + inOrder.verify(task, times(1)).onPreCall(); + inOrder.verify(task, times(1)).call(); + inOrder.verify(task, times(1)).onError(exception); + + verifyNoMoreInteractions(task); + } + + @Test + public void testPreCallException() throws Exception { + final AsynchronousService service = new AsynchronousService(new LinkedBlockingQueue<>()); + final AsyncTask task = mock(AsyncTask.class); + final IllegalStateException exception = new IllegalStateException(); + doThrow(exception).when(task).onPreCall(); + service.execute(task); + + verify(task, timeout(2000)).onError(eq(exception)); + + final InOrder inOrder = inOrder(task); + inOrder.verify(task, times(1)).onPreCall(); + inOrder.verify(task, times(1)).onError(exception); + + verifyNoMoreInteractions(task); + } + +} \ No newline at end of file From 9059d2b96cff7bf39ac5aa8afca47a3f83abff9d Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sun, 13 Dec 2015 13:58:39 +0100 Subject: [PATCH 07/10] Added proper tests for front-controller pattern --- front-controller/pom.xml | 5 ++ .../controller/ApplicationExceptionTest.java | 20 ++++++ .../front/controller/CommandTest.java | 62 +++++++++++++++++++ .../front/controller/FrontControllerTest.java | 61 ++++++++++++++++++ .../iluwatar/front/controller/StdOutTest.java | 54 ++++++++++++++++ .../iluwatar/front/controller/ViewTest.java | 61 ++++++++++++++++++ 6 files changed, 263 insertions(+) create mode 100644 front-controller/src/test/java/com/iluwatar/front/controller/ApplicationExceptionTest.java create mode 100644 front-controller/src/test/java/com/iluwatar/front/controller/CommandTest.java create mode 100644 front-controller/src/test/java/com/iluwatar/front/controller/FrontControllerTest.java create mode 100644 front-controller/src/test/java/com/iluwatar/front/controller/StdOutTest.java create mode 100644 front-controller/src/test/java/com/iluwatar/front/controller/ViewTest.java diff --git a/front-controller/pom.xml b/front-controller/pom.xml index 33a30c258..91ad6c1ab 100644 --- a/front-controller/pom.xml +++ b/front-controller/pom.xml @@ -15,5 +15,10 @@ junit test + + org.mockito + mockito-core + test + diff --git a/front-controller/src/test/java/com/iluwatar/front/controller/ApplicationExceptionTest.java b/front-controller/src/test/java/com/iluwatar/front/controller/ApplicationExceptionTest.java new file mode 100644 index 000000000..18bdf0d13 --- /dev/null +++ b/front-controller/src/test/java/com/iluwatar/front/controller/ApplicationExceptionTest.java @@ -0,0 +1,20 @@ +package com.iluwatar.front.controller; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Date: 12/13/15 - 1:35 PM + * + * @author Jeroen Meulemeester + */ +public class ApplicationExceptionTest { + + @Test + public void testCause() throws Exception { + final Exception cause = new Exception(); + assertSame(cause, new ApplicationException(cause).getCause()); + } + +} \ No newline at end of file diff --git a/front-controller/src/test/java/com/iluwatar/front/controller/CommandTest.java b/front-controller/src/test/java/com/iluwatar/front/controller/CommandTest.java new file mode 100644 index 000000000..fa85caa39 --- /dev/null +++ b/front-controller/src/test/java/com/iluwatar/front/controller/CommandTest.java @@ -0,0 +1,62 @@ +package com.iluwatar.front.controller; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Date: 12/13/15 - 1:39 PM + * + * @author Jeroen Meulemeester + */ +@RunWith(Parameterized.class) +public class CommandTest extends StdOutTest { + + @Parameters + public static List data() { + final List parameters = new ArrayList<>(); + parameters.add(new Object[]{"Archer", "Displaying archers"}); + parameters.add(new Object[]{"Catapult", "Displaying catapults"}); + parameters.add(new Object[]{"NonExistentCommand", "Error 500"}); + return parameters; + } + + /** + * The view that's been tested + */ + private final String request; + + /** + * The expected display message + */ + private final String displayMessage; + + /** + * Create a new instance of the {@link CommandTest} with the given view and expected message + * + * @param request The request that's been tested + * @param displayMessage The expected display message + */ + public CommandTest(final String request, final String displayMessage) { + this.displayMessage = displayMessage; + this.request = request; + } + + @Test + public void testDisplay() { + final FrontController frontController = new FrontController(); + verifyZeroInteractions(getStdOutMock()); + frontController.handleRequest(request); + verify(getStdOutMock()).println(displayMessage); + verifyNoMoreInteractions(getStdOutMock()); + } + +} diff --git a/front-controller/src/test/java/com/iluwatar/front/controller/FrontControllerTest.java b/front-controller/src/test/java/com/iluwatar/front/controller/FrontControllerTest.java new file mode 100644 index 000000000..9bc4253c0 --- /dev/null +++ b/front-controller/src/test/java/com/iluwatar/front/controller/FrontControllerTest.java @@ -0,0 +1,61 @@ +package com.iluwatar.front.controller; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Date: 12/13/15 - 1:39 PM + * + * @author Jeroen Meulemeester + */ +@RunWith(Parameterized.class) +public class FrontControllerTest extends StdOutTest { + + @Parameters + public static List data() { + final List parameters = new ArrayList<>(); + parameters.add(new Object[]{new ArcherCommand(), "Displaying archers"}); + parameters.add(new Object[]{new CatapultCommand(), "Displaying catapults"}); + parameters.add(new Object[]{new UnknownCommand(), "Error 500"}); + return parameters; + } + + /** + * The view that's been tested + */ + private final Command command; + + /** + * The expected display message + */ + private final String displayMessage; + + /** + * Create a new instance of the {@link FrontControllerTest} with the given view and expected message + * + * @param command The command that's been tested + * @param displayMessage The expected display message + */ + public FrontControllerTest(final Command command, final String displayMessage) { + this.displayMessage = displayMessage; + this.command = command; + } + + @Test + public void testDisplay() { + verifyZeroInteractions(getStdOutMock()); + this.command.process(); + verify(getStdOutMock()).println(displayMessage); + verifyNoMoreInteractions(getStdOutMock()); + } + +} diff --git a/front-controller/src/test/java/com/iluwatar/front/controller/StdOutTest.java b/front-controller/src/test/java/com/iluwatar/front/controller/StdOutTest.java new file mode 100644 index 000000000..31d061b08 --- /dev/null +++ b/front-controller/src/test/java/com/iluwatar/front/controller/StdOutTest.java @@ -0,0 +1,54 @@ +package com.iluwatar.front.controller; + +import org.junit.After; +import org.junit.Before; + +import java.io.PrintStream; + +import static org.mockito.Mockito.mock; + +/** + * Date: 12/10/15 - 8:37 PM + * + * @author Jeroen Meulemeester + */ +public abstract class StdOutTest { + + /** + * The mocked standard out {@link PrintStream}, required since the actions of the views don't have + * any influence on any other accessible objects, except for writing to std-out using {@link + * System#out} + */ + private final PrintStream stdOutMock = mock(PrintStream.class); + + /** + * Keep the original std-out so it can be restored after the test + */ + private final PrintStream stdOutOrig = System.out; + + /** + * Inject the mocked std-out {@link PrintStream} into the {@link System} class before each test + */ + @Before + public void setUp() { + System.setOut(this.stdOutMock); + } + + /** + * Removed the mocked std-out {@link PrintStream} again from the {@link System} class + */ + @After + public void tearDown() { + System.setOut(this.stdOutOrig); + } + + /** + * Get the mocked stdOut {@link PrintStream} + * + * @return The stdOut print stream mock, renewed before each test + */ + final PrintStream getStdOutMock() { + return this.stdOutMock; + } + +} diff --git a/front-controller/src/test/java/com/iluwatar/front/controller/ViewTest.java b/front-controller/src/test/java/com/iluwatar/front/controller/ViewTest.java new file mode 100644 index 000000000..fb2df1c60 --- /dev/null +++ b/front-controller/src/test/java/com/iluwatar/front/controller/ViewTest.java @@ -0,0 +1,61 @@ +package com.iluwatar.front.controller; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.util.ArrayList; +import java.util.List; + +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; + +/** + * Date: 12/13/15 - 1:39 PM + * + * @author Jeroen Meulemeester + */ +@RunWith(Parameterized.class) +public class ViewTest extends StdOutTest { + + @Parameters + public static List data() { + final List parameters = new ArrayList<>(); + parameters.add(new Object[]{new ArcherView(), "Displaying archers"}); + parameters.add(new Object[]{new CatapultView(), "Displaying catapults"}); + parameters.add(new Object[]{new ErrorView(), "Error 500"}); + return parameters; + } + + /** + * The view that's been tested + */ + private final View view; + + /** + * The expected display message + */ + private final String displayMessage; + + /** + * Create a new instance of the {@link ViewTest} with the given view and expected message + * + * @param view The view that's been tested + * @param displayMessage The expected display message + */ + public ViewTest(final View view, final String displayMessage) { + this.displayMessage = displayMessage; + this.view = view; + } + + @Test + public void testDisplay() { + verifyZeroInteractions(getStdOutMock()); + this.view.display(); + verify(getStdOutMock()).println(displayMessage); + verifyNoMoreInteractions(getStdOutMock()); + } + +} \ No newline at end of file From de78490d29879936dea373087a5cf400158db830 Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Sun, 13 Dec 2015 15:18:13 +0100 Subject: [PATCH 08/10] Added tests for intercepting-filter pattern --- intercepting-filter/pom.xml | 5 + .../intercepting/filter/NameFilter.java | 2 +- .../filter/FilterManagerTest.java | 46 +++++++++ .../intercepting/filter/FilterTest.java | 95 +++++++++++++++++++ .../intercepting/filter/OrderTest.java | 51 ++++++++++ 5 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/FilterManagerTest.java create mode 100644 intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/FilterTest.java create mode 100644 intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/OrderTest.java diff --git a/intercepting-filter/pom.xml b/intercepting-filter/pom.xml index c69f40ee5..2c10af5d0 100644 --- a/intercepting-filter/pom.xml +++ b/intercepting-filter/pom.xml @@ -14,5 +14,10 @@ junit test + + org.mockito + mockito-core + test + diff --git a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/NameFilter.java b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/NameFilter.java index a458e475b..2f431caad 100644 --- a/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/NameFilter.java +++ b/intercepting-filter/src/main/java/com/iluwatar/intercepting/filter/NameFilter.java @@ -14,7 +14,7 @@ public class NameFilter extends AbstractFilter { String result = super.execute(order); if (order.getName() == null || order.getName().isEmpty() || order.getName().matches(".*[^\\w|\\s]+.*")) { - return result + "Invalid order! "; + return result + "Invalid name! "; } else { return result; } diff --git a/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/FilterManagerTest.java b/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/FilterManagerTest.java new file mode 100644 index 000000000..6806cd70a --- /dev/null +++ b/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/FilterManagerTest.java @@ -0,0 +1,46 @@ +package com.iluwatar.intercepting.filter; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +/** + * Date: 12/13/15 - 3:01 PM + * + * @author Jeroen Meulemeester + */ +public class FilterManagerTest { + + @Test + public void testFilterRequest() throws Exception { + final Target target = mock(Target.class); + final FilterManager filterManager = new FilterManager(target); + assertEquals("RUNNING...", filterManager.filterRequest(mock(Order.class))); + verifyZeroInteractions(target); + } + + @Test + public void testAddFilter() throws Exception { + final Target target = mock(Target.class); + final FilterManager filterManager = new FilterManager(target); + + verifyZeroInteractions(target); + + final Filter filter = mock(Filter.class); + when(filter.execute(any(Order.class))).thenReturn("filter"); + + filterManager.addFilter(filter); + + final Order order = mock(Order.class); + assertEquals("filter", filterManager.filterRequest(order)); + + verify(filter, times(1)).execute(any(Order.class)); + verifyZeroInteractions(target, filter, order); + } +} \ No newline at end of file diff --git a/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/FilterTest.java b/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/FilterTest.java new file mode 100644 index 000000000..f15760f08 --- /dev/null +++ b/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/FilterTest.java @@ -0,0 +1,95 @@ +package com.iluwatar.intercepting.filter; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.util.ArrayList; +import java.util.List; + +import static junit.framework.TestCase.assertSame; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +/** + * Date: 12/13/15 - 2:17 PM + * + * @author Jeroen Meulemeester + */ +@RunWith(Parameterized.class) +public class FilterTest { + + private static final Order PERFECT_ORDER = new Order("name", "12345678901", "addr", "dep", "order"); + private static final Order WRONG_ORDER = new Order("name", "12345678901", "addr", "dep", ""); + private static final Order WRONG_DEPOSIT = new Order("name", "12345678901", "addr", "", "order"); + private static final Order WRONG_ADDRESS = new Order("name", "12345678901", "", "dep", "order"); + private static final Order WRONG_CONTACT = new Order("name", "", "addr", "dep", "order"); + private static final Order WRONG_NAME = new Order("", "12345678901", "addr", "dep", "order"); + + @Parameters + public static List getTestData() { + final List testData = new ArrayList<>(); + testData.add(new Object[]{new NameFilter(), PERFECT_ORDER, ""}); + testData.add(new Object[]{new NameFilter(), WRONG_NAME, "Invalid name!"}); + testData.add(new Object[]{new NameFilter(), WRONG_CONTACT, ""}); + testData.add(new Object[]{new NameFilter(), WRONG_ADDRESS, ""}); + testData.add(new Object[]{new NameFilter(), WRONG_DEPOSIT, ""}); + testData.add(new Object[]{new NameFilter(), WRONG_ORDER, ""}); + + testData.add(new Object[]{new ContactFilter(), PERFECT_ORDER, ""}); + testData.add(new Object[]{new ContactFilter(), WRONG_NAME, ""}); + testData.add(new Object[]{new ContactFilter(), WRONG_CONTACT, "Invalid contact number!"}); + testData.add(new Object[]{new ContactFilter(), WRONG_ADDRESS, ""}); + testData.add(new Object[]{new ContactFilter(), WRONG_DEPOSIT, ""}); + testData.add(new Object[]{new ContactFilter(), WRONG_ORDER, ""}); + + testData.add(new Object[]{new AddressFilter(), PERFECT_ORDER, ""}); + testData.add(new Object[]{new AddressFilter(), WRONG_NAME, ""}); + testData.add(new Object[]{new AddressFilter(), WRONG_CONTACT, ""}); + testData.add(new Object[]{new AddressFilter(), WRONG_ADDRESS, "Invalid address!"}); + testData.add(new Object[]{new AddressFilter(), WRONG_DEPOSIT, ""}); + testData.add(new Object[]{new AddressFilter(), WRONG_ORDER, ""}); + + testData.add(new Object[]{new DepositFilter(), PERFECT_ORDER, ""}); + testData.add(new Object[]{new DepositFilter(), WRONG_NAME, ""}); + testData.add(new Object[]{new DepositFilter(), WRONG_CONTACT, ""}); + testData.add(new Object[]{new DepositFilter(), WRONG_ADDRESS, ""}); + testData.add(new Object[]{new DepositFilter(), WRONG_DEPOSIT, "Invalid deposit number!"}); + testData.add(new Object[]{new DepositFilter(), WRONG_ORDER, ""}); + + testData.add(new Object[]{new OrderFilter(), PERFECT_ORDER, ""}); + testData.add(new Object[]{new OrderFilter(), WRONG_NAME, ""}); + testData.add(new Object[]{new OrderFilter(), WRONG_CONTACT, ""}); + testData.add(new Object[]{new OrderFilter(), WRONG_ADDRESS, ""}); + testData.add(new Object[]{new OrderFilter(), WRONG_DEPOSIT, ""}); + testData.add(new Object[]{new OrderFilter(), WRONG_ORDER, "Invalid order!"}); + + return testData; + } + + private final Filter filter; + private final Order order; + private final String result; + + public FilterTest(Filter filter, Order order, String result) { + this.filter = filter; + this.order = order; + this.result = result; + } + + @Test + public void testExecute() throws Exception { + final String result = this.filter.execute(this.order); + assertNotNull(result); + assertEquals(this.result, result.trim()); + } + + @Test + public void testNext() throws Exception { + assertNull(this.filter.getNext()); + assertSame(this.filter, this.filter.getLast()); + } + +} diff --git a/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/OrderTest.java b/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/OrderTest.java new file mode 100644 index 000000000..70862ed0f --- /dev/null +++ b/intercepting-filter/src/test/java/com/iluwatar/intercepting/filter/OrderTest.java @@ -0,0 +1,51 @@ +package com.iluwatar.intercepting.filter; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Date: 12/13/15 - 2:57 PM + * + * @author Jeroen Meulemeester + */ +public class OrderTest { + + private static final String EXPECTED_VALUE = "test"; + + @Test + public void testSetName() throws Exception { + final Order order = new Order(); + order.setName(EXPECTED_VALUE); + assertEquals(EXPECTED_VALUE, order.getName()); + } + + @Test + public void testSetContactNumber() throws Exception { + final Order order = new Order(); + order.setContactNumber(EXPECTED_VALUE); + assertEquals(EXPECTED_VALUE, order.getContactNumber()); + } + + @Test + public void testSetAddress() throws Exception { + final Order order = new Order(); + order.setAddress(EXPECTED_VALUE); + assertEquals(EXPECTED_VALUE, order.getAddress()); + } + + @Test + public void testSetDepositNumber() throws Exception { + final Order order = new Order(); + order.setDepositNumber(EXPECTED_VALUE); + assertEquals(EXPECTED_VALUE, order.getDepositNumber()); + } + + @Test + public void testSetOrder() throws Exception { + final Order order = new Order(); + order.setOrder(EXPECTED_VALUE); + assertEquals(EXPECTED_VALUE, order.getOrder()); + } + +} From 323e4c87515ddf96e36d767f530e5f1ea97818de Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Mon, 14 Dec 2015 12:46:07 +0100 Subject: [PATCH 09/10] Added tests for interpreter pattern --- .../iluwatar/interpreter/ExpressionTest.java | 111 ++++++++++++++++++ .../interpreter/MinusExpressionTest.java | 38 ++++++ .../interpreter/MultiplyExpressionTest.java | 38 ++++++ .../interpreter/NumberExpressionTest.java | 52 ++++++++ .../interpreter/PlusExpressionTest.java | 38 ++++++ 5 files changed, 277 insertions(+) create mode 100644 interpreter/src/test/java/com/iluwatar/interpreter/ExpressionTest.java create mode 100644 interpreter/src/test/java/com/iluwatar/interpreter/MinusExpressionTest.java create mode 100644 interpreter/src/test/java/com/iluwatar/interpreter/MultiplyExpressionTest.java create mode 100644 interpreter/src/test/java/com/iluwatar/interpreter/NumberExpressionTest.java create mode 100644 interpreter/src/test/java/com/iluwatar/interpreter/PlusExpressionTest.java diff --git a/interpreter/src/test/java/com/iluwatar/interpreter/ExpressionTest.java b/interpreter/src/test/java/com/iluwatar/interpreter/ExpressionTest.java new file mode 100644 index 000000000..2cdee9966 --- /dev/null +++ b/interpreter/src/test/java/com/iluwatar/interpreter/ExpressionTest.java @@ -0,0 +1,111 @@ +package com.iluwatar.interpreter; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Date: 12/14/15 - 11:48 AM + * + * @author Jeroen Meulemeester + */ +public abstract class ExpressionTest { + + /** + * Generate inputs ranging from -10 to 10 for both input params and calculate the expected result + * + * @param resultCalc The function used to calculate the expected result + * @return A data set with test entries + */ + static List prepareParameters(final BiFunction resultCalc) { + final List testData = new ArrayList<>(); + for (int i = -10; i < 10; i++) { + for (int j = -10; j < 10; j++) { + testData.add(new Object[]{ + new NumberExpression(i), + new NumberExpression(j), + resultCalc.apply(i, j) + }); + } + } + return testData; + } + + /** + * The input used as first parameter during the test + */ + private final NumberExpression first; + + /** + * The input used as second parameter during the test + */ + private final NumberExpression second; + + /** + * The expected result of the calculation, taking the first and second parameter in account + */ + private final int result; + + /** + * The expected {@link E#toString()} response + */ + private final String expectedToString; + + /** + * Factory, used to create a new test object instance with the correct first and second parameter + */ + private final BiFunction factory; + + /** + * Create a new test instance with the given parameters and expected results + * + * @param first The input used as first parameter during the test + * @param second The input used as second parameter during the test + * @param result The expected result of the tested expression + * @param expectedToString The expected {@link E#toString()} response + * @param factory Factory, used to create a new test object instance + */ + ExpressionTest(final NumberExpression first, final NumberExpression second, final int result, + final String expectedToString, final BiFunction factory) { + + this.first = first; + this.second = second; + this.result = result; + this.expectedToString = expectedToString; + this.factory = factory; + } + + /** + * Get the first parameter + * + * @return The first parameter + */ + final NumberExpression getFirst() { + return this.first; + } + + /** + * Verify if the expression calculates the correct result when calling {@link E#interpret()} + */ + @Test + public void testInterpret() { + final E expression = this.factory.apply(this.first, this.second); + assertNotNull(expression); + assertEquals(this.result, expression.interpret()); + } + + /** + * Verify if the expression has the expected {@link E#toString()} value + */ + @Test + public void testToString() { + final E expression = this.factory.apply(this.first, this.second); + assertNotNull(expression); + assertEquals(expectedToString, expression.toString()); + } +} diff --git a/interpreter/src/test/java/com/iluwatar/interpreter/MinusExpressionTest.java b/interpreter/src/test/java/com/iluwatar/interpreter/MinusExpressionTest.java new file mode 100644 index 000000000..3b6d322fe --- /dev/null +++ b/interpreter/src/test/java/com/iluwatar/interpreter/MinusExpressionTest.java @@ -0,0 +1,38 @@ +package com.iluwatar.interpreter; + +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.util.List; + +/** + * Date: 12/14/15 - 12:08 PM + * + * @author Jeroen Meulemeester + */ +@RunWith(Parameterized.class) +public class MinusExpressionTest extends ExpressionTest { + + /** + * Create a new set of test entries with the expected result + * + * @return The list of parameters used during this test + */ + @Parameters + public static List data() { + return prepareParameters((f, s) -> f - s); + } + + /** + * Create a new test instance using the given test parameters and expected result + * + * @param first The first expression parameter + * @param second The second expression parameter + * @param result The expected result + */ + public MinusExpressionTest(final NumberExpression first, final NumberExpression second, final int result) { + super(first, second, result, "-", MinusExpression::new); + } + +} \ No newline at end of file diff --git a/interpreter/src/test/java/com/iluwatar/interpreter/MultiplyExpressionTest.java b/interpreter/src/test/java/com/iluwatar/interpreter/MultiplyExpressionTest.java new file mode 100644 index 000000000..91ecdb008 --- /dev/null +++ b/interpreter/src/test/java/com/iluwatar/interpreter/MultiplyExpressionTest.java @@ -0,0 +1,38 @@ +package com.iluwatar.interpreter; + +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.util.List; + +/** + * Date: 12/14/15 - 12:08 PM + * + * @author Jeroen Meulemeester + */ +@RunWith(Parameterized.class) +public class MultiplyExpressionTest extends ExpressionTest { + + /** + * Create a new set of test entries with the expected result + * + * @return The list of parameters used during this test + */ + @Parameters + public static List data() { + return prepareParameters((f, s) -> f * s); + } + + /** + * Create a new test instance using the given test parameters and expected result + * + * @param first The first expression parameter + * @param second The second expression parameter + * @param result The expected result + */ + public MultiplyExpressionTest(final NumberExpression first, final NumberExpression second, final int result) { + super(first, second, result, "*", MultiplyExpression::new); + } + +} \ No newline at end of file diff --git a/interpreter/src/test/java/com/iluwatar/interpreter/NumberExpressionTest.java b/interpreter/src/test/java/com/iluwatar/interpreter/NumberExpressionTest.java new file mode 100644 index 000000000..2c4a35be7 --- /dev/null +++ b/interpreter/src/test/java/com/iluwatar/interpreter/NumberExpressionTest.java @@ -0,0 +1,52 @@ +package com.iluwatar.interpreter; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.util.List; + +import static org.junit.Assert.assertEquals; + +/** + * Date: 12/14/15 - 12:08 PM + * + * @author Jeroen Meulemeester + */ +@RunWith(Parameterized.class) +public class NumberExpressionTest extends ExpressionTest { + + /** + * Create a new set of test entries with the expected result + * + * @return The list of parameters used during this test + */ + @Parameters + public static List data() { + return prepareParameters((f, s) -> f); + } + + /** + * Create a new test instance using the given test parameters and expected result + * + * @param first The first expression parameter + * @param second The second expression parameter + * @param result The expected result + */ + public NumberExpressionTest(final NumberExpression first, final NumberExpression second, final int result) { + super(first, second, result, "number", (f, s) -> f); + } + + /** + * Verify if the {@link NumberExpression#NumberExpression(String)} constructor works as expected + */ + @Test + public void testFromString() throws Exception { + final int expectedValue = getFirst().interpret(); + final String testStingValue = String.valueOf(expectedValue); + final NumberExpression numberExpression = new NumberExpression(testStingValue); + assertEquals(expectedValue, numberExpression.interpret()); + } + +} \ No newline at end of file diff --git a/interpreter/src/test/java/com/iluwatar/interpreter/PlusExpressionTest.java b/interpreter/src/test/java/com/iluwatar/interpreter/PlusExpressionTest.java new file mode 100644 index 000000000..065213631 --- /dev/null +++ b/interpreter/src/test/java/com/iluwatar/interpreter/PlusExpressionTest.java @@ -0,0 +1,38 @@ +package com.iluwatar.interpreter; + +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +import java.util.List; + +/** + * Date: 12/14/15 - 12:08 PM + * + * @author Jeroen Meulemeester + */ +@RunWith(Parameterized.class) +public class PlusExpressionTest extends ExpressionTest { + + /** + * Create a new set of test entries with the expected result + * + * @return The list of parameters used during this test + */ + @Parameters + public static List data() { + return prepareParameters((f, s) -> f + s); + } + + /** + * Create a new test instance using the given test parameters and expected result + * + * @param first The first expression parameter + * @param second The second expression parameter + * @param result The expected result + */ + public PlusExpressionTest(final NumberExpression first, final NumberExpression second, final int result) { + super(first, second, result, "+", PlusExpression::new); + } + +} \ No newline at end of file From 25cacdbbc9cde921a2836ecac05996a524f14c6b Mon Sep 17 00:00:00 2001 From: Jeroen Meulemeester Date: Mon, 14 Dec 2015 15:14:48 +0100 Subject: [PATCH 10/10] Added tests for iterator pattern --- .../iluwatar/iterator/TreasureChestTest.java | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java diff --git a/iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java b/iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java new file mode 100644 index 000000000..a32066ea8 --- /dev/null +++ b/iterator/src/test/java/com/iluwatar/iterator/TreasureChestTest.java @@ -0,0 +1,108 @@ +package com.iluwatar.iterator; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +/** + * Date: 12/14/15 - 2:58 PM + * + * @author Jeroen Meulemeester + */ +@RunWith(Parameterized.class) +public class TreasureChestTest { + + /** + * Create a list of all expected items in the chest. + * + * @return The set of all expected items in the chest + */ + @Parameterized.Parameters + public static List data() { + final List parameters = new ArrayList<>(); + parameters.add(new Object[]{new Item(ItemType.POTION, "Potion of courage")}); + parameters.add(new Object[]{new Item(ItemType.RING, "Ring of shadows")}); + parameters.add(new Object[]{new Item(ItemType.POTION, "Potion of wisdom")}); + parameters.add(new Object[]{new Item(ItemType.POTION, "Potion of blood")}); + parameters.add(new Object[]{new Item(ItemType.WEAPON, "Sword of silver +1")}); + parameters.add(new Object[]{new Item(ItemType.POTION, "Potion of rust")}); + parameters.add(new Object[]{new Item(ItemType.POTION, "Potion of healing")}); + parameters.add(new Object[]{new Item(ItemType.RING, "Ring of armor")}); + parameters.add(new Object[]{new Item(ItemType.WEAPON, "Steel halberd")}); + parameters.add(new Object[]{new Item(ItemType.WEAPON, "Dagger of poison")}); + return parameters; + } + + /** + * One of the expected items in the chest + */ + private final Item expectedItem; + + /** + * Create a new test instance, test if the given expected item can be retrieved from the chest + * + * @param expectedItem One of the items that should be in the chest + */ + public TreasureChestTest(final Item expectedItem) { + this.expectedItem = expectedItem; + } + + /** + * Test if the expected item can be retrieved from the chest using the {@link ItemIterator} + */ + @Test + public void testIterator() { + final TreasureChest chest = new TreasureChest(); + final ItemIterator iterator = chest.Iterator(expectedItem.getType()); + assertNotNull(iterator); + + while (iterator.hasNext()) { + final Item item = iterator.next(); + assertNotNull(item); + assertEquals(this.expectedItem.getType(), item.getType()); + + final String name = item.toString(); + assertNotNull(name); + if (this.expectedItem.toString().equals(name)) { + return; + } + } + + fail("Expected to find item [" + this.expectedItem + "] using iterator, but we didn't."); + + } + + /** + * Test if the expected item can be retrieved from the chest using the {@link + * TreasureChest#getItems()} method + */ + @Test + public void testGetItems() throws Exception { + final TreasureChest chest = new TreasureChest(); + final List items = chest.getItems(); + assertNotNull(items); + + for (final Item item : items) { + assertNotNull(item); + assertNotNull(item.getType()); + assertNotNull(item.toString()); + + final boolean sameType = this.expectedItem.getType() == item.getType(); + final boolean sameName = this.expectedItem.toString().equals(item.toString()); + if (sameType && sameName) { + return; + } + } + + fail("Expected to find item [" + this.expectedItem + "] in the item list, but we didn't."); + + } + +} \ No newline at end of file