/** * Defines an "autonomous system reaction", meaning the system will react * without needing an event provided via {@link ModelRunner#reactTo(Object)}. * * @param systemReaction * the autonomous system reaction * @return the created system part of this step */ public StepSystemPart<ModelRunner> system(Runnable systemReaction) { Objects.requireNonNull(systemReaction); StepSystemPart<ModelRunner> systemPart = as(systemActor).system(systemReaction); return systemPart; }
/** * Defines an "autonomous system reaction", meaning the system will react * without needing an event provided via {@link ModelRunner#reactTo(Object)}. * Instead, the model runner provides itself as an event to the system reaction. * * @param modelRunnerConsumer * the autonomous system reaction (that needs information from a model runner to work) * @return the created system part of this step */ public StepSystemPart<ModelRunner> system(Consumer<ModelRunner> modelRunnerConsumer) { Objects.requireNonNull(modelRunnerConsumer); StepSystemPart<ModelRunner> systemPart = as(systemActor).system(modelRunnerConsumer); return systemPart; }
/** * Defines an "autonomous system reaction", meaning the system will react * without needing an event provided via {@link ModelRunner#reactTo(Object)}. * * @param autonomousSystemReaction * the autonomous system reaction * @return the created system part of this step */ public StepSystemPart<ModelRunner> system(Runnable autonomousSystemReaction) { Objects.requireNonNull(autonomousSystemReaction); AutonomousSystemReaction wrappedSystemReaction = new AutonomousSystemReaction(autonomousSystemReaction); StepSystemPart<ModelRunner> systemPart = system(wrappedSystemReaction); return systemPart; }
public UseCasePart continuesWithoutAlternativeAt(String stepName) { system(new ContinuesWithoutAlternativeAt(stepName, (FlowStep)step)); return stepPart.getUseCasePart(); } }
public UseCasePart continuesAt(String stepName) { system(new ContinuesAt(stepName, step.getUseCase())); return stepPart.getUseCasePart(); }
public UseCasePart continuesAfter(String stepName) { system(new ContinuesAfter(stepName, step.getUseCase())); return stepPart.getUseCasePart(); }
/** * Includes the use case with the specified name. * * The runner starts the included use case right after the current step. The * runner returns to the current flow when it reaches the end of an included * flow. The runner then continues after the current step of the current flow. * * @param useCaseName * the name of the use case to include * @return the step system part, to ease creation of further steps and flows * @throws NoSuchElementInModel * if the included use case has not been specified before */ public StepSystemPart<ModelRunner> includesUseCase(String useCaseName) { FlowStep flowStep = (FlowStep) step; UseCase includedUseCase = flowStep.getModel().findUseCase(useCaseName); StepSystemPart<ModelRunner> stepSystemPart = as(systemActor) .system(new IncludesUseCase(includedUseCase, flowStep)); return stepSystemPart; }
public Model buildWith(ModelBuilder modelBuilder) { normalUser = modelBuilder.actor("Normal User"); anonymousUser = modelBuilder.actor("Anonymous User"); Model model = modelBuilder.useCase("Get greeted") .basicFlow() .step("S1").as(normalUser).system(this::promptsUserToEnterFirstName) .step("S2").as(normalUser).user(ENTERS_FIRST_NAME).system(this::savesFirstName) .step("S3").as(normalUser, anonymousUser).system(this::promptsUserToEnterAge) .step("S4").as(normalUser, anonymousUser).user(ENTERS_AGE).system(this::savesAge) .step("S5").as(normalUser).system(this::greetsUserWithFirstName) .step("S6").as(normalUser, anonymousUser).system(this::greetsUserWithAge) .step("S7").as(normalUser, anonymousUser).system(this::stops) .flow("Handle out-of-bounds age").insteadOf("S5").condition(this::ageIsOutOfBounds) .step("S5a_1").system(this::informsUserAboutOutOfBoundsAge) .step("S5a_2").continuesAt("S3") .flow("Handle non-numerical age").insteadOf("S5") .step("S5b_1").on(NON_NUMERICAL_AGE).system(this::informsUserAboutNonNumericalAge) .step("S5b_2").continuesAt("S3") .flow("Anonymous greeted with age only").insteadOf("S5").condition(this::ageIsOk) .step("S5c_1").as(anonymousUser).continuesAt("S6") .flow("Anonymous does not enter name").insteadOf("S1") .step("S1a_1").as(anonymousUser).continuesAt("S3") .build(); return model; }
@Test public void printsTextAutonomouslyOnlyIfActorIsRightInFirstStep() { Model model = modelBuilder .useCase(USE_CASE) .basicFlow() .step(SYSTEM_DISPLAYS_TEXT).as(customer).system(displaysConstantText()) .step(SYSTEM_DISPLAYS_TEXT_AGAIN).as(secondActor).system(displaysConstantText()) .build(); modelRunner.as(customer).run(model); assertRecordedStepNames(SYSTEM_DISPLAYS_TEXT); }
@Test public void createsSingleStepThatPerformsSystemReactionAutomaticallyForSpecificActor() { UseCasePart useCasePart = modelBuilder.useCase(USE_CASE); Model model = useCasePart.basicFlow() .step(SYSTEM_DISPLAYS_TEXT).as(customer).system(displaysConstantText()) .build(); Collection<Step> steps = useCasePart.getUseCase().getSteps(); assertEquals(1, steps.size()); Step step = steps.iterator().next(); assertEquals(SYSTEM_DISPLAYS_TEXT, step.getName()); assertEquals(USE_CASE, step.getUseCase().getName()); assertTrue(model.hasActor(customer.getName())); assertEquals(customer, step.getActors()[0]); }
@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); }
.step("S3").as(firstActor).user(entersName()).system(greetsUser()).reactWhile(someConditionIsFulfilled()) .step("S4").as(firstActor, secondActor).user(decidesToQuit()) .step("S5").as(firstActor, secondActor).system(promptsUserToEnterName()) .step("S6").system(quits()) .flow("Alternative flow A").insteadOf("S4")