dal-engine-core-js-lib-dev 0.0.1 → 0.0.2
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.
- package/dist/index.cjs +77 -14
- package/dist/index.esm.js +77 -14
- package/package.json +1 -1
- package/src/BehavioralControlGraph/BehavioralControlGraph.js +5 -5
- package/src/BehavioralControlGraph/GraphNode.js +16 -7
- package/src/DALEngine.js +57 -2
- package/tests/DALEngine.test.js +30 -33
- package/tests/Invariant.test.js +6 -7
- package/tests/SimpleDesign.test.js +13 -23
- package/tests/simple_design_temp.json +1 -0
package/dist/index.cjs
CHANGED
|
@@ -387,13 +387,13 @@ class GraphNode extends Base {
|
|
|
387
387
|
constructor (args) {
|
|
388
388
|
super();
|
|
389
389
|
this.type = ENGINE_TYPES$1.GRAPH_NODE;
|
|
390
|
-
this.
|
|
390
|
+
this.goToBehaviorsIds = [];
|
|
391
391
|
if (typeof args === "object" && args !== null) {
|
|
392
392
|
if (Object.hasOwn(args, "uid")) {
|
|
393
393
|
this.loadNodeFromJSON(args);
|
|
394
394
|
} else {
|
|
395
395
|
this.behavior = args.behavior;
|
|
396
|
-
this.
|
|
396
|
+
this.goToBehaviorsIds = args.goToBehaviorsIds;
|
|
397
397
|
}
|
|
398
398
|
}
|
|
399
399
|
}
|
|
@@ -406,13 +406,22 @@ class GraphNode extends Base {
|
|
|
406
406
|
for (const [key, value] of Object.entries(nodesJSON)) {
|
|
407
407
|
if (key === "behavior") {
|
|
408
408
|
this.behavior = new Behavior(value);
|
|
409
|
-
} else if (key === "
|
|
410
|
-
value.forEach(
|
|
409
|
+
} else if (key === "goToBehaviorsIds") {
|
|
410
|
+
value.forEach(behaviorId => this.goToBehaviorsIds.push(behaviorId));
|
|
411
411
|
} else {
|
|
412
412
|
this[key] = nodesJSON[key];
|
|
413
413
|
}
|
|
414
414
|
} }
|
|
415
415
|
|
|
416
|
+
/**
|
|
417
|
+
* Adds a behavior name to the list of behaviors that this
|
|
418
|
+
* node transitions to.
|
|
419
|
+
* @param {String} behaviorId ID of behavior.
|
|
420
|
+
*/
|
|
421
|
+
addGoToBehavior (behaviorId) {
|
|
422
|
+
this.goToBehaviorsIds.push(behaviorId);
|
|
423
|
+
}
|
|
424
|
+
|
|
416
425
|
/**
|
|
417
426
|
* Checks if the provided behavior name is a valid
|
|
418
427
|
* behavior that the control flow selects as a
|
|
@@ -422,9 +431,9 @@ class GraphNode extends Base {
|
|
|
422
431
|
* @returns {Boolean}
|
|
423
432
|
*/
|
|
424
433
|
isValidGoToBehavior (behaviorName) {
|
|
425
|
-
for (let i = 0; i < this.
|
|
426
|
-
const
|
|
427
|
-
if (
|
|
434
|
+
for (let i = 0; i < this.goToBehaviorsIds.length; i++) {
|
|
435
|
+
const behaviorId = this.goToBehaviorsIds[i];
|
|
436
|
+
if (behaviorId === behaviorName) {
|
|
428
437
|
return true;
|
|
429
438
|
}
|
|
430
439
|
}
|
|
@@ -470,13 +479,13 @@ class BehavioralControlGraph extends Base {
|
|
|
470
479
|
/**
|
|
471
480
|
* Adds a node to the graph.
|
|
472
481
|
* @param {Behavior} behavior
|
|
473
|
-
* @param {Array}
|
|
482
|
+
* @param {Array} goToBehaviorsIds
|
|
474
483
|
* @returns
|
|
475
484
|
*/
|
|
476
|
-
addNode (behavior,
|
|
485
|
+
addNode (behavior, goToBehaviorsIds) {
|
|
477
486
|
const node = new GraphNode({
|
|
478
487
|
behavior: behavior,
|
|
479
|
-
|
|
488
|
+
goToBehaviorsIds: goToBehaviorsIds,
|
|
480
489
|
});
|
|
481
490
|
this.nodes.push(node);
|
|
482
491
|
return node;
|
|
@@ -541,8 +550,8 @@ class BehavioralControlGraph extends Base {
|
|
|
541
550
|
exportAsMermaid () {
|
|
542
551
|
let mermaid = "flowchart TD\n";
|
|
543
552
|
this.nodes.forEach((node) => {
|
|
544
|
-
node.
|
|
545
|
-
mermaid += ` ${node.behavior.name} --> ${
|
|
553
|
+
node.goToBehaviorsIds.forEach((behaviorId) => {
|
|
554
|
+
mermaid += ` ${node.behavior.name} --> ${behaviorId}\n`;
|
|
546
555
|
});
|
|
547
556
|
});
|
|
548
557
|
return mermaid;
|
|
@@ -565,9 +574,26 @@ class BehavioralControlGraph extends Base {
|
|
|
565
574
|
class DALEngine {
|
|
566
575
|
constructor (args) {
|
|
567
576
|
this.graph = new BehavioralControlGraph();
|
|
568
|
-
|
|
569
|
-
|
|
577
|
+
this.loadArgs(args);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Loads the provided arguments.
|
|
582
|
+
* @throws {MissingAttributes} Thrown when required attr is not present.
|
|
583
|
+
* @param {Object} args
|
|
584
|
+
*/
|
|
585
|
+
loadArgs (args) {
|
|
586
|
+
const expectedAttributes = ["name"];
|
|
587
|
+
if (typeof args !== "object" || args === null || Array.isArray(args)) {
|
|
588
|
+
// Not an object, so all attributes are missing.
|
|
589
|
+
throw new MissingAttributes("Engine", expectedAttributes);
|
|
570
590
|
}
|
|
591
|
+
expectedAttributes.forEach((attr) => {
|
|
592
|
+
if (!(attr in args)) {
|
|
593
|
+
throw new MissingAttributes("Engine", attr);
|
|
594
|
+
}
|
|
595
|
+
this[attr] = args[attr];
|
|
596
|
+
});
|
|
571
597
|
}
|
|
572
598
|
|
|
573
599
|
/**
|
|
@@ -613,6 +639,43 @@ class DALEngine {
|
|
|
613
639
|
createInvariant (args) {
|
|
614
640
|
return new Invariant(args);
|
|
615
641
|
}
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Returns the node in the graph with the given behavior name.
|
|
646
|
+
* @param {String} behaviorId
|
|
647
|
+
* @returns {GraphNode}
|
|
648
|
+
*/
|
|
649
|
+
getNode (behaviorId) {
|
|
650
|
+
return this.graph.findNode(behaviorId);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Adds a node to the graph with the given behaviorId and goToBehaviors.
|
|
655
|
+
* @param {String} behaviorId
|
|
656
|
+
* @param {Array} goToBehaviorsIds
|
|
657
|
+
* @returns {GraphNode}
|
|
658
|
+
*/
|
|
659
|
+
addNode (behaviorId, goToBehaviorsIds) {
|
|
660
|
+
const behavior = this.createBehavior({name: behaviorId});
|
|
661
|
+
return this.graph.addNode(behavior, goToBehaviorsIds);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Adds a goToBehavior to the node with the given behaviorId.
|
|
666
|
+
* @param {String} behaviorId
|
|
667
|
+
* @param {String|Array} goToBehaviorIds
|
|
668
|
+
* @returns {GraphNode}
|
|
669
|
+
*/
|
|
670
|
+
addGoToBehavior (behaviorId, goToBehaviorIds) {
|
|
671
|
+
const node = this.graph.findNode(behaviorId);
|
|
672
|
+
if (Array.isArray(goToBehaviorIds)) {
|
|
673
|
+
node.goToBehaviorsIds.push(...goToBehaviorIds);
|
|
674
|
+
} else {
|
|
675
|
+
node.goToBehaviorsIds.push(goToBehaviorIds);
|
|
676
|
+
}
|
|
677
|
+
return node;
|
|
678
|
+
}
|
|
616
679
|
}
|
|
617
680
|
|
|
618
681
|
exports.DALEngine = DALEngine;
|
package/dist/index.esm.js
CHANGED
|
@@ -385,13 +385,13 @@ class GraphNode extends Base {
|
|
|
385
385
|
constructor (args) {
|
|
386
386
|
super();
|
|
387
387
|
this.type = ENGINE_TYPES.GRAPH_NODE;
|
|
388
|
-
this.
|
|
388
|
+
this.goToBehaviorsIds = [];
|
|
389
389
|
if (typeof args === "object" && args !== null) {
|
|
390
390
|
if (Object.hasOwn(args, "uid")) {
|
|
391
391
|
this.loadNodeFromJSON(args);
|
|
392
392
|
} else {
|
|
393
393
|
this.behavior = args.behavior;
|
|
394
|
-
this.
|
|
394
|
+
this.goToBehaviorsIds = args.goToBehaviorsIds;
|
|
395
395
|
}
|
|
396
396
|
}
|
|
397
397
|
}
|
|
@@ -404,13 +404,22 @@ class GraphNode extends Base {
|
|
|
404
404
|
for (const [key, value] of Object.entries(nodesJSON)) {
|
|
405
405
|
if (key === "behavior") {
|
|
406
406
|
this.behavior = new Behavior(value);
|
|
407
|
-
} else if (key === "
|
|
408
|
-
value.forEach(
|
|
407
|
+
} else if (key === "goToBehaviorsIds") {
|
|
408
|
+
value.forEach(behaviorId => this.goToBehaviorsIds.push(behaviorId));
|
|
409
409
|
} else {
|
|
410
410
|
this[key] = nodesJSON[key];
|
|
411
411
|
}
|
|
412
412
|
} }
|
|
413
413
|
|
|
414
|
+
/**
|
|
415
|
+
* Adds a behavior name to the list of behaviors that this
|
|
416
|
+
* node transitions to.
|
|
417
|
+
* @param {String} behaviorId ID of behavior.
|
|
418
|
+
*/
|
|
419
|
+
addGoToBehavior (behaviorId) {
|
|
420
|
+
this.goToBehaviorsIds.push(behaviorId);
|
|
421
|
+
}
|
|
422
|
+
|
|
414
423
|
/**
|
|
415
424
|
* Checks if the provided behavior name is a valid
|
|
416
425
|
* behavior that the control flow selects as a
|
|
@@ -420,9 +429,9 @@ class GraphNode extends Base {
|
|
|
420
429
|
* @returns {Boolean}
|
|
421
430
|
*/
|
|
422
431
|
isValidGoToBehavior (behaviorName) {
|
|
423
|
-
for (let i = 0; i < this.
|
|
424
|
-
const
|
|
425
|
-
if (
|
|
432
|
+
for (let i = 0; i < this.goToBehaviorsIds.length; i++) {
|
|
433
|
+
const behaviorId = this.goToBehaviorsIds[i];
|
|
434
|
+
if (behaviorId === behaviorName) {
|
|
426
435
|
return true;
|
|
427
436
|
}
|
|
428
437
|
}
|
|
@@ -468,13 +477,13 @@ class BehavioralControlGraph extends Base {
|
|
|
468
477
|
/**
|
|
469
478
|
* Adds a node to the graph.
|
|
470
479
|
* @param {Behavior} behavior
|
|
471
|
-
* @param {Array}
|
|
480
|
+
* @param {Array} goToBehaviorsIds
|
|
472
481
|
* @returns
|
|
473
482
|
*/
|
|
474
|
-
addNode (behavior,
|
|
483
|
+
addNode (behavior, goToBehaviorsIds) {
|
|
475
484
|
const node = new GraphNode({
|
|
476
485
|
behavior: behavior,
|
|
477
|
-
|
|
486
|
+
goToBehaviorsIds: goToBehaviorsIds,
|
|
478
487
|
});
|
|
479
488
|
this.nodes.push(node);
|
|
480
489
|
return node;
|
|
@@ -539,8 +548,8 @@ class BehavioralControlGraph extends Base {
|
|
|
539
548
|
exportAsMermaid () {
|
|
540
549
|
let mermaid = "flowchart TD\n";
|
|
541
550
|
this.nodes.forEach((node) => {
|
|
542
|
-
node.
|
|
543
|
-
mermaid += ` ${node.behavior.name} --> ${
|
|
551
|
+
node.goToBehaviorsIds.forEach((behaviorId) => {
|
|
552
|
+
mermaid += ` ${node.behavior.name} --> ${behaviorId}\n`;
|
|
544
553
|
});
|
|
545
554
|
});
|
|
546
555
|
return mermaid;
|
|
@@ -563,9 +572,26 @@ class BehavioralControlGraph extends Base {
|
|
|
563
572
|
class DALEngine {
|
|
564
573
|
constructor (args) {
|
|
565
574
|
this.graph = new BehavioralControlGraph();
|
|
566
|
-
|
|
567
|
-
|
|
575
|
+
this.loadArgs(args);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Loads the provided arguments.
|
|
580
|
+
* @throws {MissingAttributes} Thrown when required attr is not present.
|
|
581
|
+
* @param {Object} args
|
|
582
|
+
*/
|
|
583
|
+
loadArgs (args) {
|
|
584
|
+
const expectedAttributes = ["name"];
|
|
585
|
+
if (typeof args !== "object" || args === null || Array.isArray(args)) {
|
|
586
|
+
// Not an object, so all attributes are missing.
|
|
587
|
+
throw new MissingAttributes("Engine", expectedAttributes);
|
|
568
588
|
}
|
|
589
|
+
expectedAttributes.forEach((attr) => {
|
|
590
|
+
if (!(attr in args)) {
|
|
591
|
+
throw new MissingAttributes("Engine", attr);
|
|
592
|
+
}
|
|
593
|
+
this[attr] = args[attr];
|
|
594
|
+
});
|
|
569
595
|
}
|
|
570
596
|
|
|
571
597
|
/**
|
|
@@ -611,6 +637,43 @@ class DALEngine {
|
|
|
611
637
|
createInvariant (args) {
|
|
612
638
|
return new Invariant(args);
|
|
613
639
|
}
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Returns the node in the graph with the given behavior name.
|
|
644
|
+
* @param {String} behaviorId
|
|
645
|
+
* @returns {GraphNode}
|
|
646
|
+
*/
|
|
647
|
+
getNode (behaviorId) {
|
|
648
|
+
return this.graph.findNode(behaviorId);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Adds a node to the graph with the given behaviorId and goToBehaviors.
|
|
653
|
+
* @param {String} behaviorId
|
|
654
|
+
* @param {Array} goToBehaviorsIds
|
|
655
|
+
* @returns {GraphNode}
|
|
656
|
+
*/
|
|
657
|
+
addNode (behaviorId, goToBehaviorsIds) {
|
|
658
|
+
const behavior = this.createBehavior({name: behaviorId});
|
|
659
|
+
return this.graph.addNode(behavior, goToBehaviorsIds);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
/**
|
|
663
|
+
* Adds a goToBehavior to the node with the given behaviorId.
|
|
664
|
+
* @param {String} behaviorId
|
|
665
|
+
* @param {String|Array} goToBehaviorIds
|
|
666
|
+
* @returns {GraphNode}
|
|
667
|
+
*/
|
|
668
|
+
addGoToBehavior (behaviorId, goToBehaviorIds) {
|
|
669
|
+
const node = this.graph.findNode(behaviorId);
|
|
670
|
+
if (Array.isArray(goToBehaviorIds)) {
|
|
671
|
+
node.goToBehaviorsIds.push(...goToBehaviorIds);
|
|
672
|
+
} else {
|
|
673
|
+
node.goToBehaviorsIds.push(goToBehaviorIds);
|
|
674
|
+
}
|
|
675
|
+
return node;
|
|
676
|
+
}
|
|
614
677
|
}
|
|
615
678
|
|
|
616
679
|
export { DALEngine };
|
package/package.json
CHANGED
|
@@ -43,13 +43,13 @@ class BehavioralControlGraph extends Base {
|
|
|
43
43
|
/**
|
|
44
44
|
* Adds a node to the graph.
|
|
45
45
|
* @param {Behavior} behavior
|
|
46
|
-
* @param {Array}
|
|
46
|
+
* @param {Array} goToBehaviorsIds
|
|
47
47
|
* @returns
|
|
48
48
|
*/
|
|
49
|
-
addNode (behavior,
|
|
49
|
+
addNode (behavior, goToBehaviorsIds) {
|
|
50
50
|
const node = new GraphNode({
|
|
51
51
|
behavior: behavior,
|
|
52
|
-
|
|
52
|
+
goToBehaviorsIds: goToBehaviorsIds,
|
|
53
53
|
});
|
|
54
54
|
this.nodes.push(node);
|
|
55
55
|
return node;
|
|
@@ -114,8 +114,8 @@ class BehavioralControlGraph extends Base {
|
|
|
114
114
|
exportAsMermaid () {
|
|
115
115
|
let mermaid = "flowchart TD\n";
|
|
116
116
|
this.nodes.forEach((node) => {
|
|
117
|
-
node.
|
|
118
|
-
mermaid += ` ${node.behavior.name} --> ${
|
|
117
|
+
node.goToBehaviorsIds.forEach((behaviorId) => {
|
|
118
|
+
mermaid += ` ${node.behavior.name} --> ${behaviorId}\n`;
|
|
119
119
|
});
|
|
120
120
|
});
|
|
121
121
|
return mermaid;
|
|
@@ -13,13 +13,13 @@ class GraphNode extends Base {
|
|
|
13
13
|
constructor (args) {
|
|
14
14
|
super();
|
|
15
15
|
this.type = ENGINE_TYPES.GRAPH_NODE;
|
|
16
|
-
this.
|
|
16
|
+
this.goToBehaviorsIds = [];
|
|
17
17
|
if (typeof args === "object" && args !== null) {
|
|
18
18
|
if (Object.hasOwn(args, "uid")) {
|
|
19
19
|
this.loadNodeFromJSON(args);
|
|
20
20
|
} else {
|
|
21
21
|
this.behavior = args.behavior;
|
|
22
|
-
this.
|
|
22
|
+
this.goToBehaviorsIds = args.goToBehaviorsIds;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -32,14 +32,23 @@ class GraphNode extends Base {
|
|
|
32
32
|
for (const [key, value] of Object.entries(nodesJSON)) {
|
|
33
33
|
if (key === "behavior") {
|
|
34
34
|
this.behavior = new Behavior(value);
|
|
35
|
-
} else if (key === "
|
|
36
|
-
value.forEach(
|
|
35
|
+
} else if (key === "goToBehaviorsIds") {
|
|
36
|
+
value.forEach(behaviorId => this.goToBehaviorsIds.push(behaviorId));
|
|
37
37
|
} else {
|
|
38
38
|
this[key] = nodesJSON[key];
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Adds a behavior name to the list of behaviors that this
|
|
45
|
+
* node transitions to.
|
|
46
|
+
* @param {String} behaviorId ID of behavior.
|
|
47
|
+
*/
|
|
48
|
+
addGoToBehavior (behaviorId) {
|
|
49
|
+
this.goToBehaviorsIds.push(behaviorId);
|
|
50
|
+
}
|
|
51
|
+
|
|
43
52
|
/**
|
|
44
53
|
* Checks if the provided behavior name is a valid
|
|
45
54
|
* behavior that the control flow selects as a
|
|
@@ -49,9 +58,9 @@ class GraphNode extends Base {
|
|
|
49
58
|
* @returns {Boolean}
|
|
50
59
|
*/
|
|
51
60
|
isValidGoToBehavior (behaviorName) {
|
|
52
|
-
for (let i = 0; i < this.
|
|
53
|
-
const
|
|
54
|
-
if (
|
|
61
|
+
for (let i = 0; i < this.goToBehaviorsIds.length; i++) {
|
|
62
|
+
const behaviorId = this.goToBehaviorsIds[i];
|
|
63
|
+
if (behaviorId === behaviorName) {
|
|
55
64
|
return true;
|
|
56
65
|
}
|
|
57
66
|
}
|
package/src/DALEngine.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import BehavioralControlGraph from "./BehavioralControlGraph/BehavioralControlGraph";
|
|
2
|
+
import MissingAttributes from "./Errors/MissingAttributes";
|
|
2
3
|
import Behavior from "./Members/Behavior";
|
|
3
4
|
import Invariant from "./Members/Invariant";
|
|
4
5
|
import Participant from "./Members/Participant";
|
|
@@ -19,9 +20,26 @@ import Participant from "./Members/Participant";
|
|
|
19
20
|
export class DALEngine {
|
|
20
21
|
constructor (args) {
|
|
21
22
|
this.graph = new BehavioralControlGraph();
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
this.loadArgs(args);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Loads the provided arguments.
|
|
28
|
+
* @throws {MissingAttributes} Thrown when required attr is not present.
|
|
29
|
+
* @param {Object} args
|
|
30
|
+
*/
|
|
31
|
+
loadArgs (args) {
|
|
32
|
+
const expectedAttributes = ["name"];
|
|
33
|
+
if (typeof args !== "object" || args === null || Array.isArray(args)) {
|
|
34
|
+
// Not an object, so all attributes are missing.
|
|
35
|
+
throw new MissingAttributes("Engine", expectedAttributes);
|
|
24
36
|
}
|
|
37
|
+
expectedAttributes.forEach((attr) => {
|
|
38
|
+
if (!(attr in args)) {
|
|
39
|
+
throw new MissingAttributes("Engine", attr);
|
|
40
|
+
}
|
|
41
|
+
this[attr] = args[attr];
|
|
42
|
+
});
|
|
25
43
|
}
|
|
26
44
|
|
|
27
45
|
/**
|
|
@@ -67,4 +85,41 @@ export class DALEngine {
|
|
|
67
85
|
createInvariant (args) {
|
|
68
86
|
return new Invariant(args);
|
|
69
87
|
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Returns the node in the graph with the given behavior name.
|
|
92
|
+
* @param {String} behaviorId
|
|
93
|
+
* @returns {GraphNode}
|
|
94
|
+
*/
|
|
95
|
+
getNode (behaviorId) {
|
|
96
|
+
return this.graph.findNode(behaviorId);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Adds a node to the graph with the given behaviorId and goToBehaviors.
|
|
101
|
+
* @param {String} behaviorId
|
|
102
|
+
* @param {Array} goToBehaviorsIds
|
|
103
|
+
* @returns {GraphNode}
|
|
104
|
+
*/
|
|
105
|
+
addNode (behaviorId, goToBehaviorsIds) {
|
|
106
|
+
const behavior = this.createBehavior({name: behaviorId});
|
|
107
|
+
return this.graph.addNode(behavior, goToBehaviorsIds);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Adds a goToBehavior to the node with the given behaviorId.
|
|
112
|
+
* @param {String} behaviorId
|
|
113
|
+
* @param {String|Array} goToBehaviorIds
|
|
114
|
+
* @returns {GraphNode}
|
|
115
|
+
*/
|
|
116
|
+
addGoToBehavior (behaviorId, goToBehaviorIds) {
|
|
117
|
+
const node = this.graph.findNode(behaviorId);
|
|
118
|
+
if (Array.isArray(goToBehaviorIds)) {
|
|
119
|
+
node.goToBehaviorsIds.push(...goToBehaviorIds);
|
|
120
|
+
} else {
|
|
121
|
+
node.goToBehaviorsIds.push(goToBehaviorIds);
|
|
122
|
+
}
|
|
123
|
+
return node;
|
|
124
|
+
}
|
|
70
125
|
}
|
package/tests/DALEngine.test.js
CHANGED
|
@@ -14,7 +14,8 @@ describe("DALEngine", () => {
|
|
|
14
14
|
expect(dalInstance.name).toBe("Library Manager");
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
it("throws on missing attributes", () => {
|
|
17
|
+
it(" throws on missing attributes", () => {
|
|
18
|
+
expect(() => {new DALEngine()}).toThrow(MissingAttributes);
|
|
18
19
|
const d = new DALEngine({name: "Library Manager"});
|
|
19
20
|
expect(() => {d.createBehavior()}).toThrow(MissingAttributes);
|
|
20
21
|
expect(() => {d.createBehavior({})}).toThrow(MissingAttributes);
|
|
@@ -26,39 +27,33 @@ describe("DALEngine", () => {
|
|
|
26
27
|
|
|
27
28
|
it("adds node to graph", () => {
|
|
28
29
|
const d = new DALEngine({name: "Library Manager"});
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const goToBehaviors = [behavior2];
|
|
32
|
-
|
|
33
|
-
const node = d.graph.addNode(behavior1, goToBehaviors)
|
|
30
|
+
const goToBehaviorIds = ["AddBookToBasket"];
|
|
31
|
+
const node = d.addNode("AcceptBookFromUser", goToBehaviorIds)
|
|
34
32
|
|
|
35
33
|
const nodeType = node.type;
|
|
36
34
|
expect(nodeType).toBe(ENGINE_TYPES.GRAPH_NODE);
|
|
37
|
-
expect(node.behavior).toStrictEqual(
|
|
38
|
-
expect(node.
|
|
39
|
-
|
|
40
|
-
const foundNode = d.graph.findNode("AcceptBookFromUser");
|
|
41
|
-
expect(foundNode).toStrictEqual(node);
|
|
35
|
+
expect(node.behavior.name).toStrictEqual("AcceptBookFromUser");
|
|
36
|
+
expect(node.goToBehaviorsIds).toStrictEqual(goToBehaviorIds);
|
|
42
37
|
});
|
|
43
38
|
|
|
44
39
|
it("find node that was added using behavior name", () => {
|
|
45
40
|
const d = new DALEngine({name: "Library Manager"});
|
|
46
|
-
const
|
|
47
|
-
const behavior2 = d.createBehavior({name: "AddBookToBasket"});
|
|
48
|
-
const node = d.graph.addNode(behavior1, [behavior2])
|
|
41
|
+
const node = d.addNode("AcceptBookFromUser", []);
|
|
49
42
|
|
|
50
|
-
|
|
43
|
+
expect(() => {d.getNode("AcceptBookFrmUser")}).toThrow(UnknownBehaviorError);
|
|
44
|
+
|
|
45
|
+
const foundNode = d.getNode("AcceptBookFromUser");
|
|
51
46
|
expect(foundNode).toStrictEqual(node);
|
|
52
47
|
});
|
|
53
48
|
|
|
54
49
|
it("find node and check if observed behavior is valid transition", () => {
|
|
55
50
|
const d = new DALEngine({name: "Library Manager"});
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
51
|
+
const node1 = d.addNode("AcceptBookFromUser", []);
|
|
52
|
+
const node2 = d.addNode("AddBookToBasket", []);
|
|
53
|
+
d.addNode("AnotherBehavior", []);
|
|
54
|
+
|
|
55
|
+
node1.addGoToBehavior("AddBookToBasket");
|
|
56
|
+
node2.addGoToBehavior("AnotherBehavior");
|
|
62
57
|
|
|
63
58
|
// Misspell behavior name to trigger unknown behavior error
|
|
64
59
|
expect(() => {
|
|
@@ -66,20 +61,20 @@ describe("DALEngine", () => {
|
|
|
66
61
|
}).toThrow(UnknownBehaviorError);
|
|
67
62
|
|
|
68
63
|
d.graph.setCurrentBehavior("AcceptBookFromUser");
|
|
69
|
-
expect(d.graph.currentNode
|
|
64
|
+
expect(d.graph.currentNode).toBe(node1);
|
|
70
65
|
|
|
71
66
|
d.graph.goToBehavior("AddBookToBasket")
|
|
72
|
-
expect(d.graph.currentNode
|
|
67
|
+
expect(d.graph.currentNode).toBe(node2);
|
|
73
68
|
|
|
74
69
|
// Reset current behavior so transition is valid
|
|
75
70
|
d.graph.setCurrentBehavior("AcceptBookFromUser");
|
|
76
|
-
d.graph.goToBehavior("
|
|
77
|
-
expect(d.graph.currentNode
|
|
71
|
+
d.graph.goToBehavior("AddBookToBasket")
|
|
72
|
+
expect(d.graph.currentNode).toBe(node2);
|
|
78
73
|
|
|
79
74
|
// Raises error because current behavior is "AnotherBehavior"
|
|
80
75
|
// and it does not transition to itself.
|
|
81
76
|
expect(() => {
|
|
82
|
-
d.graph.goToBehavior("
|
|
77
|
+
d.graph.goToBehavior("AddBookToBasket")
|
|
83
78
|
}).toThrow(InvalidTransitionError);
|
|
84
79
|
|
|
85
80
|
// Reset the current behavior and then go to a behavior
|
|
@@ -125,13 +120,15 @@ describe("DALEngine", () => {
|
|
|
125
120
|
);
|
|
126
121
|
book.addInvariant(invariant);
|
|
127
122
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
123
|
+
|
|
124
|
+
const node1 = d.addNode("AcceptBookFromUser", []);
|
|
125
|
+
d.addNode("AddBookToBasket", []);
|
|
126
|
+
d.addNode("AnotherBehavior", []);
|
|
127
|
+
|
|
128
|
+
node1.addGoToBehavior("AddBookToBasket");
|
|
129
|
+
node1.addGoToBehavior("AnotherBehavior");
|
|
130
|
+
|
|
131
|
+
node1.behavior.addParticpant(book);
|
|
135
132
|
|
|
136
133
|
const filePath = resolve(__dirname, "./temp/inspectSerializeTemp.json")
|
|
137
134
|
await writeFile(filePath, d.serialize())
|
package/tests/Invariant.test.js
CHANGED
|
@@ -72,28 +72,27 @@ describe("invariantTests", () => {
|
|
|
72
72
|
));
|
|
73
73
|
|
|
74
74
|
// Create behavior and participant
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
d.graph.addNode(behavior1, []);
|
|
75
|
+
const node1 = d.addNode("AcceptBookFromUser", []);
|
|
76
|
+
node1.behavior.addParticpant(book);
|
|
78
77
|
|
|
79
78
|
// Add value that respects invariant and expect valid world state
|
|
80
|
-
|
|
79
|
+
node1.behavior.setParticipantValue("book", {
|
|
81
80
|
"uid": 1,
|
|
82
81
|
"value": {
|
|
83
82
|
"name": "Harry Potter and Chamber of Secrets",
|
|
84
83
|
},
|
|
85
84
|
})
|
|
86
|
-
expect(
|
|
85
|
+
expect(node1.behavior.invalidWorldState).toBe(false);
|
|
87
86
|
|
|
88
87
|
|
|
89
88
|
// Add value that violates invariant and expect invalid world state
|
|
90
|
-
|
|
89
|
+
node1.behavior.setParticipantValue("book", {
|
|
91
90
|
"uid": 1,
|
|
92
91
|
"value": {
|
|
93
92
|
"name": "",
|
|
94
93
|
},
|
|
95
94
|
})
|
|
96
|
-
expect(
|
|
95
|
+
expect(node1.behavior.invalidWorldState).toBe(true);
|
|
97
96
|
|
|
98
97
|
// Write to file for inspection
|
|
99
98
|
const filePath = resolve(__dirname, "./temp/invariantBehaviorTemp.json")
|
|
@@ -8,31 +8,21 @@ describe("SimpleDesignTest", () => {
|
|
|
8
8
|
|
|
9
9
|
it("create simple design", async () => {
|
|
10
10
|
const d = new DALEngine({name: "Library Manager"});
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
d.
|
|
14
|
-
|
|
15
|
-
d.
|
|
11
|
+
d.addNode("AcceptChoiceToAddBookToBasket", ["AcceptBookFromUser"]);
|
|
12
|
+
d.addNode("AcceptBookFromUser", ["AddBookToBasket"]);
|
|
13
|
+
d.addNode("AddBookToBasket", []);
|
|
14
|
+
d.addNode("AcceptChoiceToAuditLibrary", ["GenerateAuditReport"]);
|
|
15
|
+
d.addNode("GenerateAuditReport", ["HandAuditToUser"]);
|
|
16
|
+
d.addNode("HandAuditToUser", []);
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
d.
|
|
20
|
-
|
|
21
|
-
d.
|
|
18
|
+
d.addNode("AcceptChoiceToPlaceBooksOnShelf", ["GetBookFromBasket"]);
|
|
19
|
+
d.addNode("GetBookFromBasket", ["GetFirstLetterOfBookName"]);
|
|
20
|
+
d.addNode("GetFirstLetterOfBookName", ["CreateSlotOnBookShelf", "AddBookToShelf"]);
|
|
21
|
+
d.addNode("CreateSlotOnBookShelf", ["AddBookToShelf"]);
|
|
22
|
+
d.addNode("AddBookToShelf", ["GetBookFromBasket"]);
|
|
22
23
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
);
|
|
26
|
-
const GetBookFromBasket = d.createBehavior({name: "GetBookFromBasket"});
|
|
27
|
-
d.graph.addNode(AcceptChoiceToPlaceBooksOnShelf, [GetBookFromBasket]);
|
|
28
|
-
const GetFirstLetterOfBookName = d.createBehavior({name: "GetFirstLetterOfBookName"});
|
|
29
|
-
d.graph.addNode(GetBookFromBasket, [GetFirstLetterOfBookName]);
|
|
30
|
-
const CreateSlotOnBookShelf = d.createBehavior({name: "CreateSlotOnBookShelf"});
|
|
31
|
-
const AddBookToShelf = d.createBehavior({name: "AddBookToShelf"});
|
|
32
|
-
d.graph.addNode(GetFirstLetterOfBookName, [CreateSlotOnBookShelf]);
|
|
33
|
-
d.graph.addNode(GetFirstLetterOfBookName, [AddBookToShelf]);
|
|
34
|
-
d.graph.addNode(CreateSlotOnBookShelf, [AddBookToShelf]);
|
|
35
|
-
d.graph.addNode(AddBookToShelf, [GetBookFromBasket]);
|
|
24
|
+
const filePath = resolve(__dirname, "./simple_design_temp.json")
|
|
25
|
+
await writeFile(filePath, d.serialize())
|
|
36
26
|
|
|
37
27
|
// Output can be viewed using https://mermaid.live/
|
|
38
28
|
const filePath2 = resolve(__dirname, "./temp/simple_design_mermaid.txt")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"uid":"0f4433c4-abd7-43da-96e3-6809863c93ab","type":5,"nodes":[{"uid":"1b0751a9-c46e-4fa6-ae7f-cf6204fdd83b","type":6,"goToBehaviorsIds":["AcceptBookFromUser"],"behavior":{"uid":"e336a950-f89c-43a6-b3c4-09df32f64831","type":1,"participants":[],"abstractionIds":[],"invalidWorldState":false,"name":"AcceptChoiceToAddBookToBasket"}},{"uid":"deb11624-0fae-4d1b-9d22-d421dea1d712","type":6,"goToBehaviorsIds":["AddBookToBasket"],"behavior":{"uid":"65b253bb-c4f2-4dee-8f36-648f73b3300c","type":1,"participants":[],"abstractionIds":[],"invalidWorldState":false,"name":"AcceptBookFromUser"}},{"uid":"f914f2c9-86e3-4c54-a926-b6c9c425cf9f","type":6,"goToBehaviorsIds":[],"behavior":{"uid":"76b6962c-24b1-4999-9719-5ac2e4f1c022","type":1,"participants":[],"abstractionIds":[],"invalidWorldState":false,"name":"AddBookToBasket"}},{"uid":"84912fd4-c193-4b7d-ad62-cdc6b254d529","type":6,"goToBehaviorsIds":["GenerateAuditReport"],"behavior":{"uid":"76f3d5a5-2e64-4bea-8beb-70d0d38e0645","type":1,"participants":[],"abstractionIds":[],"invalidWorldState":false,"name":"AcceptChoiceToAuditLibrary"}},{"uid":"4056410c-37c5-4ffa-8766-2ecd7a079617","type":6,"goToBehaviorsIds":["HandAuditToUser"],"behavior":{"uid":"f6a6e7d4-0151-4881-8d57-fb327620fd4a","type":1,"participants":[],"abstractionIds":[],"invalidWorldState":false,"name":"GenerateAuditReport"}},{"uid":"e6de6529-7d64-40f4-8787-c0e1c1c324eb","type":6,"goToBehaviorsIds":[],"behavior":{"uid":"8a3efec4-1068-4ee5-b66d-715bcc7b6d79","type":1,"participants":[],"abstractionIds":[],"invalidWorldState":false,"name":"HandAuditToUser"}},{"uid":"91b71f6c-e384-4c31-9d39-4eae95e61872","type":6,"goToBehaviorsIds":["GetBookFromBasket"],"behavior":{"uid":"9caee137-24b9-4314-b5a7-e4a7f6e93256","type":1,"participants":[],"abstractionIds":[],"invalidWorldState":false,"name":"AcceptChoiceToPlaceBooksOnShelf"}},{"uid":"4ea36149-15cf-4e6d-8770-cfd6bdc9645d","type":6,"goToBehaviorsIds":["GetFirstLetterOfBookName"],"behavior":{"uid":"1477b094-eb0a-4c2c-88b2-35ba99155f1e","type":1,"participants":[],"abstractionIds":[],"invalidWorldState":false,"name":"GetBookFromBasket"}},{"uid":"bd6116de-8cd9-41b2-a256-fab5d979d80e","type":6,"goToBehaviorsIds":["CreateSlotOnBookShelf","AddBookToShelf"],"behavior":{"uid":"36b0483d-d831-4478-a34e-c091db38370d","type":1,"participants":[],"abstractionIds":[],"invalidWorldState":false,"name":"GetFirstLetterOfBookName"}},{"uid":"54948771-65b7-40cb-8331-85f5b7d6cbf1","type":6,"goToBehaviorsIds":["AddBookToShelf"],"behavior":{"uid":"1fcd8aa4-6f25-4406-a0bc-ba43912ec572","type":1,"participants":[],"abstractionIds":[],"invalidWorldState":false,"name":"CreateSlotOnBookShelf"}},{"uid":"ff292a3c-e556-44de-9a47-9510ef0910e4","type":6,"goToBehaviorsIds":["GetBookFromBasket"],"behavior":{"uid":"b736147d-faf3-4718-86c2-a2e8ffa8fb51","type":1,"participants":[],"abstractionIds":[],"invalidWorldState":false,"name":"AddBookToShelf"}}]}
|