gurkencheck 0.0.4
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/LICENSE +13 -0
- package/README.md +327 -0
- package/dist/config-parser.d.ts +21 -0
- package/dist/config-parser.d.ts.map +1 -0
- package/dist/config-parser.js +171 -0
- package/dist/config-parser.js.map +1 -0
- package/dist/config-verifier.d.ts +4 -0
- package/dist/config-verifier.d.ts.map +1 -0
- package/dist/config-verifier.js +81 -0
- package/dist/config-verifier.js.map +1 -0
- package/dist/feature-finder.d.ts +18 -0
- package/dist/feature-finder.d.ts.map +1 -0
- package/dist/feature-finder.js +70 -0
- package/dist/feature-finder.js.map +1 -0
- package/dist/formatters/index.d.ts +23 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +79 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/json.d.ts +31 -0
- package/dist/formatters/json.d.ts.map +1 -0
- package/dist/formatters/json.js +31 -0
- package/dist/formatters/json.js.map +1 -0
- package/dist/formatters/junit.d.ts +17 -0
- package/dist/formatters/junit.d.ts.map +1 -0
- package/dist/formatters/junit.js +61 -0
- package/dist/formatters/junit.js.map +1 -0
- package/dist/formatters/sarif.d.ts +6 -0
- package/dist/formatters/sarif.d.ts.map +1 -0
- package/dist/formatters/sarif.js +81 -0
- package/dist/formatters/sarif.js.map +1 -0
- package/dist/formatters/stylish.d.ts +9 -0
- package/dist/formatters/stylish.d.ts.map +1 -0
- package/dist/formatters/stylish.js +66 -0
- package/dist/formatters/stylish.js.map +1 -0
- package/dist/formatters/tap.d.ts +14 -0
- package/dist/formatters/tap.d.ts.map +1 -0
- package/dist/formatters/tap.js +45 -0
- package/dist/formatters/tap.js.map +1 -0
- package/dist/gherkin/dialects.d.ts +31 -0
- package/dist/gherkin/dialects.d.ts.map +1 -0
- package/dist/gherkin/dialects.js +40 -0
- package/dist/gherkin/dialects.js.map +1 -0
- package/dist/gherkin/keywords.d.ts +21 -0
- package/dist/gherkin/keywords.d.ts.map +1 -0
- package/dist/gherkin/keywords.js +53 -0
- package/dist/gherkin/keywords.js.map +1 -0
- package/dist/gherkin/parse.d.ts +32 -0
- package/dist/gherkin/parse.d.ts.map +1 -0
- package/dist/gherkin/parse.js +236 -0
- package/dist/gherkin/parse.js.map +1 -0
- package/dist/gherkin/traverse.d.ts +45 -0
- package/dist/gherkin/traverse.d.ts.map +1 -0
- package/dist/gherkin/traverse.js +89 -0
- package/dist/gherkin/traverse.js.map +1 -0
- package/dist/gherkin/variables.d.ts +26 -0
- package/dist/gherkin/variables.d.ts.map +1 -0
- package/dist/gherkin/variables.js +51 -0
- package/dist/gherkin/variables.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/linter.d.ts +23 -0
- package/dist/linter.d.ts.map +1 -0
- package/dist/linter.js +57 -0
- package/dist/linter.js.map +1 -0
- package/dist/logger.d.ts +16 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +28 -0
- package/dist/logger.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +144 -0
- package/dist/main.js.map +1 -0
- package/dist/presets.d.ts +19 -0
- package/dist/presets.d.ts.map +1 -0
- package/dist/presets.js +24 -0
- package/dist/presets.js.map +1 -0
- package/dist/rules/allowed-tags.d.ts +4 -0
- package/dist/rules/allowed-tags.d.ts.map +1 -0
- package/dist/rules/allowed-tags.js +34 -0
- package/dist/rules/allowed-tags.js.map +1 -0
- package/dist/rules/file-name.d.ts +4 -0
- package/dist/rules/file-name.d.ts.map +1 -0
- package/dist/rules/file-name.js +41 -0
- package/dist/rules/file-name.js.map +1 -0
- package/dist/rules/indentation.d.ts +4 -0
- package/dist/rules/indentation.d.ts.map +1 -0
- package/dist/rules/indentation.js +153 -0
- package/dist/rules/indentation.js.map +1 -0
- package/dist/rules/index.d.ts +13 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +70 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/keywords-in-logical-order.d.ts +4 -0
- package/dist/rules/keywords-in-logical-order.d.ts.map +1 -0
- package/dist/rules/keywords-in-logical-order.js +37 -0
- package/dist/rules/keywords-in-logical-order.js.map +1 -0
- package/dist/rules/max-scenarios-per-file.d.ts +4 -0
- package/dist/rules/max-scenarios-per-file.d.ts.map +1 -0
- package/dist/rules/max-scenarios-per-file.js +42 -0
- package/dist/rules/max-scenarios-per-file.js.map +1 -0
- package/dist/rules/name-length.d.ts +4 -0
- package/dist/rules/name-length.d.ts.map +1 -0
- package/dist/rules/name-length.js +50 -0
- package/dist/rules/name-length.js.map +1 -0
- package/dist/rules/new-line-at-eof.d.ts +4 -0
- package/dist/rules/new-line-at-eof.d.ts.map +1 -0
- package/dist/rules/new-line-at-eof.js +30 -0
- package/dist/rules/new-line-at-eof.js.map +1 -0
- package/dist/rules/no-background-only-scenario.d.ts +4 -0
- package/dist/rules/no-background-only-scenario.d.ts.map +1 -0
- package/dist/rules/no-background-only-scenario.js +43 -0
- package/dist/rules/no-background-only-scenario.js.map +1 -0
- package/dist/rules/no-dupe-feature-names.d.ts +4 -0
- package/dist/rules/no-dupe-feature-names.d.ts.map +1 -0
- package/dist/rules/no-dupe-feature-names.js +25 -0
- package/dist/rules/no-dupe-feature-names.js.map +1 -0
- package/dist/rules/no-dupe-file-names.d.ts +4 -0
- package/dist/rules/no-dupe-file-names.d.ts.map +1 -0
- package/dist/rules/no-dupe-file-names.js +28 -0
- package/dist/rules/no-dupe-file-names.js.map +1 -0
- package/dist/rules/no-dupe-scenario-names.d.ts +4 -0
- package/dist/rules/no-dupe-scenario-names.d.ts.map +1 -0
- package/dist/rules/no-dupe-scenario-names.js +41 -0
- package/dist/rules/no-dupe-scenario-names.js.map +1 -0
- package/dist/rules/no-duplicate-tags.d.ts +4 -0
- package/dist/rules/no-duplicate-tags.d.ts.map +1 -0
- package/dist/rules/no-duplicate-tags.js +38 -0
- package/dist/rules/no-duplicate-tags.js.map +1 -0
- package/dist/rules/no-empty-background.d.ts +4 -0
- package/dist/rules/no-empty-background.d.ts.map +1 -0
- package/dist/rules/no-empty-background.js +24 -0
- package/dist/rules/no-empty-background.js.map +1 -0
- package/dist/rules/no-empty-file.d.ts +4 -0
- package/dist/rules/no-empty-file.d.ts.map +1 -0
- package/dist/rules/no-empty-file.js +12 -0
- package/dist/rules/no-empty-file.js.map +1 -0
- package/dist/rules/no-examples-in-scenarios.d.ts +4 -0
- package/dist/rules/no-examples-in-scenarios.d.ts.map +1 -0
- package/dist/rules/no-examples-in-scenarios.js +25 -0
- package/dist/rules/no-examples-in-scenarios.js.map +1 -0
- package/dist/rules/no-files-without-scenarios.d.ts +4 -0
- package/dist/rules/no-files-without-scenarios.d.ts.map +1 -0
- package/dist/rules/no-files-without-scenarios.js +18 -0
- package/dist/rules/no-files-without-scenarios.js.map +1 -0
- package/dist/rules/no-homogenous-tags.d.ts +4 -0
- package/dist/rules/no-homogenous-tags.d.ts.map +1 -0
- package/dist/rules/no-homogenous-tags.js +54 -0
- package/dist/rules/no-homogenous-tags.js.map +1 -0
- package/dist/rules/no-multiple-empty-lines.d.ts +4 -0
- package/dist/rules/no-multiple-empty-lines.d.ts.map +1 -0
- package/dist/rules/no-multiple-empty-lines.js +44 -0
- package/dist/rules/no-multiple-empty-lines.js.map +1 -0
- package/dist/rules/no-partially-commented-tag-lines.d.ts +4 -0
- package/dist/rules/no-partially-commented-tag-lines.d.ts.map +1 -0
- package/dist/rules/no-partially-commented-tag-lines.js +44 -0
- package/dist/rules/no-partially-commented-tag-lines.js.map +1 -0
- package/dist/rules/no-restricted-patterns.d.ts +4 -0
- package/dist/rules/no-restricted-patterns.d.ts.map +1 -0
- package/dist/rules/no-restricted-patterns.js +101 -0
- package/dist/rules/no-restricted-patterns.js.map +1 -0
- package/dist/rules/no-restricted-tags.d.ts +4 -0
- package/dist/rules/no-restricted-tags.d.ts.map +1 -0
- package/dist/rules/no-restricted-tags.js +35 -0
- package/dist/rules/no-restricted-tags.js.map +1 -0
- package/dist/rules/no-scenario-outlines-without-examples.d.ts +4 -0
- package/dist/rules/no-scenario-outlines-without-examples.d.ts.map +1 -0
- package/dist/rules/no-scenario-outlines-without-examples.js +29 -0
- package/dist/rules/no-scenario-outlines-without-examples.js.map +1 -0
- package/dist/rules/no-superfluous-tags.d.ts +4 -0
- package/dist/rules/no-superfluous-tags.d.ts.map +1 -0
- package/dist/rules/no-superfluous-tags.js +40 -0
- package/dist/rules/no-superfluous-tags.js.map +1 -0
- package/dist/rules/no-trailing-spaces.d.ts +4 -0
- package/dist/rules/no-trailing-spaces.d.ts.map +1 -0
- package/dist/rules/no-trailing-spaces.js +24 -0
- package/dist/rules/no-trailing-spaces.js.map +1 -0
- package/dist/rules/no-undeclared-variables.d.ts +4 -0
- package/dist/rules/no-undeclared-variables.d.ts.map +1 -0
- package/dist/rules/no-undeclared-variables.js +35 -0
- package/dist/rules/no-undeclared-variables.js.map +1 -0
- package/dist/rules/no-unnamed-features.d.ts +4 -0
- package/dist/rules/no-unnamed-features.d.ts.map +1 -0
- package/dist/rules/no-unnamed-features.js +19 -0
- package/dist/rules/no-unnamed-features.js.map +1 -0
- package/dist/rules/no-unnamed-scenarios.d.ts +4 -0
- package/dist/rules/no-unnamed-scenarios.d.ts.map +1 -0
- package/dist/rules/no-unnamed-scenarios.js +24 -0
- package/dist/rules/no-unnamed-scenarios.js.map +1 -0
- package/dist/rules/no-unused-variables.d.ts +4 -0
- package/dist/rules/no-unused-variables.d.ts.map +1 -0
- package/dist/rules/no-unused-variables.js +36 -0
- package/dist/rules/no-unused-variables.js.map +1 -0
- package/dist/rules/one-space-between-tags.d.ts +4 -0
- package/dist/rules/one-space-between-tags.d.ts.map +1 -0
- package/dist/rules/one-space-between-tags.js +36 -0
- package/dist/rules/one-space-between-tags.js.map +1 -0
- package/dist/rules/only-one-when.d.ts +4 -0
- package/dist/rules/only-one-when.d.ts.map +1 -0
- package/dist/rules/only-one-when.js +59 -0
- package/dist/rules/only-one-when.js.map +1 -0
- package/dist/rules/required-tags.d.ts +4 -0
- package/dist/rules/required-tags.d.ts.map +1 -0
- package/dist/rules/required-tags.js +36 -0
- package/dist/rules/required-tags.js.map +1 -0
- package/dist/rules/scenario-size.d.ts +4 -0
- package/dist/rules/scenario-size.d.ts.map +1 -0
- package/dist/rules/scenario-size.js +37 -0
- package/dist/rules/scenario-size.js.map +1 -0
- package/dist/rules/use-and.d.ts +4 -0
- package/dist/rules/use-and.d.ts.map +1 -0
- package/dist/rules/use-and.js +33 -0
- package/dist/rules/use-and.js.map +1 -0
- package/dist/rules.d.ts +24 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/rules.js +109 -0
- package/dist/rules.js.map +1 -0
- package/dist/suppressions.d.ts +33 -0
- package/dist/suppressions.d.ts.map +1 -0
- package/dist/suppressions.js +84 -0
- package/dist/suppressions.js.map +1 -0
- package/dist/types.d.ts +81 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/util/case.d.ts +21 -0
- package/dist/util/case.d.ts.map +1 -0
- package/dist/util/case.js +42 -0
- package/dist/util/case.js.map +1 -0
- package/dist/util/collections.d.ts +30 -0
- package/dist/util/collections.d.ts.map +1 -0
- package/dist/util/collections.js +87 -0
- package/dist/util/collections.js.map +1 -0
- package/dist/util/glob.d.ts +20 -0
- package/dist/util/glob.d.ts.map +1 -0
- package/dist/util/glob.js +203 -0
- package/dist/util/glob.js.map +1 -0
- package/dist/util/json.d.ts +14 -0
- package/dist/util/json.d.ts.map +1 -0
- package/dist/util/json.js +63 -0
- package/dist/util/json.js.map +1 -0
- package/dist/util/lines.d.ts +24 -0
- package/dist/util/lines.d.ts.map +1 -0
- package/dist/util/lines.js +45 -0
- package/dist/util/lines.js.map +1 -0
- package/dist/util/location.d.ts +15 -0
- package/dist/util/location.d.ts.map +1 -0
- package/dist/util/location.js +11 -0
- package/dist/util/location.js.map +1 -0
- package/dist/util/xml.d.ts +16 -0
- package/dist/util/xml.d.ts.map +1 -0
- package/dist/util/xml.js +36 -0
- package/dist/util/xml.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +24 -0
- package/dist/version.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { scenariosOf } from '../gherkin/traverse.js';
|
|
2
|
+
import { at } from '../util/location.js';
|
|
3
|
+
const name = 'no-dupe-scenario-names';
|
|
4
|
+
/** Whether duplicates are looked for across all files or within each file. */
|
|
5
|
+
const availableConfigs = ['anywhere', 'in-feature'];
|
|
6
|
+
/** Scenario name -> everywhere it has already been seen. */
|
|
7
|
+
const seen = new Map();
|
|
8
|
+
const rule = {
|
|
9
|
+
name,
|
|
10
|
+
availableConfigs,
|
|
11
|
+
reset() {
|
|
12
|
+
seen.clear();
|
|
13
|
+
},
|
|
14
|
+
run(feature, file, configuration) {
|
|
15
|
+
if (feature === undefined) {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
if (configuration === 'in-feature') {
|
|
19
|
+
seen.clear();
|
|
20
|
+
}
|
|
21
|
+
const errors = [];
|
|
22
|
+
for (const { scenario } of scenariosOf(feature)) {
|
|
23
|
+
const sighting = { file: file.relativePath, line: scenario.location.line };
|
|
24
|
+
const previous = seen.get(scenario.name);
|
|
25
|
+
if (previous === undefined) {
|
|
26
|
+
seen.set(scenario.name, [sighting]);
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const where = previous.map((seenAt) => `${seenAt.file}:${seenAt.line}`).join(', ');
|
|
30
|
+
previous.push(sighting);
|
|
31
|
+
errors.push({
|
|
32
|
+
message: `Scenario name is already used in: ${where}`,
|
|
33
|
+
rule: name,
|
|
34
|
+
...at(scenario.location),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return errors;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
export default rule;
|
|
41
|
+
//# sourceMappingURL=no-dupe-scenario-names.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-dupe-scenario-names.js","sourceRoot":"","sources":["../../src/rules/no-dupe-scenario-names.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAC,EAAE,EAAC,MAAM,qBAAqB,CAAC;AAEvC,MAAM,IAAI,GAAG,wBAAwB,CAAC;AAEtC,8EAA8E;AAC9E,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,YAAY,CAAU,CAAC;AAO7D,4DAA4D;AAC5D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAsB,CAAC;AAE3C,MAAM,IAAI,GAAa;IACrB,IAAI;IACJ,gBAAgB;IAChB,KAAK;QACH,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;IACD,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,aAAa;QAC9B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,aAAa,KAAK,YAAY,EAAE,CAAC;YACnC,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;QAED,MAAM,MAAM,GAAgB,EAAE,CAAC;QAE/B,KAAK,MAAM,EAAC,QAAQ,EAAC,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9C,MAAM,QAAQ,GAAa,EAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAC,CAAC;YACnF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAEzC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACpC,SAAS;YACX,CAAC;YAED,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnF,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC;gBACV,OAAO,EAAE,qCAAqC,KAAK,EAAE;gBACrD,IAAI,EAAE,IAAI;gBACV,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;aACzB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-duplicate-tags.d.ts","sourceRoot":"","sources":["../../src/rules/no-duplicate-tags.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,QAAQ,EAAY,MAAM,aAAa,CAAC;AA0BrD,QAAA,MAAM,IAAI,EAAE,QAYX,CAAC;eAEa,IAAI"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { taggedNodesOf } from '../gherkin/traverse.js';
|
|
2
|
+
import { at } from '../util/location.js';
|
|
3
|
+
const name = 'no-duplicate-tags';
|
|
4
|
+
/**
|
|
5
|
+
* Reports every repeat of a tag, not just the first. Three copies of a tag
|
|
6
|
+
* are two mistakes, and being told about one at a time means running the
|
|
7
|
+
* linter again after each fix.
|
|
8
|
+
*/
|
|
9
|
+
function checkTags(tags, errors) {
|
|
10
|
+
const seen = new Set();
|
|
11
|
+
for (const tag of tags) {
|
|
12
|
+
if (seen.has(tag.name)) {
|
|
13
|
+
errors.push({
|
|
14
|
+
message: `Duplicate tags are not allowed: ${tag.name}`,
|
|
15
|
+
rule: name,
|
|
16
|
+
...at(tag.location),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
seen.add(tag.name);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const rule = {
|
|
25
|
+
name,
|
|
26
|
+
run(feature) {
|
|
27
|
+
if (feature === undefined) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
const errors = [];
|
|
31
|
+
for (const { node } of taggedNodesOf(feature)) {
|
|
32
|
+
checkTags(node.tags, errors);
|
|
33
|
+
}
|
|
34
|
+
return errors;
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
export default rule;
|
|
38
|
+
//# sourceMappingURL=no-duplicate-tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-duplicate-tags.js","sourceRoot":"","sources":["../../src/rules/no-duplicate-tags.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAErD,OAAO,EAAC,EAAE,EAAC,MAAM,qBAAqB,CAAC;AAEvC,MAAM,IAAI,GAAG,mBAAmB,CAAC;AAEjC;;;;GAIG;AACH,SAAS,SAAS,CAAC,IAAoB,EAAE,MAAmB;IAC1D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,CAAC,IAAI,CAAC;gBACV,OAAO,EAAE,mCAAmC,GAAG,CAAC,IAAI,EAAE;gBACtD,IAAI,EAAE,IAAI;gBACV,GAAG,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;aACpB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,IAAI,GAAa;IACrB,IAAI;IACJ,GAAG,CAAC,OAAO;QACT,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,MAAM,GAAgB,EAAE,CAAC;QAC/B,KAAK,MAAM,EAAC,IAAI,EAAC,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5C,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-empty-background.d.ts","sourceRoot":"","sources":["../../src/rules/no-empty-background.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,QAAQ,EAAY,MAAM,aAAa,CAAC;AAKrD,QAAA,MAAM,IAAI,EAAE,QAkBX,CAAC;eAEa,IAAI"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { backgroundsOf } from '../gherkin/traverse.js';
|
|
2
|
+
import { at } from '../util/location.js';
|
|
3
|
+
const name = 'no-empty-background';
|
|
4
|
+
const rule = {
|
|
5
|
+
name,
|
|
6
|
+
run(feature) {
|
|
7
|
+
if (feature === undefined) {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
const errors = [];
|
|
11
|
+
for (const { background } of backgroundsOf(feature)) {
|
|
12
|
+
if (background.steps.length === 0) {
|
|
13
|
+
errors.push({
|
|
14
|
+
message: 'Empty backgrounds are not allowed.',
|
|
15
|
+
rule: name,
|
|
16
|
+
...at(background.location),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return errors;
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
export default rule;
|
|
24
|
+
//# sourceMappingURL=no-empty-background.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-empty-background.js","sourceRoot":"","sources":["../../src/rules/no-empty-background.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAErD,OAAO,EAAC,EAAE,EAAC,MAAM,qBAAqB,CAAC;AAEvC,MAAM,IAAI,GAAG,qBAAqB,CAAC;AAEnC,MAAM,IAAI,GAAa;IACrB,IAAI;IACJ,GAAG,CAAC,OAAO;QACT,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,MAAM,GAAgB,EAAE,CAAC;QAC/B,KAAK,MAAM,EAAC,UAAU,EAAC,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClC,MAAM,CAAC,IAAI,CAAC;oBACV,OAAO,EAAE,oCAAoC;oBAC7C,IAAI,EAAE,IAAI;oBACV,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;iBAC3B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-empty-file.d.ts","sourceRoot":"","sources":["../../src/rules/no-empty-file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAI1C,QAAA,MAAM,IAAI,EAAE,QAQX,CAAC;eAEa,IAAI"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const name = 'no-empty-file';
|
|
2
|
+
const rule = {
|
|
3
|
+
name,
|
|
4
|
+
run(feature) {
|
|
5
|
+
if (feature !== undefined) {
|
|
6
|
+
return [];
|
|
7
|
+
}
|
|
8
|
+
return [{ message: 'Empty feature files are disallowed', rule: name, line: 1 }];
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
export default rule;
|
|
12
|
+
//# sourceMappingURL=no-empty-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-empty-file.js","sourceRoot":"","sources":["../../src/rules/no-empty-file.ts"],"names":[],"mappings":"AAEA,MAAM,IAAI,GAAG,eAAe,CAAC;AAE7B,MAAM,IAAI,GAAa;IACrB,IAAI;IACJ,GAAG,CAAC,OAAO;QACT,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,CAAC,EAAC,OAAO,EAAE,oCAAoC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAC,CAAC,CAAC;IAChF,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-examples-in-scenarios.d.ts","sourceRoot":"","sources":["../../src/rules/no-examples-in-scenarios.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,QAAQ,EAAY,MAAM,aAAa,CAAC;AAKrD,QAAA,MAAM,IAAI,EAAE,QAqBX,CAAC;eAEa,IAAI"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getNodeType } from '../gherkin/keywords.js';
|
|
2
|
+
import { scenariosOf } from '../gherkin/traverse.js';
|
|
3
|
+
import { at } from '../util/location.js';
|
|
4
|
+
const name = 'no-examples-in-scenarios';
|
|
5
|
+
const rule = {
|
|
6
|
+
name,
|
|
7
|
+
run(feature) {
|
|
8
|
+
if (feature === undefined) {
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
11
|
+
const errors = [];
|
|
12
|
+
for (const { scenario } of scenariosOf(feature)) {
|
|
13
|
+
if (getNodeType(scenario, feature.language) === 'Scenario' && scenario.examples.length > 0) {
|
|
14
|
+
errors.push({
|
|
15
|
+
message: 'Cannot use "Examples" in a "Scenario", use a "Scenario Outline" instead',
|
|
16
|
+
rule: name,
|
|
17
|
+
...at(scenario.location),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return errors;
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
export default rule;
|
|
25
|
+
//# sourceMappingURL=no-examples-in-scenarios.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-examples-in-scenarios.js","sourceRoot":"","sources":["../../src/rules/no-examples-in-scenarios.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAC,WAAW,EAAC,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAC,EAAE,EAAC,MAAM,qBAAqB,CAAC;AAEvC,MAAM,IAAI,GAAG,0BAA0B,CAAC;AAExC,MAAM,IAAI,GAAa;IACrB,IAAI;IACJ,GAAG,CAAC,OAAO;QACT,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,MAAM,GAAgB,EAAE,CAAC;QAE/B,KAAK,MAAM,EAAC,QAAQ,EAAC,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9C,IAAI,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,UAAU,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3F,MAAM,CAAC,IAAI,CAAC;oBACV,OAAO,EAAE,yEAAyE;oBAClF,IAAI,EAAE,IAAI;oBACV,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;iBACzB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-files-without-scenarios.d.ts","sourceRoot":"","sources":["../../src/rules/no-files-without-scenarios.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAW1C,QAAA,MAAM,IAAI,EAAE,QAQX,CAAC;eAEa,IAAI"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const name = 'no-files-without-scenarios';
|
|
2
|
+
function hasScenario(child) {
|
|
3
|
+
if (child.scenario !== undefined) {
|
|
4
|
+
return true;
|
|
5
|
+
}
|
|
6
|
+
return 'rule' in child && child.rule !== undefined && child.rule.children.some(hasScenario);
|
|
7
|
+
}
|
|
8
|
+
const rule = {
|
|
9
|
+
name,
|
|
10
|
+
run(feature) {
|
|
11
|
+
if (feature === undefined || feature.children.some(hasScenario)) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
return [{ message: 'Feature file does not have any Scenarios', rule: name, line: 1 }];
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
export default rule;
|
|
18
|
+
//# sourceMappingURL=no-files-without-scenarios.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-files-without-scenarios.js","sourceRoot":"","sources":["../../src/rules/no-files-without-scenarios.ts"],"names":[],"mappings":"AAGA,MAAM,IAAI,GAAG,4BAA4B,CAAC;AAE1C,SAAS,WAAW,CAAC,KAA+B;IAClD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC9F,CAAC;AAED,MAAM,IAAI,GAAa;IACrB,IAAI;IACJ,GAAG,CAAC,OAAO;QACT,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAChE,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,CAAC,EAAC,OAAO,EAAE,0CAA0C,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAC,CAAC,CAAC;IACtF,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-homogenous-tags.d.ts","sourceRoot":"","sources":["../../src/rules/no-homogenous-tags.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,QAAQ,EAAY,MAAM,aAAa,CAAC;AAUrD,QAAA,MAAM,IAAI,EAAE,QAoDX,CAAC;eAEa,IAAI"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { scenariosOf } from '../gherkin/traverse.js';
|
|
2
|
+
import { intersection } from '../util/collections.js';
|
|
3
|
+
import { at } from '../util/location.js';
|
|
4
|
+
const name = 'no-homogenous-tags';
|
|
5
|
+
function tagNames(tags) {
|
|
6
|
+
return tags.map((tag) => tag.name);
|
|
7
|
+
}
|
|
8
|
+
const rule = {
|
|
9
|
+
name,
|
|
10
|
+
run(feature) {
|
|
11
|
+
if (feature === undefined) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
const errors = [];
|
|
15
|
+
const scenarioTags = [];
|
|
16
|
+
// One error per tag rather than one summary listing them all, so that
|
|
17
|
+
// each finding points at a single thing to fix, the way every other
|
|
18
|
+
// rule reports.
|
|
19
|
+
for (const { scenario } of scenariosOf(feature)) {
|
|
20
|
+
scenarioTags.push(tagNames(scenario.tags));
|
|
21
|
+
// "Every Examples table has this tag" says nothing when there is only
|
|
22
|
+
// one of them, and hoisting the tag would change what it means as soon
|
|
23
|
+
// as a second table is added.
|
|
24
|
+
if (scenario.examples.length < 2) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
for (const tag of intersection(scenario.examples.map((e) => tagNames(e.tags)))) {
|
|
28
|
+
errors.push({
|
|
29
|
+
message: 'Every Examples table of this Scenario Outline has the tag ' +
|
|
30
|
+
`${tag}, it should be defined on the Scenario Outline instead`,
|
|
31
|
+
rule: name,
|
|
32
|
+
...at(scenario.location),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Likewise, a single scenario's tags are not shared with anything. Tags
|
|
37
|
+
// that identify one scenario - a ticket reference, say - belong on the
|
|
38
|
+
// scenario, and moving them to the Feature would be wrong advice.
|
|
39
|
+
if (scenarioTags.length < 2) {
|
|
40
|
+
return errors;
|
|
41
|
+
}
|
|
42
|
+
for (const tag of intersection(scenarioTags)) {
|
|
43
|
+
errors.push({
|
|
44
|
+
message: `Every Scenario on this Feature has the tag ${tag}, ` +
|
|
45
|
+
'it should be defined on the Feature instead',
|
|
46
|
+
rule: name,
|
|
47
|
+
...at(feature.location),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return errors;
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
export default rule;
|
|
54
|
+
//# sourceMappingURL=no-homogenous-tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-homogenous-tags.js","sourceRoot":"","sources":["../../src/rules/no-homogenous-tags.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,WAAW,EAAC,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAC,YAAY,EAAC,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAC,EAAE,EAAC,MAAM,qBAAqB,CAAC;AAEvC,MAAM,IAAI,GAAG,oBAAoB,CAAC;AAElC,SAAS,QAAQ,CAAC,IAAoB;IACpC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,IAAI,GAAa;IACrB,IAAI;IACJ,GAAG,CAAC,OAAO;QACT,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,MAAM,GAAgB,EAAE,CAAC;QAC/B,MAAM,YAAY,GAAe,EAAE,CAAC;QAEpC,sEAAsE;QACtE,oEAAoE;QACpE,gBAAgB;QAChB,KAAK,MAAM,EAAC,QAAQ,EAAC,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9C,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YAE3C,sEAAsE;YACtE,uEAAuE;YACvE,8BAA8B;YAC9B,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjC,SAAS;YACX,CAAC;YACD,KAAK,MAAM,GAAG,IAAI,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/E,MAAM,CAAC,IAAI,CAAC;oBACV,OAAO,EACL,4DAA4D;wBAC5D,GAAG,GAAG,wDAAwD;oBAChE,IAAI,EAAE,IAAI;oBACV,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;iBACzB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,wEAAwE;QACxE,uEAAuE;QACvE,kEAAkE;QAClE,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC;gBACV,OAAO,EACL,8CAA8C,GAAG,IAAI;oBACrD,6CAA6C;gBAC/C,IAAI,EAAE,IAAI;gBACV,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;aACxB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-multiple-empty-lines.d.ts","sourceRoot":"","sources":["../../src/rules/no-multiple-empty-lines.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAY,MAAM,aAAa,CAAC;AAiBrD,QAAA,MAAM,IAAI,EAAE,QAiCX,CAAC;eAEa,IAAI"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { mergeDefaults } from '../util/collections.js';
|
|
2
|
+
import { contentLines, markDocStrings } from '../util/lines.js';
|
|
3
|
+
const name = 'no-multiple-empty-lines';
|
|
4
|
+
const availableConfigs = {
|
|
5
|
+
/** How many blank lines may sit next to each other. */
|
|
6
|
+
max: 1,
|
|
7
|
+
};
|
|
8
|
+
function messageFor(max) {
|
|
9
|
+
return max === 1
|
|
10
|
+
? 'Multiple empty lines are not allowed'
|
|
11
|
+
: `More than ${max} empty lines in a row are not allowed`;
|
|
12
|
+
}
|
|
13
|
+
const rule = {
|
|
14
|
+
name,
|
|
15
|
+
availableConfigs,
|
|
16
|
+
run(_feature, file, configuration) {
|
|
17
|
+
const { max } = mergeDefaults(availableConfigs, configuration);
|
|
18
|
+
const lines = contentLines(file);
|
|
19
|
+
const inDocString = markDocStrings(lines);
|
|
20
|
+
const message = messageFor(max);
|
|
21
|
+
const errors = [];
|
|
22
|
+
let blanksInARow = 0;
|
|
23
|
+
lines.forEach((line, index) => {
|
|
24
|
+
// Blank lines inside a doc string are part of the text being quoted,
|
|
25
|
+
// and they do not join up runs of blank lines on either side of it.
|
|
26
|
+
if (inDocString[index] === true) {
|
|
27
|
+
blanksInARow = 0;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (line.trim() !== '') {
|
|
31
|
+
blanksInARow = 0;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
blanksInARow++;
|
|
35
|
+
// One error per blank line past the limit, pointing at that line.
|
|
36
|
+
if (blanksInARow > max) {
|
|
37
|
+
errors.push({ message, rule: name, line: index + 1 });
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return errors;
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
export default rule;
|
|
44
|
+
//# sourceMappingURL=no-multiple-empty-lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-multiple-empty-lines.js","sourceRoot":"","sources":["../../src/rules/no-multiple-empty-lines.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAC,YAAY,EAAE,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAE9D,MAAM,IAAI,GAAG,yBAAyB,CAAC;AAEvC,MAAM,gBAAgB,GAAG;IACvB,uDAAuD;IACvD,GAAG,EAAE,CAAC;CACP,CAAC;AAEF,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,GAAG,KAAK,CAAC;QACd,CAAC,CAAC,sCAAsC;QACxC,CAAC,CAAC,aAAa,GAAG,uCAAuC,CAAC;AAC9D,CAAC;AAED,MAAM,IAAI,GAAa;IACrB,IAAI;IACJ,gBAAgB;IAChB,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,aAAa;QAC/B,MAAM,EAAC,GAAG,EAAC,GAAG,aAAa,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,MAAM,GAAgB,EAAE,CAAC;QAC/B,IAAI,YAAY,GAAG,CAAC,CAAC;QAErB,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YAC5B,qEAAqE;YACrE,oEAAoE;YACpE,IAAI,WAAW,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;gBAChC,YAAY,GAAG,CAAC,CAAC;gBACjB,OAAO;YACT,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBACvB,YAAY,GAAG,CAAC,CAAC;gBACjB,OAAO;YACT,CAAC;YAED,YAAY,EAAE,CAAC;YACf,kEAAkE;YAClE,IAAI,YAAY,GAAG,GAAG,EAAE,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC,EAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,EAAC,CAAC,CAAC;YACtD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-partially-commented-tag-lines.d.ts","sourceRoot":"","sources":["../../src/rules/no-partially-commented-tag-lines.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,QAAQ,EAAY,MAAM,aAAa,CAAC;AAoBrD,QAAA,MAAM,IAAI,EAAE,QA0BX,CAAC;eAEa,IAAI"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { taggedNodesOf } from '../gherkin/traverse.js';
|
|
2
|
+
import { atLineColumn } from '../util/location.js';
|
|
3
|
+
const name = 'no-partially-commented-tag-lines';
|
|
4
|
+
/**
|
|
5
|
+
* A `#` on a tag line comments out everything after it. That is easy to do by
|
|
6
|
+
* accident and silently disables tags, so it is worth flagging.
|
|
7
|
+
*
|
|
8
|
+
* The check reads the original source line rather than the parsed tags,
|
|
9
|
+
* because by the time the file is parsed the commented-out part is gone.
|
|
10
|
+
* Only lines the parser identified as tag lines are looked at, so a `#`
|
|
11
|
+
* inside a doc string is not mistaken for one.
|
|
12
|
+
*/
|
|
13
|
+
function collectTagLines(tags, into) {
|
|
14
|
+
for (const tag of tags) {
|
|
15
|
+
into.add(tag.location.line);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const rule = {
|
|
19
|
+
name,
|
|
20
|
+
run(feature, file) {
|
|
21
|
+
if (feature === undefined) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
const tagLines = new Set();
|
|
25
|
+
for (const { node } of taggedNodesOf(feature)) {
|
|
26
|
+
collectTagLines(node.tags, tagLines);
|
|
27
|
+
}
|
|
28
|
+
const errors = [];
|
|
29
|
+
for (const line of [...tagLines].sort((a, b) => a - b)) {
|
|
30
|
+
const comment = file.lines[line - 1]?.indexOf('#') ?? -1;
|
|
31
|
+
if (comment !== -1) {
|
|
32
|
+
errors.push({
|
|
33
|
+
message: 'Partially commented tag lines not allowed',
|
|
34
|
+
rule: name,
|
|
35
|
+
// Point at the '#' itself: that is the character to remove.
|
|
36
|
+
...atLineColumn(line, comment + 1),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return errors;
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
export default rule;
|
|
44
|
+
//# sourceMappingURL=no-partially-commented-tag-lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-partially-commented-tag-lines.js","sourceRoot":"","sources":["../../src/rules/no-partially-commented-tag-lines.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAErD,OAAO,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAC;AAEjD,MAAM,IAAI,GAAG,kCAAkC,CAAC;AAEhD;;;;;;;;GAQG;AACH,SAAS,eAAe,CAAC,IAAoB,EAAE,IAAiB;IAC9D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,MAAM,IAAI,GAAa;IACrB,IAAI;IACJ,GAAG,CAAC,OAAO,EAAE,IAAI;QACf,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;QACnC,KAAK,MAAM,EAAC,IAAI,EAAC,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5C,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,MAAM,GAAgB,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACvD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YACzD,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;gBACnB,MAAM,CAAC,IAAI,CAAC;oBACV,OAAO,EAAE,2CAA2C;oBACpD,IAAI,EAAE,IAAI;oBACV,4DAA4D;oBAC5D,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,CAAC,CAAC;iBACnC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-restricted-patterns.d.ts","sourceRoot":"","sources":["../../src/rules/no-restricted-patterns.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,QAAQ,EAAY,MAAM,aAAa,CAAC;AA2DrD,QAAA,MAAM,IAAI,EAAE,QA8DX,CAAC;eAEa,IAAI"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { getNeutralKeyword, getNodeType } from '../gherkin/keywords.js';
|
|
2
|
+
import { rulesOf, stepContainersOf } from '../gherkin/traverse.js';
|
|
3
|
+
import { mergeDefaults } from '../util/collections.js';
|
|
4
|
+
import { at } from '../util/location.js';
|
|
5
|
+
const name = 'no-restricted-patterns';
|
|
6
|
+
/**
|
|
7
|
+
* Patterns are grouped by where they apply. `Global` applies everywhere; the
|
|
8
|
+
* rest apply only inside that kind of block.
|
|
9
|
+
*/
|
|
10
|
+
const availableConfigs = {
|
|
11
|
+
Global: [],
|
|
12
|
+
Feature: [],
|
|
13
|
+
Rule: [],
|
|
14
|
+
Background: [],
|
|
15
|
+
Scenario: [],
|
|
16
|
+
ScenarioOutline: [],
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* A description written over several lines arrives as one string containing
|
|
20
|
+
* real newlines. A user who literally typed `\n` in a description gets that
|
|
21
|
+
* as two characters, and must not be split on. This sentinel keeps the two
|
|
22
|
+
* apart while splitting.
|
|
23
|
+
*/
|
|
24
|
+
const ESCAPED_NEWLINE_SENTINEL = '<!gurkencheck new line sentinel!>';
|
|
25
|
+
/** Builds the pattern list for each block kind, keyed by neutral keyword. */
|
|
26
|
+
function compilePatterns(config) {
|
|
27
|
+
const global = config.Global.map((pattern) => new RegExp(pattern, 'i'));
|
|
28
|
+
const compiled = new Map();
|
|
29
|
+
for (const key of Object.keys(availableConfigs)) {
|
|
30
|
+
if (key === 'Global') {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const neutralKey = key.toLowerCase().replace(/ /g, '');
|
|
34
|
+
compiled.set(neutralKey, [
|
|
35
|
+
...config[key].map((pattern) => new RegExp(pattern, 'i')),
|
|
36
|
+
...global,
|
|
37
|
+
]);
|
|
38
|
+
}
|
|
39
|
+
return compiled;
|
|
40
|
+
}
|
|
41
|
+
/** Splits a description into the lines it was written on. */
|
|
42
|
+
function toCheckableStrings(property, value) {
|
|
43
|
+
if (property !== 'description') {
|
|
44
|
+
return [value];
|
|
45
|
+
}
|
|
46
|
+
return value
|
|
47
|
+
.replaceAll('\\n', ESCAPED_NEWLINE_SENTINEL)
|
|
48
|
+
.split('\n')
|
|
49
|
+
.map((line) => line.replaceAll(ESCAPED_NEWLINE_SENTINEL, '\\n'));
|
|
50
|
+
}
|
|
51
|
+
const rule = {
|
|
52
|
+
name,
|
|
53
|
+
availableConfigs,
|
|
54
|
+
run(feature, _file, configuration) {
|
|
55
|
+
if (feature === undefined) {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
const patterns = compilePatterns(mergeDefaults(availableConfigs, configuration));
|
|
59
|
+
const language = feature.language;
|
|
60
|
+
const errors = [];
|
|
61
|
+
const check = (node, property, value, applicable) => {
|
|
62
|
+
if (value === undefined || value === '') {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const type = getNodeType(node, language);
|
|
66
|
+
for (const pattern of applicable) {
|
|
67
|
+
for (const candidate of toCheckableStrings(property, value)) {
|
|
68
|
+
// Names and descriptions may be padded with whitespace; steps are not.
|
|
69
|
+
const text = candidate.trim();
|
|
70
|
+
if (pattern.test(text)) {
|
|
71
|
+
errors.push({
|
|
72
|
+
message: `${type} ${property}: "${text}" matches restricted pattern "${pattern}"`,
|
|
73
|
+
rule: name,
|
|
74
|
+
...at(node.location),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const patternsFor = (node) => patterns.get(getNeutralKeyword(node, language)) ?? [];
|
|
81
|
+
check(feature, 'name', feature.name, patternsFor(feature));
|
|
82
|
+
check(feature, 'description', feature.description, patternsFor(feature));
|
|
83
|
+
for (const featureRule of rulesOf(feature)) {
|
|
84
|
+
const applicable = patternsFor(featureRule);
|
|
85
|
+
check(featureRule, 'name', featureRule.name, applicable);
|
|
86
|
+
check(featureRule, 'description', featureRule.description, applicable);
|
|
87
|
+
}
|
|
88
|
+
for (const { node } of stepContainersOf(feature)) {
|
|
89
|
+
const applicable = patternsFor(node);
|
|
90
|
+
check(node, 'name', node.name, applicable);
|
|
91
|
+
check(node, 'description', node.description, applicable);
|
|
92
|
+
// Steps are checked against the patterns of the block they sit in.
|
|
93
|
+
for (const step of node.steps) {
|
|
94
|
+
check(step, 'text', step.text, applicable);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return errors;
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
export default rule;
|
|
101
|
+
//# sourceMappingURL=no-restricted-patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-restricted-patterns.js","sourceRoot":"","sources":["../../src/rules/no-restricted-patterns.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-restricted-tags.d.ts","sourceRoot":"","sources":["../../src/rules/no-restricted-tags.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,QAAQ,EAAY,MAAM,aAAa,CAAC;AAerD,QAAA,MAAM,IAAI,EAAE,QA6BX,CAAC;eAEa,IAAI"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getNodeType } from '../gherkin/keywords.js';
|
|
2
|
+
import { taggedNodesOf } from '../gherkin/traverse.js';
|
|
3
|
+
import { mergeDefaults } from '../util/collections.js';
|
|
4
|
+
import { at } from '../util/location.js';
|
|
5
|
+
const name = 'no-restricted-tags';
|
|
6
|
+
const availableConfigs = { tags: [], patterns: [] };
|
|
7
|
+
const rule = {
|
|
8
|
+
name,
|
|
9
|
+
availableConfigs,
|
|
10
|
+
run(feature, _file, configuration) {
|
|
11
|
+
if (feature === undefined) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
const config = mergeDefaults(availableConfigs, configuration);
|
|
15
|
+
const forbiddenTags = new Set(config.tags);
|
|
16
|
+
const forbiddenPatterns = config.patterns.map((pattern) => new RegExp(pattern));
|
|
17
|
+
const errors = [];
|
|
18
|
+
for (const { node } of taggedNodesOf(feature)) {
|
|
19
|
+
const nodeType = getNodeType(node, feature.language);
|
|
20
|
+
for (const tag of node.tags) {
|
|
21
|
+
const forbidden = forbiddenTags.has(tag.name) || forbiddenPatterns.some((pattern) => pattern.test(tag.name));
|
|
22
|
+
if (forbidden) {
|
|
23
|
+
errors.push({
|
|
24
|
+
message: `Forbidden tag ${tag.name} on ${nodeType}`,
|
|
25
|
+
rule: name,
|
|
26
|
+
...at(tag.location),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return errors;
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
export default rule;
|
|
35
|
+
//# sourceMappingURL=no-restricted-tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-restricted-tags.js","sourceRoot":"","sources":["../../src/rules/no-restricted-tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAC,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAErD,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAC,EAAE,EAAC,MAAM,qBAAqB,CAAC;AAEvC,MAAM,IAAI,GAAG,oBAAoB,CAAC;AASlC,MAAM,gBAAgB,GAAyB,EAAC,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAC,CAAC;AAExE,MAAM,IAAI,GAAa;IACrB,IAAI;IACJ,gBAAgB;IAChB,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa;QAC/B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,MAAM,GAAG,aAAa,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;QAC9D,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,iBAAiB,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAChF,MAAM,MAAM,GAAgB,EAAE,CAAC;QAE/B,KAAK,MAAM,EAAC,IAAI,EAAC,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;YACrD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC5B,MAAM,SAAS,GACb,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC7F,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,CAAC,IAAI,CAAC;wBACV,OAAO,EAAE,iBAAiB,GAAG,CAAC,IAAI,OAAO,QAAQ,EAAE;wBACnD,IAAI,EAAE,IAAI;wBACV,GAAG,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;qBACpB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-scenario-outlines-without-examples.d.ts","sourceRoot":"","sources":["../../src/rules/no-scenario-outlines-without-examples.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,QAAQ,EAAY,MAAM,aAAa,CAAC;AAKrD,QAAA,MAAM,IAAI,EAAE,QAyBX,CAAC;eAEa,IAAI"}
|