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.HashMap;
020import java.util.HashSet;
021import java.util.Map;
022import java.util.Set;
023
024import org.apache.commons.scxml2.model.EnterableState;
025import org.apache.commons.scxml2.model.TransitionTarget;
026import org.junit.Assert;
027import org.junit.Test;
028/**
029 * Unit tests {@link org.apache.commons.scxml2.SCXMLExecutor}.
030 */
031public class SCXMLExecutorTest {
032
033    /**
034     * Test the implementation
035     */
036    @Test
037    public void testSCXMLExecutorMicrowave01JexlSample() throws Exception {
038        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/env/jexl/microwave-01.xml");
039        exec.go();
040        checkMicrowave01Sample(exec);
041    }
042
043    @Test
044    public void testSCXMLExecutorMicrowave02JexlSample() throws Exception {
045        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/env/jexl/microwave-02.xml");
046        exec.go();
047        checkMicrowave02Sample(exec);
048    }
049
050    @Test
051    public void testSCXMLExecutorMicrowave03JexlSample() throws Exception {
052        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/env/jexl/microwave-03.xml");
053        exec.go();
054        checkMicrowave01Sample(exec);
055    }
056
057    @Test
058    public void testSCXMLExecutorMicrowave04JexlSample() throws Exception {
059        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/env/jexl/microwave-04.xml");
060        exec.go();
061        checkMicrowave02Sample(exec);
062    }
063
064    @Test
065    public void testSCXMLExecutorMicrowave05JexlSample() throws Exception {
066        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/env/jexl/microwave-05.xml");
067        exec.go();
068        checkMicrowave02Sample(exec);
069    }
070
071    @Test
072    public void testSCXMLExecutorMicrowave01grvSample() throws Exception {
073        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/env/groovy/microwave-01.xml");
074        exec.go();
075        checkMicrowave01Sample(exec);
076    }
077
078    @Test
079    public void testSCXMLExecutorMicrowave02grvSample() throws Exception {
080        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/env/groovy/microwave-02.xml");
081        exec.go();
082        checkMicrowave02Sample(exec);
083    }
084
085    @Test
086    public void testSCXMLExecutorMicrowave03grvSample() throws Exception {
087        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/env/groovy/microwave-03.xml");
088        exec.go();
089        checkMicrowave01Sample(exec);
090    }
091
092    @Test
093    public void testSCXMLExecutorMicrowave04grvSample() throws Exception {
094        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/env/groovy/microwave-04.xml");
095        exec.go();
096        checkMicrowave02Sample(exec);
097    }
098
099    @Test
100    public void testSCXMLExecutorMicrowave05grvSample() throws Exception {
101        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/env/groovy/microwave-05.xml");
102        exec.go();
103        checkMicrowave02Sample(exec);
104    }
105
106    @Test
107    public void testSCXMLExecutorPrefix01Sample() throws Exception {
108        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/prefix-01.xml");
109        exec.go();
110        Set<EnterableState> currentStates = exec.getStatus().getStates();
111        Assert.assertEquals(1, currentStates.size());
112        Assert.assertEquals("ten", currentStates.iterator().next().getId());
113        currentStates = SCXMLTestHelper.fireEvent(exec, "done.state.ten");
114        Assert.assertEquals(1, currentStates.size());
115        Assert.assertEquals("twenty", currentStates.iterator().next().getId());
116    }
117
118    @Test
119    public void testSCXMLExecutorTransitions01Sample() throws Exception {
120        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/transitions-01.xml");
121        exec.go();
122        Set<EnterableState> currentStates = SCXMLTestHelper.fireEvent(exec, "done.state.ten");
123        Assert.assertEquals(1, currentStates.size());
124        Assert.assertEquals("twenty_one", currentStates.iterator().next().getId());
125        currentStates = SCXMLTestHelper.fireEvent(exec, "done.state.twenty_one");
126        Assert.assertEquals(1, currentStates.size());
127        Assert.assertEquals("twenty_two", currentStates.iterator().next().getId());
128        SCXMLTestHelper.fireEvent(exec, "done.state.twenty_two");
129        Assert.assertEquals(3, exec.getStatus().getStates().size());
130    }
131
132    @Test
133    public void testSCXMLExecutorTransitions02Sample() throws Exception {
134        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/transitions-02.xml");
135        exec.go();
136        Set<EnterableState> currentStates = SCXMLTestHelper.fireEvent(exec, "ten.stay");
137        Assert.assertEquals(1, currentStates.size());
138        Assert.assertEquals("ten", currentStates.iterator().next().getId());
139        exec = SCXMLTestHelper.testInstanceSerializability(exec);
140        currentStates = SCXMLTestHelper.fireEvent(exec, "ten.self");
141        Assert.assertEquals(1, currentStates.size());
142        Assert.assertEquals("ten", currentStates.iterator().next().getId());
143        currentStates = SCXMLTestHelper.fireEvent(exec, "done.state.ten");
144        Assert.assertEquals(1, currentStates.size());
145        Assert.assertEquals("twenty", currentStates.iterator().next().getId());
146    }
147
148    @Test
149    public void testSCXMLExecutorTransitions03Sample() throws Exception {
150        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/transitions-03.xml");
151        exec.go();
152        Set<EnterableState> currentStates = SCXMLTestHelper.fireEvent(exec, "done.state.ten");
153        Assert.assertEquals(3, currentStates.size());
154        Set<String> expected = new HashSet<String>();
155        expected.add("twenty_one_2");
156        expected.add("twenty_two_2");
157        expected.add("twenty_three_2");
158        for (TransitionTarget tt : currentStates) {
159            if (!expected.remove(tt.getId())) {
160                Assert.fail("'" + tt.getId()
161                    + "' is not an expected current state ID");
162            }
163        }
164    }
165
166    @Test
167    public void testSCXMLExecutorTransitions04Sample() throws Exception {
168        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/transitions-04.xml");
169        exec.go();
170        Set<EnterableState> currentStates = SCXMLTestHelper.fireEvent(exec, "done.state.ten");
171        Assert.assertEquals(3, currentStates.size());
172        Set<String> expected = new HashSet<String>();
173        expected.add("twenty_one_1");
174        expected.add("twenty_two_1");
175        expected.add("twenty_three_1");
176        for (TransitionTarget tt : currentStates) {
177            if (!expected.remove(tt.getId())) {
178                Assert.fail("'" + tt.getId()
179                    + "' is not an expected current state ID");
180            }
181        }
182        currentStates = SCXMLTestHelper.fireEvent(exec, "bar");
183        Assert.assertEquals(1, currentStates.size());
184        Assert.assertEquals("thirty", (currentStates.iterator().
185            next()).getId());
186    }
187
188    @Test
189    public void testSCXMLExecutorTransitions05Sample() throws Exception {
190        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/transitions-05.xml");
191        exec.go();
192        SCXMLTestHelper.assertPostTriggerState(exec, "foo", "end");
193    }
194
195    @Test
196    public void testSCXMLExecutorTransitions06Sample() throws Exception {
197        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/transitions-06.xml");
198        exec.go();
199        SCXMLTestHelper.assertPostTriggerStates(exec, "start", new String[]{"one", "two"});
200        SCXMLTestHelper.assertPostTriggerState(exec, "onetwo_three", "three");
201        SCXMLTestHelper.assertPostTriggerStates(exec, "three_one", new String[]{"one", "two"});
202        SCXMLTestHelper.assertPostTriggerState(exec, "two_four", "four");
203    }
204
205    @Test
206    public void testSend01Sample() throws Exception {
207        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/send-01.xml");
208        exec.go();
209        Set<EnterableState> currentStates = exec.getStatus().getStates();
210        Assert.assertEquals(1, currentStates.size());
211        Assert.assertEquals("ten", currentStates.iterator().next().getId());
212        currentStates = SCXMLTestHelper.fireEvent(exec, "done.state.ten");
213        Assert.assertEquals(1, currentStates.size());
214        Assert.assertEquals("twenty", currentStates.iterator().next().getId());
215    }
216
217    @Test
218    public void testSend02TypeSCXMLSample() throws Exception {
219        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/send-02.xml");
220        exec.go();
221        Set<EnterableState> currentStates = exec.getStatus().getStates();
222        Assert.assertEquals(1, currentStates.size());
223        Assert.assertEquals("ninety", currentStates.iterator().next().getId());
224        Assert.assertTrue(exec.getStatus().isFinal());
225    }
226
227    @Test
228    public void testSCXMLExecutorTransitionsWithCond01Sample() throws Exception {
229        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/transitions-with-cond-01.xml");
230        exec.go();
231        Map<String, Object> payload = new HashMap<String, Object>();
232
233        // with _event.data set to true, transition should happen as expected.
234        payload.put("keyed", Boolean.TRUE);
235        SCXMLTestHelper.assertPostTriggerState(exec, "open", payload, "opened");
236        // turn back to closed
237        SCXMLTestHelper.assertPostTriggerState(exec, "close", payload, "closed");
238
239        // with _event.data set to false, transition shouldn't happen as expected.
240        payload.put("keyed", Boolean.FALSE);
241        SCXMLTestHelper.assertPostTriggerState(exec, "open", payload, "closed");
242
243        // with _event.data set to null, transition shouldn't happen as expected.
244        payload.clear();
245        SCXMLTestHelper.assertPostTriggerState(exec, "open", payload, "closed");
246
247        // with _event.data set to null, transition shouldn't happen as expected.
248        SCXMLTestHelper.assertPostTriggerState(exec, "open", null, "closed");
249
250        // transition to locked for testing
251        SCXMLTestHelper.assertPostTriggerState(exec, "lock", null, "locked");
252        // due to intentional expression syntax error, it catches an exception and so treat the cond as false
253        SCXMLTestHelper.assertPostTriggerState(exec, "unlock", null, "locked");
254    }
255
256    @Test
257    public void testSCXMLExecutorSystemEventVariable() throws Exception {
258        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/transitions-event-variable.xml");
259        exec.go();
260        Map<String, Object> payload = new HashMap<String, Object>();
261        payload.put("keyed", Boolean.TRUE);
262        SCXMLTestHelper.assertPostTriggerState(exec, "open", payload, "opened");
263    }
264
265    @Test
266    public void testSCXMLExecutorSetConfiguration() throws Exception {
267        SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/transitions-01.xml");
268        exec.go();
269        Set<EnterableState> currentStates = SCXMLTestHelper.fireEvent(exec, "done.state.ten");
270        Assert.assertEquals(1, currentStates.size());
271        Assert.assertEquals("twenty_one", currentStates.iterator().next().getId());
272        currentStates = SCXMLTestHelper.fireEvent(exec, "done.state.twenty_one");
273        Assert.assertEquals(1, currentStates.size());
274        Assert.assertEquals("twenty_two", currentStates.iterator().next().getId());
275        Set<String> stateIds = new HashSet<String>();
276        stateIds.add("twenty_one");
277        exec.setConfiguration(stateIds);
278        Assert.assertEquals(1, exec.getStatus().getStates().size());
279        SCXMLTestHelper.fireEvent(exec, "done.state.twenty_one");
280        Assert.assertEquals(1, currentStates.size());
281        Assert.assertEquals("twenty_two", currentStates.iterator().next().getId());
282    }
283
284    private void checkMicrowave01Sample(SCXMLExecutor exec) throws Exception {
285        Set<EnterableState> currentStates = SCXMLTestHelper.fireEvent(exec, "turn_on");
286        Assert.assertEquals(1, currentStates.size());
287        Assert.assertEquals("cooking", currentStates.iterator().next().getId());
288    }
289
290    private void checkMicrowave02Sample(SCXMLExecutor exec) throws Exception {
291        Set<EnterableState> currentStates = SCXMLTestHelper.fireEvent(exec, "turn_on");
292        Assert.assertEquals(2, currentStates.size());
293        String id = (currentStates.iterator().next()).getId();
294        Assert.assertTrue(id.equals("closed") || id.equals("cooking"));
295    }
296}