diff --git a/nflow-engine/src/test/java/com/nitorcreations/nflow/engine/internal/workflow/WorkflowDefinitionScannerTest.java b/nflow-engine/src/test/java/com/nitorcreations/nflow/engine/internal/workflow/WorkflowDefinitionScannerTest.java index 7b67a15f6..0d264870c 100644 --- a/nflow-engine/src/test/java/com/nitorcreations/nflow/engine/internal/workflow/WorkflowDefinitionScannerTest.java +++ b/nflow-engine/src/test/java/com/nitorcreations/nflow/engine/internal/workflow/WorkflowDefinitionScannerTest.java @@ -1,9 +1,28 @@ package com.nitorcreations.nflow.engine.internal.workflow; +import static com.nitorcreations.Matchers.hasItemsOf; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.util.Arrays.asList; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.lang.reflect.Type; +import java.util.Map; +import java.util.Objects; + +import org.hamcrest.CustomMatcher; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import com.nitorcreations.nflow.engine.internal.workflow.WorkflowStateMethod.StateParameter; +import com.nitorcreations.nflow.engine.workflow.definition.Mutable; import com.nitorcreations.nflow.engine.workflow.definition.StateExecution; import com.nitorcreations.nflow.engine.workflow.definition.StateVar; import com.nitorcreations.nflow.engine.workflow.definition.WorkflowDefinition; @@ -14,8 +33,12 @@ public class WorkflowDefinitionScannerTest { @Rule public ExpectedException thrown = ExpectedException.none(); - WorkflowDefinitionScanner scanner = new WorkflowDefinitionScanner(); + WorkflowDefinitionScanner scanner; + @Before + public void setup() { + scanner = new WorkflowDefinitionScanner(); + } @Test public void overloadingStateMethodShouldThrowException() { thrown.expect(IllegalStateException.class); @@ -31,6 +54,57 @@ public void missingStateVarAnnotationShouldThrowException() { scanner.getStateMethods(MissingStateVarWorkflow.class); } + @Test + public void unknownAnnotationOnParameterIsIgnored() { + Map methods = scanner.getStateMethods(UnknownAnnotationWorkflow.class); + assertThat(methods.keySet(), hasItemsOf(asList("start", "end"))); + assertThat(methods.get("end").params[0], stateParam("paramKey", String.class, true, false)); + } + + @Test + public void mutableStateParamSetsMutableFlag() { + Map methods = scanner.getStateMethods(MutableParamWorkflow.class); + assertThat(methods.keySet(), hasItemsOf(asList("start", "end"))); + assertThat(methods.get("end").params[0], stateParam("paramKey", String.class, false, true)); + } + + @Test + public void instantiateNullFlagCausesParameterObjectToInstantiate() { + Map methods = scanner.getStateMethods(InitiateParameterWorkflow.class); + assertThat(methods.keySet(), hasItemsOf(asList("start", "end"))); + assertNotNull(methods.get("end").params[0].nullValue); + assertThat(methods.get("end").params[0], stateParam("paramKey", ParamObj.class, false, false)); + + StateParameter longParam = methods.get("end").params[1]; + assertThat(longParam, stateParam("paramKey2", long.class, true, false)); + assertEquals(0L, longParam.nullValue); + } + + @Test + public void onlyPublicMethodsWithCorrectSignatureAreReturns() { + Map methods = scanner.getStateMethods(NonStateMethodsWorkflow.class); + assertThat(methods.keySet(), hasItemsOf(asList("start", "end"))); + assertThat(methods.keySet().size(), is(2)); + } + + @Test + public void readOnlyStateVarFlagSetsFlagInStateParameter() { + Map methods = scanner.getStateMethods(ReadOnlyStateVarWorkflow.class); + assertThat(methods.keySet(), hasItemsOf(asList("start", "end"))); + assertThat(methods.get("end").params[0], stateParam("paramKey", String.class, true, false)); + } + + private CustomMatcher stateParam(final String key, final Type type, final boolean readOnly, final boolean mutable) { + return new CustomMatcher("") { + @Override + public boolean matches(Object item) { + StateParameter p = (StateParameter) item; + return Objects.equals(key, p.key) && Objects.equals(type, p.type) + && Objects.equals(readOnly, p.readOnly) && Objects.equals(mutable, p.mutable); + + } + }; + } public static enum ScannerState implements WorkflowState{ start(WorkflowStateType.start), end(WorkflowStateType.end); @@ -55,6 +129,13 @@ public String getDescription() { } } + @Retention(RUNTIME) + @Target(PARAMETER) + public @interface Dummy{ + } + + public static class ParamObj { } + public static class OverloadedStateMethodWorkflow extends WorkflowDefinition { public OverloadedStateMethodWorkflow() { super("overload", ScannerState.start, ScannerState.end); @@ -67,11 +148,57 @@ public void end(StateExecution exec, @StateVar("foo") String param) { } public static class MissingStateVarWorkflow extends WorkflowDefinition { public MissingStateVarWorkflow() { - super("overload", ScannerState.start, ScannerState.end); + super("missingStateVar", ScannerState.start, ScannerState.end); } public void start(StateExecution exec) { } public void end(StateExecution exec, String param) { } } + public static class UnknownAnnotationWorkflow extends WorkflowDefinition { + public UnknownAnnotationWorkflow() { + super("unknownAnnotation", ScannerState.start, ScannerState.end); + } + + public void start(StateExecution exec) { } + public void end(StateExecution exec, @Dummy @StateVar("paramKey") String param) { } + } + + public static class MutableParamWorkflow extends WorkflowDefinition { + public MutableParamWorkflow() { + super("mutableParam", ScannerState.start, ScannerState.end); + } + public void start(StateExecution exec) { } + public void end(StateExecution exec, @StateVar("paramKey") Mutable param) { } + } + + public static class InitiateParameterWorkflow extends WorkflowDefinition { + public InitiateParameterWorkflow() { + super("instantiateNull", ScannerState.start, ScannerState.end); + } + public void start(StateExecution exec) { } + public void end(StateExecution exec, + @StateVar(value = "paramKey", instantiateNull = true) ParamObj param, + @StateVar(value = "paramKey2", instantiateNull = true) long paramPrimitive) { } + } + + public static class NonStateMethodsWorkflow extends WorkflowDefinition { + public NonStateMethodsWorkflow() { + super("nonStateMethods", ScannerState.start, ScannerState.end); + } + public void start(StateExecution exec) { } + public void end(StateExecution exec) { } + public void noArgs() { } + public void wrongFirstArg(String x) { } + public static void staticMethod(StateExecution exec) { } + protected void nonPublic(StateExecution exec) { } + } + + public static class ReadOnlyStateVarWorkflow extends WorkflowDefinition { + public ReadOnlyStateVarWorkflow() { + super("readOnly", ScannerState.start, ScannerState.end); + } + public void start(StateExecution exec) { } + public void end(StateExecution exec, @StateVar(value = "paramKey", readOnly = true) String param) { } + } }