|
@@ -0,0 +1,483 @@
|
|
|
+/*=========================================================================
|
|
|
+
|
|
|
+ Library: CTK
|
|
|
+
|
|
|
+ Copyright (c) 2010 Kitware Inc.
|
|
|
+
|
|
|
+ Licensed 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.commontk.org/LICENSE
|
|
|
+
|
|
|
+ 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.
|
|
|
+
|
|
|
+ =========================================================================*/
|
|
|
+
|
|
|
+// QT includes
|
|
|
+#include <QApplication>
|
|
|
+#include <QTimer>
|
|
|
+
|
|
|
+// CTK includes
|
|
|
+#include "ctkExampleDerivedWorkflowStep.h"
|
|
|
+#include "ctkWorkflow.h"
|
|
|
+
|
|
|
+// STD includes
|
|
|
+#include <cstdlib>
|
|
|
+#include <iostream>
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+int numberOfTimesEntryExitTest(ctkExampleDerivedWorkflowStep* step1=0, int step1Entry=0, int step1Exit=0, ctkExampleDerivedWorkflowStep* step2=0, int step2Entry=0, int step2Exit=0, ctkExampleDerivedWorkflowStep* step3=0, int step3Entry=0, int step3Exit=0, ctkExampleDerivedWorkflowStep* step4=0, int step4Entry=0, int step4Exit=0)
|
|
|
+{
|
|
|
+ if (step1)
|
|
|
+ {
|
|
|
+ if (step1->numberOfTimesRanOnEntry() != step1Entry || step1->numberOfTimesRanOnExit() != step1Exit)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (step2)
|
|
|
+ {
|
|
|
+ if (step2->numberOfTimesRanOnEntry() != step2Entry || step2->numberOfTimesRanOnExit() != step2Exit)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (step3)
|
|
|
+ {
|
|
|
+ if (step3->numberOfTimesRanOnEntry() != step3Entry || step3->numberOfTimesRanOnExit() != step3Exit)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (step4)
|
|
|
+ {
|
|
|
+ if (step4->numberOfTimesRanOnEntry() != step4Entry || step4->numberOfTimesRanOnExit() != step4Exit)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+int currentStepAndNumberOfTimesEntryExitTest(ctkWorkflow* workflow, ctkExampleDerivedWorkflowStep* expectedStep, ctkExampleDerivedWorkflowStep* step1, int step1Entry, int step1Exit, ctkExampleDerivedWorkflowStep* step2, int step2Entry, int step2Exit, ctkExampleDerivedWorkflowStep* step3=0, int step3Entry=0, int step3Exit=0, ctkExampleDerivedWorkflowStep* step4=0, int step4Entry=0, int step4Exit=0)
|
|
|
+{
|
|
|
+ if (expectedStep)
|
|
|
+ {
|
|
|
+ if (workflow->currentStep() != expectedStep)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return numberOfTimesEntryExitTest(step1, step1Entry, step1Exit, step2, step2Entry, step2Exit, step3, step3Entry, step3Exit, step4, step4Entry, step4Exit);
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+int transitionTest(ctkWorkflow* workflow, int defaultTime, QApplication& app, ctkExampleDerivedWorkflowStep* expectedStep, ctkExampleDerivedWorkflowStep* step1, int step1Entry, int step1Exit, ctkExampleDerivedWorkflowStep* step2, int step2Entry, int step2Exit, ctkExampleDerivedWorkflowStep* step3=0, int step3Entry=0, int step3Exit=0, ctkExampleDerivedWorkflowStep* step4=0, int step4Entry=0, int step4Exit=0)
|
|
|
+{
|
|
|
+ QTimer::singleShot(defaultTime, &app, SLOT(quit()));
|
|
|
+ app.exec();
|
|
|
+ return currentStepAndNumberOfTimesEntryExitTest(workflow, expectedStep, step1, step1Entry, step1Exit, step2, step2Entry, step2Exit, step3, step3Entry, step3Exit, step4, step4Entry, step4Exit);
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+int testStartWorkflow(ctkWorkflow* workflow, int defaultTime, QApplication& app, int shouldRun, ctkExampleDerivedWorkflowStep* expectedStep=0, ctkExampleDerivedWorkflowStep* step1=0, int step1Entry=0, int step1Exit=0, ctkExampleDerivedWorkflowStep* step2=0, int step2Entry=0, int step2Exit=0, ctkExampleDerivedWorkflowStep* step3=0, int step3Entry=0, int step3Exit=0, ctkExampleDerivedWorkflowStep* step4=0, int step4Entry=0, int step4Exit=0)
|
|
|
+{
|
|
|
+ workflow->start();
|
|
|
+ QTimer::singleShot(defaultTime, &app, SLOT(quit()));
|
|
|
+ app.exec();
|
|
|
+ if (workflow->isRunning() != shouldRun)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return currentStepAndNumberOfTimesEntryExitTest(workflow, expectedStep, step1, step1Entry, step1Exit, step2, step2Entry, step2Exit, step3, step3Entry, step3Exit, step4, step4Entry, step4Exit);
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+int testStopWorkflow(ctkWorkflow* workflow, int defaultTime, QApplication& app, ctkExampleDerivedWorkflowStep* step1, int step1Entry, int step1Exit, ctkExampleDerivedWorkflowStep* step2, int step2Entry, int step2Exit, ctkExampleDerivedWorkflowStep* step3=0, int step3Entry=0, int step3Exit=0, ctkExampleDerivedWorkflowStep* step4=0, int step4Entry=0, int step4Exit=0)
|
|
|
+{
|
|
|
+ workflow->stop();
|
|
|
+ QTimer::singleShot(defaultTime, &app, SLOT(quit()));
|
|
|
+ app.exec();
|
|
|
+ if (workflow->isRunning())
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return numberOfTimesEntryExitTest(step1, step1Entry, step1Exit, step2, step2Entry, step2Exit, step3, step3Entry, step3Exit, step4, step4Entry, step4Exit);
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+int ctkWorkflowTest1(int argc, char * argv [] )
|
|
|
+{
|
|
|
+ QApplication app(argc, argv);
|
|
|
+ int defaultTime = 100;
|
|
|
+
|
|
|
+ // create two steps and the workflow
|
|
|
+ ctkWorkflow *workflow = new ctkWorkflow();
|
|
|
+ ctkExampleDerivedWorkflowStep *step1 = new ctkExampleDerivedWorkflowStep(workflow, "Step 1");
|
|
|
+ step1->setName("Step 1");
|
|
|
+ step1->setDescription("Description for step 1");
|
|
|
+ ctkExampleDerivedWorkflowStep *step2 = new ctkExampleDerivedWorkflowStep(workflow, "Step 2");
|
|
|
+ step2->setName("Step 2");
|
|
|
+ step2->setDescription("Description for step 2");
|
|
|
+
|
|
|
+ // --------------------------------------------------------------------------
|
|
|
+ // try to add a transition for a step with the same id
|
|
|
+ ctkExampleDerivedWorkflowStep *step1Duplicated = new ctkExampleDerivedWorkflowStep(workflow, "Step 1");
|
|
|
+ if (workflow->addTransition(step1, step1Duplicated))
|
|
|
+ {
|
|
|
+ std::cerr << "workflow connected two steps with the same id";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // try to add a transition from a step to itself
|
|
|
+ if (workflow->addTransition(step1, step1))
|
|
|
+ {
|
|
|
+ std::cerr << "workflow connected two steps with the same id";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // --------------------------------------------------------------------------
|
|
|
+ // workflow with no steps
|
|
|
+ // try erroneously starting with no steps
|
|
|
+
|
|
|
+ if (!testStartWorkflow(workflow, defaultTime, app, 0))
|
|
|
+ {
|
|
|
+ std::cerr << "empty workflow is running after start()";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // add the first step
|
|
|
+ if (!workflow->addTransition(step1, 0))
|
|
|
+ {
|
|
|
+ std::cerr << "could not add first step";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // try erroneously starting with no initial step
|
|
|
+ if (!testStartWorkflow(workflow, defaultTime, app, 0))
|
|
|
+ {
|
|
|
+ std::cerr << "workflow is running after start() with no initial step";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // --------------------------------------------------------------------------
|
|
|
+ // workflow with one step
|
|
|
+
|
|
|
+ // set the initial step (which sets the initial state)
|
|
|
+ workflow->setInitialStep(step1);
|
|
|
+
|
|
|
+ // try starting with one step
|
|
|
+ if (!testStartWorkflow(workflow, defaultTime, app, 1, step1, step1, 1, 0, step2, 0, 0))
|
|
|
+ {
|
|
|
+ std::cerr << "workflow is not running after start() with a single step";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // triggering ValidationTransition and TransitionToPreviousStep
|
|
|
+ // should keep us in the same step, when there is only one step
|
|
|
+ workflow->goForward();
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step1, step1, 1, 0, step2, 0, 0))
|
|
|
+ {
|
|
|
+ std::cerr << "error in validation transition in a workflow with a single step";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // transition to the previous step
|
|
|
+ workflow->goBackward();
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step1, step1, 1, 0, step2, 0, 0))
|
|
|
+ {
|
|
|
+ std::cerr << "error after transition to previous step in a workflow with a single step";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // stop the workflow
|
|
|
+ if (!testStopWorkflow(workflow, defaultTime, app, step1, 1, 1, step2, 0, 0))
|
|
|
+ {
|
|
|
+ std::cerr << "workflow with one step still running after stop";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // --------------------------------------------------------------------------
|
|
|
+ // workflow with two steps
|
|
|
+
|
|
|
+ // add the second step
|
|
|
+ if (!workflow->addTransition(step1, step2))
|
|
|
+ {
|
|
|
+ std::cerr << "could not add second step";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // start the workflow
|
|
|
+ if (!testStartWorkflow(workflow, defaultTime, app, 1, step1, step1, 2, 1, step2, 0, 0))
|
|
|
+ {
|
|
|
+ std::cerr << "workflow is not running after start() with two steps";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // make sure the workflow has the steps
|
|
|
+ if (!workflow->hasStep(step1->id()))
|
|
|
+ {
|
|
|
+ std::cerr << "Step1 not added to workflow";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!workflow->hasStep(step2->id()))
|
|
|
+ {
|
|
|
+ std::cerr << "Step2 not added to workflow";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // if (workflow->numberOfSteps() != 2)
|
|
|
+ // {
|
|
|
+ // std::cerr << "workflow has " << workflow->numberOfSteps() << " steps, not 2";
|
|
|
+ // return EXIT_FAILURE;
|
|
|
+ // }
|
|
|
+
|
|
|
+ // Test that the workflow transitions from processing to validation state
|
|
|
+ workflow->goForward();
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step2, step1, 2, 2, step2, 1, 0))
|
|
|
+ {
|
|
|
+ std::cerr << "error transitioning to next step in workflow with two steps";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Test that the workflow transitions back to the previous step
|
|
|
+ workflow->goBackward();
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step1, step1, 3, 2, step2, 1, 1))
|
|
|
+ {
|
|
|
+ std::cerr << "error transitioning to previous step in workflow with step steps";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // make sure the workflow stops properly
|
|
|
+ if (!testStopWorkflow(workflow, defaultTime, app, step1, 3, 3, step2, 1, 1))
|
|
|
+ {
|
|
|
+ std::cerr << "workflow with two steps is running after stop()";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // --------------------------------------------------------------------------
|
|
|
+ // workflow with three steps
|
|
|
+
|
|
|
+ // add a third step manually
|
|
|
+ ctkExampleDerivedWorkflowStep *step3 = new ctkExampleDerivedWorkflowStep(workflow, "Step 3");
|
|
|
+ step3->setName("Step 3");
|
|
|
+ step3->setDescription("Description for step 3");
|
|
|
+
|
|
|
+ if (!workflow->addTransition(step2, step3, "", ctkWorkflow::Forward))
|
|
|
+ {
|
|
|
+ std::cerr << "could not add step 3 with forward transition";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!workflow->addTransition(step2, step3, "", ctkWorkflow::Backward))
|
|
|
+ {
|
|
|
+ std::cerr << "could not add next transition between step2 and step 3";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (workflow->forwardSteps(step1).length() != 1
|
|
|
+ || workflow->forwardSteps(step1).first() != step2
|
|
|
+ || workflow->forwardSteps(step2).length() != 1
|
|
|
+ || workflow->forwardSteps(step2).first() != step3
|
|
|
+ || workflow->forwardSteps(step3).length() != 0)
|
|
|
+ {
|
|
|
+ std::cerr << "error in list of forward steps" << std::endl;
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (workflow->backwardSteps(step1).length() != 0
|
|
|
+ || workflow->backwardSteps(step2).length() != 1
|
|
|
+ || workflow->backwardSteps(step2).first() != step1
|
|
|
+ || workflow->backwardSteps(step3).length() != 1
|
|
|
+ || workflow->backwardSteps(step3).first() != step2)
|
|
|
+ {
|
|
|
+ std::cerr << "error in list of backward steps" << std::endl;
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!workflow->hasStep(step3->id()))
|
|
|
+ {
|
|
|
+ std::cerr << "Step3 not added to workflow";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ // if (workflow->numberOfSteps() != 3)
|
|
|
+ // {
|
|
|
+ // std::cerr << "workflow has " << workflow->numberOfSteps() << " steps, not 2";
|
|
|
+ // return EXIT_FAILURE;
|
|
|
+ // }
|
|
|
+
|
|
|
+ // now that we've stopped and restarted the state machine, we should
|
|
|
+ // be back in the initial step (step 1)
|
|
|
+ if (!testStartWorkflow(workflow, defaultTime, app, 1, step1, step1, 4, 3, step2, 1, 1, step3, 0, 0))
|
|
|
+ {
|
|
|
+ std::cerr << "workflow is not running after start() with three steps";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // test to make sure our lists of forward and backwards steps is correct
|
|
|
+ if (!workflow->canGoForward(step1)
|
|
|
+ || workflow->canGoBackward(step1)
|
|
|
+ || !workflow->canGoForward(step2)
|
|
|
+ || !workflow->canGoBackward(step2)
|
|
|
+ || workflow->canGoForward(step3)
|
|
|
+ || !workflow->canGoBackward(step3))
|
|
|
+ {
|
|
|
+ std::cerr << "error in can go forward/backward" << std::endl;
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Test that the workflow transitions from step1 to step 2 to step 3
|
|
|
+ workflow->goForward();
|
|
|
+ QTimer::singleShot(defaultTime, &app, SLOT(quit()));
|
|
|
+ app.exec();
|
|
|
+ workflow->goForward();
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step3, step1, 4, 4, step2, 2, 2, step3, 1, 0))
|
|
|
+ {
|
|
|
+ std::cerr << "error transitioning to step3 in workflow with three steps";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Test that the workflow transitions back to the previous step
|
|
|
+ workflow->goBackward();
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step2, step1, 4, 4, step2, 3, 2, step3, 1, 1))
|
|
|
+ {
|
|
|
+ std::cerr << "error transitioning to previous step in workflow with three steps";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // make sure the workflow stops properly
|
|
|
+ if (!testStopWorkflow(workflow, defaultTime, app, step1, 4, 4, step2, 3, 3, step3, 1, 1))
|
|
|
+ {
|
|
|
+ std::cerr << "error stopping workflow with three steps";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // --------------------------------------------------------------------------
|
|
|
+ // workflow with a finish step (step 3)
|
|
|
+
|
|
|
+ // restart the workflow
|
|
|
+ if (!testStartWorkflow(workflow, defaultTime, app, 1, step1, step1, 5, 4, step2, 3, 3, step3, 1, 1))
|
|
|
+ {
|
|
|
+ std::cerr << "workflow with finish step is not running after start()";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // try to go automatically to step 3
|
|
|
+ workflow->goToStep("Step 3");
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step1, step1, 6, 5, step2, 4, 4, step3, 2, 2))
|
|
|
+ {
|
|
|
+ std::cerr << "error after going to finish step";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // try to go automatically to step 3 again
|
|
|
+ workflow->goToStep("Step 3");
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step1, step1, 7, 6, step2, 5, 5, step3, 3, 3))
|
|
|
+ {
|
|
|
+ std::cerr << "error after going to finish step the second time";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // stop workflow
|
|
|
+ if (!testStopWorkflow(workflow, defaultTime, app, step1, 7, 7, step2, 5, 5, step3, 3, 3))
|
|
|
+ {
|
|
|
+ std::cerr << "error stopping workflow with finish step";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // --------------------------------------------------------------------------
|
|
|
+ // workflow with two finishing steps (step3 and step4)
|
|
|
+ ctkExampleDerivedWorkflowStep *step4 = new ctkExampleDerivedWorkflowStep(workflow, "Step 4");
|
|
|
+ step4->setName("Step 4");
|
|
|
+ step4->setDescription("Description for step 4");
|
|
|
+ workflow->addTransition(step3, step4);
|
|
|
+
|
|
|
+ // restart the workflow
|
|
|
+ if (!testStartWorkflow(workflow, defaultTime, app, 1, step1, step1, 8, 7, step2, 5, 5, step3, 3, 3, step4, 0, 0))
|
|
|
+ {
|
|
|
+ std::cerr << "workflow with two finish steps is not running after start()";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // try to go automatically to step 3
|
|
|
+ workflow->goToStep("Step 3");
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step1, step1, 9, 8, step2, 6, 6, step3, 4, 4, step4, 0, 0))
|
|
|
+ {
|
|
|
+ std::cerr << "error going to the first finish step of two";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // try to go automatically to step 4
|
|
|
+ workflow->goToStep("Step 4");
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step1, step1, 10, 9, step2, 7, 7, step3, 5, 5, step4, 1, 1))
|
|
|
+ {
|
|
|
+ std::cerr << "error going to the second finish step of two";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // go to step 3 (a finish step)
|
|
|
+ workflow->goForward();
|
|
|
+ QTimer::singleShot(defaultTime, &app, SLOT(quit()));
|
|
|
+ app.exec();
|
|
|
+ workflow->goForward();
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step3, step1, 10, 10, step2, 8, 8, step3, 6, 5, step4, 1, 1))
|
|
|
+ {
|
|
|
+ std::cerr << "error going from step1 to step3";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // try to go automatically to step 4 (another goTo step)
|
|
|
+ workflow->goToStep("Step 4");
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step3, step1, 10, 10, step2, 8, 8, step3, 7, 6, step4, 2, 2))
|
|
|
+ {
|
|
|
+ std::cerr << "error going from the first finish step to the second finish step";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // go to step 4, and then go forward (should not let you go past last step)
|
|
|
+ workflow->goForward();
|
|
|
+ QTimer::singleShot(defaultTime, &app, SLOT(quit()));
|
|
|
+ app.exec();
|
|
|
+ workflow->goForward();
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step4, step1, 10, 10, step2, 8, 8, step3, 7, 7, step4, 3, 2))
|
|
|
+ {
|
|
|
+ std::cerr << "error going forward past last step - shouldn't let you";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // now try to go from step 4 to step 4 (should loop)
|
|
|
+ workflow->goToStep("Step 4");
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step4, step1, 10, 10, step2, 8, 8, step3, 7, 7, step4, 4, 3))
|
|
|
+ {
|
|
|
+ std::cerr << "error looping from step 4 to step 4";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+ // go back to step 3, and then go from step 3 to step 3 (should loop without hitting step4)
|
|
|
+ workflow->goBackward();
|
|
|
+ QTimer::singleShot(defaultTime, &app, SLOT(quit()));
|
|
|
+ app.exec();
|
|
|
+ workflow->goToStep("Step 3");
|
|
|
+ if (!transitionTest(workflow, defaultTime, app, step3, step1, 10, 10, step2, 8, 8, step3, 9, 8, step4, 4, 4))
|
|
|
+ {
|
|
|
+ std::cerr << "error looping from step 3 to step 3";
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // handles deletions of the workflow, steps, states and transitions
|
|
|
+ delete workflow;
|
|
|
+
|
|
|
+ return EXIT_SUCCESS;
|
|
|
+}
|