@particle-academy/fancy-conformance 0.24.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1199 @@
1
+ {
2
+ "$schema": "../../../schema/case-table.schema.json",
3
+ "suite": "flow/durable-dispatch",
4
+ "cases": [
5
+ {
6
+ "id": "0001-a-fan-out-dispatches-one-node-at-a-time-by-default",
7
+ "title": "Serial: a trigger fanning out to three nodes hands out one node per settle, in declaration order.",
8
+ "since": "0.25.0",
9
+ "tags": [
10
+ "serial",
11
+ "default",
12
+ "fan-out"
13
+ ],
14
+ "input": {
15
+ "schema": {
16
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
17
+ "version": 1,
18
+ "graph": {
19
+ "nodes": [
20
+ {
21
+ "id": "t",
22
+ "kind": "manual_trigger",
23
+ "position": {
24
+ "x": 0,
25
+ "y": 0
26
+ }
27
+ },
28
+ {
29
+ "id": "a",
30
+ "kind": "log",
31
+ "position": {
32
+ "x": 0,
33
+ "y": 0
34
+ }
35
+ },
36
+ {
37
+ "id": "b",
38
+ "kind": "log",
39
+ "position": {
40
+ "x": 0,
41
+ "y": 0
42
+ }
43
+ },
44
+ {
45
+ "id": "c",
46
+ "kind": "log",
47
+ "position": {
48
+ "x": 0,
49
+ "y": 0
50
+ }
51
+ }
52
+ ],
53
+ "edges": [
54
+ {
55
+ "id": "t-a",
56
+ "source": "t",
57
+ "target": "a"
58
+ },
59
+ {
60
+ "id": "t-b",
61
+ "source": "t",
62
+ "target": "b"
63
+ },
64
+ {
65
+ "id": "t-c",
66
+ "source": "t",
67
+ "target": "c"
68
+ }
69
+ ]
70
+ }
71
+ },
72
+ "maxConcurrent": 1,
73
+ "pauses": [],
74
+ "publishes": {}
75
+ },
76
+ "expected": {
77
+ "trace": [
78
+ "dispatch t",
79
+ "complete t",
80
+ "dispatch a",
81
+ "complete a",
82
+ "dispatch b",
83
+ "complete b",
84
+ "dispatch c",
85
+ "complete c"
86
+ ],
87
+ "neverDispatched": []
88
+ },
89
+ "notes": "The default. Before fancy-flow-php 0.54.0 an unset limit dispatched the whole frontier here, as 0002 does."
90
+ },
91
+ {
92
+ "id": "0002-unlimited-dispatches-the-whole-ready-frontier",
93
+ "title": "maxConcurrent 0 is the opt-in to parallel: the whole ready frontier goes out in one batch.",
94
+ "since": "0.25.0",
95
+ "tags": [
96
+ "unlimited",
97
+ "fan-out"
98
+ ],
99
+ "input": {
100
+ "schema": {
101
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
102
+ "version": 1,
103
+ "graph": {
104
+ "nodes": [
105
+ {
106
+ "id": "t",
107
+ "kind": "manual_trigger",
108
+ "position": {
109
+ "x": 0,
110
+ "y": 0
111
+ }
112
+ },
113
+ {
114
+ "id": "a",
115
+ "kind": "log",
116
+ "position": {
117
+ "x": 0,
118
+ "y": 0
119
+ }
120
+ },
121
+ {
122
+ "id": "b",
123
+ "kind": "log",
124
+ "position": {
125
+ "x": 0,
126
+ "y": 0
127
+ }
128
+ },
129
+ {
130
+ "id": "c",
131
+ "kind": "log",
132
+ "position": {
133
+ "x": 0,
134
+ "y": 0
135
+ }
136
+ }
137
+ ],
138
+ "edges": [
139
+ {
140
+ "id": "t-a",
141
+ "source": "t",
142
+ "target": "a"
143
+ },
144
+ {
145
+ "id": "t-b",
146
+ "source": "t",
147
+ "target": "b"
148
+ },
149
+ {
150
+ "id": "t-c",
151
+ "source": "t",
152
+ "target": "c"
153
+ }
154
+ ]
155
+ }
156
+ },
157
+ "maxConcurrent": 0,
158
+ "pauses": [],
159
+ "publishes": {}
160
+ },
161
+ "expected": {
162
+ "trace": [
163
+ "dispatch t",
164
+ "complete t",
165
+ "dispatch a",
166
+ "dispatch b",
167
+ "dispatch c",
168
+ "complete a",
169
+ "complete b",
170
+ "complete c"
171
+ ],
172
+ "neverDispatched": []
173
+ }
174
+ },
175
+ {
176
+ "id": "0003-a-cap-of-two-fills-both-slots-then-waits",
177
+ "title": "A cap of 2 dispatches two siblings, and the third only once one of them settles.",
178
+ "since": "0.25.0",
179
+ "tags": [
180
+ "cap",
181
+ "fan-out"
182
+ ],
183
+ "input": {
184
+ "schema": {
185
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
186
+ "version": 1,
187
+ "graph": {
188
+ "nodes": [
189
+ {
190
+ "id": "t",
191
+ "kind": "manual_trigger",
192
+ "position": {
193
+ "x": 0,
194
+ "y": 0
195
+ }
196
+ },
197
+ {
198
+ "id": "a",
199
+ "kind": "log",
200
+ "position": {
201
+ "x": 0,
202
+ "y": 0
203
+ }
204
+ },
205
+ {
206
+ "id": "b",
207
+ "kind": "log",
208
+ "position": {
209
+ "x": 0,
210
+ "y": 0
211
+ }
212
+ },
213
+ {
214
+ "id": "c",
215
+ "kind": "log",
216
+ "position": {
217
+ "x": 0,
218
+ "y": 0
219
+ }
220
+ }
221
+ ],
222
+ "edges": [
223
+ {
224
+ "id": "t-a",
225
+ "source": "t",
226
+ "target": "a"
227
+ },
228
+ {
229
+ "id": "t-b",
230
+ "source": "t",
231
+ "target": "b"
232
+ },
233
+ {
234
+ "id": "t-c",
235
+ "source": "t",
236
+ "target": "c"
237
+ }
238
+ ]
239
+ }
240
+ },
241
+ "maxConcurrent": 2,
242
+ "pauses": [],
243
+ "publishes": {}
244
+ },
245
+ "expected": {
246
+ "trace": [
247
+ "dispatch t",
248
+ "complete t",
249
+ "dispatch a",
250
+ "dispatch b",
251
+ "complete a",
252
+ "dispatch c",
253
+ "complete b",
254
+ "complete c"
255
+ ],
256
+ "neverDispatched": []
257
+ }
258
+ },
259
+ {
260
+ "id": "0004-declaration-order-not-edge-order",
261
+ "title": "Siblings go out in the order the graph DECLARES them, not the order their edges are listed.",
262
+ "since": "0.25.0",
263
+ "tags": [
264
+ "serial",
265
+ "order"
266
+ ],
267
+ "input": {
268
+ "schema": {
269
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
270
+ "version": 1,
271
+ "graph": {
272
+ "nodes": [
273
+ {
274
+ "id": "t",
275
+ "kind": "manual_trigger",
276
+ "position": {
277
+ "x": 0,
278
+ "y": 0
279
+ }
280
+ },
281
+ {
282
+ "id": "b",
283
+ "kind": "log",
284
+ "position": {
285
+ "x": 0,
286
+ "y": 0
287
+ }
288
+ },
289
+ {
290
+ "id": "a",
291
+ "kind": "log",
292
+ "position": {
293
+ "x": 0,
294
+ "y": 0
295
+ }
296
+ }
297
+ ],
298
+ "edges": [
299
+ {
300
+ "id": "t-a",
301
+ "source": "t",
302
+ "target": "a"
303
+ },
304
+ {
305
+ "id": "t-b",
306
+ "source": "t",
307
+ "target": "b"
308
+ }
309
+ ]
310
+ }
311
+ },
312
+ "maxConcurrent": 1,
313
+ "pauses": [],
314
+ "publishes": {}
315
+ },
316
+ "expected": {
317
+ "trace": [
318
+ "dispatch t",
319
+ "complete t",
320
+ "dispatch b",
321
+ "complete b",
322
+ "dispatch a",
323
+ "complete a"
324
+ ],
325
+ "neverDispatched": []
326
+ }
327
+ },
328
+ {
329
+ "id": "0005-a-diamond-joins-once-after-both-branches-serially",
330
+ "title": "Serial diamond: each branch in turn, then the join, which is never dispatched before both inputs settle.",
331
+ "since": "0.25.0",
332
+ "tags": [
333
+ "serial",
334
+ "fan-in"
335
+ ],
336
+ "input": {
337
+ "schema": {
338
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
339
+ "version": 1,
340
+ "graph": {
341
+ "nodes": [
342
+ {
343
+ "id": "t",
344
+ "kind": "manual_trigger",
345
+ "position": {
346
+ "x": 0,
347
+ "y": 0
348
+ }
349
+ },
350
+ {
351
+ "id": "a",
352
+ "kind": "log",
353
+ "position": {
354
+ "x": 0,
355
+ "y": 0
356
+ }
357
+ },
358
+ {
359
+ "id": "b",
360
+ "kind": "log",
361
+ "position": {
362
+ "x": 0,
363
+ "y": 0
364
+ }
365
+ },
366
+ {
367
+ "id": "j",
368
+ "kind": "merge",
369
+ "position": {
370
+ "x": 0,
371
+ "y": 0
372
+ }
373
+ }
374
+ ],
375
+ "edges": [
376
+ {
377
+ "id": "t-a",
378
+ "source": "t",
379
+ "target": "a"
380
+ },
381
+ {
382
+ "id": "t-b",
383
+ "source": "t",
384
+ "target": "b"
385
+ },
386
+ {
387
+ "id": "a-j",
388
+ "source": "a",
389
+ "target": "j"
390
+ },
391
+ {
392
+ "id": "b-j",
393
+ "source": "b",
394
+ "target": "j"
395
+ }
396
+ ]
397
+ }
398
+ },
399
+ "maxConcurrent": 1,
400
+ "pauses": [],
401
+ "publishes": {}
402
+ },
403
+ "expected": {
404
+ "trace": [
405
+ "dispatch t",
406
+ "complete t",
407
+ "dispatch a",
408
+ "complete a",
409
+ "dispatch b",
410
+ "complete b",
411
+ "dispatch j",
412
+ "complete j"
413
+ ],
414
+ "neverDispatched": []
415
+ }
416
+ },
417
+ {
418
+ "id": "0006-a-diamond-under-unlimited",
419
+ "title": "Unlimited diamond: both branches together, then the join.",
420
+ "since": "0.25.0",
421
+ "tags": [
422
+ "unlimited",
423
+ "fan-in"
424
+ ],
425
+ "input": {
426
+ "schema": {
427
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
428
+ "version": 1,
429
+ "graph": {
430
+ "nodes": [
431
+ {
432
+ "id": "t",
433
+ "kind": "manual_trigger",
434
+ "position": {
435
+ "x": 0,
436
+ "y": 0
437
+ }
438
+ },
439
+ {
440
+ "id": "a",
441
+ "kind": "log",
442
+ "position": {
443
+ "x": 0,
444
+ "y": 0
445
+ }
446
+ },
447
+ {
448
+ "id": "b",
449
+ "kind": "log",
450
+ "position": {
451
+ "x": 0,
452
+ "y": 0
453
+ }
454
+ },
455
+ {
456
+ "id": "j",
457
+ "kind": "merge",
458
+ "position": {
459
+ "x": 0,
460
+ "y": 0
461
+ }
462
+ }
463
+ ],
464
+ "edges": [
465
+ {
466
+ "id": "t-a",
467
+ "source": "t",
468
+ "target": "a"
469
+ },
470
+ {
471
+ "id": "t-b",
472
+ "source": "t",
473
+ "target": "b"
474
+ },
475
+ {
476
+ "id": "a-j",
477
+ "source": "a",
478
+ "target": "j"
479
+ },
480
+ {
481
+ "id": "b-j",
482
+ "source": "b",
483
+ "target": "j"
484
+ }
485
+ ]
486
+ }
487
+ },
488
+ "maxConcurrent": 0,
489
+ "pauses": [],
490
+ "publishes": {}
491
+ },
492
+ "expected": {
493
+ "trace": [
494
+ "dispatch t",
495
+ "complete t",
496
+ "dispatch a",
497
+ "dispatch b",
498
+ "complete a",
499
+ "complete b",
500
+ "dispatch j",
501
+ "complete j"
502
+ ],
503
+ "neverDispatched": []
504
+ }
505
+ },
506
+ {
507
+ "id": "0007-a-successor-declared-before-a-waiting-sibling-goes-first",
508
+ "title": "Order is declaration order among what is READY NOW: a node that just became ready and is declared earlier goes before a sibling that has been waiting. Not breadth-first.",
509
+ "since": "0.25.0",
510
+ "tags": [
511
+ "serial",
512
+ "order"
513
+ ],
514
+ "input": {
515
+ "schema": {
516
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
517
+ "version": 1,
518
+ "graph": {
519
+ "nodes": [
520
+ {
521
+ "id": "t",
522
+ "kind": "manual_trigger",
523
+ "position": {
524
+ "x": 0,
525
+ "y": 0
526
+ }
527
+ },
528
+ {
529
+ "id": "c",
530
+ "kind": "log",
531
+ "position": {
532
+ "x": 0,
533
+ "y": 0
534
+ }
535
+ },
536
+ {
537
+ "id": "a",
538
+ "kind": "log",
539
+ "position": {
540
+ "x": 0,
541
+ "y": 0
542
+ }
543
+ },
544
+ {
545
+ "id": "b",
546
+ "kind": "log",
547
+ "position": {
548
+ "x": 0,
549
+ "y": 0
550
+ }
551
+ }
552
+ ],
553
+ "edges": [
554
+ {
555
+ "id": "t-a",
556
+ "source": "t",
557
+ "target": "a"
558
+ },
559
+ {
560
+ "id": "t-b",
561
+ "source": "t",
562
+ "target": "b"
563
+ },
564
+ {
565
+ "id": "a-c",
566
+ "source": "a",
567
+ "target": "c"
568
+ }
569
+ ]
570
+ }
571
+ },
572
+ "maxConcurrent": 1,
573
+ "pauses": [],
574
+ "publishes": {}
575
+ },
576
+ "expected": {
577
+ "trace": [
578
+ "dispatch t",
579
+ "complete t",
580
+ "dispatch a",
581
+ "complete a",
582
+ "dispatch c",
583
+ "complete c",
584
+ "dispatch b",
585
+ "complete b"
586
+ ],
587
+ "neverDispatched": []
588
+ },
589
+ "notes": "The discriminating order row: breadth-first would dispatch b before c."
590
+ },
591
+ {
592
+ "id": "0008-a-paused-gate-keeps-its-slot",
593
+ "title": "Serial: a node paused for a person holds the only slot, so its ready siblings are never dispatched while the person decides.",
594
+ "since": "0.25.0",
595
+ "tags": [
596
+ "serial",
597
+ "pause"
598
+ ],
599
+ "input": {
600
+ "schema": {
601
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
602
+ "version": 1,
603
+ "graph": {
604
+ "nodes": [
605
+ {
606
+ "id": "t",
607
+ "kind": "manual_trigger",
608
+ "position": {
609
+ "x": 0,
610
+ "y": 0
611
+ }
612
+ },
613
+ {
614
+ "id": "gate",
615
+ "kind": "human_approval",
616
+ "position": {
617
+ "x": 0,
618
+ "y": 0
619
+ }
620
+ },
621
+ {
622
+ "id": "b",
623
+ "kind": "log",
624
+ "position": {
625
+ "x": 0,
626
+ "y": 0
627
+ }
628
+ },
629
+ {
630
+ "id": "c",
631
+ "kind": "log",
632
+ "position": {
633
+ "x": 0,
634
+ "y": 0
635
+ }
636
+ }
637
+ ],
638
+ "edges": [
639
+ {
640
+ "id": "t-gate",
641
+ "source": "t",
642
+ "target": "gate"
643
+ },
644
+ {
645
+ "id": "t-b",
646
+ "source": "t",
647
+ "target": "b"
648
+ },
649
+ {
650
+ "id": "t-c",
651
+ "source": "t",
652
+ "target": "c"
653
+ }
654
+ ]
655
+ }
656
+ },
657
+ "maxConcurrent": 1,
658
+ "pauses": [
659
+ "gate"
660
+ ],
661
+ "publishes": {}
662
+ },
663
+ "expected": {
664
+ "trace": [
665
+ "dispatch t",
666
+ "complete t",
667
+ "dispatch gate",
668
+ "pause gate"
669
+ ],
670
+ "neverDispatched": [
671
+ "b",
672
+ "c"
673
+ ]
674
+ },
675
+ "notes": "The gap the ruling closes: b and c are never dispatched while the gate is paused."
676
+ },
677
+ {
678
+ "id": "0009-a-paused-gate-under-unlimited",
679
+ "title": "Unlimited: the gate and its siblings go out together, and the siblings complete while the gate waits.",
680
+ "since": "0.25.0",
681
+ "tags": [
682
+ "unlimited",
683
+ "pause"
684
+ ],
685
+ "input": {
686
+ "schema": {
687
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
688
+ "version": 1,
689
+ "graph": {
690
+ "nodes": [
691
+ {
692
+ "id": "t",
693
+ "kind": "manual_trigger",
694
+ "position": {
695
+ "x": 0,
696
+ "y": 0
697
+ }
698
+ },
699
+ {
700
+ "id": "gate",
701
+ "kind": "human_approval",
702
+ "position": {
703
+ "x": 0,
704
+ "y": 0
705
+ }
706
+ },
707
+ {
708
+ "id": "b",
709
+ "kind": "log",
710
+ "position": {
711
+ "x": 0,
712
+ "y": 0
713
+ }
714
+ },
715
+ {
716
+ "id": "c",
717
+ "kind": "log",
718
+ "position": {
719
+ "x": 0,
720
+ "y": 0
721
+ }
722
+ }
723
+ ],
724
+ "edges": [
725
+ {
726
+ "id": "t-gate",
727
+ "source": "t",
728
+ "target": "gate"
729
+ },
730
+ {
731
+ "id": "t-b",
732
+ "source": "t",
733
+ "target": "b"
734
+ },
735
+ {
736
+ "id": "t-c",
737
+ "source": "t",
738
+ "target": "c"
739
+ }
740
+ ]
741
+ }
742
+ },
743
+ "maxConcurrent": 0,
744
+ "pauses": [
745
+ "gate"
746
+ ],
747
+ "publishes": {}
748
+ },
749
+ "expected": {
750
+ "trace": [
751
+ "dispatch t",
752
+ "complete t",
753
+ "dispatch gate",
754
+ "dispatch b",
755
+ "dispatch c",
756
+ "pause gate",
757
+ "complete b",
758
+ "complete c"
759
+ ],
760
+ "neverDispatched": []
761
+ }
762
+ },
763
+ {
764
+ "id": "0010-a-paused-gate-counts-against-a-cap",
765
+ "title": "A cap of 2 with a paused gate: the gate keeps one slot after it pauses, so only one sibling runs at a time beside it.",
766
+ "since": "0.25.0",
767
+ "tags": [
768
+ "cap",
769
+ "pause"
770
+ ],
771
+ "input": {
772
+ "schema": {
773
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
774
+ "version": 1,
775
+ "graph": {
776
+ "nodes": [
777
+ {
778
+ "id": "t",
779
+ "kind": "manual_trigger",
780
+ "position": {
781
+ "x": 0,
782
+ "y": 0
783
+ }
784
+ },
785
+ {
786
+ "id": "gate",
787
+ "kind": "human_approval",
788
+ "position": {
789
+ "x": 0,
790
+ "y": 0
791
+ }
792
+ },
793
+ {
794
+ "id": "b",
795
+ "kind": "log",
796
+ "position": {
797
+ "x": 0,
798
+ "y": 0
799
+ }
800
+ },
801
+ {
802
+ "id": "c",
803
+ "kind": "log",
804
+ "position": {
805
+ "x": 0,
806
+ "y": 0
807
+ }
808
+ }
809
+ ],
810
+ "edges": [
811
+ {
812
+ "id": "t-gate",
813
+ "source": "t",
814
+ "target": "gate"
815
+ },
816
+ {
817
+ "id": "t-b",
818
+ "source": "t",
819
+ "target": "b"
820
+ },
821
+ {
822
+ "id": "t-c",
823
+ "source": "t",
824
+ "target": "c"
825
+ }
826
+ ]
827
+ }
828
+ },
829
+ "maxConcurrent": 2,
830
+ "pauses": [
831
+ "gate"
832
+ ],
833
+ "publishes": {}
834
+ },
835
+ "expected": {
836
+ "trace": [
837
+ "dispatch t",
838
+ "complete t",
839
+ "dispatch gate",
840
+ "dispatch b",
841
+ "pause gate",
842
+ "complete b",
843
+ "dispatch c",
844
+ "complete c"
845
+ ],
846
+ "neverDispatched": []
847
+ },
848
+ "notes": "Held counts the paused gate: c goes out only after b settles. An implementation that does not count a paused node dispatches c the moment the gate pauses."
849
+ },
850
+ {
851
+ "id": "0011-a-dead-branch-is-skipped-and-never-dispatched",
852
+ "title": "The branch publishes only `true`: the false side and everything below it is settled as skipped, and never takes a slot.",
853
+ "since": "0.25.0",
854
+ "tags": [
855
+ "serial",
856
+ "skip"
857
+ ],
858
+ "input": {
859
+ "schema": {
860
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
861
+ "version": 1,
862
+ "graph": {
863
+ "nodes": [
864
+ {
865
+ "id": "t",
866
+ "kind": "manual_trigger",
867
+ "position": {
868
+ "x": 0,
869
+ "y": 0
870
+ }
871
+ },
872
+ {
873
+ "id": "br",
874
+ "kind": "branch",
875
+ "position": {
876
+ "x": 0,
877
+ "y": 0
878
+ },
879
+ "config": {
880
+ "condition": true
881
+ }
882
+ },
883
+ {
884
+ "id": "y",
885
+ "kind": "log",
886
+ "position": {
887
+ "x": 0,
888
+ "y": 0
889
+ }
890
+ },
891
+ {
892
+ "id": "n",
893
+ "kind": "log",
894
+ "position": {
895
+ "x": 0,
896
+ "y": 0
897
+ }
898
+ },
899
+ {
900
+ "id": "n2",
901
+ "kind": "log",
902
+ "position": {
903
+ "x": 0,
904
+ "y": 0
905
+ }
906
+ }
907
+ ],
908
+ "edges": [
909
+ {
910
+ "id": "t-br",
911
+ "source": "t",
912
+ "target": "br"
913
+ },
914
+ {
915
+ "id": "br-y",
916
+ "source": "br",
917
+ "target": "y",
918
+ "sourceHandle": "true"
919
+ },
920
+ {
921
+ "id": "br-n",
922
+ "source": "br",
923
+ "target": "n",
924
+ "sourceHandle": "false"
925
+ },
926
+ {
927
+ "id": "n-n2",
928
+ "source": "n",
929
+ "target": "n2"
930
+ }
931
+ ]
932
+ }
933
+ },
934
+ "maxConcurrent": 1,
935
+ "publishes": {
936
+ "br": [
937
+ "true"
938
+ ]
939
+ },
940
+ "pauses": []
941
+ },
942
+ "expected": {
943
+ "trace": [
944
+ "dispatch t",
945
+ "complete t",
946
+ "dispatch br",
947
+ "complete br",
948
+ "skip n",
949
+ "skip n2",
950
+ "dispatch y",
951
+ "complete y"
952
+ ],
953
+ "neverDispatched": []
954
+ }
955
+ },
956
+ {
957
+ "id": "0012-a-note-is-settled-not-dispatched",
958
+ "title": "A sticky note is never executed: it settles as skipped without taking a slot.",
959
+ "since": "0.25.0",
960
+ "tags": [
961
+ "serial",
962
+ "note"
963
+ ],
964
+ "input": {
965
+ "schema": {
966
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
967
+ "version": 1,
968
+ "graph": {
969
+ "nodes": [
970
+ {
971
+ "id": "t",
972
+ "kind": "manual_trigger",
973
+ "position": {
974
+ "x": 0,
975
+ "y": 0
976
+ }
977
+ },
978
+ {
979
+ "id": "memo",
980
+ "kind": "note",
981
+ "position": {
982
+ "x": 0,
983
+ "y": 0
984
+ }
985
+ },
986
+ {
987
+ "id": "a",
988
+ "kind": "log",
989
+ "position": {
990
+ "x": 0,
991
+ "y": 0
992
+ }
993
+ }
994
+ ],
995
+ "edges": [
996
+ {
997
+ "id": "t-a",
998
+ "source": "t",
999
+ "target": "a"
1000
+ }
1001
+ ]
1002
+ }
1003
+ },
1004
+ "maxConcurrent": 1,
1005
+ "pauses": [],
1006
+ "publishes": {}
1007
+ },
1008
+ "expected": {
1009
+ "trace": [
1010
+ "skip memo",
1011
+ "dispatch t",
1012
+ "complete t",
1013
+ "dispatch a",
1014
+ "complete a"
1015
+ ],
1016
+ "neverDispatched": []
1017
+ }
1018
+ },
1019
+ {
1020
+ "id": "0013-two-entry-points-take-turns",
1021
+ "title": "Two triggers with nothing between them: serial dispatches them one after the other, in declaration order.",
1022
+ "since": "0.25.0",
1023
+ "tags": [
1024
+ "serial",
1025
+ "entry-points"
1026
+ ],
1027
+ "input": {
1028
+ "schema": {
1029
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
1030
+ "version": 1,
1031
+ "graph": {
1032
+ "nodes": [
1033
+ {
1034
+ "id": "t1",
1035
+ "kind": "manual_trigger",
1036
+ "position": {
1037
+ "x": 0,
1038
+ "y": 0
1039
+ }
1040
+ },
1041
+ {
1042
+ "id": "t2",
1043
+ "kind": "manual_trigger",
1044
+ "position": {
1045
+ "x": 0,
1046
+ "y": 0
1047
+ }
1048
+ },
1049
+ {
1050
+ "id": "a",
1051
+ "kind": "log",
1052
+ "position": {
1053
+ "x": 0,
1054
+ "y": 0
1055
+ }
1056
+ },
1057
+ {
1058
+ "id": "b",
1059
+ "kind": "log",
1060
+ "position": {
1061
+ "x": 0,
1062
+ "y": 0
1063
+ }
1064
+ }
1065
+ ],
1066
+ "edges": [
1067
+ {
1068
+ "id": "t1-a",
1069
+ "source": "t1",
1070
+ "target": "a"
1071
+ },
1072
+ {
1073
+ "id": "t2-b",
1074
+ "source": "t2",
1075
+ "target": "b"
1076
+ }
1077
+ ]
1078
+ }
1079
+ },
1080
+ "maxConcurrent": 1,
1081
+ "pauses": [],
1082
+ "publishes": {}
1083
+ },
1084
+ "expected": {
1085
+ "trace": [
1086
+ "dispatch t1",
1087
+ "complete t1",
1088
+ "dispatch t2",
1089
+ "complete t2",
1090
+ "dispatch a",
1091
+ "complete a",
1092
+ "dispatch b",
1093
+ "complete b"
1094
+ ],
1095
+ "neverDispatched": []
1096
+ }
1097
+ },
1098
+ {
1099
+ "id": "0014-a-cap-is-measured-against-held-work-not-the-batch",
1100
+ "title": "A cap of 2 over four siblings: when one settles, ONE more goes out, because the other is still held. A cap applied per batch would dispatch two.",
1101
+ "since": "0.25.0",
1102
+ "tags": [
1103
+ "cap",
1104
+ "budget"
1105
+ ],
1106
+ "input": {
1107
+ "schema": {
1108
+ "$schema": "https://particle.academy/schemas/workflow/v1.json",
1109
+ "version": 1,
1110
+ "graph": {
1111
+ "nodes": [
1112
+ {
1113
+ "id": "t",
1114
+ "kind": "manual_trigger",
1115
+ "position": {
1116
+ "x": 0,
1117
+ "y": 0
1118
+ }
1119
+ },
1120
+ {
1121
+ "id": "a",
1122
+ "kind": "log",
1123
+ "position": {
1124
+ "x": 0,
1125
+ "y": 0
1126
+ }
1127
+ },
1128
+ {
1129
+ "id": "b",
1130
+ "kind": "log",
1131
+ "position": {
1132
+ "x": 0,
1133
+ "y": 0
1134
+ }
1135
+ },
1136
+ {
1137
+ "id": "c",
1138
+ "kind": "log",
1139
+ "position": {
1140
+ "x": 0,
1141
+ "y": 0
1142
+ }
1143
+ },
1144
+ {
1145
+ "id": "d",
1146
+ "kind": "log",
1147
+ "position": {
1148
+ "x": 0,
1149
+ "y": 0
1150
+ }
1151
+ }
1152
+ ],
1153
+ "edges": [
1154
+ {
1155
+ "id": "t-a",
1156
+ "source": "t",
1157
+ "target": "a"
1158
+ },
1159
+ {
1160
+ "id": "t-b",
1161
+ "source": "t",
1162
+ "target": "b"
1163
+ },
1164
+ {
1165
+ "id": "t-c",
1166
+ "source": "t",
1167
+ "target": "c"
1168
+ },
1169
+ {
1170
+ "id": "t-d",
1171
+ "source": "t",
1172
+ "target": "d"
1173
+ }
1174
+ ]
1175
+ }
1176
+ },
1177
+ "maxConcurrent": 2,
1178
+ "pauses": [],
1179
+ "publishes": {}
1180
+ },
1181
+ "expected": {
1182
+ "trace": [
1183
+ "dispatch t",
1184
+ "complete t",
1185
+ "dispatch a",
1186
+ "dispatch b",
1187
+ "complete a",
1188
+ "dispatch c",
1189
+ "complete b",
1190
+ "dispatch d",
1191
+ "complete c",
1192
+ "complete d"
1193
+ ],
1194
+ "neverDispatched": []
1195
+ },
1196
+ "notes": "A per-batch cap dispatches c AND d when a settles, putting three in flight under a cap of 2."
1197
+ }
1198
+ ]
1199
+ }