public Model buildWith(ModelBuilder modelBuilder) { Model model = modelBuilder.useCase("Get greeted") .basicFlow() .step("S1").system(this::greetsUser) .step("S2").system(this::printsHooray).reactWhile(this::lessThanThreeHooraysHaveBeenPrinted) .build(); return model; }
@Test public void createsSingleStepWithNoPreviousStep() { UseCasePart useCasePart = modelBuilder.useCase(USE_CASE); useCasePart.basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()); Collection<Step> steps = useCasePart.getUseCase().getSteps(); assertEquals(1, steps.size()); Optional<FlowStep> previousStep = ((FlowStep) steps.iterator().next()).getPreviousStepInFlow(); assertFalse(previousStep.isPresent()); }
@Test public void useCasesAreUniquelyIdentifiedByName() { UseCasePart useCasePart = modelBuilder.useCase(USE_CASE); Model model = useCasePart.basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .flow(ALTERNATIVE_FLOW) .step(SYSTEM_DISPLAYS_TEXT_AGAIN).system(displaysConstantText()).build(); assertEquals(1, model.getUseCases().size()); assertEquals(model.findUseCase(USE_CASE), model.getUseCases().iterator().next()); }
static Model model() { SaysHelloWorld saysHelloWorld = new SaysHelloWorld(); SaysHelloToUser saysHelloToUser = new SaysHelloToUser(); Model model = Model.builder().useCase("Say hello to world, then user") .basicFlow() .step("S1").user(ASKS_FOR_HELLO_WORLD).system(saysHelloWorld) .step("S2").user(ASKS_FOR_HELLO_TO_USER).system(saysHelloToUser) .build(); return model; }
@Test public void rethrowsExceptionIfExceptionIsNotHandled() { thrown.expect(IllegalStateException.class); modelBuilder.useCase(USE_CASE).basicFlow().step(CUSTOMER_ENTERS_TEXT).system(() -> { throw new IllegalStateException(); }); Model model = modelBuilder.build(); modelRunner.run(model); }
public void start() { ModelBuilder modelBuilder = Model.builder(); Model model = modelBuilder.useCase("Measure performance of simple mathematical operations") .basicFlow() .step("S1").system(this::addsTwoNumbers) .step("S2").system(this::calculatesTwoToThePowerOfAThousand) .step("S3").system(this::displaysResults).build(); ModelRunner modelRunner = new ModelRunner(); modelRunner.handleWith(this::measuresPerformance); modelRunner.run(model); }
public Model buildWith(ModelBuilder modelBuilder) { Model model = modelBuilder.useCase("Get greeted") .basicFlow() .step("S1").system(this::promptsUserToEnterFirstName) .step("S2").user(ENTERS_FIRST_NAME).system(this::savesFirstName) .step("S3").system(this::promptsUserToEnterAge) .step("S4").user(ENTERS_AGE).system(this::savesAge) .step("S5").system(this::greetsUserWithFirstNameAndAge) .build(); return model; }
@Test public void throwsExceptionIfActorPartIsNotSpecified() { thrown.expect(MissingUseCaseStepPart.class); thrown.expectMessage(CUSTOMER_ENTERS_TEXT); modelBuilder.useCase(USE_CASE).basicFlow().step(CUSTOMER_ENTERS_TEXT); Model model = modelBuilder.build(); modelRunner.run(model); }
@Test public void createsTwoStepsInBasicFlowAndCheckIfTheyExistByIndex() { UseCasePart useCasePart = modelBuilder.useCase(USE_CASE); useCasePart.basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .step(SYSTEM_DISPLAYS_TEXT_AGAIN).system(displaysConstantText()); List<FlowStep> steps = useCasePart.getUseCase().getBasicFlow().getSteps(); assertEquals(2, steps.size()); assertEquals(SYSTEM_DISPLAYS_TEXT, steps.get(0).getName()); assertEquals(SYSTEM_DISPLAYS_TEXT_AGAIN, steps.get(1).getName()); }
@Test public void cantReactIfEventIsWrong() { Model model = modelBuilder.useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .build(); modelRunner.run(model); boolean canReact = modelRunner.canReactTo(entersNumber().getClass()); assertFalse(canReact); }
@Test public void printsTextAutonomously() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .build(); modelRunner.run(model); assertRecordedStepNames(SYSTEM_DISPLAYS_TEXT); }
@Test public void createsTwoStepsAndPreviousStepOfSecondOneIsFirstOne() { UseCasePart useCasePart = modelBuilder.useCase(USE_CASE); useCasePart.basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .step(SYSTEM_DISPLAYS_TEXT_AGAIN).system(displaysConstantText()); FlowStep firstUseCaseStep = (FlowStep)useCasePart.getUseCase().findStep(SYSTEM_DISPLAYS_TEXT); FlowStep secondUseCaseStep = (FlowStep)useCasePart.getUseCase().findStep(SYSTEM_DISPLAYS_TEXT_AGAIN); assertEquals(firstUseCaseStep, secondUseCaseStep.getPreviousStepInFlow().get()); }
@Test public void oneStepInFlowReacts() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .build(); modelRunner.run(model); reactToAndAssertEvents(entersText()); }
@Test public void stepThasHasTrueConditionReactsEvenIfOtherStepWouldBePerformedBySystem() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .flow("Alternative Flow: Skipped").condition(() -> false) .step(THIS_STEP_SHOULD_BE_SKIPPED).system(() -> System.out.println("You should not see this!")) .build(); modelRunner.run(model).reactTo(entersText(), entersText()); assertRecordedStepNames(CUSTOMER_ENTERS_TEXT); }
@Test public void printsTextAutonomouslyOnlyIfActorIsRightInSecondStep() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .step(SYSTEM_DISPLAYS_TEXT_AGAIN).as(customer).system(displaysConstantText()) .build(); modelRunner.as(customer).run(model); assertRecordedStepNames(SYSTEM_DISPLAYS_TEXT, SYSTEM_DISPLAYS_TEXT_AGAIN); }
@Test public void doesNotHandleExceptionIfNoExceptionOccurs() { Model model = modelBuilder.useCase(USE_CASE) .basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .flow(ALTERNATIVE_FLOW).after(SYSTEM_DISPLAYS_TEXT) .step(SYSTEM_HANDLES_EXCEPTION).on(ArrayIndexOutOfBoundsException.class).system(e -> {}) .build(); modelRunner.run(model); assertRecordedStepNames(SYSTEM_DISPLAYS_TEXT); }
@Test public void doesNotHandleExceptionIfSystemReactionDoesNotThrowException() { Model model = modelBuilder.useCase(USE_CASE) .basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .flow(ALTERNATIVE_FLOW).after(SYSTEM_DISPLAYS_TEXT) .step(SYSTEM_HANDLES_EXCEPTION).on(ArrayIndexOutOfBoundsException.class).system(e -> {}) .build(); modelRunner.run(model); assertRecordedStepNames(SYSTEM_DISPLAYS_TEXT); }
@Test public void handlesExceptionAfterSpecificStep() { Model model = modelBuilder.useCase(USE_CASE) .basicFlow() .step(SYSTEM_THROWS_EXCEPTION).system(throwsArrayIndexOutOfBoundsException()) .flow(ALTERNATIVE_FLOW).after(SYSTEM_THROWS_EXCEPTION) .step(SYSTEM_HANDLES_EXCEPTION).on(ArrayIndexOutOfBoundsException.class).system(e -> {}) .build(); modelRunner.run(model); assertEquals(SYSTEM_HANDLES_EXCEPTION, latestStepName()); }
@Test public void twoSequentialStepsReactToEventsOfDifferentType() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_NUMBER).user(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model); reactToAndAssertEvents(entersText(), entersNumber()); }
@Test public void onlyStepWithTrueConditionReacts() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .flow("Alternative Flow: Skipped").condition(() -> false) .step(THIS_STEP_SHOULD_BE_SKIPPED).user(EntersText.class).system(throwsRuntimeException()) .build(); modelRunner.run(model).reactTo(entersText(), entersText()); assertRecordedStepNames(CUSTOMER_ENTERS_TEXT); }