View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.scxml2.model;
18  
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.apache.commons.scxml2.SCXMLExecutor;
23  import org.apache.commons.scxml2.SCXMLTestHelper;
24  import org.junit.Assert;
25  import org.junit.Before;
26  import org.junit.Test;
27  
28  public class CustomActionTest {
29  
30      /**
31       * Set up instance variables required by this test case.
32       */
33      @Before
34      public void setUp() {
35          Hello.callbacks = 0;
36      }
37  
38      @Test
39      public void testAddGoodCustomAction01() throws Exception {
40          new CustomAction("http://my.actions.domain/CUSTOM", "hello",
41              Hello.class);
42      }
43  
44      @Test
45      public void testAddBadCustomAction01() {
46          try {
47              new CustomAction(null, "hello", Hello.class);
48              Assert.fail("Added custom action with illegal namespace");
49          } catch (IllegalArgumentException iae) {
50              // Expected
51          }
52      }
53  
54      @Test
55      public void testAddBadCustomAction02() {
56          try {
57              new CustomAction("  ", "hello", Hello.class);
58              Assert.fail("Added custom action with illegal namespace");
59          } catch (IllegalArgumentException iae) {
60              // Expected
61          }
62      }
63  
64      @Test
65      public void testAddBadCustomAction03() {
66          try {
67              new CustomAction("http://my.actions.domain/CUSTOM", "",
68                  Hello.class);
69              Assert.fail("Added custom action with illegal local name");
70          } catch (IllegalArgumentException iae) {
71              // Expected
72          }
73      }
74  
75      @Test
76      public void testAddBadCustomAction04() {
77          try {
78              new CustomAction("http://my.actions.domain/CUSTOM", "  ",
79                  Hello.class);
80              Assert.fail("Added custom action with illegal local name");
81          } catch (IllegalArgumentException iae) {
82              // Expected
83          }
84      }
85  
86      @Test
87      public void testAddBadCustomAction05() {
88          try {            
89              new CustomAction("http://www.w3.org/2005/07/scxml", "foo",
90                  Hello.class);
91              Assert.fail("Added custom action in the SCXML namespace");
92          } catch (IllegalArgumentException iae) {
93              // Expected
94          }
95      }
96  
97      // Hello World example using the SCXML <log> action
98      @Test
99      public void testHelloWorld() throws Exception {
100         // (1) Get a SCXMLExecutor
101         SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/hello-world.xml");
102         exec.go();
103         // (2) Single, final state
104         Assert.assertEquals("hello", (exec.getStatus().getStates().
105                 iterator().next()).getId());
106         Assert.assertTrue(exec.getStatus().isFinal());
107     }
108 
109     // Hello World example using a custom <hello> action
110     @Test
111     public void testCustomActionHelloWorld() throws Exception {
112         // (1) Form a list of custom actions defined in the SCXML
113         //     document (and any included documents via "src" attributes)
114         CustomAction ca1 =
115             new CustomAction("http://my.custom-actions.domain/CUSTOM1",
116                              "hello", Hello.class);
117         // Register the same action under a different name, just to test
118         // multiple custom actions
119         CustomAction ca2 =
120             new CustomAction("http://my.custom-actions.domain/CUSTOM2",
121                              "bar", Hello.class);
122         List<CustomAction> customActions = new ArrayList<CustomAction>();
123         customActions.add(ca1);
124         customActions.add(ca2);
125         // (2) Parse the document
126         SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/custom-hello-world-01.xml", customActions);
127         // (3) Get a SCXMLExecutor
128         SCXMLExecutor exec = SCXMLTestHelper.getExecutor(scxml);
129         exec.go();
130         // (4) Single, final state
131         Assert.assertEquals("custom", (exec.getStatus().getStates().
132                 iterator().next()).getId());
133         Assert.assertTrue(exec.getStatus().isFinal());
134 
135         // The custom action defined by Hello.class should be called
136         // to execute() exactly twice at this point (one by <my:hello/> and the other by <foo:bar/>).
137         Assert.assertEquals(2, Hello.callbacks);
138     }
139 
140     // Hello World example using custom <my:hello> action
141     // as part of an external state source (src attribute)
142     @Test
143     public void testCustomActionExternalSrcHelloWorld() throws Exception {
144         // (1) Form a list of custom actions defined in the SCXML
145         //     document (and any included documents via "src" attributes)
146         CustomAction ca =
147             new CustomAction("http://my.custom-actions.domain/CUSTOM",
148                              "hello", Hello.class);
149         List<CustomAction> customActions = new ArrayList<CustomAction>();
150         customActions.add(ca);
151         // (2) Parse the document
152         SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/external-hello-world.xml", customActions);
153         // (3) Get a SCXMLExecutor
154         SCXMLExecutor exec = SCXMLTestHelper.getExecutor(scxml);
155         exec.go();
156         // (4) Single, final state
157         Assert.assertEquals("custom", (exec.getStatus().getStates().
158             iterator().next()).getId());
159 
160         // The custom action defined by Hello.class should be called
161         // to execute() exactly twice at this point (one by <my:hello/> and the other by <my:hello/> in external).
162         Assert.assertEquals(2, Hello.callbacks);
163     }
164 
165     // Hello World example using custom <my:send> action
166     // (overriding SCXML local name "send")
167     @Test
168     public void testCustomActionOverrideLocalName() throws Exception {
169         // (1) List of custom actions, use same local name as SCXML action
170         CustomAction ca =
171             new CustomAction("http://my.custom-actions.domain/CUSTOM",
172                              "send", Hello.class);
173         List<CustomAction> customActions = new ArrayList<CustomAction>();
174         customActions.add(ca);
175         // (2) Parse the document
176         SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/custom-hello-world-03.xml", customActions);
177         // (3) Get a SCXMLExecutor
178         SCXMLExecutor exec = SCXMLTestHelper.getExecutor(scxml);
179         exec.go();
180         // (4) Single, final state
181         Assert.assertEquals("custom", (exec.getStatus().getStates().
182             iterator().next()).getId());
183 
184         // The custom action defined by Hello.class should be called
185         // to execute() exactly once at this point (by <my:send/>).
186         Assert.assertEquals(1, Hello.callbacks);
187     }
188 
189     // Hello World example using custom <my:hello> action that generates an
190     // event which has the payload examined with JEXL expressions
191     @Test
192     public void testCustomActionEventPayloadHelloWorldJexl() throws Exception {
193         // (1) Form a list of custom actions defined in the SCXML
194         //     document (and any included documents via "src" attributes)
195         CustomAction ca =
196             new CustomAction("http://my.custom-actions.domain/CUSTOM",
197                              "hello", Hello.class);
198         List<CustomAction> customActions = new ArrayList<CustomAction>();
199         customActions.add(ca);
200         // (2) Parse the document
201         SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/custom-hello-world-04-jexl.xml", customActions);
202         // (3) Get a SCXMLExecutor
203         SCXMLExecutor exec = SCXMLTestHelper.getExecutor(scxml);
204         exec.go();
205         // (4) Single, final state
206         Assert.assertEquals("Invalid intermediate state",
207                      "custom1", (exec.getStatus().getStates().
208                                 iterator().next()).getId());
209         // (5) Verify datamodel variable is correct
210         Assert.assertEquals("Missing helloName1 in root context", "custom04a",
211                      exec.getGlobalContext().get("helloName1"));
212 
213         // The custom action defined by Hello.class should be called
214         // to execute() exactly once at this point (by onentry in init state).
215         Assert.assertEquals(1, Hello.callbacks);
216 
217         // (6) Check use of payload in non-initial state
218         SCXMLTestHelper.fireEvent(exec, "custom.next");
219         // (7) Verify correct end state
220         Assert.assertEquals("Missing helloName1 in root context", "custom04b",
221                 exec.getGlobalContext().get("helloName1"));
222         Assert.assertEquals("Invalid final state",
223                 "end", (exec.getStatus().getStates().
224                 iterator().next()).getId());
225         Assert.assertTrue(exec.getStatus().isFinal());
226 
227         // The custom action defined by Hello.class should be called
228         // to execute() exactly two times at this point (by onentry in custom2 state).
229         Assert.assertEquals(2, Hello.callbacks);
230     }
231 }
232