├── .gitattributes ├── images ├── B03130_01_07.png ├── B03130_08_05.png └── testing-with-junit-book-cover.png ├── chapter-5 ├── src │ ├── test │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── chapter_5 │ │ │ ├── Unit.java │ │ │ ├── Acceptance.java │ │ │ ├── Integration.java │ │ │ ├── FakeItems.java │ │ │ ├── UiITest.java │ │ │ ├── AllTestSuite.java │ │ │ ├── Execute.java │ │ │ ├── AllUnitTestCpSuite.java │ │ │ ├── ThrowableCaptor.java │ │ │ ├── AllUnitTestSuite.java │ │ │ ├── FakeItem.java │ │ │ ├── ExecutorSample.java │ │ │ ├── FetchItemsData.java │ │ │ ├── Listing_2_Parameterized_FetchItemsDataProvider.java │ │ │ ├── Listing_3_JUnitParams_FetchItemsDataProvider.java │ │ │ ├── FetchItemsEnum.java │ │ │ └── ItemProviderStub.java │ └── main │ │ └── java │ │ └── book │ │ └── twju │ │ └── chapter_5 │ │ ├── Item.java │ │ ├── SessionStorage.java │ │ └── ItemProvider.java ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ ├── org.moreunit.prefs │ └── org.eclipse.jdt.core.prefs ├── .project └── .classpath ├── chapter-8 ├── alltests │ ├── .settings │ │ ├── org.moreunit.prefs │ │ ├── org.eclipse.m2e.core.prefs │ │ ├── org.eclipse.core.resources.prefs │ │ └── org.eclipse.jdt.core.prefs │ ├── src │ │ └── test │ │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── alltests │ │ │ └── AllTestSuite.java │ ├── .project │ ├── pom.xml │ └── AllTestSuite.launch ├── build │ ├── .settings │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.eclipse.m2e.core.prefs │ │ └── org.eclipse.jdt.core.prefs │ ├── .classpath │ ├── .project │ └── Timeline Build All.launch ├── timeline │ ├── .settings │ │ ├── org.eclipse.m2e.core.prefs │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.moreunit.prefs │ │ └── org.eclipse.jdt.core.prefs │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── book │ │ │ │ └── twju │ │ │ │ └── timeline │ │ │ │ ├── ui │ │ │ │ ├── ItemUi.java │ │ │ │ ├── AutoUpdate.java │ │ │ │ ├── TopItemScroller.java │ │ │ │ ├── ItemUiFactory.java │ │ │ │ ├── ItemViewerCompound.java │ │ │ │ ├── FetchOperation.java │ │ │ │ └── ItemViewer.java │ │ │ │ └── model │ │ │ │ ├── SessionStorage.java │ │ │ │ ├── ItemSerialization.java │ │ │ │ └── ItemProvider.java │ │ └── test │ │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── timeline │ │ │ ├── model │ │ │ ├── FakeItem.java │ │ │ ├── FakeItemSerialization.java │ │ │ ├── CompareItemData.java │ │ │ ├── FakeItems.java │ │ │ └── MementoAssert.java │ │ │ └── ui │ │ │ ├── TestItemUiList.java │ │ │ ├── TestTopItemUpdater.java │ │ │ └── ItemViewerCompoundHelper.java │ ├── .project │ ├── .classpath │ └── pom.xml ├── timeline.swing │ ├── .settings │ │ ├── org.eclipse.m2e.core.prefs │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.moreunit.prefs │ │ └── org.eclipse.jdt.core.prefs │ ├── .project │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── book │ │ │ │ └── twju │ │ │ │ └── timeline │ │ │ │ └── swing │ │ │ │ ├── SwingUiThreadDispatcher.java │ │ │ │ ├── Resources.java │ │ │ │ └── SwingItemUi.java │ │ └── test │ │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── timeline │ │ │ └── swing │ │ │ ├── ResourcesTest.java │ │ │ ├── FrameRule.java │ │ │ ├── SwingUiThreadDispatcherITest.java │ │ │ └── SwingTimelineCompoundHelper.java │ ├── .classpath │ └── pom.xml ├── timeline.swt │ ├── .settings │ │ ├── org.eclipse.m2e.core.prefs │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.moreunit.prefs │ │ └── org.eclipse.jdt.core.prefs │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── book │ │ │ │ └── twju │ │ │ │ └── timeline │ │ │ │ └── swt │ │ │ │ ├── SwtItemUi.java │ │ │ │ ├── SwtUiThreadDispatcher.java │ │ │ │ └── Resources.java │ │ └── test │ │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── timeline │ │ │ └── swt │ │ │ ├── ShellHelper.java │ │ │ └── SwtTimelineCompoundHelper.java │ ├── .project │ ├── .classpath │ └── pom.xml ├── timeline.tabris │ ├── .settings │ │ ├── org.eclipse.m2e.core.prefs │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.moreunit.prefs │ │ └── org.eclipse.jdt.core.prefs │ ├── src │ │ └── main │ │ │ ├── java │ │ │ └── book │ │ │ │ └── twju │ │ │ │ └── timeline │ │ │ │ └── tabris │ │ │ │ └── Configuration.java │ │ │ └── webapp │ │ │ └── WEB-INF │ │ │ └── web.xml │ ├── .project │ └── .classpath ├── timeline.util │ ├── .settings │ │ ├── org.eclipse.m2e.core.prefs │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.moreunit.prefs │ │ └── org.eclipse.jdt.core.prefs │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── book │ │ │ │ └── twju │ │ │ │ └── timeline │ │ │ │ └── util │ │ │ │ ├── UiThreadDispatcher.java │ │ │ │ ├── NiceTime.java │ │ │ │ ├── Iterables.java │ │ │ │ ├── Assertion.java │ │ │ │ └── Exceptions.java │ │ └── test │ │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── timeline │ │ │ └── util │ │ │ ├── NiceTimeTest.java │ │ │ └── IterablesTest.java │ ├── .project │ ├── pom.xml │ └── .classpath ├── timeline.provider │ ├── .settings │ │ ├── org.eclipse.m2e.core.prefs │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.moreunit.prefs │ │ └── org.eclipse.jdt.core.prefs │ ├── .project │ ├── .classpath │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── book │ │ └── twju │ │ └── timeline │ │ └── provider │ │ └── git │ │ └── GitItemSerialization.java ├── timeline.test.util │ ├── .settings │ │ ├── org.eclipse.m2e.core.prefs │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.moreunit.prefs │ │ └── org.eclipse.jdt.core.prefs │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── book │ │ │ │ └── twju │ │ │ │ └── timeline │ │ │ │ └── test │ │ │ │ └── util │ │ │ │ ├── GitOperationException.java │ │ │ │ ├── NotRunningOnWindows.java │ │ │ │ ├── ThreadHelper.java │ │ │ │ ├── ThrowableCaptor.java │ │ │ │ ├── FileHelper.java │ │ │ │ └── GitRule.java │ │ └── test │ │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── timeline │ │ │ └── test │ │ │ └── util │ │ │ └── ThrowableCaptorTest.java │ ├── .project │ ├── pom.xml │ └── .classpath ├── timeline.swt.application │ ├── .settings │ │ ├── org.eclipse.m2e.core.prefs │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.moreunit.prefs │ │ └── org.eclipse.jdt.core.prefs │ ├── .project │ ├── .classpath │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── timeline │ │ │ └── swt │ │ │ └── application │ │ │ └── itemui │ │ │ └── git │ │ │ ├── GitItemUiFactory.java │ │ │ └── GitTimelineFactory.java │ ├── SWT Timeline.launch │ └── pom.xml ├── timeline.swt.test.util │ ├── .settings │ │ ├── org.eclipse.m2e.core.prefs │ │ ├── org.eclipse.core.resources.prefs │ │ ├── org.eclipse.jdt.core.prefs │ │ └── org.moreunit.prefs │ ├── .project │ ├── src │ │ └── main │ │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── timeline │ │ │ └── swt │ │ │ └── test │ │ │ └── util │ │ │ └── EventQueueHelper.java │ ├── pom.xml │ └── .classpath ├── timeline.util.test.util │ ├── .settings │ │ ├── org.eclipse.m2e.core.prefs │ │ ├── org.eclipse.core.resources.prefs │ │ └── org.eclipse.jdt.core.prefs │ ├── .project │ ├── pom.xml │ ├── .classpath │ └── src │ │ └── main │ │ └── java │ │ └── book │ │ └── twju │ │ └── timeline │ │ └── util │ │ └── test │ │ └── util │ │ └── BackgroundThreadHelper.java └── timeline.swing.application │ ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ ├── org.moreunit.prefs │ └── org.eclipse.jdt.core.prefs │ ├── .project │ ├── .classpath │ ├── Swing Timeline.launch │ ├── pom.xml │ └── src │ └── main │ └── java │ └── book │ └── twju │ └── timeline │ └── swing │ └── application │ └── itemui │ └── git │ ├── GitItemUiFactory.java │ └── GitTimelineFactory.java ├── chapter-1 ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ ├── org.moreunit.prefs │ └── org.eclipse.jdt.core.prefs ├── src │ ├── main │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── chapter_1 │ │ │ └── Timeline.java │ └── test │ │ └── java │ │ └── book │ │ └── twju │ │ └── chapter_1 │ │ └── TimelineTest.java ├── .project ├── .classpath └── pom.xml ├── chapter-2 ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ ├── org.moreunit.prefs │ └── org.eclipse.jdt.core.prefs ├── .project ├── src │ ├── test │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── chapter_2 │ │ │ ├── Listing_6_InlineTearDown_TimelineTest.java │ │ │ ├── Listing_1_PhasesComments_TimelineTest.java │ │ │ ├── Listing_2_InlineSetup_TimelineTest.java │ │ │ ├── Listing_4_ImplicitSetup_TimelineTest.java │ │ │ ├── Listing_3_DelegateSetup_TimelineTest.java │ │ │ ├── Listing_5_ImplicitTearDown_TimelineTest.java │ │ │ ├── Listing_7_BoundaryConditions_TimelineTest.java │ │ │ ├── Listing_8_BDD_Comments_TimelineTest.java │ │ │ └── TimelineTest.java │ └── main │ │ └── java │ │ └── book │ │ └── twju │ │ └── chapter_2 │ │ └── Timeline.java ├── .classpath └── pom.xml ├── chapter-3 ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ ├── org.moreunit.prefs │ └── org.eclipse.jdt.core.prefs ├── src │ ├── main │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── chapter_3 │ │ │ ├── Item.java │ │ │ ├── SessionStorage.java │ │ │ ├── ItemProvider.java │ │ │ └── SessionStorageFake.java │ └── test │ │ └── java │ │ └── book │ │ └── twju │ │ └── chapter_3 │ │ ├── FakeItem.java │ │ ├── SessionStorageSpy.java │ │ ├── ItemProviderDummy.java │ │ ├── SessionStorageMock.java │ │ ├── Listing_8_Mockito_ArgumentCapture_TimelineTest.java │ │ ├── Listing_1_Dummy_TimelineTest.java │ │ └── ItemProviderStub.java ├── .project ├── .classpath └── pom.xml ├── chapter-4 ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ ├── org.moreunit.prefs │ └── org.eclipse.jdt.core.prefs ├── src │ ├── main │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── chapter_4 │ │ │ ├── Item.java │ │ │ ├── SessionStorage.java │ │ │ └── ItemProvider.java │ └── test │ │ └── java │ │ └── book │ │ └── twju │ │ └── chapter_4 │ │ ├── ThrowableCaptor.java │ │ ├── FakeItem.java │ │ ├── Listing_2_Annotation_TimelineTest.java │ │ └── ItemProviderStub.java ├── .project ├── .classpath └── pom.xml ├── chapter-6 ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ ├── org.moreunit.prefs │ └── org.eclipse.jdt.core.prefs ├── src │ ├── main │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── chapter_6 │ │ │ ├── SessionStorage.java │ │ │ └── Memento.java │ └── test │ │ └── java │ │ └── book │ │ └── twju │ │ └── chapter_6 │ │ ├── NotRunningOnWindows.java │ │ ├── MyRuleTest.java │ │ ├── MyRule.java │ │ ├── MyRuleConfiguration.java │ │ ├── MyRuleBasedOnExternalResourceTest.java │ │ ├── MyConfigurableRule.java │ │ ├── MyConfigurableRuleTest.java │ │ ├── MyRuleBasedOnExternalResource.java │ │ ├── ThrowableCaptor.java │ │ ├── AssumptionTest.java │ │ ├── ConditionalIgnoreTest.java │ │ ├── ServerIntegrationTestSuite.java │ │ ├── MyServerTest.java │ │ ├── MyStatement.java │ │ ├── ServerRule.java │ │ ├── ClearPropertiesExample.java │ │ ├── ServerIntegrationWithRuleChainTestSuite.java │ │ ├── CaptureSystemOutputExample.java │ │ ├── ProvideSystemPropertyExample.java │ │ ├── ProvideSystemInputExample.java │ │ └── MyConfigurableStatement.java ├── .project └── .classpath ├── chapter-7 ├── .settings │ ├── org.eclipse.m2e.core.prefs │ ├── org.eclipse.core.resources.prefs │ ├── org.moreunit.prefs │ └── org.eclipse.jdt.core.prefs ├── src │ ├── main │ │ └── java │ │ │ └── book │ │ │ └── twju │ │ │ └── chapter_7 │ │ │ ├── Item.java │ │ │ ├── SessionStorage.java │ │ │ ├── ItemSerialization.java │ │ │ └── Memento.java │ └── test │ │ └── java │ │ └── book │ │ └── twju │ │ └── chapter_7 │ │ ├── FakeItemSerialization.java │ │ ├── FakeItems.java │ │ ├── Listing_4_Hamcrest_MementoMatcher_Light.java │ │ ├── Listing_5_AssertJ_ThrowableAssert_Test.java │ │ ├── Listing_2_JUnit_MementoAssert.java │ │ ├── FakeItem.java │ │ ├── Listing_4_Hamcrest_MementoMatcher.java │ │ ├── Listing_7_AssertJ_MementoAssert.java │ │ └── Listing_2_JUnit_MementoAssert_FileSessionStorageITest.java ├── .project ├── .classpath └── pom.xml ├── .gitignore └── .travis.yml /.gitattributes: -------------------------------------------------------------------------------- 1 | # Prevent git from modifying line endings at all 2 | * binary 3 | 4 | -------------------------------------------------------------------------------- /images/B03130_01_07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fappel/Testing-with-JUnit/HEAD/images/B03130_01_07.png -------------------------------------------------------------------------------- /images/B03130_08_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fappel/Testing-with-JUnit/HEAD/images/B03130_08_05.png -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/Unit.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | public interface Unit {} -------------------------------------------------------------------------------- /chapter-8/alltests/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | -------------------------------------------------------------------------------- /chapter-8/build/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding/=UTF-8 3 | -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/Acceptance.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | public interface Acceptance {} 4 | -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/Integration.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | public interface Integration {} 4 | -------------------------------------------------------------------------------- /images/testing-with-junit-book-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fappel/Testing-with-JUnit/HEAD/images/testing-with-junit-book-cover.png -------------------------------------------------------------------------------- /chapter-1/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-2/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-3/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-3/src/main/java/book/twju/chapter_3/Item.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_3; 2 | 3 | public interface Item { 4 | long getTimeStamp(); 5 | } -------------------------------------------------------------------------------- /chapter-4/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-4/src/main/java/book/twju/chapter_4/Item.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_4; 2 | 3 | public interface Item { 4 | long getTimeStamp(); 5 | } -------------------------------------------------------------------------------- /chapter-5/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-5/src/main/java/book/twju/chapter_5/Item.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | public interface Item { 4 | long getTimeStamp(); 5 | } -------------------------------------------------------------------------------- /chapter-6/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-7/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-7/src/main/java/book/twju/chapter_7/Item.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_7; 2 | 3 | public interface Item { 4 | long getTimeStamp(); 5 | } -------------------------------------------------------------------------------- /chapter-8/build/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-8/alltests/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-8/timeline/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-8/build/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.swing/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.tabris/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.util/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.provider/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt.application/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt.test.util/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.util.test.util/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.swing.application/.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /chapter-1/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-2/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-3/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-4/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-5/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-6/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-7/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-8/alltests/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-8/timeline/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-3/src/main/java/book/twju/chapter_3/SessionStorage.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_3; 2 | 3 | public interface SessionStorage { 4 | void storeTop( Item top ); 5 | Item readTop(); 6 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.tabris/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.util/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-6/src/main/java/book/twju/chapter_6/SessionStorage.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | public interface SessionStorage { 4 | void store( Memento memento ); 5 | Memento read(); 6 | } -------------------------------------------------------------------------------- /chapter-7/src/main/java/book/twju/chapter_7/SessionStorage.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_7; 2 | 3 | public interface SessionStorage { 4 | void store( Memento memento ); 5 | Memento read(); 6 | } -------------------------------------------------------------------------------- /chapter-8/timeline.provider/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt.application/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt.test.util/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.util.test.util/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.swing.application/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /chapter-8/timeline.util/src/main/java/book/twju/timeline/util/UiThreadDispatcher.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.util; 2 | 3 | public interface UiThreadDispatcher { 4 | void dispatch( Runnable runnable ); 5 | } -------------------------------------------------------------------------------- /chapter-7/src/main/java/book/twju/chapter_7/ItemSerialization.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_7; 2 | 3 | public interface ItemSerialization { 4 | String serialize( Item item ); 5 | Item deserialize( String input ); 6 | } -------------------------------------------------------------------------------- /chapter-8/timeline/src/main/java/book/twju/timeline/ui/ItemUi.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.ui; 2 | 3 | import book.twju.timeline.model.Item; 4 | 5 | public interface ItemUi { 6 | void update(); 7 | } 8 | -------------------------------------------------------------------------------- /chapter-8/timeline/src/main/java/book/twju/timeline/model/SessionStorage.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.model; 2 | 3 | public interface SessionStorage { 4 | void store( Memento Memento ); 5 | Memento read(); 6 | } -------------------------------------------------------------------------------- /chapter-8/timeline/src/main/java/book/twju/timeline/ui/AutoUpdate.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.ui; 2 | 3 | import book.twju.timeline.model.Item; 4 | 5 | public interface AutoUpdate { 6 | void start(); 7 | void stop(); 8 | } -------------------------------------------------------------------------------- /chapter-8/timeline/src/main/java/book/twju/timeline/model/ItemSerialization.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.model; 2 | 3 | public interface ItemSerialization { 4 | String serialize( T item ); 5 | T deserialize( String input ); 6 | } 7 | -------------------------------------------------------------------------------- /chapter-8/timeline/src/main/java/book/twju/timeline/ui/TopItemScroller.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.ui; 2 | 3 | import book.twju.timeline.model.Item; 4 | 5 | public interface TopItemScroller { 6 | void scrollIntoView(); 7 | } 8 | -------------------------------------------------------------------------------- /chapter-4/src/main/java/book/twju/chapter_4/SessionStorage.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_4; 2 | 3 | import java.io.IOException; 4 | 5 | public interface SessionStorage { 6 | void storeTop( Item top ) throws IOException; 7 | Item readTop() throws IOException; 8 | } -------------------------------------------------------------------------------- /chapter-5/src/main/java/book/twju/chapter_5/SessionStorage.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | import java.io.IOException; 4 | 5 | public interface SessionStorage { 6 | void storeTop( Item top ) throws IOException; 7 | Item readTop() throws IOException; 8 | } -------------------------------------------------------------------------------- /chapter-8/timeline/src/main/java/book/twju/timeline/ui/ItemUiFactory.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.ui; 2 | 3 | import book.twju.timeline.model.Item; 4 | 5 | public interface ItemUiFactory { 6 | ItemUi create( U uiContext, T item, int index ); 7 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | 14 | bin/ 15 | target/ 16 | Thumbs.db 17 | .DS_Store 18 | -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/FakeItems.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | public class FakeItems { 4 | 5 | static final FakeItem FIRST_ITEM = new FakeItem( 10 ); 6 | static final FakeItem SECOND_ITEM = new FakeItem( 20 ); 7 | static final FakeItem THIRD_ITEM = new FakeItem( 30 ); 8 | } -------------------------------------------------------------------------------- /chapter-3/src/main/java/book/twju/chapter_3/ItemProvider.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_3; 2 | 3 | import java.util.List; 4 | 5 | public interface ItemProvider { 6 | List fetchItems( Item ancestor, int itemCount ); 7 | int getNewCount( Item predecessor ); 8 | List fetchNew( Item predecessor ); 9 | } -------------------------------------------------------------------------------- /chapter-4/src/main/java/book/twju/chapter_4/ItemProvider.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_4; 2 | 3 | import java.util.List; 4 | 5 | public interface ItemProvider { 6 | List fetchItems( Item ancestor, int itemCount ); 7 | int getNewCount( Item predecessor ); 8 | List fetchNew( Item predecessor ); 9 | } -------------------------------------------------------------------------------- /chapter-5/src/main/java/book/twju/chapter_5/ItemProvider.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | import java.util.List; 4 | 5 | public interface ItemProvider { 6 | List fetchItems( Item ancestor, int itemCount ); 7 | int getNewCount( Item predecessor ); 8 | List fetchNew( Item predecessor ); 9 | } -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/UiITest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import org.junit.Test; 6 | 7 | public class UiITest { 8 | 9 | @Test 10 | public void doSomething() { 11 | assertTrue( true ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt.test.util/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 3 | org.eclipse.jdt.core.compiler.compliance=1.8 4 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 5 | org.eclipse.jdt.core.compiler.source=1.8 6 | -------------------------------------------------------------------------------- /chapter-1/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.test_methodType=testMethodTypeNoPrefix 5 | org.moreunit.unitsourcefolder=chapter-1\:src/main/java\:chapter-1\:src/test/java 6 | org.moreunit.useprojectsettings=true 7 | -------------------------------------------------------------------------------- /chapter-2/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.test_methodType=testMethodTypeNoPrefix 5 | org.moreunit.unitsourcefolder=chapter-2\:src/main/java\:chapter-2\:src/test/java 6 | org.moreunit.useprojectsettings=true 7 | -------------------------------------------------------------------------------- /chapter-3/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.test_methodType=testMethodTypeNoPrefix 5 | org.moreunit.unitsourcefolder=chapter-3\:src/main/java\:chapter-3\:src/test/java 6 | org.moreunit.useprojectsettings=true 7 | -------------------------------------------------------------------------------- /chapter-4/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.test_methodType=testMethodTypeNoPrefix 5 | org.moreunit.unitsourcefolder=chapter-4\:src/main/java\:chapter-4\:src/test/java 6 | org.moreunit.useprojectsettings=true 7 | -------------------------------------------------------------------------------- /chapter-5/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.test_methodType=testMethodTypeNoPrefix 5 | org.moreunit.unitsourcefolder=chapter-5\:src/main/java\:chapter-5\:src/test/java 6 | org.moreunit.useprojectsettings=true 7 | -------------------------------------------------------------------------------- /chapter-8/timeline/src/main/java/book/twju/timeline/model/ItemProvider.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.model; 2 | 3 | import java.util.List; 4 | 5 | public interface ItemProvider { 6 | List fetchItems( T ancestor, int fetchCount ); 7 | int getNewCount( T predecessor ); 8 | List fetchNew( T predecessor ); 9 | } -------------------------------------------------------------------------------- /chapter-6/src/main/java/book/twju/chapter_6/Memento.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | public class Memento { 4 | 5 | private String content; 6 | 7 | public Memento( String content ) { 8 | this.content = content; 9 | } 10 | 11 | @Override 12 | public String toString() { 13 | return content; 14 | } 15 | } -------------------------------------------------------------------------------- /chapter-8/timeline/src/main/java/book/twju/timeline/ui/ItemViewerCompound.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.ui; 2 | 3 | import book.twju.timeline.model.Item; 4 | 5 | public interface ItemViewerCompound { 6 | ItemUiList getItemUiList(); 7 | TopItemScroller getScroller(); 8 | TopItemUpdater getTopItemUpdater(); 9 | } -------------------------------------------------------------------------------- /chapter-1/src/main/java/book/twju/chapter_1/Timeline.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_1; 2 | 3 | public class Timeline { 4 | 5 | private int fetchCount; 6 | 7 | public void setFetchCount( int fetchCount ) { 8 | this.fetchCount = fetchCount; 9 | } 10 | 11 | public int getFetchCount() { 12 | return fetchCount; 13 | } 14 | } -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/NotRunningOnWindows.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import book.twju.chapter_6.ConditionalIgnoreRule.IgnoreCondition; 4 | 5 | class NotRunningOnWindows implements IgnoreCondition { 6 | public boolean isSatisfied() { 7 | return !System.getProperty( "os.name" ).startsWith( "Windows" ); 8 | } 9 | } -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/MyRuleTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.Rule; 4 | import org.junit.Test; 5 | 6 | public class MyRuleTest { 7 | 8 | @Rule 9 | public MyRule myRule = new MyRule(); 10 | 11 | @Test 12 | public void testRun() { 13 | System.out.println( "during" ); 14 | } 15 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swt/src/main/java/book/twju/timeline/swt/SwtItemUi.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swt; 2 | 3 | import org.eclipse.swt.widgets.Control; 4 | 5 | import book.twju.timeline.model.Item; 6 | import book.twju.timeline.ui.ItemUi; 7 | 8 | public interface SwtItemUi extends ItemUi { 9 | Control getControl(); 10 | } 11 | -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/AllTestSuite.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | import org.junit.runner.RunWith; 4 | import org.junit.runners.Suite; 5 | import org.junit.runners.Suite.SuiteClasses; 6 | 7 | @RunWith( Suite.class ) 8 | @SuiteClasses( { 9 | TimelineTest.class, 10 | UiITest.class 11 | } ) 12 | public class AllTestSuite {} -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/src/main/java/book/twju/timeline/test/util/GitOperationException.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.test.util; 2 | 3 | public class GitOperationException extends RuntimeException { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | GitOperationException( Throwable cause ) { 8 | super( cause ); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.test.test_methodDefaultContent= 3 | org.moreunit.testClassNameTemplate=${srcFile}(Test|ITest) 4 | org.moreunit.test_methodType=testMethodTypeNoPrefix 5 | org.moreunit.unitsourcefolder=timeline.swt\:src/main/java\:timeline.swt\:src/test/java 6 | org.moreunit.useprojectsettings=true 7 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt.test.util/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.test_methodType=testMethodTypeNoPrefix 5 | org.moreunit.unitsourcefolder=timeline.swt.test.util\:src/main/java\:timeline.swt.test.util\:src/test/java 6 | org.moreunit.useprojectsettings=true 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | branches: 5 | only: 6 | - master 7 | script: mvn -f chapter-8/build/pom.xml verify 8 | before_script: 9 | - "export DISPLAY=:99.0" 10 | - "sh -e /etc/init.d/xvfb start" 11 | - sleep 3 # give xvfb some time to start 12 | after_success: 13 | - mvn -f chapter-8/build/pom.xml test jacoco:report coveralls:report -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/Execute.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention( RetentionPolicy.RUNTIME ) 9 | @Target( { ElementType.METHOD } ) 10 | public @interface Execute {} -------------------------------------------------------------------------------- /chapter-6/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.testClassNameTemplate=${srcFile}(Test|ITest) 5 | org.moreunit.test_methodType=testMethodTypeNoPrefix 6 | org.moreunit.unitsourcefolder=chapter-6\:src/main/java\:chapter-6\:src/test/java 7 | org.moreunit.useprojectsettings=true 8 | -------------------------------------------------------------------------------- /chapter-7/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.testClassNameTemplate=${srcFile}(Test|ITest) 5 | org.moreunit.test_methodType=testMethodTypeNoPrefix 6 | org.moreunit.unitsourcefolder=chapter-7\:src/main/java\:chapter-7\:src/test/java 7 | org.moreunit.useprojectsettings=true 8 | -------------------------------------------------------------------------------- /chapter-8/alltests/src/test/java/book/twju/alltests/AllTestSuite.java: -------------------------------------------------------------------------------- 1 | package book.twju.alltests; 2 | 3 | import org.junit.extensions.cpsuite.ClasspathSuite; 4 | import org.junit.extensions.cpsuite.ClasspathSuite.ClassnameFilters; 5 | import org.junit.runner.RunWith; 6 | 7 | @RunWith(ClasspathSuite.class) 8 | @ClassnameFilters( { 9 | ".*Test" 10 | } ) 11 | public class AllTestSuite {} 12 | -------------------------------------------------------------------------------- /chapter-8/timeline/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.testClassNameTemplate=${srcFile}(Test|ITest) 5 | org.moreunit.test_methodType=testMethodTypeNoPrefix 6 | org.moreunit.unitsourcefolder=timeline\:src/main/java\:timeline\:src/test/java 7 | org.moreunit.useprojectsettings=true 8 | -------------------------------------------------------------------------------- /chapter-8/timeline/src/test/java/book/twju/timeline/model/FakeItem.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.model; 2 | 3 | public class FakeItem extends Item { 4 | 5 | public FakeItem( String id , long timeStamp ) { 6 | super( id, timeStamp ); 7 | } 8 | 9 | @Override 10 | public String toString() { 11 | return "FakeItem [timeStamp=" + timeStamp + ", id=" + id + "]"; 12 | } 13 | } -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/src/main/java/book/twju/timeline/test/util/NotRunningOnWindows.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.test.util; 2 | 3 | import book.twju.timeline.test.util.ConditionalIgnoreRule.IgnoreCondition; 4 | 5 | public class NotRunningOnWindows implements IgnoreCondition { 6 | public boolean isSatisfied() { 7 | return !System.getProperty( "os.name" ).startsWith( "Windows" ); 8 | } 9 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swt.application/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.test.test_methodDefaultContent= 3 | org.moreunit.testClassNameTemplate=${srcFile}(Test|ITest) 4 | org.moreunit.test_methodType=testMethodTypeNoPrefix 5 | org.moreunit.unitsourcefolder=timeline.swt.application\:src/main/java\:timeline.swt.application\:src/test/java 6 | org.moreunit.useprojectsettings=true 7 | -------------------------------------------------------------------------------- /chapter-8/timeline.util/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.testClassNameTemplate=${srcFile}(Test|ITest) 5 | org.moreunit.test_methodType=testMethodTypeNoPrefix 6 | org.moreunit.unitsourcefolder=timeline.util\:src/main/java\:timeline.util\:src/test/java 7 | org.moreunit.useprojectsettings=true 8 | -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/MyRule.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.rules.TestRule; 4 | import org.junit.runner.Description; 5 | import org.junit.runners.model.Statement; 6 | 7 | public class MyRule implements TestRule { 8 | 9 | @Override 10 | public Statement apply( Statement base, Description description ) { 11 | return new MyStatement( base ); 12 | } 13 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.testClassNameTemplate=${srcFile}(Test|ITest) 5 | org.moreunit.test_methodType=testMethodTypeNoPrefix 6 | org.moreunit.unitsourcefolder=timeline.swing\:src/main/java\:timeline.swing\:src/test/java 7 | org.moreunit.useprojectsettings=true 8 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt/src/test/java/book/twju/timeline/swt/ShellHelper.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swt; 2 | 3 | import org.eclipse.swt.layout.FillLayout; 4 | import org.eclipse.swt.widgets.Shell; 5 | 6 | class ShellHelper { 7 | 8 | static void showShell( Shell shell ) { 9 | shell.setLayout( new FillLayout() ); 10 | shell.setBounds( 100, 100, 350, 700 ); 11 | shell.open(); 12 | } 13 | } -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/src/main/java/book/twju/timeline/test/util/ThreadHelper.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.test.util; 2 | 3 | public class ThreadHelper { 4 | 5 | public static void sleep( int delay ) { 6 | try { 7 | Thread.sleep( delay + 100 ); 8 | } catch( InterruptedException shouldNotHappen ) { 9 | throw new IllegalStateException( shouldNotHappen ); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/AllUnitTestCpSuite.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | import org.junit.extensions.cpsuite.ClasspathSuite; 4 | import org.junit.extensions.cpsuite.ClasspathSuite.ClassnameFilters; 5 | import org.junit.runner.RunWith; 6 | 7 | @RunWith(ClasspathSuite.class) 8 | @ClassnameFilters( { 9 | ".*Test", 10 | "!.*ITest", 11 | } ) 12 | public class AllUnitTestCpSuite {} 13 | -------------------------------------------------------------------------------- /chapter-8/timeline.tabris/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.testClassNameTemplate=${srcFile}(Test|ITest) 5 | org.moreunit.test_methodType=testMethodTypeNoPrefix 6 | org.moreunit.unitsourcefolder=timeline.tabris\:src/main/java\:timeline.tabris\:src/test/java 7 | org.moreunit.useprojectsettings=true 8 | -------------------------------------------------------------------------------- /chapter-8/timeline.provider/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.testClassNameTemplate=${srcFile}(Test|ITest) 5 | org.moreunit.test_methodType=testMethodTypeNoPrefix 6 | org.moreunit.unitsourcefolder=timeline.provider\:src/main/java\:timeline.provider\:src/test/java 7 | org.moreunit.useprojectsettings=true 8 | -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.testClassNameTemplate=${srcFile}(Test|ITest) 5 | org.moreunit.test_methodType=testMethodTypeNoPrefix 6 | org.moreunit.unitsourcefolder=timeline.test.util\:src/main/java\:timeline.test.util\:src/test/java 7 | org.moreunit.useprojectsettings=true 8 | -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/MyRuleConfiguration.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target({ElementType.METHOD}) 10 | public @interface MyRuleConfiguration { 11 | String value() default ""; 12 | } -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/MyRuleBasedOnExternalResourceTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.Rule; 4 | import org.junit.Test; 5 | 6 | public class MyRuleBasedOnExternalResourceTest { 7 | 8 | @Rule 9 | public MyRuleBasedOnExternalResource myRule = new MyRuleBasedOnExternalResource(); 10 | 11 | @Test 12 | public void testRun() { 13 | System.out.println( "during" ); 14 | } 15 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing.application/.settings/org.moreunit.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.moreunit.preferences.version=2 3 | org.moreunit.test.test_methodDefaultContent= 4 | org.moreunit.testClassNameTemplate=${srcFile}(Test|ITest) 5 | org.moreunit.test_methodType=testMethodTypeNoPrefix 6 | org.moreunit.unitsourcefolder=timeline.swing.application\:src/main/java\:timeline.swing.application\:src/test/java 7 | org.moreunit.useprojectsettings=true 8 | -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/MyConfigurableRule.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.rules.TestRule; 4 | import org.junit.runner.Description; 5 | import org.junit.runners.model.Statement; 6 | 7 | public class MyConfigurableRule implements TestRule { 8 | 9 | @Override 10 | public Statement apply( Statement base, Description description ) { 11 | return new MyConfigurableStatement( base, description ); 12 | } 13 | } -------------------------------------------------------------------------------- /chapter-4/src/test/java/book/twju/chapter_4/ThrowableCaptor.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_4; 2 | 3 | public class ThrowableCaptor { 4 | 5 | @FunctionalInterface 6 | public interface Actor { 7 | void act() throws Throwable; 8 | } 9 | 10 | public static Throwable thrownBy( Actor actor ) { 11 | try { 12 | actor.act(); 13 | } catch( Throwable throwable ) { 14 | return throwable; 15 | } 16 | return null; 17 | } 18 | } -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/ThrowableCaptor.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | public class ThrowableCaptor { 4 | 5 | @FunctionalInterface 6 | public interface Actor { 7 | void act() throws Throwable; 8 | } 9 | 10 | public static Throwable thrownBy( Actor actor ) { 11 | try { 12 | actor.act(); 13 | } catch( Throwable throwable ) { 14 | return throwable; 15 | } 16 | return null; 17 | } 18 | } -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/MyConfigurableRuleTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.Rule; 4 | import org.junit.Test; 5 | 6 | public class MyConfigurableRuleTest { 7 | 8 | @Rule 9 | public MyConfigurableRule myConfigurableRule = new MyConfigurableRule(); 10 | 11 | @Test 12 | @MyRuleConfiguration( "myConfigurationValue" ) 13 | public void testRun() { 14 | System.out.println( "during" ); 15 | } 16 | } -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/MyRuleBasedOnExternalResource.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.rules.ExternalResource; 4 | 5 | 6 | public class MyRuleBasedOnExternalResource extends ExternalResource { 7 | 8 | @Override 9 | protected void before() { 10 | System.out.println( "before" ); 11 | } 12 | 13 | @Override 14 | protected void after() { 15 | System.out.println( "after" ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/ThrowableCaptor.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | public class ThrowableCaptor { 4 | 5 | @FunctionalInterface 6 | public interface Actor { 7 | void act() throws Throwable; 8 | } 9 | 10 | public static Throwable thrownBy( Actor actor ) { 11 | try { 12 | actor.act(); 13 | } catch( Throwable throwable ) { 14 | return throwable; 15 | } 16 | return null; 17 | } 18 | } -------------------------------------------------------------------------------- /chapter-3/src/main/java/book/twju/chapter_3/SessionStorageFake.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_3; 2 | 3 | // This fake session storage implementation is only available to avoid 4 | // compile error due to test listing evaluation and will be removed 5 | class SessionStorageFake implements SessionStorage { 6 | 7 | @Override 8 | public void storeTop( Item top ) { 9 | } 10 | 11 | @Override 12 | public Item readTop() { 13 | return null; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /chapter-1/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-2/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-3/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-4/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-5/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/AllUnitTestSuite.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | import org.junit.experimental.categories.Categories; 4 | import org.junit.experimental.categories.Categories.IncludeCategory; 5 | import org.junit.runner.RunWith; 6 | import org.junit.runners.Suite.SuiteClasses; 7 | 8 | @RunWith( Categories.class ) 9 | @IncludeCategory( Unit.class ) 10 | @SuiteClasses( { 11 | AllTestSuite.class, 12 | } ) 13 | public class AllUnitTestSuite {} -------------------------------------------------------------------------------- /chapter-6/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-7/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-3/src/test/java/book/twju/chapter_3/FakeItem.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_3; 2 | 3 | public class FakeItem implements Item { 4 | 5 | private final long timeStamp; 6 | 7 | FakeItem( long timeStamp ) { 8 | this.timeStamp = timeStamp; 9 | } 10 | 11 | @Override 12 | public long getTimeStamp() { 13 | return timeStamp; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "FakeItem [timeStamp=" + timeStamp + "]"; 19 | } 20 | } -------------------------------------------------------------------------------- /chapter-4/src/test/java/book/twju/chapter_4/FakeItem.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_4; 2 | 3 | public class FakeItem implements Item { 4 | 5 | private final long timeStamp; 6 | 7 | FakeItem( long timeStamp ) { 8 | this.timeStamp = timeStamp; 9 | } 10 | 11 | @Override 12 | public long getTimeStamp() { 13 | return timeStamp; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "FakeItem [timeStamp=" + timeStamp + "]"; 19 | } 20 | } -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/FakeItem.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | public class FakeItem implements Item { 4 | 5 | private final long timeStamp; 6 | 7 | FakeItem( long timeStamp ) { 8 | this.timeStamp = timeStamp; 9 | } 10 | 11 | @Override 12 | public long getTimeStamp() { 13 | return timeStamp; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "FakeItem [timeStamp=" + timeStamp + "]"; 19 | } 20 | } -------------------------------------------------------------------------------- /chapter-7/src/test/java/book/twju/chapter_7/FakeItemSerialization.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_7; 2 | 3 | import static java.lang.Long.parseLong; 4 | 5 | public class FakeItemSerialization implements ItemSerialization { 6 | 7 | @Override 8 | public String serialize( Item item ) { 9 | return String.valueOf( item.getTimeStamp() ); 10 | } 11 | 12 | @Override 13 | public Item deserialize( String input ) { 14 | return new FakeItem( parseLong( input ) ); 15 | } 16 | } -------------------------------------------------------------------------------- /chapter-8/alltests/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 4 | org.eclipse.jdt.core.compiler.compliance=1.5 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.5 9 | -------------------------------------------------------------------------------- /chapter-8/build/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-8/timeline/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/AssumptionTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.Assume; 4 | import org.junit.Test; 5 | 6 | public class AssumptionTest { 7 | 8 | @Test 9 | public void ignored() { 10 | Assume.assumeFalse( true ); 11 | // statements below this line are skipped 12 | } 13 | 14 | @Test 15 | public void executed() { 16 | Assume.assumeTrue( true ); 17 | // statements below this line are executed 18 | } 19 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-8/timeline.util/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-8/timeline.provider/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-8/timeline.tabris/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/src/main/java/book/twju/timeline/test/util/ThrowableCaptor.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.test.util; 2 | 3 | public class ThrowableCaptor { 4 | 5 | @FunctionalInterface 6 | public interface Actor { 7 | void act() throws Throwable; 8 | } 9 | 10 | public static Throwable thrownBy( Actor actor ) { 11 | try { 12 | actor.act(); 13 | } catch( Throwable throwable ) { 14 | return throwable; 15 | } 16 | return null; 17 | } 18 | } -------------------------------------------------------------------------------- /chapter-1/src/test/java/book/twju/chapter_1/TimelineTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_1; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | public class TimelineTest { 8 | 9 | @Test 10 | public void setFetchCount() { 11 | Timeline timeline = new Timeline(); 12 | int expected = 5; 13 | 14 | timeline.setFetchCount( expected ); 15 | int actual = timeline.getFetchCount(); 16 | 17 | assertEquals( expected, actual ); 18 | } 19 | } -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/ExecutorSample.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | import org.junit.runner.RunWith; 4 | 5 | @RunWith( Executor.class ) 6 | public class ExecutorSample { 7 | 8 | @Execute 9 | public void doIt() {} 10 | 11 | @Execute 12 | public void doItWithProblem() { 13 | throw new RuntimeException( "Bad" ); 14 | } 15 | 16 | @Execute 17 | public void doItWithFailure() { 18 | throw new AssertionError( "Invalid" ); 19 | } 20 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swt.application/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-8/timeline.util.test.util/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-8/timeline.util/src/main/java/book/twju/timeline/util/NiceTime.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.util; 2 | 3 | import java.util.Date; 4 | import java.util.Locale; 5 | 6 | import org.ocpsoft.prettytime.PrettyTime; 7 | 8 | public class NiceTime { 9 | 10 | private PrettyTime prettyTime; 11 | 12 | public NiceTime() { 13 | prettyTime = new PrettyTime( Locale.ENGLISH ); 14 | } 15 | 16 | public String format( Date then ) { 17 | return prettyTime.format( then ); 18 | } 19 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing.application/.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 4 | org.eclipse.jdt.core.compiler.compliance=1.8 5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 8 | org.eclipse.jdt.core.compiler.source=1.8 9 | -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/ConditionalIgnoreTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.Rule; 4 | import org.junit.Test; 5 | 6 | import book.twju.chapter_6.ConditionalIgnoreRule.ConditionalIgnore; 7 | 8 | public class ConditionalIgnoreTest { 9 | 10 | @Rule 11 | public ConditionalIgnoreRule rule = new ConditionalIgnoreRule(); 12 | 13 | @Test 14 | @ConditionalIgnore( condition = NotRunningOnWindows.class ) 15 | public void focus() { 16 | // ... 17 | } 18 | } -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/ServerIntegrationTestSuite.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.ClassRule; 4 | import org.junit.extensions.cpsuite.ClasspathSuite; 5 | import org.junit.extensions.cpsuite.ClasspathSuite.ClassnameFilters; 6 | import org.junit.runner.RunWith; 7 | 8 | @RunWith( ClasspathSuite.class ) 9 | @ClassnameFilters( { ".*ServerTest" } ) 10 | public class ServerIntegrationTestSuite { 11 | 12 | @ClassRule 13 | public static ServerRule serverRule = new ServerRule( 4711 ); 14 | } -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/MyServerTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.Rule; 4 | import org.junit.Test; 5 | import org.junit.rules.TestName; 6 | 7 | public class MyServerTest { 8 | 9 | @Rule 10 | public TestName name = new TestName(); 11 | 12 | @Test 13 | public void runFirstServerTest() { 14 | System.out.println( name.getMethodName() ); 15 | } 16 | 17 | @Test 18 | public void runSecondServerTest() { 19 | System.out.println( name.getMethodName() ); 20 | } 21 | } -------------------------------------------------------------------------------- /chapter-7/src/main/java/book/twju/chapter_7/Memento.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_7; 2 | 3 | import java.util.Set; 4 | 5 | public class Memento { 6 | 7 | private final Set items; 8 | private final Item topItem; 9 | 10 | public Memento( Set items, Item topItem ) { 11 | this.items = items; 12 | this.topItem = topItem; 13 | } 14 | 15 | public Set getItems() { 16 | return items; 17 | } 18 | 19 | public Item getTopItem() { 20 | return topItem; 21 | } 22 | } -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/MyStatement.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.runners.model.Statement; 4 | 5 | class MyStatement extends Statement { 6 | 7 | private final Statement base; 8 | 9 | MyStatement( Statement base ) { 10 | this.base = base; 11 | } 12 | 13 | @Override 14 | public void evaluate() throws Throwable { 15 | System.out.println( "before" ); 16 | try { 17 | base.evaluate(); 18 | } finally { 19 | System.out.println( "after" ); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/ServerRule.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.rules.ExternalResource; 4 | 5 | public class ServerRule extends ExternalResource { 6 | 7 | private final int port; 8 | 9 | public ServerRule( int port ) { 10 | this.port = port; 11 | } 12 | 13 | @Override 14 | protected void before() throws Throwable { 15 | System.out.println( "start server on port: " + port ); 16 | } 17 | 18 | @Override 19 | protected void after() { 20 | System.out.println( "stop server on port: " + port ); 21 | } 22 | } -------------------------------------------------------------------------------- /chapter-3/src/test/java/book/twju/chapter_3/SessionStorageSpy.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_3; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | class SessionStorageSpy implements SessionStorage { 7 | 8 | private final List log; 9 | 10 | SessionStorageSpy() { 11 | log = new ArrayList<>(); 12 | } 13 | 14 | @Override 15 | public void storeTop( Item top ) { 16 | log.add( top ); 17 | } 18 | 19 | public List getLog() { 20 | return log; 21 | } 22 | 23 | @Override 24 | public Item readTop() { 25 | return null; 26 | } 27 | } -------------------------------------------------------------------------------- /chapter-8/timeline.tabris/src/main/java/book/twju/timeline/tabris/Configuration.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.tabris; 2 | 3 | import static com.eclipsesource.tabris.TabrisClientInstaller.install; 4 | 5 | import org.eclipse.rap.rwt.application.Application; 6 | import org.eclipse.rap.rwt.application.ApplicationConfiguration; 7 | 8 | public class Configuration implements ApplicationConfiguration { 9 | 10 | @Override 11 | public void configure( Application application ) { 12 | install( application ); 13 | application.addEntryPoint( "/timeline", TimelineEntryPoint.class, null ); 14 | } 15 | } -------------------------------------------------------------------------------- /chapter-7/src/test/java/book/twju/chapter_7/FakeItems.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_7; 2 | 3 | import static java.util.Arrays.asList; 4 | import static java.util.Collections.unmodifiableSet; 5 | 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | 9 | public class FakeItems { 10 | 11 | static final FakeItem FIRST_ITEM = new FakeItem( 10 ); 12 | static final FakeItem SECOND_ITEM = new FakeItem( 20 ); 13 | static final FakeItem THIRD_ITEM = new FakeItem( 30 ); 14 | 15 | public static final Set ALL_ITEMS 16 | = unmodifiableSet( new HashSet( asList( FIRST_ITEM, SECOND_ITEM, THIRD_ITEM ) ) ); 17 | } -------------------------------------------------------------------------------- /chapter-7/src/test/java/book/twju/chapter_7/Listing_4_Hamcrest_MementoMatcher_Light.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_7; 2 | 3 | import static org.hamcrest.CoreMatchers.allOf; 4 | import static org.hamcrest.beans.HasPropertyWithValue.hasProperty; 5 | 6 | import org.hamcrest.CoreMatchers; 7 | import org.hamcrest.Matcher; 8 | 9 | public class Listing_4_Hamcrest_MementoMatcher_Light { 10 | 11 | public static Matcher equalTo( Memento expected ) { 12 | return allOf( 13 | hasProperty( "items", CoreMatchers.equalTo( expected.getItems() ) ), 14 | hasProperty( "topItem", CoreMatchers.equalTo( expected.getTopItem() ) ) ); 15 | } 16 | } -------------------------------------------------------------------------------- /chapter-1/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | chapter-1 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-2/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | chapter-2 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-3/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | chapter-3 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-4/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | chapter-4 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-5/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | chapter-5 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-6/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | chapter-6 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-7/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | chapter-7 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-8/build/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | build 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/ClearPropertiesExample.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import static org.junit.Assert.assertNull; 4 | 5 | import org.junit.Rule; 6 | import org.junit.Test; 7 | import org.junit.contrib.java.lang.system.ClearSystemProperties; 8 | 9 | public class ClearPropertiesExample { 10 | 11 | private static final String JAVA_IO_TMPDIR = "java.io.tmpdir"; 12 | 13 | @Rule 14 | public final ClearSystemProperties clearTempDirRule 15 | = new ClearSystemProperties( JAVA_IO_TMPDIR ); 16 | 17 | @Test 18 | public void checkTempDir() { 19 | assertNull( System.getProperty( JAVA_IO_TMPDIR ) ); 20 | } 21 | } -------------------------------------------------------------------------------- /chapter-8/alltests/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | alltests 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-8/timeline/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | timeline 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | timeline.swt 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-8/timeline.util/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | timeline.util 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-8/timeline/src/test/java/book/twju/timeline/model/FakeItemSerialization.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.model; 2 | 3 | import static java.lang.Long.parseLong; 4 | 5 | public class FakeItemSerialization implements ItemSerialization { 6 | 7 | private static final String SEPARATOR = "@"; 8 | 9 | @Override 10 | public String serialize( FakeItem item ) { 11 | return item.getId() + SEPARATOR + String.valueOf( item.getTimeStamp() ); 12 | } 13 | 14 | @Override 15 | public FakeItem deserialize( String input ) { 16 | String[] split = input.split( SEPARATOR ); 17 | return new FakeItem( split[ 0 ], parseLong( split[ 1 ] ) ); 18 | } 19 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | timeline.swing 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-8/timeline.tabris/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | timeline.tabris 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-8/timeline.provider/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | timeline.provider 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-8/timeline.swing/src/main/java/book/twju/timeline/swing/SwingUiThreadDispatcher.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swing; 2 | 3 | import static book.twju.timeline.util.Assertion.checkArgument; 4 | import static javax.swing.SwingUtilities.invokeLater; 5 | import book.twju.timeline.util.UiThreadDispatcher; 6 | 7 | public class SwingUiThreadDispatcher implements UiThreadDispatcher { 8 | 9 | static final String RUNNABLE_MUST_NOT_BE_NULL = "Argument 'runnable' must not be null."; 10 | 11 | @Override 12 | public void dispatch( Runnable runnable ) { 13 | checkArgument( runnable != null, RUNNABLE_MUST_NOT_BE_NULL ); 14 | 15 | invokeLater( runnable ); 16 | } 17 | } -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | timeline.test.util 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-2/src/test/java/book/twju/chapter_2/Listing_6_InlineTearDown_TimelineTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_2; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | public class Listing_6_InlineTearDown_TimelineTest { 8 | 9 | private final static int NEW_FETCH_COUNT 10 | = new Timeline().getFetchCount() + 1; 11 | 12 | @Test 13 | public void setFetchCount() { 14 | Timeline timeline = new Timeline(); 15 | 16 | try { 17 | timeline.setFetchCount( NEW_FETCH_COUNT ); 18 | 19 | assertEquals( NEW_FETCH_COUNT, timeline.getFetchCount() ); 20 | } finally { 21 | timeline.dispose(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/ServerIntegrationWithRuleChainTestSuite.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.ClassRule; 4 | import org.junit.extensions.cpsuite.ClasspathSuite; 5 | import org.junit.extensions.cpsuite.ClasspathSuite.ClassnameFilters; 6 | import org.junit.rules.RuleChain; 7 | import org.junit.rules.TestRule; 8 | import org.junit.runner.RunWith; 9 | 10 | @RunWith( ClasspathSuite.class ) 11 | @ClassnameFilters( { ".*ServerTest" } ) 12 | public class ServerIntegrationWithRuleChainTestSuite { 13 | 14 | @ClassRule 15 | public static TestRule chain = RuleChain 16 | .outerRule( new ServerRule( 4711 ) ) 17 | .around( new MyRule() ); 18 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swt.test.util/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | timeline.swt.test.util 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-8/timeline.util.test.util/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | timeline.util.test.util 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt.application/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | timeline.swt.application 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/CaptureSystemOutputExample.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Rule; 6 | import org.junit.Test; 7 | import org.junit.contrib.java.lang.system.SystemOutRule; 8 | 9 | public class CaptureSystemOutputExample { 10 | 11 | private static final String OUTPUT = "output"; 12 | 13 | @Rule 14 | public final SystemOutRule systemOutRule 15 | = new SystemOutRule().enableLog().muteForSuccessfulTests(); 16 | 17 | @Test 18 | public void captureSystemOutput() { 19 | System.out.print( OUTPUT ); 20 | 21 | assertEquals( OUTPUT, systemOutRule.getLog() ); 22 | } 23 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing.application/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | timeline.swing.application 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /chapter-8/timeline.swing/src/main/java/book/twju/timeline/swing/Resources.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swing; 2 | 3 | import java.awt.Color; 4 | import java.awt.Component; 5 | import java.awt.Font; 6 | 7 | public class Resources { 8 | 9 | public static final Color WHITE = new Color( 255, 255, 255 ); 10 | 11 | public static void changeFontSize( Component component, int increment ) { 12 | Font baseFont = component.getFont(); 13 | Font font = createFrom( baseFont, increment ); 14 | component.setFont( font ); 15 | } 16 | 17 | static Font createFrom( Font baseFont, int increment ) { 18 | return new Font( baseFont.getName(), baseFont.getStyle(), baseFont.getSize() + increment ); 19 | } 20 | } -------------------------------------------------------------------------------- /chapter-2/src/test/java/book/twju/chapter_2/Listing_1_PhasesComments_TimelineTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_2; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | public class Listing_1_PhasesComments_TimelineTest { 8 | 9 | private final static int NEW_FETCH_COUNT 10 | = Timeline.DEFAULT_FETCH_COUNT + 1; 11 | 12 | @Test 13 | public void setFetchCount() { 14 | // (1) setup (arrange, build) 15 | Timeline timeline = new Timeline(); 16 | 17 | // (2) exercise (act, operate) 18 | timeline.setFetchCount( NEW_FETCH_COUNT ); 19 | 20 | // (3) verify (assert, check) 21 | assertEquals( NEW_FETCH_COUNT, timeline.getFetchCount() ); 22 | } 23 | } -------------------------------------------------------------------------------- /chapter-8/timeline.util/src/main/java/book/twju/timeline/util/Iterables.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.util; 2 | 3 | import static book.twju.timeline.util.Assertion.checkArgument; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class Iterables { 9 | 10 | static final String ITERABLE_MUST_NOT_BE_NULL = "Argument 'iterable' must not be null."; 11 | 12 | public static List asList( Iterable iterable ) { 13 | checkArgument( iterable != null, ITERABLE_MUST_NOT_BE_NULL ); 14 | 15 | List result = new ArrayList<>(); 16 | for( T element : iterable ) { 17 | result.add( element ); 18 | } 19 | return result; 20 | } 21 | 22 | private Iterables() {} 23 | } -------------------------------------------------------------------------------- /chapter-3/src/test/java/book/twju/chapter_3/ItemProviderDummy.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_3; 2 | 3 | import java.util.List; 4 | 5 | public class ItemProviderDummy implements ItemProvider { 6 | 7 | private static String MESSAGE 8 | = "Dummy method must never be called."; 9 | 10 | @Override 11 | public List fetchItems( Item ancestor, int fetchCount ) { 12 | throw new UnsupportedOperationException( MESSAGE ); 13 | } 14 | 15 | @Override 16 | public int getNewCount( Item predecessor ) { 17 | throw new UnsupportedOperationException( MESSAGE ); 18 | } 19 | 20 | @Override 21 | public List fetchNew( Item predecessor ) { 22 | throw new UnsupportedOperationException( MESSAGE ); 23 | } 24 | } -------------------------------------------------------------------------------- /chapter-7/src/test/java/book/twju/chapter_7/Listing_5_AssertJ_ThrowableAssert_Test.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_7; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import org.junit.Test; 6 | 7 | public class Listing_5_AssertJ_ThrowableAssert_Test { 8 | 9 | private static final String EXPECTED_ERROR_MESSAGE = "bad"; 10 | 11 | @Test 12 | public void throwableAssertionDemo() { 13 | String description = "Expected exception does not match specification."; 14 | 15 | Throwable actual = new NullPointerException( "bad" ); 16 | 17 | assertThat( actual ) 18 | .describedAs( description ) 19 | .hasMessage( EXPECTED_ERROR_MESSAGE ) 20 | .isInstanceOf( NullPointerException.class ); 21 | } 22 | } -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/ProvideSystemPropertyExample.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Rule; 6 | import org.junit.Test; 7 | import org.junit.contrib.java.lang.system.ProvideSystemProperty; 8 | 9 | public class ProvideSystemPropertyExample { 10 | 11 | private static final String JAVA_IO_TMPDIR = "java.io.tmpdir"; 12 | private static final String MY_TMPDIR = "/path/to/my/tmpdir"; 13 | 14 | @Rule 15 | public final ProvideSystemProperty provideCustomTempDirRule 16 | = new ProvideSystemProperty( JAVA_IO_TMPDIR, MY_TMPDIR ); 17 | 18 | @Test 19 | public void checkTempDir() { 20 | assertEquals( MY_TMPDIR, System.getProperty( JAVA_IO_TMPDIR ) ); 21 | } 22 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing/src/main/java/book/twju/timeline/swing/SwingItemUi.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swing; 2 | 3 | import static java.awt.GridBagConstraints.HORIZONTAL; 4 | 5 | import java.awt.Component; 6 | import java.awt.GridBagConstraints; 7 | import java.awt.Insets; 8 | 9 | import book.twju.timeline.model.Item; 10 | import book.twju.timeline.ui.ItemUi; 11 | 12 | public interface SwingItemUi extends ItemUi { 13 | 14 | Component getComponent(); 15 | 16 | public static GridBagConstraints createUiItemConstraints() { 17 | GridBagConstraints result = new GridBagConstraints(); 18 | result.gridx = 0; 19 | result.fill = HORIZONTAL; 20 | result.weightx = 1; 21 | result.insets = new Insets( 15, 10, 5, 10 ); 22 | return result; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/src/main/java/book/twju/timeline/test/util/FileHelper.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.test.util; 2 | 3 | import java.io.File; 4 | 5 | public final class FileHelper { 6 | 7 | public static void delete( File file ) { 8 | if( file.exists() ) { 9 | deleteDirectory( file ); 10 | deleteFile( file ); 11 | } 12 | } 13 | 14 | private static void deleteDirectory( File file ) { 15 | if( file.isDirectory() ) { 16 | File[] children = file.listFiles(); 17 | for( File child : children ) { 18 | delete( child ); 19 | } 20 | } 21 | } 22 | 23 | private static void deleteFile( File file ) { 24 | if( !file.delete() ) { 25 | throw new IllegalStateException( "Unable to delete file: " + file ); 26 | } 27 | } 28 | 29 | private FileHelper() {} 30 | } -------------------------------------------------------------------------------- /chapter-2/src/test/java/book/twju/chapter_2/Listing_2_InlineSetup_TimelineTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_2; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import org.junit.Test; 7 | 8 | public class Listing_2_InlineSetup_TimelineTest { 9 | 10 | private final static int NEW_FETCH_COUNT 11 | = new Timeline().getFetchCount() + 1; 12 | 13 | @Test 14 | public void setFetchCount() { 15 | Timeline timeline = new Timeline(); 16 | 17 | timeline.setFetchCount( NEW_FETCH_COUNT ); 18 | 19 | assertEquals( NEW_FETCH_COUNT, timeline.getFetchCount() ); 20 | } 21 | 22 | @Test 23 | public void initialState() { 24 | Timeline timeline = new Timeline(); 25 | 26 | assertTrue( timeline.getFetchCount() > 0 ); 27 | } 28 | } -------------------------------------------------------------------------------- /chapter-3/src/test/java/book/twju/chapter_3/SessionStorageMock.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_3; 2 | 3 | import static org.junit.Assert.assertFalse; 4 | import static org.junit.Assert.assertSame; 5 | import static org.junit.Assert.assertTrue; 6 | 7 | class SessionStorageMock implements SessionStorage { 8 | 9 | private boolean storeTopDone; 10 | private Item expectedTopItem; 11 | 12 | @Override 13 | public void storeTop( Item top ) { 14 | assertFalse( storeTopDone ); 15 | assertSame( expectedTopItem, top ); 16 | storeTopDone = true; 17 | } 18 | 19 | void setExpectedTopItem( Item expectedTopItem ) { 20 | this.expectedTopItem = expectedTopItem; 21 | } 22 | 23 | public void verify() { 24 | assertTrue( storeTopDone ); 25 | } 26 | 27 | @Override 28 | public Item readTop() { 29 | return null; 30 | } 31 | } -------------------------------------------------------------------------------- /chapter-2/src/main/java/book/twju/chapter_2/Timeline.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_2; 2 | 3 | public class Timeline { 4 | 5 | public static final int FETCH_COUNT_LOWER_BOUND = 1; 6 | public static final int FETCH_COUNT_UPPER_BOUND = 20; 7 | 8 | static final int DEFAULT_FETCH_COUNT = 10; 9 | 10 | private int fetchCount; 11 | 12 | public Timeline() { 13 | fetchCount = DEFAULT_FETCH_COUNT; 14 | } 15 | 16 | public void setFetchCount( int fetchCount ) { 17 | if( fetchCount >= FETCH_COUNT_LOWER_BOUND 18 | && fetchCount <= FETCH_COUNT_UPPER_BOUND ) 19 | { 20 | this.fetchCount = fetchCount; 21 | } 22 | } 23 | 24 | public int getFetchCount() { 25 | return fetchCount; 26 | } 27 | 28 | public void dispose() { 29 | // Note: this method only for teardown handling demonstration and will be removed 30 | } 31 | } -------------------------------------------------------------------------------- /chapter-2/src/test/java/book/twju/chapter_2/Listing_4_ImplicitSetup_TimelineTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_2; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | public class Listing_4_ImplicitSetup_TimelineTest { 10 | 11 | private final static int NEW_FETCH_COUNT 12 | = new Timeline().getFetchCount() + 1; 13 | 14 | private Timeline timeline; 15 | 16 | @Before 17 | public void setUp() { 18 | timeline = new Timeline(); 19 | } 20 | 21 | @Test 22 | public void setFetchCount() { 23 | timeline.setFetchCount( NEW_FETCH_COUNT ); 24 | 25 | assertEquals( NEW_FETCH_COUNT, timeline.getFetchCount() ); 26 | } 27 | 28 | @Test 29 | public void initialState() { 30 | assertTrue( timeline.getFetchCount() > 0 ); 31 | } 32 | } -------------------------------------------------------------------------------- /chapter-2/src/test/java/book/twju/chapter_2/Listing_3_DelegateSetup_TimelineTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_2; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import org.junit.Test; 7 | 8 | public class Listing_3_DelegateSetup_TimelineTest { 9 | 10 | private final static int NEW_FETCH_COUNT 11 | = new Timeline().getFetchCount() + 1; 12 | 13 | @Test 14 | public void setFetchCount() { 15 | Timeline timeline = createTimeline(); 16 | 17 | timeline.setFetchCount( NEW_FETCH_COUNT ); 18 | 19 | assertEquals( NEW_FETCH_COUNT, timeline.getFetchCount() ); 20 | } 21 | 22 | @Test 23 | public void initialState() { 24 | Timeline timeline = createTimeline(); 25 | 26 | assertTrue( timeline.getFetchCount() > 0 ); 27 | } 28 | 29 | private static Timeline createTimeline() { 30 | return new Timeline(); 31 | } 32 | } -------------------------------------------------------------------------------- /chapter-7/src/test/java/book/twju/chapter_7/Listing_2_JUnit_MementoAssert.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_7; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNotSame; 5 | 6 | public class Listing_2_JUnit_MementoAssert { 7 | 8 | public static void assertEqualsButNotSame( Memento expected, Memento actual ) { 9 | assertTopItemEquals( expected, actual ); 10 | assertItemsEquals( expected, actual ); 11 | assertNotSame( "Mementos must not be the same.", expected, actual ); 12 | } 13 | 14 | public static void assertItemsEquals( Memento expected, Memento actual ) { 15 | assertEquals( "Memento items do not match\n", expected.getItems(), actual.getItems() ); 16 | } 17 | 18 | public static void assertTopItemEquals( Memento expected, Memento actual ) { 19 | assertEquals( "Memento top item does not match\n", expected.getTopItem(), actual.getTopItem() ); 20 | } 21 | } -------------------------------------------------------------------------------- /chapter-8/timeline/src/test/java/book/twju/timeline/ui/TestItemUiList.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.ui; 2 | 3 | import book.twju.timeline.model.Item; 4 | import book.twju.timeline.util.BackgroundProcessor; 5 | 6 | class TestItemUiList extends ItemUiList { 7 | 8 | private final Object content; 9 | 10 | TestItemUiList( ItemUiMap itemUiMap, BackgroundProcessor backgroundProcessor ) { 11 | super( itemUiMap, backgroundProcessor ); 12 | content = new Object(); 13 | } 14 | 15 | @Override 16 | protected void createUi( Object parent ) { 17 | } 18 | 19 | @Override 20 | protected void beforeContentUpdate() { 21 | } 22 | 23 | @Override 24 | protected void afterContentUpdate() { 25 | } 26 | 27 | @Override 28 | protected Object getContent() { 29 | return content; 30 | } 31 | 32 | @Override 33 | protected Object getUiRoot() { 34 | return null; 35 | } 36 | } -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/ProvideSystemInputExample.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.io.InputStream; 6 | import java.util.Scanner; 7 | 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | import org.junit.contrib.java.lang.system.TextFromStandardInputStream; 11 | 12 | public class ProvideSystemInputExample { 13 | 14 | private static final String INPUT = "input"; 15 | 16 | @Rule 17 | public final TextFromStandardInputStream systemInRule 18 | = TextFromStandardInputStream.emptyStandardInputStream(); 19 | 20 | @Test 21 | public void stubInput() { 22 | systemInRule.provideLines( INPUT ); 23 | 24 | assertEquals( INPUT, readLine( System.in ) ); 25 | } 26 | 27 | @SuppressWarnings("resource") 28 | private String readLine( InputStream inputstream ) { 29 | return new Scanner( inputstream ).nextLine(); 30 | } 31 | } -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/FetchItemsData.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | public class FetchItemsData { 4 | 5 | private int fetchCount; 6 | private Item[] input; 7 | private Item[] output; 8 | 9 | public static FetchItemsData newFetchItemsData() { 10 | return new FetchItemsData(); 11 | } 12 | 13 | public FetchItemsData withInput( Item ... input ) { 14 | this.input = input; 15 | return this; 16 | } 17 | 18 | public FetchItemsData withFetchCount( int fetchCount ) { 19 | this.fetchCount = fetchCount; 20 | return this; 21 | } 22 | 23 | public FetchItemsData withOutput( Item ... output ) { 24 | this.output = output; 25 | return this; 26 | } 27 | 28 | public int getFetchCount() { 29 | return fetchCount; 30 | } 31 | 32 | public Item[] getInput() { 33 | return input; 34 | } 35 | 36 | public Item[] getOutput() { 37 | return output; 38 | } 39 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swt.test.util/src/main/java/book/twju/timeline/swt/test/util/EventQueueHelper.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swt.test.util; 2 | 3 | import org.eclipse.swt.SWT; 4 | import org.eclipse.swt.widgets.Display; 5 | 6 | class EventQueueHelper { 7 | 8 | static void flushPendingEvents() { 9 | int repeat = getRepeatCount(); 10 | while( repeat > 0 ) { 11 | doFlushPendingEvents(); 12 | repeat--; 13 | } 14 | } 15 | 16 | // TODO [fappel]: Strange behaviour on cocoa. Single call to Display#readAndDispatch seems 17 | // not to be sufficient. This solution was accomplished by try and error. 18 | private static int getRepeatCount() { 19 | return "cocoa".equals( SWT.getPlatform() ) ? 3 : 1; 20 | } 21 | 22 | private static void doFlushPendingEvents() { 23 | while( Display.getCurrent() != null 24 | && !Display.getCurrent().isDisposed() 25 | && Display.getCurrent().readAndDispatch() ) {} 26 | } 27 | } -------------------------------------------------------------------------------- /chapter-8/timeline/src/main/java/book/twju/timeline/ui/FetchOperation.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.ui; 2 | 3 | import static book.twju.timeline.util.Assertion.checkArgument; 4 | import book.twju.timeline.model.Item; 5 | import book.twju.timeline.model.Timeline; 6 | 7 | public enum FetchOperation { 8 | 9 | NEW { 10 | @Override 11 | public void fetch( Timeline timeline ) { 12 | checkArgument( timeline != null, TIMELINE_MUST_NOT_BE_NULL ); 13 | 14 | timeline.fetchNew(); 15 | } 16 | }, 17 | 18 | MORE { 19 | @Override 20 | public void fetch( Timeline timeline ) { 21 | checkArgument( timeline != null, TIMELINE_MUST_NOT_BE_NULL ); 22 | 23 | timeline.fetchItems(); 24 | } 25 | }; 26 | 27 | static final String TIMELINE_MUST_NOT_BE_NULL = "Argument 'timeline' must not be null."; 28 | 29 | public abstract void fetch( Timeline timeline ); 30 | } -------------------------------------------------------------------------------- /chapter-8/alltests/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | book.twju 5 | alltests 6 | 0.0.1-SNAPSHOT 7 | 8 | alltests 9 | http://maven.apache.org 10 | 11 | 12 | UTF-8 13 | 14 | 15 | 16 | 17 | junit 18 | junit 19 | 4.12 20 | test 21 | 22 | 23 | io.takari.junit 24 | takari-cpsuite 25 | 1.2.7 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/Listing_2_Parameterized_FetchItemsDataProvider.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | public class Listing_2_Parameterized_FetchItemsDataProvider { 4 | 5 | private static final FakeItem FIRST_ITEM = new FakeItem( 10 ); 6 | private static final FakeItem SECOND_ITEM = new FakeItem( 20 ); 7 | private static final FakeItem THIRD_ITEM = new FakeItem( 30 ); 8 | 9 | static FetchItemsData fetchItemsOnLowerFetchCountBound() { 10 | return FetchItemsData.newFetchItemsData() 11 | .withInput( FIRST_ITEM, SECOND_ITEM, THIRD_ITEM ) 12 | .withFetchCount( Timeline.FETCH_COUNT_LOWER_BOUND ) 13 | .withOutput( THIRD_ITEM, SECOND_ITEM ); 14 | } 15 | 16 | static FetchItemsData fetchItemsIfFetchCountExceedsItemCount() { 17 | return FetchItemsData.newFetchItemsData() 18 | .withInput( FIRST_ITEM, SECOND_ITEM, THIRD_ITEM ) 19 | .withFetchCount( 2 ) 20 | .withOutput( THIRD_ITEM, SECOND_ITEM, FIRST_ITEM ); 21 | } 22 | } -------------------------------------------------------------------------------- /chapter-8/timeline.tabris/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | org.eclipse.rap.applicationConfiguration 9 | book.twju.timeline.tabris.Configuration 10 | 11 | 12 | 13 | org.eclipse.rap.rwt.engine.RWTServletContextListener 14 | 15 | 16 | 17 | rwtServlet 18 | org.eclipse.rap.rwt.engine.RWTServlet 19 | 20 | 21 | 22 | rwtServlet 23 | /timeline 24 | 25 | -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | timeline.test.util 5 | ${revision} 6 | 7 | 8 | book.twju 9 | build 10 | 0.0.1-SNAPSHOT 11 | ../build/pom.xml 12 | 13 | 14 | 15 | 16 | 17 | org.eclipse.jgit 18 | org.eclipse.jgit 19 | 3.7.1.201504261725-r 20 | 21 | 22 | junit 23 | junit 24 | 4.12 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-8/timeline/src/test/java/book/twju/timeline/model/CompareItemData.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.model; 2 | 3 | public enum CompareItemData { 4 | 5 | WITH_DIFFERENT_TIME_STAMP_X_TO_Y( new FakeItem( "1", 10L ), new FakeItem( "2", 20L ) ) {}, 6 | WITH_DIFFERENT_TIME_STAMP_Y_TO_Z( new FakeItem( "2", 20L ), new FakeItem( "3", 30L ) ) {}, 7 | WITH_DIFFERENT_TIME_STAMP_X_TO_Z( new FakeItem( "1", 10L ), new FakeItem( "3", 30L ) ) {}, 8 | WITH_SAME_TIME_STAMP_X_TO_Y( new FakeItem( "1", 10L ), new FakeItem( "2", 10L ) ) {}, 9 | WITH_SAME_TIME_STAMP_Y_TO_Z( new FakeItem( "2", 10L ), new FakeItem( "3", 10L ) ) {}, 10 | WITH_SAME_TIME_STAMP_X_TO_Z( new FakeItem( "1", 10L ), new FakeItem( "3", 10L ) ) {}; 11 | 12 | private final Item x; 13 | private final Item y; 14 | 15 | CompareItemData( Item x, Item y ) { 16 | this.x = x; 17 | this.y = y; 18 | } 19 | 20 | Item getX() { 21 | return x; 22 | } 23 | 24 | Item getY() { 25 | return y; 26 | } 27 | } -------------------------------------------------------------------------------- /chapter-6/src/test/java/book/twju/chapter_6/MyConfigurableStatement.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_6; 2 | 3 | import org.junit.runner.Description; 4 | import org.junit.runners.model.Statement; 5 | 6 | class MyConfigurableStatement extends Statement { 7 | 8 | private final Description description; 9 | private final Statement base; 10 | 11 | MyConfigurableStatement( Statement base, Description description ) { 12 | this.description = description; 13 | this.base = base; 14 | } 15 | 16 | @Override 17 | public void evaluate() throws Throwable { 18 | String configuration = getConfiguration(); 19 | System.out.println( "before [" + configuration + "]" ); 20 | try { 21 | base.evaluate(); 22 | } finally { 23 | System.out.println( "after [" + configuration + "]" ); 24 | } 25 | } 26 | 27 | private String getConfiguration() { 28 | return description 29 | .getAnnotation( MyRuleConfiguration.class ) 30 | .value(); 31 | } 32 | } -------------------------------------------------------------------------------- /chapter-8/timeline.util.test.util/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | timeline.util.test.util 5 | ${revision} 6 | 7 | 8 | book.twju 9 | build 10 | 0.0.1-SNAPSHOT 11 | ../build/pom.xml 12 | 13 | 14 | 15 | 16 | 17 | org.mockito 18 | mockito-all 19 | ${mockito-version} 20 | 21 | 22 | book.twju 23 | timeline.util 24 | ${revision} 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-2/src/test/java/book/twju/chapter_2/Listing_5_ImplicitTearDown_TimelineTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_2; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import org.junit.After; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | 10 | public class Listing_5_ImplicitTearDown_TimelineTest { 11 | 12 | private final static int NEW_FETCH_COUNT 13 | = new Timeline().getFetchCount() + 1; 14 | 15 | private Timeline timeline; 16 | 17 | @Before 18 | public void setUp() { 19 | timeline = new Timeline(); 20 | } 21 | 22 | @After 23 | public void tearDown() { 24 | timeline.dispose(); 25 | } 26 | 27 | @Test 28 | public void setFetchCount() { 29 | timeline.setFetchCount( NEW_FETCH_COUNT ); 30 | 31 | assertEquals( NEW_FETCH_COUNT, timeline.getFetchCount() ); 32 | } 33 | 34 | @Test 35 | public void initialState() { 36 | assertTrue( timeline.getFetchCount() > 0 ); 37 | } 38 | } -------------------------------------------------------------------------------- /chapter-2/src/test/java/book/twju/chapter_2/Listing_7_BoundaryConditions_TimelineTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_2; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | public class Listing_7_BoundaryConditions_TimelineTest { 9 | 10 | private Timeline timeline; 11 | 12 | @Before 13 | public void setUp() { 14 | timeline = new Timeline(); 15 | } 16 | 17 | @Test 18 | public void setFetchCountExceedsLowerBound() { 19 | int originalFetchCount = timeline.getFetchCount(); 20 | 21 | timeline.setFetchCount( Timeline.FETCH_COUNT_LOWER_BOUND - 1 ); 22 | 23 | assertEquals( originalFetchCount, timeline.getFetchCount() ); 24 | } 25 | 26 | @Test 27 | public void setFetchCountExceedsUpperBound() { 28 | int originalFetchCount = timeline.getFetchCount(); 29 | 30 | timeline.setFetchCount( Timeline.FETCH_COUNT_UPPER_BOUND + 1 ); 31 | 32 | assertEquals( originalFetchCount, timeline.getFetchCount() ); 33 | } 34 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swt.test.util/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | timeline.swt.test.util 5 | ${revision} 6 | 7 | 8 | book.twju 9 | swt-parent 10 | 0.0.1-SNAPSHOT 11 | ../build/swt-pom.xml 12 | 13 | 14 | 15 | 16 | 17 | junit 18 | junit 19 | ${junit-version} 20 | 21 | 22 | 23 | 24 | book.twju 25 | timeline.test.util 26 | ${revision} 27 | test 28 | 29 | 30 | -------------------------------------------------------------------------------- /chapter-8/timeline.util/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | timeline.util 5 | ${revision} 6 | 7 | 8 | book.twju 9 | build 10 | 0.0.1-SNAPSHOT 11 | ../build/pom.xml 12 | 13 | 14 | 15 | 16 | 17 | org.ocpsoft.prettytime 18 | prettytime 19 | 3.2.7.Final 20 | 21 | 22 | 23 | 24 | book.twju 25 | timeline.test.util 26 | ${revision} 27 | test 28 | 29 | 30 | -------------------------------------------------------------------------------- /chapter-8/timeline/src/test/java/book/twju/timeline/ui/TestTopItemUpdater.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.ui; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import book.twju.timeline.model.FakeItem; 7 | import book.twju.timeline.model.Timeline; 8 | 9 | class TestTopItemUpdater extends TopItemUpdater { 10 | 11 | private final List> itemsBelowTop; 12 | 13 | TestTopItemUpdater( Timeline timeline, ItemUiMap itemUiMap ) { 14 | super( timeline, itemUiMap ); 15 | itemsBelowTop = new ArrayList<>(); 16 | } 17 | 18 | public void setBelowTop( FakeItem ... itemsBelowTop ) { 19 | this.itemsBelowTop.clear(); 20 | for( FakeItem fakeItem : itemsBelowTop ) { 21 | this.itemsBelowTop.add( itemUiMap.findByItemId( fakeItem.getId() ) ); 22 | } 23 | } 24 | 25 | @Override 26 | protected void register() { 27 | } 28 | 29 | @Override 30 | protected boolean isBelowTop( ItemUi itemUi ) { 31 | return itemsBelowTop.contains( itemUi ); 32 | } 33 | } -------------------------------------------------------------------------------- /chapter-8/timeline.util/src/test/java/book/twju/timeline/util/NiceTimeTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.util; 2 | 3 | import static java.lang.System.currentTimeMillis; 4 | import static org.assertj.core.api.Assertions.assertThat; 5 | 6 | import java.util.Date; 7 | 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | 11 | public class NiceTimeTest { 12 | 13 | private NiceTime niceTime; 14 | 15 | @Before 16 | public void setUp() { 17 | niceTime = new NiceTime(); 18 | } 19 | 20 | @Test 21 | public void formatNow() { 22 | String actual = niceTime.format( now() ); 23 | 24 | assertThat( actual ).contains( "moments" ); 25 | } 26 | 27 | @Test 28 | public void formatFiveMinutesAgo() { 29 | String actual = niceTime.format( fiveMinutesAgo() ); 30 | 31 | assertThat( actual ).contains( "5 minutes ago" ); 32 | } 33 | 34 | private Date fiveMinutesAgo() { 35 | return new Date( currentTimeMillis() - 5 * 1_000 * 60 ); 36 | } 37 | 38 | private Date now() { 39 | return new Date( currentTimeMillis() ); 40 | } 41 | } -------------------------------------------------------------------------------- /chapter-8/timeline.util/src/test/java/book/twju/timeline/util/IterablesTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.util; 2 | 3 | import static book.twju.timeline.test.util.ThrowableCaptor.thrownBy; 4 | import static org.assertj.core.api.Assertions.assertThat; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | import org.junit.Test; 10 | 11 | import book.twju.timeline.util.Iterables; 12 | 13 | public class IterablesTest { 14 | 15 | @Test 16 | public void asList() { 17 | String[] expected = new String[] { "A", "B", "C" }; 18 | Iterable iterable = Arrays.asList( expected ); 19 | 20 | List actual = Iterables.asList( iterable ); 21 | 22 | assertThat( actual ) 23 | .isNotSameAs( iterable ) 24 | .containsExactly( expected ); 25 | } 26 | 27 | @Test 28 | public void asListWithNullAsIterable() { 29 | Throwable actual = thrownBy( () -> Iterables.asList( null ) ); 30 | 31 | assertThat( actual ) 32 | .hasMessage( Iterables.ITERABLE_MUST_NOT_BE_NULL ) 33 | .isInstanceOf( IllegalArgumentException.class ); 34 | } 35 | } -------------------------------------------------------------------------------- /chapter-1/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-2/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-3/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-4/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-5/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-6/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-7/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-8/timeline/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-2/src/test/java/book/twju/chapter_2/Listing_8_BDD_Comments_TimelineTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_2; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | public class Listing_8_BDD_Comments_TimelineTest { 9 | 10 | private Timeline timeline; 11 | 12 | @Before 13 | public void setUp() { 14 | timeline = new Timeline(); 15 | } 16 | 17 | @Test 18 | public void setFetchCountExceedsLowerBound() { 19 | // given 20 | int originalFetchCount = timeline.getFetchCount(); 21 | 22 | // when 23 | timeline.setFetchCount( Timeline.FETCH_COUNT_LOWER_BOUND - 1 ); 24 | 25 | // then 26 | assertEquals( originalFetchCount, timeline.getFetchCount() ); 27 | } 28 | 29 | @Test 30 | public void setFetchCountExceedsUpperBound() { 31 | // given 32 | int originalFetchCount = timeline.getFetchCount(); 33 | 34 | // when 35 | timeline.setFetchCount( Timeline.FETCH_COUNT_UPPER_BOUND + 1 ); 36 | 37 | // then 38 | assertEquals( originalFetchCount, timeline.getFetchCount() ); 39 | } 40 | } -------------------------------------------------------------------------------- /chapter-8/timeline.provider/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-8/timeline.swing/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-8/timeline.tabris/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-8/timeline.util/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt.test.util/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-7/src/test/java/book/twju/chapter_7/FakeItem.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_7; 2 | 3 | public class FakeItem implements Item { 4 | 5 | private final long timeStamp; 6 | 7 | FakeItem( long timeStamp ) { 8 | this.timeStamp = timeStamp; 9 | } 10 | 11 | @Override 12 | public long getTimeStamp() { 13 | return timeStamp; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "FakeItem [timeStamp=" + timeStamp + "]"; 19 | } 20 | 21 | @Override 22 | public int hashCode() { 23 | final int prime = 31; 24 | int result = 1; 25 | result = prime * result + ( int )( timeStamp ^ ( timeStamp >>> 32 ) ); 26 | return result; 27 | } 28 | 29 | @Override 30 | public boolean equals( Object obj ) { 31 | if( this == obj ) { 32 | return true; 33 | } 34 | if( obj == null ) { 35 | return false; 36 | } 37 | if( getClass() != obj.getClass() ) { 38 | return false; 39 | } 40 | FakeItem other = ( FakeItem )obj; 41 | if( timeStamp != other.timeStamp ) { 42 | return false; 43 | } 44 | return true; 45 | } 46 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing.application/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt.application/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-8/timeline.util.test.util/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt/src/main/java/book/twju/timeline/swt/SwtUiThreadDispatcher.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swt; 2 | 3 | import static book.twju.timeline.util.Assertion.checkArgument; 4 | 5 | import org.eclipse.swt.widgets.Display; 6 | 7 | import book.twju.timeline.util.UiThreadDispatcher; 8 | 9 | public class SwtUiThreadDispatcher implements UiThreadDispatcher { 10 | 11 | static final String RUNNABLE_MUST_NOT_BE_NULL = "Argument 'runnable' must not be null."; 12 | static final String DISPLAY_MUST_NOT_BE_NULL = "Argument 'display' must not be null."; 13 | 14 | private final Display display; 15 | 16 | 17 | public SwtUiThreadDispatcher() { 18 | this( Display.getCurrent() ); 19 | } 20 | 21 | public SwtUiThreadDispatcher( Display display ) { 22 | checkArgument( display != null, DISPLAY_MUST_NOT_BE_NULL ); 23 | 24 | this.display = display; 25 | } 26 | 27 | @Override 28 | public void dispatch( Runnable runnable ) { 29 | checkArgument( runnable != null, RUNNABLE_MUST_NOT_BE_NULL ); 30 | 31 | if( !display.isDisposed() ) { 32 | display.asyncExec( runnable ); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swt.application/src/main/java/book/twju/timeline/swt/application/itemui/git/GitItemUiFactory.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swt.application.itemui.git; 2 | 3 | import static book.twju.timeline.util.Assertion.checkArgument; 4 | 5 | import org.eclipse.swt.widgets.Composite; 6 | 7 | import book.twju.timeline.provider.git.GitItem; 8 | import book.twju.timeline.ui.ItemUi; 9 | import book.twju.timeline.ui.ItemUiFactory; 10 | 11 | public class GitItemUiFactory implements ItemUiFactory { 12 | 13 | static final String UI_CONTEXT_MUST_NOT_BE_NULL = "Argument 'uiContext' must not be null."; 14 | static final String ITEM_MUST_NOT_BE_NULL = "Argument 'item' must not be null."; 15 | static final String INDEX_MUST_NOT_BE_NEGATIVE = "Index must not be negative."; 16 | 17 | @Override 18 | public ItemUi create( Composite uiContext, GitItem item, int index ) { 19 | checkArgument( uiContext != null, UI_CONTEXT_MUST_NOT_BE_NULL ); 20 | checkArgument( item != null, ITEM_MUST_NOT_BE_NULL ); 21 | checkArgument( index >= 0 , INDEX_MUST_NOT_BE_NEGATIVE ); 22 | 23 | return new GitItemUi( uiContext, item, index ); 24 | } 25 | } -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/src/test/java/book/twju/timeline/test/util/ThrowableCaptorTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.test.util; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | import static org.mockito.Mockito.doThrow; 5 | import static org.mockito.Mockito.mock; 6 | 7 | import org.junit.Test; 8 | 9 | import book.twju.timeline.test.util.ThrowableCaptor.Actor; 10 | 11 | public class ThrowableCaptorTest { 12 | 13 | @Test 14 | public void thrownBy() throws Throwable { 15 | Throwable expected = new Throwable(); 16 | Actor actor = createActorThatThrows( expected ); 17 | 18 | Throwable actual = ThrowableCaptor.thrownBy( actor ); 19 | 20 | assertThat( actual ).isSameAs( expected ); 21 | } 22 | 23 | @Test 24 | public void thrownByIfNoThrowableOccurs() { 25 | Actor actor = mock( Actor.class ); 26 | 27 | Throwable actual = ThrowableCaptor.thrownBy( actor ); 28 | 29 | assertThat( actual ).isNull(); 30 | } 31 | 32 | private static Actor createActorThatThrows( Throwable toBeThrown ) throws Throwable { 33 | Actor result = mock( Actor.class ); 34 | doThrow( toBeThrown ).when( result ).act(); 35 | return result; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/Listing_3_JUnitParams_FetchItemsDataProvider.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | public class Listing_3_JUnitParams_FetchItemsDataProvider { 4 | 5 | private static final FakeItem FIRST_ITEM = new FakeItem( 10 ); 6 | private static final FakeItem SECOND_ITEM = new FakeItem( 20 ); 7 | private static final FakeItem THIRD_ITEM = new FakeItem( 30 ); 8 | 9 | public static Object[] provideData() { 10 | return new Object[] { 11 | fetchItemsOnLowerFetchCountBound(), 12 | fetchItemsIfFetchCountExceedsItemCount() 13 | }; 14 | } 15 | 16 | static FetchItemsData fetchItemsOnLowerFetchCountBound() { 17 | return FetchItemsData.newFetchItemsData() 18 | .withInput( FIRST_ITEM, SECOND_ITEM, THIRD_ITEM ) 19 | .withFetchCount( Timeline.FETCH_COUNT_LOWER_BOUND ) 20 | .withOutput( THIRD_ITEM, SECOND_ITEM ); 21 | } 22 | 23 | static FetchItemsData fetchItemsIfFetchCountExceedsItemCount() { 24 | return FetchItemsData.newFetchItemsData() 25 | .withInput( FIRST_ITEM, SECOND_ITEM, THIRD_ITEM ) 26 | .withFetchCount( 2 ) 27 | .withOutput( THIRD_ITEM, SECOND_ITEM, FIRST_ITEM ); 28 | } 29 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swt.application/SWT Timeline.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /chapter-8/timeline.util/src/main/java/book/twju/timeline/util/Assertion.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.util; 2 | 3 | import static java.lang.String.format; 4 | 5 | public class Assertion { 6 | 7 | static final String MESSAGE_PATTERN_MUST_NOT_BE_NULL = "Argument 'messagePattern' must not be null."; 8 | static final String ARGUMENTS_MUST_NOT_BE_NULL = "Argument 'arguments' must not be null."; 9 | 10 | public static void checkArgument( boolean condition, String messagePattern, Object ... arguments ) { 11 | if( !condition ) { 12 | throw new IllegalArgumentException( formatErrorMessage( messagePattern, arguments ) ); 13 | } 14 | } 15 | 16 | public static void checkState( boolean condition, String messagePattern, Object ... arguments) { 17 | if( !condition ) { 18 | throw new IllegalStateException( formatErrorMessage( messagePattern, arguments ) ); 19 | } 20 | } 21 | 22 | public static String formatErrorMessage( String messagePattern, Object... arguments ) { 23 | checkArgument( messagePattern != null, MESSAGE_PATTERN_MUST_NOT_BE_NULL ); 24 | checkArgument( arguments != null, ARGUMENTS_MUST_NOT_BE_NULL ); 25 | return format( messagePattern, arguments ); 26 | } 27 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing.application/Swing Timeline.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /chapter-1/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | book.twju 6 | chapter-1 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | chapter-1 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | 20 | org.apache.maven.plugins 21 | maven-compiler-plugin 22 | 3.3 23 | 24 | 1.8 25 | 1.8 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | junit 34 | junit 35 | 4.12 36 | test 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /chapter-2/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | book.twju 6 | chapter-2 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | chapter-2 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | 20 | org.apache.maven.plugins 21 | maven-compiler-plugin 22 | 3.3 23 | 24 | 1.8 25 | 1.8 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | junit 34 | junit 35 | 4.12 36 | test 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /chapter-8/timeline.provider/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | timeline.provider 5 | ${revision} 6 | 7 | 8 | book.twju 9 | build 10 | 0.0.1-SNAPSHOT 11 | ../build/pom.xml 12 | 13 | 14 | 15 | 16 | 17 | org.eclipse.jgit 18 | org.eclipse.jgit 19 | 3.7.1.201504261725-r 20 | 21 | 22 | book.twju 23 | timeline 24 | ${revision} 25 | 26 | 27 | 28 | 29 | book.twju 30 | timeline.test.util 31 | ${revision} 32 | test 33 | 34 | 35 | -------------------------------------------------------------------------------- /chapter-8/timeline.swing.application/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | timeline.swing.application 5 | ${revision} 6 | 7 | 8 | book.twju 9 | build 10 | 0.0.1-SNAPSHOT 11 | ../build/pom.xml 12 | 13 | 14 | 15 | 16 | 17 | book.twju 18 | timeline.provider 19 | ${revision} 20 | 21 | 22 | book.twju 23 | timeline.swing 24 | ${revision} 25 | 26 | 27 | 28 | 29 | book.twju 30 | timeline.test.util 31 | ${revision} 32 | test 33 | 34 | 35 | -------------------------------------------------------------------------------- /chapter-8/timeline/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | timeline 5 | ${revision} 6 | 7 | 8 | book.twju 9 | build 10 | 0.0.1-SNAPSHOT 11 | ../build/pom.xml 12 | 13 | 14 | 15 | 16 | 17 | book.twju 18 | timeline.util 19 | ${revision} 20 | 21 | 22 | 23 | 24 | book.twju 25 | timeline.test.util 26 | ${revision} 27 | test 28 | 29 | 30 | book.twju 31 | timeline.util.test.util 32 | ${revision} 33 | test 34 | 35 | 36 | -------------------------------------------------------------------------------- /chapter-8/timeline.swing/src/test/java/book/twju/timeline/swing/ResourcesTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swing; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import java.awt.Component; 6 | import java.awt.Font; 7 | 8 | import javax.swing.JLabel; 9 | 10 | import org.junit.Test; 11 | 12 | public class ResourcesTest { 13 | 14 | private static final int BASE_SIZE = 10; 15 | private static final int INCREMENT = 10; 16 | private static final String FONT_NAME = "fontName"; 17 | private static final int FONT_STYLE = Font.BOLD; 18 | 19 | @Test 20 | public void changeFontSize() { 21 | Component component = new JLabel(); 22 | Font expected = Resources.createFrom( component.getFont(), INCREMENT ); 23 | 24 | Resources.changeFontSize( component, INCREMENT ); 25 | 26 | assertThat( component.getFont() ).isEqualTo( expected ); 27 | } 28 | 29 | @Test 30 | public void createFrom() { 31 | Font base = new Font( FONT_NAME, FONT_STYLE, BASE_SIZE ); 32 | Font expected = new Font( FONT_NAME, FONT_STYLE, BASE_SIZE + INCREMENT ); 33 | 34 | Font actual = Resources.createFrom( base, INCREMENT ); 35 | 36 | assertThat( actual ).isEqualTo( expected ); 37 | } 38 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | timeline.swing 5 | ${revision} 6 | 7 | 8 | book.twju 9 | build 10 | 0.0.1-SNAPSHOT 11 | ../build/pom.xml 12 | 13 | 14 | 15 | 16 | 17 | book.twju 18 | timeline 19 | ${revision} 20 | 21 | 22 | 23 | 24 | book.twju 25 | timeline.test.util 26 | ${revision} 27 | test 28 | 29 | 30 | book.twju 31 | timeline.util.test.util 32 | ${revision} 33 | test 34 | 35 | 36 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt/src/main/java/book/twju/timeline/swt/Resources.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swt; 2 | 3 | import static java.util.Arrays.asList; 4 | 5 | import org.eclipse.swt.SWT; 6 | import org.eclipse.swt.graphics.Color; 7 | import org.eclipse.swt.graphics.Font; 8 | import org.eclipse.swt.graphics.FontData; 9 | import org.eclipse.swt.widgets.Control; 10 | import org.eclipse.swt.widgets.Display; 11 | 12 | public class Resources { 13 | 14 | public static final int MARGIN = 5; 15 | 16 | public static Color getColorWhite() { 17 | return getSystemColor( SWT.COLOR_WHITE ); 18 | } 19 | 20 | public static Color getColorRed() { 21 | return getSystemColor( SWT.COLOR_RED ); 22 | } 23 | 24 | private static Color getSystemColor( int colorCode ) { 25 | return Display.getCurrent().getSystemColor( colorCode ); 26 | } 27 | 28 | public static void changeFontHeight( Control control, int increment ) { 29 | FontData[] fontData = control.getFont().getFontData(); 30 | asList( fontData ).forEach( data -> data.setHeight( data.getHeight() + increment ) ); 31 | Font newFont = new Font( control.getDisplay(), fontData ); 32 | control.setFont( newFont ); 33 | control.addListener( SWT.Dispose, evt -> newFont.dispose() ); 34 | } 35 | } -------------------------------------------------------------------------------- /chapter-8/build/Timeline Build All.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /chapter-8/timeline.swing/src/test/java/book/twju/timeline/swing/FrameRule.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swing; 2 | 3 | import static javax.swing.JFrame.EXIT_ON_CLOSE; 4 | import static javax.swing.SwingUtilities.invokeAndWait; 5 | import static javax.swing.SwingUtilities.invokeLater; 6 | import static org.mockito.Mockito.mock; 7 | 8 | import java.awt.Container; 9 | import java.util.HashSet; 10 | 11 | import javax.swing.JFrame; 12 | 13 | import org.junit.rules.ExternalResource; 14 | 15 | class FrameRule extends ExternalResource { 16 | 17 | private final HashSet frames; 18 | 19 | FrameRule() { 20 | frames = new HashSet<>(); 21 | } 22 | 23 | Container showInFrame( Container container ) throws Exception { 24 | JFrame frame = new JFrame( "Test Window" ); 25 | frames.add( frame ); 26 | invokeLater( () -> { 27 | frame.add( container ); 28 | frame.setDefaultCloseOperation( EXIT_ON_CLOSE ); 29 | frame.setBounds( 100, 100, 350, 700 ); 30 | frame.setVisible( true ); 31 | } ); 32 | invokeAndWait( mock( Runnable.class ) ); 33 | invokeAndWait( mock( Runnable.class ) ); 34 | return container; 35 | } 36 | 37 | @Override 38 | protected void after() { 39 | frames.forEach( frame -> frame.dispose() ); 40 | } 41 | } -------------------------------------------------------------------------------- /chapter-4/src/test/java/book/twju/chapter_4/Listing_2_Annotation_TimelineTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_4; 2 | 3 | import static org.mockito.Mockito.mock; 4 | 5 | import org.junit.Test; 6 | 7 | public class Listing_2_Annotation_TimelineTest { 8 | 9 | @Test( expected = IllegalArgumentException.class ) 10 | public void constructWithNullAsItemProvider() { 11 | new Timeline( null, mock( SessionStorage.class ) ); 12 | } 13 | 14 | @Test( expected = IllegalArgumentException.class ) 15 | public void constructWithNullAsSessionStorage() { 16 | new Timeline( mock( ItemProvider.class ), null ); 17 | } 18 | 19 | @Test( expected = IllegalArgumentException.class ) 20 | public void setFetchCountExceedsLowerBound() { 21 | Timeline timeline = createTimeline(); 22 | 23 | timeline.setFetchCount( Timeline.FETCH_COUNT_LOWER_BOUND - 1 ); 24 | } 25 | 26 | @Test( expected = IllegalArgumentException.class ) 27 | public void setFetchCountExceedsUpperBound() { 28 | Timeline timeline = createTimeline(); 29 | 30 | timeline.setFetchCount( Timeline.FETCH_COUNT_LOWER_BOUND - 1 ); 31 | } 32 | 33 | private Timeline createTimeline() { 34 | return new Timeline( mock( ItemProvider.class ), 35 | mock( SessionStorage.class ) ); 36 | } 37 | } -------------------------------------------------------------------------------- /chapter-8/timeline/src/main/java/book/twju/timeline/ui/ItemViewer.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.ui; 2 | 3 | import static book.twju.timeline.ui.FetchOperation.MORE; 4 | import static book.twju.timeline.ui.FetchOperation.NEW; 5 | import book.twju.timeline.model.Item; 6 | 7 | public class ItemViewer { 8 | 9 | private final ItemUiList itemUiList; 10 | private final TopItemScroller scroller; 11 | private final TopItemUpdater topItemUpdater; 12 | 13 | public ItemViewer( ItemViewerCompound itemViewerCompound ) { 14 | itemUiList = itemViewerCompound.getItemUiList(); 15 | scroller = itemViewerCompound.getScroller(); 16 | topItemUpdater = itemViewerCompound.getTopItemUpdater(); 17 | } 18 | 19 | public void createUi( U parent ) { 20 | itemUiList.createUi( parent ); 21 | } 22 | 23 | public U getUiRoot() { 24 | return itemUiList.getUiRoot(); 25 | } 26 | 27 | public void initialize() { 28 | if( itemUiList.isTimelineEmpty() ) { 29 | itemUiList.fetch( MORE ); 30 | } 31 | itemUiList.update(); 32 | scroller.scrollIntoView(); 33 | topItemUpdater.register(); 34 | } 35 | 36 | public void fetchNew() { 37 | itemUiList.fetch( NEW ); 38 | } 39 | 40 | public void update() { 41 | itemUiList.update(); 42 | } 43 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing.application/src/main/java/book/twju/timeline/swing/application/itemui/git/GitItemUiFactory.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swing.application.itemui.git; 2 | 3 | import static book.twju.timeline.swing.SwingItemUi.createUiItemConstraints; 4 | import static book.twju.timeline.util.Assertion.checkArgument; 5 | 6 | import java.awt.Container; 7 | 8 | import book.twju.timeline.provider.git.GitItem; 9 | import book.twju.timeline.ui.ItemUi; 10 | import book.twju.timeline.ui.ItemUiFactory; 11 | 12 | public class GitItemUiFactory implements ItemUiFactory { 13 | 14 | static final String UI_CONTEXT_MUST_NOT_BE_NULL = "Argument 'uiContext' must not be null."; 15 | static final String ITEM_MUST_NOT_BE_NULL = "Argument 'item' must not be null."; 16 | static final String INDEX_MUST_NOT_BE_NEGATIVE = "Index must not be negative."; 17 | 18 | @Override 19 | public ItemUi create( Container uiContext, GitItem item, int index ) { 20 | checkArgument( uiContext != null, UI_CONTEXT_MUST_NOT_BE_NULL ); 21 | checkArgument( item != null, ITEM_MUST_NOT_BE_NULL ); 22 | checkArgument( index >= 0 , INDEX_MUST_NOT_BE_NEGATIVE ); 23 | 24 | GitItemUi result = new GitItemUi( item ); 25 | uiContext.add( result.getComponent(), createUiItemConstraints(), index ); 26 | return result; 27 | } 28 | } -------------------------------------------------------------------------------- /chapter-8/timeline/src/test/java/book/twju/timeline/ui/ItemViewerCompoundHelper.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.ui; 2 | 3 | import static org.mockito.Mockito.mock; 4 | import static org.mockito.Mockito.when; 5 | import book.twju.timeline.model.Item; 6 | 7 | class ItemViewerCompoundHelper { 8 | 9 | @SuppressWarnings("unchecked") 10 | static ItemViewerCompound stubItemViewerCompound( 11 | ItemUiList itemUiList, TopItemScroller scroller, TopItemUpdater topItemUpdater ) 12 | { 13 | ItemViewerCompound itemViewerCompound = mock( ItemViewerCompound.class ); 14 | when( itemViewerCompound.getItemUiList() ).thenReturn( itemUiList ); 15 | when( itemViewerCompound.getScroller() ).thenReturn( scroller ); 16 | when( itemViewerCompound.getTopItemUpdater() ).thenReturn( topItemUpdater ); 17 | return itemViewerCompound; 18 | } 19 | 20 | @SuppressWarnings("unchecked") 21 | static TopItemUpdater stubTopItemUpdater() { 22 | return mock( TopItemUpdater.class ); 23 | } 24 | 25 | @SuppressWarnings("unchecked") 26 | static TopItemScroller stubScroller() { 27 | return mock( TopItemScroller.class ); 28 | } 29 | 30 | @SuppressWarnings("unchecked") 31 | static ItemUiList stubItemList() { 32 | return mock( ItemUiList.class ); 33 | } 34 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing.application/src/main/java/book/twju/timeline/swing/application/itemui/git/GitTimelineFactory.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swing.application.itemui.git; 2 | 3 | import java.io.File; 4 | 5 | import book.twju.timeline.provider.git.GitItem; 6 | import book.twju.timeline.provider.git.GitItemProvider; 7 | import book.twju.timeline.provider.git.GitItemSerialization; 8 | import book.twju.timeline.swing.SwingTimeline; 9 | import book.twju.timeline.util.FileSessionStorage; 10 | import book.twju.timeline.util.FileStorageStructure; 11 | 12 | public class GitTimelineFactory { 13 | 14 | private final FileStorageStructure storageStructure; 15 | 16 | public GitTimelineFactory( FileStorageStructure storageStructure ) { 17 | this.storageStructure = storageStructure; 18 | } 19 | 20 | public SwingTimeline create( String uri, String name ) { 21 | File timelineDirectory = storageStructure.getTimelineDirectory(); 22 | GitItemProvider itemProvider = new GitItemProvider( uri, timelineDirectory, name ); 23 | GitItemUiFactory itemUiFactory = new GitItemUiFactory(); 24 | File storageFile = storageStructure.getStorageFile(); 25 | FileSessionStorage storage = new FileSessionStorage<>( storageFile, new GitItemSerialization() ); 26 | return new SwingTimeline( itemProvider, itemUiFactory, storage ); 27 | } 28 | } -------------------------------------------------------------------------------- /chapter-8/timeline.provider/src/main/java/book/twju/timeline/provider/git/GitItemSerialization.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.provider.git; 2 | 3 | import static book.twju.timeline.util.Assertion.checkArgument; 4 | import static java.lang.Long.parseLong; 5 | import book.twju.timeline.model.ItemSerialization; 6 | 7 | public class GitItemSerialization implements ItemSerialization { 8 | 9 | static final String ITEM_MUST_NOT_BE_NULL = "Argument 'item' must not be null."; 10 | static final String INPUT_MUST_NOT_BE_NULL = "Argument 'input' must not be null."; 11 | static final String INPUT_IS_NO_VALID = "Input <%s> is no valid."; 12 | 13 | private static final String SEPARATOR = "@;@;@;@"; 14 | 15 | 16 | @Override 17 | public String serialize( GitItem item ) { 18 | checkArgument( item != null, ITEM_MUST_NOT_BE_NULL ); 19 | 20 | return new StringBuilder() 21 | .append( item.getId() ).append( SEPARATOR ) 22 | .append( item.getTimeStamp() ).append( SEPARATOR ) 23 | .append( item.getAuthor() ).append( SEPARATOR ) 24 | .append( item.getContent() ).toString(); 25 | } 26 | 27 | @Override 28 | public GitItem deserialize( String input ) { 29 | checkArgument( input != null, INPUT_MUST_NOT_BE_NULL ); 30 | 31 | String[] split = input.split( SEPARATOR ); 32 | return new GitItem( split[ 0 ], parseLong( split[ 1 ] ), split[ 2 ], split[ 3 ] ); 33 | } 34 | } -------------------------------------------------------------------------------- /chapter-3/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | book.twju 6 | chapter-3 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | chapter-3 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | 20 | org.apache.maven.plugins 21 | maven-compiler-plugin 22 | 3.3 23 | 24 | 1.8 25 | 1.8 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | junit 34 | junit 35 | 4.12 36 | test 37 | 38 | 39 | org.mockito 40 | mockito-all 41 | 1.10.19 42 | test 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /chapter-4/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | book.twju 6 | chapter-4 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | chapter-4 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | 20 | org.apache.maven.plugins 21 | maven-compiler-plugin 22 | 3.3 23 | 24 | 1.8 25 | 1.8 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | junit 34 | junit 35 | 4.12 36 | test 37 | 38 | 39 | org.mockito 40 | mockito-all 41 | 1.10.19 42 | test 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /chapter-8/timeline.swt.application/src/main/java/book/twju/timeline/swt/application/itemui/git/GitTimelineFactory.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swt.application.itemui.git; 2 | 3 | import java.io.File; 4 | 5 | import org.eclipse.swt.widgets.Composite; 6 | 7 | import book.twju.timeline.provider.git.GitItem; 8 | import book.twju.timeline.provider.git.GitItemProvider; 9 | import book.twju.timeline.provider.git.GitItemSerialization; 10 | import book.twju.timeline.swt.SwtTimeline; 11 | import book.twju.timeline.util.FileSessionStorage; 12 | import book.twju.timeline.util.FileStorageStructure; 13 | 14 | public class GitTimelineFactory { 15 | 16 | private final FileStorageStructure storageStructure; 17 | 18 | public GitTimelineFactory( FileStorageStructure storageStructure ) { 19 | this.storageStructure = storageStructure; 20 | } 21 | 22 | public SwtTimeline create( Composite parent, String uri, String name ) { 23 | File timelineDirectory = storageStructure.getTimelineDirectory(); 24 | GitItemProvider itemProvider = new GitItemProvider( uri, timelineDirectory, name ); 25 | GitItemUiFactory itemUiFactory = new GitItemUiFactory(); 26 | File storageFile = storageStructure.getStorageFile(); 27 | FileSessionStorage storage = new FileSessionStorage<>( storageFile, new GitItemSerialization() ); 28 | return new SwtTimeline( parent, itemProvider, itemUiFactory, storage ); 29 | } 30 | } -------------------------------------------------------------------------------- /chapter-8/timeline.util.test.util/src/main/java/book/twju/timeline/util/test/util/BackgroundThreadHelper.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.util.test.util; 2 | 3 | import static org.mockito.Matchers.any; 4 | import static org.mockito.Mockito.doAnswer; 5 | import static org.mockito.Mockito.mock; 6 | 7 | import org.mockito.invocation.InvocationOnMock; 8 | 9 | import book.twju.timeline.util.BackgroundProcessor; 10 | import book.twju.timeline.util.UiThreadDispatcher; 11 | 12 | public class BackgroundThreadHelper { 13 | 14 | public static BackgroundProcessor directBackgroundProcessor() { 15 | BackgroundProcessor result = mock( BackgroundProcessor.class ); 16 | doAnswer( invocation -> runDirectly( invocation ) ) 17 | .when( result ).process( any( Runnable.class ) ); 18 | doAnswer( invocation -> runDirectly( invocation ) ) 19 | .when( result ).dispatchToUiThread( any( Runnable.class ) ); 20 | return result; 21 | } 22 | 23 | public static UiThreadDispatcher directUiThreadDispatcher() { 24 | UiThreadDispatcher result = mock( UiThreadDispatcher.class ); 25 | doAnswer( invocation -> runDirectly( invocation ) ) 26 | .when( result ).dispatch( any( Runnable.class ) ); 27 | return result; 28 | } 29 | 30 | private static Object runDirectly( InvocationOnMock invocation ) { 31 | Runnable runnable = ( Runnable )invocation.getArguments()[ 0 ]; 32 | runnable.run(); 33 | return null; 34 | } 35 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swt.application/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | timeline.swt.application 5 | ${revision} 6 | 7 | 8 | book.twju 9 | swt-parent 10 | 0.0.1-SNAPSHOT 11 | ../build/swt-pom.xml 12 | 13 | 14 | 15 | 16 | 17 | book.twju 18 | timeline.provider 19 | ${revision} 20 | 21 | 22 | book.twju 23 | timeline.swt 24 | ${revision} 25 | 26 | 27 | 28 | 29 | book.twju 30 | timeline.test.util 31 | ${revision} 32 | test 33 | 34 | 35 | book.twju 36 | timeline.swt.test.util 37 | ${revision} 38 | test 39 | 40 | 41 | -------------------------------------------------------------------------------- /chapter-8/timeline.swing/src/test/java/book/twju/timeline/swing/SwingUiThreadDispatcherITest.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swing; 2 | 3 | import static book.twju.timeline.swing.SwingUiThreadDispatcher.RUNNABLE_MUST_NOT_BE_NULL; 4 | import static book.twju.timeline.test.util.ThreadHelper.sleep; 5 | import static book.twju.timeline.test.util.ThrowableCaptor.thrownBy; 6 | import static java.lang.Thread.currentThread; 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | import org.junit.Before; 10 | import org.junit.Test; 11 | 12 | public class SwingUiThreadDispatcherITest { 13 | 14 | private SwingUiThreadDispatcher dispatcher; 15 | private volatile Thread uiThread; 16 | 17 | @Before 18 | public void setUp() { 19 | dispatcher = new SwingUiThreadDispatcher(); 20 | } 21 | 22 | @Test 23 | public void dispatch() { 24 | dispatcher.dispatch( () -> executeInUiThread() ); 25 | 26 | sleep( 100 ); 27 | 28 | assertThat( uiThread ) 29 | .isNotNull() 30 | .isNotSameAs( currentThread() ); 31 | } 32 | 33 | @Test 34 | public void dispatchWithNullAsRunnable() { 35 | Throwable actual = thrownBy( () -> dispatcher.dispatch( null ) ); 36 | 37 | assertThat( actual ) 38 | .hasMessage( RUNNABLE_MUST_NOT_BE_NULL ) 39 | .isInstanceOf( IllegalArgumentException.class ); 40 | } 41 | 42 | private void executeInUiThread() { 43 | uiThread = Thread.currentThread(); 44 | } 45 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swt/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | timeline.swt 5 | ${revision} 6 | 7 | 8 | book.twju 9 | swt-parent 10 | 0.0.1-SNAPSHOT 11 | ../build/swt-pom.xml 12 | 13 | 14 | 15 | 16 | 17 | book.twju 18 | timeline 19 | ${revision} 20 | 21 | 22 | 23 | 24 | book.twju 25 | timeline.test.util 26 | ${revision} 27 | test 28 | 29 | 30 | book.twju 31 | timeline.util.test.util 32 | ${revision} 33 | test 34 | 35 | 36 | book.twju 37 | timeline.swt.test.util 38 | ${revision} 39 | test 40 | 41 | 42 | -------------------------------------------------------------------------------- /chapter-8/timeline.test.util/src/main/java/book/twju/timeline/test/util/GitRule.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.test.util; 2 | 3 | import static book.twju.timeline.test.util.FileHelper.delete; 4 | 5 | import java.io.File; 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | 9 | import org.eclipse.jgit.api.Git; 10 | import org.eclipse.jgit.api.InitCommand; 11 | import org.eclipse.jgit.api.errors.GitAPIException; 12 | import org.junit.rules.ExternalResource; 13 | 14 | public class GitRule extends ExternalResource { 15 | 16 | private final Set repositories; 17 | 18 | public GitRule() { 19 | repositories = new HashSet<>(); 20 | } 21 | 22 | @Override 23 | protected void after() { 24 | repositories.forEach( repository -> delete( repository ) ); 25 | } 26 | 27 | public GitRepository create( File location ) { 28 | createRepositoryOnDisk( location ); 29 | GitRepository result = new GitRepository( location ); 30 | repositories.add( location ); 31 | return result; 32 | } 33 | 34 | private void createRepositoryOnDisk( File location ) { 35 | InitCommand init = Git.init(); 36 | init.setDirectory( location ); 37 | init.setBare( false ); 38 | callInit( init ); 39 | } 40 | 41 | private static void callInit( InitCommand init ) { 42 | try { 43 | init.call().close(); 44 | } catch( GitAPIException exception ) { 45 | throw new GitOperationException( exception ); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /chapter-3/src/test/java/book/twju/chapter_3/Listing_8_Mockito_ArgumentCapture_TimelineTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_3; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.mockito.ArgumentCaptor.forClass; 5 | import static org.mockito.Mockito.mock; 6 | import static org.mockito.Mockito.verify; 7 | 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | import org.mockito.ArgumentCaptor; 11 | 12 | public class Listing_8_Mockito_ArgumentCapture_TimelineTest { 13 | 14 | private static final FakeItem FIRST_ITEM = new FakeItem( 10 ); 15 | private static final FakeItem SECOND_ITEM = new FakeItem( 20 ); 16 | 17 | private SessionStorage sessionStorage; 18 | private ItemProviderStub itemProvider; 19 | private Timeline timeline; 20 | 21 | @Before 22 | public void setUp() { 23 | itemProvider = new ItemProviderStub(); 24 | sessionStorage = mock( SessionStorage.class ); 25 | timeline = new Timeline( itemProvider, sessionStorage ); 26 | } 27 | 28 | @Test 29 | public void fetchFirstItemsWithArgumentCaptureExample() { 30 | itemProvider.addItems( FIRST_ITEM, SECOND_ITEM ); 31 | timeline.setFetchCount( 1 ); 32 | 33 | timeline.fetchItems(); 34 | 35 | // Note that we go with item here since Memento has not been defined yet 36 | ArgumentCaptor captor = forClass( Item.class ); 37 | verify( sessionStorage ).storeTop( captor.capture() ); 38 | assertEquals( SECOND_ITEM, captor.getValue() ); 39 | } 40 | } -------------------------------------------------------------------------------- /chapter-8/timeline/src/test/java/book/twju/timeline/model/FakeItems.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.model; 2 | 3 | import static java.util.Arrays.asList; 4 | import static java.util.Collections.unmodifiableSet; 5 | 6 | import java.util.Collections; 7 | import java.util.HashSet; 8 | import java.util.List; 9 | import java.util.Set; 10 | 11 | public class FakeItems { 12 | 13 | public static final FakeItem FIRST_ITEM = new FakeItem( "1", 10 ); 14 | public static final FakeItem SECOND_ITEM = new FakeItem( "2", 20 ); 15 | public static final FakeItem THIRD_ITEM = new FakeItem( "3", 30 ); 16 | 17 | public static final Set ALL_ITEMS 18 | = unmodifiableSet( 19 | new HashSet( 20 | asList( FIRST_ITEM, SECOND_ITEM, THIRD_ITEM ) ) ); 21 | 22 | public static FakeItem[] createItems( int itemCount ) { 23 | FakeItem[] result = new FakeItem[ itemCount ]; 24 | for( int i = 0; i < result.length; i++ ) { 25 | result[ i ] = new FakeItem( String.valueOf( i ), i * 10L ); 26 | } 27 | return result; 28 | } 29 | 30 | public static FakeItem[] reverse( FakeItem[] items ) { 31 | List itemList = asList( items ); 32 | Collections.reverse( itemList ); 33 | return itemList.toArray( new FakeItem[ items.length ] ); 34 | } 35 | 36 | public static FakeItem[] subArray( FakeItem[] items, int fromIndex, int toIndex ) { 37 | return asList( items ) 38 | .subList( fromIndex, toIndex ) 39 | .toArray( new FakeItem[ toIndex ] ); 40 | } 41 | } -------------------------------------------------------------------------------- /chapter-7/src/test/java/book/twju/chapter_7/Listing_4_Hamcrest_MementoMatcher.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_7; 2 | 3 | import org.hamcrest.Description; 4 | import org.hamcrest.Factory; 5 | import org.hamcrest.Matcher; 6 | import org.hamcrest.TypeSafeMatcher; 7 | 8 | public class Listing_4_Hamcrest_MementoMatcher extends TypeSafeMatcher { 9 | 10 | private Memento expected; 11 | 12 | @Factory 13 | public static Matcher equalTo( Memento expected ) { 14 | return new Listing_4_Hamcrest_MementoMatcher( expected ); 15 | } 16 | 17 | @Override 18 | protected boolean matchesSafely( Memento actual ) { 19 | return actual.getItems().equals( expected.getItems() ) 20 | && actual.getTopItem().equals( expected.getTopItem() ); 21 | } 22 | 23 | @Override 24 | public void describeTo( Description description ) { 25 | String pattern = "\n topItem: %s\n items: %s"; 26 | description.appendText( format( expected, pattern ) ); 27 | } 28 | 29 | @Override 30 | protected void describeMismatchSafely( Memento actual, Description description ) { 31 | String pattern = "\n was:\n topItem: %s\n items: %s"; 32 | description.appendText( format( actual, pattern ) ); 33 | } 34 | 35 | private Listing_4_Hamcrest_MementoMatcher( Memento expected ) { 36 | this.expected = expected; 37 | } 38 | 39 | private static String format( Memento memento, String pattern ) { 40 | return String.format( pattern, memento.getTopItem(), memento.getItems() ); 41 | } 42 | } -------------------------------------------------------------------------------- /chapter-7/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | book.twju 6 | chapter-7 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | chapter-7 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | 20 | org.apache.maven.plugins 21 | maven-compiler-plugin 22 | 3.3 23 | 24 | 1.8 25 | 1.8 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | junit 34 | junit 35 | 4.12 36 | test 37 | 38 | 39 | org.assertj 40 | assertj-core 41 | 3.0.0 42 | test 43 | 44 | 45 | org.hamcrest 46 | java-hamcrest 47 | 2.0.0.0 48 | 49 | 50 | -------------------------------------------------------------------------------- /chapter-2/src/test/java/book/twju/chapter_2/TimelineTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_2; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import org.junit.After; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | 10 | public class TimelineTest { 11 | 12 | private final static int NEW_FETCH_COUNT 13 | = new Timeline().getFetchCount() + 1; 14 | 15 | private Timeline timeline; 16 | 17 | @Before 18 | public void setUp() { 19 | timeline = new Timeline(); 20 | } 21 | 22 | @After 23 | public void tearDown() { 24 | timeline.dispose(); 25 | } 26 | 27 | @Test 28 | public void setFetchCount() { 29 | timeline.setFetchCount( NEW_FETCH_COUNT ); 30 | 31 | assertEquals( NEW_FETCH_COUNT, timeline.getFetchCount() ); 32 | } 33 | 34 | @Test 35 | public void initialState() { 36 | assertTrue( timeline.getFetchCount() > 0 ); 37 | } 38 | 39 | @Test 40 | public void setFetchCountExceedsLowerBound() { 41 | int originalFetchCount = timeline.getFetchCount(); 42 | 43 | timeline.setFetchCount( Timeline.FETCH_COUNT_LOWER_BOUND - 1 ); 44 | 45 | assertEquals( originalFetchCount, timeline.getFetchCount() ); 46 | } 47 | 48 | @Test 49 | public void setFetchCountExceedsUpperBound() { 50 | int originalFetchCount = timeline.getFetchCount(); 51 | 52 | timeline.setFetchCount( Timeline.FETCH_COUNT_UPPER_BOUND + 1 ); 53 | 54 | assertEquals( originalFetchCount, timeline.getFetchCount() ); 55 | } 56 | } -------------------------------------------------------------------------------- /chapter-8/timeline.util/src/main/java/book/twju/timeline/util/Exceptions.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.util; 2 | 3 | import static java.lang.String.format; 4 | 5 | import java.util.concurrent.Callable; 6 | 7 | public class Exceptions { 8 | 9 | private Callable callable; 10 | 11 | public static Exceptions guard( Callable callable ) { 12 | return new Exceptions<>( callable ); 13 | } 14 | 15 | public V with( Class targetType ) { 16 | try { 17 | return callable.call(); 18 | } catch( RuntimeException rte ) { 19 | throw rte; 20 | } catch( Exception cause ) { 21 | throw createExceptionEnvelope( targetType, cause ); 22 | } 23 | } 24 | 25 | private static T createExceptionEnvelope( Class targetType, Exception cause ) { 26 | try { 27 | return targetType.getConstructor( Throwable.class ).newInstance( cause ); 28 | } catch( Exception e ) { 29 | throw new IllegalArgumentException( createProblemMessage( targetType, cause ), e ); 30 | } 31 | } 32 | 33 | private static String createProblemMessage( Class targetType, Exception cause ) { 34 | return format( "Target exception type <%s> cannot be instanciated to defuse checked exception <%s[%s]>.", 35 | targetType.getName(), 36 | cause.getClass().getName(), 37 | cause.getMessage() ); 38 | } 39 | 40 | private Exceptions( Callable callable ) { 41 | this.callable = callable; 42 | } 43 | } -------------------------------------------------------------------------------- /chapter-8/timeline/src/test/java/book/twju/timeline/model/MementoAssert.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.model; 2 | 3 | import org.assertj.core.api.AbstractAssert; 4 | 5 | public class MementoAssert 6 | extends AbstractAssert> 7 | { 8 | 9 | private static final String ITEM_PATTERN 10 | = "\nExpected items to be\n <%s>,\nbut were\n <%s>."; 11 | private static final String TOP_ITEM_PATTERN 12 | = "\nExpected top item to be\n <%s>,\nbut was\n <%s>."; 13 | 14 | public static MementoAssert assertThat( Memento actual ) { 15 | return new MementoAssert( actual ); 16 | } 17 | 18 | public MementoAssert( Memento actual ) { 19 | super( actual, MementoAssert.class ); 20 | } 21 | 22 | @Override 23 | public MementoAssert isEqualTo( Object expected ) { 24 | hasEqualItems( ( Memento )expected ); 25 | hasEqualTopItem( ( Memento )expected ); 26 | return this; 27 | } 28 | 29 | public MementoAssert hasEqualItems( Memento expected ) { 30 | isNotNull(); 31 | if( !actual.getItems().equals( expected.getItems() ) ) { 32 | failWithMessage( ITEM_PATTERN, expected.getItems(), actual.getItems() ); 33 | } 34 | return this; 35 | } 36 | 37 | public MementoAssert hasEqualTopItem( Memento expected ) { 38 | isNotNull(); 39 | if( !actual.getTopItem().equals( expected.getTopItem() ) ) { 40 | failWithMessage( TOP_ITEM_PATTERN, expected.getTopItem(), actual.getTopItem() ); 41 | } 42 | return this; 43 | } 44 | } -------------------------------------------------------------------------------- /chapter-3/src/test/java/book/twju/chapter_3/Listing_1_Dummy_TimelineTest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_3; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | public class Listing_1_Dummy_TimelineTest { 10 | 11 | private final static int NEW_FETCH_COUNT 12 | = new Timeline( new ItemProviderDummy() ).getFetchCount() + 1; 13 | 14 | private Timeline timeline; 15 | private ItemProvider itemProvider; 16 | 17 | @Before 18 | public void setUp() { 19 | itemProvider = null; 20 | timeline = new Timeline( itemProvider ); 21 | } 22 | 23 | @Test 24 | public void setFetchCount() { 25 | timeline.setFetchCount( NEW_FETCH_COUNT ); 26 | 27 | assertEquals( NEW_FETCH_COUNT, timeline.getFetchCount() ); 28 | } 29 | 30 | @Test 31 | public void initialState() { 32 | assertTrue( timeline.getFetchCount() > 0 ); 33 | } 34 | 35 | @Test 36 | public void setFetchCountExceedsLowerBound() { 37 | int originalFetchCount = timeline.getFetchCount(); 38 | 39 | timeline.setFetchCount( Timeline.FETCH_COUNT_LOWER_BOUND - 1 ); 40 | 41 | assertEquals( originalFetchCount, timeline.getFetchCount() ); 42 | } 43 | 44 | @Test 45 | public void setFetchCountExceedsUpperBound() { 46 | int originalFetchCount = timeline.getFetchCount(); 47 | 48 | timeline.setFetchCount( Timeline.FETCH_COUNT_UPPER_BOUND + 1 ); 49 | 50 | assertEquals( originalFetchCount, timeline.getFetchCount() ); 51 | } 52 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swing/src/test/java/book/twju/timeline/swing/SwingTimelineCompoundHelper.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swing; 2 | 3 | import static org.mockito.Mockito.mock; 4 | import static org.mockito.Mockito.when; 5 | 6 | import java.awt.Container; 7 | 8 | import javax.swing.JPanel; 9 | 10 | import book.twju.timeline.model.Item; 11 | import book.twju.timeline.ui.ItemViewer; 12 | 13 | class SwingTimelineCompoundHelper { 14 | 15 | @SuppressWarnings("unchecked") 16 | static Header stubHeader() { 17 | Header result = mock( Header.class ); 18 | when( result.getComponent() ).thenReturn( new JPanel() ); 19 | return result; 20 | } 21 | 22 | @SuppressWarnings("unchecked") 23 | static ItemViewer stubItemViewer() { 24 | ItemViewer result = mock( ItemViewer.class ); 25 | when( result.getUiRoot() ).thenReturn( new JPanel() ); 26 | return result; 27 | } 28 | 29 | @SuppressWarnings("unchecked") 30 | static SwingAutoUpdate stubAutoUpdate() { 31 | return mock( SwingAutoUpdate.class ); 32 | } 33 | 34 | @SuppressWarnings("unchecked") 35 | static SwingTimelineCompound stubCompound( 36 | Header header, ItemViewer itemViewer, SwingAutoUpdate autoUpdate ) 37 | { 38 | SwingTimelineCompound result = mock( SwingTimelineCompound.class ); 39 | when( result.getAutoUpdate() ).thenReturn( autoUpdate ); 40 | when( result.getItemViewer() ).thenReturn( itemViewer ); 41 | when( result.getHeader() ).thenReturn( header ); 42 | return result; 43 | } 44 | } -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/FetchItemsEnum.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | import static book.twju.chapter_5.FakeItems.FIRST_ITEM; 4 | import static book.twju.chapter_5.FakeItems.SECOND_ITEM; 5 | import static book.twju.chapter_5.FakeItems.THIRD_ITEM; 6 | 7 | public enum FetchItemsEnum { 8 | 9 | ON_LOWER_FETCH_COUNT_BOUND { 10 | @Override 11 | void init() { 12 | withInput( FIRST_ITEM, SECOND_ITEM, THIRD_ITEM ); 13 | withFetchCount( Timeline.FETCH_COUNT_LOWER_BOUND ); 14 | withOutput( THIRD_ITEM, SECOND_ITEM ); 15 | } 16 | }, 17 | 18 | ON_FETCH_COUNT_EXCEEDS_ITEM_COUNT { 19 | @Override 20 | void init() { 21 | withInput( FIRST_ITEM, SECOND_ITEM, THIRD_ITEM ); 22 | withFetchCount( 2 ); 23 | withOutput( THIRD_ITEM, SECOND_ITEM, FIRST_ITEM ); 24 | } 25 | }; 26 | 27 | private int fetchCount; 28 | private Item[] input; 29 | private Item[] output; 30 | 31 | FetchItemsEnum() { 32 | init(); 33 | } 34 | 35 | abstract void init(); 36 | 37 | public int getFetchCount() { 38 | return fetchCount; 39 | } 40 | 41 | public Item[] getInput() { 42 | return input; 43 | } 44 | 45 | public Item[] getOutput() { 46 | return output; 47 | } 48 | 49 | FetchItemsEnum withInput( Item ... input ) { 50 | this.input = input; 51 | return this; 52 | } 53 | 54 | FetchItemsEnum withFetchCount( int fetchCount ) { 55 | this.fetchCount = fetchCount; 56 | return this; 57 | } 58 | 59 | FetchItemsEnum withOutput( Item ... output ) { 60 | this.output = output; 61 | return this; 62 | } 63 | } -------------------------------------------------------------------------------- /chapter-7/src/test/java/book/twju/chapter_7/Listing_7_AssertJ_MementoAssert.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_7; 2 | 3 | import org.assertj.core.api.AbstractAssert; 4 | 5 | public class Listing_7_AssertJ_MementoAssert extends AbstractAssert { 6 | 7 | private static final String ITEM_PATTERN 8 | = "\nExpected items to be\n <%s>,\nbut were\n <%s>."; 9 | private static final String TOP_ITEM_PATTERN 10 | = "\nExpected top item to be\n <%s>,\nbut was\n <%s>."; 11 | 12 | public static Listing_7_AssertJ_MementoAssert assertThat( Memento actual ) { 13 | return new Listing_7_AssertJ_MementoAssert( actual ); 14 | } 15 | 16 | public Listing_7_AssertJ_MementoAssert( Memento actual ) { 17 | super( actual, Listing_7_AssertJ_MementoAssert.class ); 18 | } 19 | 20 | @Override 21 | public Listing_7_AssertJ_MementoAssert isEqualTo( Object expected ) { 22 | hasEqualItems( ( Memento )expected ); 23 | hasEqualTopItem( ( Memento )expected ); 24 | return this; 25 | } 26 | 27 | public Listing_7_AssertJ_MementoAssert hasEqualItems( Memento expected ) { 28 | isNotNull(); 29 | if( !actual.getItems().equals( expected.getItems() ) ) { 30 | failWithMessage( ITEM_PATTERN, expected.getItems(), actual.getItems() ); 31 | } 32 | return this; 33 | } 34 | 35 | public Listing_7_AssertJ_MementoAssert hasEqualTopItem( Memento expected ) { 36 | isNotNull(); 37 | if( !actual.getTopItem().equals( expected.getTopItem() ) ) { 38 | failWithMessage( TOP_ITEM_PATTERN, expected.getTopItem(), actual.getTopItem() ); 39 | } 40 | return this; 41 | } 42 | } -------------------------------------------------------------------------------- /chapter-8/timeline.swt/src/test/java/book/twju/timeline/swt/SwtTimelineCompoundHelper.java: -------------------------------------------------------------------------------- 1 | package book.twju.timeline.swt; 2 | 3 | import static org.mockito.Mockito.mock; 4 | import static org.mockito.Mockito.when; 5 | 6 | import org.eclipse.swt.SWT; 7 | import org.eclipse.swt.widgets.Composite; 8 | 9 | import book.twju.timeline.model.Item; 10 | import book.twju.timeline.ui.ItemViewer; 11 | 12 | class SwtTimelineCompoundHelper { 13 | 14 | @SuppressWarnings("unchecked") 15 | static Header stubHeader( Composite parent ) { 16 | Header result = mock( Header.class ); 17 | when( result.getControl() ).thenReturn( new Composite( parent, SWT.NONE ) ); 18 | return result; 19 | } 20 | 21 | @SuppressWarnings("unchecked") 22 | static ItemViewer stubItemViewer( Composite parent) { 23 | ItemViewer result = mock( ItemViewer.class ); 24 | when( result.getUiRoot() ).thenReturn( new Composite( parent, SWT.NONE ) ); 25 | return result; 26 | } 27 | 28 | @SuppressWarnings("unchecked") 29 | static SwtAutoUpdate stubAutoUpdate() { 30 | return mock( SwtAutoUpdate.class ); 31 | } 32 | 33 | @SuppressWarnings("unchecked") 34 | static SwtTimelineCompound stubCompound( 35 | Header header, ItemViewer itemViewer, SwtAutoUpdate autoUpdate ) 36 | { 37 | SwtTimelineCompound result = mock( SwtTimelineCompound.class ); 38 | when( result.getAutoUpdate() ).thenReturn( autoUpdate ); 39 | when( result.getItemViewer() ).thenReturn( itemViewer ); 40 | when( result.getHeader() ).thenReturn( header ); 41 | return result; 42 | } 43 | } -------------------------------------------------------------------------------- /chapter-7/src/test/java/book/twju/chapter_7/Listing_2_JUnit_MementoAssert_FileSessionStorageITest.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_7; 2 | 3 | import static book.twju.chapter_7.FakeItems.ALL_ITEMS; 4 | import static book.twju.chapter_7.FakeItems.FIRST_ITEM; 5 | import static book.twju.chapter_7.Listing_2_JUnit_MementoAssert.assertEqualsButNotSame; 6 | import static org.junit.Assert.assertTrue; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.nio.file.Files; 11 | 12 | import org.junit.Before; 13 | import org.junit.Rule; 14 | import org.junit.Test; 15 | import org.junit.rules.TemporaryFolder; 16 | 17 | public class Listing_2_JUnit_MementoAssert_FileSessionStorageITest { 18 | 19 | @Rule 20 | public TemporaryFolder temporaryFolder = new TemporaryFolder(); 21 | 22 | private ItemSerialization itemSerialization; 23 | private FileSessionStorage storage; 24 | private File storageLocation; 25 | 26 | @Before 27 | public void setUp() throws IOException { 28 | storageLocation = temporaryFolder.newFile(); 29 | itemSerialization = new FakeItemSerialization(); 30 | storage = new FileSessionStorage( storageLocation, itemSerialization ); 31 | } 32 | 33 | @Test 34 | public void storage() throws IOException { 35 | Memento expected = new Memento( ALL_ITEMS, FIRST_ITEM ); 36 | 37 | storage.store( expected ); 38 | Memento actual = storage.read(); 39 | 40 | assertEqualsButNotSame( expected, actual ); 41 | assertTrue( storedMemento().length > 0 ); 42 | } 43 | 44 | private byte[] storedMemento() throws IOException { 45 | return Files.readAllBytes( storageLocation.toPath() ); 46 | } 47 | } -------------------------------------------------------------------------------- /chapter-3/src/test/java/book/twju/chapter_3/ItemProviderStub.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_3; 2 | 3 | import static java.lang.Long.compare; 4 | import static java.util.Arrays.asList; 5 | import static java.util.Collections.emptyList; 6 | import static java.util.stream.Collectors.toList; 7 | 8 | import java.util.Comparator; 9 | import java.util.HashSet; 10 | import java.util.List; 11 | import java.util.Set; 12 | 13 | class ItemProviderStub implements ItemProvider { 14 | 15 | private final Set items; 16 | 17 | ItemProviderStub() { 18 | items = new HashSet<>(); 19 | } 20 | 21 | @Override 22 | // location 1: stub implementation to provide items to fetch 23 | public List fetchItems( Item ancestor, int itemCount ) { 24 | return items 25 | .stream() 26 | .sorted( descending() ) 27 | .filter( item -> isApplicable( ancestor, item ) ) 28 | .limit( itemCount ) 29 | .collect( toList() ); 30 | } 31 | 32 | // location 2: method for stub configuration 33 | void addItems( Item ... itemsToAdd ) { 34 | items.addAll( asList( itemsToAdd ) ); 35 | } 36 | 37 | private Comparator descending() { 38 | return ( first, second ) 39 | -> compare( second.getTimeStamp(), first.getTimeStamp() ); 40 | } 41 | 42 | private boolean isApplicable( Item ancestor, Item item ) { 43 | return ancestor == null 44 | || item.getTimeStamp() < ancestor.getTimeStamp(); 45 | } 46 | 47 | @Override 48 | public int getNewCount( Item predecessor ) { 49 | return 0; 50 | } 51 | 52 | @Override 53 | public List fetchNew( Item predecessor ) { 54 | return emptyList(); 55 | } 56 | } -------------------------------------------------------------------------------- /chapter-4/src/test/java/book/twju/chapter_4/ItemProviderStub.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_4; 2 | 3 | import static java.lang.Long.compare; 4 | import static java.util.Arrays.asList; 5 | import static java.util.Collections.emptyList; 6 | import static java.util.stream.Collectors.toList; 7 | 8 | import java.util.Comparator; 9 | import java.util.HashSet; 10 | import java.util.List; 11 | import java.util.Set; 12 | 13 | class ItemProviderStub implements ItemProvider { 14 | 15 | private final Set items; 16 | 17 | ItemProviderStub() { 18 | items = new HashSet<>(); 19 | } 20 | 21 | @Override 22 | // location 1: stub implementation to provide items to fetch 23 | public List fetchItems( Item ancestor, int itemCount ) { 24 | return items 25 | .stream() 26 | .sorted( descending() ) 27 | .filter( item -> isApplicable( ancestor, item ) ) 28 | .limit( itemCount ) 29 | .collect( toList() ); 30 | } 31 | 32 | // location 2: method for stub configuration 33 | void addItems( Item ... itemsToAdd ) { 34 | items.addAll( asList( itemsToAdd ) ); 35 | } 36 | 37 | private Comparator descending() { 38 | return ( first, second ) 39 | -> compare( second.getTimeStamp(), first.getTimeStamp() ); 40 | } 41 | 42 | private boolean isApplicable( Item ancestor, Item item ) { 43 | return ancestor == null 44 | || item.getTimeStamp() < ancestor.getTimeStamp(); 45 | } 46 | 47 | @Override 48 | public int getNewCount( Item predecessor ) { 49 | return 0; 50 | } 51 | 52 | @Override 53 | public List fetchNew( Item predecessor ) { 54 | return emptyList(); 55 | } 56 | } -------------------------------------------------------------------------------- /chapter-5/src/test/java/book/twju/chapter_5/ItemProviderStub.java: -------------------------------------------------------------------------------- 1 | package book.twju.chapter_5; 2 | 3 | import static java.lang.Long.compare; 4 | import static java.util.Arrays.asList; 5 | import static java.util.Collections.emptyList; 6 | import static java.util.stream.Collectors.toList; 7 | 8 | import java.util.Comparator; 9 | import java.util.HashSet; 10 | import java.util.List; 11 | import java.util.Set; 12 | 13 | class ItemProviderStub implements ItemProvider { 14 | 15 | private final Set items; 16 | 17 | ItemProviderStub() { 18 | items = new HashSet<>(); 19 | } 20 | 21 | @Override 22 | // location 1: stub implementation to provide items to fetch 23 | public List fetchItems( Item ancestor, int itemCount ) { 24 | return items 25 | .stream() 26 | .sorted( descending() ) 27 | .filter( item -> isApplicable( ancestor, item ) ) 28 | .limit( itemCount ) 29 | .collect( toList() ); 30 | } 31 | 32 | // location 2: method for stub configuration 33 | void addItems( Item ... itemsToAdd ) { 34 | items.addAll( asList( itemsToAdd ) ); 35 | } 36 | 37 | private Comparator descending() { 38 | return ( first, second ) 39 | -> compare( second.getTimeStamp(), first.getTimeStamp() ); 40 | } 41 | 42 | private boolean isApplicable( Item ancestor, Item item ) { 43 | return ancestor == null 44 | || item.getTimeStamp() < ancestor.getTimeStamp(); 45 | } 46 | 47 | @Override 48 | public int getNewCount( Item predecessor ) { 49 | return 0; 50 | } 51 | 52 | @Override 53 | public List fetchNew( Item predecessor ) { 54 | return emptyList(); 55 | } 56 | } -------------------------------------------------------------------------------- /chapter-8/alltests/AllTestSuite.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | --------------------------------------------------------------------------------