@woosh/meep-engine 2.48.6 → 2.48.8
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/package.json +1 -1
- package/src/core/assert.js +25 -0
- package/src/core/debug/BaseDescription.js +85 -0
- package/src/core/debug/BaseMatcher.js +7 -0
- package/src/core/debug/Description.js +53 -0
- package/src/core/debug/InMemoryDescriptor.js +11 -0
- package/src/core/debug/Matcher.js +35 -0
- package/src/core/debug/NullDescription.js +28 -0
- package/src/core/debug/SelfDescribing.js +15 -0
- package/src/core/debug/SelfDescribingValue.js +15 -0
- package/src/core/debug/SelfDescribingValueIterator.js +27 -0
- package/src/core/debug/matchers/AllOf.js +38 -0
- package/src/core/debug/matchers/AnyOf.js +35 -0
- package/src/core/debug/matchers/CombinableMatcher.js +53 -0
- package/src/core/debug/matchers/IsEqual.js +44 -0
- package/src/core/debug/matchers/IsIterableContaining.js +74 -0
- package/src/core/debug/matchers/IsNot.js +26 -0
- package/src/core/debug/matchers/IsNull.js +11 -0
- package/src/core/debug/matchers/IsUndefined.js +11 -0
- package/src/core/debug/matchers/matchers.js +50 -0
- package/src/core/model/node-graph/node/NodeInstancePortReference.js +20 -0
package/package.json
CHANGED
package/src/core/assert.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isArrayEqualStrict } from "./collection/array/isArrayEqualStrict.js";
|
|
2
2
|
import { isTypedArray } from "./collection/array/typed/isTypedArray.js";
|
|
3
|
+
import { InMemoryDescriptor } from "./debug/InMemoryDescriptor.js";
|
|
3
4
|
|
|
4
5
|
function equal(a, b, m) {
|
|
5
6
|
assert(a === b, m) // eslint-disable-line eqeqeq
|
|
@@ -385,6 +386,30 @@ assert.isFiniteNumber = function (value, name = "value") {
|
|
|
385
386
|
}
|
|
386
387
|
};
|
|
387
388
|
|
|
389
|
+
/**
|
|
390
|
+
* @template T
|
|
391
|
+
* @param {T} value
|
|
392
|
+
* @param {string} name
|
|
393
|
+
* @param {Matcher<T>} matcher
|
|
394
|
+
*/
|
|
395
|
+
assert.that = function (value, name, matcher) {
|
|
396
|
+
if (matcher.matches(value)) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const mismatch_description = new InMemoryDescriptor();
|
|
401
|
+
|
|
402
|
+
mismatch_description.appendText(`Expected ${name} to be `);
|
|
403
|
+
|
|
404
|
+
matcher.describeTo(mismatch_description);
|
|
405
|
+
|
|
406
|
+
mismatch_description.appendText(" instead ");
|
|
407
|
+
|
|
408
|
+
matcher.describeMismatch(value, mismatch_description);
|
|
409
|
+
|
|
410
|
+
throw new Error(mismatch_description.value);
|
|
411
|
+
}
|
|
412
|
+
|
|
388
413
|
export {
|
|
389
414
|
assert
|
|
390
415
|
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Description } from "./Description.js";
|
|
2
|
+
import { SelfDescribingValueIterator } from "./SelfDescribingValueIterator.js";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
function descriptionOf(value) {
|
|
6
|
+
try {
|
|
7
|
+
return String(value);
|
|
8
|
+
} catch (e) {
|
|
9
|
+
return 'VALUE@0';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param {number} value
|
|
16
|
+
* @return {string}
|
|
17
|
+
*/
|
|
18
|
+
function formatNumber(value) {
|
|
19
|
+
return String(value);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
export class BaseDescription extends Description {
|
|
24
|
+
appendDescriptionOf(value) {
|
|
25
|
+
value.describeTo(this);
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#toJavaScriptSyntax(unformatted) {
|
|
30
|
+
this.appendText('"');
|
|
31
|
+
|
|
32
|
+
// TODO escape string
|
|
33
|
+
this.appendText(unformatted);
|
|
34
|
+
|
|
35
|
+
this.appendText('"');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
appendValue(value) {
|
|
39
|
+
if (value == null) {
|
|
40
|
+
this.appendText("null");
|
|
41
|
+
} else if (value === undefined) {
|
|
42
|
+
this.appendText("undefined");
|
|
43
|
+
} else if (typeof value === "string") {
|
|
44
|
+
this.#toJavaScriptSyntax(value);
|
|
45
|
+
} else if (typeof value === "number") {
|
|
46
|
+
this.appendText(formatNumber(value));
|
|
47
|
+
} else if (Array.isArray(value)) {
|
|
48
|
+
this.appendValueList("[", ", ", "]", value);
|
|
49
|
+
} else {
|
|
50
|
+
this.appendText('<');
|
|
51
|
+
this.appendText(descriptionOf(value));
|
|
52
|
+
this.appendText('>');
|
|
53
|
+
}
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
appendValueList(start, separator, end, values) {
|
|
58
|
+
this.appendList(start, separator, end, new SelfDescribingValueIterator(values));
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
appendList(start, separator, end, values) {
|
|
63
|
+
let separate = false;
|
|
64
|
+
|
|
65
|
+
this.appendText(start);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
*
|
|
69
|
+
*/
|
|
70
|
+
const iterator = values[Symbol.iterator]();
|
|
71
|
+
|
|
72
|
+
for (let i = iterator.next(); i.done !== true; i = iterator.next()) {
|
|
73
|
+
if (separate) {
|
|
74
|
+
this.appendText(separator);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
this.appendDescriptionOf(i.value);
|
|
78
|
+
separate = true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
this.appendText(end);
|
|
82
|
+
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export class Description {
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* @param {SelfDescribing} value
|
|
5
|
+
* @returns {this}
|
|
6
|
+
*/
|
|
7
|
+
appendDescriptionOf(value) {
|
|
8
|
+
throw new Error('Not Implemented');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {string} start
|
|
13
|
+
* @param {string} separator
|
|
14
|
+
* @param {string} end
|
|
15
|
+
* @param {Iterable<SelfDescribing>} values
|
|
16
|
+
* @returns {this}
|
|
17
|
+
*/
|
|
18
|
+
appendList(start, separator, end, values) {
|
|
19
|
+
throw new Error('Not Implemented');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @param {string} text
|
|
25
|
+
* @returns {this}
|
|
26
|
+
*/
|
|
27
|
+
appendText(text) {
|
|
28
|
+
throw new Error('Not Implemented');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @template T
|
|
33
|
+
* @param {T} value
|
|
34
|
+
* @returns {this}
|
|
35
|
+
*/
|
|
36
|
+
appendValue(value) {
|
|
37
|
+
throw new Error('Not Implemented');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
*
|
|
42
|
+
* @template T
|
|
43
|
+
* @param {string} start
|
|
44
|
+
* @param {string} separator
|
|
45
|
+
* @param {string} end
|
|
46
|
+
* @param {Iterable<T>} values
|
|
47
|
+
* @returns {this}
|
|
48
|
+
*/
|
|
49
|
+
appendValueList(start, separator, end, values) {
|
|
50
|
+
throw new Error('Not Implemented');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { SelfDescribing } from "./SelfDescribing.js";
|
|
2
|
+
import { NullDescription } from "./NullDescription.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Heavily influenced by Hamcrest, pretty much a straight port
|
|
6
|
+
* @template T
|
|
7
|
+
*/
|
|
8
|
+
export class Matcher extends SelfDescribing {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param {T} item
|
|
13
|
+
* @param {Description} [mismatch_description]
|
|
14
|
+
* @returns {boolean}
|
|
15
|
+
*/
|
|
16
|
+
matches(item, mismatch_description = NullDescription.INSTANCE) {
|
|
17
|
+
throw new Error('Not Implemented');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
* @param {T} item
|
|
23
|
+
* @param {Description} mismatch_description
|
|
24
|
+
* @returns {void}
|
|
25
|
+
*/
|
|
26
|
+
describeMismatch(item, mismatch_description) {
|
|
27
|
+
throw new Error('Not Implemented');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @readonly
|
|
33
|
+
* @type {boolean}
|
|
34
|
+
*/
|
|
35
|
+
Matcher.prototype.isMatcher = true;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Description } from "./Description.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Special description that doesn't record anything
|
|
5
|
+
*/
|
|
6
|
+
export class NullDescription extends Description {
|
|
7
|
+
appendText(text) {
|
|
8
|
+
return this;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
appendList(start, separator, end, values) {
|
|
12
|
+
return this;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
appendValueList(start, separator, end, values) {
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
appendValue(value) {
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
appendDescriptionOf(value) {
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
NullDescription.INSTANCE = new NullDescription();
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ability of an object to describe itself.
|
|
3
|
+
*/
|
|
4
|
+
export class SelfDescribing {
|
|
5
|
+
/**
|
|
6
|
+
* Generates a description of the object. The description may be part of a
|
|
7
|
+
* description of a larger object of which this is just a component, so it
|
|
8
|
+
* should be worded appropriately.
|
|
9
|
+
* @param {Description} description The description to be built or appended to
|
|
10
|
+
* @returns {void}
|
|
11
|
+
*/
|
|
12
|
+
describeTo(description) {
|
|
13
|
+
throw new Error('Not Implemented');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SelfDescribing } from "./SelfDescribing.js";
|
|
2
|
+
|
|
3
|
+
export class SelfDescribingValue extends SelfDescribing{
|
|
4
|
+
value;
|
|
5
|
+
|
|
6
|
+
constructor(value) {
|
|
7
|
+
super();
|
|
8
|
+
|
|
9
|
+
this.value = value;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describeTo(description) {
|
|
13
|
+
description.appendValue(this.value);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SelfDescribingValue } from "./SelfDescribingValue.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @template T
|
|
5
|
+
* @extends Iterable<SelfDescribing>
|
|
6
|
+
*/
|
|
7
|
+
export class SelfDescribingValueIterator {
|
|
8
|
+
#iterable;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param {Iterable<T>} iterable
|
|
13
|
+
*/
|
|
14
|
+
constructor(iterable) {
|
|
15
|
+
this.#iterable = iterable;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
* [Symbol.iterator]() {
|
|
19
|
+
|
|
20
|
+
for (const el of this.#iterable) {
|
|
21
|
+
|
|
22
|
+
yield new SelfDescribingValue(el);
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Matcher } from "../Matcher.js";
|
|
2
|
+
import { NullDescription } from "../NullDescription.js";
|
|
3
|
+
import { BaseMatcher } from "../BaseMatcher.js";
|
|
4
|
+
|
|
5
|
+
export class AllOf extends BaseMatcher {
|
|
6
|
+
/**
|
|
7
|
+
* @type {Matcher[]}
|
|
8
|
+
*/
|
|
9
|
+
#matchers;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param {Matcher[]} matchers
|
|
14
|
+
*/
|
|
15
|
+
constructor(matchers) {
|
|
16
|
+
super();
|
|
17
|
+
|
|
18
|
+
this.#matchers = matchers;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
matches(item, mismatch_description) {
|
|
22
|
+
for (const matcher of this.#matchers) {
|
|
23
|
+
if (!matcher.matches(item, NullDescription.INSTANCE)) {
|
|
24
|
+
|
|
25
|
+
mismatch_description.appendDescriptionOf(matcher).appendText(" ");
|
|
26
|
+
matcher.describeMismatch(item, mismatch_description);
|
|
27
|
+
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
describeTo(description) {
|
|
36
|
+
description.appendList("(", ' and ', ")", this.#matchers);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Matcher } from "../Matcher.js";
|
|
2
|
+
import { NullDescription } from "../NullDescription.js";
|
|
3
|
+
import { BaseMatcher } from "../BaseMatcher.js";
|
|
4
|
+
|
|
5
|
+
export class AnyOf extends BaseMatcher {
|
|
6
|
+
/**
|
|
7
|
+
* @type {Matcher[]}
|
|
8
|
+
*/
|
|
9
|
+
#matchers;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param {Matcher[]} matchers
|
|
14
|
+
*/
|
|
15
|
+
constructor(matchers) {
|
|
16
|
+
super();
|
|
17
|
+
|
|
18
|
+
this.#matchers = matchers;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
matches(item, mismatch_description) {
|
|
22
|
+
for (const matcher of this.#matchers) {
|
|
23
|
+
if (!matcher.matches(item, NullDescription.INSTANCE)) {
|
|
24
|
+
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
describeTo(description) {
|
|
33
|
+
description.appendList("(", " or ", ")", this.#matchers);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { BaseMatcher } from "../BaseMatcher.js";
|
|
2
|
+
import { NullDescription } from "../NullDescription.js";
|
|
3
|
+
import { AllOf } from "./AllOf.js";
|
|
4
|
+
import { AnyOf } from "./AnyOf.js";
|
|
5
|
+
|
|
6
|
+
export class CombinableMatcher extends BaseMatcher {
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @type {Matcher}
|
|
10
|
+
*/
|
|
11
|
+
#matcher
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param {Matcher} matcher
|
|
16
|
+
*/
|
|
17
|
+
constructor(matcher) {
|
|
18
|
+
super();
|
|
19
|
+
this.#matcher = matcher;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
matches(item, mismatch_description) {
|
|
24
|
+
if (!this.#matcher.matches(item, NullDescription.INSTANCE)) {
|
|
25
|
+
this.#matcher.describeMismatch(item, mismatch_description);
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
describeTo(description) {
|
|
33
|
+
description.appendDescriptionOf(this.#matcher);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* @param {Matcher} other
|
|
39
|
+
* @return {CombinableMatcher}
|
|
40
|
+
*/
|
|
41
|
+
and(other) {
|
|
42
|
+
return new CombinableMatcher(new AllOf([this.#matcher, other]))
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @param {Matcher} other
|
|
48
|
+
* @return {CombinableMatcher}
|
|
49
|
+
*/
|
|
50
|
+
or(other) {
|
|
51
|
+
return new CombinableMatcher(new AnyOf([this.#matcher, other]));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { BaseMatcher } from "../BaseMatcher.js";
|
|
2
|
+
import { isArrayEqualStrict } from "../../collection/array/isArrayEqualStrict.js";
|
|
3
|
+
|
|
4
|
+
export class IsEqual extends BaseMatcher {
|
|
5
|
+
#expected;
|
|
6
|
+
|
|
7
|
+
constructor(expected) {
|
|
8
|
+
super();
|
|
9
|
+
this.#expected = expected;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
matches(item, mismatch_description) {
|
|
13
|
+
return this.areEqual(item, this.#expected);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describeTo(description) {
|
|
17
|
+
description.appendValue(this.#expected);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
areEqual(actual, expected) {
|
|
22
|
+
if (expected === actual) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (actual === null || actual === undefined) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (expected !== null && Array.isArray(actual)) {
|
|
31
|
+
return Array.isArray(expected) && isArrayEqualStrict(actual, expected);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (typeof actual === "object" && typeof expected === "object" && typeof actual.equals === "function") {
|
|
35
|
+
|
|
36
|
+
return actual.equals(expected);
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { BaseMatcher } from "../BaseMatcher.js";
|
|
2
|
+
import { NullDescription } from "../NullDescription.js";
|
|
3
|
+
|
|
4
|
+
export class IsIterableContaining extends BaseMatcher {
|
|
5
|
+
/**
|
|
6
|
+
* @type {Matcher}
|
|
7
|
+
*/
|
|
8
|
+
#element_matcher
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param {Matcher} matcher
|
|
13
|
+
*/
|
|
14
|
+
constructor(matcher) {
|
|
15
|
+
super();
|
|
16
|
+
|
|
17
|
+
this.#element_matcher = matcher;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
matches(item, mismatch_description) {
|
|
21
|
+
if (this.#isEmpty(item)) {
|
|
22
|
+
mismatch_description.appendText("was empty");
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
for (const itemElement of item) {
|
|
27
|
+
if (this.#element_matcher.matches(itemElement, NullDescription.INSTANCE)) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
mismatch_description.appendText("mismatches were: [");
|
|
33
|
+
|
|
34
|
+
let is_past_first = false;
|
|
35
|
+
|
|
36
|
+
for (const itemElement of item) {
|
|
37
|
+
if (is_past_first) {
|
|
38
|
+
mismatch_description.appendText(", ");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.#element_matcher.describeMismatch(item, mismatch_description);
|
|
42
|
+
|
|
43
|
+
is_past_first = true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
mismatch_description.appendText("]");
|
|
48
|
+
|
|
49
|
+
return false;
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
* @param {Iterable} iterable
|
|
56
|
+
* @return {boolean}
|
|
57
|
+
*/
|
|
58
|
+
#isEmpty(iterable) {
|
|
59
|
+
const iterator = iterable[Symbol.iterator]();
|
|
60
|
+
|
|
61
|
+
const el = iterator.next();
|
|
62
|
+
|
|
63
|
+
return el.done === true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
describeTo(description) {
|
|
68
|
+
|
|
69
|
+
description
|
|
70
|
+
.appendText("a collection containing ")
|
|
71
|
+
.appendDescriptionOf(this.#element_matcher);
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Matcher } from "../Matcher.js";
|
|
2
|
+
import { BaseMatcher } from "../BaseMatcher.js";
|
|
3
|
+
|
|
4
|
+
export class IsNot extends BaseMatcher {
|
|
5
|
+
/**
|
|
6
|
+
* @type {Matcher}
|
|
7
|
+
*/
|
|
8
|
+
#matcher
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param {Matcher} matcher
|
|
13
|
+
*/
|
|
14
|
+
constructor(matcher) {
|
|
15
|
+
super();
|
|
16
|
+
this.#matcher = matcher;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
matches(item, mismatch_description) {
|
|
20
|
+
return !this.#matcher.matches(item, mismatch_description);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describeTo(description) {
|
|
24
|
+
description.appendText('not ').appendDescriptionOf(this.#matcher);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { AnyOf } from "./AnyOf.js";
|
|
2
|
+
import { AllOf } from "./AllOf.js";
|
|
3
|
+
import { IsNot } from "./IsNot.js";
|
|
4
|
+
import { IsEqual } from "./IsEqual.js";
|
|
5
|
+
import { IsNull } from "./IsNull.js";
|
|
6
|
+
import { IsIterableContaining } from "./IsIterableContaining.js";
|
|
7
|
+
import { Matcher } from "../Matcher.js";
|
|
8
|
+
|
|
9
|
+
export function anyOf(...matchers) {
|
|
10
|
+
return new AnyOf(matchers);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function allOf(...matchers) {
|
|
14
|
+
return new AllOf(matchers);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function not(matcher) {
|
|
18
|
+
return new IsNot(matcher);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function equalTo(thing) {
|
|
22
|
+
return new IsEqual(thing);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function notEqualTo(thing) {
|
|
26
|
+
return not(equalTo(thing));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function isNull() {
|
|
30
|
+
return new IsNull();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function isNotNull() {
|
|
34
|
+
return not(isNull());
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @template
|
|
39
|
+
* @param {Matcher|T} value
|
|
40
|
+
* @return {Matcher}
|
|
41
|
+
*/
|
|
42
|
+
export function hasItem(value) {
|
|
43
|
+
if (value instanceof Matcher) {
|
|
44
|
+
return new IsIterableContaining(value);
|
|
45
|
+
} else {
|
|
46
|
+
return new IsIterableContaining(equalTo(value));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
@@ -64,6 +64,26 @@ export class NodeInstancePortReference {
|
|
|
64
64
|
return this.connections.length > 0;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Checks if a connection exists from this endpoint to a specific node instance
|
|
69
|
+
* @param {number} node_instance_id
|
|
70
|
+
* @returns {boolean}
|
|
71
|
+
*/
|
|
72
|
+
isConnectedToNode(node_instance_id) {
|
|
73
|
+
const connections = this.connections;
|
|
74
|
+
const connection_count = connections.length;
|
|
75
|
+
|
|
76
|
+
for (let i = 0; i < connection_count; i++) {
|
|
77
|
+
const connection = connections[i];
|
|
78
|
+
|
|
79
|
+
if (connection.isAttachedToNode(node_instance_id)) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
|
|
67
87
|
|
|
68
88
|
/**
|
|
69
89
|
*
|