/** The exit action must be part of the reaction effect sequence */
  @SuppressWarnings("unused")
  @Test
  public void testStateReaction_WithEntryAction() {
    SimpleFlatTSC tsc = new SimpleFlatTSC();

    VariableDefinition v1 = _createVariableDefinition("v1", TYPE_INTEGER, tsc.s_scope);
    LocalReaction entryAction = _createEntryAction(tsc.s2);
    AssignmentExpression assign =
        _createVariableAssignment(
            v1,
            AssignmentOperator.ASSIGN,
            _createValue(21),
            (ReactionEffect) entryAction.getEffect());

    ExecutionFlow flow = sequencer.transform(tsc.sc);

    // test state with one outgoing transition
    ExecutionState _s1 = flow.getStates().get(0);
    ExecutionState _s2 = flow.getStates().get(1);
    assertEquals(tsc.s1.getName(), _s1.getSimpleName());
    assertEquals(tsc.s2.getName(), _s2.getSimpleName());

    assertEquals(1, _s1.getReactions().size());
    Reaction reaction = _s1.getReactions().get(0);

    assertNotNull(reaction.getCheck());

    assertNotNull(reaction.getEffect());
    Sequence seq = (Sequence) reaction.getEffect();
    assertEquals(2, seq.getSteps().size());

    assertCall(seq, 0, _s1.getExitSequence());
    assertCall(seq, 1, _s2.getEnterSequences().get(0));
    assertCall(_s2.getEnterSequences().get(0), 0, _s2.getEntryAction());
  }
  /** Local reactions must be created for behavior with 'always' trigger */
  @Test
  public void testAlwaysLocalReaction() {

    Statechart sc = _createStatechart("test");
    Scope scope = _createInterfaceScope("interface", sc);
    VariableDefinition v1 = _createVariableDefinition("v1", TYPE_INTEGER, scope);
    Region r = _createRegion("main", sc);
    State s = _createState("s", r);

    LocalReaction timeTriggeredReaction =
        _createLocalReaction(s, StextFactory.eINSTANCE.createAlwaysEvent());
    AssignmentExpression assign =
        _createVariableAssignment(
            v1,
            AssignmentOperator.ASSIGN,
            _createValue(42),
            (ReactionEffect) timeTriggeredReaction.getEffect());

    ExecutionFlow flow = sequencer.transform(sc);

    ExecutionState _s = flow.getStates().get(0);

    // assert that a local reaction is created
    Reaction reaction = _s.getReactions().get(0);
    PrimitiveValueExpression pve = (PrimitiveValueExpression) reaction.getCheck().getCondition();
    assertBoolLiteral(true, pve.getValue());
  }
  /** The transition action must be part of the reaction effect sequence */
  @Test
  public void testStateReaction_WithTransitionAction() {
    SimpleFlatTSC tsc = new SimpleFlatTSC();
    VariableDefinition v1 = _createVariableDefinition("v1", TYPE_INTEGER, tsc.s_scope);
    ReactionEffect effect = _createReactionEffect(tsc.t1);
    AssignmentExpression assign =
        _createVariableAssignment(v1, AssignmentOperator.ASSIGN, _createValue(42), effect);

    ExecutionFlow flow = sequencer.transform(tsc.sc);

    // test state with one outgoing transition
    ExecutionState s1 = flow.getStates().get(0);
    ExecutionState s2 = flow.getStates().get(1);
    assertEquals(tsc.s1.getName(), s1.getSimpleName());
    assertEquals(tsc.s2.getName(), s2.getSimpleName());

    assertEquals(1, s1.getReactions().size());
    Reaction reaction = s1.getReactions().get(0);

    assertNotNull(reaction.getCheck());

    assertNotNull(reaction.getEffect());
    Sequence seq = (Sequence) reaction.getEffect();

    assertCall(seq, 0, s1.getExitSequence());

    assertClass(Sequence.class, seq.getSteps().get(1));
    Execution _exec = (Execution) ((Sequence) seq.getSteps().get(1)).getSteps().get(0);
    AssignmentExpression _assign = (AssignmentExpression) _exec.getStatement();
    assertNotSame(_assign, assign);
    assertNotSame(_assign.getVarRef(), assign.getVarRef());
    assertNotSame(_assign.getVarRef(), v1);

    assertCall(seq, 2, s2.getEnterSequences().get(0));
  }
  @Test
  public void testTransitionCheckSequenceWithGuard() {

    EventDefinition e1 = _createEventDefinition("e1", null);
    EventDefinition e2 = _createEventDefinition("e2", null);

    ReactionTrigger tr1 = _createReactionTrigger(null);
    _createRegularEventSpec(e1, tr1);
    _createRegularEventSpec(e2, tr1);

    PrimitiveValueExpression exp = _createValue(false);
    tr1.setGuard(createGuardExpression(exp));

    Transition t = SGraphFactory.eINSTANCE.createTransition();
    t.setTrigger(tr1);

    Statechart sc = _createStatechart("test");
    Region region = _createRegion("r1", sc);
    t.setSource(_createState("A", region));
    t.setTarget(_createState("B", region));

    Reaction reaction = behaviorMapping.mapTransition(t);

    // now check the expression structure ...

    // the root is an and condition with the trigger check as the first
    // (left) part and the guard as the right (second) part.
    LogicalAndExpression and = (LogicalAndExpression) reaction.getCheck().getCondition();
    LogicalOrExpression triggerCheck = (LogicalOrExpression) and.getLeftOperand();
    PrimitiveValueExpression guardCheck = (PrimitiveValueExpression) and.getRightOperand();

    assertClass(ElementReferenceExpression.class, triggerCheck.getLeftOperand());
    assertClass(ElementReferenceExpression.class, triggerCheck.getRightOperand());
    assertEquals(
        e1.getName(),
        ((NamedElement) ((ElementReferenceExpression) triggerCheck.getLeftOperand()).getReference())
            .getName());
    assertEquals(
        e2.getName(),
        ((NamedElement)
                ((ElementReferenceExpression) triggerCheck.getRightOperand()).getReference())
            .getName());

    assertBoolLiteral(false, guardCheck.getValue());
  }
  @Test
  public void testStateReaction_SimpleFlatTSC() {
    SimpleFlatTSC tsc = new SimpleFlatTSC();

    ExecutionFlow flow = sequencer.transform(tsc.sc);

    // test state with one outgoing transition
    ExecutionState s1 = flow.getStates().get(0);
    ExecutionState s2 = flow.getStates().get(1);
    assertEquals(tsc.s1.getName(), s1.getSimpleName());
    assertEquals(tsc.s2.getName(), s2.getSimpleName());

    assertEquals(1, s1.getReactions().size());
    Reaction reaction = s1.getReactions().get(0);

    assertNotNull(reaction.getCheck());

    assertNotNull(reaction.getEffect());
    Sequence seq = (Sequence) reaction.getEffect();

    assertCall(seq, 0, s1.getExitSequence());
    assertCall(seq, 1, s2.getEnterSequences().get(0));
  }
  @Test
  public void testTransitionCheckSequenceWithoutTrigger() {

    ReactionTrigger tr1 = _createReactionTrigger(null);
    PrimitiveValueExpression exp = _createValue(false);
    tr1.setGuard(createGuardExpression(exp));

    Transition t = SGraphFactory.eINSTANCE.createTransition();
    t.setTrigger(tr1);

    Statechart sc = _createStatechart("test");
    Region region = _createRegion("r1", sc);
    t.setSource(_createState("A", region));
    t.setTarget(_createState("B", region));

    Reaction reaction = behaviorMapping.mapTransition(t);

    // now check the expression structure ...

    // the root is an and condition with the trigger check as the first
    // (left) part and the guard as the right (second) part.
    PrimitiveValueExpression guard = (PrimitiveValueExpression) reaction.getCheck().getCondition();
    assertBoolLiteral(false, guard.getValue());
  }
  @Test
  public void testTransitionCheckSequenceWithoutGuard() {

    EventDefinition e1 = _createEventDefinition("e1", null);
    EventDefinition e2 = _createEventDefinition("e2", null);

    ReactionTrigger tr1 = _createReactionTrigger(null);
    _createRegularEventSpec(e1, tr1);
    _createRegularEventSpec(e2, tr1);

    Transition t = SGraphFactory.eINSTANCE.createTransition();
    t.setTrigger(tr1);

    Statechart sc = _createStatechart("test");
    Region region = _createRegion("r1", sc);
    t.setSource(_createState("A", region));
    t.setTarget(_createState("B", region));

    Reaction reaction = behaviorMapping.mapTransition(t);

    assertTrue(reaction.getCheck().getCondition() instanceof LogicalOrExpression);
    assertClass(
        ElementReferenceExpression.class,
        ((LogicalOrExpression) reaction.getCheck().getCondition()).getLeftOperand());
    assertClass(
        ElementReferenceExpression.class,
        ((LogicalOrExpression) reaction.getCheck().getCondition()).getRightOperand());

    assertEquals(
        e1.getName(),
        ((NamedElement)
                ((ElementReferenceExpression)
                        ((LogicalOrExpression) reaction.getCheck().getCondition()).getLeftOperand())
                    .getReference())
            .getName());
    assertEquals(
        e2.getName(),
        ((NamedElement)
                ((ElementReferenceExpression)
                        ((LogicalOrExpression) reaction.getCheck().getCondition())
                            .getRightOperand())
                    .getReference())
            .getName());
  }