blob: 951acaa33b038b79069e2435d23abf8077d5555d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.scxml2.model;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.scxml2.SCXMLExecutor;
import org.apache.commons.scxml2.SCXMLTestHelper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class CustomActionTest {
/**
* Set up instance variables required by this test case.
*/
@BeforeEach
public void setUp() {
Hello.callbacks = 0;
}
@Test
public void testAddGoodCustomAction01() throws Exception {
new CustomAction("http://my.actions.domain/CUSTOM", "hello",
Hello.class);
}
@Test
public void testAddBadCustomAction01() {
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new CustomAction(null, "hello", Hello.class),
"Added custom action with illegal namespace");
}
@Test
public void testAddBadCustomAction02() {
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new CustomAction(" ", "hello", Hello.class),
"Added custom action with illegal namespace");
}
@Test
public void testAddBadCustomAction03() {
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new CustomAction("http://my.actions.domain/CUSTOM", "", Hello.class),
"Added custom action with illegal local name");
}
@Test
public void testAddBadCustomAction04() {
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new CustomAction("http://my.actions.domain/CUSTOM", " ", Hello.class),
"Added custom action with illegal local name");
}
@Test
public void testAddBadCustomAction05() {
Assertions.assertThrows(
IllegalArgumentException.class,
() -> new CustomAction("http://www.w3.org/2005/07/scxml", "foo", Hello.class),
"Added custom action in the SCXML namespace");
}
// Hello World example using the SCXML <log> action
@Test
public void testHelloWorld() throws Exception {
// (1) Get a SCXMLExecutor
SCXMLExecutor exec = SCXMLTestHelper.getExecutor("org/apache/commons/scxml2/hello-world.xml");
exec.go();
// (2) Single, final state
Assertions.assertEquals("hello", (exec.getStatus().getStates().
iterator().next()).getId());
Assertions.assertTrue(exec.getStatus().isFinal());
}
// Hello World example using a custom <hello> action
@Test
public void testCustomActionHelloWorld() throws Exception {
// (1) Form a list of custom actions defined in the SCXML
// document (and any included documents via "src" attributes)
CustomAction ca1 =
new CustomAction("http://my.custom-actions.domain/CUSTOM1",
"hello", Hello.class);
// Register the same action under a different name, just to test
// multiple custom actions
CustomAction ca2 =
new CustomAction("http://my.custom-actions.domain/CUSTOM2",
"bar", Hello.class);
List<CustomAction> customActions = new ArrayList<>();
customActions.add(ca1);
customActions.add(ca2);
// (2) Parse the document
SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/custom-hello-world-01.xml", customActions);
// (3) Get a SCXMLExecutor
SCXMLExecutor exec = SCXMLTestHelper.getExecutor(scxml);
exec.go();
// (4) Single, final state
Assertions.assertEquals("custom", (exec.getStatus().getStates().
iterator().next()).getId());
Assertions.assertTrue(exec.getStatus().isFinal());
// The custom action defined by Hello.class should be called
// to execute() exactly twice at this point (one by <my:hello/> and the other by <foo:bar/>).
Assertions.assertEquals(2, Hello.callbacks);
}
// Hello World example using custom <my:hello> action
// as part of an external state source (src attribute)
@Test
public void testCustomActionExternalSrcHelloWorld() throws Exception {
// (1) Form a list of custom actions defined in the SCXML
// document (and any included documents via "src" attributes)
CustomAction ca =
new CustomAction("http://my.custom-actions.domain/CUSTOM",
"hello", Hello.class);
List<CustomAction> customActions = new ArrayList<>();
customActions.add(ca);
// (2) Parse the document
SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/external-hello-world.xml", customActions);
// (3) Get a SCXMLExecutor
SCXMLExecutor exec = SCXMLTestHelper.getExecutor(scxml);
exec.go();
// (4) Single, final state
Assertions.assertEquals("custom", (exec.getStatus().getStates().
iterator().next()).getId());
// The custom action defined by Hello.class should be called
// to execute() exactly twice at this point (one by <my:hello/> and the other by <my:hello/> in external).
Assertions.assertEquals(2, Hello.callbacks);
}
// Hello World example using custom <my:send> action
// (overriding SCXML local name "send")
@Test
public void testCustomActionOverrideLocalName() throws Exception {
// (1) List of custom actions, use same local name as SCXML action
CustomAction ca =
new CustomAction("http://my.custom-actions.domain/CUSTOM",
"send", Hello.class);
List<CustomAction> customActions = new ArrayList<>();
customActions.add(ca);
// (2) Parse the document
SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/custom-hello-world-03.xml", customActions);
// (3) Get a SCXMLExecutor
SCXMLExecutor exec = SCXMLTestHelper.getExecutor(scxml);
exec.go();
// (4) Single, final state
Assertions.assertEquals("custom", (exec.getStatus().getStates().
iterator().next()).getId());
// The custom action defined by Hello.class should be called
// to execute() exactly once at this point (by <my:send/>).
Assertions.assertEquals(1, Hello.callbacks);
}
// Hello World example using custom <my:hello> action that generates an
// event which has the payload examined with JEXL expressions
@Test
public void testCustomActionEventPayloadHelloWorldJexl() throws Exception {
// (1) Form a list of custom actions defined in the SCXML
// document (and any included documents via "src" attributes)
CustomAction ca =
new CustomAction("http://my.custom-actions.domain/CUSTOM",
"hello", Hello.class);
List<CustomAction> customActions = new ArrayList<>();
customActions.add(ca);
// (2) Parse the document
SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/custom-hello-world-04-jexl.xml", customActions);
// (3) Get a SCXMLExecutor
SCXMLExecutor exec = SCXMLTestHelper.getExecutor(scxml);
exec.go();
// (4) Single, final state
Assertions.assertEquals("custom1", exec.getStatus().getStates().iterator().next().getId(),
"Invalid intermediate state");
// (5) Verify datamodel variable is correct
Assertions.assertEquals("custom04a", exec.getGlobalContext().get("helloName1"),
"Missing helloName1 in root context");
// The custom action defined by Hello.class should be called
// to execute() exactly once at this point (by onentry in init state).
Assertions.assertEquals(1, Hello.callbacks);
// (6) Check use of payload in non-initial state
SCXMLTestHelper.fireEvent(exec, "custom.next");
// (7) Verify correct end state
Assertions.assertEquals("custom04b", exec.getGlobalContext().get("helloName1"),
"Missing helloName1 in root context");
Assertions.assertEquals("end", exec.getStatus().getStates().iterator().next().getId(),
"Invalid final state");
Assertions.assertTrue(exec.getStatus().isFinal());
// The custom action defined by Hello.class should be called
// to execute() exactly two times at this point (by onentry in custom2 state).
Assertions.assertEquals(2, Hello.callbacks);
}
}