@codeperfect/eslint-plugin 2.3.0 → 2.5.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/application/index.d.ts +1 -1
- package/dist/application/index.d.ts.map +1 -1
- package/dist/application/index.js +2 -2
- package/dist/codeperfect-eslint-plugin-1.0.0.tgz +0 -0
- package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/consistent-barrel-files-options.js +4 -2
- 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 +2 -4
- package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-rule.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-rule.js +4 -134
- package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-utilities.d.ts +14 -0
- package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/consistent-barrel-files/no-import-export-aliases-utilities.js +154 -0
- package/dist/domain/architecture/consistent-barrel-files/no-import-export-extensions-rule.d.ts.map +1 -1
- package/dist/domain/architecture/consistent-barrel-files/no-import-export-extensions-rule.js +10 -12
- 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 +4 -11
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-declaration-utilities.d.ts +14 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-declaration-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-declaration-utilities.js +187 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-identifier-utilities.d.ts +26 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-identifier-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-identifier-utilities.js +95 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-pattern-utilities.d.ts +32 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-pattern-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-pattern-utilities.js +78 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-public-api-usage-utilities.d.ts +18 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-public-api-usage-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-public-api-usage-utilities.js +45 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-record-utilities.d.ts +34 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-record-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-record-utilities.js +44 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-symbol-utilities.d.ts +59 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-symbol-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-symbol-utilities.js +133 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-usage-utilities.d.ts +28 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-usage-utilities.d.ts.map +1 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-usage-utilities.js +106 -0
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.d.ts +21 -21
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.d.ts.map +1 -1
- package/dist/domain/architecture/no-unused-exports/no-unused-exports-utilities.js +24 -587
- package/dist/domain/architecture/no-unused-exports/rule.js +3 -3
- package/dist/domain/core/no-multiple-declarators/rule-utilities.d.ts +58 -0
- package/dist/domain/core/no-multiple-declarators/rule-utilities.d.ts.map +1 -0
- package/dist/domain/core/no-multiple-declarators/rule-utilities.js +204 -0
- package/dist/domain/core/no-multiple-declarators/rule.d.ts.map +1 -1
- package/dist/domain/core/no-multiple-declarators/rule.js +9 -211
- package/dist/domain/core/no-multiple-declarators/types.js +2 -2
- package/dist/domain/core/prefer-interface-types/rule-utilities.d.ts +57 -0
- package/dist/domain/core/prefer-interface-types/rule-utilities.d.ts.map +1 -0
- package/dist/domain/core/prefer-interface-types/rule-utilities.js +105 -0
- package/dist/domain/core/prefer-interface-types/rule.d.ts.map +1 -1
- package/dist/domain/core/prefer-interface-types/rule.js +2 -104
- package/dist/domain/docs/no-interface-member-docs/comment-removal-ranges.d.ts +25 -0
- package/dist/domain/docs/no-interface-member-docs/comment-removal-ranges.d.ts.map +1 -0
- package/dist/domain/docs/no-interface-member-docs/comment-removal-ranges.js +64 -0
- package/dist/domain/docs/no-interface-member-docs/comment-utilities.d.ts +2 -24
- package/dist/domain/docs/no-interface-member-docs/comment-utilities.d.ts.map +1 -1
- package/dist/domain/docs/no-interface-member-docs/comment-utilities.js +3 -65
- package/dist/domain/docs/no-interface-member-docs/parameter-tags.js +2 -2
- package/dist/domain/docs/no-interface-member-docs/parameter-utilities.js +2 -2
- package/dist/domain/docs/no-interface-member-docs/rule.d.ts.map +1 -1
- package/dist/domain/docs/no-interface-member-docs/rule.js +3 -2
- package/dist/domain/docs/require-example-language/examples-collect.d.ts +15 -0
- package/dist/domain/docs/require-example-language/examples-collect.d.ts.map +1 -0
- package/dist/domain/docs/require-example-language/examples-collect.js +113 -0
- package/dist/domain/docs/require-example-language/examples.d.ts +24 -13
- package/dist/domain/docs/require-example-language/examples.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/examples.js +2 -111
- package/dist/domain/docs/require-example-language/fixes.js +4 -4
- package/dist/domain/docs/require-example-language/rule.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/rule.js +9 -8
- package/dist/domain/docs/require-example-language/types.d.ts.map +1 -1
- package/dist/domain/docs/require-example-language/types.js +1 -1
- package/dist/domain/index.d.ts +1 -1
- package/dist/domain/index.d.ts.map +1 -1
- package/dist/domain/index.js +2 -2
- package/dist/domain/testing/aaa/analyzer.analysis.helpers.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.analysis.helpers.js +8 -8
- package/dist/domain/testing/aaa/analyzer.assertions.helpers.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.assertions.helpers.js +10 -9
- package/dist/domain/testing/aaa/analyzer.assertions.operands.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.assertions.operands.js +2 -5
- package/dist/domain/testing/aaa/analyzer.classification.helpers.js +14 -16
- package/dist/domain/testing/aaa/analyzer.classification.traversal.js +6 -4
- package/dist/domain/testing/aaa/analyzer.super.d.ts.map +1 -1
- package/dist/domain/testing/aaa/analyzer.super.js +10 -8
- package/dist/domain/testing/assert-actual-expected-names/rule.d.ts.map +1 -1
- package/dist/domain/testing/assert-actual-expected-names/rule.js +21 -23
- package/dist/domain/testing/enforce-aaa-phase-purity/pattern-identifiers.d.ts.map +1 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/pattern-identifiers.js +1 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.d.ts.map +1 -1
- package/dist/domain/testing/enforce-aaa-phase-purity/phase-purity-reporting.js +2 -160
- package/dist/domain/testing/enforce-aaa-phase-purity/statement-purity-reporters.d.ts +41 -0
- package/dist/domain/testing/enforce-aaa-phase-purity/statement-purity-reporters.d.ts.map +1 -0
- package/dist/domain/testing/enforce-aaa-phase-purity/statement-purity-reporters.js +161 -0
- package/dist/domain/testing/enforce-aaa-structure/missing-section-fixes.d.ts.map +1 -1
- package/dist/domain/testing/enforce-aaa-structure/missing-section-fixes.js +2 -2
- package/dist/domain/testing/enforce-aaa-structure/rule-section-reporting.d.ts +81 -0
- package/dist/domain/testing/enforce-aaa-structure/rule-section-reporting.d.ts.map +1 -0
- package/dist/domain/testing/enforce-aaa-structure/rule-section-reporting.js +181 -0
- package/dist/domain/testing/enforce-aaa-structure/rule.d.ts.map +1 -1
- package/dist/domain/testing/enforce-aaa-structure/rule.js +28 -217
- package/dist/domain/testing/index.d.ts +1 -0
- package/dist/domain/testing/index.d.ts.map +1 -1
- package/dist/domain/testing/index.js +2 -1
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/index.d.ts +2 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/index.d.ts.map +1 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/index.js +2 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-detection.d.ts +29 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-detection.d.ts.map +1 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-detection.js +200 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-names.d.ts +12 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-names.d.ts.map +1 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-names.js +151 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-reporting.d.ts +16 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-reporting.d.ts.map +1 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule-reporting.js +109 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule.d.ts +5 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule.d.ts.map +1 -0
- package/dist/domain/testing/no-unsafe-vitest-mock-factory-cast/rule.js +35 -0
- package/dist/domain/testing/prefer-vi-mocked-import/fix-import-updates.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/fix-import-updates.js +7 -4
- package/dist/domain/testing/prefer-vi-mocked-import/fix-imports.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/fix-imports.js +7 -4
- package/dist/domain/testing/prefer-vi-mocked-import/fix.js +2 -2
- package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.d.ts +18 -0
- package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.d.ts.map +1 -0
- package/dist/domain/testing/prefer-vi-mocked-import/match-collisions.js +162 -0
- package/dist/domain/testing/prefer-vi-mocked-import/match-rewrites.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/match-rewrites.js +5 -4
- package/dist/domain/testing/prefer-vi-mocked-import/match-seeds.d.ts +29 -0
- package/dist/domain/testing/prefer-vi-mocked-import/match-seeds.d.ts.map +1 -0
- package/dist/domain/testing/prefer-vi-mocked-import/match-seeds.js +100 -0
- package/dist/domain/testing/prefer-vi-mocked-import/match.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/match.js +5 -246
- package/dist/domain/testing/prefer-vi-mocked-import/rule.d.ts.map +1 -1
- package/dist/domain/testing/prefer-vi-mocked-import/rule.js +18 -20
- package/dist/domain/testing/require-act-result-capture/rule.d.ts.map +1 -1
- package/dist/domain/testing/require-act-result-capture/rule.js +47 -21
- package/dist/domain/testing/require-test-companion/rule.d.ts.map +1 -1
- package/dist/domain/testing/require-test-companion/rule.js +2 -4
- package/dist/domain/testing/single-act-statement/rule.d.ts.map +1 -1
- package/dist/domain/testing/single-act-statement/rule.js +20 -22
- package/dist/infrastructure/codeperfect-plugin.d.ts +2 -0
- package/dist/infrastructure/codeperfect-plugin.d.ts.map +1 -1
- package/dist/infrastructure/codeperfect-plugin.js +3 -2
- package/dist/infrastructure/presets.d.ts.map +1 -1
- package/dist/infrastructure/presets.js +3 -1
- package/package.json +58 -58
- package/dist/.tsbuildinfo +0 -1
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { Rule } from "eslint";
|
|
2
|
+
import type { getFlattenedSections } from "../aaa/analyzer.analysis.helpers.js";
|
|
3
|
+
import type { TestBlockAnalysis } from "../aaa/types.js";
|
|
4
|
+
/** Flattened section entry emitted by the AAA analyzer helper. */
|
|
5
|
+
type FlattenedSection = ReturnType<typeof getFlattenedSections>[number];
|
|
6
|
+
/** Union of valid AAA phase labels emitted for flattened sections. */
|
|
7
|
+
type FlattenedSectionPhase = FlattenedSection["phase"];
|
|
8
|
+
/** Composite input for advancing the AAA section ordering state. */
|
|
9
|
+
interface UpdateSectionOrderInput {
|
|
10
|
+
/** Active ESLint rule context. */
|
|
11
|
+
context: Rule.RuleContext;
|
|
12
|
+
/** Highest phase order seen so far. */
|
|
13
|
+
lastPhaseOrder: number;
|
|
14
|
+
/** Section comment and phase metadata under inspection. */
|
|
15
|
+
section: FlattenedSection;
|
|
16
|
+
/** Set of phases already seen in the current test block. */
|
|
17
|
+
seenPhases: Set<FlattenedSectionPhase>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Reports section comments that are missing a blank line above them.
|
|
21
|
+
* @param context ESLint rule context.
|
|
22
|
+
* @param analysis Parsed test-block analysis.
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* reportBlankLineSeparators({ report() {} } as never, { sectionComments: [], sourceText: "" } as never);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
declare function reportBlankLineSeparators(context: Rule.RuleContext, analysis: TestBlockAnalysis): void;
|
|
29
|
+
/**
|
|
30
|
+
* Reports executable statements that appear before the first Arrange section.
|
|
31
|
+
* @param context ESLint rule context.
|
|
32
|
+
* @param analysis Parsed test-block analysis.
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* reportCodeBeforeArrange({ report() {} } as never, { sectionComments: [], statements: [] } as never);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
declare function reportCodeBeforeArrange(context: Rule.RuleContext, analysis: TestBlockAnalysis): void;
|
|
39
|
+
/**
|
|
40
|
+
* Reports sections that contain only comments or whitespace.
|
|
41
|
+
* @param context ESLint rule context.
|
|
42
|
+
* @param analysis Parsed test-block analysis.
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* reportEmptySections({ report() {} } as never, { sectionComments: [], statements: [] } as never);
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
declare function reportEmptySections(context: Rule.RuleContext, analysis: TestBlockAnalysis): void;
|
|
49
|
+
/**
|
|
50
|
+
* Reports any AAA section markers that are missing from a supported test block.
|
|
51
|
+
* @param context ESLint rule context.
|
|
52
|
+
* @param analysis Parsed test-block analysis.
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* reportMissingSections({ report() {} } as never, { sectionComments: [] } as never);
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
declare function reportMissingSections(context: Rule.RuleContext, analysis: TestBlockAnalysis): void;
|
|
59
|
+
/**
|
|
60
|
+
* Reports section comments that appear out of canonical Arrange -> Act -> Assert order.
|
|
61
|
+
* @param context ESLint rule context.
|
|
62
|
+
* @param analysis Parsed test-block analysis.
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* reportOutOfOrderSections({ report() {} } as never, { sectionComments: [] } as never);
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
declare function reportOutOfOrderSections(context: Rule.RuleContext, analysis: TestBlockAnalysis): void;
|
|
69
|
+
/**
|
|
70
|
+
* Tracks the current AAA ordering state for one flattened section.
|
|
71
|
+
* @param input Composite ordering state for the current section.
|
|
72
|
+
* @returns Updated phase order watermark.
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const nextOrder = updateSectionOrder({ context: {} as Rule.RuleContext, lastPhaseOrder: -1, section: {} as never, seenPhases: new Set() });
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
declare const updateSectionOrder: (input: UpdateSectionOrderInput) => number;
|
|
79
|
+
export type { FlattenedSectionPhase };
|
|
80
|
+
export { reportBlankLineSeparators, reportCodeBeforeArrange, reportEmptySections, reportMissingSections, reportOutOfOrderSections, updateSectionOrder, };
|
|
81
|
+
//# sourceMappingURL=rule-section-reporting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-section-reporting.d.ts","sourceRoot":"","sources":["../../../../src/domain/testing/enforce-aaa-structure/rule-section-reporting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,KAAK,EAAkB,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAUtE,kEAAkE;AAClE,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,sEAAsE;AACtE,KAAK,qBAAqB,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAcvD,oEAAoE;AACpE,UAAU,uBAAuB;IAC/B,kCAAkC;IAClC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC;IAE1B,uCAAuC;IACvC,cAAc,EAAE,MAAM,CAAC;IAEvB,2DAA2D;IAC3D,OAAO,EAAE,gBAAgB,CAAC;IAE1B,4DAA4D;IAC5D,UAAU,EAAE,GAAG,CAAC,qBAAqB,CAAC,CAAC;CACxC;AAED;;;;;;;;GAQG;AACH,iBAAS,yBAAyB,CAChC,OAAO,EAAE,IAAI,CAAC,WAAW,EACzB,QAAQ,EAAE,iBAAiB,GAC1B,IAAI,CAuBN;AAED;;;;;;;;GAQG;AACH,iBAAS,uBAAuB,CAC9B,OAAO,EAAE,IAAI,CAAC,WAAW,EACzB,QAAQ,EAAE,iBAAiB,GAC1B,IAAI,CAmBN;AAED;;;;;;;;GAQG;AACH,iBAAS,mBAAmB,CAC1B,OAAO,EAAE,IAAI,CAAC,WAAW,EACzB,QAAQ,EAAE,iBAAiB,GAC1B,IAAI,CAqBN;AAiCD;;;;;;;;GAQG;AACH,iBAAS,qBAAqB,CAC5B,OAAO,EAAE,IAAI,CAAC,WAAW,EACzB,QAAQ,EAAE,iBAAiB,GAC1B,IAAI,CA2BN;AAED;;;;;;;;GAQG;AACH,iBAAS,wBAAwB,CAC/B,OAAO,EAAE,IAAI,CAAC,WAAW,EACzB,QAAQ,EAAE,iBAAiB,GAC1B,IAAI,CAUN;AAoBD;;;;;;;;GAQG;AACH,QAAA,MAAM,kBAAkB,GAAI,OAAO,uBAAuB,KAAG,MAe5D,CAAC;AAEF,YAAY,EAAE,qBAAqB,EAAE,CAAC;AACtC,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,EACrB,wBAAwB,EACxB,kBAAkB,GACnB,CAAC"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { aaaPhaseOrder, getLineStartRange, getPhaseBoundaryComments, } from "../aaa/analyzer.analysis.helpers.js";
|
|
2
|
+
import { hasBlankLineBeforeComment } from "../aaa/analyzer.classification.helpers.js";
|
|
3
|
+
import { buildMissingSectionFixes } from "./missing-section-fixes.js";
|
|
4
|
+
/**
|
|
5
|
+
* Reports section comments that are missing a blank line above them.
|
|
6
|
+
* @param context ESLint rule context.
|
|
7
|
+
* @param analysis Parsed test-block analysis.
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* reportBlankLineSeparators({ report() {} } as never, { sectionComments: [], sourceText: "" } as never);
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
function reportBlankLineSeparators(context, analysis) {
|
|
14
|
+
const firstSectionComment = analysis.sectionComments[0]?.comment;
|
|
15
|
+
for (const sectionComment of getPhaseBoundaryComments(analysis)) {
|
|
16
|
+
if (sectionComment.comment !== firstSectionComment &&
|
|
17
|
+
!hasBlankLineBeforeComment(analysis.sourceText, sectionComment.comment)) {
|
|
18
|
+
context.report({
|
|
19
|
+
data: { section: sectionComment.phases.join(" & ") },
|
|
20
|
+
fix: (fixer) => fixer.insertTextBeforeRange(getLineStartRange(analysis.sourceText, sectionComment.comment.loc.start.line), analysis.newline),
|
|
21
|
+
messageId: "blankLineBeforeSection",
|
|
22
|
+
node: sectionComment.comment,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Reports executable statements that appear before the first Arrange section.
|
|
29
|
+
* @param context ESLint rule context.
|
|
30
|
+
* @param analysis Parsed test-block analysis.
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* reportCodeBeforeArrange({ report() {} } as never, { sectionComments: [], statements: [] } as never);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
function reportCodeBeforeArrange(context, analysis) {
|
|
37
|
+
const firstArrangeLine = analysis.sectionComments.find((sectionComment) => sectionComment.phases.includes("Arrange"))?.comment.loc.start.line;
|
|
38
|
+
if (firstArrangeLine === void 0) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const statementBeforeArrange = analysis.statements.find((statement) => statement.node.loc.start.line < firstArrangeLine);
|
|
42
|
+
if (statementBeforeArrange === void 0) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
context.report({
|
|
46
|
+
messageId: "codeBeforeArrange",
|
|
47
|
+
node: statementBeforeArrange.node,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Reports sections that contain only comments or whitespace.
|
|
52
|
+
* @param context ESLint rule context.
|
|
53
|
+
* @param analysis Parsed test-block analysis.
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* reportEmptySections({ report() {} } as never, { sectionComments: [], statements: [] } as never);
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
function reportEmptySections(context, analysis) {
|
|
60
|
+
for (const [index, sectionComment] of analysis.sectionComments.entries()) {
|
|
61
|
+
const nextSectionLine = analysis.sectionComments[index + 1]?.comment.loc.start.line;
|
|
62
|
+
const hasCodeInSection = analysis.statements.some((statement) => {
|
|
63
|
+
const statementLine = statement.node.loc.start.line;
|
|
64
|
+
return (statementLine > sectionComment.comment.loc.start.line &&
|
|
65
|
+
(nextSectionLine === void 0 || statementLine < nextSectionLine));
|
|
66
|
+
});
|
|
67
|
+
if (!hasCodeInSection) {
|
|
68
|
+
context.report({
|
|
69
|
+
data: { section: sectionComment.phases.join(" & ") },
|
|
70
|
+
messageId: "emptySection",
|
|
71
|
+
node: sectionComment.comment,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Reports a single out-of-order section pair.
|
|
78
|
+
* @param context ESLint rule context.
|
|
79
|
+
* @param previous Previous section comment.
|
|
80
|
+
* @param current Current section comment.
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* reportIfOutOfOrder({ report() {} } as never, { comment: {} as never, phases: [] }, { comment: {} as never, phases: [] });
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
function reportIfOutOfOrder(context, previous, current) {
|
|
87
|
+
const maxPreviousOrder = Math.max(...previous.phases.map((phase) => aaaPhaseOrder[phase]));
|
|
88
|
+
const minCurrentOrder = Math.min(...current.phases.map((phase) => aaaPhaseOrder[phase]));
|
|
89
|
+
if (minCurrentOrder <= maxPreviousOrder) {
|
|
90
|
+
context.report({
|
|
91
|
+
data: { section: current.phases.join(" & ") },
|
|
92
|
+
messageId: "outOfOrderSection",
|
|
93
|
+
node: current.comment,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Reports any AAA section markers that are missing from a supported test block.
|
|
99
|
+
* @param context ESLint rule context.
|
|
100
|
+
* @param analysis Parsed test-block analysis.
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* reportMissingSections({ report() {} } as never, { sectionComments: [] } as never);
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
function reportMissingSections(context, analysis) {
|
|
107
|
+
const presentSections = new Set(analysis.sectionComments.flatMap((sectionComment) => sectionComment.phases));
|
|
108
|
+
const hasPreSectionStatements = analysis.statements.some((statement) => statement.phases.length === 0);
|
|
109
|
+
const missingSections = ["Arrange", "Act", "Assert"].filter((phase) => !presentSections.has(phase) &&
|
|
110
|
+
(phase !== "Arrange" || hasPreSectionStatements));
|
|
111
|
+
if (missingSections.length === 0) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
context.report({
|
|
115
|
+
data: { sections: missingSections.join(", ") },
|
|
116
|
+
fix: analysis.bodyLineCount >= 3
|
|
117
|
+
? (fixer) => buildMissingSectionFixes(analysis, missingSections, fixer)
|
|
118
|
+
: void 0,
|
|
119
|
+
messageId: "missingSections",
|
|
120
|
+
node: analysis.callExpression,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Reports section comments that appear out of canonical Arrange -> Act -> Assert order.
|
|
125
|
+
* @param context ESLint rule context.
|
|
126
|
+
* @param analysis Parsed test-block analysis.
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* reportOutOfOrderSections({ report() {} } as never, { sectionComments: [] } as never);
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
function reportOutOfOrderSections(context, analysis) {
|
|
133
|
+
const comments = analysis.sectionComments;
|
|
134
|
+
const lastIndex = comments.length - 1;
|
|
135
|
+
for (let index = 0; index < lastIndex; index += 1) {
|
|
136
|
+
const previous = comments[index];
|
|
137
|
+
const current = comments[index + 1];
|
|
138
|
+
if (previous && current)
|
|
139
|
+
reportIfOutOfOrder(context, previous, current);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Reports a duplicate or out-of-order AAA section comment.
|
|
144
|
+
* @param input Composite reporting input for the current section.
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* reportSectionIssue({ context: {} as Rule.RuleContext, messageId: "duplicateSection", section: {} as never });
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
const reportSectionIssue = (input) => {
|
|
151
|
+
const { context, messageId, section } = input;
|
|
152
|
+
context.report({
|
|
153
|
+
data: { section: section.phase },
|
|
154
|
+
messageId,
|
|
155
|
+
node: section.comment,
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
/**
|
|
159
|
+
* Tracks the current AAA ordering state for one flattened section.
|
|
160
|
+
* @param input Composite ordering state for the current section.
|
|
161
|
+
* @returns Updated phase order watermark.
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* const nextOrder = updateSectionOrder({ context: {} as Rule.RuleContext, lastPhaseOrder: -1, section: {} as never, seenPhases: new Set() });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
const updateSectionOrder = (input) => {
|
|
168
|
+
const { context, lastPhaseOrder, section, seenPhases } = input;
|
|
169
|
+
if (seenPhases.has(section.phase)) {
|
|
170
|
+
reportSectionIssue({ context, messageId: "duplicateSection", section });
|
|
171
|
+
return lastPhaseOrder;
|
|
172
|
+
}
|
|
173
|
+
const currentPhaseOrder = aaaPhaseOrder[section.phase];
|
|
174
|
+
if (currentPhaseOrder < lastPhaseOrder) {
|
|
175
|
+
reportSectionIssue({ context, messageId: "invalidOrder", section });
|
|
176
|
+
}
|
|
177
|
+
seenPhases.add(section.phase);
|
|
178
|
+
return Math.max(lastPhaseOrder, currentPhaseOrder);
|
|
179
|
+
};
|
|
180
|
+
export { reportBlankLineSeparators, reportCodeBeforeArrange, reportEmptySections, reportMissingSections, reportOutOfOrderSections, updateSectionOrder, };
|
|
181
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZS1zZWN0aW9uLXJlcG9ydGluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kb21haW4vdGVzdGluZy9lbmZvcmNlLWFhYS1zdHJ1Y3R1cmUvcnVsZS1zZWN0aW9uLXJlcG9ydGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFLQSxPQUFPLEVBQ0wsYUFBYSxFQUNiLGlCQUFpQixFQUNqQix3QkFBd0IsR0FDekIsTUFBTSxrQ0FBa0MsQ0FBQztBQUMxQyxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUNuRixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQW1DbkU7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFTLHlCQUF5QixDQUNoQyxPQUF5QixFQUN6QixRQUEyQjtJQUUzQixNQUFNLG1CQUFtQixHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDO0lBRWpFLEtBQUssTUFBTSxjQUFjLElBQUksd0JBQXdCLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztRQUNoRSxJQUNFLGNBQWMsQ0FBQyxPQUFPLEtBQUssbUJBQW1CO1lBQzlDLENBQUMseUJBQXlCLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxjQUFjLENBQUMsT0FBTyxDQUFDLEVBQ3ZFLENBQUM7WUFDRCxPQUFPLENBQUMsTUFBTSxDQUFDO2dCQUNiLElBQUksRUFBRSxFQUFFLE9BQU8sRUFBRSxjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDcEQsR0FBRyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FDYixLQUFLLENBQUMscUJBQXFCLENBQ3pCLGlCQUFpQixDQUNmLFFBQVEsQ0FBQyxVQUFVLEVBQ25CLGNBQWMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQ3RDLEVBQ0QsUUFBUSxDQUFD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UUFDVCxJQUFJLEVBQUUsT0FBTyxDQUFDLE9BQU87S0FDdEIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDO0FBRUY7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLGtCQUFrQixHQUFHLENBQUMsS0FBOEIsRUFBVSxFQUFFO0lBQ3BFLE1BQU0sRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsR0FBRyxLQUFLLENBQUM7SUFFL0QsSUFBSSxVQUFVLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ2xDLGtCQUFrQixDQUFDLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ3hFLE9BQU8sY0FBYyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxNQUFNLGlCQUFpQixHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkQsSUFBSSxpQkFBaUIsR0FBRyxjQUFjLEVBQUUsQ0FBQztRQUN2QyxrQkFBa0IsQ0FBQyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVELFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlCLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztBQUNyRCxDQUFDLENBQUM7QUFHRixPQUFPLEVBQ0wseUJBQXlCLEVBQ3pCLHVCQUF1QixFQUN2QixtQkFBbUIsRUFDbkIscUJBQXFCLEVBQ3JCLHdCQUF3QixFQUN4QixrQkFBa0IsR0FDbkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgUnVsZSB9IGZyb20gXCJlc2xpbnRcIjtcblxuaW1wb3J0IHR5cGUgeyBnZXRGbGF0dGVuZWRTZWN0aW9ucyB9IGZyb20gXCIuLi9hYWEvYW5hbHl6ZXIuYW5hbHlzaXMuaGVscGVyc1wiO1xuaW1wb3J0IHR5cGUgeyBTZWN0aW9uQ29tbWVudCwgVGVzdEJsb2NrQW5hbHlzaXMgfSBmcm9tIFwiLi4vYWFhL3R5cGVzXCI7XG5cbmltcG9ydCB7XG4gIGFhYVBoYXNlT3JkZXIsXG4gIGdldExpbmVTdGFydFJhbmdlLFxuICBnZXRQaGFzZUJvdW5kYXJ5Q29tbWVudHMsXG59IGZyb20gXCIuLi9hYWEvYW5hbHl6ZXIuYW5hbHlzaXMuaGVscGVyc1wiO1xuaW1wb3J0IHsgaGFzQmxhbmtMaW5lQmVmb3JlQ29tbWVudCB9IGZyb20gXCIuLi9hYWEvYW5hbHl6ZXIuY2xhc3NpZmljYXRpb24uaGVscGVyc1wiO1xuaW1wb3J0IHsgYnVpbGRNaXNzaW5nU2VjdGlvbkZpeGVzIH0gZnJvbSBcIi4vbWlzc2luZy1zZWN0aW9uLWZpeGVzXCI7XG5cbi8qKiBGbGF0dGVuZWQgc2VjdGlvbiBlbnRyeSBlbWl0dGVkIGJ5IHRoZSBBQUEgYW5hbHl6ZXIgaGVscGVyLiAqL1xudHlwZSBGbGF0dGVuZWRTZWN0aW9uID0gUmV0dXJuVHlwZTx0eXBlb2YgZ2V0RmxhdHRlbmVkU2VjdGlvbnM+W251bWJlcl07XG5cbi8qKiBVbmlvbiBvZiB2YWxpZCBBQUEgcGhhc2UgbGFiZWxzIGVtaXR0ZWQgZm9yIGZsYXR0ZW5lZCBzZWN0aW9ucy4gKi9cbnR5cGUgRmxhdHRlbmVkU2VjdGlvblBoYXNlID0gRmxhdHRlbmVkU2VjdGlvbltcInBoYXNlXCJdO1xuXG4vKiogQ29tcG9zaXRlIGlucHV0IGZvciByZXBvcnRpbmcgb25lIEFBQSBzZWN0aW9uIGlzc3VlLiAqL1xuaW50ZXJmYWNlIFJlcG9ydFNlY3Rpb25Jc3N1ZUlucHV0IHtcbiAgLyoqIEFjdGl2ZSBFU0xpbnQgcnVsZSBjb250ZXh0LiAqL1xuICBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0O1xuXG4gIC8qKiBNZXNzYWdlIGlkZW50aWZpZXIgdG8gcmVwb3J0IGZvciB0aGUgc2VjdGlvbi4gKi9cbiAgbWVzc2FnZUlkOiBcImR1cGxpY2F0ZVNlY3Rpb25cIiB8IFwiaW52YWxpZE9yZGVyXCI7XG5cbiAgLyoqIFNlY3Rpb24gY29tbWVudCBhbmQgcGhhc2UgbWV0YWRhdGEgdW5kZXIgaW5zcGVjdGlvbi4gKi9cbiAgc2VjdGlvbjogRmxhdHRlbmVkU2VjdGlvbjtcbn1cblxuLyoqIENvbXBvc2l0ZSBpbnB1dCBmb3IgYWR2YW5jaW5nIHRoZSBBQUEgc2VjdGlvbiBvcmRlcmluZyBzdGF0ZS4gKi9cbmludGVyZmFjZSBVcGRhdGVTZWN0aW9uT3JkZXJJbnB1dCB7XG4gIC8qKiBBY3RpdmUgRVNMaW50IHJ1bGUgY29udGV4dC4gKi9cbiAgY29udGV4dDogUnVsZS5SdWxlQ29udGV4dDtcblxuICAvKiogSGlnaGVzdCBwaGFzZSBvcmRlciBzZWVuIHNvIGZhci4gKi9cbiAgbGFzdFBoYXNlT3JkZXI6IG51bWJlcjtcblxuICAvKiogU2VjdGlvbiBjb21tZW50IGFuZCBwaGFzZSBtZXRhZGF0YSB1bmRlciBpbnNwZWN0aW9uLiAqL1xuICBzZWN0aW9uOiBGbGF0dGVuZWRTZWN0aW9uO1xuXG4gIC8qKiBTZXQgb2YgcGhhc2VzIGFscmVhZHkgc2VlbiBpbiB0aGUgY3VycmVudCB0ZXN0IGJsb2NrLiAqL1xuICBzZWVuUGhhc2VzOiBTZXQ8RmxhdHRlbmVkU2VjdGlvblBoYXNlPjtcbn1cblxuLyoqXG4gKiBSZXBvcnRzIHNlY3Rpb24gY29tbWVudHMgdGhhdCBhcmUgbWlzc2luZyBhIGJsYW5rIGxpbmUgYWJvdmUgdGhlbS5cbiAqIEBwYXJhbSBjb250ZXh0IEVTTGludCBydWxlIGNvbnRleHQuXG4gKiBAcGFyYW0gYW5hbHlzaXMgUGFyc2VkIHRlc3QtYmxvY2sgYW5hbHlzaXMuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogcmVwb3J0QmxhbmtMaW5lU2VwYXJhdG9ycyh7IHJlcG9ydCgpIHt9IH0gYXMgbmV2ZXIsIHsgc2VjdGlvbkNvbW1lbnRzOiBbXSwgc291cmNlVGV4dDogXCJcIiB9IGFzIG5ldmVyKTtcbiAqIGBgYFxuICovXG5mdW5jdGlvbiByZXBvcnRCbGFua0xpbmVTZXBhcmF0b3JzKFxuICBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0LFxuICBhbmFseXNpczogVGVzdEJsb2NrQW5hbHlzaXMsXG4pOiB2b2lkIHtcbiAgY29uc3QgZmlyc3RTZWN0aW9uQ29tbWVudCA9IGFuYWx5c2lzLnNlY3Rpb25Db21tZW50c1swXT8uY29tbWVudDtcblxuICBmb3IgKGNvbnN0IHNlY3Rpb25Db21tZW50IG9mIGdldFBoYXNlQm91bmRhcnlDb21tZW50cyhhbmFseXNpcykpIHtcbiAgICBpZiAoXG4gICAgICBzZWN0aW9uQ29tbWVudC5jb21tZW50ICE9PSBmaXJzdFNlY3Rpb25Db21tZW50ICYmXG4gICAgICAhaGFzQmxhbmtMaW5lQmVmb3JlQ29tbWVudChhbmFseXNpcy5zb3VyY2VUZXh0LCBzZWN0aW9uQ29tbWVudC5jb21tZW50KVxuICAgICkge1xuICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICBkYXRhOiB7IHNlY3Rpb246IHNlY3Rpb25Db21tZW50LnBoYXNlcy5qb2luKFwiICYgXCIpIH0sXG4gICAgICAgIGZpeDogKGZpeGVyKSA9PlxuICAgICAgICAgIGZpeGVyLmluc2VydFRleHRCZWZvcmVSYW5nZShcbiAgICAgICAgICAgIGdldExpbmVTdGFydFJhbmdlKFxuICAgICAgICAgICAgICBhbmFseXNpcy5zb3VyY2VUZXh0LFxuICAgICAgICAgICAgICBzZWN0aW9uQ29tbWVudC5jb21tZW50LmxvYy5zdGFydC5saW5lLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIGFuYWx5c2lzLm5ld2xpbmUsXG4gICAgICAgICAgKSxcbiAgICAgICAgbWVzc2FnZUlkOiBcImJsYW5rTGluZUJlZm9yZVNlY3Rpb25cIixcbiAgICAgICAgbm9kZTogc2VjdGlvbkNvbW1lbnQuY29tbWVudCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlcG9ydHMgZXhlY3V0YWJsZSBzdGF0ZW1lbnRzIHRoYXQgYXBwZWFyIGJlZm9yZSB0aGUgZmlyc3QgQXJyYW5nZSBzZWN0aW9uLlxuICogQHBhcmFtIGNvbnRleHQgRVNMaW50IHJ1bGUgY29udGV4dC5cbiAqIEBwYXJhbSBhbmFseXNpcyBQYXJzZWQgdGVzdC1ibG9jayBhbmFseXNpcy5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiByZXBvcnRDb2RlQmVmb3JlQXJyYW5nZSh7IHJlcG9ydCgpIHt9IH0gYXMgbmV2ZXIsIHsgc2VjdGlvbkNvbW1lbnRzOiBbXSwgc3RhdGVtZW50czogW10gfSBhcyBuZXZlcik7XG4gKiBgYGBcbiAqL1xuZnVuY3Rpb24gcmVwb3J0Q29kZUJlZm9yZUFycmFuZ2UoXG4gIGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQsXG4gIGFuYWx5c2lzOiBUZXN0QmxvY2tBbmFseXNpcyxcbik6IHZvaWQge1xuICBjb25zdCBmaXJzdEFycmFuZ2VMaW5lID0gYW5hbHlzaXMuc2VjdGlvbkNvbW1lbnRzLmZpbmQoKHNlY3Rpb25Db21tZW50KSA9PlxuICAgIHNlY3Rpb25Db21tZW50LnBoYXNlcy5pbmNsdWRlcyhcIkFycmFuZ2VcIiksXG4gICk/LmNvbW1lbnQubG9jLnN0YXJ0LmxpbmU7XG4gIGlmIChmaXJzdEFycmFuZ2VMaW5lID09PSB2b2lkIDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBzdGF0ZW1lbnRCZWZvcmVBcnJhbmdlID0gYW5hbHlzaXMuc3RhdGVtZW50cy5maW5kKFxuICAgIChzdGF0ZW1lbnQpID0+IHN0YXRlbWVudC5ub2RlLmxvYy5zdGFydC5saW5lIDwgZmlyc3RBcnJhbmdlTGluZSxcbiAgKTtcbiAgaWYgKHN0YXRlbWVudEJlZm9yZUFycmFuZ2UgPT09IHZvaWQgMCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnRleHQucmVwb3J0KHtcbiAgICBtZXNzYWdlSWQ6IFwiY29kZUJlZm9yZUFycmFuZ2VcIixcbiAgICBub2RlOiBzdGF0ZW1lbnRCZWZvcmVBcnJhbmdlLm5vZGUsXG4gIH0pO1xufVxuXG4vKipcbiAqIFJlcG9ydHMgc2VjdGlvbnMgdGhhdCBjb250YWluIG9ubHkgY29tbWVudHMgb3Igd2hpdGVzcGFjZS5cbiAqIEBwYXJhbSBjb250ZXh0IEVTTGludCBydWxlIGNvbnRleHQuXG4gKiBAcGFyYW0gYW5hbHlzaXMgUGFyc2VkIHRlc3QtYmxvY2sgYW5hbHlzaXMuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogcmVwb3J0RW1wdHlTZWN0aW9ucyh7IHJlcG9ydCgpIHt9IH0gYXMgbmV2ZXIsIHsgc2VjdGlvbkNvbW1lbnRzOiBbXSwgc3RhdGVtZW50czogW10gfSBhcyBuZXZlcik7XG4gKiBgYGBcbiAqL1xuZnVuY3Rpb24gcmVwb3J0RW1wdHlTZWN0aW9ucyhcbiAgY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCxcbiAgYW5hbHlzaXM6IFRlc3RCbG9ja0FuYWx5c2lzLFxuKTogdm9pZCB7XG4gIGZvciAoY29uc3QgW2luZGV4LCBzZWN0aW9uQ29tbWVudF0gb2YgYW5hbHlzaXMuc2VjdGlvbkNvbW1lbnRzLmVudHJpZXMoKSkge1xuICAgIGNvbnN0IG5leHRTZWN0aW9uTGluZSA9XG4gICAgICBhbmFseXNpcy5zZWN0aW9uQ29tbWVudHNbaW5kZXggKyAxXT8uY29tbWVudC5sb2Muc3RhcnQubGluZTtcbiAgICBjb25zdCBoYXNDb2RlSW5TZWN0aW9uID0gYW5hbHlzaXMuc3RhdGVtZW50cy5zb21lKChzdGF0ZW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IHN0YXRlbWVudExpbmUgPSBzdGF0ZW1lbnQubm9kZS5sb2Muc3RhcnQubGluZTtcblxuICAgICAgcmV0dXJuIChcbiAgICAgICAgc3RhdGVtZW50TGluZSA+IHNlY3Rpb25Db21tZW50LmNvbW1lbnQubG9jLnN0YXJ0LmxpbmUgJiZcbiAgICAgICAgKG5leHRTZWN0aW9uTGluZSA9PT0gdm9pZCAwIHx8IHN0YXRlbWVudExpbmUgPCBuZXh0U2VjdGlvbkxpbmUpXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaWYgKCFoYXNDb2RlSW5TZWN0aW9uKSB7XG4gICAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICAgIGRhdGE6IHsgc2VjdGlvbjogc2VjdGlvbkNvbW1lbnQucGhhc2VzLmpvaW4oXCIgJiBcIikgfSxcbiAgICAgICAgbWVzc2FnZUlkOiBcImVtcHR5U2VjdGlvblwiLFxuICAgICAgICBub2RlOiBzZWN0aW9uQ29tbWVudC5jb21tZW50LFxuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUmVwb3J0cyBhIHNpbmdsZSBvdXQtb2Ytb3JkZXIgc2VjdGlvbiBwYWlyLlxuICogQHBhcmFtIGNvbnRleHQgRVNMaW50IHJ1bGUgY29udGV4dC5cbiAqIEBwYXJhbSBwcmV2aW91cyBQcmV2aW91cyBzZWN0aW9uIGNvbW1lbnQuXG4gKiBAcGFyYW0gY3VycmVudCBDdXJyZW50IHNlY3Rpb24gY29tbWVudC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiByZXBvcnRJZk91dE9mT3JkZXIoeyByZXBvcnQoKSB7fSB9IGFzIG5ldmVyLCB7IGNvbW1lbnQ6IHt9IGFzIG5ldmVyLCBwaGFzZXM6IFtdIH0sIHsgY29tbWVudDoge30gYXMgbmV2ZXIsIHBoYXNlczogW10gfSk7XG4gKiBgYGBcbiAqL1xuZnVuY3Rpb24gcmVwb3J0SWZPdXRPZk9yZGVyKFxuICBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0LFxuICBwcmV2aW91czogU2VjdGlvbkNvbW1lbnQsXG4gIGN1cnJlbnQ6IFNlY3Rpb25Db21tZW50LFxuKTogdm9pZCB7XG4gIGNvbnN0IG1heFByZXZpb3VzT3JkZXIgPSBNYXRoLm1heChcbiAgICAuLi5wcmV2aW91cy5waGFzZXMubWFwKChwaGFzZSkgPT4gYWFhUGhhc2VPcmRlcltwaGFzZV0pLFxuICApO1xuICBjb25zdCBtaW5DdXJyZW50T3JkZXIgPSBNYXRoLm1pbihcbiAgICAuLi5jdXJyZW50LnBoYXNlcy5tYXAoKHBoYXNlKSA9PiBhYWFQaGFzZU9yZGVyW3BoYXNlXSksXG4gICk7XG5cbiAgaWYgKG1pbkN1cnJlbnRPcmRlciA8PSBtYXhQcmV2aW91c09yZGVyKSB7XG4gICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgZGF0YTogeyBzZWN0aW9uOiBjdXJyZW50LnBoYXNlcy5qb2luKFwiICYgXCIpIH0sXG4gICAgICBtZXNzYWdlSWQ6IFwib3V0T2ZPcmRlclNlY3Rpb25cIixcbiAgICAgIG5vZGU6IGN1cnJlbnQuY29tbWVudCxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIFJlcG9ydHMgYW55IEFBQSBzZWN0aW9uIG1hcmtlcnMgdGhhdCBhcmUgbWlzc2luZyBmcm9tIGEgc3VwcG9ydGVkIHRlc3QgYmxvY2suXG4gKiBAcGFyYW0gY29udGV4dCBFU0xpbnQgcnVsZSBjb250ZXh0LlxuICogQHBhcmFtIGFuYWx5c2lzIFBhcnNlZCB0ZXN0LWJsb2NrIGFuYWx5c2lzLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHJlcG9ydE1pc3NpbmdTZWN0aW9ucyh7IHJlcG9ydCgpIHt9IH0gYXMgbmV2ZXIsIHsgc2VjdGlvbkNvbW1lbnRzOiBbXSB9IGFzIG5ldmVyKTtcbiAqIGBgYFxuICovXG5mdW5jdGlvbiByZXBvcnRNaXNzaW5nU2VjdGlvbnMoXG4gIGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQsXG4gIGFuYWx5c2lzOiBUZXN0QmxvY2tBbmFseXNpcyxcbik6IHZvaWQge1xuICBjb25zdCBwcmVzZW50U2VjdGlvbnMgPSBuZXcgU2V0KFxuICAgIGFuYWx5c2lzLnNlY3Rpb25Db21tZW50cy5mbGF0TWFwKChzZWN0aW9uQ29tbWVudCkgPT4gc2VjdGlvbkNvbW1lbnQucGhhc2VzKSxcbiAgKTtcbiAgY29uc3QgaGFzUHJlU2VjdGlvblN0YXRlbWVudHMgPSBhbmFseXNpcy5zdGF0ZW1lbnRzLnNvbWUoXG4gICAgKHN0YXRlbWVudCkgPT4gc3RhdGVtZW50LnBoYXNlcy5sZW5ndGggPT09IDAsXG4gICk7XG4gIGNvbnN0IG1pc3NpbmdTZWN0aW9ucyA9IChbXCJBcnJhbmdlXCIsIFwiQWN0XCIsIFwiQXNzZXJ0XCJdIGFzIGNvbnN0KS5maWx0ZXIoXG4gICAgKHBoYXNlKSA9PlxuICAgICAgIXByZXNlbnRTZWN0aW9ucy5oYXMocGhhc2UpICYmXG4gICAgICAocGhhc2UgIT09IFwiQXJyYW5nZVwiIHx8IGhhc1ByZVNlY3Rpb25TdGF0ZW1lbnRzKSxcbiAgKTtcblxuICBpZiAobWlzc2luZ1NlY3Rpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnRleHQucmVwb3J0KHtcbiAgICBkYXRhOiB7IHNlY3Rpb25zOiBtaXNzaW5nU2VjdGlvbnMuam9pbihcIiwgXCIpIH0sXG4gICAgZml4OlxuICAgICAgYW5hbHlzaXMuYm9keUxpbmVDb3VudCA+PSAzXG4gICAgICAgID8gKGZpeGVyOiBSdWxlLlJ1bGVGaXhlcik6IFJ1bGUuRml4W10gPT5cbiAgICAgICAgICAgIGJ1aWxkTWlzc2luZ1NlY3Rpb25GaXhlcyhhbmFseXNpcywgbWlzc2luZ1NlY3Rpb25zLCBmaXhlcilcbiAgICAgICAgOiB2b2lkIDAsXG4gICAgbWVzc2FnZUlkOiBcIm1pc3NpbmdTZWN0aW9uc1wiLFxuICAgIG5vZGU6IGFuYWx5c2lzLmNhbGxFeHByZXNzaW9uLFxuICB9KTtcbn1cblxuLyoqXG4gKiBSZXBvcnRzIHNlY3Rpb24gY29tbWVudHMgdGhhdCBhcHBlYXIgb3V0IG9mIGNhbm9uaWNhbCBBcnJhbmdlIC0+IEFjdCAtPiBBc3NlcnQgb3JkZXIuXG4gKiBAcGFyYW0gY29udGV4dCBFU0xpbnQgcnVsZSBjb250ZXh0LlxuICogQHBhcmFtIGFuYWx5c2lzIFBhcnNlZCB0ZXN0LWJsb2NrIGFuYWx5c2lzLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHJlcG9ydE91dE9mT3JkZXJTZWN0aW9ucyh7IHJlcG9ydCgpIHt9IH0gYXMgbmV2ZXIsIHsgc2VjdGlvbkNvbW1lbnRzOiBbXSB9IGFzIG5ldmVyKTtcbiAqIGBgYFxuICovXG5mdW5jdGlvbiByZXBvcnRPdXRPZk9yZGVyU2VjdGlvbnMoXG4gIGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQsXG4gIGFuYWx5c2lzOiBUZXN0QmxvY2tBbmFseXNpcyxcbik6IHZvaWQge1xuICBjb25zdCBjb21tZW50cyA9IGFuYWx5c2lzLnNlY3Rpb25Db21tZW50cztcbiAgY29uc3QgbGFzdEluZGV4ID0gY29tbWVudHMubGVuZ3RoIC0gMTtcblxuICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbGFzdEluZGV4OyBpbmRleCArPSAxKSB7XG4gICAgY29uc3QgcHJldmlvdXMgPSBjb21tZW50c1tpbmRleF07XG4gICAgY29uc3QgY3VycmVudCA9IGNvbW1lbnRzW2luZGV4ICsgMV07XG5cbiAgICBpZiAocHJldmlvdXMgJiYgY3VycmVudCkgcmVwb3J0SWZPdXRPZk9yZGVyKGNvbnRleHQsIHByZXZpb3VzLCBjdXJyZW50KTtcbiAgfVxufVxuXG4vKipcbiAqIFJlcG9ydHMgYSBkdXBsaWNhdGUgb3Igb3V0LW9mLW9yZGVyIEFBQSBzZWN0aW9uIGNvbW1lbnQuXG4gKiBAcGFyYW0gaW5wdXQgQ29tcG9zaXRlIHJlcG9ydGluZyBpbnB1dCBmb3IgdGhlIGN1cnJlbnQgc2VjdGlvbi5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiByZXBvcnRTZWN0aW9uSXNzdWUoeyBjb250ZXh0OiB7fSBhcyBSdWxlLlJ1bGVDb250ZXh0LCBtZXNzYWdlSWQ6IFwiZHVwbGljYXRlU2VjdGlvblwiLCBzZWN0aW9uOiB7fSBhcyBuZXZlciB9KTtcbiAqIGBgYFxuICovXG5jb25zdCByZXBvcnRTZWN0aW9uSXNzdWUgPSAoaW5wdXQ6IFJlcG9ydFNlY3Rpb25Jc3N1ZUlucHV0KTogdm9pZCA9PiB7XG4gIGNvbnN0IHsgY29udGV4dCwgbWVzc2FnZUlkLCBzZWN0aW9uIH0gPSBpbnB1dDtcblxuICBjb250ZXh0LnJlcG9ydCh7XG4gICAgZGF0YTogeyBzZWN0aW9uOiBzZWN0aW9uLnBoYXNlIH0sXG4gICAgbWVzc2FnZUlkLFxuICAgIG5vZGU6IHNlY3Rpb24uY29tbWVudCxcbiAgfSk7XG59O1xuXG4vKipcbiAqIFRyYWNrcyB0aGUgY3VycmVudCBBQUEgb3JkZXJpbmcgc3RhdGUgZm9yIG9uZSBmbGF0dGVuZWQgc2VjdGlvbi5cbiAqIEBwYXJhbSBpbnB1dCBDb21wb3NpdGUgb3JkZXJpbmcgc3RhdGUgZm9yIHRoZSBjdXJyZW50IHNlY3Rpb24uXG4gKiBAcmV0dXJucyBVcGRhdGVkIHBoYXNlIG9yZGVyIHdhdGVybWFyay5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBuZXh0T3JkZXIgPSB1cGRhdGVTZWN0aW9uT3JkZXIoeyBjb250ZXh0OiB7fSBhcyBSdWxlLlJ1bGVDb250ZXh0LCBsYXN0UGhhc2VPcmRlcjogLTEsIHNlY3Rpb246IHt9IGFzIG5ldmVyLCBzZWVuUGhhc2VzOiBuZXcgU2V0KCkgfSk7XG4gKiBgYGBcbiAqL1xuY29uc3QgdXBkYXRlU2VjdGlvbk9yZGVyID0gKGlucHV0OiBVcGRhdGVTZWN0aW9uT3JkZXJJbnB1dCk6IG51bWJlciA9PiB7XG4gIGNvbnN0IHsgY29udGV4dCwgbGFzdFBoYXNlT3JkZXIsIHNlY3Rpb24sIHNlZW5QaGFzZXMgfSA9IGlucHV0O1xuXG4gIGlmIChzZWVuUGhhc2VzLmhhcyhzZWN0aW9uLnBoYXNlKSkge1xuICAgIHJlcG9ydFNlY3Rpb25Jc3N1ZSh7IGNvbnRleHQsIG1lc3NhZ2VJZDogXCJkdXBsaWNhdGVTZWN0aW9uXCIsIHNlY3Rpb24gfSk7XG4gICAgcmV0dXJuIGxhc3RQaGFzZU9yZGVyO1xuICB9XG5cbiAgY29uc3QgY3VycmVudFBoYXNlT3JkZXIgPSBhYWFQaGFzZU9yZGVyW3NlY3Rpb24ucGhhc2VdO1xuICBpZiAoY3VycmVudFBoYXNlT3JkZXIgPCBsYXN0UGhhc2VPcmRlcikge1xuICAgIHJlcG9ydFNlY3Rpb25Jc3N1ZSh7IGNvbnRleHQsIG1lc3NhZ2VJZDogXCJpbnZhbGlkT3JkZXJcIiwgc2VjdGlvbiB9KTtcbiAgfVxuXG4gIHNlZW5QaGFzZXMuYWRkKHNlY3Rpb24ucGhhc2UpO1xuICByZXR1cm4gTWF0aC5tYXgobGFzdFBoYXNlT3JkZXIsIGN1cnJlbnRQaGFzZU9yZGVyKTtcbn07XG5cbmV4cG9ydCB0eXBlIHsgRmxhdHRlbmVkU2VjdGlvblBoYXNlIH07XG5leHBvcnQge1xuICByZXBvcnRCbGFua0xpbmVTZXBhcmF0b3JzLFxuICByZXBvcnRDb2RlQmVmb3JlQXJyYW5nZSxcbiAgcmVwb3J0RW1wdHlTZWN0aW9ucyxcbiAgcmVwb3J0TWlzc2luZ1NlY3Rpb25zLFxuICByZXBvcnRPdXRPZk9yZGVyU2VjdGlvbnMsXG4gIHVwZGF0ZVNlY3Rpb25PcmRlcixcbn07XG4iXX0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../../../src/domain/testing/enforce-aaa-structure/rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../../../src/domain/testing/enforce-aaa-structure/rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAiBnC,kFAAkF;AAClF,QAAA,MAAM,uBAAuB,EAAE,IAAI,CAAC,UAoEnC,CAAC;AAEF,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -1,86 +1,35 @@
|
|
|
1
1
|
import { createRuleDocumentation } from "../../custom-rule-documentation.js";
|
|
2
2
|
import { analyzeTestBlock } from "../aaa/analyzer.analysis.js";
|
|
3
|
-
import {
|
|
4
|
-
import { hasBlankLineBeforeComment } from "../aaa/analyzer.classification.helpers.js";
|
|
3
|
+
import { getFlattenedSections } from "../aaa/analyzer.analysis.helpers.js";
|
|
5
4
|
import { reportPhasePurityViolations } from "../enforce-aaa-phase-purity/phase-purity-reporting.js";
|
|
6
|
-
import {
|
|
7
|
-
/**
|
|
8
|
-
* Reports a duplicate or out-of-order AAA section comment.
|
|
9
|
-
* @param input Composite reporting input for the current section.
|
|
10
|
-
* @example
|
|
11
|
-
* ```typescript
|
|
12
|
-
* reportSectionIssue({
|
|
13
|
-
* context: {} as Rule.RuleContext,
|
|
14
|
-
* messageId: "duplicateSection",
|
|
15
|
-
* section: {} as ReturnType<typeof getFlattenedSections>[number],
|
|
16
|
-
* });
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
const reportSectionIssue = (input) => {
|
|
20
|
-
const { context, messageId, section } = input;
|
|
21
|
-
context.report({
|
|
22
|
-
data: { section: section.phase },
|
|
23
|
-
messageId,
|
|
24
|
-
node: section.comment,
|
|
25
|
-
});
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Tracks the current AAA ordering state for one flattened section.
|
|
29
|
-
* @param input Composite ordering state for the current section.
|
|
30
|
-
* @returns Updated phase order watermark.
|
|
31
|
-
* @example
|
|
32
|
-
* ```typescript
|
|
33
|
-
* const nextOrder = updateSectionOrder({
|
|
34
|
-
* context: {} as Rule.RuleContext,
|
|
35
|
-
* lastPhaseOrder: -1,
|
|
36
|
-
* section: {} as ReturnType<typeof getFlattenedSections>[number],
|
|
37
|
-
* seenPhases: new Set(),
|
|
38
|
-
* });
|
|
39
|
-
* void nextOrder;
|
|
40
|
-
* ```
|
|
41
|
-
*/
|
|
42
|
-
const updateSectionOrder = (input) => {
|
|
43
|
-
const { context, lastPhaseOrder, section, seenPhases } = input;
|
|
44
|
-
if (seenPhases.has(section.phase)) {
|
|
45
|
-
reportSectionIssue({ context, messageId: "duplicateSection", section });
|
|
46
|
-
return lastPhaseOrder;
|
|
47
|
-
}
|
|
48
|
-
const currentPhaseOrder = aaaPhaseOrder[section.phase];
|
|
49
|
-
if (currentPhaseOrder < lastPhaseOrder) {
|
|
50
|
-
reportSectionIssue({ context, messageId: "invalidOrder", section });
|
|
51
|
-
}
|
|
52
|
-
seenPhases.add(section.phase);
|
|
53
|
-
return Math.max(lastPhaseOrder, currentPhaseOrder);
|
|
54
|
-
};
|
|
5
|
+
import { reportBlankLineSeparators, reportCodeBeforeArrange, reportEmptySections, reportMissingSections, reportOutOfOrderSections, updateSectionOrder, } from "./rule-section-reporting.js";
|
|
55
6
|
/** Enforces a single Arrange/Act/Assert sequence inside supported test blocks. */
|
|
56
7
|
const enforceAaaStructureRule = {
|
|
57
|
-
create(context) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
};
|
|
83
|
-
},
|
|
8
|
+
create: (context) => ({
|
|
9
|
+
CallExpression(node) {
|
|
10
|
+
const analysis = analyzeTestBlock(context, node);
|
|
11
|
+
if (analysis === void 0) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const flattenedSections = getFlattenedSections(analysis);
|
|
15
|
+
const seenPhases = new Set();
|
|
16
|
+
let lastPhaseOrder = -1;
|
|
17
|
+
for (const section of flattenedSections) {
|
|
18
|
+
lastPhaseOrder = updateSectionOrder({
|
|
19
|
+
context,
|
|
20
|
+
lastPhaseOrder,
|
|
21
|
+
section,
|
|
22
|
+
seenPhases,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
reportMissingSections(context, analysis);
|
|
26
|
+
reportEmptySections(context, analysis);
|
|
27
|
+
reportOutOfOrderSections(context, analysis);
|
|
28
|
+
reportCodeBeforeArrange(context, analysis);
|
|
29
|
+
reportBlankLineSeparators(context, analysis);
|
|
30
|
+
reportPhasePurityViolations(context, analysis);
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
84
33
|
meta: {
|
|
85
34
|
docs: createRuleDocumentation("enforce-aaa-structure", "Require explicit AAA markers, enforce section order and uniqueness, and keep setup, action, and assertions in their intended phases."),
|
|
86
35
|
fixable: "code",
|
|
@@ -105,143 +54,5 @@ const enforceAaaStructureRule = {
|
|
|
105
54
|
type: "problem",
|
|
106
55
|
},
|
|
107
56
|
};
|
|
108
|
-
/**
|
|
109
|
-
* Reports section comments that are missing a blank line above them.
|
|
110
|
-
* @param context ESLint rule context.
|
|
111
|
-
* @param analysis Parsed test-block analysis.
|
|
112
|
-
* @example
|
|
113
|
-
* ```typescript
|
|
114
|
-
* reportBlankLineSeparators({ report() {} } as never, { sectionComments: [], sourceText: "" } as never);
|
|
115
|
-
* ```
|
|
116
|
-
*/
|
|
117
|
-
function reportBlankLineSeparators(context, analysis) {
|
|
118
|
-
const firstSectionComment = analysis.sectionComments[0]?.comment;
|
|
119
|
-
for (const sectionComment of getPhaseBoundaryComments(analysis)) {
|
|
120
|
-
if (sectionComment.comment !== firstSectionComment &&
|
|
121
|
-
!hasBlankLineBeforeComment(analysis.sourceText, sectionComment.comment)) {
|
|
122
|
-
context.report({
|
|
123
|
-
data: { section: sectionComment.phases.join(" & ") },
|
|
124
|
-
fix: (fixer) => fixer.insertTextBeforeRange(getLineStartRange(analysis.sourceText, sectionComment.comment.loc.start.line), analysis.newline),
|
|
125
|
-
messageId: "blankLineBeforeSection",
|
|
126
|
-
node: sectionComment.comment,
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Reports executable statements that appear before the first Arrange section.
|
|
133
|
-
* @param context ESLint rule context.
|
|
134
|
-
* @param analysis Parsed test-block analysis.
|
|
135
|
-
* @example
|
|
136
|
-
* ```typescript
|
|
137
|
-
* reportCodeBeforeArrange({ report() {} } as never, { sectionComments: [], statements: [] } as never);
|
|
138
|
-
* ```
|
|
139
|
-
*/
|
|
140
|
-
function reportCodeBeforeArrange(context, analysis) {
|
|
141
|
-
const firstArrangeLine = analysis.sectionComments.find((sectionComment) => sectionComment.phases.includes("Arrange"))?.comment.loc.start.line;
|
|
142
|
-
if (firstArrangeLine === void 0) {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
const statementBeforeArrange = analysis.statements.find((statement) => statement.node.loc.start.line < firstArrangeLine);
|
|
146
|
-
if (statementBeforeArrange === void 0) {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
context.report({
|
|
150
|
-
messageId: "codeBeforeArrange",
|
|
151
|
-
node: statementBeforeArrange.node,
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Reports sections that contain only comments or whitespace.
|
|
156
|
-
* @param context ESLint rule context.
|
|
157
|
-
* @param analysis Parsed test-block analysis.
|
|
158
|
-
* @example
|
|
159
|
-
* ```typescript
|
|
160
|
-
* reportEmptySections({ report() {} } as never, { sectionComments: [], statements: [] } as never);
|
|
161
|
-
* ```
|
|
162
|
-
*/
|
|
163
|
-
function reportEmptySections(context, analysis) {
|
|
164
|
-
for (const [index, sectionComment] of analysis.sectionComments.entries()) {
|
|
165
|
-
const nextSectionLine = analysis.sectionComments[index + 1]?.comment.loc.start.line;
|
|
166
|
-
const hasCodeInSection = analysis.statements.some((statement) => {
|
|
167
|
-
const statementLine = statement.node.loc.start.line;
|
|
168
|
-
return (statementLine > sectionComment.comment.loc.start.line &&
|
|
169
|
-
(nextSectionLine === void 0 || statementLine < nextSectionLine));
|
|
170
|
-
});
|
|
171
|
-
if (!hasCodeInSection) {
|
|
172
|
-
context.report({
|
|
173
|
-
data: { section: sectionComment.phases.join(" & ") },
|
|
174
|
-
messageId: "emptySection",
|
|
175
|
-
node: sectionComment.comment,
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Reports a single out-of-order section pair.
|
|
182
|
-
* @param context ESLint rule context.
|
|
183
|
-
* @param previous Previous section comment.
|
|
184
|
-
* @param current Current section comment.
|
|
185
|
-
* @example
|
|
186
|
-
* ```typescript
|
|
187
|
-
* reportIfOutOfOrder({ report() {} } as never, { comment: {} as never, phases: [] }, { comment: {} as never, phases: [] });
|
|
188
|
-
* ```
|
|
189
|
-
*/
|
|
190
|
-
function reportIfOutOfOrder(context, previous, current) {
|
|
191
|
-
const maxPreviousOrder = Math.max(...previous.phases.map((phase) => aaaPhaseOrder[phase]));
|
|
192
|
-
const minCurrentOrder = Math.min(...current.phases.map((phase) => aaaPhaseOrder[phase]));
|
|
193
|
-
if (minCurrentOrder <= maxPreviousOrder) {
|
|
194
|
-
context.report({
|
|
195
|
-
data: { section: current.phases.join(" & ") },
|
|
196
|
-
messageId: "outOfOrderSection",
|
|
197
|
-
node: current.comment,
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Reports any AAA section markers that are missing from a supported test block.
|
|
203
|
-
* @param context ESLint rule context.
|
|
204
|
-
* @param analysis Parsed test-block analysis.
|
|
205
|
-
* @example
|
|
206
|
-
* ```typescript
|
|
207
|
-
* reportMissingSections({ report() {} } as never, { sectionComments: [] } as never);
|
|
208
|
-
* ```
|
|
209
|
-
*/
|
|
210
|
-
function reportMissingSections(context, analysis) {
|
|
211
|
-
const presentSections = new Set(analysis.sectionComments.flatMap((sectionComment) => sectionComment.phases));
|
|
212
|
-
const hasPreSectionStatements = analysis.statements.some((statement) => statement.phases.length === 0);
|
|
213
|
-
const missingSections = ["Arrange", "Act", "Assert"].filter((phase) => !presentSections.has(phase) &&
|
|
214
|
-
(phase !== "Arrange" || hasPreSectionStatements));
|
|
215
|
-
if (missingSections.length === 0) {
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
context.report({
|
|
219
|
-
data: { sections: missingSections.join(", ") },
|
|
220
|
-
fix: analysis.bodyLineCount >= 3
|
|
221
|
-
? (fixer) => buildMissingSectionFixes(analysis, missingSections, fixer)
|
|
222
|
-
: void 0,
|
|
223
|
-
messageId: "missingSections",
|
|
224
|
-
node: analysis.callExpression,
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Reports section comments that appear out of canonical Arrange -> Act -> Assert order.
|
|
229
|
-
* @param context ESLint rule context.
|
|
230
|
-
* @param analysis Parsed test-block analysis.
|
|
231
|
-
* @example
|
|
232
|
-
* ```typescript
|
|
233
|
-
* reportOutOfOrderSections({ report() {} } as never, { sectionComments: [] } as never);
|
|
234
|
-
* ```
|
|
235
|
-
*/
|
|
236
|
-
function reportOutOfOrderSections(context, analysis) {
|
|
237
|
-
const comments = analysis.sectionComments;
|
|
238
|
-
const lastIndex = comments.length - 1;
|
|
239
|
-
for (let index = 0; index < lastIndex; index += 1) {
|
|
240
|
-
const previous = comments[index];
|
|
241
|
-
const current = comments[index + 1];
|
|
242
|
-
if (previous && current)
|
|
243
|
-
reportIfOutOfOrder(context, previous, current);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
57
|
export { enforceAaaStructureRule };
|
|
247
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kb21haW4vdGVzdGluZy9lbmZvcmNlLWFhYS1zdHJ1Y3R1cmUvcnVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM1RCxPQUFPLEVBQ0wsYUFBYSxFQUNiLG9CQUFvQixFQUNwQixpQkFBaUIsRUFDakIsd0JBQXdCLEdBQ3pCLE1BQU0sa0NBQWtDLENBQUM7QUFDMUMsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDbkYsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sb0RBQW9ELENBQUM7QUFDakcsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFtQ25FOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxrQkFBa0IsR0FBRyxDQUFDLEtBQThCLEVBQVEsRUFBRTtJQUNsRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsR0FBRyxLQUFLLENBQUM7SUFFOUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUNiLElBQUksRUFBRSxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsS0FBSyxFQUFFO1FBQ2hDLFNBQVM7UUFDVCxJQUFJLEVBQUUsT0FBTyxDQUFDLE9BQU87S0FDdEIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDO0FBRUY7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxNQUFNLGtCQUFrQixHQUFHLENBQUMsS0FBOEIsRUFBVSxFQUFFO0lBQ3BFLE1BQU0sRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsR0FBRyxLQUFLLENBQUM7SUFFL0QsSUFBSSxVQUFVLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ2xDLGtCQUFrQixDQUFDLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQ3hFLE9BQU8sY0FBYyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxNQUFNLGlCQUFpQixHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkQsSUFBSSxpQkFBaUIsR0FBRyxjQUFjLEVBQUUsQ0FBQztRQUN2QyxrQkFBa0IsQ0FBQyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVELFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlCLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztBQUNyRCxDQUFDLENBQUM7QUFFRixrRkFBa0Y7QUFDbEYsTUFBTSx1QkFBdUIsR0FBb0I7SUFDL0MsTUFBTSxDQUFDLE9BQXlCO1FBQzlCLE9BQU87WUFDTCxjQUFjLENBQUMsSUFBSTtnQkFDakIsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUNqRCxJQUFJLFFBQVEsS0FBSyxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUN4QixPQUFPO2dCQUNULENBQUM7Z0JBRUQsTUFBTSxpQkFBaUIsR0FBRyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDekQsTUFBTSxVQUFVLEdBQUcsSUFBSSxHQUFHLEVBQXlCLENBQUM7Z0JBQ3BELElBQUksY0FBYyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUV4QixLQUFLLE1BQU0sT0FBTyxJQUFJLGlCQUFpQixFQUFFLENBQUM7b0JBQ3hDLGNBQWMsR0FBRyxrQkFBa0IsQ0FBQzt3QkFDbEMsT0FBTzt3QkFDUCxjQUFjO3dCQUNkLE9BQU87d0JBQ1AsVUFBVTtxQkFDWCxDQUFDLENBQUM7Z0JBQ0wsQ0FBQztnQkFFRCxxQkFBcUIsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0JBQ3pDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDdkMsd0JBQXdCLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUM1Qyx1QkFBdUIsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0JBQzNDLHlCQUF5QixDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDN0MsMkJBQTJCLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ2pELENBQUM7U0FDMEIsQ0FBQztJQUNoQyxDQUFDO0lBQ0QsSUFBSSxFQUFFO1FBQ0osSUFBSSxFQUFFLHVCQUF1QixDQUMzQix1QkFBdUIsRUFDdkIsc0lBQXNJLENBQ3ZJO1FBQ0QsT0FBTyxFQUFFLE1BQU07UUFDZixRQUFRLEVBQUU7WUFDUixlQUFlLEVBQ2IsOEVBQThFO1lBQ2hGLHNCQUFzQixFQUNwQixpRkFBaUY7WUFDbkYsY0FBYyxFQUFFLDJDQUEyQztZQUMzRCxlQUFlLEVBQUUsMkNBQTJDO1lBQzVELHNCQUFzQixFQUNwQixnRUFBZ0U7WUFDbEUsaUJBQWlCLEVBQ2YsbUVBQW1FO1lBQ3JFLGdCQUFnQixFQUNkLDREQUE0RDtZQUM5RCxZQUFZLEVBQ1YsNEVBQTRFO1lBQzlFLFlBQVksRUFDViwyRkFBMkY7WUFDN0Ysb0JBQW9CLEVBQ2xCLGdHQUFnRztZQUNsRyxlQUFlLEVBQUUscURBQXFEO1lBQ3RFLGdCQUFnQixFQUNkLDJEQUEyRDtZQUM3RCxvQkFBb0IsRUFDbEIsOEVBQThFO1lBQ2hGLGlCQUFpQixFQUNmLDBEQUEwRDtZQUM1RCxhQUFhLEVBQ1gsMkVBQTJFO1NBQzlFO1FBQ0QsTUFBTSxFQUFFLEVBQUU7UUFDVixJQUFJLEVBQUUsU0FBUztLQUNoQjtDQUNGLENBQUM7QUFFRjs7Ozs7Ozs7R0FRRztBQUNILFNBQVMseUJBQXlCLENBQ2hDLE9BQXlCLEVBQ3pCLFFBQTJCO0lBRTNCLE1BQU0sbUJBQW1CLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUM7SUFFakUsS0FBSyxNQUFNLGNBQWMsSUFBSSx3QkFBd0IsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQ2hFLElBQ0UsY0FBYyxDQUFDLE9BQU8sS0FBSyxtQkFBbUI7WUFDOUMsQ0FBQyx5QkFBeUIsQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxPQUFPLENBQUMsRUFDdkUsQ0FBQztZQUNELE9BQU8sQ0FBQyxNQUFNLENBQUM7Z0JBQ2IsSUFBSSxFQUFFLEVBQUUsT0FBTyxFQUFFLGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUNwRCxHQUFHLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUNiLEtBQUssQ0FBQyxxQkFBcUIsQ0FDekIsaUJBQWlCLENBQ2YsUUFBUSxDQUFDLFVBQVUsRUFDbkIsY0FBYyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FDdEMsRUFDRCxRQUFRLENBQUMsT0FBTyxDQUNqQjtnQkFDSCxTQUFTLEVBQUUsd0JBQXdCO2dCQUNuQyxJQUFJLEVBQUUsY0FBYyxDQUFDLE9BQU87YUFDN0IsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFTLHVCQUF1QixDQUM5QixPQUF5QixFQUN6QixRQUEyQjtJQUUzQixNQUFNLGdCQUFnQixHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FDeEUsY0FBYyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQzFDLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDO0lBQzFCLElBQUksZ0JBQWdCLEtBQUssS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNoQyxPQUFPO0lBQ1QsQ0FBQztJQUVELE1BQU0sc0JBQXNCLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQ3JELENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLGdCQUFnQixDQUNoRSxDQUFDO0lBQ0YsSUFBSSxzQkFBc0IsS0FBSyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3RDLE9BQU87SUFDVCxDQUFDO0lBRUQsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUNiLFNBQVMsRUFBRSxtQkFBbUI7UUFDOUIsSUFBSSxFQUFFLHNCQUFzQixDQUFDLElBQUk7S0FDbEMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBUyxtQkFBbUIsQ0FDMUIsT0FBeUIsRUFDekIsUUFBMkI7SUFFM0IsS0FBSyxNQUFNLENBQUMsS0FBSyxFQUFFLGNBQWMsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztRQUN6RSxNQUFNLGVBQWUsR0FDbkIsUUFBUSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDO1FBQzlELE1BQU0sZ0JBQWdCLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRTtZQUM5RCxNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDO1lBRXBELE9BQU8sQ0FDTCxhQUFhLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUk7Z0JBQ3JELENBQUMsZUFBZSxLQUFLLEtBQUssQ0FBQyxJQUFJLGFBQWEsR0FBRyxlQUFlLENBQUMsQ0FDaEUsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDdEIsT0FBTyxDQUFDLE1BQU0sQ0FBQztnQkFDYixJQUFJLEVBQUUsRUFBRSxPQUFPLEVBQUUsY0FBYyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQ3BELFNBQVMsRUFBRSxjQUFjO2dCQUN6QixJQUFJLEVBQUUsY0FBYyxDQUFDLE9BQU87YUFDN0IsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsU0FBUyxrQkFBa0IsQ0FDekIsT0FBeUIsRUFDekIsUUFBd0IsRUFDeEIsT0FBdUI7SUFFdkIsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUMvQixHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FDeEQsQ0FBQztJQUNGLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQzlCLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUN2RCxDQUFDO0lBRUYsSUFBSSxlQUFlLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztRQUN4QyxPQUFPLENBQUMsTUFBTSxDQUFDO1lBQ2IsSUFBSSxFQUFFLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQzdDLFNBQVMsRUFBRSxtQkFBbUI7WUFDOUIsSUFBSSxFQUFFLE9BQU8sQ0FBQyxPQUFPO1NBQ3RCLENBQUMsQ0FBQztJQUNMLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFTLHFCQUFxQixDQUM1QixPQUF5QixFQUN6QixRQUEyQjtJQUUzQixNQUFNLGVBQWUsR0FBRyxJQUFJLEdBQUcsQ0FDN0IsUUFBUSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxjQUFjLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FDNUUsQ0FBQztJQUNGLE1BQU0sdUJBQXVCLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQ3RELENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQzdDLENBQUM7SUFDRixNQUFNLGVBQWUsR0FBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsUUFBUSxDQUFXLENBQUMsTUFBTSxDQUNwRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQ1IsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQztRQUMzQixDQUFDLEtBQUssS0FBSyxTQUFTLElBQUksdUJBQXVCLENBQUMsQ0FDbkQsQ0FBQztJQUVGLElBQUksZUFBZSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNqQyxPQUFPO0lBQ1QsQ0FBQztJQUVELE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDYixJQUFJLEVBQUUsRUFBRSxRQUFRLEVBQUUsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUM5QyxHQUFHLEVBQ0QsUUFBUSxDQUFDLGFBQWEsSUFBSSxDQUFDO1lBQ3pCLENBQUMsQ0FBQyxDQUFDLEtBQXFCLEVBQWMsRUFBRSxDQUNwQyx3QkFBd0IsQ0FBQyxRQUFRLEVBQUUsZUFBZSxFQUFFLEtBQUssQ0FBQztZQUM5RCxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQ1osU0FBUyxFQUFFLGlCQUFpQjtRQUM1QixJQUFJLEVBQUUsUUFBUSxDQUFDLGNBQWM7S0FDOUIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBUyx3QkFBd0IsQ0FDL0IsT0FBeUIsRUFDekIsUUFBMkI7SUFFM0IsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQztJQUMxQyxNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUV0QyxLQUFLLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUcsU0FBUyxFQUFFLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUNsRCxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDakMsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztRQUVwQyxJQUFJLFFBQVEsSUFBSSxPQUFPO1lBQUUsa0JBQWtCLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUMxRSxDQUFDO0FBQ0gsQ0FBQztBQUVELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBSdWxlIH0gZnJvbSBcImVzbGludFwiO1xuXG5pbXBvcnQgdHlwZSB7IFNlY3Rpb25Db21tZW50LCBUZXN0QmxvY2tBbmFseXNpcyB9IGZyb20gXCIuLi9hYWEvdHlwZXNcIjtcblxuaW1wb3J0IHsgY3JlYXRlUnVsZURvY3VtZW50YXRpb24gfSBmcm9tIFwiLi4vLi4vY3VzdG9tLXJ1bGUtZG9jdW1lbnRhdGlvblwiO1xuaW1wb3J0IHsgYW5hbHl6ZVRlc3RCbG9jayB9IGZyb20gXCIuLi9hYWEvYW5hbHl6ZXIuYW5hbHlzaXNcIjtcbmltcG9ydCB7XG4gIGFhYVBoYXNlT3JkZXIsXG4gIGdldEZsYXR0ZW5lZFNlY3Rpb25zLFxuICBnZXRMaW5lU3RhcnRSYW5nZSxcbiAgZ2V0UGhhc2VCb3VuZGFyeUNvbW1lbnRzLFxufSBmcm9tIFwiLi4vYWFhL2FuYWx5emVyLmFuYWx5c2lzLmhlbHBlcnNcIjtcbmltcG9ydCB7IGhhc0JsYW5rTGluZUJlZm9yZUNvbW1lbnQgfSBmcm9tIFwiLi4vYWFhL2FuYWx5emVyLmNsYXNzaWZpY2F0aW9uLmhlbHBlcnNcIjtcbmltcG9ydCB7IHJlcG9ydFBoYXNlUHVyaXR5VmlvbGF0aW9ucyB9IGZyb20gXCIuLi9lbmZvcmNlLWFhYS1waGFzZS1wdXJpdHkvcGhhc2UtcHVyaXR5LXJlcG9ydGluZ1wiO1xuaW1wb3J0IHsgYnVpbGRNaXNzaW5nU2VjdGlvbkZpeGVzIH0gZnJvbSBcIi4vbWlzc2luZy1zZWN0aW9uLWZpeGVzXCI7XG5cbi8qKiBGbGF0dGVuZWQgc2VjdGlvbiBlbnRyeSBlbWl0dGVkIGJ5IHRoZSBBQUEgYW5hbHl6ZXIgaGVscGVyLiAqL1xudHlwZSBGbGF0dGVuZWRTZWN0aW9uID0gUmV0dXJuVHlwZTx0eXBlb2YgZ2V0RmxhdHRlbmVkU2VjdGlvbnM+W251bWJlcl07XG5cbi8qKiBVbmlvbiBvZiB2YWxpZCBBQUEgcGhhc2UgbGFiZWxzIGVtaXR0ZWQgZm9yIGZsYXR0ZW5lZCBzZWN0aW9ucy4gKi9cbnR5cGUgRmxhdHRlbmVkU2VjdGlvblBoYXNlID0gRmxhdHRlbmVkU2VjdGlvbltcInBoYXNlXCJdO1xuXG4vKiogQ29tcG9zaXRlIGlucHV0IGZvciByZXBvcnRpbmcgb25lIEFBQSBzZWN0aW9uIGlzc3VlLiAqL1xuaW50ZXJmYWNlIFJlcG9ydFNlY3Rpb25Jc3N1ZUlucHV0IHtcbiAgLyoqIEFjdGl2ZSBFU0xpbnQgcnVsZSBjb250ZXh0LiAqL1xuICBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0O1xuXG4gIC8qKiBNZXNzYWdlIGlkZW50aWZpZXIgdG8gcmVwb3J0IGZvciB0aGUgc2VjdGlvbi4gKi9cbiAgbWVzc2FnZUlkOiBcImR1cGxpY2F0ZVNlY3Rpb25cIiB8IFwiaW52YWxpZE9yZGVyXCI7XG5cbiAgLyoqIFNlY3Rpb24gY29tbWVudCBhbmQgcGhhc2UgbWV0YWRhdGEgdW5kZXIgaW5zcGVjdGlvbi4gKi9cbiAgc2VjdGlvbjogRmxhdHRlbmVkU2VjdGlvbjtcbn1cblxuLyoqIENvbXBvc2l0ZSBpbnB1dCBmb3IgYWR2YW5jaW5nIHRoZSBBQUEgc2VjdGlvbiBvcmRlcmluZyBzdGF0ZS4gKi9cbmludGVyZmFjZSBVcGRhdGVTZWN0aW9uT3JkZXJJbnB1dCB7XG4gIC8qKiBBY3RpdmUgRVNMaW50IHJ1bGUgY29udGV4dC4gKi9cbiAgY29udGV4dDogUnVsZS5SdWxlQ29udGV4dDtcblxuICAvKiogSGlnaGVzdCBwaGFzZSBvcmRlciBzZWVuIHNvIGZhci4gKi9cbiAgbGFzdFBoYXNlT3JkZXI6IG51bWJlcjtcblxuICAvKiogU2VjdGlvbiBjb21tZW50IGFuZCBwaGFzZSBtZXRhZGF0YSB1bmRlciBpbnNwZWN0aW9uLiAqL1xuICBzZWN0aW9uOiBGbGF0dGVuZWRTZWN0aW9uO1xuXG4gIC8qKiBTZXQgb2YgcGhhc2VzIGFscmVhZHkgc2VlbiBpbiB0aGUgY3VycmVudCB0ZXN0IGJsb2NrLiAqL1xuICBzZWVuUGhhc2VzOiBTZXQ8RmxhdHRlbmVkU2VjdGlvblBoYXNlPjtcbn1cblxuLyoqXG4gKiBSZXBvcnRzIGEgZHVwbGljYXRlIG9yIG91dC1vZi1vcmRlciBBQUEgc2VjdGlvbiBjb21tZW50LlxuICogQHBhcmFtIGlucHV0IENvbXBvc2l0ZSByZXBvcnRpbmcgaW5wdXQgZm9yIHRoZSBjdXJyZW50IHNlY3Rpb24uXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogcmVwb3J0U2VjdGlvbklzc3VlKHtcbiAqICAgY29udGV4dDoge30gYXMgUnVsZS5SdWxlQ29udGV4dCxcbiAqICAgbWVzc2FnZUlkOiBcImR1cGxpY2F0ZVNlY3Rpb25cIixcbiAqICAgc2VjdGlvbjoge30gYXMgUmV0dXJuVHlwZTx0eXBlb2YgZ2V0RmxhdHRlbmVkU2VjdGlvbnM+W251bWJlcl0sXG4gKiB9KTtcbiAqIGBgYFxuICovXG5jb25zdCByZXBvcnRTZWN0aW9uSXNzdWUgPSAoaW5wdXQ6IFJlcG9ydFNlY3Rpb25Jc3N1ZUlucHV0KTogdm9pZCA9PiB7XG4gIGNvbnN0IHsgY29udGV4dCwgbWVzc2FnZUlkLCBzZWN0aW9uIH0gPSBpbnB1dDtcblxuICBjb250ZXh0LnJlcG9ydCh7XG4gICAgZGF0YTogeyBzZWN0aW9uOiBzZWN0aW9uLnBoYXNlIH0sXG4gICAgbWVzc2FnZUlkLFxuICAgIG5vZGU6IHNlY3Rpb24uY29tbWVudCxcbiAgfSk7XG59O1xuXG4vKipcbiAqIFRyYWNrcyB0aGUgY3VycmVudCBBQUEgb3JkZXJpbmcgc3RhdGUgZm9yIG9uZSBmbGF0dGVuZWQgc2VjdGlvbi5cbiAqIEBwYXJhbSBpbnB1dCBDb21wb3NpdGUgb3JkZXJpbmcgc3RhdGUgZm9yIHRoZSBjdXJyZW50IHNlY3Rpb24uXG4gKiBAcmV0dXJucyBVcGRhdGVkIHBoYXNlIG9yZGVyIHdhdGVybWFyay5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBuZXh0T3JkZXIgPSB1cGRhdGVTZWN0aW9uT3JkZXIoe1xuICogICBjb250ZXh0OiB7fSBhcyBSdWxlLlJ1bGVDb250ZXh0LFxuICogICBsYXN0UGhhc2VPcmRlcjogLTEsXG4gKiAgIHNlY3Rpb246IHt9IGFzIFJldHVyblR5cGU8dHlwZW9mIGdldEZsYXR0ZW5lZFNlY3Rpb25zPltudW1iZXJdLFxuICogICBzZWVuUGhhc2VzOiBuZXcgU2V0KCksXG4gKiB9KTtcbiAqIHZvaWQgbmV4dE9yZGVyO1xuICogYGBgXG4gKi9cbmNvbnN0IHVwZGF0ZVNlY3Rpb25PcmRlciA9IChpbnB1dDogVXBkYXRlU2VjdGlvbk9yZGVySW5wdXQpOiBudW1iZXIgPT4ge1xuICBjb25zdCB7IGNvbnRleHQsIGxhc3RQaGFzZU9yZGVyLCBzZWN0aW9uLCBzZWVuUGhhc2VzIH0gPSBpbnB1dDtcblxuICBpZiAoc2VlblBoYXNlcy5oYXMoc2VjdGlvbi5waGFzZSkpIHtcbiAgICByZXBvcnRTZWN0aW9uSXNzdWUoeyBjb250ZXh0LCBtZXNzYWdlSWQ6IFwiZHVwbGljYXRlU2VjdGlvblwiLCBzZWN0aW9uIH0pO1xuICAgIHJldHVybiBsYXN0UGhhc2VPcmRlcjtcbiAgfVxuXG4gIGNvbnN0IGN1cnJlbnRQaGFzZU9yZGVyID0gYWFhUGhhc2VPcmRlcltzZWN0aW9uLnBoYXNlXTtcbiAgaWYgKGN1cnJlbnRQaGFzZU9yZGVyIDwgbGFzdFBoYXNlT3JkZXIpIHtcbiAgICByZXBvcnRTZWN0aW9uSXNzdWUoeyBjb250ZXh0LCBtZXNzYWdlSWQ6IFwiaW52YWxpZE9yZGVyXCIsIHNlY3Rpb24gfSk7XG4gIH1cblxuICBzZWVuUGhhc2VzLmFkZChzZWN0aW9uLnBoYXNlKTtcbiAgcmV0dXJuIE1hdGgubWF4KGxhc3RQaGFzZU9yZGVyLCBjdXJyZW50UGhhc2VPcmRlcik7XG59O1xuXG4vKiogRW5mb3JjZXMgYSBzaW5nbGUgQXJyYW5nZS9BY3QvQXNzZXJ0IHNlcXVlbmNlIGluc2lkZSBzdXBwb3J0ZWQgdGVzdCBibG9ja3MuICovXG5jb25zdCBlbmZvcmNlQWFhU3RydWN0dXJlUnVsZTogUnVsZS5SdWxlTW9kdWxlID0ge1xuICBjcmVhdGUoY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCk6IFJ1bGUuUnVsZUxpc3RlbmVyIHtcbiAgICByZXR1cm4ge1xuICAgICAgQ2FsbEV4cHJlc3Npb24obm9kZSk6IHZvaWQge1xuICAgICAgICBjb25zdCBhbmFseXNpcyA9IGFuYWx5emVUZXN0QmxvY2soY29udGV4dCwgbm9kZSk7XG4gICAgICAgIGlmIChhbmFseXNpcyA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmxhdHRlbmVkU2VjdGlvbnMgPSBnZXRGbGF0dGVuZWRTZWN0aW9ucyhhbmFseXNpcyk7XG4gICAgICAgIGNvbnN0IHNlZW5QaGFzZXMgPSBuZXcgU2V0PEZsYXR0ZW5lZFNlY3Rpb25QaGFzZT4oKTtcbiAgICAgICAgbGV0IGxhc3RQaGFzZU9yZGVyID0gLTE7XG5cbiAgICAgICAgZm9yIChjb25zdCBzZWN0aW9uIG9mIGZsYXR0ZW5lZFNlY3Rpb25zKSB7XG4gICAgICAgICAgbGFzdFBoYXNlT3JkZXIgPSB1cGRhdGVTZWN0aW9uT3JkZXIoe1xuICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgIGxhc3RQaGFzZU9yZGVyLFxuICAgICAgICAgICAgc2VjdGlvbixcbiAgICAgICAgICAgIHNlZW5QaGFzZXMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXBvcnRNaXNzaW5nU2VjdGlvbnMoY29udGV4dCwgYW5hbHlzaXMpO1xuICAgICAgICByZXBvcnRFbXB0eVNlY3Rpb25zKGNvbnRleHQsIGFuYWx5c2lzKTtcbiAgICAgICAgcmVwb3J0T3V0T2ZPcmRlclNlY3Rpb25zKGNvbnRleHQsIGFuYWx5c2lzKTtcbiAgICAgICAgcmVwb3J0Q29kZUJlZm9yZUFycmFuZ2UoY29udGV4dCwgYW5hbHlzaXMpO1xuICAgICAgICByZXBvcnRCbGFua0xpbmVTZXBhcmF0b3JzKGNvbnRleHQsIGFuYWx5c2lzKTtcbiAgICAgICAgcmVwb3J0UGhhc2VQdXJpdHlWaW9sYXRpb25zKGNvbnRleHQsIGFuYWx5c2lzKTtcbiAgICAgIH0sXG4gICAgfSBzYXRpc2ZpZXMgUnVsZS5SdWxlTGlzdGVuZXI7XG4gIH0sXG4gIG1ldGE6IHtcbiAgICBkb2NzOiBjcmVhdGVSdWxlRG9jdW1lbnRhdGlvbihcbiAgICAgIFwiZW5mb3JjZS1hYWEtc3RydWN0dXJlXCIsXG4gICAgICBcIlJlcXVpcmUgZXhwbGljaXQgQUFBIG1hcmtlcnMsIGVuZm9yY2Ugc2VjdGlvbiBvcmRlciBhbmQgdW5pcXVlbmVzcywgYW5kIGtlZXAgc2V0dXAsIGFjdGlvbiwgYW5kIGFzc2VydGlvbnMgaW4gdGhlaXIgaW50ZW5kZWQgcGhhc2VzLlwiLFxuICAgICksXG4gICAgZml4YWJsZTogXCJjb2RlXCIsXG4gICAgbWVzc2FnZXM6IHtcbiAgICAgIGFjdGlvbkluQXJyYW5nZTpcbiAgICAgICAgXCJLZWVwIHRoZSBmdW5jdGlvbiB1bmRlciB0ZXN0IG91dCBvZiBBcnJhbmdlOyByZXNlcnZlIEFycmFuZ2UgZm9yIHNldHVwIG9ubHkuXCIsXG4gICAgICBhc3NlcnRpb25PdXRzaWRlQXNzZXJ0OlxuICAgICAgICBcIk1vdmUgYXNzZXJ0aW9ucyBpbnRvIHRoZSAvLyBBc3NlcnQgc2VjdGlvbiBzbyB0ZXN0IGxvZ2ljIGRvZXMgbm90IGxlYWsgZWFybGllci5cIixcbiAgICAgIGFzeW5jSW5BcnJhbmdlOiBcIkRvIG5vdCB0cmlnZ2VyIGFzeW5jIGJlaGF2aW9yIGluIEFycmFuZ2UuXCIsXG4gICAgICBhd2FpdE91dHNpZGVBY3Q6IFwiVXNlIGF3YWl0IG9ubHkgaW5zaWRlIHRoZSAvLyBBY3Qgc2VjdGlvbi5cIixcbiAgICAgIGJsYW5rTGluZUJlZm9yZVNlY3Rpb246XG4gICAgICAgIFwiSW5zZXJ0IGEgYmxhbmsgbGluZSBiZWZvcmUgdGhlIC8vIHt7c2VjdGlvbn19IHNlY3Rpb24gY29tbWVudC5cIixcbiAgICAgIGNvZGVCZWZvcmVBcnJhbmdlOlxuICAgICAgICBcIk1vdmUgc2V0dXAgc3RhdGVtZW50cyBiZWxvdyB0aGUgZmlyc3QgLy8gQXJyYW5nZSBzZWN0aW9uIGNvbW1lbnQuXCIsXG4gICAgICBkdXBsaWNhdGVTZWN0aW9uOlxuICAgICAgICBcIlVzZSB0aGUgLy8ge3tzZWN0aW9ufX0gc2VjdGlvbiBjb21tZW50IG9ubHkgb25jZSBwZXIgdGVzdC5cIixcbiAgICAgIGVtcHR5U2VjdGlvbjpcbiAgICAgICAgXCJUaGUgLy8ge3tzZWN0aW9ufX0gc2VjdGlvbiBtdXN0IGNvbnRhaW4gY29kZTsgY29tbWVudHMgYWxvbmUgZG8gbm90IGNvdW50LlwiLFxuICAgICAgaW52YWxpZE9yZGVyOlxuICAgICAgICBcIk1vdmUgdGhlIC8vIHt7c2VjdGlvbn19IHNlY3Rpb24gY29tbWVudCBzbyBBQUEgcGhhc2VzIHN0YXkgaW4gQXJyYW5nZSwgQWN0LCBBc3NlcnQgb3JkZXIuXCIsXG4gICAgICBtaXNzaW5nTWVhbmluZ2Z1bEFjdDpcbiAgICAgICAgXCJUaGUgLy8gQWN0IHNlY3Rpb24gbXVzdCBjb250YWluIGEgbWVhbmluZ2Z1bCBTVVQgaW50ZXJhY3Rpb24sIG5vdCBvbmx5IHV0aWxpdHkgb3Igc2V0dXAgY2FsbHMuXCIsXG4gICAgICBtaXNzaW5nU2VjdGlvbnM6IFwiQWRkIHRoZSBtaXNzaW5nIEFBQSBzZWN0aW9uIGNvbW1lbnRzOiB7e3NlY3Rpb25zfX0uXCIsXG4gICAgICBtdXRhdGlvbkFmdGVyQWN0OlxuICAgICAgICBcIkRvIG5vdCBtdXRhdGUgdGVzdCBkYXRhIGFmdGVyIHRoZSAvLyBBY3Qgc2VjdGlvbiBoYXMgcnVuLlwiLFxuICAgICAgbm9uQXNzZXJ0aW9uSW5Bc3NlcnQ6XG4gICAgICAgIFwiS2VlcCB0aGUgLy8gQXNzZXJ0IHNlY3Rpb24gZm9jdXNlZCBvbiBhc3NlcnRpb25zIGFuZCBhc3NlcnRpb24tbG9jYWwgdmFsdWVzLlwiLFxuICAgICAgb3V0T2ZPcmRlclNlY3Rpb246XG4gICAgICAgIFwiVGhlIC8vIHt7c2VjdGlvbn19IHNlY3Rpb24gY29tbWVudCBhcHBlYXJzIG91dCBvZiBvcmRlci5cIixcbiAgICAgIHNldHVwQWZ0ZXJBY3Q6XG4gICAgICAgIFwiRG8gbm90IGNvbnRpbnVlIGFycmFuZ2luZyB0ZXN0IGRhdGEgYWZ0ZXIgdGhlIC8vIEFjdCBzZWN0aW9uIGhhcyBzdGFydGVkLlwiLFxuICAgIH0sXG4gICAgc2NoZW1hOiBbXSxcbiAgICB0eXBlOiBcInByb2JsZW1cIixcbiAgfSxcbn07XG5cbi8qKlxuICogUmVwb3J0cyBzZWN0aW9uIGNvbW1lbnRzIHRoYXQgYXJlIG1pc3NpbmcgYSBibGFuayBsaW5lIGFib3ZlIHRoZW0uXG4gKiBAcGFyYW0gY29udGV4dCBFU0xpbnQgcnVsZSBjb250ZXh0LlxuICogQHBhcmFtIGFuYWx5c2lzIFBhcnNlZCB0ZXN0LWJsb2NrIGFuYWx5c2lzLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHJlcG9ydEJsYW5rTGluZVNlcGFyYXRvcnMoeyByZXBvcnQoKSB7fSB9IGFzIG5ldmVyLCB7IHNlY3Rpb25Db21tZW50czogW10sIHNvdXJjZVRleHQ6IFwiXCIgfSBhcyBuZXZlcik7XG4gKiBgYGBcbiAqL1xuZnVuY3Rpb24gcmVwb3J0QmxhbmtMaW5lU2VwYXJhdG9ycyhcbiAgY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCxcbiAgYW5hbHlzaXM6IFRlc3RCbG9ja0FuYWx5c2lzLFxuKTogdm9pZCB7XG4gIGNvbnN0IGZpcnN0U2VjdGlvbkNvbW1lbnQgPSBhbmFseXNpcy5zZWN0aW9uQ29tbWVudHNbMF0/LmNvbW1lbnQ7XG5cbiAgZm9yIChjb25zdCBzZWN0aW9uQ29tbWVudCBvZiBnZXRQaGFzZUJvdW5kYXJ5Q29tbWVudHMoYW5hbHlzaXMpKSB7XG4gICAgaWYgKFxuICAgICAgc2VjdGlvbkNvbW1lbnQuY29tbWVudCAhPT0gZmlyc3RTZWN0aW9uQ29tbWVudCAmJlxuICAgICAgIWhhc0JsYW5rTGluZUJlZm9yZUNvbW1lbnQoYW5hbHlzaXMuc291cmNlVGV4dCwgc2VjdGlvbkNvbW1lbnQuY29tbWVudClcbiAgICApIHtcbiAgICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgICAgZGF0YTogeyBzZWN0aW9uOiBzZWN0aW9uQ29tbWVudC5waGFzZXMuam9pbihcIiAmIFwiKSB9LFxuICAgICAgICBmaXg6IChmaXhlcikgPT5cbiAgICAgICAgICBmaXhlci5pbnNlcnRUZXh0QmVmb3JlUmFuZ2UoXG4gICAgICAgICAgICBnZXRMaW5lU3RhcnRSYW5nZShcbiAgICAgICAgICAgICAgYW5hbHlzaXMuc291cmNlVGV4dCxcbiAgICAgICAgICAgICAgc2VjdGlvbkNvbW1lbnQuY29tbWVudC5sb2Muc3RhcnQubGluZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBhbmFseXNpcy5uZXdsaW5lLFxuICAgICAgICAgICksXG4gICAgICAgIG1lc3NhZ2VJZDogXCJibGFua0xpbmVCZWZvcmVTZWN0aW9uXCIsXG4gICAgICAgIG5vZGU6IHNlY3Rpb25Db21tZW50LmNvbW1lbnQsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXBvcnRzIGV4ZWN1dGFibGUgc3RhdGVtZW50cyB0aGF0IGFwcGVhciBiZWZvcmUgdGhlIGZpcnN0IEFycmFuZ2Ugc2VjdGlvbi5cbiAqIEBwYXJhbSBjb250ZXh0IEVTTGludCBydWxlIGNvbnRleHQuXG4gKiBAcGFyYW0gYW5hbHlzaXMgUGFyc2VkIHRlc3QtYmxvY2sgYW5hbHlzaXMuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogcmVwb3J0Q29kZUJlZm9yZUFycmFuZ2UoeyByZXBvcnQoKSB7fSB9IGFzIG5ldmVyLCB7IHNlY3Rpb25Db21tZW50czogW10sIHN0YXRlbWVudHM6IFtdIH0gYXMgbmV2ZXIpO1xuICogYGBgXG4gKi9cbmZ1bmN0aW9uIHJlcG9ydENvZGVCZWZvcmVBcnJhbmdlKFxuICBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0LFxuICBhbmFseXNpczogVGVzdEJsb2NrQW5hbHlzaXMsXG4pOiB2b2lkIHtcbiAgY29uc3QgZmlyc3RBcnJhbmdlTGluZSA9IGFuYWx5c2lzLnNlY3Rpb25Db21tZW50cy5maW5kKChzZWN0aW9uQ29tbWVudCkgPT5cbiAgICBzZWN0aW9uQ29tbWVudC5waGFzZXMuaW5jbHVkZXMoXCJBcnJhbmdlXCIpLFxuICApPy5jb21tZW50LmxvYy5zdGFydC5saW5lO1xuICBpZiAoZmlyc3RBcnJhbmdlTGluZSA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qgc3RhdGVtZW50QmVmb3JlQXJyYW5nZSA9IGFuYWx5c2lzLnN0YXRlbWVudHMuZmluZChcbiAgICAoc3RhdGVtZW50KSA9PiBzdGF0ZW1lbnQubm9kZS5sb2Muc3RhcnQubGluZSA8IGZpcnN0QXJyYW5nZUxpbmUsXG4gICk7XG4gIGlmIChzdGF0ZW1lbnRCZWZvcmVBcnJhbmdlID09PSB2b2lkIDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb250ZXh0LnJlcG9ydCh7XG4gICAgbWVzc2FnZUlkOiBcImNvZGVCZWZvcmVBcnJhbmdlXCIsXG4gICAgbm9kZTogc3RhdGVtZW50QmVmb3JlQXJyYW5nZS5ub2RlLFxuICB9KTtcbn1cblxuLyoqXG4gKiBSZXBvcnRzIHNlY3Rpb25zIHRoYXQgY29udGFpbiBvbmx5IGNvbW1lbnRzIG9yIHdoaXRlc3BhY2UuXG4gKiBAcGFyYW0gY29udGV4dCBFU0xpbnQgcnVsZSBjb250ZXh0LlxuICogQHBhcmFtIGFuYWx5c2lzIFBhcnNlZCB0ZXN0LWJsb2NrIGFuYWx5c2lzLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHJlcG9ydEVtcHR5U2VjdGlvbnMoeyByZXBvcnQoKSB7fSB9IGFzIG5ldmVyLCB7IHNlY3Rpb25Db21tZW50czogW10sIHN0YXRlbWVudHM6IFtdIH0gYXMgbmV2ZXIpO1xuICogYGBgXG4gKi9cbmZ1bmN0aW9uIHJlcG9ydEVtcHR5U2VjdGlvbnMoXG4gIGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQsXG4gIGFuYWx5c2lzOiBUZXN0QmxvY2tBbmFseXNpcyxcbik6IHZvaWQge1xuICBmb3IgKGNvbnN0IFtpbmRleCwgc2VjdGlvbkNvbW1lbnRdIG9mIGFuYWx5c2lzLnNlY3Rpb25Db21tZW50cy5lbnRyaWVzKCkpIHtcbiAgICBjb25zdCBuZXh0U2VjdGlvbkxpbmUgPVxuICAgICAgYW5hbHlzaXMuc2VjdGlvbkNvbW1lbnRzW2luZGV4ICsgMV0/LmNvbW1lbnQubG9jLnN0YXJ0LmxpbmU7XG4gICAgY29uc3QgaGFzQ29kZUluU2VjdGlvbiA9IGFuYWx5c2lzLnN0YXRlbWVudHMuc29tZSgoc3RhdGVtZW50KSA9PiB7XG4gICAgICBjb25zdCBzdGF0ZW1lbnRMaW5lID0gc3RhdGVtZW50Lm5vZGUubG9jLnN0YXJ0LmxpbmU7XG5cbiAgICAgIHJldHVybiAoXG4gICAgICAgIHN0YXRlbWVudExpbmUgPiBzZWN0aW9uQ29tbWVudC5jb21tZW50LmxvYy5zdGFydC5saW5lICYmXG4gICAgICAgIChuZXh0U2VjdGlvbkxpbmUgPT09IHZvaWQgMCB8fCBzdGF0ZW1lbnRMaW5lIDwgbmV4dFNlY3Rpb25MaW5lKVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGlmICghaGFzQ29kZUluU2VjdGlvbikge1xuICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICBkYXRhOiB7IHNlY3Rpb246IHNlY3Rpb25Db21tZW50LnBoYXNlcy5qb2luKFwiICYgXCIpIH0sXG4gICAgICAgIG1lc3NhZ2VJZDogXCJlbXB0eVNlY3Rpb25cIixcbiAgICAgICAgbm9kZTogc2VjdGlvbkNvbW1lbnQuY29tbWVudCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlcG9ydHMgYSBzaW5nbGUgb3V0LW9mLW9yZGVyIHNlY3Rpb24gcGFpci5cbiAqIEBwYXJhbSBjb250ZXh0IEVTTGludCBydWxlIGNvbnRleHQuXG4gKiBAcGFyYW0gcHJldmlvdXMgUHJldmlvdXMgc2VjdGlvbiBjb21tZW50LlxuICogQHBhcmFtIGN1cnJlbnQgQ3VycmVudCBzZWN0aW9uIGNvbW1lbnQuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogcmVwb3J0SWZPdXRPZk9yZGVyKHsgcmVwb3J0KCkge30gfSBhcyBuZXZlciwgeyBjb21tZW50OiB7fSBhcyBuZXZlciwgcGhhc2VzOiBbXSB9LCB7IGNvbW1lbnQ6IHt9IGFzIG5ldmVyLCBwaGFzZXM6IFtdIH0pO1xuICogYGBgXG4gKi9cbmZ1bmN0aW9uIHJlcG9ydElmT3V0T2ZPcmRlcihcbiAgY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCxcbiAgcHJldmlvdXM6IFNlY3Rpb25Db21tZW50LFxuICBjdXJyZW50OiBTZWN0aW9uQ29tbWVudCxcbik6IHZvaWQge1xuICBjb25zdCBtYXhQcmV2aW91c09yZGVyID0gTWF0aC5tYXgoXG4gICAgLi4ucHJldmlvdXMucGhhc2VzLm1hcCgocGhhc2UpID0+IGFhYVBoYXNlT3JkZXJbcGhhc2VdKSxcbiAgKTtcbiAgY29uc3QgbWluQ3VycmVudE9yZGVyID0gTWF0aC5taW4oXG4gICAgLi4uY3VycmVudC5waGFzZXMubWFwKChwaGFzZSkgPT4gYWFhUGhhc2VPcmRlcltwaGFzZV0pLFxuICApO1xuXG4gIGlmIChtaW5DdXJyZW50T3JkZXIgPD0gbWF4UHJldmlvdXNPcmRlcikge1xuICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgIGRhdGE6IHsgc2VjdGlvbjogY3VycmVudC5waGFzZXMuam9pbihcIiAmIFwiKSB9LFxuICAgICAgbWVzc2FnZUlkOiBcIm91dE9mT3JkZXJTZWN0aW9uXCIsXG4gICAgICBub2RlOiBjdXJyZW50LmNvbW1lbnQsXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXBvcnRzIGFueSBBQUEgc2VjdGlvbiBtYXJrZXJzIHRoYXQgYXJlIG1pc3NpbmcgZnJvbSBhIHN1cHBvcnRlZCB0ZXN0IGJsb2NrLlxuICogQHBhcmFtIGNvbnRleHQgRVNMaW50IHJ1bGUgY29udGV4dC5cbiAqIEBwYXJhbSBhbmFseXNpcyBQYXJzZWQgdGVzdC1ibG9jayBhbmFseXNpcy5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiByZXBvcnRNaXNzaW5nU2VjdGlvbnMoeyByZXBvcnQoKSB7fSB9IGFzIG5ldmVyLCB7IHNlY3Rpb25Db21tZW50czogW10gfSBhcyBuZXZlcik7XG4gKiBgYGBcbiAqL1xuZnVuY3Rpb24gcmVwb3J0TWlzc2luZ1NlY3Rpb25zKFxuICBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0LFxuICBhbmFseXNpczogVGVzdEJsb2NrQW5hbHlzaXMsXG4pOiB2b2lkIHtcbiAgY29uc3QgcHJlc2VudFNlY3Rpb25zID0gbmV3IFNldChcbiAgICBhbmFseXNpcy5zZWN0aW9uQ29tbWVudHMuZmxhdE1hcCgoc2VjdGlvbkNvbW1lbnQpID0+IHNlY3Rpb25Db21tZW50LnBoYXNlcyksXG4gICk7XG4gIGNvbnN0IGhhc1ByZVNlY3Rpb25TdGF0ZW1lbnRzID0gYW5hbHlzaXMuc3RhdGVtZW50cy5zb21lKFxuICAgIChzdGF0ZW1lbnQpID0+IHN0YXRlbWVudC5waGFzZXMubGVuZ3RoID09PSAwLFxuICApO1xuICBjb25zdCBtaXNzaW5nU2VjdGlvbnMgPSAoW1wiQXJyYW5nZVwiLCBcIkFjdFwiLCBcIkFzc2VydFwiXSBhcyBjb25zdCkuZmlsdGVyKFxuICAgIChwaGFzZSkgPT5cbiAgICAgICFwcmVzZW50U2VjdGlvbnMuaGFzKHBoYXNlKSAmJlxuICAgICAgKHBoYXNlICE9PSBcIkFycmFuZ2VcIiB8fCBoYXNQcmVTZWN0aW9uU3RhdGVtZW50cyksXG4gICk7XG5cbiAgaWYgKG1pc3NpbmdTZWN0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb250ZXh0LnJlcG9ydCh7XG4gICAgZGF0YTogeyBzZWN0aW9uczogbWlzc2luZ1NlY3Rpb25zLmpvaW4oXCIsIFwiKSB9LFxuICAgIGZpeDpcbiAgICAgIGFuYWx5c2lzLmJvZHlMaW5lQ291bnQgPj0gM1xuICAgICAgICA/IChmaXhlcjogUnVsZS5SdWxlRml4ZXIpOiBSdWxlLkZpeFtdID0+XG4gICAgICAgICAgICBidWlsZE1pc3NpbmdTZWN0aW9uRml4ZXMoYW5hbHlzaXMsIG1pc3NpbmdTZWN0aW9ucywgZml4ZXIpXG4gICAgICAgIDogdm9pZCAwLFxuICAgIG1lc3NhZ2VJZDogXCJtaXNzaW5nU2VjdGlvbnNcIixcbiAgICBub2RlOiBhbmFseXNpcy5jYWxsRXhwcmVzc2lvbixcbiAgfSk7XG59XG5cbi8qKlxuICogUmVwb3J0cyBzZWN0aW9uIGNvbW1lbnRzIHRoYXQgYXBwZWFyIG91dCBvZiBjYW5vbmljYWwgQXJyYW5nZSAtPiBBY3QgLT4gQXNzZXJ0IG9yZGVyLlxuICogQHBhcmFtIGNvbnRleHQgRVNMaW50IHJ1bGUgY29udGV4dC5cbiAqIEBwYXJhbSBhbmFseXNpcyBQYXJzZWQgdGVzdC1ibG9jayBhbmFseXNpcy5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiByZXBvcnRPdXRPZk9yZGVyU2VjdGlvbnMoeyByZXBvcnQoKSB7fSB9IGFzIG5ldmVyLCB7IHNlY3Rpb25Db21tZW50czogW10gfSBhcyBuZXZlcik7XG4gKiBgYGBcbiAqL1xuZnVuY3Rpb24gcmVwb3J0T3V0T2ZPcmRlclNlY3Rpb25zKFxuICBjb250ZXh0OiBSdWxlLlJ1bGVDb250ZXh0LFxuICBhbmFseXNpczogVGVzdEJsb2NrQW5hbHlzaXMsXG4pOiB2b2lkIHtcbiAgY29uc3QgY29tbWVudHMgPSBhbmFseXNpcy5zZWN0aW9uQ29tbWVudHM7XG4gIGNvbnN0IGxhc3RJbmRleCA9IGNvbW1lbnRzLmxlbmd0aCAtIDE7XG5cbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGxhc3RJbmRleDsgaW5kZXggKz0gMSkge1xuICAgIGNvbnN0IHByZXZpb3VzID0gY29tbWVudHNbaW5kZXhdO1xuICAgIGNvbnN0IGN1cnJlbnQgPSBjb21tZW50c1tpbmRleCArIDFdO1xuXG4gICAgaWYgKHByZXZpb3VzICYmIGN1cnJlbnQpIHJlcG9ydElmT3V0T2ZPcmRlcihjb250ZXh0LCBwcmV2aW91cywgY3VycmVudCk7XG4gIH1cbn1cblxuZXhwb3J0IHsgZW5mb3JjZUFhYVN0cnVjdHVyZVJ1bGUgfTtcbiJdfQ==
|
|
58
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kb21haW4vdGVzdGluZy9lbmZvcmNlLWFhYS1zdHJ1Y3R1cmUvcnVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUN4RSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxvREFBb0QsQ0FBQztBQUNqRyxPQUFPLEVBQ0wseUJBQXlCLEVBQ3pCLHVCQUF1QixFQUN2QixtQkFBbUIsRUFDbkIscUJBQXFCLEVBQ3JCLHdCQUF3QixFQUN4QixrQkFBa0IsR0FDbkIsTUFBTSwwQkFBMEIsQ0FBQztBQUVsQyxrRkFBa0Y7QUFDbEYsTUFBTSx1QkFBdUIsR0FBb0I7SUFDL0MsTUFBTSxFQUFFLENBQUMsT0FBeUIsRUFBcUIsRUFBRSxDQUN2RCxDQUFDO1FBQ0MsY0FBYyxDQUFDLElBQUk7WUFDakIsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2pELElBQUksUUFBUSxLQUFLLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3hCLE9BQU87WUFDVCxDQUFDO1lBRUQsTUFBTSxpQkFBaUIsR0FBRyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUN6RCxNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBeUIsQ0FBQztZQUNwRCxJQUFJLGNBQWMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUV4QixLQUFLLE1BQU0sT0FBTyxJQUFJLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3hDLGNBQWMsR0FBRyxrQkFBa0IsQ0FBQztvQkFDbEMsT0FBTztvQkFDUCxjQUFjO29CQUNkLE9BQU87b0JBQ1AsVUFBVTtpQkFDWCxDQUFDLENBQUM7WUFDTCxDQUFDO1lBRUQscUJBQXFCLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3pDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztZQUN2Qyx3QkFBd0IsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDNUMsdUJBQXVCLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzNDLHlCQUF5QixDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztZQUM3QywyQkFBMkIsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDakQsQ0FBQztLQUNGLENBQTZCO0lBQ2hDLElBQUksRUFBRTtRQUNKLElBQUksRUFBRSx1QkFBdUIsQ0FDM0IsdUJBQXVCLEVBQ3ZCLHNJQUFzSSxDQUN2STtRQUNELE9BQU8sRUFBRSxNQUFNO1FBQ2YsUUFBUSxFQUFFO1lBQ1IsZUFBZSxFQUNiLDhFQUE4RTtZQUNoRixzQkFBc0IsRUFDcEIsaUZBQWlGO1lBQ25GLGNBQWMsRUFBRSwyQ0FBMkM7WUFDM0QsZUFBZSxFQUFFLDJDQUEyQztZQUM1RCxzQkFBc0IsRUFDcEIsZ0VBQWdFO1lBQ2xFLGlCQUFpQixFQUNmLG1FQUFtRTtZQUNyRSxnQkFBZ0IsRUFDZCw0REFBNEQ7WUFDOUQsWUFBWSxFQUNWLDRFQUE0RTtZQUM5RSxZQUFZLEVBQ1YsMkZBQTJGO1lBQzdGLG9CQUFvQixFQUNsQixnR0FBZ0c7WUFDbEcsZUFBZSxFQUFFLHFEQUFxRDtZQUN0RSxnQkFBZ0IsRUFDZCwyREFBMkQ7WUFDN0Qsb0JBQW9CLEVBQ2xCLDhFQUE4RTtZQUNoRixpQkFBaUIsRUFDZiwwREFBMEQ7WUFDNUQsYUFBYSxFQUNYLDJFQUEyRTtTQUM5RTtRQUNELE1BQU0sRUFBRSxFQUFFO1FBQ1YsSUFBSSxFQUFFLFNBQVM7S0FDaEI7Q0FDRixDQUFDO0FBRUYsT0FBTyxFQUFFLHVCQUF1QixFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFJ1bGUgfSBmcm9tIFwiZXNsaW50XCI7XG5cbmltcG9ydCB0eXBlIHsgRmxhdHRlbmVkU2VjdGlvblBoYXNlIH0gZnJvbSBcIi4vcnVsZS1zZWN0aW9uLXJlcG9ydGluZ1wiO1xuXG5pbXBvcnQgeyBjcmVhdGVSdWxlRG9jdW1lbnRhdGlvbiB9IGZyb20gXCIuLi8uLi9jdXN0b20tcnVsZS1kb2N1bWVudGF0aW9uXCI7XG5pbXBvcnQgeyBhbmFseXplVGVzdEJsb2NrIH0gZnJvbSBcIi4uL2FhYS9hbmFseXplci5hbmFseXNpc1wiO1xuaW1wb3J0IHsgZ2V0RmxhdHRlbmVkU2VjdGlvbnMgfSBmcm9tIFwiLi4vYWFhL2FuYWx5emVyLmFuYWx5c2lzLmhlbHBlcnNcIjtcbmltcG9ydCB7IHJlcG9ydFBoYXNlUHVyaXR5VmlvbGF0aW9ucyB9IGZyb20gXCIuLi9lbmZvcmNlLWFhYS1waGFzZS1wdXJpdHkvcGhhc2UtcHVyaXR5LXJlcG9ydGluZ1wiO1xuaW1wb3J0IHtcbiAgcmVwb3J0QmxhbmtMaW5lU2VwYXJhdG9ycyxcbiAgcmVwb3J0Q29kZUJlZm9yZUFycmFuZ2UsXG4gIHJlcG9ydEVtcHR5U2VjdGlvbnMsXG4gIHJlcG9ydE1pc3NpbmdTZWN0aW9ucyxcbiAgcmVwb3J0T3V0T2ZPcmRlclNlY3Rpb25zLFxuICB1cGRhdGVTZWN0aW9uT3JkZXIsXG59IGZyb20gXCIuL3J1bGUtc2VjdGlvbi1yZXBvcnRpbmdcIjtcblxuLyoqIEVuZm9yY2VzIGEgc2luZ2xlIEFycmFuZ2UvQWN0L0Fzc2VydCBzZXF1ZW5jZSBpbnNpZGUgc3VwcG9ydGVkIHRlc3QgYmxvY2tzLiAqL1xuY29uc3QgZW5mb3JjZUFhYVN0cnVjdHVyZVJ1bGU6IFJ1bGUuUnVsZU1vZHVsZSA9IHtcbiAgY3JlYXRlOiAoY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCk6IFJ1bGUuUnVsZUxpc3RlbmVyID0+XG4gICAgKHtcbiAgICAgIENhbGxFeHByZXNzaW9uKG5vZGUpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgYW5hbHlzaXMgPSBhbmFseXplVGVzdEJsb2NrKGNvbnRleHQsIG5vZGUpO1xuICAgICAgICBpZiAoYW5hbHlzaXMgPT09IHZvaWQgMCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZsYXR0ZW5lZFNlY3Rpb25zID0gZ2V0RmxhdHRlbmVkU2VjdGlvbnMoYW5hbHlzaXMpO1xuICAgICAgICBjb25zdCBzZWVuUGhhc2VzID0gbmV3IFNldDxGbGF0dGVuZWRTZWN0aW9uUGhhc2U+KCk7XG4gICAgICAgIGxldCBsYXN0UGhhc2VPcmRlciA9IC0xO1xuXG4gICAgICAgIGZvciAoY29uc3Qgc2VjdGlvbiBvZiBmbGF0dGVuZWRTZWN0aW9ucykge1xuICAgICAgICAgIGxhc3RQaGFzZU9yZGVyID0gdXBkYXRlU2VjdGlvbk9yZGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBsYXN0UGhhc2VPcmRlcixcbiAgICAgICAgICAgIHNlY3Rpb24sXG4gICAgICAgICAgICBzZWVuUGhhc2VzLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVwb3J0TWlzc2luZ1NlY3Rpb25zKGNvbnRleHQsIGFuYWx5c2lzKTtcbiAgICAgICAgcmVwb3J0RW1wdHlTZWN0aW9ucyhjb250ZXh0LCBhbmFseXNpcyk7XG4gICAgICAgIHJlcG9ydE91dE9mT3JkZXJTZWN0aW9ucyhjb250ZXh0LCBhbmFseXNpcyk7XG4gICAgICAgIHJlcG9ydENvZGVCZWZvcmVBcnJhbmdlKGNvbnRleHQsIGFuYWx5c2lzKTtcbiAgICAgICAgcmVwb3J0QmxhbmtMaW5lU2VwYXJhdG9ycyhjb250ZXh0LCBhbmFseXNpcyk7XG4gICAgICAgIHJlcG9ydFBoYXNlUHVyaXR5VmlvbGF0aW9ucyhjb250ZXh0LCBhbmFseXNpcyk7XG4gICAgICB9LFxuICAgIH0pIHNhdGlzZmllcyBSdWxlLlJ1bGVMaXN0ZW5lcixcbiAgbWV0YToge1xuICAgIGRvY3M6IGNyZWF0ZVJ1bGVEb2N1bWVudGF0aW9uKFxuICAgICAgXCJlbmZvcmNlLWFhYS1zdHJ1Y3R1cmVcIixcbiAgICAgIFwiUmVxdWlyZSBleHBsaWNpdCBBQUEgbWFya2VycywgZW5mb3JjZSBzZWN0aW9uIG9yZGVyIGFuZCB1bmlxdWVuZXNzLCBhbmQga2VlcCBzZXR1cCwgYWN0aW9uLCBhbmQgYXNzZXJ0aW9ucyBpbiB0aGVpciBpbnRlbmRlZCBwaGFzZXMuXCIsXG4gICAgKSxcbiAgICBmaXhhYmxlOiBcImNvZGVcIixcbiAgICBtZXNzYWdlczoge1xuICAgICAgYWN0aW9uSW5BcnJhbmdlOlxuICAgICAgICBcIktlZXAgdGhlIGZ1bmN0aW9uIHVuZGVyIHRlc3Qgb3V0IG9mIEFycmFuZ2U7IHJlc2VydmUgQXJyYW5nZSBmb3Igc2V0dXAgb25seS5cIixcbiAgICAgIGFzc2VydGlvbk91dHNpZGVBc3NlcnQ6XG4gICAgICAgIFwiTW92ZSBhc3NlcnRpb25zIGludG8gdGhlIC8vIEFzc2VydCBzZWN0aW9uIHNvIHRlc3QgbG9naWMgZG9lcyBub3QgbGVhayBlYXJsaWVyLlwiLFxuICAgICAgYXN5bmNJbkFycmFuZ2U6IFwiRG8gbm90IHRyaWdnZXIgYXN5bmMgYmVoYXZpb3IgaW4gQXJyYW5nZS5cIixcbiAgICAgIGF3YWl0T3V0c2lkZUFjdDogXCJVc2UgYXdhaXQgb25seSBpbnNpZGUgdGhlIC8vIEFjdCBzZWN0aW9uLlwiLFxuICAgICAgYmxhbmtMaW5lQmVmb3JlU2VjdGlvbjpcbiAgICAgICAgXCJJbnNlcnQgYSBibGFuayBsaW5lIGJlZm9yZSB0aGUgLy8ge3tzZWN0aW9ufX0gc2VjdGlvbiBjb21tZW50LlwiLFxuICAgICAgY29kZUJlZm9yZUFycmFuZ2U6XG4gICAgICAgIFwiTW92ZSBzZXR1cCBzdGF0ZW1lbnRzIGJlbG93IHRoZSBmaXJzdCAvLyBBcnJhbmdlIHNlY3Rpb24gY29tbWVudC5cIixcbiAgICAgIGR1cGxpY2F0ZVNlY3Rpb246XG4gICAgICAgIFwiVXNlIHRoZSAvLyB7e3NlY3Rpb259fSBzZWN0aW9uIGNvbW1lbnQgb25seSBvbmNlIHBlciB0ZXN0LlwiLFxuICAgICAgZW1wdHlTZWN0aW9uOlxuICAgICAgICBcIlRoZSAvLyB7e3NlY3Rpb259fSBzZWN0aW9uIG11c3QgY29udGFpbiBjb2RlOyBjb21tZW50cyBhbG9uZSBkbyBub3QgY291bnQuXCIsXG4gICAgICBpbnZhbGlkT3JkZXI6XG4gICAgICAgIFwiTW92ZSB0aGUgLy8ge3tzZWN0aW9ufX0gc2VjdGlvbiBjb21tZW50IHNvIEFBQSBwaGFzZXMgc3RheSBpbiBBcnJhbmdlLCBBY3QsIEFzc2VydCBvcmRlci5cIixcbiAgICAgIG1pc3NpbmdNZWFuaW5nZnVsQWN0OlxuICAgICAgICBcIlRoZSAvLyBBY3Qgc2VjdGlvbiBtdXN0IGNvbnRhaW4gYSBtZWFuaW5nZnVsIFNVVCBpbnRlcmFjdGlvbiwgbm90IG9ubHkgdXRpbGl0eSBvciBzZXR1cCBjYWxscy5cIixcbiAgICAgIG1pc3NpbmdTZWN0aW9uczogXCJBZGQgdGhlIG1pc3NpbmcgQUFBIHNlY3Rpb24gY29tbWVudHM6IHt7c2VjdGlvbnN9fS5cIixcbiAgICAgIG11dGF0aW9uQWZ0ZXJBY3Q6XG4gICAgICAgIFwiRG8gbm90IG11dGF0ZSB0ZXN0IGRhdGEgYWZ0ZXIgdGhlIC8vIEFjdCBzZWN0aW9uIGhhcyBydW4uXCIsXG4gICAgICBub25Bc3NlcnRpb25JbkFzc2VydDpcbiAgICAgICAgXCJLZWVwIHRoZSAvLyBBc3NlcnQgc2VjdGlvbiBmb2N1c2VkIG9uIGFzc2VydGlvbnMgYW5kIGFzc2VydGlvbi1sb2NhbCB2YWx1ZXMuXCIsXG4gICAgICBvdXRPZk9yZGVyU2VjdGlvbjpcbiAgICAgICAgXCJUaGUgLy8ge3tzZWN0aW9ufX0gc2VjdGlvbiBjb21tZW50IGFwcGVhcnMgb3V0IG9mIG9yZGVyLlwiLFxuICAgICAgc2V0dXBBZnRlckFjdDpcbiAgICAgICAgXCJEbyBub3QgY29udGludWUgYXJyYW5naW5nIHRlc3QgZGF0YSBhZnRlciB0aGUgLy8gQWN0IHNlY3Rpb24gaGFzIHN0YXJ0ZWQuXCIsXG4gICAgfSxcbiAgICBzY2hlbWE6IFtdLFxuICAgIHR5cGU6IFwicHJvYmxlbVwiLFxuICB9LFxufTtcblxuZXhwb3J0IHsgZW5mb3JjZUFhYVN0cnVjdHVyZVJ1bGUgfTtcbiJdfQ==
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { assertActualExpectedNamesRule } from "./assert-actual-expected-names/index.js";
|
|
2
2
|
export { enforceAaaStructureRule } from "./enforce-aaa-structure/index.js";
|
|
3
|
+
export { noUnsafeVitestMockFactoryCastRule } from "./no-unsafe-vitest-mock-factory-cast/index.js";
|
|
3
4
|
export { preferViMockedImportRule } from "./prefer-vi-mocked-import/index.js";
|
|
4
5
|
export { requireActResultCaptureRule } from "./require-act-result-capture/index.js";
|
|
5
6
|
export { requireTestCompanionRule } from "./require-test-companion/index.js";
|