@codeperfect/eslint-plugin 2.0.0 → 2.1.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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/codeperfect-eslint-plugin-1.0.0.tgz +0 -0
- package/dist/domain/architecture/consistent-barrel-files/exports-only-rule.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/exports-only-rule.js +8 -3
- package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-rule.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/no-reexports-outside-barrels-rule.js +8 -3
- package/dist/domain/architecture/consistent-barrel-files/rule.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/rule.js +12 -4
- package/dist/domain/core/no-multiple-declarators/rule.d.ts.map +1 -1
- package/dist/domain/core/no-multiple-declarators/rule.js +6 -3
- package/dist/domain/core/prefer-interface-types/rule.d.ts.map +1 -1
- package/dist/domain/core/prefer-interface-types/rule.js +6 -3
- package/dist/domain/core/prefer-interface-types/test-helpers.d.ts.map +1 -1
- package/dist/domain/core/prefer-interface-types/test-helpers.js +1 -1
- package/dist/domain/custom-rule-documentation.d.ts +2 -0
- package/dist/domain/custom-rule-documentation.d.ts.map +1 -1
- package/dist/domain/custom-rule-documentation.js +2 -1
- package/dist/domain/docs/no-interface-member-docs/comment-utilities-test-helpers.d.ts.map +1 -1
- package/dist/domain/docs/no-interface-member-docs/comment-utilities-test-helpers.js +1 -1
- package/dist/domain/docs/no-interface-member-docs/parameter-utilities.js +1 -1
- package/dist/domain/docs/no-interface-member-docs/rule.d.ts.map +1 -1
- package/dist/domain/docs/no-interface-member-docs/rule.js +6 -3
- package/dist/domain/docs/no-interface-member-docs/test-helpers.js +1 -1
- package/dist/domain/docs/require-example-language/create-fixer.js +1 -1
- package/dist/domain/docs/require-example-language/fixes.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/fixes.js +1 -1
- package/dist/domain/docs/require-example-language/reporting.js +1 -1
- package/dist/domain/docs/require-example-language/rule.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/rule.js +6 -3
- package/dist/domain/docs/single-line-jsdoc/rule.d.ts +1 -2
- package/dist/domain/docs/single-line-jsdoc/rule.d.ts.map +1 -1
- package/dist/domain/docs/single-line-jsdoc/rule.edge-cases.js +1 -1
- package/dist/domain/docs/single-line-jsdoc/rule.js +11 -6
- package/dist/domain/docs/single-line-jsdoc/rule.node-lookups.js +1 -1
- package/dist/domain/testing/aaa/analyzer.analysis.d.ts +14 -72
- package/dist/domain/testing/aaa/analyzer.analysis.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.analysis.helpers.d.ts +144 -3
- package/dist/domain/testing/aaa/analyzer.analysis.helpers.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.analysis.helpers.js +202 -3
- package/dist/domain/testing/aaa/analyzer.analysis.js +36 -201
- package/dist/domain/testing/aaa/analyzer.analysis.unsupported.d.ts +4 -0
- package/dist/domain/testing/aaa/analyzer.analysis.unsupported.d.ts.map +1 -0
- package/dist/domain/testing/aaa/analyzer.analysis.unsupported.js +4 -0
- package/dist/domain/testing/aaa/analyzer.assertions.d.ts +16 -91
- package/dist/domain/testing/aaa/analyzer.assertions.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.assertions.destructured.d.ts +4 -0
- package/dist/domain/testing/aaa/analyzer.assertions.destructured.d.ts.map +1 -0
- package/dist/domain/testing/aaa/analyzer.assertions.destructured.js +4 -0
- package/dist/domain/testing/aaa/analyzer.assertions.helpers.d.ts +95 -0
- package/dist/domain/testing/aaa/analyzer.assertions.helpers.d.ts.map +1 -0
- package/dist/domain/testing/aaa/analyzer.assertions.helpers.js +185 -0
- package/dist/domain/testing/aaa/analyzer.assertions.js +32 -282
- package/dist/domain/testing/aaa/analyzer.assertions.operands.d.ts +64 -0
- package/dist/domain/testing/aaa/analyzer.assertions.operands.d.ts.map +1 -0
- package/dist/domain/testing/aaa/analyzer.assertions.operands.js +105 -0
- package/dist/domain/testing/aaa/analyzer.classification.d.ts +14 -73
- package/dist/domain/testing/aaa/analyzer.classification.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.classification.helpers.d.ts +77 -0
- package/dist/domain/testing/aaa/analyzer.classification.helpers.d.ts.map +1 -0
- package/dist/domain/testing/aaa/analyzer.classification.helpers.js +203 -0
- package/dist/domain/testing/aaa/analyzer.classification.js +30 -200
- package/dist/domain/testing/aaa/analyzer.classification.mutations.d.ts +4 -0
- package/dist/domain/testing/aaa/analyzer.classification.mutations.d.ts.map +1 -0
- package/dist/domain/testing/aaa/analyzer.classification.mutations.js +4 -0
- package/dist/domain/testing/aaa/analyzer.classification.traversal.d.ts +15 -0
- package/dist/domain/testing/aaa/analyzer.classification.traversal.d.ts.map +1 -0
- package/dist/domain/testing/aaa/analyzer.classification.traversal.js +34 -0
- package/dist/domain/testing/aaa/analyzer.d.ts +2 -2
- package/dist/domain/testing/aaa/analyzer.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.super.d.ts +8 -9
- package/dist/domain/testing/aaa/analyzer.super.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.super.helpers.d.ts +27 -0
- package/dist/domain/testing/aaa/analyzer.super.helpers.d.ts.map +1 -0
- package/dist/domain/testing/aaa/analyzer.super.helpers.js +66 -0
- package/dist/domain/testing/aaa/analyzer.super.js +43 -60
- package/dist/domain/testing/assert-actual-expected-names/rule.d.ts.map +1 -1
- package/dist/domain/testing/assert-actual-expected-names/rule.js +6 -3
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.behavior.combined.d.ts +4 -0
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.behavior.combined.d.ts.map +1 -0
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.behavior.combined.js +4 -0
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.behavior.companion.d.ts +4 -0
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.behavior.companion.d.ts.map +1 -0
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.behavior.companion.js +4 -0
- package/dist/domain/testing/enforce-aaa-phase-purity/rule-test-helpers.js +1 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/rule.d.ts.map +1 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/rule.js +6 -3
- package/dist/domain/testing/enforce-aaa-structure/rule.d.ts.map +1 -1
- package/dist/domain/testing/enforce-aaa-structure/rule.js +6 -3
- package/dist/domain/testing/prefer-vi-mocked-import/rule.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/rule.js +6 -3
- package/dist/domain/testing/prefer-vitest-incremental-casts/ast-helpers.d.ts +12 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/ast-helpers.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/ast-helpers.js +26 -2
- package/dist/domain/testing/prefer-vitest-incremental-casts/match-input.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/match-input.js +13 -10
- package/dist/domain/testing/prefer-vitest-incremental-casts/match.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/match.js +8 -2
- package/dist/domain/testing/prefer-vitest-incremental-casts/replacement-helpers.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/replacement-helpers.js +9 -5
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/rule.js +28 -2
- package/dist/domain/testing/prefer-vitest-incremental-casts/type-helpers.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/type-helpers.js +1 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/types.d.ts +9 -25
- package/dist/domain/testing/prefer-vitest-incremental-casts/types.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vitest-incremental-casts/types.js +1 -1
- package/dist/domain/testing/require-aaa-sections/rule.d.ts.map +1 -1
- package/dist/domain/testing/require-aaa-sections/rule.js +9 -4
- package/dist/domain/testing/require-aaa-sections/rule.reporting.d.ts.map +1 -1
- package/dist/domain/testing/require-aaa-sections/rule.reporting.js +3 -4
- package/dist/domain/testing/require-act-result-capture/rule.d.ts.map +1 -1
- package/dist/domain/testing/require-act-result-capture/rule.js +6 -3
- package/dist/domain/testing/require-test-companion/rule.d.ts.map +1 -1
- package/dist/domain/testing/require-test-companion/rule.js +31 -6
- package/dist/domain/testing/single-act-statement/rule.d.ts.map +1 -1
- package/dist/domain/testing/single-act-statement/rule.js +6 -3
- package/dist/infrastructure/presets.js +1 -1
- package/package.json +37 -29
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gets assert operands.
|
|
3
|
+
* @param expression Input expression value.
|
|
4
|
+
* @returns Return value output.
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* getAssertOperands(expression);
|
|
8
|
+
* ```
|
|
9
|
+
*/
|
|
10
|
+
function getAssertOperands(expression) {
|
|
11
|
+
if (expression.callee.type === "MemberExpression" &&
|
|
12
|
+
expression.callee.object.type === "Identifier" &&
|
|
13
|
+
expression.callee.object.name === "assert") {
|
|
14
|
+
const [actual, expected] = expression.arguments;
|
|
15
|
+
if (actual?.type !== "SpreadElement" &&
|
|
16
|
+
expected?.type !== "SpreadElement") {
|
|
17
|
+
return { actual, expected };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Gets expect operands.
|
|
24
|
+
* @param expression Input expression value.
|
|
25
|
+
* @returns Return value output.
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* getExpectOperands(expression);
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
function getExpectOperands(expression) {
|
|
32
|
+
if (expression.callee.type === "Identifier" &&
|
|
33
|
+
expression.callee.name === "expect") {
|
|
34
|
+
const [actual] = expression.arguments;
|
|
35
|
+
return actual?.type === "SpreadElement"
|
|
36
|
+
? { actual: void 0, expected: void 0 }
|
|
37
|
+
: { actual, expected: void 0 };
|
|
38
|
+
}
|
|
39
|
+
if (expression.callee.type === "MemberExpression" &&
|
|
40
|
+
expression.callee.object.type === "CallExpression") {
|
|
41
|
+
const nestedOperands = getExpectOperands(expression.callee.object);
|
|
42
|
+
if (nestedOperands === void 0) {
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
const [expected] = expression.arguments;
|
|
46
|
+
return expected?.type === "SpreadElement"
|
|
47
|
+
? nestedOperands
|
|
48
|
+
: { actual: nestedOperands.actual, expected };
|
|
49
|
+
}
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Gets an identifier name.
|
|
54
|
+
* @param expression Input expression value.
|
|
55
|
+
* @returns Return value output.
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* getIdentifierName(expression);
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
function getIdentifierName(expression) {
|
|
62
|
+
return expression?.type === "Identifier" ? expression.name : void 0;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Checks whether an assertion evaluates the actual operand inline.
|
|
66
|
+
* @param expression Assertion call expression to inspect.
|
|
67
|
+
* @param isActionExpression Predicate that identifies action-like expressions.
|
|
68
|
+
* @returns True when the assertion actual operand performs action-like work.
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const actual = hasEvaluatedAssertionActual(expression, () => true);
|
|
72
|
+
* void actual;
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
function hasEvaluatedAssertionActual(expression, isActionExpression) {
|
|
76
|
+
const operands = getExpectOperands(expression) ?? getAssertOperands(expression);
|
|
77
|
+
return operands !== void 0 && isActionExpression(operands.actual);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Checks for assertion calls.
|
|
81
|
+
* @param node Input node value.
|
|
82
|
+
* @returns Return value output.
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* isAssertionCall(node);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
function isAssertionCall(node) {
|
|
89
|
+
if (node.callee.type === "Identifier") {
|
|
90
|
+
return node.callee.name === "expect" || node.callee.name === "assert";
|
|
91
|
+
}
|
|
92
|
+
if (node.callee.type !== "MemberExpression") {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
if (node.callee.object.type === "Identifier" &&
|
|
96
|
+
node.callee.object.name === "assert") {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
return (node.callee.object.type === "CallExpression" &&
|
|
100
|
+
isAssertionCall(node.callee.object));
|
|
101
|
+
}
|
|
102
|
+
/** Companion marker for test isolation. */
|
|
103
|
+
const analyzerAssertionsOperandsCompanion = true;
|
|
104
|
+
export { analyzerAssertionsOperandsCompanion, getAssertOperands, getExpectOperands, getIdentifierName, hasEvaluatedAssertionActual, isAssertionCall, };
|
|
105
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5hbHl6ZXIuYXNzZXJ0aW9ucy5vcGVyYW5kcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kb21haW4vdGVzdGluZy9hYWEvYW5hbHl6ZXIuYXNzZXJ0aW9ucy5vcGVyYW5kcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFVQTs7Ozs7Ozs7R0FRRztBQUNILFNBQVMsaUJBQWlCLENBQ3hCLFVBQWlDO0lBRWpDLElBQ0UsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssa0JBQWtCO1FBQzdDLFVBQVUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxZQUFZO1FBQzlDLFVBQVUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQzFDLENBQUM7UUFDRCxNQUFNLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUM7UUFDaEQsSUFDRSxNQUFNLEVBQUUsSUFBSSxLQUFLLGVBQWU7WUFDaEMsUUFBUSxFQUFFLElBQUksS0FBSyxlQUFlLEVBQ2xDLENBQUM7WUFDRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxDQUFDO1FBQzlCLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUMsQ0FBQztBQUNoQixDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFTLGlCQUFpQixDQUN4QixVQUFpQztJQUVqQyxJQUNFLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLFlBQVk7UUFDdkMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUNuQyxDQUFDO1FBQ0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxHQUFHLFVBQVUsQ0FBQyxTQUFTLENBQUM7UUFDdEMsT0FBTyxNQUFNLEVBQUUsSUFBSSxLQUFLLGVBQWU7WUFDckMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRTtZQUN0QyxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUM7SUFDbkMsQ0FBQztJQUVELElBQ0UsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssa0JBQWtCO1FBQzdDLFVBQVUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxnQkFBZ0IsRUFDbEQsQ0FBQztRQUNELE1BQU0sY0FBYyxHQUFHLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbkUsSUFBSSxjQUFjLEtBQUssS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM5QixPQUFPLEtBQUssQ0FBQyxDQUFDO1FBQ2hCLENBQUM7UUFFRCxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsVUFBVSxDQUFDLFNBQVMsQ0FBQztRQUV4QyxPQUFPLFFBQVEsRUFBRSxJQUFJLEtBQUssZUFBZTtZQUN2QyxDQUFDLENBQUMsY0FBYztZQUNoQixDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsY0FBYyxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQztJQUNsRCxDQUFDO0lBRUQsT0FBTyxLQUFLLENBQUMsQ0FBQztBQUNoQixDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFTLGlCQUFpQixDQUN4QixVQUF5QztJQUV6QyxPQUFPLFVBQVUsRUFBRSxJQUFJLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN0RSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILFNBQVMsMkJBQTJCLENBQ2xDLFVBQWlDLEVBQ2pDLGtCQUEwRTtJQUUxRSxNQUFNLFFBQVEsR0FDWixpQkFBaUIsQ0FBQyxVQUFVLENBQUMsSUFBSSxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUVqRSxPQUFPLFFBQVEsS0FBSyxLQUFLLENBQUMsSUFBSSxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDcEUsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBUyxlQUFlLENBQUMsSUFBMkI7SUFDbEQsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxZQUFZLEVBQUUsQ0FBQztRQUN0QyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLFFBQVEsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxRQUFRLENBQUM7SUFDeEUsQ0FBQztJQUVELElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssa0JBQWtCLEVBQUUsQ0FBQztRQUM1QyxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxJQUNFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxZQUFZO1FBQ3hDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQ3BDLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLENBQ0wsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLGdCQUFnQjtRQUM1QyxlQUFlLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FDcEMsQ0FBQztBQUNKLENBQUM7QUFFRCwyQ0FBMkM7QUFDM0MsTUFBTSxtQ0FBbUMsR0FBRyxJQUFhLENBQUM7QUFFMUQsT0FBTyxFQUNMLG1DQUFtQyxFQUNuQyxpQkFBaUIsRUFDakIsaUJBQWlCLEVBQ2pCLGlCQUFpQixFQUNqQiwyQkFBMkIsRUFDM0IsZUFBZSxHQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgKiBhcyBFU1RyZWUgZnJvbSBcImVzdHJlZVwiO1xyXG5cclxuLyoqIFJhdyBhc3NlcnRpb24gb3BlcmFuZHMgZXh0cmFjdGVkIGZyb20gYSBjYWxsIGV4cHJlc3Npb24uICovXHJcbmludGVyZmFjZSBBc3NlcnRpb25PcGVyYW5kcyB7XHJcbiAgLyoqIEV4cHJlc3Npb24gdXNlZCBhcyB0aGUgYWN0dWFsIG9wZXJhbmQuICovXHJcbiAgYWN0dWFsOiBFU1RyZWUuRXhwcmVzc2lvbiB8IHVuZGVmaW5lZDtcclxuICAvKiogRXhwcmVzc2lvbiB1c2VkIGFzIHRoZSBleHBlY3RlZCBvcGVyYW5kLiAqL1xyXG4gIGV4cGVjdGVkOiBFU1RyZWUuRXhwcmVzc2lvbiB8IHVuZGVmaW5lZDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldHMgYXNzZXJ0IG9wZXJhbmRzLlxyXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBJbnB1dCBleHByZXNzaW9uIHZhbHVlLlxyXG4gKiBAcmV0dXJucyBSZXR1cm4gdmFsdWUgb3V0cHV0LlxyXG4gKiBAZXhhbXBsZVxyXG4gKiBgYGB0eXBlc2NyaXB0XHJcbiAqIGdldEFzc2VydE9wZXJhbmRzKGV4cHJlc3Npb24pO1xyXG4gKiBgYGBcclxuICovXHJcbmZ1bmN0aW9uIGdldEFzc2VydE9wZXJhbmRzKFxyXG4gIGV4cHJlc3Npb246IEVTVHJlZS5DYWxsRXhwcmVzc2lvbixcclxuKTogQXNzZXJ0aW9uT3BlcmFuZHMgfCB1bmRlZmluZWQge1xyXG4gIGlmIChcclxuICAgIGV4cHJlc3Npb24uY2FsbGVlLnR5cGUgPT09IFwiTWVtYmVyRXhwcmVzc2lvblwiICYmXHJcbiAgICBleHByZXNzaW9uLmNhbGxlZS5vYmplY3QudHlwZSA9PT0gXCJJZGVudGlmaWVyXCIgJiZcclxuICAgIGV4cHJlc3Npb24uY2FsbGVlLm9iamVjdC5uYW1lID09PSBcImFzc2VydFwiXHJcbiAgKSB7XHJcbiAgICBjb25zdCBbYWN0dWFsLCBleHBlY3RlZF0gPSBleHByZXNzaW9uLmFyZ3VtZW50cztcclxuICAgIGlmIChcclxuICAgICAgYWN0dWFsPy50eXBlICE9PSBcIlNwcmVhZEVsZW1lbnRcIiAmJlxyXG4gICAgICBleHBlY3RlZD8udHlwZSAhPT0gXCJTcHJlYWRFbGVtZW50XCJcclxuICAgICkge1xyXG4gICAgICByZXR1cm4geyBhY3R1YWwsIGV4cGVjdGVkIH07XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiB2b2lkIDA7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXRzIGV4cGVjdCBvcGVyYW5kcy5cclxuICogQHBhcmFtIGV4cHJlc3Npb24gSW5wdXQgZXhwcmVzc2lvbiB2YWx1ZS5cclxuICogQHJldHVybnMgUmV0dXJuIHZhbHVlIG91dHB1dC5cclxuICogQGV4YW1wbGVcclxuICogYGBgdHlwZXNjcmlwdFxyXG4gKiBnZXRFeHBlY3RPcGVyYW5kcyhleHByZXNzaW9uKTtcclxuICogYGBgXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRFeHBlY3RPcGVyYW5kcyhcclxuICBleHByZXNzaW9uOiBFU1RyZWUuQ2FsbEV4cHJlc3Npb24sXHJcbik6IEFzc2VydGlvbk9wZXJhbmRzIHwgdW5kZWZpbmVkIHtcclxuICBpZiAoXHJcbiAgICBleHByZXNzaW9uLmNhbGxlZS50eXBlID09PSBcIklkZW50aWZpZXJcIiAmJlxyXG4gICAgZXhwcmVzc2lvbi5jYWxsZWUubmFtZSA9PT0gXCJleHBlY3RcIlxyXG4gICkge1xyXG4gICAgY29uc3QgW2FjdHVhbF0gPSBleHByZXNzaW9uLmFyZ3VtZW50cztcclxuICAgIHJldHVybiBhY3R1YWw/LnR5cGUgPT09IFwiU3ByZWFkRWxlbWVudFwiXHJcbiAgICAgID8geyBhY3R1YWw6IHZvaWQgMCwgZXhwZWN0ZWQ6IHZvaWQgMCB9XHJcbiAgICAgIDogeyBhY3R1YWwsIGV4cGVjdGVkOiB2b2lkIDAgfTtcclxuICB9XHJcblxyXG4gIGlmIChcclxuICAgIGV4cHJlc3Npb24uY2FsbGVlLnR5cGUgPT09IFwiTWVtYmVyRXhwcmVzc2lvblwiICYmXHJcbiAgICBleHByZXNzaW9uLmNhbGxlZS5vYmplY3QudHlwZSA9PT0gXCJDYWxsRXhwcmVzc2lvblwiXHJcbiAgKSB7XHJcbiAgICBjb25zdCBuZXN0ZWRPcGVyYW5kcyA9IGdldEV4cGVjdE9wZXJhbmRzKGV4cHJlc3Npb24uY2FsbGVlLm9iamVjdCk7XHJcbiAgICBpZiAobmVzdGVkT3BlcmFuZHMgPT09IHZvaWQgMCkge1xyXG4gICAgICByZXR1cm4gdm9pZCAwO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IFtleHBlY3RlZF0gPSBleHByZXNzaW9uLmFyZ3VtZW50cztcclxuXHJcbiAgICByZXR1cm4gZXhwZWN0ZWQ/LnR5cGUgPT09IFwiU3ByZWFkRWxlbWVudFwiXHJcbiAgICAgID8gbmVzdGVkT3BlcmFuZHNcclxuICAgICAgOiB7IGFjdHVhbDogbmVzdGVkT3BlcmFuZHMuYWN0dWFsLCBleHBlY3RlZCB9O1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHZvaWQgMDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldHMgYW4gaWRlbnRpZmllciBuYW1lLlxyXG4gKiBAcGFyYW0gZXhwcmVzc2lvbiBJbnB1dCBleHByZXNzaW9uIHZhbHVlLlxyXG4gKiBAcmV0dXJucyBSZXR1cm4gdmFsdWUgb3V0cHV0LlxyXG4gKiBAZXhhbXBsZVxyXG4gKiBgYGB0eXBlc2NyaXB0XHJcbiAqIGdldElkZW50aWZpZXJOYW1lKGV4cHJlc3Npb24pO1xyXG4gKiBgYGBcclxuICovXHJcbmZ1bmN0aW9uIGdldElkZW50aWZpZXJOYW1lKFxyXG4gIGV4cHJlc3Npb246IEVTVHJlZS5FeHByZXNzaW9uIHwgdW5kZWZpbmVkLFxyXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xyXG4gIHJldHVybiBleHByZXNzaW9uPy50eXBlID09PSBcIklkZW50aWZpZXJcIiA/IGV4cHJlc3Npb24ubmFtZSA6IHZvaWQgMDtcclxufVxyXG5cclxuLyoqXHJcbiAqIENoZWNrcyB3aGV0aGVyIGFuIGFzc2VydGlvbiBldmFsdWF0ZXMgdGhlIGFjdHVhbCBvcGVyYW5kIGlubGluZS5cclxuICogQHBhcmFtIGV4cHJlc3Npb24gQXNzZXJ0aW9uIGNhbGwgZXhwcmVzc2lvbiB0byBpbnNwZWN0LlxyXG4gKiBAcGFyYW0gaXNBY3Rpb25FeHByZXNzaW9uIFByZWRpY2F0ZSB0aGF0IGlkZW50aWZpZXMgYWN0aW9uLWxpa2UgZXhwcmVzc2lvbnMuXHJcbiAqIEByZXR1cm5zIFRydWUgd2hlbiB0aGUgYXNzZXJ0aW9uIGFjdHVhbCBvcGVyYW5kIHBlcmZvcm1zIGFjdGlvbi1saWtlIHdvcmsuXHJcbiAqIEBleGFtcGxlXHJcbiAqIGBgYHR5cGVzY3JpcHRcclxuICogY29uc3QgYWN0dWFsID0gaGFzRXZhbHVhdGVkQXNzZXJ0aW9uQWN0dWFsKGV4cHJlc3Npb24sICgpID0+IHRydWUpO1xyXG4gKiB2b2lkIGFjdHVhbDtcclxuICogYGBgXHJcbiAqL1xyXG5mdW5jdGlvbiBoYXNFdmFsdWF0ZWRBc3NlcnRpb25BY3R1YWwoXHJcbiAgZXhwcmVzc2lvbjogRVNUcmVlLkNhbGxFeHByZXNzaW9uLFxyXG4gIGlzQWN0aW9uRXhwcmVzc2lvbjogKGV4cHJlc3Npb246IEVTVHJlZS5FeHByZXNzaW9uIHwgdW5kZWZpbmVkKSA9PiBib29sZWFuLFxyXG4pOiBib29sZWFuIHtcclxuICBjb25zdCBvcGVyYW5kcyA9XHJcbiAgICBnZXRFeHBlY3RPcGVyYW5kcyhleHByZXNzaW9uKSA/PyBnZXRBc3NlcnRPcGVyYW5kcyhleHByZXNzaW9uKTtcclxuXHJcbiAgcmV0dXJuIG9wZXJhbmRzICE9PSB2b2lkIDAgJiYgaXNBY3Rpb25FeHByZXNzaW9uKG9wZXJhbmRzLmFjdHVhbCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVja3MgZm9yIGFzc2VydGlvbiBjYWxscy5cclxuICogQHBhcmFtIG5vZGUgSW5wdXQgbm9kZSB2YWx1ZS5cclxuICogQHJldHVybnMgUmV0dXJuIHZhbHVlIG91dHB1dC5cclxuICogQGV4YW1wbGVcclxuICogYGBgdHlwZXNjcmlwdFxyXG4gKiBpc0Fzc2VydGlvbkNhbGwobm9kZSk7XHJcbiAqIGBgYFxyXG4gKi9cclxuZnVuY3Rpb24gaXNBc3NlcnRpb25DYWxsKG5vZGU6IEVTVHJlZS5DYWxsRXhwcmVzc2lvbik6IGJvb2xlYW4ge1xyXG4gIGlmIChub2RlLmNhbGxlZS50eXBlID09PSBcIklkZW50aWZpZXJcIikge1xyXG4gICAgcmV0dXJuIG5vZGUuY2FsbGVlLm5hbWUgPT09IFwiZXhwZWN0XCIgfHwgbm9kZS5jYWxsZWUubmFtZSA9PT0gXCJhc3NlcnRcIjtcclxuICB9XHJcblxyXG4gIGlmIChub2RlLmNhbGxlZS50eXBlICE9PSBcIk1lbWJlckV4cHJlc3Npb25cIikge1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgaWYgKFxyXG4gICAgbm9kZS5jYWxsZWUub2JqZWN0LnR5cGUgPT09IFwiSWRlbnRpZmllclwiICYmXHJcbiAgICBub2RlLmNhbGxlZS5vYmplY3QubmFtZSA9PT0gXCJhc3NlcnRcIlxyXG4gICkge1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gKFxyXG4gICAgbm9kZS5jYWxsZWUub2JqZWN0LnR5cGUgPT09IFwiQ2FsbEV4cHJlc3Npb25cIiAmJlxyXG4gICAgaXNBc3NlcnRpb25DYWxsKG5vZGUuY2FsbGVlLm9iamVjdClcclxuICApO1xyXG59XHJcblxyXG4vKiogQ29tcGFuaW9uIG1hcmtlciBmb3IgdGVzdCBpc29sYXRpb24uICovXHJcbmNvbnN0IGFuYWx5emVyQXNzZXJ0aW9uc09wZXJhbmRzQ29tcGFuaW9uID0gdHJ1ZSBhcyBjb25zdDtcclxuXHJcbmV4cG9ydCB7XHJcbiAgYW5hbHl6ZXJBc3NlcnRpb25zT3BlcmFuZHNDb21wYW5pb24sXHJcbiAgZ2V0QXNzZXJ0T3BlcmFuZHMsXHJcbiAgZ2V0RXhwZWN0T3BlcmFuZHMsXHJcbiAgZ2V0SWRlbnRpZmllck5hbWUsXHJcbiAgaGFzRXZhbHVhdGVkQXNzZXJ0aW9uQWN0dWFsLFxyXG4gIGlzQXNzZXJ0aW9uQ2FsbCxcclxufTtcclxuIl19
|
|
@@ -1,75 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
*/
|
|
12
|
-
declare
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
* @param statement Input statement value.
|
|
16
|
-
* @returns Return value output.
|
|
17
|
-
* @example
|
|
18
|
-
* ```typescript
|
|
19
|
-
* hasAwait(statement);
|
|
20
|
-
* ```
|
|
21
|
-
*/
|
|
22
|
-
declare function hasAwait(statement: ESTree.Statement): boolean;
|
|
23
|
-
/**
|
|
24
|
-
* Checks for blank lines before comments.
|
|
25
|
-
* @param sourceText Input sourceText value.
|
|
26
|
-
* @param comment Input comment value.
|
|
27
|
-
* @returns Return value output.
|
|
28
|
-
* @example
|
|
29
|
-
* ```typescript
|
|
30
|
-
* hasBlankLineBeforeComment(sourceText, comment);
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
declare function hasBlankLineBeforeComment(sourceText: string, comment: SourceComment): boolean;
|
|
34
|
-
/**
|
|
35
|
-
* Checks for capturable Act results.
|
|
36
|
-
* @param statement Input statement value.
|
|
37
|
-
* @returns Return value output.
|
|
38
|
-
* @example
|
|
39
|
-
* ```typescript
|
|
40
|
-
* hasCapturableActResult(statement);
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
declare function hasCapturableActResult(statement: ESTree.Statement): boolean;
|
|
44
|
-
/**
|
|
45
|
-
* Checks for mutation.
|
|
46
|
-
* @param statement Input statement value.
|
|
47
|
-
* @returns Return value output.
|
|
48
|
-
* @example
|
|
49
|
-
* ```typescript
|
|
50
|
-
* hasMutation(statement);
|
|
51
|
-
* ```
|
|
52
|
-
*/
|
|
53
|
-
declare function hasMutation(statement: ESTree.Statement): boolean;
|
|
54
|
-
/**
|
|
55
|
-
* Checks for meaningful Act statements.
|
|
56
|
-
* @param statement Input statement value.
|
|
57
|
-
* @returns Return value output.
|
|
58
|
-
* @example
|
|
59
|
-
* ```typescript
|
|
60
|
-
* isMeaningfulActStatement(statement);
|
|
61
|
-
* ```
|
|
62
|
-
*/
|
|
63
|
-
declare function isMeaningfulActStatement(statement: ESTree.Statement): boolean;
|
|
64
|
-
/**
|
|
65
|
-
* Checks for setup-like statements.
|
|
66
|
-
* @param statement Input statement value.
|
|
67
|
-
* @returns Return value output.
|
|
68
|
-
* @example
|
|
69
|
-
* ```typescript
|
|
70
|
-
* isSetupLikeStatement(statement);
|
|
71
|
-
* ```
|
|
72
|
-
*/
|
|
73
|
-
declare function isSetupLikeStatement(statement: ESTree.Statement): boolean;
|
|
1
|
+
/** Checks whether a statement contains any async or await logic. */
|
|
2
|
+
declare const hasAsyncLogic: (statement: import("estree").Statement) => boolean;
|
|
3
|
+
/** Checks whether a node contains an `await` expression. */
|
|
4
|
+
declare const hasAwait: (statement: import("estree").Statement) => boolean;
|
|
5
|
+
/** Checks whether there is a blank line immediately before a comment node. */
|
|
6
|
+
declare const hasBlankLineBeforeComment: (sourceText: string, comment: import("estree").Comment) => boolean;
|
|
7
|
+
/** Checks whether an Act statement produces a result worth capturing. */
|
|
8
|
+
declare const hasCapturableActResult: (statement: import("estree").Statement) => boolean;
|
|
9
|
+
/** Checks whether a statement performs an observable state mutation. */
|
|
10
|
+
declare const hasMutation: (statement: import("estree").Statement) => boolean;
|
|
11
|
+
/** Checks whether a statement is a meaningful Act step (not setup or assertion). */
|
|
12
|
+
declare const isMeaningfulActStatement: (statement: import("estree").Statement) => boolean;
|
|
13
|
+
/** Checks whether a statement looks like an Arrange-phase setup step. */
|
|
14
|
+
declare const isSetupLikeStatement: (statement: import("estree").Statement) => boolean;
|
|
74
15
|
export { hasAsyncLogic, hasAwait, hasBlankLineBeforeComment, hasCapturableActResult, hasMutation, isMeaningfulActStatement, isSetupLikeStatement, };
|
|
75
16
|
//# sourceMappingURL=analyzer.classification.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.classification.d.ts","sourceRoot":"","sources":["../../../../src/domain/testing/aaa/analyzer.classification.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"analyzer.classification.d.ts","sourceRoot":"","sources":["../../../../src/domain/testing/aaa/analyzer.classification.ts"],"names":[],"mappings":"AA2BA,oEAAoE;AACpE,QAAA,MAAM,aAAa,oDAAuC,CAAC;AAE3D,4DAA4D;AAC5D,QAAA,MAAM,QAAQ,oDAAkC,CAAC;AAEjD,8EAA8E;AAC9E,QAAA,MAAM,yBAAyB,oEAE9B,CAAC;AAEF,yEAAyE;AACzE,QAAA,MAAM,sBAAsB,oDAAgD,CAAC;AAE7E,wEAAwE;AACxE,QAAA,MAAM,WAAW,oDAAqC,CAAC;AAEvD,oFAAoF;AACpF,QAAA,MAAM,wBAAwB,oDAE7B,CAAC;AAEF,yEAAyE;AACzE,QAAA,MAAM,oBAAoB,oDAA8C,CAAC;AAEzE,OAAO,EACL,aAAa,EACb,QAAQ,EACR,yBAAyB,EACzB,sBAAsB,EACtB,WAAW,EACX,wBAAwB,EACxB,oBAAoB,GACrB,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type * as ESTree from "estree";
|
|
2
|
+
import type { SourceComment } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Checks for async logic.
|
|
5
|
+
* @param statement Input statement value.
|
|
6
|
+
* @returns Return value output.
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* hasAsyncLogic(statement);
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
declare function hasAsyncLogic(statement: ESTree.Statement): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Checks for await usage.
|
|
15
|
+
* @param statement Input statement value.
|
|
16
|
+
* @returns Return value output.
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* hasAwait(statement);
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare function hasAwait(statement: ESTree.Statement): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Checks for blank lines before comments.
|
|
25
|
+
* @param sourceText Input sourceText value.
|
|
26
|
+
* @param comment Input comment value.
|
|
27
|
+
* @returns Return value output.
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* hasBlankLineBeforeComment(sourceText, comment);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
declare function hasBlankLineBeforeComment(sourceText: string, comment: SourceComment): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Checks for capturable Act results.
|
|
36
|
+
* @param statement Input statement value.
|
|
37
|
+
* @returns Return value output.
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* hasCapturableActResult(statement);
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
declare function hasCapturableActResult(statement: ESTree.Statement): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Checks for mutation.
|
|
46
|
+
* @param statement Input statement value.
|
|
47
|
+
* @returns Return value output.
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* hasMutation(statement);
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
declare function hasMutation(statement: ESTree.Statement): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Checks for meaningful Act statements.
|
|
56
|
+
* @param statement Input statement value.
|
|
57
|
+
* @returns Return value output.
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* isMeaningfulActStatement(statement);
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
declare function isMeaningfulActStatement(statement: ESTree.Statement): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Checks for setup-like statements.
|
|
66
|
+
* @param statement Input statement value.
|
|
67
|
+
* @returns Return value output.
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* isSetupLikeStatement(statement);
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
declare function isSetupLikeStatement(statement: ESTree.Statement): boolean;
|
|
74
|
+
/** Companion marker for test isolation. */
|
|
75
|
+
declare const analyzerClassificationHelpersCompanion: true;
|
|
76
|
+
export { analyzerClassificationHelpersCompanion, hasAsyncLogic, hasAwait, hasBlankLineBeforeComment, hasCapturableActResult, hasMutation, isMeaningfulActStatement, isSetupLikeStatement, };
|
|
77
|
+
//# sourceMappingURL=analyzer.classification.helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.classification.helpers.d.ts","sourceRoot":"","sources":["../../../../src/domain/testing/aaa/analyzer.classification.helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAuB7C;;;;;;;;GAQG;AACH,iBAAS,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,OAAO,CAwB3D;AAED;;;;;;;;GAQG;AACH,iBAAS,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,OAAO,CAQtD;AAED;;;;;;;;;GASG;AACH,iBAAS,yBAAyB,CAChC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,aAAa,GACrB,OAAO,CAOT;AAED;;;;;;;;GAQG;AACH,iBAAS,sBAAsB,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,OAAO,CAepE;AAED;;;;;;;;GAQG;AACH,iBAAS,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,OAAO,CAuBzD;AAED;;;;;;;;GAQG;AACH,iBAAS,wBAAwB,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,OAAO,CAUtE;AAwBD;;;;;;;;GAQG;AACH,iBAAS,oBAAoB,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,GAAG,OAAO,CAYlE;AA8BD,2CAA2C;AAC3C,QAAA,MAAM,sCAAsC,EAAG,IAAa,CAAC;AAE7D,OAAO,EACL,sCAAsC,EACtC,aAAa,EACb,QAAQ,EACR,yBAAyB,EACzB,sBAAsB,EACtB,WAAW,EACX,wBAAwB,EACxB,oBAAoB,GACrB,CAAC"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { getStatementExpression, hasAssertion, isActionExpression, unwrapExpression, } from "./analyzer.assertions.js";
|
|
2
|
+
import { visitStatementWithoutDeferredBodies } from "./analyzer.classification.traversal.js";
|
|
3
|
+
import { arrayMutationMethods, getExpressionName, getInvokedName, isCallableExpression, isLocatedComment, isUtilityConstructor, isUtilityNamedCall, isUtilityNamespaceCall, isVoidLikeMethodName, visitNode, voidLikeMethodNames, } from "./analyzer.super.js";
|
|
4
|
+
/**
|
|
5
|
+
* Checks for async logic.
|
|
6
|
+
* @param statement Input statement value.
|
|
7
|
+
* @returns Return value output.
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* hasAsyncLogic(statement);
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
function hasAsyncLogic(statement) {
|
|
14
|
+
let foundAsyncLogic = false;
|
|
15
|
+
visitStatementWithoutDeferredBodies(statement, (node) => {
|
|
16
|
+
if (node.type === "AwaitExpression") {
|
|
17
|
+
foundAsyncLogic = true;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (node.type === "CallExpression" &&
|
|
21
|
+
node.callee.type === "MemberExpression" &&
|
|
22
|
+
node.callee.property.type === "Identifier" &&
|
|
23
|
+
["catch", "finally", "then"].includes(node.callee.property.name)) {
|
|
24
|
+
foundAsyncLogic = true;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (node.type === "NewExpression" &&
|
|
28
|
+
getExpressionName(node.callee) === "Promise") {
|
|
29
|
+
foundAsyncLogic = true;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return foundAsyncLogic;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Checks for await usage.
|
|
36
|
+
* @param statement Input statement value.
|
|
37
|
+
* @returns Return value output.
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* hasAwait(statement);
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
function hasAwait(statement) {
|
|
44
|
+
let foundAwait = false;
|
|
45
|
+
visitStatementWithoutDeferredBodies(statement, (node) => {
|
|
46
|
+
if (node.type === "AwaitExpression") {
|
|
47
|
+
foundAwait = true;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return foundAwait;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Checks for blank lines before comments.
|
|
54
|
+
* @param sourceText Input sourceText value.
|
|
55
|
+
* @param comment Input comment value.
|
|
56
|
+
* @returns Return value output.
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* hasBlankLineBeforeComment(sourceText, comment);
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
function hasBlankLineBeforeComment(sourceText, comment) {
|
|
63
|
+
if (!isLocatedComment(comment)) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
const lines = sourceText.split(/\r\n|\n/u);
|
|
67
|
+
const previousLine = lines[comment.loc.start.line - 2];
|
|
68
|
+
return previousLine === void 0 || previousLine.trim().length === 0;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Checks for capturable Act results.
|
|
72
|
+
* @param statement Input statement value.
|
|
73
|
+
* @returns Return value output.
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* hasCapturableActResult(statement);
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
function hasCapturableActResult(statement) {
|
|
80
|
+
if (statement.type !== "ExpressionStatement") {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
const expression = unwrapExpression(statement.expression);
|
|
84
|
+
if (!isActionExpression(expression) || isUtilityLikeExpression(expression)) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
const calleeName = getInvokedName(expression);
|
|
88
|
+
return (calleeName === void 0 ||
|
|
89
|
+
(!voidLikeMethodNames.has(calleeName) && !isVoidLikeMethodName(calleeName)));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Checks for mutation.
|
|
93
|
+
* @param statement Input statement value.
|
|
94
|
+
* @returns Return value output.
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* hasMutation(statement);
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
function hasMutation(statement) {
|
|
101
|
+
let foundMutation = false;
|
|
102
|
+
visitNode(statement, (node) => {
|
|
103
|
+
if (node.type === "AssignmentExpression" ||
|
|
104
|
+
node.type === "UpdateExpression" ||
|
|
105
|
+
node.type === "UnaryExpression") {
|
|
106
|
+
if (node.type !== "UnaryExpression" || node.operator === "delete") {
|
|
107
|
+
foundMutation = true;
|
|
108
|
+
}
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (node.type === "CallExpression" &&
|
|
112
|
+
node.callee.type === "MemberExpression" &&
|
|
113
|
+
node.callee.property.type === "Identifier" &&
|
|
114
|
+
arrayMutationMethods.has(node.callee.property.name)) {
|
|
115
|
+
foundMutation = true;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
return foundMutation;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Checks for meaningful Act statements.
|
|
122
|
+
* @param statement Input statement value.
|
|
123
|
+
* @returns Return value output.
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* isMeaningfulActStatement(statement);
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
function isMeaningfulActStatement(statement) {
|
|
130
|
+
const expression = getStatementExpression(statement);
|
|
131
|
+
if (expression === void 0) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
return (isActionExpression(expression) &&
|
|
135
|
+
!isUtilityLikeExpression(expression) &&
|
|
136
|
+
!hasAssertion(statement));
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Checks for rule create calls.
|
|
140
|
+
* @param expression Input expression value.
|
|
141
|
+
* @returns Return value output.
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* isRuleCreateInvocation(expression);
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
function isRuleCreateInvocation(expression) {
|
|
148
|
+
return (expression.type === "CallExpression" &&
|
|
149
|
+
expression.callee.type === "MemberExpression" &&
|
|
150
|
+
expression.callee.object.type === "Identifier" &&
|
|
151
|
+
expression.callee.property.type === "Identifier" &&
|
|
152
|
+
expression.callee.property.name === "create" &&
|
|
153
|
+
expression.callee.object.name.endsWith("Rule"));
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Checks for setup-like statements.
|
|
157
|
+
* @param statement Input statement value.
|
|
158
|
+
* @returns Return value output.
|
|
159
|
+
* @example
|
|
160
|
+
* ```typescript
|
|
161
|
+
* isSetupLikeStatement(statement);
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
function isSetupLikeStatement(statement) {
|
|
165
|
+
if (statement.type === "VariableDeclaration") {
|
|
166
|
+
return statement.declarations.every((declaration) => {
|
|
167
|
+
if (declaration.init === null) {
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
const init = unwrapExpression(declaration.init);
|
|
171
|
+
return !isActionExpression(init) || isUtilityLikeExpression(init);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const expression = getStatementExpression(statement);
|
|
175
|
+
return expression !== void 0 && isUtilityLikeExpression(expression);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Checks for utility-like expressions.
|
|
179
|
+
* @param expression Input expression value.
|
|
180
|
+
* @returns Return value output.
|
|
181
|
+
* @example
|
|
182
|
+
* ```typescript
|
|
183
|
+
* isUtilityLikeExpression(expression);
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
function isUtilityLikeExpression(expression) {
|
|
187
|
+
const unwrappedExpression = unwrapExpression(expression);
|
|
188
|
+
if (!isCallableExpression(unwrappedExpression)) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
const calleeName = getExpressionName(unwrappedExpression.callee);
|
|
192
|
+
if (calleeName === void 0) {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
return (!isRuleCreateInvocation(unwrappedExpression) &&
|
|
196
|
+
(isUtilityConstructor(unwrappedExpression, calleeName) ||
|
|
197
|
+
isUtilityNamedCall(calleeName) ||
|
|
198
|
+
isUtilityNamespaceCall(unwrappedExpression)));
|
|
199
|
+
}
|
|
200
|
+
/** Companion marker for test isolation. */
|
|
201
|
+
const analyzerClassificationHelpersCompanion = true;
|
|
202
|
+
export { analyzerClassificationHelpersCompanion, hasAsyncLogic, hasAwait, hasBlankLineBeforeComment, hasCapturableActResult, hasMutation, isMeaningfulActStatement, isSetupLikeStatement, };
|
|
203
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5hbHl6ZXIuY2xhc3NpZmljYXRpb24uaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kb21haW4vdGVzdGluZy9hYWEvYW5hbHl6ZXIuY2xhc3NpZmljYXRpb24uaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLFlBQVksRUFDWixrQkFBa0IsRUFDbEIsZ0JBQWdCLEdBQ2pCLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUFFLG1DQUFtQyxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDMUYsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixpQkFBaUIsRUFDakIsY0FBYyxFQUNkLG9CQUFvQixFQUNwQixnQkFBZ0IsRUFDaEIsb0JBQW9CLEVBQ3BCLGtCQUFrQixFQUNsQixzQkFBc0IsRUFDdEIsb0JBQW9CLEVBQ3BCLFNBQVMsRUFDVCxtQkFBbUIsR0FDcEIsTUFBTSxrQkFBa0IsQ0FBQztBQUUxQjs7Ozs7Ozs7R0FRRztBQUNILFNBQVMsYUFBYSxDQUFDLFNBQTJCO0lBQ2hELElBQUksZUFBZSxHQUFHLEtBQUssQ0FBQztJQUM1QixtQ0FBbUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRTtRQUN0RCxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssaUJBQWlCLEVBQUUsQ0FBQztZQUNwQyxlQUFlLEdBQUcsSUFBSSxDQUFDO1lBQ3ZCLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFDRSxJQUFJLENBQUMsSUFBSSxLQUFLLGdCQUFnQjtZQUM5QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxrQkFBa0I7WUFDdkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLFlBQVk7WUFDMUMsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFD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Q3BELGtCQUFrQixDQUFDLFVBQVUsQ0FBQztZQUM5QixzQkFBc0IsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQy9DLENBQUM7QUFDSixDQUFDO0FBRUQsMkNBQTJDO0FBQzNDLE1BQU0sc0NBQXNDLEdBQUcsSUFBYSxDQUFDO0FBRTdELE9BQU8sRUFDTCxzQ0FBc0MsRUFDdEMsYUFBYSxFQUNiLFFBQVEsRUFDUix5QkFBeUIsRUFDekIsc0JBQXNCLEVBQ3RCLFdBQVcsRUFDWCx3QkFBd0IsRUFDeEIsb0JBQW9CLEdBQ3JCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSAqIGFzIEVTVHJlZSBmcm9tIFwiZXN0cmVlXCI7XHJcblxyXG5pbXBvcnQgdHlwZSB7IFNvdXJjZUNvbW1lbnQgfSBmcm9tIFwiLi90eXBlc1wiO1xyXG5cclxuaW1wb3J0IHtcclxuICBnZXRTdGF0ZW1lbnRFeHByZXNzaW9uLFxyXG4gIGhhc0Fzc2VydGlvbixcclxuICBpc0FjdGlvbkV4cHJlc3Npb24sXHJcbiAgdW53cmFwRXhwcmVzc2lvbixcclxufSBmcm9tIFwiLi9hbmFseXplci5hc3NlcnRpb25zXCI7XHJcbmltcG9ydCB7IHZpc2l0U3RhdGVtZW50V2l0aG91dERlZmVycmVkQm9kaWVzIH0gZnJvbSBcIi4vYW5hbHl6ZXIuY2xhc3NpZmljYXRpb24udHJhdmVyc2FsXCI7XHJcbmltcG9ydCB7XHJcbiAgYXJyYXlNdXRhdGlvbk1ldGhvZHMsXHJcbiAgZ2V0RXhwcmVzc2lvbk5hbWUsXHJcbiAgZ2V0SW52b2tlZE5hbWUsXHJcbiAgaXNDYWxsYWJsZUV4cHJlc3Npb24sXHJcbiAgaXNMb2NhdGVkQ29tbWVudCxcclxuICBpc1V0aWxpdHlDb25zdHJ1Y3RvcixcclxuICBpc1V0aWxpdHlOYW1lZENhbGwsXHJcbiAgaXNVdGlsaXR5TmFtZXNwYWNlQ2FsbCxcclxuICBpc1ZvaWRMaWtlTWV0aG9kTmFtZSxcclxuICB2aXNpdE5vZGUsXHJcbiAgdm9pZExpa2VNZXRob2ROYW1lcyxcclxufSBmcm9tIFwiLi9hbmFseXplci5zdXBlclwiO1xyXG5cclxuLyoqXHJcbiAqIENoZWNrcyBmb3IgYXN5bmMgbG9naWMuXHJcbiAqIEBwYXJhbSBzdGF0ZW1lbnQgSW5wdXQgc3RhdGVtZW50IHZhbHVlLlxyXG4gKiBAcmV0dXJucyBSZXR1cm4gdmFsdWUgb3V0cHV0LlxyXG4gKiBAZXhhbXBsZVxyXG4gKiBgYGB0eXBlc2NyaXB0XHJcbiAqIGhhc0FzeW5jTG9naWMoc3RhdGVtZW50KTtcclxuICogYGBgXHJcbiAqL1xyXG5mdW5jdGlvbiBoYXNBc3luY0xvZ2ljKHN0YXRlbWVudDogRVNUcmVlLlN0YXRlbWVudCk6IGJvb2xlYW4ge1xyXG4gIGxldCBmb3VuZEFzeW5jTG9naWMgPSBmYWxzZTtcclxuICB2aXNpdFN0YXRlbWVudFdpdGhvdXREZWZlcnJlZEJvZGllcyhzdGF0ZW1lbnQsIChub2RlKSA9PiB7XHJcbiAgICBpZiAobm9kZS50eXBlID09PSBcIkF3YWl0RXhwcmVzc2lvblwiKSB7XHJcbiAgICAgIGZvdW5kQXN5bmNMb2dpYyA9IHRydWU7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmIChcclxuICAgICAgbm9kZS50eXBlID09PSBcIkNhbGxFeHByZXNzaW9uXCIgJiZcclxuICAgICAgbm9kZS5jYWxsZWUudHlwZSA9PT0gXCJNZW1iZXJFeHByZXNzaW9uXCIgJiZcclxuICAgICAgbm9kZS5jYWxsZWUucHJvcGVydHkudHlwZSA9PT0gXCJJZGVudGlmaWVyXCIgJiZcclxuICAgICAgW1wiY2F0Y2hcIiwgXCJmaW5hbGx5XCIsIFwidGhlblwiXS5pbmNsdWRlcyhub2RlLmNhbGxlZS5wcm9wZXJ0eS5uYW1lKVxyXG4gICAgKSB7XHJcbiAgICAgIGZvdW5kQXN5bmNMb2dpYyA9IHRydWU7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmIChcclxuICAgICAgbm9kZS50eXBlID09PSBcIk5ld0V4cHJlc3Npb25cIiAmJlxyXG4gICAgICBnZXRFeHByZXNzaW9uTmFtZShub2RlLmNhbGxlZSkgPT09IFwiUHJvbWlzZVwiXHJcbiAgICApIHtcclxuICAgICAgZm91bmRBc3luY0xvZ2ljID0gdHJ1ZTtcclxuICAgIH1cclxuICB9KTtcclxuICByZXR1cm4gZm91bmRBc3luY0xvZ2ljO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGZvciBhd2FpdCB1c2FnZS5cclxuICogQHBhcmFtIHN0YXRlbWVudCBJbnB1dCBzdGF0ZW1lbnQgdmFsdWUuXHJcbiAqIEByZXR1cm5zIFJldHVybiB2YWx1ZSBvdXRwdXQuXHJcbiAqIEBleGFtcGxlXHJcbiAqIGBgYHR5cGVzY3JpcHRcclxuICogaGFzQXdhaXQoc3RhdGVtZW50KTtcclxuICogYGBgXHJcbiAqL1xyXG5mdW5jdGlvbiBoYXNBd2FpdChzdGF0ZW1lbnQ6IEVTVHJlZS5TdGF0ZW1lbnQpOiBib29sZWFuIHtcclxuICBsZXQgZm91bmRBd2FpdCA9IGZhbHNlO1xyXG4gIHZpc2l0U3RhdGVtZW50V2l0aG91dERlZmVycmVkQm9kaWVzKHN0YXRlbWVudCwgKG5vZGUpID0+IHtcclxuICAgIGlmIChub2RlLnR5cGUgPT09IFwiQXdhaXRFeHByZXNzaW9uXCIpIHtcclxuICAgICAgZm91bmRBd2FpdCA9IHRydWU7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgcmV0dXJuIGZvdW5kQXdhaXQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVja3MgZm9yIGJsYW5rIGxpbmVzIGJlZm9yZSBjb21tZW50cy5cclxuICogQHBhcmFtIHNvdXJjZVRleHQgSW5wdXQgc291cmNlVGV4dCB2YWx1ZS5cclxuICogQHBhcmFtIGNvbW1lbnQgSW5wdXQgY29tbWVudCB2YWx1ZS5cclxuICogQHJldHVybnMgUmV0dXJuIHZhbHVlIG91dHB1dC5cclxuICogQGV4YW1wbGVcclxuICogYGBgdHlwZXNjcmlwdFxyXG4gKiBoYXNCbGFua0xpbmVCZWZvcmVDb21tZW50KHNvdXJjZVRleHQsIGNvbW1lbnQpO1xyXG4gKiBgYGBcclxuICovXHJcbmZ1bmN0aW9uIGhhc0JsYW5rTGluZUJlZm9yZUNvbW1lbnQoXHJcbiAgc291cmNlVGV4dDogc3RyaW5nLFxyXG4gIGNvbW1lbnQ6IFNvdXJjZUNvbW1lbnQsXHJcbik6IGJvb2xlYW4ge1xyXG4gIGlmICghaXNMb2NhdGVkQ29tbWVudChjb21tZW50KSkge1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG4gIGNvbnN0IGxpbmVzID0gc291cmNlVGV4dC5zcGxpdCgvXFxyXFxufFxcbi91KTtcclxuICBjb25zdCBwcmV2aW91c0xpbmUgPSBsaW5lc1tjb21tZW50LmxvYy5zdGFydC5saW5lIC0gMl07XHJcbiAgcmV0dXJuIHByZXZpb3VzTGluZSA9PT0gdm9pZCAwIHx8IHByZXZpb3VzTGluZS50cmltKCkubGVuZ3RoID09PSAwO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGZvciBjYXB0dXJhYmxlIEFjdCByZXN1bHRzLlxyXG4gKiBAcGFyYW0gc3RhdGVtZW50IElucHV0IHN0YXRlbWVudCB2YWx1ZS5cclxuICogQHJldHVybnMgUmV0dXJuIHZhbHVlIG91dHB1dC5cclxuICogQGV4YW1wbGVcclxuICogYGBgdHlwZXNjcmlwdFxyXG4gKiBoYXNDYXB0dXJhYmxlQWN0UmVzdWx0KHN0YXRlbWVudCk7XHJcbiAqIGBgYFxyXG4gKi9cclxuZnVuY3Rpb24gaGFzQ2FwdHVyYWJsZUFjdFJlc3VsdChzdGF0ZW1lbnQ6IEVTVHJlZS5TdGF0ZW1lbnQpOiBib29sZWFuIHtcclxuICBpZiAoc3RhdGVtZW50LnR5cGUgIT09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiKSB7XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG4gIGNvbnN0IGV4cHJlc3Npb24gPSB1bndyYXBFeHByZXNzaW9uKHN0YXRlbWVudC5leHByZXNzaW9uKTtcclxuICBpZiAoIWlzQWN0aW9uRXhwcmVzc2lvbihleHByZXNzaW9uKSB8fCBpc1V0aWxpdHlMaWtlRXhwcmVzc2lvbihleHByZXNzaW9uKSkge1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuICBjb25zdCBjYWxsZWVOYW1lID0gZ2V0SW52b2tlZE5hbWUoXHJcbiAgICBleHByZXNzaW9uIGFzIEVTVHJlZS5DYWxsRXhwcmVzc2lvbiB8IEVTVHJlZS5OZXdFeHByZXNzaW9uLFxyXG4gICk7XHJcbiAgcmV0dXJuIChcclxuICAgIGNhbGxlZU5hbWUgPT09IHZvaWQgMCB8fFxyXG4gICAgKCF2b2lkTGlrZU1ldGhvZE5hbWVzLmhhcyhjYWxsZWVOYW1lKSAmJiAhaXNWb2lkTGlrZU1ldGhvZE5hbWUoY2FsbGVlTmFtZSkpXHJcbiAgKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENoZWNrcyBmb3IgbXV0YXRpb24uXHJcbiAqIEBwYXJhbSBzdGF0ZW1lbnQgSW5wdXQgc3RhdGVtZW50IHZhbHVlLlxyXG4gKiBAcmV0dXJucyBSZXR1cm4gdmFsdWUgb3V0cHV0LlxyXG4gKiBAZXhhbXBsZVxyXG4gKiBgYGB0eXBlc2NyaXB0XHJcbiAqIGhhc011dGF0aW9uKHN0YXRlbWVudCk7XHJcbiAqIGBgYFxyXG4gKi9cclxuZnVuY3Rpb24gaGFzTXV0YXRpb24oc3RhdGVtZW50OiBFU1RyZWUuU3RhdGVtZW50KTogYm9vbGVhbiB7XHJcbiAgbGV0IGZvdW5kTXV0YXRpb24gPSBmYWxzZTtcclxuICB2aXNpdE5vZGUoc3RhdGVtZW50LCAobm9kZSkgPT4ge1xyXG4gICAgaWYgKFxyXG4gICAgICBub2RlLnR5cGUgPT09IFwiQXNzaWdubWVudEV4cHJlc3Npb25cIiB8fFxyXG4gICAgICBub2RlLnR5cGUgPT09IFwiVXBkYXRlRXhwcmVzc2lvblwiIHx8XHJcbiAgICAgIG5vZGUudHlwZSA9PT0gXCJVbmFyeUV4cHJlc3Npb25cIlxyXG4gICAgKSB7XHJcbiAgICAgIGlmIChub2RlLnR5cGUgIT09IFwiVW5hcnlFeHByZXNzaW9uXCIgfHwgbm9kZS5vcGVyYXRvciA9PT0gXCJkZWxldGVcIikge1xyXG4gICAgICAgIGZvdW5kTXV0YXRpb24gPSB0cnVlO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmIChcclxuICAgICAgbm9kZS50eXBlID09PSBcIkNhbGxFeHByZXNzaW9uXCIgJiZcclxuICAgICAgbm9kZS5jYWxsZWUudHlwZSA9PT0gXCJNZW1iZXJFeHByZXNzaW9uXCIgJiZcclxuICAgICAgbm9kZS5jYWxsZWUucHJvcGVydHkudHlwZSA9PT0gXCJJZGVudGlmaWVyXCIgJiZcclxuICAgICAgYXJyYXlNdXRhdGlvbk1ldGhvZHMuaGFzKG5vZGUuY2FsbGVlLnByb3BlcnR5Lm5hbWUpXHJcbiAgICApIHtcclxuICAgICAgZm91bmRNdXRhdGlvbiA9IHRydWU7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgcmV0dXJuIGZvdW5kTXV0YXRpb247XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVja3MgZm9yIG1lYW5pbmdmdWwgQWN0IHN0YXRlbWVudHMuXHJcbiAqIEBwYXJhbSBzdGF0ZW1lbnQgSW5wdXQgc3RhdGVtZW50IHZhbHVlLlxyXG4gKiBAcmV0dXJucyBSZXR1cm4gdmFsdWUgb3V0cHV0LlxyXG4gKiBAZXhhbXBsZVxyXG4gKiBgYGB0eXBlc2NyaXB0XHJcbiAqIGlzTWVhbmluZ2Z1bEFjdFN0YXRlbWVudChzdGF0ZW1lbnQpO1xyXG4gKiBgYGBcclxuICovXHJcbmZ1bmN0aW9uIGlzTWVhbmluZ2Z1bEFjdFN0YXRlbWVudChzdGF0ZW1lbnQ6IEVTVHJlZS5TdGF0ZW1lbnQpOiBib29sZWFuIHtcclxuICBjb25zdCBleHByZXNzaW9uID0gZ2V0U3RhdGVtZW50RXhwcmVzc2lvbihzdGF0ZW1lbnQpO1xyXG4gIGlmIChleHByZXNzaW9uID09PSB2b2lkIDApIHtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcbiAgcmV0dXJuIChcclxuICAgIGlzQWN0aW9uRXhwcmVzc2lvbihleHByZXNzaW9uKSAmJlxyXG4gICAgIWlzVXRpbGl0eUxpa2VFeHByZXNzaW9uKGV4cHJlc3Npb24pICYmXHJcbiAgICAhaGFzQXNzZXJ0aW9uKHN0YXRlbWVudClcclxuICApO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGZvciBydWxlIGNyZWF0ZSBjYWxscy5cclxuICogQHBhcmFtIGV4cHJlc3Npb24gSW5wdXQgZXhwcmVzc2lvbiB2YWx1ZS5cclxuICogQHJldHVybnMgUmV0dXJuIHZhbHVlIG91dHB1dC5cclxuICogQGV4YW1wbGVcclxuICogYGBgdHlwZXNjcmlwdFxyXG4gKiBpc1J1bGVDcmVhdGVJbnZvY2F0aW9uKGV4cHJlc3Npb24pO1xyXG4gKiBgYGBcclxuICovXHJcbmZ1bmN0aW9uIGlzUnVsZUNyZWF0ZUludm9jYXRpb24oXHJcbiAgZXhwcmVzc2lvbjogRVNUcmVlLkNhbGxFeHByZXNzaW9uIHwgRVNUcmVlLk5ld0V4cHJlc3Npb24sXHJcbik6IGJvb2xlYW4ge1xyXG4gIHJldHVybiAoXHJcbiAgICBleHByZXNzaW9uLnR5cGUgPT09IFwiQ2FsbEV4cHJlc3Npb25cIiAmJlxyXG4gICAgZXhwcmVzc2lvbi5jYWxsZWUudHlwZSA9PT0gXCJNZW1iZXJFeHByZXNzaW9uXCIgJiZcclxuICAgIGV4cHJlc3Npb24uY2FsbGVlLm9iamVjdC50eXBlID09PSBcIklkZW50aWZpZXJcIiAmJlxyXG4gICAgZXhwcmVzc2lvbi5jYWxsZWUucHJvcGVydHkudHlwZSA9PT0gXCJJZGVudGlmaWVyXCIgJiZcclxuICAgIGV4cHJlc3Npb24uY2FsbGVlLnByb3BlcnR5Lm5hbWUgPT09IFwiY3JlYXRlXCIgJiZcclxuICAgIGV4cHJlc3Npb24uY2FsbGVlLm9iamVjdC5uYW1lLmVuZHNXaXRoKFwiUnVsZVwiKVxyXG4gICk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVja3MgZm9yIHNldHVwLWxpa2Ugc3RhdGVtZW50cy5cclxuICogQHBhcmFtIHN0YXRlbWVudCBJbnB1dCBzdGF0ZW1lbnQgdmFsdWUuXHJcbiAqIEByZXR1cm5zIFJldHVybiB2YWx1ZSBvdXRwdXQuXHJcbiAqIEBleGFtcGxlXHJcbiAqIGBgYHR5cGVzY3JpcHRcclxuICogaXNTZXR1cExpa2VTdGF0ZW1lbnQoc3RhdGVtZW50KTtcclxuICogYGBgXHJcbiAqL1xyXG5mdW5jdGlvbiBpc1NldHVwTGlrZVN0YXRlbWVudChzdGF0ZW1lbnQ6IEVTVHJlZS5TdGF0ZW1lbnQpOiBib29sZWFuIHtcclxuICBpZiAoc3RhdGVtZW50LnR5cGUgPT09IFwiVmFyaWFibGVEZWNsYXJhdGlvblwiKSB7XHJcbiAgICByZXR1cm4gc3RhdGVtZW50LmRlY2xhcmF0aW9ucy5ldmVyeSgoZGVjbGFyYXRpb24pID0+IHtcclxuICAgICAgaWYgKGRlY2xhcmF0aW9uLmluaXQgPT09IG51bGwpIHtcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBpbml0ID0gdW53cmFwRXhwcmVzc2lvbihkZWNsYXJhdGlvbi5pbml0KTtcclxuICAgICAgcmV0dXJuICFpc0FjdGlvbkV4cHJlc3Npb24oaW5pdCkgfHwgaXNVdGlsaXR5TGlrZUV4cHJlc3Npb24oaW5pdCk7XHJcbiAgICB9KTtcclxuICB9XHJcbiAgY29uc3QgZXhwcmVzc2lvbiA9IGdldFN0YXRlbWVudEV4cHJlc3Npb24oc3RhdGVtZW50KTtcclxuICByZXR1cm4gZXhwcmVzc2lvbiAhPT0gdm9pZCAwICYmIGlzVXRpbGl0eUxpa2VFeHByZXNzaW9uKGV4cHJlc3Npb24pO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGZvciB1dGlsaXR5LWxpa2UgZXhwcmVzc2lvbnMuXHJcbiAqIEBwYXJhbSBleHByZXNzaW9uIElucHV0IGV4cHJlc3Npb24gdmFsdWUuXHJcbiAqIEByZXR1cm5zIFJldHVybiB2YWx1ZSBvdXRwdXQuXHJcbiAqIEBleGFtcGxlXHJcbiAqIGBgYHR5cGVzY3JpcHRcclxuICogaXNVdGlsaXR5TGlrZUV4cHJlc3Npb24oZXhwcmVzc2lvbik7XHJcbiAqIGBgYFxyXG4gKi9cclxuZnVuY3Rpb24gaXNVdGlsaXR5TGlrZUV4cHJlc3Npb24oXHJcbiAgZXhwcmVzc2lvbjogRVNUcmVlLkV4cHJlc3Npb24gfCB1bmRlZmluZWQsXHJcbik6IGJvb2xlYW4ge1xyXG4gIGNvbnN0IHVud3JhcHBlZEV4cHJlc3Npb24gPSB1bndyYXBFeHByZXNzaW9uKGV4cHJlc3Npb24pO1xyXG4gIGlmICghaXNDYWxsYWJsZUV4cHJlc3Npb24odW53cmFwcGVkRXhwcmVzc2lvbikpIHtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcbiAgY29uc3QgY2FsbGVlTmFtZSA9IGdldEV4cHJlc3Npb25OYW1lKHVud3JhcHBlZEV4cHJlc3Npb24uY2FsbGVlKTtcclxuICBpZiAoY2FsbGVlTmFtZSA9PT0gdm9pZCAwKSB7XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG4gIHJldHVybiAoXHJcbiAgICAhaXNSdWxlQ3JlYXRlSW52b2NhdGlvbih1bndyYXBwZWRFeHByZXNzaW9uKSAmJlxyXG4gICAgKGlzVXRpbGl0eUNvbnN0cnVjdG9yKHVud3JhcHBlZEV4cHJlc3Npb24sIGNhbGxlZU5hbWUpIHx8XHJcbiAgICAgIGlzVXRpbGl0eU5hbWVkQ2FsbChjYWxsZWVOYW1lKSB8fFxyXG4gICAgICBpc1V0aWxpdHlOYW1lc3BhY2VDYWxsKHVud3JhcHBlZEV4cHJlc3Npb24pKVxyXG4gICk7XHJcbn1cclxuXHJcbi8qKiBDb21wYW5pb24gbWFya2VyIGZvciB0ZXN0IGlzb2xhdGlvbi4gKi9cclxuY29uc3QgYW5hbHl6ZXJDbGFzc2lmaWNhdGlvbkhlbHBlcnNDb21wYW5pb24gPSB0cnVlIGFzIGNvbnN0O1xyXG5cclxuZXhwb3J0IHtcclxuICBhbmFseXplckNsYXNzaWZpY2F0aW9uSGVscGVyc0NvbXBhbmlvbixcclxuICBoYXNBc3luY0xvZ2ljLFxyXG4gIGhhc0F3YWl0LFxyXG4gIGhhc0JsYW5rTGluZUJlZm9yZUNvbW1lbnQsXHJcbiAgaGFzQ2FwdHVyYWJsZUFjdFJlc3VsdCxcclxuICBoYXNNdXRhdGlvbixcclxuICBpc01lYW5pbmdmdWxBY3RTdGF0ZW1lbnQsXHJcbiAgaXNTZXR1cExpa2VTdGF0ZW1lbnQsXHJcbn07XHJcbiJdfQ==
|