package org.requirementsascode;

import static org.junit.Assert.assertEquals;

import org.junit.Before;
import org.junit.Test;

public class IncludeTest extends AbstractTestCase{
    private static final String SYSTEM_INCLUDES_USE_CASE = "Step that includes use case";
    private static final String SYSTEM_INCLUDES_USE_CASE_2 = "Another step that includes use case";
    private static final String INCLUDED_USE_CASE = "Included use case";

    @Before
    public void setup() {
      setupWith(new TestUseCaseModelRunner());
    }

    @Test
    public void includeBasicFlowOnce() {
      UseCaseModel useCaseModel = useCaseModelBuilder
        .useCase(INCLUDED_USE_CASE)
          .basicFlow()
            .step(SYSTEM_DISPLAYS_NUMBER).user(EnterNumber.class).system(displayEnteredNumber())
        .useCase(USE_CASE)
          .basicFlow()
            .step(SYSTEM_DISPLAYS_TEXT).user(EnterText.class).system(displayEnteredText())
            .step(SYSTEM_INCLUDES_USE_CASE).include(INCLUDED_USE_CASE)
            .step(SYSTEM_DISPLAYS_TEXT_AGAIN).system(displayConstantText())
        .build();
      
    useCaseModelRunner.run(useCaseModel);
    useCaseModelRunner.reactTo(enterText(), enterNumber());

    String expectedSteps =
        SYSTEM_DISPLAYS_TEXT + ";"
            + SYSTEM_INCLUDES_USE_CASE + ";"
            + SYSTEM_DISPLAYS_NUMBER + ";"
            + SYSTEM_DISPLAYS_TEXT_AGAIN + ";";
    assertEquals(expectedSteps, runStepNames());
  }
    
  @Test
  public void includeBasicFlowTwoNonConsecutiveTimes() {
      UseCaseModel useCaseModel = useCaseModelBuilder
        .useCase(INCLUDED_USE_CASE)
          .basicFlow()
            .step(SYSTEM_DISPLAYS_NUMBER).user(EnterNumber.class).system(displayEnteredNumber())
        .useCase(USE_CASE)
          .basicFlow()
            .step(SYSTEM_DISPLAYS_TEXT).user(EnterText.class).system(displayEnteredText())
            .step(SYSTEM_INCLUDES_USE_CASE).include(INCLUDED_USE_CASE)
            .step(SYSTEM_DISPLAYS_TEXT_AGAIN).system(displayConstantText())
            .step(SYSTEM_INCLUDES_USE_CASE_2).include(INCLUDED_USE_CASE)
        .build();
      
    useCaseModelRunner.run(useCaseModel);
    useCaseModelRunner.reactTo(enterText(), enterNumber(), enterNumber());

    String expectedSteps =
        SYSTEM_DISPLAYS_TEXT + ";"
            + SYSTEM_INCLUDES_USE_CASE + ";"
            + SYSTEM_DISPLAYS_NUMBER + ";"
            + SYSTEM_DISPLAYS_TEXT_AGAIN + ";"
            + SYSTEM_INCLUDES_USE_CASE_2 + ";"
            + SYSTEM_DISPLAYS_NUMBER + ";";
    assertEquals(expectedSteps, runStepNames());
  }
    
  @Test
  public void includedBasicFlowCanBeRunOnItsOwn() {
      UseCaseModel useCaseModel = useCaseModelBuilder
        .useCase(INCLUDED_USE_CASE)
          .basicFlow()
            .step(SYSTEM_DISPLAYS_NUMBER).user(EnterNumber.class).system(displayEnteredNumber())
        .useCase(USE_CASE)
          .basicFlow()
            .step(SYSTEM_DISPLAYS_TEXT).user(EnterText.class).system(displayEnteredText())
            .step(SYSTEM_INCLUDES_USE_CASE).include(INCLUDED_USE_CASE)
        .build();
      
    useCaseModelRunner.run(useCaseModel);
    useCaseModelRunner.reactTo(enterNumber());

    assertEquals(SYSTEM_DISPLAYS_NUMBER + ";", runStepNames());
  }
}

@@ -574,16 +574,824 @@
 FlowOnce
+AtFirstStep() %7B%0A      UseCaseModel useCaseModel = useCaseModelBuilder%0A        .useCase(INCLUDED_USE_CASE)%0A          .basicFlow().when(r -%3E false)%0A            .step(SYSTEM_DISPLAYS_NUMBER).user(EnterNumber.class).system(displayEnteredNumber())%0A        .useCase(USE_CASE)%0A          .basicFlow()%0A            .step(SYSTEM_INCLUDES_USE_CASE).include(INCLUDED_USE_CASE)%0A            .step(SYSTEM_DISPLAYS_TEXT).system(displayConstantText())%0A        .build();%0A      %0A    useCaseModelRunner.run(useCaseModel);%0A    useCaseModelRunner.reactTo(enterNumber());%0A%0A    String expectedSteps =%0A        SYSTEM_INCLUDES_USE_CASE + %22;%22%0A        + SYSTEM_DISPLAYS_NUMBER + %22;%22%0A        + SYSTEM_DISPLAYS_TEXT + %22;%22;%0A    assertEquals(expectedSteps, runStepNames());%0A  %7D%0A    %0A    @Test%0A    public void includeBasicFlowOnceAtSecondStep
 () %7B%0A   

Include basic flow at first step