@Test public void sameEventTypeReactedTo() { Model model = modelBuilder.useCase(USE_CASE) .basicFlow().anytime() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .flow("Alternative Flow: Could react as well").anytime() .step(CUSTOMER_ENTERS_ALTERNATIVE_TEXT).user(EntersText.class).system(displaysEnteredText()) .build(); modelRunner.run(model); Set<Class<?>> reactToTypes = modelRunner.getReactToTypes(); assertEquals(1, reactToTypes.size()); Class<?> eventTypeReactedTo = reactToTypes.iterator().next(); assertEquals(EntersText.class, eventTypeReactedTo); }
@Test public void differentEventTypesReactedTo() { Model model = modelBuilder.useCase(USE_CASE) .basicFlow().anytime() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .flow("Alternative Flow: Could react as well").anytime() .step(CUSTOMER_ENTERS_NUMBER).user(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model); Set<Class<?>> reactToTypes = modelRunner.getReactToTypes(); assertEquals(2, reactToTypes.size()); assertTrue(reactToTypes.contains(EntersText.class)); assertTrue(reactToTypes.contains(EntersNumber.class)); }
@Test public void moreThanOneStepCanReact() { Model model = modelBuilder.useCase(USE_CASE) .basicFlow().anytime() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .flow("Alternative Flow: Could react as well").anytime() .step(CUSTOMER_ENTERS_ALTERNATIVE_TEXT).user(EntersText.class).system(displaysEnteredText()) .build(); modelRunner.run(model); boolean canReact = modelRunner.canReactTo(entersText().getClass()); assertTrue(canReact); Set<Step> stepsThatCanReact = modelRunner.getStepsThatCanReactTo(entersText().getClass()); assertEquals(2, stepsThatCanReact.size()); } }
@Test public void throwsExceptionIfMoreThanOneStepCanReactInSameUseCase() { thrown.expect(MoreThanOneStepCanReact.class); thrown.expectMessage(CUSTOMER_ENTERS_TEXT); thrown.expectMessage(CUSTOMER_ENTERS_ALTERNATIVE_TEXT); Model model = modelBuilder .useCase(USE_CASE) .basicFlow().anytime() .step(CUSTOMER_ENTERS_TEXT).system(displaysConstantText()) .flow(ALTERNATIVE_FLOW).anytime() .step(CUSTOMER_ENTERS_ALTERNATIVE_TEXT).system(displaysConstantText()) .build(); modelRunner.run(model); }
@Test public void eventTypesReactedOnlyIfConditionFulfilled() { Model model = modelBuilder.useCase(USE_CASE) .basicFlow().condition(() -> false) .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .flow("Alternative Flow: Could react as well").anytime() .step(CUSTOMER_ENTERS_NUMBER).user(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model); Set<Class<?>> reactToTypes = modelRunner.getReactToTypes(); assertEquals(1, reactToTypes.size()); Class<?> eventTypeReactedTo = reactToTypes.iterator().next(); assertEquals(EntersNumber.class, eventTypeReactedTo); }
@Test public void handlesExceptionAtAnyTime() { Model model = modelBuilder.useCase(USE_CASE) .basicFlow() .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .flow(ALTERNATIVE_FLOW).after(SYSTEM_DISPLAYS_TEXT) .step(SYSTEM_THROWS_EXCEPTION).system(throwsArrayIndexOutOfBoundsException()) .flow(ALTERNATIVE_FLOW_2).anytime() .step(SYSTEM_HANDLES_EXCEPTION).on(ArrayIndexOutOfBoundsException.class).system(e -> {}) .build(); modelRunner.run(model); assertRecordedStepNames(SYSTEM_DISPLAYS_TEXT, SYSTEM_THROWS_EXCEPTION, SYSTEM_HANDLES_EXCEPTION); } }
@Test public void includesUseCaseWithBasicFlowAtFirstStep_withAnytimeCondition() { Model model = modelBuilder .useCase(INCLUDED_USE_CASE) .basicFlow().anytime() .step(CUSTOMER_ENTERS_NUMBER).user(EntersNumber.class).system(displaysEnteredNumber()) .useCase(USE_CASE) .basicFlow() .step(SYSTEM_INCLUDES_USE_CASE).includesUseCase(INCLUDED_USE_CASE) .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .build(); modelRunner.run(model).reactTo(entersNumber(), entersNumber()); assertRecordedStepNames(SYSTEM_INCLUDES_USE_CASE, CUSTOMER_ENTERS_NUMBER, SYSTEM_DISPLAYS_TEXT, CUSTOMER_ENTERS_NUMBER); }
@Test public void includesUseCaseWithAlternativeFlowAtSecondStep_withAnytimeCondition() { Model model = modelBuilder .useCase(INCLUDED_USE_CASE) .basicFlow() .step(SYSTEM_HANDLES_EXCEPTION).user(Throwable.class).system(e -> e.printStackTrace()) .flow(ALTERNATIVE_FLOW).anytime() .step(CUSTOMER_ENTERS_NUMBER).user(EntersNumber.class).system(displaysEnteredNumber()) .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .step(SYSTEM_INCLUDES_USE_CASE).includesUseCase(INCLUDED_USE_CASE) .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .build(); modelRunner.run(model).reactTo(entersText(), entersNumber(), entersNumber()); assertRecordedStepNames(CUSTOMER_ENTERS_TEXT, SYSTEM_INCLUDES_USE_CASE, CUSTOMER_ENTERS_NUMBER, SYSTEM_DISPLAYS_TEXT, CUSTOMER_ENTERS_NUMBER); }
@Test public void includesUseCaseWithBasicFlowAtSecondStep_withAnytimeCondition() { Model model = modelBuilder .useCase(INCLUDED_USE_CASE) .basicFlow().anytime() .step(CUSTOMER_ENTERS_NUMBER).user(EntersNumber.class).system(displaysEnteredNumber()) .useCase(USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .step(SYSTEM_INCLUDES_USE_CASE).includesUseCase(INCLUDED_USE_CASE) .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .build(); modelRunner.run(model).reactTo(entersText(), entersNumber(), entersNumber()); assertRecordedStepNames(CUSTOMER_ENTERS_TEXT, SYSTEM_INCLUDES_USE_CASE, CUSTOMER_ENTERS_NUMBER, SYSTEM_DISPLAYS_TEXT, CUSTOMER_ENTERS_NUMBER); }
@Test public void includesUseCaseWithAlternativeFlowAtFirstStep_witAnytimeCondition() { Model model = modelBuilder .useCase(INCLUDED_USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .flow(ALTERNATIVE_FLOW).anytime() .step(CUSTOMER_ENTERS_NUMBER).user(EntersNumber.class).system(displaysEnteredNumber()) .useCase(USE_CASE) .basicFlow() .step(SYSTEM_INCLUDES_USE_CASE).includesUseCase(INCLUDED_USE_CASE) .step(SYSTEM_DISPLAYS_TEXT).system(displaysConstantText()) .build(); modelRunner.run(model).reactTo(entersNumber(), entersNumber()); assertRecordedStepNames(SYSTEM_INCLUDES_USE_CASE, CUSTOMER_ENTERS_NUMBER, SYSTEM_DISPLAYS_TEXT, CUSTOMER_ENTERS_NUMBER); }
@Test public void doesNotReenterAlternativeFlowEvenIfItHasTrueCondition() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(THIS_STEP_SHOULD_BE_SKIPPED).user(EntersText.class).system(throwsRuntimeException()) .step(THIS_STEP_SHOULD_BE_SKIPPED_AS_WELL).user(EntersText.class).system(throwsRuntimeException()) .flow(ALTERNATIVE_FLOW).anytime() .step(CUSTOMER_ENTERS_ALTERNATIVE_TEXT).user(EntersText.class).system(displaysEnteredText()) .step(CUSTOMER_ENTERS_NUMBER).user(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model) .reactTo(entersAlternativeText(), entersNumber(), entersAlternativeText(), entersNumber()); assertRecordedStepNames(CUSTOMER_ENTERS_ALTERNATIVE_TEXT, CUSTOMER_ENTERS_NUMBER); }
@Test public void includeUseCaseFromTwoDifferentUseCases() { Model model = modelBuilder .useCase(INCLUDED_USE_CASE) .basicFlow() .step(CUSTOMER_ENTERS_NUMBER).user(EntersNumber.class).system(displaysEnteredNumber()) .useCase(USE_CASE) .basicFlow().anytime() .step(CUSTOMER_ENTERS_TEXT).user(EntersText.class).system(displaysEnteredText()) .step(SYSTEM_INCLUDES_USE_CASE_3).includesUseCase(INCLUDED_USE_CASE) .step(CUSTOMER_ENTERS_TEXT_AGAIN).user(EntersText.class).system(displaysEnteredText()) .useCase(USE_CASE_2) .basicFlow() .step(SYSTEM_INCLUDES_USE_CASE).includesUseCase(INCLUDED_USE_CASE) .step(SYSTEM_INCLUDES_USE_CASE_2).includesUseCase(INCLUDED_USE_CASE) .build(); modelRunner.run(model).reactTo(entersNumber(), entersNumber(), entersText(), entersNumber(), entersText(), entersNumber()); assertRecordedStepNames(SYSTEM_INCLUDES_USE_CASE, CUSTOMER_ENTERS_NUMBER, SYSTEM_INCLUDES_USE_CASE_2, CUSTOMER_ENTERS_NUMBER, CUSTOMER_ENTERS_TEXT, SYSTEM_INCLUDES_USE_CASE_3, CUSTOMER_ENTERS_NUMBER, CUSTOMER_ENTERS_TEXT_AGAIN); }
.step("S4c_1").includesUseCase("Included use case") .step("S4c_2").continuesAt("S1") .flow("EX").anytime() .step("EX1").on(Exception.class).system(logsException()) .build();