Squashed 'SpiffWorkflow/' changes from 4195453a4..1f51db962
1f51db962 Merge pull request #283 from sartography/feature/better_errors 69fb4967e Patching up some bugs and logical disconnects as I test out the errors. cf5be0096 * Making a few more things consistent in the error messages -- so there isn't filename for validation errors, and file_name for WorkflowExceptions. Same for line_number vs sourceline. * Assure than an error_type is consistently set on exceptions. * ValidationExceptions should not bild up a detailed error message that replicates information available within it. 440ee16c8 Responding to some excellent suggestions from Elizabeth: 655e415e1 Merge pull request #282 from subhakarks/fix-workfowspec-dump 1f6d3cf4e Explain that the error happened in a pre-script or post script. 8119abd14 Added a top level SpiffWorklowException that all exceptions inherit from. Aside from a message string you can append information to these exceptions with "add_note", which is a new method that all exceptions have starting in python 3.11 Switched arguments to the WorkflowException, WorkflowTaskException - which now always takes a string message as the first argument, and named arguments thereafter to be consistent with all other error messages in Python. Consistently raise ValidationExceptions whenever we encounter an error anywhere during parsing of xml. The BPMN/WorkflowTaskExecException is removed, in favor of just calling a WorkflowTaskException. There is nothing BPMN Specific in the logic, so no need for this. Consolidated error message logic so that things like "Did you mean" just get added by default if possible. So we don't have to separately deal with that logic each time. Better Error messages for DMN (include row number as a part of the error information) 13463b5c5 fix for workflowspec dump be26100bc Merge pull request #280 from sartography/feature/remove-unused-bpmn-attributes-and-methods 23a5c1d70 remove 'entering_* methods 4e5875ec8 remove sequence flow 5eed83ab1 Merge pull request #278 from sartography/feature/remove-old-serializer 614f1c68a remove compact serializer and references e7e410d4a remove old serializer and references git-subtree-dir: SpiffWorkflow git-subtree-split: 1f51db962ccaed5810f5d0f7d76a932f056430ab
This commit is contained in:
parent
80cb923b14
commit
af293a91d1
|
@ -0,0 +1,90 @@
|
||||||
|
SpiffWorkflow Exceptions
|
||||||
|
====================================
|
||||||
|
Details about the exceptions and exception hierarchy within SpiffWorkflow
|
||||||
|
|
||||||
|
SpiffWorkflowException
|
||||||
|
----------
|
||||||
|
Base exception for all exceptions raised by SpiffWorkflow
|
||||||
|
|
||||||
|
ValidationException
|
||||||
|
----------
|
||||||
|
|
||||||
|
**Extends**
|
||||||
|
SpiffWorkflowException
|
||||||
|
|
||||||
|
Thrown during the parsing of a workflow.
|
||||||
|
|
||||||
|
**Attributes/Methods**
|
||||||
|
|
||||||
|
- **tag**: The type of xml tag being parsed
|
||||||
|
- **id**: the id attribute of the xml tag, if available.
|
||||||
|
- **name**: the name attribute of the xml tag, if available.
|
||||||
|
- **line_number**: the line number where the tag occurs.
|
||||||
|
- **file_name**: The name of the file where the error occurred.
|
||||||
|
- **message**: a human readable error message.
|
||||||
|
|
||||||
|
|
||||||
|
WorkflowException
|
||||||
|
--------
|
||||||
|
When an error occurs with a Task Specification (maybe should have been called
|
||||||
|
a SpecException)
|
||||||
|
|
||||||
|
**Extends**
|
||||||
|
SpiffWorkflowException
|
||||||
|
|
||||||
|
**Attributes/Methods**
|
||||||
|
|
||||||
|
- **sender**: The TaskSpec - the specific Task, Gateway, etc... that caused the error to happen.
|
||||||
|
- **error**: a human readable error message describing the problem.
|
||||||
|
- **get_task_trace**: Provided a specific Task, will work it's way through the workflow / sub-processes
|
||||||
|
and call activities to show where an error occurred. Useful if the error happened within a deeply nested structure (where call activities include call activities ....)
|
||||||
|
|
||||||
|
WorkflowDataException
|
||||||
|
------------------
|
||||||
|
When an exception occurs moving data between tasks and Data Objects (including
|
||||||
|
data inputs and data outputs.)
|
||||||
|
|
||||||
|
**Extends**
|
||||||
|
WorkflowException
|
||||||
|
|
||||||
|
**Attributes/Methods**
|
||||||
|
|
||||||
|
(in addition to the values in a WorkflowException)
|
||||||
|
|
||||||
|
- **task**: The specific task (not the task spec, but the actual executing task)
|
||||||
|
- **data_input**: The spec of the input variable
|
||||||
|
- **data_output**: The spec of the output variable
|
||||||
|
|
||||||
|
WorkflowTaskException
|
||||||
|
--------
|
||||||
|
**Extends**
|
||||||
|
WorkflowException
|
||||||
|
|
||||||
|
**Attributes/Methods**
|
||||||
|
|
||||||
|
(in addition to the values in a WorkflowException)
|
||||||
|
|
||||||
|
- **task**: The specific task (not the task spec, but the actual executing task)
|
||||||
|
- **error_msg**: The detailed human readable message. (conflicts with error above)
|
||||||
|
- **exception**: The original exception this wraps around.
|
||||||
|
- **line_number** The line number that contains the error
|
||||||
|
- **offset** The point in the line that caused the error
|
||||||
|
- **error_line** The content of the line that caused the error.
|
||||||
|
|
||||||
|
It will accept the line_number and error_line as arguments - if the
|
||||||
|
underlying error provided is a SyntaxError it will try to derive this
|
||||||
|
information from the error.
|
||||||
|
If this is a name error, it will attempt to calculate a did-you-mean
|
||||||
|
error_msg.
|
||||||
|
|
||||||
|
Unused / Deprecated errors
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
** StorageException **
|
||||||
|
Deprecated -- Used only by the PrettyXmlSerializer - which is not under active
|
||||||
|
support.
|
||||||
|
|
||||||
|
** DeadMethodCalled **
|
||||||
|
Something related to WeakMethod -- which doesn't look to be utilized anymore.
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,13 @@
|
||||||
showgrid="false"
|
showgrid="false"
|
||||||
showguides="true"
|
showguides="true"
|
||||||
inkscape:guide-bbox="true"
|
inkscape:guide-bbox="true"
|
||||||
inkscape:zoom="0.27433373"
|
inkscape:zoom="1.5518659"
|
||||||
inkscape:cx="-586.87643"
|
inkscape:cx="2265.0153"
|
||||||
inkscape:cy="1882.7433"
|
inkscape:cy="3541.2209"
|
||||||
inkscape:window-width="1916"
|
inkscape:window-width="1916"
|
||||||
inkscape:window-height="1076"
|
inkscape:window-height="916"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="0"
|
inkscape:window-y="162"
|
||||||
inkscape:window-maximized="1"
|
inkscape:window-maximized="1"
|
||||||
inkscape:current-layer="layer1">
|
inkscape:current-layer="layer1">
|
||||||
<sodipodi:guide
|
<sodipodi:guide
|
||||||
|
@ -70,6 +70,18 @@
|
||||||
position="30.565253,-441.07447"
|
position="30.565253,-441.07447"
|
||||||
orientation="1,0"
|
orientation="1,0"
|
||||||
id="guide37861" />
|
id="guide37861" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="700.40724,-579.16044"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide49435" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="639.13561,-614.28335"
|
||||||
|
orientation="0,-1"
|
||||||
|
id="guide49437" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="734.70955,-597.73685"
|
||||||
|
orientation="1,0"
|
||||||
|
id="guide83679" />
|
||||||
</sodipodi:namedview>
|
</sodipodi:namedview>
|
||||||
<defs
|
<defs
|
||||||
id="defs2">
|
id="defs2">
|
||||||
|
@ -839,6 +851,91 @@
|
||||||
x="-580.08496"
|
x="-580.08496"
|
||||||
y="716.69928">Draw the code</tspan></text>
|
y="716.69928">Draw the code</tspan></text>
|
||||||
</g>
|
</g>
|
||||||
|
<path
|
||||||
|
id="path73257-7-2-9-159-9-8"
|
||||||
|
style="vector-effect:none;fill:#126d82;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.433;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
|
d="m 599.99956,911.28335 v 0.91595 c 0.96107,0.84548 1.66181,1.94689 2.02041,3.17567 h -17.54738 c -3.11685,0 -5.68164,2.56482 -5.68164,5.68159 v 3.91192 c 0,3.11682 2.56479,5.68164 5.68164,5.68164 h 5.6851 4.69113 5.6878 c 1.21493,0 2.13344,0.91846 2.13344,2.13344 v 3.91632 c 0,1.21498 -0.91851,2.13346 -2.13344,2.13346 h -14.79076 c -0.75878,-2.29982 -2.93713,-3.97943 -5.47735,-3.97943 -3.16218,0 -5.76138,2.60267 -5.76138,5.76489 0,3.1622 2.5992,5.76399 5.76138,5.76399 2.54974,0 4.73517,-1.69176 5.48615,-4.00482 h 14.78196 c 3.1168,0 5.67808,-2.5613 5.67808,-5.67809 v -3.91632 c 0,-3.11677 -2.56128,-5.68164 -5.67808,-5.68164 h -5.6878 -4.69113 -5.6851 c -1.21497,0 -2.13609,-0.91837 -2.13609,-2.13344 v -3.91192 c 0,-1.21499 0.92112,-2.13696 2.13609,-2.13696 h 17.60609 c -0.33391,1.31874 -1.05865,2.50576 -2.07912,3.4053 v 0.68721 l 11.72877,-5.86483 z m -19.73105,27.11871 c 1.24555,0 2.21936,0.97116 2.21936,2.21674 0,1.24556 -0.97381,2.21936 -2.21936,2.21936 -1.24559,0 -2.21675,-0.9738 -2.21675,-2.21936 0,-1.24558 0.97116,-2.21674 2.21675,-2.21674 z"
|
||||||
|
sodipodi:nodetypes="cccssssccsssscssscssssccsssscccccsssss"
|
||||||
|
inkscape:export-filename="/home/dan/spiffworkflow.png"
|
||||||
|
inkscape:export-xdpi="136.48"
|
||||||
|
inkscape:export-ydpi="136.48" />
|
||||||
|
<path
|
||||||
|
id="path85339"
|
||||||
|
style="color:#000000;fill:#126d82;fill-rule:evenodd;stroke-width:3.77953;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none"
|
||||||
|
d="M 2575.416 3444.2207 L 2575.416 3447.6816 C 2579.0484 3450.8772 2581.6954 3455.0413 2583.0508 3459.6855 L 2516.7305 3459.6855 C 2504.9502 3459.6855 2495.2559 3469.3783 2495.2559 3481.1582 L 2495.2559 3487.6719 L 2475.9883 3506.9375 A 6.6148345 6.6148345 0 0 0 2475.9883 3516.293 L 2495.2559 3535.5586 L 2495.2559 3540.2656 C 2495.2559 3552.0455 2504.9502 3561.7402 2516.7305 3561.7402 L 2583.0508 3561.7402 C 2581.6954 3566.3844 2579.0484 3570.5467 2575.416 3573.7422 L 2575.416 3577.2051 L 2619.7441 3555.041 L 2575.416 3532.875 L 2575.416 3535.4727 C 2579.2729 3538.8725 2582.0114 3543.3595 2583.2734 3548.3438 L 2516.7305 3548.3438 C 2512.1385 3548.3437 2508.6582 3544.8577 2508.6582 3540.2656 L 2508.6582 3535.6543 L 2526.8945 3517.418 L 2538.2168 3517.418 L 2555.9473 3517.418 L 2577.4453 3517.418 L 2577.4453 3504.0078 L 2555.9473 3504.0078 L 2538.2168 3504.0078 L 2525.0801 3504.0078 L 2508.6582 3487.5879 L 2508.6582 3481.1582 C 2508.6582 3476.5661 2512.1385 3473.082 2516.7305 3473.082 L 2583.2734 3473.082 C 2582.0114 3478.0662 2579.2729 3482.5533 2575.416 3485.9531 L 2575.416 3488.5488 L 2619.7441 3466.3828 L 2575.416 3444.2207 z M 2502 3499.6348 L 2513.9844 3511.6211 L 2502.0039 3523.5996 L 2490.0195 3511.6152 L 2502 3499.6348 z "
|
||||||
|
transform="scale(0.26458333)" />
|
||||||
|
<path
|
||||||
|
id="path28509-8"
|
||||||
|
style="color:#000000;fill:#126d82;fill-rule:evenodd;stroke-width:3.77953;stroke-linecap:round;-inkscape-stroke:none"
|
||||||
|
d="M 2399.5488 3444.8691 C 2399.2119 3444.8591 2398.8728 3444.8589 2398.5312 3444.8789 C 2393.0057 3445.089 2388.3208 3448.0519 2384.6758 3451.8398 C 2381.0308 3455.6276 2378.0721 3460.419 2375.375 3465.8945 C 2373.2508 3470.2068 2371.3058 3474.9651 2369.5156 3479.9805 L 2345.8223 3493.6602 A 6.6148344 6.6148344 0 0 0 2343.4023 3502.6953 L 2357.3008 3526.7676 C 2353.7347 3544.8143 2351.9297 3558.8242 2351.9297 3558.8242 C 2351.4636 3562.4489 2354.0254 3565.7647 2357.6504 3566.2285 C 2361.2731 3566.6948 2364.5879 3564.1363 2365.0547 3560.5137 C 2365.0547 3560.5137 2366.8057 3547.0108 2370.2109 3529.6914 L 2391.2676 3517.5332 L 2423.0762 3519.1836 C 2421.901 3514.4062 2420.5091 3511.1637 2419.0352 3506.375 L 2394.916 3505.125 L 2382.3672 3483.3887 C 2383.9174 3479.1251 2385.5484 3475.1771 2387.2441 3471.7344 C 2389.5662 3467.0204 2392.0321 3463.2741 2394.2129 3461.0078 C 2396.3937 3458.7414 2397.9351 3458.1336 2399.0332 3458.0918 C 2400.1917 3458.0478 2401.6224 3458.4993 2403.7949 3460.4766 C 2405.9674 3462.454 2408.4992 3465.8585 2410.9258 3470.2285 C 2415.779 3478.9684 2420.2895 3491.437 2423.9551 3504.0078 C 2428.2848 3518.856 2431.4634 3533.6918 2433.3691 3543.4609 C 2428.6211 3543.3167 2423.9981 3541.8521 2420.0293 3539.2148 L 2417.5215 3539.8867 L 2450.4043 3576.9688 L 2460.3398 3528.4141 L 2456.9961 3529.3105 C 2454.8496 3533.6462 2451.5141 3537.2818 2447.3789 3539.793 L 2441.7285 3519.5527 C 2440.2594 3513.4161 2438.5627 3506.8668 2436.6504 3500.3086 C 2432.8362 3487.2285 2428.209 3474.1159 2422.4844 3463.8066 C 2419.6221 3458.652 2416.508 3454.1637 2412.6973 3450.6953 C 2409.1248 3447.4436 2404.6033 3444.9934 2399.5488 3444.8711 L 2399.5488 3444.8691 z M 2375.7188 3477.7051 C 2375.7747 3477.7091 2375.8288 3477.727 2375.8848 3477.7324 A 6.6148344 6.6148344 0 0 0 2375.666 3477.707 C 2375.6835 3477.7081 2375.7013 3477.7038 2375.7188 3477.7051 z M 2372.8359 3493.3379 L 2381.3066 3508.0098 L 2366.6348 3516.4805 L 2358.1641 3501.8086 L 2372.8359 3493.3379 z "
|
||||||
|
transform="scale(0.26458333)" />
|
||||||
|
<g
|
||||||
|
id="g38755">
|
||||||
|
<path
|
||||||
|
d="m 590.37968,815.93796 q 2.10753,0 3.40104,1.63919 1.30466,1.63918 1.30466,4.80606 0,2.11867 -0.6133,3.56829 -0.61331,1.43847 -1.69494,2.17443 -1.08165,0.73597 -2.48666,0.73597 -0.90323,0 -1.54998,-0.22302 -0.64675,-0.23417 -1.10395,-0.591 -0.45719,-0.36798 -0.79171,-0.78057 h -0.17842 q 0.0892,0.44604 0.13383,0.91439 0.0446,0.46833 0.0446,0.91437 v 5.02907 h -3.40104 v -17.95302 h 2.76543 l 0.47949,1.6169 h 0.15605 q 0.33452,-0.5018 0.81401,-0.92554 0.47949,-0.42374 1.14855,-0.66905 0.68021,-0.25647 1.57228,-0.25647 z m -1.09279,2.72082 q -0.89207,0 -1.41617,0.36799 -0.52408,0.36798 -0.76942,1.10393 -0.23416,0.73597 -0.25646,1.86222 v 0.36798 q 0,1.2043 0.22301,2.04062 0.23418,0.83631 0.76942,1.27121 0.54639,0.43488 1.49423,0.43488 0.78056,0 1.28236,-0.43488 0.50179,-0.4349 0.74711,-1.27121 0.25646,-0.84748 0.25646,-2.06292 0,-1.82875 -0.56869,-2.75428 -0.56869,-0.92554 -1.76185,-0.92554 z"
|
||||||
|
id="path105589-9-3"
|
||||||
|
style="font-weight:bold;font-size:13.4639px;line-height:125%;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';letter-spacing:0px;word-spacing:0px;fill:#126d82;fill-opacity:1;stroke-width:1.42731px" />
|
||||||
|
<path
|
||||||
|
d="m 600.11661,816.17212 v 12.46676 h -3.40104 v -12.46676 z m -1.69494,-4.8841 q 0.75826,0 1.30466,0.35683 0.54639,0.34568 0.54639,1.30466 0,0.94782 -0.54639,1.31581 -0.5464,0.35682 -1.30466,0.35682 -0.76942,0 -1.31581,-0.35682 -0.53524,-0.36799 -0.53524,-1.31581 0,-0.95898 0.53524,-1.30466 0.54639,-0.35683 1.31581,-0.35683 z"
|
||||||
|
id="path105591-5-6"
|
||||||
|
style="font-weight:bold;font-size:13.4639px;line-height:125%;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';letter-spacing:0px;word-spacing:0px;fill:#126d82;fill-opacity:1;stroke-width:1.42731px" />
|
||||||
|
<path
|
||||||
|
style="font-weight:bold;font-size:13.4639px;line-height:125%;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';letter-spacing:0px;word-spacing:0px;fill:#126d82;fill-opacity:1;stroke-width:1.42731px"
|
||||||
|
d="m 619.0778,818.72569 h -2.94385 v 9.91319 h -3.40103 v -9.91319 h -1.87336 v -1.63918 l 1.87336,-0.91439 v -0.91437 q 0,-1.59458 0.53524,-2.4755 0.54639,-0.89209 1.52768,-1.24891 0.99243,-0.36799 2.34169,-0.36799 0.99245,0 1.80646,0.16725 0.81401,0.15605 1.32696,0.35684 l -0.86978,2.4978 q -0.39027,-0.12263 -0.84747,-0.22301 -0.45719,-0.10041 -1.04819,-0.10041 -0.71365,0 -1.04818,0.43488 -0.32338,0.42374 -0.32338,1.09279 v 0.78056 h 2.94385 z"
|
||||||
|
id="path106049-0-7" />
|
||||||
|
<path
|
||||||
|
style="font-weight:bold;font-size:13.4639px;line-height:125%;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';letter-spacing:0px;word-spacing:0px;fill:#126d82;fill-opacity:1;stroke-width:1.42731px"
|
||||||
|
d="m 609.97621,818.72569 h -2.94384 v 9.91319 h -3.40104 v -9.91319 h -1.87335 v -1.63918 l 1.87335,-0.91439 v -0.91437 q 0,-1.59458 0.53525,-2.4755 0.5464,-0.89209 1.52767,-1.24891 0.99244,-0.36799 2.34171,-0.36799 0.99243,0 1.80644,0.16725 0.81403,0.15605 1.32697,0.35684 l -0.86978,2.4978 q -0.39028,-0.12263 -0.84746,-0.22301 -0.45719,-0.10041 -1.04819,-0.10041 -0.71366,0 -1.0482,0.43488 -0.32337,0.42374 -0.32337,1.09279 v 0.78056 h 2.94384 z"
|
||||||
|
id="path105593-48-5" />
|
||||||
|
<path
|
||||||
|
d="m 642.93756,812.33621 -4.14815,16.30267 h -3.93629 l -2.20788,-8.56393 q -0.0668,-0.24532 -0.17842,-0.74711 -0.11144,-0.50178 -0.23417,-1.09278 -0.12264,-0.60216 -0.22302,-1.12626 -0.0892,-0.53524 -0.12263,-0.84746 -0.0334,0.31222 -0.13383,0.83632 -0.0892,0.5241 -0.21187,1.11509 -0.11144,0.591 -0.22303,1.10394 -0.11144,0.51294 -0.1784,0.78057 l -2.19675,8.54162 H 625.018 l -4.1593,-16.30267 h 3.40103 l 2.08522,8.89845 q 0.0892,0.40143 0.20073,0.95898 0.12263,0.55753 0.23417,1.17084 0.12264,0.60216 0.21185,1.17085 0.10042,0.55755 0.14503,0.97013 0.0558,-0.42373 0.14502,-0.98128 0.0892,-0.56869 0.18956,-1.14854 0.11144,-0.591 0.22303,-1.0928 0.11144,-0.50179 0.20071,-0.81401 l 2.37516,-9.13262 h 3.26722 l 2.37515,9.13262 q 0.078,0.30107 0.17842,0.81401 0.11144,0.5018 0.22301,1.0928 0.11144,0.591 0.20073,1.15969 0.10041,0.55755 0.14502,0.97013 0.078,-0.55754 0.21187,-1.34926 0.14502,-0.80287 0.30107,-1.59459 0.16724,-0.79171 0.28993,-1.32695 l 2.07408,-8.89845 z"
|
||||||
|
id="path105595-7-3"
|
||||||
|
style="font-weight:bold;font-size:13.4639px;line-height:125%;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';letter-spacing:0px;word-spacing:0px;fill:#126d82;fill-opacity:1;stroke-width:1.42731px" />
|
||||||
|
<path
|
||||||
|
d="m 654.71528,822.38321 q 0,1.56112 -0.42374,2.76542 -0.41257,1.2043 -1.21544,2.04062 -0.79173,0.82517 -1.91797,1.24891 -1.11508,0.42374 -2.52011,0.42374 -1.3158,0 -2.41974,-0.42374 -1.09279,-0.42374 -1.90682,-1.24891 -0.80287,-0.83632 -1.2489,-2.04062 -0.43489,-1.2043 -0.43489,-2.76542 0,-2.07409 0.73597,-3.51256 0.73595,-1.43846 2.09636,-2.18557 1.36042,-0.74712 3.24494,-0.74712 1.75069,0 3.09996,0.74712 1.3604,0.74711 2.12982,2.18557 0.78056,1.43847 0.78056,3.51256 z m -8.61967,0 q 0,1.2266 0.26762,2.06292 0.26763,0.83631 0.83632,1.26005 0.56871,0.42374 1.48308,0.42374 0.90323,0 1.46077,-0.42374 0.56871,-0.42374 0.82517,-1.26005 0.26762,-0.83632 0.26762,-2.06292 0,-1.23777 -0.26762,-2.05178 -0.25646,-0.82517 -0.82517,-1.23775 -0.5687,-0.41259 -1.48307,-0.41259 -1.34927,0 -1.96256,0.92553 -0.60216,0.92552 -0.60216,2.77659 z"
|
||||||
|
id="path105597-17-5"
|
||||||
|
style="font-weight:bold;font-size:13.4639px;line-height:125%;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';letter-spacing:0px;word-spacing:0px;fill:#126d82;fill-opacity:1;stroke-width:1.42731px" />
|
||||||
|
<path
|
||||||
|
d="m 663.15875,815.93796 q 0.25648,0 0.59102,0.0334 0.34566,0.0222 0.55753,0.0668 l -0.25646,3.18918 q -0.16725,-0.0558 -0.47949,-0.078 -0.30108,-0.0334 -0.52411,-0.0334 -0.65789,0 -1.28235,0.16724 -0.61331,0.16725 -1.10394,0.54639 -0.49064,0.36799 -0.78056,0.98129 -0.27879,0.60214 -0.27879,1.48307 v 6.34489 h -3.40103 v -12.46675 h 2.57588 l 0.50178,2.09639 h 0.16724 q 0.36797,-0.63561 0.91437,-1.15971 0.55755,-0.53525 1.26006,-0.84746 0.71366,-0.32338 1.53882,-0.32338 z"
|
||||||
|
id="path105599-2-6"
|
||||||
|
style="font-weight:bold;font-size:13.4639px;line-height:125%;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';letter-spacing:0px;word-spacing:0px;fill:#126d82;fill-opacity:1;stroke-width:1.42731px" />
|
||||||
|
<path
|
||||||
|
d="m 669.19362,811.28802 v 7.76105 q 0,0.7025 -0.0558,1.40503 -0.0558,0.7025 -0.12264,1.40501 h 0.0446 q 0.34568,-0.49064 0.70252,-0.97013 0.36797,-0.47949 0.78057,-0.92554 l 3.49023,-3.79132 h 3.83593 l -4.95101,5.40822 5.25208,7.05854 h -3.92513 l -3.5906,-5.05137 -1.46078,1.17085 v 3.88052 h -3.40103 v -17.35086 z"
|
||||||
|
id="path105601-7-2"
|
||||||
|
style="font-weight:bold;font-size:13.4639px;line-height:125%;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';letter-spacing:0px;word-spacing:0px;fill:#126d82;fill-opacity:1;stroke-width:1.42731px" />
|
||||||
|
<path
|
||||||
|
d="m 686.97604,818.72569 h -2.94385 v 9.91319 h -3.40103 v -9.91319 h -1.87336 v -1.63918 l 1.87336,-0.91439 v -0.91437 q 0,-1.59458 0.53524,-2.4755 0.54639,-0.89209 1.52768,-1.24891 0.99243,-0.36799 2.34169,-0.36799 0.99245,0 1.80646,0.16725 0.81401,0.15605 1.32696,0.35684 l -0.86978,2.4978 q -0.39027,-0.12263 -0.84747,-0.22301 -0.45719,-0.10041 -1.04819,-0.10041 -0.71365,0 -1.04818,0.43488 -0.32338,0.42374 -0.32338,1.09279 v 0.78056 h 2.94385 z"
|
||||||
|
id="path105603-22-9"
|
||||||
|
style="font-weight:bold;font-size:13.4639px;line-height:125%;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';letter-spacing:0px;word-spacing:0px;fill:#126d82;fill-opacity:1;stroke-width:1.42731px" />
|
||||||
|
<path
|
||||||
|
d="m 693.05548,828.63888 h -3.40103 v -17.35086 h 3.40103 z"
|
||||||
|
id="path105605-6-1"
|
||||||
|
style="font-weight:bold;font-size:13.4639px;line-height:125%;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';letter-spacing:0px;word-spacing:0px;fill:#126d82;fill-opacity:1;stroke-width:1.42731px" />
|
||||||
|
<path
|
||||||
|
d="m 706.62835,822.38321 q 0,1.56112 -0.42372,2.76542 -0.41259,1.2043 -1.21546,2.04062 -0.79171,0.82517 -1.91797,1.24891 -1.11508,0.42374 -2.5201,0.42374 -1.31581,0 -2.41975,-0.42374 -1.09279,-0.42374 -1.90682,-1.24891 -0.80287,-0.83632 -1.24889,-2.04062 -0.4349,-1.2043 -0.4349,-2.76542 0,-2.07409 0.73597,-3.51256 0.73595,-1.43846 2.09637,-2.18557 1.36041,-0.74712 3.24493,-0.74712 1.75069,0 3.09996,0.74712 1.3604,0.74711 2.12982,2.18557 0.78056,1.43847 0.78056,3.51256 z m -8.61967,0 q 0,1.2266 0.26763,2.06292 0.26762,0.83631 0.83631,1.26005 0.56871,0.42374 1.48309,0.42374 0.90323,0 1.46076,-0.42374 0.56871,-0.42374 0.82517,-1.26005 0.26762,-0.83632 0.26762,-2.06292 0,-1.23777 -0.26762,-2.05178 -0.25646,-0.82517 -0.82517,-1.23775 -0.5687,-0.41259 -1.48307,-0.41259 -1.34925,0 -1.96256,0.92553 -0.60216,0.92552 -0.60216,2.77659 z"
|
||||||
|
id="path105607-1-2"
|
||||||
|
style="font-weight:bold;font-size:13.4639px;line-height:125%;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';letter-spacing:0px;word-spacing:0px;fill:#126d82;fill-opacity:1;stroke-width:1.42731px" />
|
||||||
|
<path
|
||||||
|
d="m 719.02496,828.63888 -0.95898,-4.36001 q -0.078,-0.39029 -0.25648,-1.14855 -0.17842,-0.76942 -0.39027,-1.6392 -0.20073,-0.88092 -0.37915,-1.62804 -0.16724,-0.7471 -0.24532,-1.09278 h -0.10041 q -0.078,0.34568 -0.24532,1.09278 -0.16724,0.74712 -0.37913,1.62804 -0.20071,0.88093 -0.37913,1.66149 -0.17842,0.76942 -0.26762,1.17085 l -1.00359,4.31542 h -3.6575 l -3.546,-12.46676 h 3.38989 l 1.43847,5.51973 q 0.14503,0.57985 0.27877,1.38272 0.13383,0.7917 0.23417,1.53882 0.11144,0.73597 0.16725,1.17085 h 0.0892 q 0.0222,-0.32338 0.0892,-0.85862 0.078,-0.53525 0.16725,-1.10394 0.10041,-0.57985 0.17842,-1.03704 0.0892,-0.46835 0.13383,-0.63561 l 1.53882,-5.97691 h 3.74671 l 1.46078,5.97691 q 0.078,0.32338 0.20071,1.02588 0.13382,0.70252 0.23417,1.44964 0.10041,0.73595 0.11144,1.15969 h 0.0892 q 0.0446,-0.37913 0.15604,-1.12624 0.11144,-0.74712 0.25648,-1.56115 0.15605,-0.82515 0.31223,-1.405 l 1.49423,-5.51973 h 3.33412 l -3.5906,12.46676 z"
|
||||||
|
id="path105609-0-7"
|
||||||
|
style="font-weight:bold;font-size:13.4639px;line-height:125%;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Bold';letter-spacing:0px;word-spacing:0px;fill:#126d82;fill-opacity:1;stroke-width:1.42731px" />
|
||||||
|
<path
|
||||||
|
id="path73257-7-2-9-159-9"
|
||||||
|
style="vector-effect:none;fill:#126d82;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.433;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
|
d="m 574.18839,797.73763 v 0.91595 c 0.96107,0.84548 1.66181,1.94689 2.02041,3.17567 h -17.54738 c -3.11685,0 -5.68164,2.56482 -5.68164,5.68159 v 3.91192 c 0,3.11682 2.56479,5.68164 5.68164,5.68164 h 5.6851 4.69113 5.6878 c 1.21493,0 2.13344,0.91846 2.13344,2.13344 v 3.91632 c 0,1.21498 -0.91851,2.13346 -2.13344,2.13346 h -14.79076 c -0.75878,-2.29982 -2.93713,-3.97943 -5.47735,-3.97943 -3.16218,0 -5.76138,2.60267 -5.76138,5.76489 0,3.1622 2.5992,5.76399 5.76138,5.76399 2.54974,0 4.73517,-1.69176 5.48615,-4.00482 h 14.78196 c 3.1168,0 5.67808,-2.5613 5.67808,-5.67809 v -3.91632 c 0,-3.11677 -2.56128,-5.68164 -5.67808,-5.68164 h -5.6878 -4.69113 -5.6851 c -1.21497,0 -2.13609,-0.91837 -2.13609,-2.13344 v -3.91192 c 0,-1.21499 0.92112,-2.13696 2.13609,-2.13696 h 17.60609 c -0.33391,1.31874 -1.05865,2.50576 -2.07912,3.4053 v 0.68721 l 11.72877,-5.86483 z m -19.73105,27.11871 c 1.24555,0 2.21936,0.97116 2.21936,2.21674 0,1.24556 -0.97381,2.21936 -2.21936,2.21936 -1.24559,0 -2.21675,-0.9738 -2.21675,-2.21936 0,-1.24558 0.97116,-2.21674 2.21675,-2.21674 z"
|
||||||
|
sodipodi:nodetypes="cccssssccsssscssscssssccsssscccccsssss" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:7.18046px;line-height:125%;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Semi-Bold';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.448779px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
x="587.66064"
|
||||||
|
y="805.95227"
|
||||||
|
id="text109870-49-3"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan109868-0-6"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Semi-Bold';fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.448779px"
|
||||||
|
x="587.66064"
|
||||||
|
y="805.95227">Draw the code</tspan></text>
|
||||||
|
</g>
|
||||||
<path
|
<path
|
||||||
d="m 129.58873,798.16413 q 2.10753,0 3.40104,1.63919 1.30466,1.63918 1.30466,4.80606 0,2.11867 -0.6133,3.56829 -0.61331,1.43847 -1.69494,2.17443 -1.08165,0.73597 -2.48666,0.73597 -0.90323,0 -1.54998,-0.22302 -0.64675,-0.23417 -1.10395,-0.591 -0.45719,-0.36798 -0.79171,-0.78057 h -0.17842 q 0.0892,0.44604 0.13383,0.91439 0.0446,0.46833 0.0446,0.91437 v 5.02907 h -3.40104 v -17.95302 h 2.76543 l 0.47949,1.6169 h 0.15605 q 0.33452,-0.5018 0.81401,-0.92554 0.47949,-0.42374 1.14855,-0.66905 0.68021,-0.25647 1.57228,-0.25647 z m -1.09279,2.72082 q -0.89207,0 -1.41617,0.36799 -0.52408,0.36798 -0.76942,1.10393 -0.23416,0.73597 -0.25646,1.86222 v 0.36798 q 0,1.2043 0.22301,2.04062 0.23418,0.83631 0.76942,1.27121 0.54639,0.43488 1.49423,0.43488 0.78056,0 1.28236,-0.43488 0.50179,-0.4349 0.74711,-1.27121 0.25646,-0.84748 0.25646,-2.06292 0,-1.82875 -0.56869,-2.75428 -0.56869,-0.92554 -1.76185,-0.92554 z"
|
d="m 129.58873,798.16413 q 2.10753,0 3.40104,1.63919 1.30466,1.63918 1.30466,4.80606 0,2.11867 -0.6133,3.56829 -0.61331,1.43847 -1.69494,2.17443 -1.08165,0.73597 -2.48666,0.73597 -0.90323,0 -1.54998,-0.22302 -0.64675,-0.23417 -1.10395,-0.591 -0.45719,-0.36798 -0.79171,-0.78057 h -0.17842 q 0.0892,0.44604 0.13383,0.91439 0.0446,0.46833 0.0446,0.91437 v 5.02907 h -3.40104 v -17.95302 h 2.76543 l 0.47949,1.6169 h 0.15605 q 0.33452,-0.5018 0.81401,-0.92554 0.47949,-0.42374 1.14855,-0.66905 0.68021,-0.25647 1.57228,-0.25647 z m -1.09279,2.72082 q -0.89207,0 -1.41617,0.36799 -0.52408,0.36798 -0.76942,1.10393 -0.23416,0.73597 -0.25646,1.86222 v 0.36798 q 0,1.2043 0.22301,2.04062 0.23418,0.83631 0.76942,1.27121 0.54639,0.43488 1.49423,0.43488 0.78056,0 1.28236,-0.43488 0.50179,-0.4349 0.74711,-1.27121 0.25646,-0.84748 0.25646,-2.06292 0,-1.82875 -0.56869,-2.75428 -0.56869,-0.92554 -1.76185,-0.92554 z"
|
||||||
id="path105589-78"
|
id="path105589-78"
|
||||||
|
@ -1029,5 +1126,29 @@
|
||||||
x="141.17513"
|
x="141.17513"
|
||||||
y="396.69467"
|
y="396.69467"
|
||||||
style="fill:#19788f;fill-opacity:1" />
|
style="fill:#19788f;fill-opacity:1" />
|
||||||
|
<circle
|
||||||
|
style="color:#000000;overflow:visible;fill:none;fill-rule:evenodd;stroke:#126d82;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path1309-1"
|
||||||
|
cx="636.84607"
|
||||||
|
cy="925.89471"
|
||||||
|
r="0" />
|
||||||
|
<circle
|
||||||
|
style="color:#000000;overflow:visible;fill:none;fill-rule:evenodd;stroke:#126d82;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path1309-28"
|
||||||
|
cx="622.87994"
|
||||||
|
cy="928.04297"
|
||||||
|
r="0" />
|
||||||
|
<circle
|
||||||
|
style="color:#000000;overflow:visible;fill:none;fill-rule:evenodd;stroke:#126d82;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path1309-2"
|
||||||
|
cx="622.87994"
|
||||||
|
cy="928.04297"
|
||||||
|
r="0" />
|
||||||
|
<circle
|
||||||
|
style="color:#000000;overflow:visible;fill:none;fill-rule:evenodd;stroke:#126d82;stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path1309-9"
|
||||||
|
cx="622.87994"
|
||||||
|
cy="928.04297"
|
||||||
|
r="0" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 7.0 MiB After Width: | Height: | Size: 7.0 MiB |
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
||||||
from SpiffWorkflow.bpmn.specs.events.event_definitions import MessageEventDefinition
|
|
||||||
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
|
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
|
||||||
|
|
||||||
__author__ = 'matth'
|
__author__ = 'matth'
|
||||||
|
@ -86,8 +85,7 @@ class ApprovalsTest(BpmnWorkflowTestCase):
|
||||||
self.save_restore()
|
self.save_restore()
|
||||||
self.do_next_named_step('Parallel_Approvals_SP.Manager_Approval')
|
self.do_next_named_step('Parallel_Approvals_SP.Manager_Approval')
|
||||||
self.do_next_exclusive_step('Parallel_Approvals_SP.Step1')
|
self.do_next_exclusive_step('Parallel_Approvals_SP.Step1')
|
||||||
self.do_next_exclusive_step(
|
self.do_next_exclusive_step('Parallel_Approvals_SP.Supervisor_Approval')
|
||||||
'Parallel_Approvals_SP.Supervisor_Approval')
|
|
||||||
self.do_next_exclusive_step('Approvals.Parallel_SP_Done')
|
self.do_next_exclusive_step('Approvals.Parallel_SP_Done')
|
||||||
|
|
||||||
def testSaveRestoreWaiting(self):
|
def testSaveRestoreWaiting(self):
|
||||||
|
@ -108,93 +106,10 @@ class ApprovalsTest(BpmnWorkflowTestCase):
|
||||||
self.save_restore()
|
self.save_restore()
|
||||||
self.do_next_exclusive_step('Parallel_Approvals_SP.Step1')
|
self.do_next_exclusive_step('Parallel_Approvals_SP.Step1')
|
||||||
self.save_restore()
|
self.save_restore()
|
||||||
self.do_next_exclusive_step(
|
self.do_next_exclusive_step('Parallel_Approvals_SP.Supervisor_Approval')
|
||||||
'Parallel_Approvals_SP.Supervisor_Approval')
|
|
||||||
self.save_restore()
|
self.save_restore()
|
||||||
self.do_next_exclusive_step('Approvals.Parallel_SP_Done')
|
self.do_next_exclusive_step('Approvals.Parallel_SP_Done')
|
||||||
|
|
||||||
def testReadonlyWaiting(self):
|
|
||||||
|
|
||||||
self.do_next_named_step('First_Approval_Wins.Manager_Approval')
|
|
||||||
|
|
||||||
readonly = self.get_read_only_workflow()
|
|
||||||
self.assertEqual(1, len(readonly.get_ready_user_tasks()))
|
|
||||||
self.assertEqual('Approvals.First_Approval_Wins_Done',
|
|
||||||
readonly.get_ready_user_tasks()[0].task_spec.name)
|
|
||||||
self.assertRaises(AssertionError, readonly.do_engine_steps)
|
|
||||||
self.assertRaises(AssertionError, readonly.refresh_waiting_tasks)
|
|
||||||
self.assertRaises(AssertionError, readonly.catch, MessageEventDefinition('Cheese'))
|
|
||||||
self.assertRaises(
|
|
||||||
AssertionError, readonly.get_ready_user_tasks()[0].complete)
|
|
||||||
|
|
||||||
self.do_next_exclusive_step('Approvals.First_Approval_Wins_Done')
|
|
||||||
|
|
||||||
readonly = self.get_read_only_workflow()
|
|
||||||
self.assertEqual(2, len(readonly.get_ready_user_tasks()))
|
|
||||||
self.assertEqual(
|
|
||||||
['Approvals.Manager_Approval__P_',
|
|
||||||
'Approvals.Supervisor_Approval__P_'],
|
|
||||||
sorted(t.task_spec.name for t in readonly.get_ready_user_tasks()))
|
|
||||||
self.assertRaises(
|
|
||||||
AssertionError, readonly.get_ready_user_tasks()[0].complete)
|
|
||||||
|
|
||||||
self.do_next_named_step('Approvals.Supervisor_Approval__P_')
|
|
||||||
|
|
||||||
readonly = self.get_read_only_workflow()
|
|
||||||
self.assertEqual(1, len(readonly.get_ready_user_tasks()))
|
|
||||||
self.assertEqual('Approvals.Manager_Approval__P_',
|
|
||||||
readonly.get_ready_user_tasks()[0].task_spec.name)
|
|
||||||
self.assertRaises(
|
|
||||||
AssertionError, readonly.get_ready_user_tasks()[0].complete)
|
|
||||||
self.do_next_named_step('Approvals.Manager_Approval__P_')
|
|
||||||
|
|
||||||
readonly = self.get_read_only_workflow()
|
|
||||||
self.assertEqual(1, len(readonly.get_ready_user_tasks()))
|
|
||||||
self.assertEqual('Approvals.Parallel_Approvals_Done',
|
|
||||||
readonly.get_ready_user_tasks()[0].task_spec.name)
|
|
||||||
self.assertRaises(
|
|
||||||
AssertionError, readonly.get_ready_user_tasks()[0].complete)
|
|
||||||
self.do_next_exclusive_step('Approvals.Parallel_Approvals_Done')
|
|
||||||
|
|
||||||
readonly = self.get_read_only_workflow()
|
|
||||||
self.assertEqual(2, len(readonly.get_ready_user_tasks()))
|
|
||||||
self.assertEqual(
|
|
||||||
['Parallel_Approvals_SP.Manager_Approval',
|
|
||||||
'Parallel_Approvals_SP.Step1'],
|
|
||||||
sorted(t.task_spec.name for t in readonly.get_ready_user_tasks()))
|
|
||||||
self.assertRaises(
|
|
||||||
AssertionError, readonly.get_ready_user_tasks()[0].complete)
|
|
||||||
self.do_next_named_step('Parallel_Approvals_SP.Manager_Approval')
|
|
||||||
|
|
||||||
readonly = self.get_read_only_workflow()
|
|
||||||
self.assertEqual(1, len(readonly.get_ready_user_tasks()))
|
|
||||||
self.assertEqual('Parallel_Approvals_SP.Step1',
|
|
||||||
readonly.get_ready_user_tasks()[0].task_spec.name)
|
|
||||||
self.assertRaises(
|
|
||||||
AssertionError, readonly.get_ready_user_tasks()[0].complete)
|
|
||||||
self.do_next_exclusive_step('Parallel_Approvals_SP.Step1')
|
|
||||||
|
|
||||||
readonly = self.get_read_only_workflow()
|
|
||||||
self.assertEqual(1, len(readonly.get_ready_user_tasks()))
|
|
||||||
self.assertEqual('Parallel_Approvals_SP.Supervisor_Approval',
|
|
||||||
readonly.get_ready_user_tasks()[0].task_spec.name)
|
|
||||||
self.assertRaises(
|
|
||||||
AssertionError, readonly.get_ready_user_tasks()[0].complete)
|
|
||||||
self.do_next_exclusive_step(
|
|
||||||
'Parallel_Approvals_SP.Supervisor_Approval')
|
|
||||||
|
|
||||||
readonly = self.get_read_only_workflow()
|
|
||||||
self.assertEqual(1, len(readonly.get_ready_user_tasks()))
|
|
||||||
self.assertEqual('Approvals.Parallel_SP_Done',
|
|
||||||
readonly.get_ready_user_tasks()[0].task_spec.name)
|
|
||||||
self.assertRaises(
|
|
||||||
AssertionError, readonly.get_ready_user_tasks()[0].complete)
|
|
||||||
self.do_next_exclusive_step('Approvals.Parallel_SP_Done')
|
|
||||||
|
|
||||||
readonly = self.get_read_only_workflow()
|
|
||||||
self.assertEqual(0, len(readonly.get_ready_user_tasks()))
|
|
||||||
self.assertEqual(0, len(readonly.get_waiting_tasks()))
|
|
||||||
|
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
return unittest.TestLoader().loadTestsFromTestCase(ApprovalsTest)
|
return unittest.TestLoader().loadTestsFromTestCase(ApprovalsTest)
|
||||||
|
|
|
@ -1,118 +0,0 @@
|
||||||
import os
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
|
||||||
from SpiffWorkflow.bpmn.serializer.BpmnSerializer import BpmnSerializer
|
|
||||||
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
|
||||||
from .BpmnLoaderForTests import TestBpmnParser
|
|
||||||
|
|
||||||
|
|
||||||
class BpmnSerializerTest(unittest.TestCase):
|
|
||||||
CORRELATE = BpmnSerializer
|
|
||||||
|
|
||||||
def load_workflow_spec(self, filename, process_name):
|
|
||||||
f = os.path.join(os.path.dirname(__file__), 'data', filename)
|
|
||||||
parser = TestBpmnParser()
|
|
||||||
parser.add_bpmn_files_by_glob(f)
|
|
||||||
top_level_spec = parser.get_spec(process_name)
|
|
||||||
subprocesses = parser.get_subprocess_specs(process_name)
|
|
||||||
return top_level_spec, subprocesses
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(BpmnSerializerTest, self).setUp()
|
|
||||||
self.serializer = BpmnSerializer()
|
|
||||||
self.spec, subprocesses = self.load_workflow_spec('random_fact.bpmn', 'random_fact')
|
|
||||||
self.workflow = BpmnWorkflow(self.spec, subprocesses)
|
|
||||||
|
|
||||||
def testDeserializeWorkflowSpec(self):
|
|
||||||
self.assertIsNotNone(self.spec)
|
|
||||||
|
|
||||||
def testSerializeWorkflowSpec(self):
|
|
||||||
spec_serialized = self.serializer.serialize_workflow_spec(self.spec)
|
|
||||||
result = self.serializer.deserialize_workflow_spec(spec_serialized)
|
|
||||||
spec_serialized2 = self.serializer.serialize_workflow_spec(result)
|
|
||||||
self.assertEqual(spec_serialized, spec_serialized2)
|
|
||||||
|
|
||||||
def testSerializeWorkflow(self):
|
|
||||||
json = self.serializer.serialize_workflow(self.workflow)
|
|
||||||
print(json)
|
|
||||||
|
|
||||||
def testDeserializeWorkflow(self):
|
|
||||||
self._compare_with_deserialized_copy(self.workflow)
|
|
||||||
|
|
||||||
def testDeserializeCallActivityChildren(self):
|
|
||||||
"""Tested as a part of deserialize workflow."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def testSerializeTask(self):
|
|
||||||
json = self.serializer.serialize_workflow(self.workflow)
|
|
||||||
print(json)
|
|
||||||
|
|
||||||
def testDeserializeTask(self):
|
|
||||||
self._compare_with_deserialized_copy(self.workflow)
|
|
||||||
|
|
||||||
def testDeserializeActiveWorkflow(self):
|
|
||||||
self.workflow.do_engine_steps()
|
|
||||||
self._compare_with_deserialized_copy(self.workflow)
|
|
||||||
|
|
||||||
def testDeserializeWithData(self):
|
|
||||||
self.workflow.data["test"] = "my_test"
|
|
||||||
json = self.serializer.serialize_workflow(self.workflow)
|
|
||||||
wf2 = self.serializer.deserialize_workflow(json, workflow_spec=self.spec)
|
|
||||||
self.assertEqual('my_test', wf2.get_data("test"))
|
|
||||||
|
|
||||||
def testDeserializeWithDefaultScriptEngineClass(self):
|
|
||||||
json = self.serializer.serialize_workflow(self.workflow)
|
|
||||||
wf2 = self.serializer.deserialize_workflow(json, workflow_spec=self.spec)
|
|
||||||
self.assertIsNotNone(self.workflow.script_engine)
|
|
||||||
self.assertIsNotNone(wf2.script_engine)
|
|
||||||
self.assertEqual(self.workflow.script_engine.__class__,
|
|
||||||
wf2.script_engine.__class__)
|
|
||||||
|
|
||||||
@unittest.skip("Deserialize does not persist the script engine, Fix me.")
|
|
||||||
def testDeserializeWithCustomScriptEngine(self):
|
|
||||||
class CustomScriptEngine(PythonScriptEngine):
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.workflow.script_engine = CustomScriptEngine()
|
|
||||||
json = self.serializer.serialize_workflow(self.workflow)
|
|
||||||
wf2 = self.serializer.deserialize_workflow(json, workflow_spec=self.spec)
|
|
||||||
self.assertEqual(self.workflow.script_engine.__class__,
|
|
||||||
wf2.script_engine.__class__)
|
|
||||||
|
|
||||||
def testDeserializeWithDataOnTask(self):
|
|
||||||
self.workflow.do_engine_steps()
|
|
||||||
user_task = self.workflow.get_ready_user_tasks()[0]
|
|
||||||
user_task.data = {"test":"my_test"}
|
|
||||||
self._compare_with_deserialized_copy(self.workflow)
|
|
||||||
|
|
||||||
def testLastTaskIsSetAndWorksThroughRestore(self):
|
|
||||||
self.workflow.do_engine_steps()
|
|
||||||
json = self.serializer.serialize_workflow(self.workflow)
|
|
||||||
wf2 = self.serializer.deserialize_workflow(json, workflow_spec=self.spec)
|
|
||||||
self.assertIsNotNone(self.workflow.last_task)
|
|
||||||
self.assertIsNotNone(wf2.last_task)
|
|
||||||
self._compare_workflows(self.workflow, wf2)
|
|
||||||
|
|
||||||
def _compare_with_deserialized_copy(self, wf):
|
|
||||||
json = self.serializer.serialize_workflow(wf)
|
|
||||||
wf2 = self.serializer.deserialize_workflow(json, workflow_spec=self.spec)
|
|
||||||
self._compare_workflows(wf, wf2)
|
|
||||||
|
|
||||||
def _compare_workflows(self, w1, w2):
|
|
||||||
self.assertIsInstance(w1, BpmnWorkflow)
|
|
||||||
self.assertIsInstance(w2, BpmnWorkflow)
|
|
||||||
self.assertEqual(w1.data, w2.data)
|
|
||||||
self.assertEqual(w1.name, w2.name)
|
|
||||||
for task in w1.get_ready_user_tasks():
|
|
||||||
w2_task = w2.get_task(task.id)
|
|
||||||
self.assertIsNotNone(w2_task)
|
|
||||||
self.assertEqual(task.data, w2_task.data)
|
|
||||||
|
|
||||||
|
|
||||||
def suite():
|
|
||||||
return unittest.TestLoader().loadTestsFromTestCase(BpmnSerializerTest)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
unittest.TextTestRunner(verbosity=2).run(suite())
|
|
|
@ -1,13 +1,11 @@
|
||||||
import os
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
import json
|
import json
|
||||||
from uuid import uuid4
|
|
||||||
|
|
||||||
from SpiffWorkflow.task import TaskState
|
from SpiffWorkflow.task import TaskState
|
||||||
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
||||||
from SpiffWorkflow.bpmn.parser.BpmnParser import BpmnParser
|
from SpiffWorkflow.bpmn.parser.BpmnParser import BpmnParser
|
||||||
from SpiffWorkflow.bpmn.serializer.workflow import BpmnWorkflowSerializer
|
from SpiffWorkflow.bpmn.serializer.workflow import BpmnWorkflowSerializer
|
||||||
from SpiffWorkflow.bpmn.serializer.BpmnSerializer import BpmnSerializer
|
|
||||||
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
||||||
from tests.SpiffWorkflow.bpmn.BpmnLoaderForTests import TestUserTaskConverter
|
from tests.SpiffWorkflow.bpmn.BpmnLoaderForTests import TestUserTaskConverter
|
||||||
|
|
||||||
|
@ -48,13 +46,6 @@ class BpmnWorkflowSerializerTest(unittest.TestCase):
|
||||||
version = self.serializer.get_version(spec_serialized)
|
version = self.serializer.get_version(spec_serialized)
|
||||||
self.assertEqual(version, self.SERIALIZER_VERSION)
|
self.assertEqual(version, self.SERIALIZER_VERSION)
|
||||||
|
|
||||||
def testSerializeToOldSerializerThenNewSerializer(self):
|
|
||||||
old_serializer = BpmnSerializer()
|
|
||||||
old_json = old_serializer.serialize_workflow(self.workflow)
|
|
||||||
new_workflow = old_serializer.deserialize_workflow(old_json)
|
|
||||||
new_json = self.serializer.serialize_json(new_workflow)
|
|
||||||
new_workflow_2 = self.serializer.deserialize_json(new_json)
|
|
||||||
|
|
||||||
def testSerializeWorkflow(self):
|
def testSerializeWorkflow(self):
|
||||||
serialized = self.serializer.serialize_json(self.workflow)
|
serialized = self.serializer.serialize_json(self.workflow)
|
||||||
json.loads(serialized)
|
json.loads(serialized)
|
||||||
|
|
|
@ -122,7 +122,7 @@ class BpmnWorkflowTestCase(unittest.TestCase):
|
||||||
before_dump = self.workflow.get_dump()
|
before_dump = self.workflow.get_dump()
|
||||||
# Check that we can actully convert this to JSON
|
# Check that we can actully convert this to JSON
|
||||||
json_str = json.dumps(before_state)
|
json_str = json.dumps(before_state)
|
||||||
after = self.serializer.workflow_from_dict(json.loads(json_str), read_only=False)
|
after = self.serializer.workflow_from_dict(json.loads(json_str))
|
||||||
# Check that serializing and deserializing results in the same workflow
|
# Check that serializing and deserializing results in the same workflow
|
||||||
after_state = self.serializer.workflow_to_dict(after)
|
after_state = self.serializer.workflow_to_dict(after)
|
||||||
after_dump = after.get_dump()
|
after_dump = after.get_dump()
|
||||||
|
@ -132,11 +132,7 @@ class BpmnWorkflowTestCase(unittest.TestCase):
|
||||||
self.workflow = after
|
self.workflow = after
|
||||||
|
|
||||||
def restore(self, state):
|
def restore(self, state):
|
||||||
self.workflow = self.serializer.workflow_from_dict(state, read_only=False)
|
self.workflow = self.serializer.workflow_from_dict(state)
|
||||||
|
|
||||||
def get_read_only_workflow(self):
|
|
||||||
state = self._get_workflow_state()
|
|
||||||
return self.serializer.workflow_from_dict(state, read_only=True)
|
|
||||||
|
|
||||||
def _get_workflow_state(self, do_steps=True):
|
def _get_workflow_state(self, do_steps=True):
|
||||||
if do_steps:
|
if do_steps:
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
||||||
from SpiffWorkflow.bpmn.exceptions import WorkflowTaskExecException
|
|
||||||
|
|
||||||
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
||||||
|
from SpiffWorkflow.exceptions import WorkflowTaskException
|
||||||
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
|
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
|
||||||
|
|
||||||
__author__ = 'kellym'
|
__author__ = 'kellym'
|
||||||
|
@ -60,7 +60,7 @@ class CallActivityTest(BpmnWorkflowTestCase):
|
||||||
def test_call_acitivity_errors_include_task_trace(self):
|
def test_call_acitivity_errors_include_task_trace(self):
|
||||||
error_spec = self.subprocesses.get('ErroringBPMN')
|
error_spec = self.subprocesses.get('ErroringBPMN')
|
||||||
error_spec, subprocesses = self.load_workflow_spec('call_activity_*.bpmn', 'ErroringBPMN')
|
error_spec, subprocesses = self.load_workflow_spec('call_activity_*.bpmn', 'ErroringBPMN')
|
||||||
with self.assertRaises(WorkflowTaskExecException) as context:
|
with self.assertRaises(WorkflowTaskException) as context:
|
||||||
self.workflow = BpmnWorkflow(error_spec, subprocesses)
|
self.workflow = BpmnWorkflow(error_spec, subprocesses)
|
||||||
self.workflow.do_engine_steps()
|
self.workflow.do_engine_steps()
|
||||||
self.assertEquals(2, len(context.exception.task_trace))
|
self.assertEquals(2, len(context.exception.task_trace))
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
from SpiffWorkflow.exceptions import WorkflowTaskException
|
||||||
from SpiffWorkflow.task import TaskState
|
from SpiffWorkflow.task import TaskState
|
||||||
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
||||||
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
||||||
from SpiffWorkflow.bpmn.exceptions import WorkflowTaskExecException
|
|
||||||
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
|
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
|
||||||
|
|
||||||
__author__ = 'McDonald, danfunk'
|
__author__ = 'McDonald, danfunk'
|
||||||
|
@ -46,7 +46,7 @@ class CustomInlineScriptTest(BpmnWorkflowTestCase):
|
||||||
def test_overwrite_function_with_local_variable(self):
|
def test_overwrite_function_with_local_variable(self):
|
||||||
ready_task = self.workflow.get_tasks(TaskState.READY)[0]
|
ready_task = self.workflow.get_tasks(TaskState.READY)[0]
|
||||||
ready_task.data = {'custom_function': "bill"}
|
ready_task.data = {'custom_function': "bill"}
|
||||||
with self.assertRaises(WorkflowTaskExecException) as e:
|
with self.assertRaises(WorkflowTaskException) as e:
|
||||||
self.workflow.do_engine_steps()
|
self.workflow.do_engine_steps()
|
||||||
self.assertTrue('' in str(e.exception))
|
self.assertTrue('' in str(e.exception))
|
||||||
self.assertTrue('custom_function' in str(e.exception))
|
self.assertTrue('custom_function' in str(e.exception))
|
||||||
|
|
|
@ -31,18 +31,11 @@ class InvalidWorkflowsTest(BpmnWorkflowTestCase):
|
||||||
except ValidationException as ex:
|
except ValidationException as ex:
|
||||||
self.assertTrue('No start event found' in ('%r' % ex),
|
self.assertTrue('No start event found' in ('%r' % ex),
|
||||||
'\'No start event found\' should be a substring of error message: \'%r\'' % ex)
|
'\'No start event found\' should be a substring of error message: \'%r\'' % ex)
|
||||||
self.assertTrue('No-Start-Event.bpmn20.xml' in ('%r' % ex),
|
self.assertTrue('No-Start-Event.bpmn20.xml' in ex.file_name,
|
||||||
'\'No-Start-Event.bpmn20.xml\' should be a substring of error message: \'%r\'' % ex)
|
'\'No-Start-Event.bpmn20.xml\' should be a substring of error message: \'%r\'' % ex)
|
||||||
self.assertTrue('process' in ('%r' % ex),
|
|
||||||
'\'process\' should be a substring of error message: \'%r\'' % ex)
|
|
||||||
self.assertTrue(
|
|
||||||
'sid-669ddebf-4196-41ee-8b04-bcc90bc5f983' in ('%r' % ex),
|
|
||||||
'\'sid-669ddebf-4196-41ee-8b04-bcc90bc5f983\' should be a substring of error message: \'%r\'' % ex)
|
|
||||||
self.assertTrue('No Start Event' in ('%r' % ex),
|
|
||||||
'\'No Start Event\' should be a substring of error message: \'%r\'' % ex)
|
|
||||||
|
|
||||||
def testSubprocessNotFound(self):
|
def testSubprocessNotFound(self):
|
||||||
|
|
||||||
with self.assertRaises(ValidationException) as exc:
|
with self.assertRaises(ValidationException) as exc:
|
||||||
self.load_workflow_spec('Invalid-Workflows/Subprocess-Not-Found.bpmn20.xml', 'Subprocess Not Found')
|
self.load_workflow_spec('Invalid-Workflows/Subprocess-Not-Found.bpmn20.xml', 'Subprocess Not Found')
|
||||||
self.assertIn("The process 'Missing subprocess' was not found.", str(exc))
|
self.assertIn("The process 'Missing subprocess' was not found.", str(exc))
|
||||||
|
@ -60,15 +53,12 @@ class InvalidWorkflowsTest(BpmnWorkflowTestCase):
|
||||||
'There is no support implemented for this task type' in (
|
'There is no support implemented for this task type' in (
|
||||||
'%r' % ex),
|
'%r' % ex),
|
||||||
'\'There is no support implemented for this task type\' should be a substring of error message: \'%r\'' % ex)
|
'\'There is no support implemented for this task type\' should be a substring of error message: \'%r\'' % ex)
|
||||||
self.assertTrue('Unsupported-Task.bpmn20.xml' in ('%r' % ex),
|
self.assertTrue('Unsupported-Task.bpmn20.xml' in ex.file_name,
|
||||||
'\'Unsupported-Task.bpmn20.xml\' should be a substring of error message: \'%r\'' % ex)
|
'\'Unsupported-Task.bpmn20.xml\' should be a substring of error message: \'%r\'' % ex)
|
||||||
self.assertTrue('businessRuleTask' in ('%r' % ex),
|
self.assertTrue('businessRuleTask' in ex.tag,
|
||||||
'\'businessRuleTask\' should be a substring of error message: \'%r\'' % ex)
|
'\'businessRuleTask\' should be a substring of the tag: \'%r\'' % ex)
|
||||||
self.assertTrue(
|
self.assertTrue('Business Rule Task' in ex.name,
|
||||||
'sid-75EEAB28-3B69-4282-B91A-0F3C97931834' in ('%r' % ex),
|
'\'Business Rule Task\' should be the name: \'%s\'' % ex.name)
|
||||||
'\'sid-75EEAB28-3B69-4282-B91A-0F3C97931834\' should be a substring of error message: \'%r\'' % ex)
|
|
||||||
self.assertTrue('Business Rule Task' in ('%r' % ex),
|
|
||||||
'\'Business Rule Task\' should be a substring of error message: \'%r\'' % ex)
|
|
||||||
|
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import unittest
|
import unittest
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from SpiffWorkflow.bpmn.parser.BpmnParser import BpmnParser
|
from SpiffWorkflow.bpmn.parser.BpmnParser import BpmnParser, BpmnValidator
|
||||||
|
from SpiffWorkflow.bpmn.parser.ValidationException import ValidationException
|
||||||
|
|
||||||
|
|
||||||
class ParserTest(unittest.TestCase):
|
class ParserTest(unittest.TestCase):
|
||||||
|
@ -27,3 +28,17 @@ class ParserTest(unittest.TestCase):
|
||||||
self.assertEqual(generate.data_output_associations[0].name, 'obj_1')
|
self.assertEqual(generate.data_output_associations[0].name, 'obj_1')
|
||||||
self.assertEqual(len(read.data_input_associations), 1)
|
self.assertEqual(len(read.data_input_associations), 1)
|
||||||
self.assertEqual(read.data_input_associations[0].name, 'obj_1')
|
self.assertEqual(read.data_input_associations[0].name, 'obj_1')
|
||||||
|
|
||||||
|
def testValidatorError(self):
|
||||||
|
parser = BpmnParser(validator=BpmnValidator())
|
||||||
|
bpmn_file = os.path.join(os.path.dirname(__file__), 'data',
|
||||||
|
'data_object_invalid.bpmn')
|
||||||
|
errored = False
|
||||||
|
try:
|
||||||
|
parser.add_bpmn_file(bpmn_file)
|
||||||
|
except ValidationException as ex:
|
||||||
|
errored = True
|
||||||
|
self.assertEqual(ex.file_name, bpmn_file)
|
||||||
|
self.assertEqual(14, ex.line_number)
|
||||||
|
self.assertIn('DataObjectReference_0cm8dnh', str(ex))
|
||||||
|
assert(errored, "This should have errored out with a validation exception.")
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from SpiffWorkflow.bpmn.exceptions import WorkflowTaskExecException
|
from SpiffWorkflow.exceptions import WorkflowTaskException
|
||||||
from SpiffWorkflow.task import TaskState
|
from SpiffWorkflow.task import TaskState
|
||||||
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
||||||
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
|
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
|
||||||
|
@ -39,7 +39,7 @@ class InlineScriptTest(BpmnWorkflowTestCase):
|
||||||
# StartTask doesn't know about testvar, it happened earlier.
|
# StartTask doesn't know about testvar, it happened earlier.
|
||||||
# calling an exec that references testvar, in the context of the
|
# calling an exec that references testvar, in the context of the
|
||||||
# start task should fail.
|
# start task should fail.
|
||||||
with self.assertRaises(WorkflowTaskExecException):
|
with self.assertRaises(WorkflowTaskException):
|
||||||
result = self.workflow.script_engine.evaluate(startTask, 'testvar == True')
|
result = self.workflow.script_engine.evaluate(startTask, 'testvar == True')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,16 +8,15 @@ sys.path.insert(0, os.path.join(dirname, '..', '..', '..'))
|
||||||
|
|
||||||
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
||||||
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
||||||
from SpiffWorkflow.bpmn.exceptions import WorkflowTaskExecException
|
|
||||||
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
|
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
|
||||||
|
|
||||||
class ServiceTaskTest(BpmnWorkflowTestCase):
|
class ServiceTaskTest(BpmnWorkflowTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
||||||
spec, subprocesses = self.load_workflow_spec('service_task.bpmn',
|
spec, subprocesses = self.load_workflow_spec('service_task.bpmn',
|
||||||
'service_task_example1')
|
'service_task_example1')
|
||||||
self.workflow = BpmnWorkflow(spec, subprocesses)
|
self.workflow = BpmnWorkflow(spec, subprocesses)
|
||||||
|
|
||||||
def testRunThroughHappy(self):
|
def testRunThroughHappy(self):
|
||||||
self.workflow.do_engine_steps()
|
self.workflow.do_engine_steps()
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_19o7vxg" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="4.11.1" modeler:executionPlatform="Camunda Platform" modeler:executionPlatformVersion="7.17.0">
|
||||||
|
<bpmn:process id="Process" isExecutable="true">
|
||||||
|
<bpmn:dataObject id="obj_1" />
|
||||||
|
<bpmn:startEvent id="Event_0kmwi7u">
|
||||||
|
<bpmn:outgoing>Flow_18858hr</bpmn:outgoing>
|
||||||
|
</bpmn:startEvent>
|
||||||
|
<bpmn:sequenceFlow id="Flow_18858hr" sourceRef="Event_0kmwi7u" targetRef="generate_data" />
|
||||||
|
<bpmn:sequenceFlow id="Flow_0gbxq9s" sourceRef="generate_data" targetRef="task_1" />
|
||||||
|
<bpmn:sequenceFlow id="Flow_1r7v9yo" sourceRef="task_1" targetRef="read_data" />
|
||||||
|
<!-- All the Data objects here have the same id, which is not valid according the to the xml schema. -->
|
||||||
|
<bpmn:dataObjectReference id="DataObjectReference_0cm8dnh" name="Data" dataObjectRef="obj_1" />
|
||||||
|
<bpmn:dataObjectReference id="DataObjectReference_0cm8dnh" name="Data" dataObjectRef="obj_1" />
|
||||||
|
<bpmn:dataObjectReference id="DataObjectReference_0cm8dnh" name="Data" dataObjectRef="obj_1" />
|
||||||
|
<bpmn:endEvent id="Event_0qw1yr0">
|
||||||
|
<bpmn:incoming>Flow_19pyf8s</bpmn:incoming>
|
||||||
|
</bpmn:endEvent>
|
||||||
|
<bpmn:sequenceFlow id="Flow_1tnu3ej" sourceRef="read_data" targetRef="subprocess" />
|
||||||
|
<bpmn:userTask id="read_data" name="Read Data">
|
||||||
|
<bpmn:incoming>Flow_1r7v9yo</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_1tnu3ej</bpmn:outgoing>
|
||||||
|
<bpmn:property id="Property_1uusomz" name="__targetRef_placeholder" />
|
||||||
|
<bpmn:dataInputAssociation id="DataInputAssociation_1vaag83">
|
||||||
|
<bpmn:sourceRef>DataObjectReference_0pztwm3</bpmn:sourceRef>
|
||||||
|
<bpmn:targetRef>Property_1uusomz</bpmn:targetRef>
|
||||||
|
</bpmn:dataInputAssociation>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:userTask id="generate_data" name="Generate Data">
|
||||||
|
<bpmn:incoming>Flow_18858hr</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0gbxq9s</bpmn:outgoing>
|
||||||
|
<bpmn:dataOutputAssociation id="DataOutputAssociation_053pozp">
|
||||||
|
<bpmn:targetRef>DataObjectReference_17fhr1j</bpmn:targetRef>
|
||||||
|
</bpmn:dataOutputAssociation>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:userTask id="task_1" name="Task">
|
||||||
|
<bpmn:incoming>Flow_0gbxq9s</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_1r7v9yo</bpmn:outgoing>
|
||||||
|
</bpmn:userTask>
|
||||||
|
<bpmn:subProcess id="subprocess" name="Subprocess">
|
||||||
|
<bpmn:incoming>Flow_1tnu3ej</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_19pyf8s</bpmn:outgoing>
|
||||||
|
<bpmn:property id="Property_1q5wp77" name="__targetRef_placeholder" />
|
||||||
|
<bpmn:dataInputAssociation id="DataInputAssociation_0w2qahx">
|
||||||
|
<bpmn:sourceRef>DataObjectReference_0cm8dnh</bpmn:sourceRef>
|
||||||
|
<bpmn:targetRef>Property_1q5wp77</bpmn:targetRef>
|
||||||
|
</bpmn:dataInputAssociation>
|
||||||
|
<bpmn:startEvent id="Event_1wuwx2f">
|
||||||
|
<bpmn:outgoing>Flow_0yx8lkz</bpmn:outgoing>
|
||||||
|
</bpmn:startEvent>
|
||||||
|
<bpmn:task id="placeholder">
|
||||||
|
<bpmn:incoming>Flow_0yx8lkz</bpmn:incoming>
|
||||||
|
<bpmn:outgoing>Flow_0rk4i35</bpmn:outgoing>
|
||||||
|
</bpmn:task>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0yx8lkz" sourceRef="Event_1wuwx2f" targetRef="placeholder" />
|
||||||
|
<bpmn:endEvent id="Event_1qcnmnt">
|
||||||
|
<bpmn:incoming>Flow_0rk4i35</bpmn:incoming>
|
||||||
|
</bpmn:endEvent>
|
||||||
|
<bpmn:sequenceFlow id="Flow_0rk4i35" sourceRef="placeholder" targetRef="Event_1qcnmnt" />
|
||||||
|
</bpmn:subProcess>
|
||||||
|
<bpmn:sequenceFlow id="Flow_19pyf8s" sourceRef="subprocess" targetRef="Event_0qw1yr0" />
|
||||||
|
</bpmn:process>
|
||||||
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process">
|
||||||
|
<bpmndi:BPMNEdge id="Flow_19pyf8s_di" bpmnElement="Flow_19pyf8s">
|
||||||
|
<di:waypoint x="1110" y="180" />
|
||||||
|
<di:waypoint x="1192" y="180" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1tnu3ej_di" bpmnElement="Flow_1tnu3ej">
|
||||||
|
<di:waypoint x="680" y="180" />
|
||||||
|
<di:waypoint x="740" y="180" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1r7v9yo_di" bpmnElement="Flow_1r7v9yo">
|
||||||
|
<di:waypoint x="520" y="180" />
|
||||||
|
<di:waypoint x="580" y="180" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0gbxq9s_di" bpmnElement="Flow_0gbxq9s">
|
||||||
|
<di:waypoint x="360" y="180" />
|
||||||
|
<di:waypoint x="420" y="180" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_18858hr_di" bpmnElement="Flow_18858hr">
|
||||||
|
<di:waypoint x="208" y="180" />
|
||||||
|
<di:waypoint x="260" y="180" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNShape id="Event_0kmwi7u_di" bpmnElement="Event_0kmwi7u">
|
||||||
|
<dc:Bounds x="172" y="162" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="DataObjectReference_17fhr1j_di" bpmnElement="DataObjectReference_17fhr1j">
|
||||||
|
<dc:Bounds x="292" y="275" width="36" height="50" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="299" y="332" width="25" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="DataObjectReference_0pztwm3_di" bpmnElement="DataObjectReference_0pztwm3">
|
||||||
|
<dc:Bounds x="612" y="275" width="36" height="50" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="619" y="332" width="25" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="DataObjectReference_0cm8dnh_di" bpmnElement="DataObjectReference_0cm8dnh">
|
||||||
|
<dc:Bounds x="907" y="375" width="36" height="50" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="913" y="432" width="25" height="14" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Event_0qw1yr0_di" bpmnElement="Event_0qw1yr0">
|
||||||
|
<dc:Bounds x="1192" y="162" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_08lb08m_di" bpmnElement="read_data">
|
||||||
|
<dc:Bounds x="580" y="140" width="100" height="80" />
|
||||||
|
<bpmndi:BPMNLabel />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_00pwxgv_di" bpmnElement="generate_data">
|
||||||
|
<dc:Bounds x="260" y="140" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_1xmp3i1_di" bpmnElement="task_1">
|
||||||
|
<dc:Bounds x="420" y="140" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_10c32lr_di" bpmnElement="subprocess" isExpanded="true">
|
||||||
|
<dc:Bounds x="740" y="80" width="370" height="200" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0rk4i35_di" bpmnElement="Flow_0rk4i35">
|
||||||
|
<di:waypoint x="970" y="180" />
|
||||||
|
<di:waypoint x="1032" y="180" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0yx8lkz_di" bpmnElement="Flow_0yx8lkz">
|
||||||
|
<di:waypoint x="816" y="180" />
|
||||||
|
<di:waypoint x="870" y="180" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNShape id="Event_1wuwx2f_di" bpmnElement="Event_1wuwx2f">
|
||||||
|
<dc:Bounds x="780" y="162" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_01ooqcb_di" bpmnElement="placeholder">
|
||||||
|
<dc:Bounds x="870" y="140" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Event_1qcnmnt_di" bpmnElement="Event_1qcnmnt">
|
||||||
|
<dc:Bounds x="1032" y="162" width="36" height="36" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNEdge id="DataInputAssociation_1vaag83_di" bpmnElement="DataInputAssociation_1vaag83">
|
||||||
|
<di:waypoint x="630" y="275" />
|
||||||
|
<di:waypoint x="630" y="220" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="DataOutputAssociation_053pozp_di" bpmnElement="DataOutputAssociation_053pozp">
|
||||||
|
<di:waypoint x="309" y="220" />
|
||||||
|
<di:waypoint x="308" y="275" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="DataInputAssociation_0w2qahx_di" bpmnElement="DataInputAssociation_0w2qahx">
|
||||||
|
<di:waypoint x="925" y="375" />
|
||||||
|
<di:waypoint x="925" y="280" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
</bpmndi:BPMNPlane>
|
||||||
|
</bpmndi:BPMNDiagram>
|
||||||
|
</bpmn:definitions>
|
|
@ -1,73 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
from builtins import str
|
|
||||||
import sys
|
|
||||||
import unittest
|
|
||||||
import os
|
|
||||||
dirname = os.path.dirname(__file__)
|
|
||||||
sys.path.insert(0, os.path.join(dirname, '..', '..', '..', '..'))
|
|
||||||
|
|
||||||
import uuid
|
|
||||||
from SpiffWorkflow.bpmn.serializer.dict import BPMNDictionarySerializer
|
|
||||||
from tests.SpiffWorkflow.serializer.baseTest import SerializerTest
|
|
||||||
from SpiffWorkflow.workflow import Workflow
|
|
||||||
|
|
||||||
|
|
||||||
class BPMNDictionarySerializerTest(SerializerTest):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(BPMNDictionarySerializerTest, self).setUp()
|
|
||||||
self.serializer = BPMNDictionarySerializer()
|
|
||||||
self.return_type = dict
|
|
||||||
|
|
||||||
def _compare_results(self, item1, item2,
|
|
||||||
exclude_dynamic=False,
|
|
||||||
exclude_items=None):
|
|
||||||
exclude_items = exclude_items if exclude_items is not None else []
|
|
||||||
if exclude_dynamic:
|
|
||||||
if 'last_state_change' not in exclude_items:
|
|
||||||
exclude_items.append('last_state_change')
|
|
||||||
if 'last_task' not in exclude_items:
|
|
||||||
exclude_items.append('last_task')
|
|
||||||
if uuid.UUID not in exclude_items:
|
|
||||||
exclude_items.append(uuid.UUID)
|
|
||||||
if type(item1) in exclude_items:
|
|
||||||
return
|
|
||||||
|
|
||||||
if isinstance(item1, dict):
|
|
||||||
self.assertIsInstance(item2, dict)
|
|
||||||
for key, value in list(item1.items()):
|
|
||||||
self.assertIn(key, item2)
|
|
||||||
if key in exclude_items:
|
|
||||||
continue
|
|
||||||
self._compare_results(value, item2[key],
|
|
||||||
exclude_dynamic=exclude_dynamic,
|
|
||||||
exclude_items=exclude_items)
|
|
||||||
for key in item2:
|
|
||||||
self.assertIn(key, item1)
|
|
||||||
|
|
||||||
elif isinstance(item1, list):
|
|
||||||
msg = "item is not a list (is a " + str(type(item2)) + ")"
|
|
||||||
self.assertIsInstance(item2, list, msg)
|
|
||||||
msg = "list lengths differ: {} vs {}".format(
|
|
||||||
len(item1), len(item2))
|
|
||||||
self.assertEqual(len(item1), len(item2), msg)
|
|
||||||
for i, listitem in enumerate(item1):
|
|
||||||
self._compare_results(listitem, item2[i],
|
|
||||||
exclude_dynamic=exclude_dynamic,
|
|
||||||
exclude_items=exclude_items)
|
|
||||||
|
|
||||||
elif isinstance(item1, Workflow):
|
|
||||||
raise Exception("Item is a Workflow")
|
|
||||||
|
|
||||||
else:
|
|
||||||
msg = "{}: types differ: {} vs {}".format(
|
|
||||||
str(item2), type(item1), type(item2))
|
|
||||||
self.assertEqual(type(item1), type(item2), msg)
|
|
||||||
self.assertEqual(item1, item2)
|
|
||||||
|
|
||||||
|
|
||||||
def suite():
|
|
||||||
return unittest.defaultTestLoader.loadTestsFromTestCase(BPMNDictionarySerializerTest)
|
|
||||||
if __name__ == '__main__':
|
|
||||||
unittest.TextTestRunner(verbosity=2).run(suite())
|
|
|
@ -1,38 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import unittest
|
|
||||||
import os
|
|
||||||
dirname = os.path.dirname(__file__)
|
|
||||||
sys.path.insert(0, os.path.join(dirname, '..', '..', '..', '..'))
|
|
||||||
|
|
||||||
import json
|
|
||||||
from SpiffWorkflow.bpmn.serializer.json import BPMNJSONSerializer
|
|
||||||
from tests.SpiffWorkflow.serializer.dictTest import DictionarySerializerTest
|
|
||||||
|
|
||||||
|
|
||||||
class BPMNJSONSerializerTest(DictionarySerializerTest):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(BPMNJSONSerializerTest, self).setUp()
|
|
||||||
self.serializer = BPMNJSONSerializer()
|
|
||||||
self.return_type = str
|
|
||||||
|
|
||||||
def _prepare_result(self, item):
|
|
||||||
return json.loads(item)
|
|
||||||
|
|
||||||
def _compare_results(self, item1, item2, exclude_dynamic=False,
|
|
||||||
exclude_items=None):
|
|
||||||
if exclude_dynamic:
|
|
||||||
exclude_items = ['__uuid__']
|
|
||||||
else:
|
|
||||||
exclude_items = []
|
|
||||||
super(BPMNJSONSerializerTest, self)._compare_results(item1, item2,
|
|
||||||
exclude_dynamic=exclude_dynamic,
|
|
||||||
exclude_items=exclude_items)
|
|
||||||
|
|
||||||
|
|
||||||
def suite():
|
|
||||||
return unittest.defaultTestLoader.loadTestsFromTestCase(BPMNJSONSerializerTest)
|
|
||||||
if __name__ == '__main__':
|
|
||||||
unittest.TextTestRunner(verbosity=2).run(suite())
|
|
|
@ -1,7 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from SpiffWorkflow.bpmn.exceptions import WorkflowTaskExecException
|
from SpiffWorkflow.exceptions import SpiffWorkflowException, WorkflowException
|
||||||
from SpiffWorkflow.task import TaskState
|
from SpiffWorkflow.task import TaskState
|
||||||
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
||||||
|
|
||||||
|
@ -15,17 +15,23 @@ class BusinessRuleTaskParserTest(BaseTestCase):
|
||||||
'invalid/InvalidDecision.bpmn', 'Process_1', 'invalid_decision.dmn')
|
'invalid/InvalidDecision.bpmn', 'Process_1', 'invalid_decision.dmn')
|
||||||
self.workflow = BpmnWorkflow(self.spec)
|
self.workflow = BpmnWorkflow(self.spec)
|
||||||
|
|
||||||
|
def testExceptionPrint(self):
|
||||||
|
e1 = Exception("test 1")
|
||||||
|
print (e1)
|
||||||
|
e = SpiffWorkflowException("test")
|
||||||
|
print (e)
|
||||||
|
|
||||||
def testDmnRaisesTaskErrors(self):
|
def testDmnRaisesTaskErrors(self):
|
||||||
self.workflow = BpmnWorkflow(self.spec)
|
self.workflow = BpmnWorkflow(self.spec)
|
||||||
self.workflow.get_tasks(TaskState.READY)[0].set_data(x=3)
|
self.workflow.get_tasks(TaskState.READY)[0].set_data(x=3)
|
||||||
try:
|
try:
|
||||||
self.workflow.do_engine_steps()
|
self.workflow.do_engine_steps()
|
||||||
self.assertTrue(False, "An error should have been raised.")
|
self.assertTrue(False, "An error should have been raised.")
|
||||||
except WorkflowTaskExecException as we:
|
except WorkflowException as we:
|
||||||
self.assertTrue(True, "An error was raised..")
|
self.assertTrue(True, "An error was raised..")
|
||||||
self.assertEquals("InvalidDecisionTaskId", we.sender.name)
|
self.assertEqual("InvalidDecisionTaskId", we.task_spec.name)
|
||||||
self.maxDiff = 1000
|
self.maxDiff = 1000
|
||||||
self.assertEquals("Error evaluating expression spam= 1", str(we))
|
self.assertEquals("Error evaluating expression 'spam= 1'. Rule failed on row 1. Business Rule Task 'Invalid Decision'.", str(we))
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
return unittest.TestLoader().loadTestsFromTestCase(BusinessRuleTaskParserTest)
|
return unittest.TestLoader().loadTestsFromTestCase(BusinessRuleTaskParserTest)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
|
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.0.0">
|
||||||
<bpmn:process id="Process_1" isExecutable="true">
|
<bpmn:process id="Process_1" isExecutable="true">
|
||||||
<bpmn:startEvent id="StartEvent_1">
|
<bpmn:startEvent id="StartEvent_1">
|
||||||
<bpmn:outgoing>Flow_1b29lxw</bpmn:outgoing>
|
<bpmn:outgoing>Flow_1b29lxw</bpmn:outgoing>
|
||||||
|
@ -46,59 +46,59 @@ of documentation</bpmn:documentation>
|
||||||
</bpmn:process>
|
</bpmn:process>
|
||||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
|
||||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
<bpmndi:BPMNEdge id="Flow_066d5e1_di" bpmnElement="Flow_066d5e1">
|
||||||
<dc:Bounds x="122" y="106" width="36" height="36" />
|
<di:waypoint x="850" y="124" />
|
||||||
<bpmndi:BPMNLabel>
|
<di:waypoint x="930" y="124" />
|
||||||
<dc:Bounds x="164" y="322" width="90" height="20" />
|
</bpmndi:BPMNEdge>
|
||||||
</bpmndi:BPMNLabel>
|
<bpmndi:BPMNEdge id="Flow_0z7tfh1_di" bpmnElement="Flow_0z7tfh1">
|
||||||
</bpmndi:BPMNShape>
|
<di:waypoint x="510" y="124" />
|
||||||
<bpmndi:BPMNShape id="EndEvent_0n32cxd_di" bpmnElement="EndEvent_0n32cxd">
|
<di:waypoint x="575" y="124" />
|
||||||
<dc:Bounds x="1132" y="106" width="36" height="36" />
|
</bpmndi:BPMNEdge>
|
||||||
<bpmndi:BPMNLabel>
|
<bpmndi:BPMNEdge id="Flow_09ciw49_di" bpmnElement="Flow_09ciw49">
|
||||||
<dc:Bounds x="933" y="505" width="0" height="12" />
|
<di:waypoint x="340" y="124" />
|
||||||
</bpmndi:BPMNLabel>
|
<di:waypoint x="410" y="124" />
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_0fusz9y_di" bpmnElement="Flow_0fusz9y">
|
||||||
|
<di:waypoint x="1030" y="124" />
|
||||||
|
<di:waypoint x="1092" y="124" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
|
<bpmndi:BPMNEdge id="Flow_1b29lxw_di" bpmnElement="Flow_1b29lxw">
|
||||||
|
<di:waypoint x="188" y="124" />
|
||||||
|
<di:waypoint x="240" y="124" />
|
||||||
|
</bpmndi:BPMNEdge>
|
||||||
<bpmndi:BPMNEdge id="SequenceFlow_06fnqj2_di" bpmnElement="SequenceFlow_06fnqj2">
|
<bpmndi:BPMNEdge id="SequenceFlow_06fnqj2_di" bpmnElement="SequenceFlow_06fnqj2">
|
||||||
<di:waypoint x="650" y="124" />
|
<di:waypoint x="675" y="124" />
|
||||||
<di:waypoint x="700" y="124" />
|
<di:waypoint x="750" y="124" />
|
||||||
<bpmndi:BPMNLabel>
|
<bpmndi:BPMNLabel>
|
||||||
<dc:Bounds x="850" y="462" width="0" height="12" />
|
<dc:Bounds x="850" y="462" width="0" height="12" />
|
||||||
</bpmndi:BPMNLabel>
|
</bpmndi:BPMNLabel>
|
||||||
</bpmndi:BPMNEdge>
|
</bpmndi:BPMNEdge>
|
||||||
<bpmndi:BPMNShape id="BusinessRuleTask_1ipm12w_di" bpmnElement="Task_067fajl">
|
|
||||||
<dc:Bounds x="550" y="84" width="100" height="80" />
|
|
||||||
</bpmndi:BPMNShape>
|
|
||||||
<bpmndi:BPMNEdge id="Flow_1b29lxw_di" bpmnElement="Flow_1b29lxw">
|
|
||||||
<di:waypoint x="158" y="124" />
|
|
||||||
<di:waypoint x="210" y="124" />
|
|
||||||
</bpmndi:BPMNEdge>
|
|
||||||
<bpmndi:BPMNEdge id="Flow_0fusz9y_di" bpmnElement="Flow_0fusz9y">
|
|
||||||
<di:waypoint x="980" y="124" />
|
|
||||||
<di:waypoint x="1132" y="124" />
|
|
||||||
</bpmndi:BPMNEdge>
|
|
||||||
<bpmndi:BPMNShape id="Activity_1uk7uyi_di" bpmnElement="Activity_0w0chd2">
|
<bpmndi:BPMNShape id="Activity_1uk7uyi_di" bpmnElement="Activity_0w0chd2">
|
||||||
<dc:Bounds x="880" y="84" width="100" height="80" />
|
<dc:Bounds x="930" y="84" width="100" height="80" />
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
<bpmndi:BPMNEdge id="Flow_09ciw49_di" bpmnElement="Flow_09ciw49">
|
|
||||||
<di:waypoint x="310" y="124" />
|
|
||||||
<di:waypoint x="360" y="124" />
|
|
||||||
</bpmndi:BPMNEdge>
|
|
||||||
<bpmndi:BPMNShape id="Activity_1v5khzq_di" bpmnElement="Activity_0qh0jpg">
|
|
||||||
<dc:Bounds x="210" y="84" width="100" height="80" />
|
|
||||||
</bpmndi:BPMNShape>
|
|
||||||
<bpmndi:BPMNEdge id="Flow_0z7tfh1_di" bpmnElement="Flow_0z7tfh1">
|
|
||||||
<di:waypoint x="460" y="124" />
|
|
||||||
<di:waypoint x="550" y="124" />
|
|
||||||
</bpmndi:BPMNEdge>
|
|
||||||
<bpmndi:BPMNShape id="Activity_0vne2ba_di" bpmnElement="Activity_1ftn207">
|
<bpmndi:BPMNShape id="Activity_0vne2ba_di" bpmnElement="Activity_1ftn207">
|
||||||
<dc:Bounds x="360" y="84" width="100" height="80" />
|
<dc:Bounds x="410" y="84" width="100" height="80" />
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
<bpmndi:BPMNEdge id="Flow_066d5e1_di" bpmnElement="Flow_066d5e1">
|
|
||||||
<di:waypoint x="800" y="124" />
|
|
||||||
<di:waypoint x="880" y="124" />
|
|
||||||
</bpmndi:BPMNEdge>
|
|
||||||
<bpmndi:BPMNShape id="Activity_0z6lv9u_di" bpmnElement="Activity_1mu3z8p">
|
<bpmndi:BPMNShape id="Activity_0z6lv9u_di" bpmnElement="Activity_1mu3z8p">
|
||||||
<dc:Bounds x="700" y="84" width="100" height="80" />
|
<dc:Bounds x="750" y="84" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||||
|
<dc:Bounds x="152" y="106" width="36" height="36" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="164" y="322" width="90" height="20" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="Activity_1v5khzq_di" bpmnElement="Activity_0qh0jpg">
|
||||||
|
<dc:Bounds x="240" y="84" width="100" height="80" />
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="EndEvent_0n32cxd_di" bpmnElement="EndEvent_0n32cxd">
|
||||||
|
<dc:Bounds x="1092" y="106" width="36" height="36" />
|
||||||
|
<bpmndi:BPMNLabel>
|
||||||
|
<dc:Bounds x="933" y="505" width="0" height="12" />
|
||||||
|
</bpmndi:BPMNLabel>
|
||||||
|
</bpmndi:BPMNShape>
|
||||||
|
<bpmndi:BPMNShape id="BusinessRuleTask_1ipm12w_di" bpmnElement="Task_067fajl">
|
||||||
|
<dc:Bounds x="575" y="84" width="100" height="80" />
|
||||||
</bpmndi:BPMNShape>
|
</bpmndi:BPMNShape>
|
||||||
</bpmndi:BPMNPlane>
|
</bpmndi:BPMNPlane>
|
||||||
</bpmndi:BPMNDiagram>
|
</bpmndi:BPMNDiagram>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<definitions xmlns="http://www.omg.org/spec/DMN/20151101/dmn.xsd" xmlns:camunda="http://camunda.org/schema/1.0/dmn" id="definitions_1jblnbx" name="definitions" namespace="http://camunda.org/schema/1.0/dmn" exporter="Camunda Modeler" exporterVersion="3.7.0">
|
<definitions xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/" xmlns:camunda="http://camunda.org/schema/1.0/dmn" xmlns:biodi="http://bpmn.io/schema/dmn/biodi/2.0" id="definitions_1jblnbx" name="definitions" namespace="http://camunda.org/schema/1.0/dmn" exporter="Camunda Modeler" exporterVersion="5.0.0">
|
||||||
<decision id="IntegerDecisionStringOutputTable" name="IntegerDecisionStringOutput">
|
<decision id="IntegerDecisionStringOutputTable" name="IntegerDecisionStringOutput">
|
||||||
<decisionTable id="decisionTable">
|
<decisionTable id="decisionTable">
|
||||||
<input id="InputClause_1tm0ceq" label="x" camunda:inputVariable="">
|
<input id="InputClause_1tm0ceq" label="x" biodi:width="192" camunda:inputVariable="">
|
||||||
<inputExpression id="LiteralExpression_04o7chw" typeRef="integer">
|
<inputExpression id="LiteralExpression_04o7chw" typeRef="integer">
|
||||||
<text>item.x</text>
|
<text>item.x</text>
|
||||||
</inputExpression>
|
</inputExpression>
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import json
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from SpiffWorkflow.camunda.specs.UserTask import FormField, UserTask, Form, \
|
from SpiffWorkflow.camunda.specs.UserTask import FormField, UserTask, Form, EnumFormField
|
||||||
EnumFormField
|
from SpiffWorkflow.camunda.serializer.task_spec_converters import UserTaskConverter
|
||||||
from SpiffWorkflow.specs.base import TaskSpec
|
|
||||||
from SpiffWorkflow.specs.WorkflowSpec import WorkflowSpec
|
from SpiffWorkflow.specs.WorkflowSpec import WorkflowSpec
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,7 +11,6 @@ class UserTaskSpecTest(unittest.TestCase):
|
||||||
def create_instance(self):
|
def create_instance(self):
|
||||||
if 'testtask' in self.wf_spec.task_specs:
|
if 'testtask' in self.wf_spec.task_specs:
|
||||||
del self.wf_spec.task_specs['testtask']
|
del self.wf_spec.task_specs['testtask']
|
||||||
task_spec = TaskSpec(self.wf_spec, 'testtask', description='foo')
|
|
||||||
self.form = Form()
|
self.form = Form()
|
||||||
return UserTask(self.wf_spec, 'userTask', self.form)
|
return UserTask(self.wf_spec, 'userTask', self.form)
|
||||||
|
|
||||||
|
@ -33,43 +30,6 @@ class UserTaskSpecTest(unittest.TestCase):
|
||||||
self.assertEqual(self.form, self.user_spec.form)
|
self.assertEqual(self.form, self.user_spec.form)
|
||||||
|
|
||||||
def testSerialize(self):
|
def testSerialize(self):
|
||||||
pass
|
|
||||||
|
|
||||||
def test_text_field(self):
|
|
||||||
form_field = FormField(form_type="text")
|
|
||||||
form_field.id = "1234"
|
|
||||||
self.form.add_field(form_field)
|
|
||||||
self.assertEqual(form_field, self.user_spec.form.fields[0])
|
|
||||||
|
|
||||||
def test_enum_field(self):
|
|
||||||
enum_field = EnumFormField()
|
|
||||||
enum_field.label = "Which kind of fool are you"
|
|
||||||
enum_field.add_option('old fool', 'This is old, therefor it is good.')
|
|
||||||
enum_field.add_option('new fool',
|
|
||||||
'This is new, therefor it is better.')
|
|
||||||
self.form.add_field(enum_field)
|
|
||||||
self.assertEqual(enum_field, self.user_spec.form.fields[-1])
|
|
||||||
|
|
||||||
def test_properties(self):
|
|
||||||
form_field = FormField(form_type="text")
|
|
||||||
self.assertFalse(form_field.has_property("wilma"))
|
|
||||||
form_field.add_property("wilma", "flintstone")
|
|
||||||
self.assertTrue(form_field.has_property("wilma"))
|
|
||||||
self.assertEquals("flintstone", form_field.get_property("wilma"))
|
|
||||||
|
|
||||||
def test_validations(self):
|
|
||||||
form_field = FormField(form_type="text")
|
|
||||||
self.assertFalse(form_field.has_validation("barney"))
|
|
||||||
form_field.add_validation("barney", "rubble")
|
|
||||||
self.assertTrue(form_field.has_validation("barney"))
|
|
||||||
self.assertEquals("rubble", form_field.get_validation("barney"))
|
|
||||||
|
|
||||||
def testIsEngineTask(self):
|
|
||||||
self.assertFalse(self.user_spec.is_engine_task())
|
|
||||||
|
|
||||||
def test_convert_to_dict(self):
|
|
||||||
form = Form()
|
|
||||||
|
|
||||||
field1 = FormField(form_type="text")
|
field1 = FormField(form_type="text")
|
||||||
field1.id = "quest"
|
field1.id = "quest"
|
||||||
field1.label = "What is your quest?"
|
field1.label = "What is your quest?"
|
||||||
|
@ -89,21 +49,14 @@ class UserTaskSpecTest(unittest.TestCase):
|
||||||
field2.add_property("description", "You know what to do.")
|
field2.add_property("description", "You know what to do.")
|
||||||
field2.add_validation("maxlength", "25")
|
field2.add_validation("maxlength", "25")
|
||||||
|
|
||||||
form.key = "formKey"
|
self.form.key = "formKey"
|
||||||
form.add_field(field1)
|
self.form.add_field(field1)
|
||||||
form.add_field(field2)
|
self.form.add_field(field2)
|
||||||
|
|
||||||
def JsonableHandler(Obj):
|
converter = UserTaskConverter()
|
||||||
if hasattr(Obj, 'jsonable'):
|
dct = converter.to_dict(self.user_spec)
|
||||||
return Obj.jsonable()
|
self.assertEqual(dct['name'], 'userTask')
|
||||||
else:
|
self.assertEqual(dct['form'], {
|
||||||
raise 'Object of type %s with value of %s is not JSON serializable' % (
|
|
||||||
type(Obj), repr(Obj))
|
|
||||||
|
|
||||||
json_form = json.dumps(form, default=JsonableHandler)
|
|
||||||
actual = json.loads(json_form)
|
|
||||||
|
|
||||||
expected = {
|
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"default_value": "I seek the grail!",
|
"default_value": "I seek the grail!",
|
||||||
|
@ -137,12 +90,39 @@ class UserTaskSpecTest(unittest.TestCase):
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"key": "formKey",
|
"key": "formKey",
|
||||||
}
|
})
|
||||||
|
|
||||||
expected_parsed = json.loads(json.dumps(expected))
|
def test_text_field(self):
|
||||||
|
form_field = FormField(form_type="text")
|
||||||
|
form_field.id = "1234"
|
||||||
|
self.form.add_field(form_field)
|
||||||
|
self.assertEqual(form_field, self.user_spec.form.fields[0])
|
||||||
|
|
||||||
self.maxDiff = None
|
def test_enum_field(self):
|
||||||
self.assertDictEqual(actual, expected_parsed)
|
enum_field = EnumFormField()
|
||||||
|
enum_field.label = "Which kind of fool are you"
|
||||||
|
enum_field.add_option('old fool', 'This is old, therefor it is good.')
|
||||||
|
enum_field.add_option('new fool',
|
||||||
|
'This is new, therefor it is better.')
|
||||||
|
self.form.add_field(enum_field)
|
||||||
|
self.assertEqual(enum_field, self.user_spec.form.fields[-1])
|
||||||
|
|
||||||
|
def test_properties(self):
|
||||||
|
form_field = FormField(form_type="text")
|
||||||
|
self.assertFalse(form_field.has_property("wilma"))
|
||||||
|
form_field.add_property("wilma", "flintstone")
|
||||||
|
self.assertTrue(form_field.has_property("wilma"))
|
||||||
|
self.assertEquals("flintstone", form_field.get_property("wilma"))
|
||||||
|
|
||||||
|
def test_validations(self):
|
||||||
|
form_field = FormField(form_type="text")
|
||||||
|
self.assertFalse(form_field.has_validation("barney"))
|
||||||
|
form_field.add_validation("barney", "rubble")
|
||||||
|
self.assertTrue(form_field.has_validation("barney"))
|
||||||
|
self.assertEquals("rubble", form_field.get_validation("barney"))
|
||||||
|
|
||||||
|
def testIsEngineTask(self):
|
||||||
|
self.assertFalse(self.user_spec.is_engine_task())
|
||||||
|
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from SpiffWorkflow.exceptions import SpiffWorkflowException
|
||||||
from SpiffWorkflow.task import TaskState
|
from SpiffWorkflow.task import TaskState
|
||||||
from .BaseTestCase import BaseTestCase
|
from .BaseTestCase import BaseTestCase
|
||||||
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
||||||
|
@ -18,7 +19,7 @@ class PrescriptPostsciptTest(BaseTestCase):
|
||||||
self.call_activity_test(True)
|
self.call_activity_test(True)
|
||||||
|
|
||||||
def testDataObject(self):
|
def testDataObject(self):
|
||||||
|
|
||||||
spec, subprocesses = self.load_workflow_spec('prescript_postscript_data_object.bpmn', 'Process_1')
|
spec, subprocesses = self.load_workflow_spec('prescript_postscript_data_object.bpmn', 'Process_1')
|
||||||
self.workflow = BpmnWorkflow(spec, subprocesses)
|
self.workflow = BpmnWorkflow(spec, subprocesses)
|
||||||
# Set a on the workflow and b in the first task.
|
# Set a on the workflow and b in the first task.
|
||||||
|
@ -45,8 +46,21 @@ class PrescriptPostsciptTest(BaseTestCase):
|
||||||
ready_tasks[0].complete()
|
ready_tasks[0].complete()
|
||||||
self.assertDictEqual({'a': 1, 'b': 2, 'c': 12, 'z': 6}, ready_tasks[0].data)
|
self.assertDictEqual({'a': 1, 'b': 2, 'c': 12, 'z': 6}, ready_tasks[0].data)
|
||||||
|
|
||||||
|
def test_for_error(self, save_restore=False):
|
||||||
|
|
||||||
|
spec, subprocesses = self.load_workflow_spec('prescript_postscript.bpmn', 'Process_1')
|
||||||
|
self.workflow = BpmnWorkflow(spec, subprocesses)
|
||||||
|
if save_restore:
|
||||||
|
self.save_restore()
|
||||||
|
ready_tasks = self.workflow.get_tasks(TaskState.READY)
|
||||||
|
# Calling do-engine steps without setting variables will raise an exception.
|
||||||
|
with self.assertRaises(SpiffWorkflowException) as se:
|
||||||
|
self.workflow.do_engine_steps()
|
||||||
|
ex = se.exception
|
||||||
|
self.assertIn("Error occurred in the Pre-Script", str(ex))
|
||||||
|
|
||||||
def call_activity_test(self, save_restore=False):
|
def call_activity_test(self, save_restore=False):
|
||||||
|
|
||||||
spec, subprocesses = self.load_workflow_spec('prescript_postscript_*.bpmn', 'parent')
|
spec, subprocesses = self.load_workflow_spec('prescript_postscript_*.bpmn', 'parent')
|
||||||
self.workflow = BpmnWorkflow(spec, subprocesses)
|
self.workflow = BpmnWorkflow(spec, subprocesses)
|
||||||
if save_restore:
|
if save_restore:
|
||||||
|
|
|
@ -9,7 +9,6 @@ sys.path.insert(0, os.path.join(dirname, '..', '..', '..'))
|
||||||
|
|
||||||
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
||||||
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
||||||
from SpiffWorkflow.bpmn.exceptions import WorkflowTaskExecException
|
|
||||||
from .BaseTestCase import BaseTestCase
|
from .BaseTestCase import BaseTestCase
|
||||||
|
|
||||||
class ServiceTaskDelegate:
|
class ServiceTaskDelegate:
|
||||||
|
|
|
@ -9,7 +9,6 @@ sys.path.insert(0, os.path.join(dirname, '..', '..', '..'))
|
||||||
|
|
||||||
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
||||||
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
||||||
from SpiffWorkflow.bpmn.exceptions import WorkflowTaskExecException
|
|
||||||
from .BaseTestCase import BaseTestCase
|
from .BaseTestCase import BaseTestCase
|
||||||
|
|
||||||
class ServiceTaskDelegate:
|
class ServiceTaskDelegate:
|
||||||
|
|
Loading…
Reference in New Issue