@Test public void createsTwoStepsWithoutFlow() { UseCasePart useCasePart = modelBuilder.useCase(USE_CASE); useCasePart .on(EntersText.class).system(displaysEnteredText()) .on(EntersNumber.class).system(displaysEnteredNumber()) .build(); Collection<Step> steps = useCasePart.getUseCase().getSteps(); assertEquals(2, steps.size()); Iterator<Step> stepIt = steps.iterator(); Step step = stepIt.next(); assertEquals("S1", step.getName()); assertEquals(USE_CASE, step.getUseCase().getName()); step = stepIt.next(); assertEquals("S2", step.getName()); assertEquals(USE_CASE, step.getUseCase().getName()); }
@Test public void continueRecordingAfterRestart() { Model model = modelBuilder.useCase(USE_CASE) .on(EntersText.class).system(displaysEnteredText()) .on(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model).startRecording(); modelRunner.reactTo(entersText()); modelRunner.restart(); modelRunner.reactTo(entersNumber()); assertEquals(2, modelRunner.getRecordedEvents().length); assertEquals(EntersText.class, modelRunner.getRecordedEvents()[0].getClass()); assertEquals(EntersNumber.class, modelRunner.getRecordedEvents()[1].getClass()); assertEquals(2, modelRunner.getRecordedStepNames().length); assertEquals("S1", modelRunner.getRecordedStepNames()[0]); assertEquals("S2", modelRunner.getRecordedStepNames()[1]); } }
@Test public void noMoreRecordingAfterRecordingIsStopped() { Model model = modelBuilder.useCase(USE_CASE) .on(EntersText.class).system(displaysEnteredText()) .on(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model).startRecording(); modelRunner.reactTo(entersText()); modelRunner.stopRecording(); modelRunner.reactTo(entersNumber()); assertEquals(1, modelRunner.getRecordedEvents().length); assertEquals(EntersText.class, modelRunner.getRecordedEvents()[0].getClass()); assertEquals(1, modelRunner.getRecordedStepNames().length); assertEquals("S1", modelRunner.getRecordedStepNames()[0]); }
@Test public void recordMultipleEvents_startRecordingBeforeRunning() { Model model = modelBuilder.useCase(USE_CASE) .on(EntersText.class).system(displaysEnteredText()) .on(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.startRecording().run(model); modelRunner.reactTo(entersText(), entersNumber()); assertEquals(2, modelRunner.getRecordedEvents().length); assertEquals(EntersText.class, modelRunner.getRecordedEvents()[0].getClass()); assertEquals(EntersNumber.class, modelRunner.getRecordedEvents()[1].getClass()); assertEquals(2, modelRunner.getRecordedStepNames().length); assertEquals("S1", modelRunner.getRecordedStepNames()[0]); assertEquals("S2", modelRunner.getRecordedStepNames()[1]); }
@Test public void extractsFlowlessModel() throws Exception { Model model = Model.builder() .on(entersName()).system(greetsUser()) .on(Exception.class).system(logsException()) .build(); String templateFileName = "testextract_flowless.ftl"; Writer outputWriter = new StringWriter(); engine.extract(model, templateFileName, outputWriter); String output = outputWriter.toString(); assertEquals( "Use case: Handles events." + " Step: S1. On EntersName: System greets user." + " Step: S2. On Exception: System logs exception.", output); }
@Test public void recordMultipleEvents_startRecordingAfterRunning() { Model model = modelBuilder.useCase(USE_CASE) .on(EntersText.class).system(displaysEnteredText()) .on(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model).startRecording(); modelRunner.reactTo(entersText(), entersNumber()); assertEquals(2, modelRunner.getRecordedEvents().length); assertEquals(EntersText.class, modelRunner.getRecordedEvents()[0].getClass()); assertEquals(EntersNumber.class, modelRunner.getRecordedEvents()[1].getClass()); assertEquals(2, modelRunner.getRecordedStepNames().length); assertEquals("S1", modelRunner.getRecordedStepNames()[0]); assertEquals("S2", modelRunner.getRecordedStepNames()[1]); }
@Test public void createsSingleStepThatHandlesUserCommandWithUseCaseButWithoutFlow() { UseCasePart useCasePart = modelBuilder.useCase(USE_CASE); Model model = useCasePart .on(EntersText.class).system(displaysEnteredText()) .build(); UseCase useCase = useCasePart.getUseCase(); Collection<Step> steps = useCase.getSteps(); assertEquals(1, steps.size()); Step step = steps.iterator().next(); assertEquals("S1", step.getName()); assertEquals(USE_CASE, step.getUseCase().getName()); assertEquals(model.getSystemActor(), step.getActors()[0]); }
@Test public void recordsStepWithEvent() { ReactionAsConsumer reactionAsConsumer = new ReactionAsConsumer(); Model model = modelBuilder.useCase(USE_CASE).condition(new AlwaysTrue()).on(EntersText.class) .system(reactionAsConsumer).build(); modelRunner.handleWith(recordStepDetails()); modelRunner.run(model); modelRunner.reactTo(entersText()); Object condition = optionalCondition.get(); assertTrue(condition instanceof AlwaysTrue); Object event = optionalEvent.get(); assertTrue(event instanceof EntersText); assertEquals(reactionAsConsumer, systemReaction); }
@Test public void twoFlowlessStepsDontReactWhenConditionIsFalseInSecondStepWithoutUseCase() { Model model = modelBuilder .on(EntersText.class).system(displaysEnteredText()) .condition(() -> false).on(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model); Optional<Step> latestStepRun = modelRunner.reactTo(entersText()); assertEquals(EntersText.class, latestStepRun.get().getEventClass()); latestStepRun = modelRunner.reactTo(entersNumber()); assertEquals(EntersText.class, latestStepRun.get().getEventClass()); } }
@Test public void twoFlowlessStepsReactToEventsOfDifferentTypeInDifferentUseCases() { Model model = modelBuilder .useCase(USE_CASE) .on(EntersText.class).system(displaysEnteredText()) .useCase(USE_CASE_2) .on(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model); Optional<Step> latestStepRun = modelRunner.reactTo(entersNumber()); assertEquals(EntersNumber.class, latestStepRun.get().getEventClass()); latestStepRun = modelRunner.reactTo(entersText()); assertEquals(EntersText.class, latestStepRun.get().getEventClass()); }
public <T> FlowlessUserPart<T> on(Class<T> eventOrExceptionClass) { FlowlessUserPart<T> flowless = new FlowlessUserPart<>(optionalCondition, eventOrExceptionClass, flowlessStepCounter); return flowless; }
public <T> FlowlessSystemPart<ModelRunner> system(Runnable systemReaction) { AutonomousSystemReaction autonomousSystemReaction = new AutonomousSystemReaction(systemReaction); return on(ModelRunner.class).system(autonomousSystemReaction); }
@Test public void twoFlowlessStepsReactWhenConditionIsTrueInSecondStepWithoutUseCase() { Model model = modelBuilder .on(EntersText.class).system(displaysEnteredText()) .condition(() -> true).on(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model); Optional<Step> latestStepRun = modelRunner.reactTo(entersText()); assertEquals(EntersText.class, latestStepRun.get().getEventClass()); latestStepRun = modelRunner.reactTo(entersNumber()); assertEquals(EntersNumber.class, latestStepRun.get().getEventClass()); }
@Test public void twoFlowlessStepsReactToEventsOfDifferentTypeInWrongOrderWithoutUseCase() { Model model = modelBuilder .on(EntersText.class).system(displaysEnteredText()) .on(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model); Optional<Step> latestStepRun = modelRunner.reactTo(entersNumber()); assertEquals(EntersNumber.class, latestStepRun.get().getEventClass()); latestStepRun = modelRunner.reactTo(entersText()); assertEquals(EntersText.class, latestStepRun.get().getEventClass()); }
@Test public void twoFlowlessStepsReactToEventsOfDifferentTypeInRightOrderWithoutUseCase() { Model model = modelBuilder .on(EntersText.class).system(displaysEnteredText()) .on(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model); Optional<Step> latestStepRun = modelRunner.reactTo(entersText()); assertEquals(EntersText.class, latestStepRun.get().getEventClass()); latestStepRun = modelRunner.reactTo(entersNumber()); assertEquals(EntersNumber.class, latestStepRun.get().getEventClass()); }
@Test public void twoFlowlessStepsReactWhenConditionIsTrueInSecondStepWithEvent() { Model model = modelBuilder.useCase(USE_CASE) .on(EntersText.class).system(displaysEnteredText()) .condition(() -> true).on(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model); Optional<Step> latestStepRun = modelRunner.reactTo(entersText()); assertEquals(EntersText.class, latestStepRun.get().getEventClass()); latestStepRun = modelRunner.reactTo(entersNumber()); assertEquals(EntersNumber.class, latestStepRun.get().getEventClass()); }
@Test public void twoFlowlessStepsReactToEventsOfDifferentTypeInRightOrder() { Model model = modelBuilder.useCase(USE_CASE) .on(EntersText.class).system(displaysEnteredText()) .on(EntersNumber.class).system(displaysEnteredNumber()) .build(); modelRunner.run(model); Optional<Step> latestStepRun = modelRunner.reactTo(entersText()); assertEquals(EntersText.class, latestStepRun.get().getEventClass()); latestStepRun = modelRunner.reactTo(entersNumber()); assertEquals(EntersNumber.class, latestStepRun.get().getEventClass()); }
@Test public void recordIsEmptyIfRecordingWasStoppedBeforeBeingStarted() { Model model = modelBuilder.useCase(USE_CASE) .on(EntersText.class).system(displaysEnteredText()) .build(); modelRunner.run(model).stopRecording(); assertEquals(0, modelRunner.getRecordedEvents().length); assertEquals(0, modelRunner.getRecordedStepNames().length); }
@Test public void recordIsEmptyForFreshlyRunModel() { Model model = modelBuilder.useCase(USE_CASE) .on(EntersText.class).system(displaysEnteredText()) .build(); modelRunner.run(model); assertEquals(0, modelRunner.getRecordedEvents().length); assertEquals(0, modelRunner.getRecordedStepNames().length); }
private FlowlessUserPart(Condition optionalCondition, Class<T> eventOrExceptionClass, long flowlessStepCounter) { this.flowlessStepCounter = flowlessStepCounter; StepPart stepPart = createStepPart(optionalCondition, eventOrExceptionClass, "S" + flowlessStepCounter); this.userPart = stepPart.on(eventOrExceptionClass); }