001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.scxml2;
018
019import java.util.Set;
020
021import org.apache.commons.scxml2.model.EnterableState;
022import org.apache.commons.scxml2.model.TransitionTarget;
023import org.junit.Assert;
024import org.junit.Test;
025/**
026 * Unit tests for testing conflict resolution amongst multiple transitions
027 * within the {@link org.apache.commons.scxml2.SCXMLExecutor}'s default
028 * semantics.
029 *
030 * Upto v0.6, non-deterministic behavior leads to an error condition. Based
031 * on the February 2007 WD, such non-determinism should now be resolved
032 * based on document order and heirarchy of states within the state machine.
033 * This class tests various such cases where more than one candidate
034 * transition exists at a particular point, and tie-breaking rules are used
035 * to make progress, rather than resulting in error conditions.
036 */
037public class TieBreakerTest {
038
039    @Test
040    public void testTieBreaker01() throws Exception {
041        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/tie-breaker-01.xml");
042        exec.go();
043        Set<EnterableState> currentStates = exec.getStatus().getStates();
044        Assert.assertEquals(1, currentStates.size());
045        Assert.assertEquals("ten", currentStates.iterator().next().getId());
046        currentStates = SCXMLTestHelper.fireEvent(exec, "done.state.ten");
047        Assert.assertEquals(1, currentStates.size());
048        Assert.assertEquals("twenty", currentStates.iterator().next().getId());
049    }
050
051    @Test
052    public void testTieBreaker02() throws Exception {
053        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/tie-breaker-02.xml");
054        exec.go();
055        Set<EnterableState> currentStates = exec.getStatus().getStates();
056        Assert.assertEquals(1, currentStates.size());
057        Assert.assertEquals("eleven", currentStates.iterator().next().getId());
058        currentStates = SCXMLTestHelper.fireEvent(exec, "done.state.ten");
059        Assert.assertEquals(1, currentStates.size());
060        Assert.assertEquals("thirty", currentStates.iterator().next().getId());
061    }
062
063    @Test
064    public void testTieBreaker03() throws Exception {
065        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/tie-breaker-03.xml");
066        exec.go();
067        Set<EnterableState> currentStates = exec.getStatus().getStates();
068        Assert.assertEquals(1, currentStates.size());
069        Assert.assertEquals("eleven", currentStates.iterator().next().getId());
070        currentStates = SCXMLTestHelper.fireEvent(exec, "done.state.ten");
071        Assert.assertEquals(1, currentStates.size());
072        Assert.assertEquals("forty", currentStates.iterator().next().getId());
073    }
074
075    @Test
076    public void testTieBreaker04() throws Exception {
077        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/tie-breaker-04.xml");
078        exec.go();
079        Set<EnterableState> currentStates = SCXMLTestHelper.fireEvent(exec, "event_2");
080        Assert.assertEquals(1, currentStates.size());
081        currentStates = SCXMLTestHelper.fireEvent(exec, "event_1");
082        Assert.assertEquals(1, currentStates.size());
083    }
084
085    @Test
086    public void testTieBreaker05() throws Exception {
087        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/tie-breaker-05.xml");
088        exec.go();
089        Set<EnterableState> currentStates = exec.getStatus().getStates();
090        Assert.assertEquals(3, currentStates.size());
091        for (TransitionTarget tt : currentStates) {
092            String id = tt.getId();
093            Assert.assertTrue(id.equals("s11") || id.equals("s212")
094                || id.equals("s2111"));
095        }
096        currentStates = SCXMLTestHelper.fireEvent(exec, "event1");
097        Assert.assertEquals(3, currentStates.size());
098        for (TransitionTarget tt : currentStates) {
099            String id = tt.getId();
100            Assert.assertTrue(id.equals("s12") || id.equals("s212")
101                || id.equals("s2112"));
102        }
103    }
104
105    @Test
106    public void testTieBreaker06() throws Exception {
107        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/tie-breaker-06.xml");
108        exec.go();
109        Set<EnterableState> currentStates = exec.getStatus().getStates();
110        Assert.assertEquals(1, currentStates.size());
111    }
112}