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.model; 018 019import java.util.ArrayList; 020import java.util.List; 021 022import org.apache.commons.scxml2.SCXMLExecutor; 023import org.apache.commons.scxml2.SCXMLTestHelper; 024import org.junit.Assert; 025import org.junit.Before; 026import org.junit.Test; 027 028public class CustomActionTest { 029 030 /** 031 * Set up instance variables required by this test case. 032 */ 033 @Before 034 public void setUp() { 035 Hello.callbacks = 0; 036 } 037 038 @Test 039 public void testAddGoodCustomAction01() throws Exception { 040 new CustomAction("http://my.actions.domain/CUSTOM", "hello", 041 Hello.class); 042 } 043 044 @Test 045 public void testAddBadCustomAction01() { 046 try { 047 new CustomAction(null, "hello", Hello.class); 048 Assert.fail("Added custom action with illegal namespace"); 049 } catch (IllegalArgumentException iae) { 050 // Expected 051 } 052 } 053 054 @Test 055 public void testAddBadCustomAction02() { 056 try { 057 new CustomAction(" ", "hello", Hello.class); 058 Assert.fail("Added custom action with illegal namespace"); 059 } catch (IllegalArgumentException iae) { 060 // Expected 061 } 062 } 063 064 @Test 065 public void testAddBadCustomAction03() { 066 try { 067 new CustomAction("http://my.actions.domain/CUSTOM", "", 068 Hello.class); 069 Assert.fail("Added custom action with illegal local name"); 070 } catch (IllegalArgumentException iae) { 071 // Expected 072 } 073 } 074 075 @Test 076 public void testAddBadCustomAction04() { 077 try { 078 new CustomAction("http://my.actions.domain/CUSTOM", " ", 079 Hello.class); 080 Assert.fail("Added custom action with illegal local name"); 081 } catch (IllegalArgumentException iae) { 082 // Expected 083 } 084 } 085 086 @Test 087 public void testAddBadCustomAction05() { 088 try { 089 new CustomAction("http://www.w3.org/2005/07/scxml", "foo", 090 Hello.class); 091 Assert.fail("Added custom action in the SCXML namespace"); 092 } catch (IllegalArgumentException iae) { 093 // Expected 094 } 095 } 096 097 // Hello World example using the SCXML <log> action 098 @Test 099 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