@mark1russell7/ste-lint 0.0.0-stage → 0.1.1
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/README.md +225 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +9 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +103 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +251 -0
- package/dist/config.js.map +1 -0
- package/dist/dictionary.d.ts +74 -0
- package/dist/dictionary.d.ts.map +1 -0
- package/dist/dictionary.js +169 -0
- package/dist/dictionary.js.map +1 -0
- package/dist/files.d.ts +35 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +181 -0
- package/dist/files.js.map +1 -0
- package/dist/format.d.ts +21 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +61 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/lexicon.d.ts +33 -0
- package/dist/lexicon.d.ts.map +1 -0
- package/dist/lexicon.js +71 -0
- package/dist/lexicon.js.map +1 -0
- package/dist/lint.d.ts +28 -0
- package/dist/lint.d.ts.map +1 -0
- package/dist/lint.js +132 -0
- package/dist/lint.js.map +1 -0
- package/dist/rules/about-quantity.d.ts +3 -0
- package/dist/rules/about-quantity.d.ts.map +1 -0
- package/dist/rules/about-quantity.js +34 -0
- package/dist/rules/about-quantity.js.map +1 -0
- package/dist/rules/index.d.ts +8 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +35 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/ing-verb.d.ts +9 -0
- package/dist/rules/ing-verb.d.ts.map +1 -0
- package/dist/rules/ing-verb.js +60 -0
- package/dist/rules/ing-verb.js.map +1 -0
- package/dist/rules/latin-abbreviation.d.ts +3 -0
- package/dist/rules/latin-abbreviation.d.ts.map +1 -0
- package/dist/rules/latin-abbreviation.js +48 -0
- package/dist/rules/latin-abbreviation.js.map +1 -0
- package/dist/rules/missing-subject.d.ts +16 -0
- package/dist/rules/missing-subject.d.ts.map +1 -0
- package/dist/rules/missing-subject.js +138 -0
- package/dist/rules/missing-subject.js.map +1 -0
- package/dist/rules/modal-verb.d.ts +3 -0
- package/dist/rules/modal-verb.d.ts.map +1 -0
- package/dist/rules/modal-verb.js +72 -0
- package/dist/rules/modal-verb.js.map +1 -0
- package/dist/rules/noun-cluster.d.ts +17 -0
- package/dist/rules/noun-cluster.d.ts.map +1 -0
- package/dist/rules/noun-cluster.js +83 -0
- package/dist/rules/noun-cluster.js.map +1 -0
- package/dist/rules/paragraph-length.d.ts +3 -0
- package/dist/rules/paragraph-length.d.ts.map +1 -0
- package/dist/rules/paragraph-length.js +19 -0
- package/dist/rules/paragraph-length.js.map +1 -0
- package/dist/rules/passive-instruction.d.ts +15 -0
- package/dist/rules/passive-instruction.d.ts.map +1 -0
- package/dist/rules/passive-instruction.js +38 -0
- package/dist/rules/passive-instruction.js.map +1 -0
- package/dist/rules/pronouns.d.ts +4 -0
- package/dist/rules/pronouns.d.ts.map +1 -0
- package/dist/rules/pronouns.js +57 -0
- package/dist/rules/pronouns.js.map +1 -0
- package/dist/rules/rule.d.ts +46 -0
- package/dist/rules/rule.d.ts.map +1 -0
- package/dist/rules/rule.js +31 -0
- package/dist/rules/rule.js.map +1 -0
- package/dist/rules/semicolon.d.ts +3 -0
- package/dist/rules/semicolon.d.ts.map +1 -0
- package/dist/rules/semicolon.js +20 -0
- package/dist/rules/semicolon.js.map +1 -0
- package/dist/rules/sentence-length.d.ts +3 -0
- package/dist/rules/sentence-length.d.ts.map +1 -0
- package/dist/rules/sentence-length.js +31 -0
- package/dist/rules/sentence-length.js.map +1 -0
- package/dist/rules/unknown-word.d.ts +9 -0
- package/dist/rules/unknown-word.d.ts.map +1 -0
- package/dist/rules/unknown-word.js +49 -0
- package/dist/rules/unknown-word.js.map +1 -0
- package/dist/rules/word-list-matcher.d.ts +25 -0
- package/dist/rules/word-list-matcher.d.ts.map +1 -0
- package/dist/rules/word-list-matcher.js +60 -0
- package/dist/rules/word-list-matcher.js.map +1 -0
- package/dist/rules/word-list.d.ts +3 -0
- package/dist/rules/word-list.d.ts.map +1 -0
- package/dist/rules/word-list.js +26 -0
- package/dist/rules/word-list.js.map +1 -0
- package/dist/run-cli.d.ts +27 -0
- package/dist/run-cli.d.ts.map +1 -0
- package/dist/run-cli.js +176 -0
- package/dist/run-cli.js.map +1 -0
- package/dist/source/blocks.d.ts +55 -0
- package/dist/source/blocks.d.ts.map +1 -0
- package/dist/source/blocks.js +464 -0
- package/dist/source/blocks.js.map +1 -0
- package/dist/source/inline.d.ts +42 -0
- package/dist/source/inline.d.ts.map +1 -0
- package/dist/source/inline.js +396 -0
- package/dist/source/inline.js.map +1 -0
- package/dist/source/jsx.d.ts +18 -0
- package/dist/source/jsx.d.ts.map +1 -0
- package/dist/source/jsx.js +137 -0
- package/dist/source/jsx.js.map +1 -0
- package/dist/source/lines.d.ts +34 -0
- package/dist/source/lines.d.ts.map +1 -0
- package/dist/source/lines.js +83 -0
- package/dist/source/lines.js.map +1 -0
- package/dist/source/markdown.d.ts +23 -0
- package/dist/source/markdown.d.ts.map +1 -0
- package/dist/source/markdown.js +42 -0
- package/dist/source/markdown.js.map +1 -0
- package/dist/source/suppressions.d.ts +38 -0
- package/dist/source/suppressions.d.ts.map +1 -0
- package/dist/source/suppressions.js +69 -0
- package/dist/source/suppressions.js.map +1 -0
- package/dist/source/tsdoc.d.ts +40 -0
- package/dist/source/tsdoc.d.ts.map +1 -0
- package/dist/source/tsdoc.js +176 -0
- package/dist/source/tsdoc.js.map +1 -0
- package/dist/text/grammar.d.ts +91 -0
- package/dist/text/grammar.d.ts.map +1 -0
- package/dist/text/grammar.js +289 -0
- package/dist/text/grammar.js.map +1 -0
- package/dist/text/phrases.d.ts +30 -0
- package/dist/text/phrases.d.ts.map +1 -0
- package/dist/text/phrases.js +65 -0
- package/dist/text/phrases.js.map +1 -0
- package/dist/text/sentences.d.ts +45 -0
- package/dist/text/sentences.d.ts.map +1 -0
- package/dist/text/sentences.js +141 -0
- package/dist/text/sentences.js.map +1 -0
- package/dist/text/tokens.d.ts +35 -0
- package/dist/text/tokens.d.ts.map +1 -0
- package/dist/text/tokens.js +113 -0
- package/dist/text/tokens.js.map +1 -0
- package/dist/text/words.d.ts +58 -0
- package/dist/text/words.d.ts.map +1 -0
- package/dist/text/words.js +159 -0
- package/dist/text/words.js.map +1 -0
- package/dist/types.d.ts +18 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +20 -0
- package/dist/types.js.map +1 -0
- package/dist/units.d.ts +47 -0
- package/dist/units.d.ts.map +1 -0
- package/dist/units.js +42 -0
- package/dist/units.js.map +1 -0
- package/dist/word-list.d.ts +34 -0
- package/dist/word-list.d.ts.map +1 -0
- package/dist/word-list.js +90 -0
- package/dist/word-list.js.map +1 -0
- package/package.json +46 -3
- package/src/cli.ts +9 -0
- package/src/config.test.ts +188 -0
- package/src/config.ts +318 -0
- package/src/dictionary.test.ts +82 -0
- package/src/dictionary.ts +177 -0
- package/src/files.test.ts +107 -0
- package/src/files.ts +191 -0
- package/src/format.ts +78 -0
- package/src/index.test.ts +28 -0
- package/src/index.ts +34 -0
- package/src/lexicon.ts +92 -0
- package/src/lint.test.ts +182 -0
- package/src/lint.ts +135 -0
- package/src/rules/about-quantity.ts +33 -0
- package/src/rules/index.ts +40 -0
- package/src/rules/ing-verb.test.ts +48 -0
- package/src/rules/ing-verb.ts +54 -0
- package/src/rules/latin-abbreviation.ts +46 -0
- package/src/rules/missing-subject.test.ts +53 -0
- package/src/rules/missing-subject.ts +129 -0
- package/src/rules/modal-verb.test.ts +45 -0
- package/src/rules/modal-verb.ts +72 -0
- package/src/rules/noun-cluster.test.ts +49 -0
- package/src/rules/noun-cluster.ts +82 -0
- package/src/rules/paragraph-length.test.ts +30 -0
- package/src/rules/paragraph-length.ts +19 -0
- package/src/rules/passive-instruction.test.ts +38 -0
- package/src/rules/passive-instruction.ts +37 -0
- package/src/rules/pronouns.test.ts +38 -0
- package/src/rules/pronouns.ts +54 -0
- package/src/rules/punctuation.test.ts +59 -0
- package/src/rules/rule.ts +73 -0
- package/src/rules/semicolon.ts +19 -0
- package/src/rules/sentence-length.test.ts +52 -0
- package/src/rules/sentence-length.ts +32 -0
- package/src/rules/unknown-word.test.ts +81 -0
- package/src/rules/unknown-word.ts +43 -0
- package/src/rules/word-list-matcher.ts +68 -0
- package/src/rules/word-list.test.ts +110 -0
- package/src/rules/word-list.ts +25 -0
- package/src/run-cli.test.ts +189 -0
- package/src/run-cli.ts +193 -0
- package/src/source/blocks.ts +534 -0
- package/src/source/inline.test.ts +92 -0
- package/src/source/inline.ts +416 -0
- package/src/source/jsx.test.ts +46 -0
- package/src/source/jsx.ts +147 -0
- package/src/source/lines.test.ts +51 -0
- package/src/source/lines.ts +91 -0
- package/src/source/markdown.test.ts +210 -0
- package/src/source/markdown.ts +49 -0
- package/src/source/suppressions.ts +79 -0
- package/src/source/tsdoc.test.ts +137 -0
- package/src/source/tsdoc.ts +189 -0
- package/src/text/grammar.ts +304 -0
- package/src/text/phrases.ts +72 -0
- package/src/text/sentences.ts +148 -0
- package/src/text/text.test.ts +262 -0
- package/src/text/tokens.ts +135 -0
- package/src/text/words.ts +183 -0
- package/src/types.ts +39 -0
- package/src/units.ts +86 -0
- package/src/word-list.ts +128 -0
- package/ste.config.schema.json +87 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The project word list: plain-language substitutions for the documentation
|
|
3
|
+
* of this repository. This list is the style guide of the project, written
|
|
4
|
+
* for it. It is not a copy of the ASD-STE100 dictionary. The local
|
|
5
|
+
* dictionary file (refer to `dictionary.ts`) does that job, and it is not
|
|
6
|
+
* part of the repository at any time.
|
|
7
|
+
*
|
|
8
|
+
* Each entry has the words or phrases to find, the words to write instead,
|
|
9
|
+
* and a severity. `ste.config.json` can add entries, change them, or set an
|
|
10
|
+
* entry to "off".
|
|
11
|
+
*/
|
|
12
|
+
function entry(input) {
|
|
13
|
+
return {
|
|
14
|
+
id: input.id ?? input.match[0],
|
|
15
|
+
match: input.match,
|
|
16
|
+
suggest: input.suggest ?? null,
|
|
17
|
+
note: input.note ?? null,
|
|
18
|
+
severity: input.severity ?? "error",
|
|
19
|
+
verbOnly: input.verbOnly ?? false,
|
|
20
|
+
context: input.context ?? null,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** The default word list. */
|
|
24
|
+
export const DEFAULT_WORD_LIST = [
|
|
25
|
+
// Long or formal words that have a short, common equivalent.
|
|
26
|
+
entry({ match: ["utilize", "utilizes", "utilized", "utilizing", "utilization", "utilise", "utilises", "utilised", "utilising"], suggest: "\"use\"" }),
|
|
27
|
+
entry({ match: ["initiate", "initiates", "initiated", "initiating"], suggest: "\"start\"" }),
|
|
28
|
+
entry({ match: ["ensure", "ensures", "ensured", "ensuring"], suggest: "\"make sure\"", note: "Write \"that\" after it: \"make sure that ...\"." }),
|
|
29
|
+
entry({ match: ["via"], suggest: "\"through\" or \"with\"" }),
|
|
30
|
+
entry({ match: ["leverage", "leverages", "leveraged", "leveraging"], suggest: "\"use\"" }),
|
|
31
|
+
entry({ match: ["facilitate", "facilitates", "facilitated", "facilitating"], suggest: "\"help\" or \"make ... easier\"" }),
|
|
32
|
+
entry({ match: ["commence", "commences", "commenced", "commencing"], suggest: "\"start\"" }),
|
|
33
|
+
entry({ match: ["terminate", "terminates", "terminated", "terminating"], suggest: "\"stop\"" }),
|
|
34
|
+
entry({ match: ["obtain", "obtains", "obtained", "obtaining"], suggest: "\"get\"" }),
|
|
35
|
+
entry({ match: ["assist", "assists", "assisted", "assisting"], suggest: "\"help\"" }),
|
|
36
|
+
entry({ match: ["modify", "modifies", "modified", "modifying"], suggest: "\"change\"" }),
|
|
37
|
+
entry({ match: ["indicate", "indicates", "indicated", "indicating"], suggest: "\"show\"" }),
|
|
38
|
+
entry({ match: ["demonstrate", "demonstrates", "demonstrated", "demonstrating"], suggest: "\"show\"" }),
|
|
39
|
+
entry({ match: ["perform", "performs", "performed", "performing"], suggest: "\"do\"" }),
|
|
40
|
+
entry({ match: ["attempt", "attempts", "attempted", "attempting"], suggest: "\"try\"" }),
|
|
41
|
+
entry({ match: ["numerous"], suggest: "\"many\", or give the number" }),
|
|
42
|
+
entry({ match: ["additional"], suggest: "\"more\"" }),
|
|
43
|
+
entry({ match: ["additionally"], suggest: "\"also\"" }),
|
|
44
|
+
entry({ match: ["regarding"], suggest: "\"about\"" }),
|
|
45
|
+
entry({ match: ["hence"], suggest: "\"thus\"" }),
|
|
46
|
+
// Phrases that have a shorter equivalent.
|
|
47
|
+
entry({ match: ["prior to"], suggest: "\"before\"" }),
|
|
48
|
+
entry({ match: ["in order to"], suggest: "\"to\"" }),
|
|
49
|
+
entry({ match: ["due to the fact that"], suggest: "\"because\"" }),
|
|
50
|
+
entry({ match: ["due to"], suggest: "\"because of\"" }),
|
|
51
|
+
entry({ match: ["in the event that"], suggest: "\"if\"" }),
|
|
52
|
+
entry({ match: ["at this point in time"], suggest: "\"at this time\"" }),
|
|
53
|
+
entry({ match: ["in an effort to"], suggest: "\"to\"" }),
|
|
54
|
+
entry({ match: ["for the purpose of"], suggest: "\"to\" or \"for\"" }),
|
|
55
|
+
entry({ match: ["with respect to", "with regard to"], suggest: "\"about\" or \"for\"" }),
|
|
56
|
+
entry({ match: ["as well as"], suggest: "\"and\"" }),
|
|
57
|
+
entry({ match: ["a number of"], suggest: "\"some\", or give the number" }),
|
|
58
|
+
entry({ match: ["is able to", "are able to", "be able to"], suggest: "\"can\"" }),
|
|
59
|
+
entry({ match: ["such as"], suggest: "\"for example\"" }),
|
|
60
|
+
entry({ match: ["follow these steps", "follow the steps"], suggest: "\"do these steps\" or \"do the steps\"" }),
|
|
61
|
+
// Connecting words.
|
|
62
|
+
entry({ match: ["however"], suggest: "\"but\"", note: "Start a new sentence with \"But\" if necessary." }),
|
|
63
|
+
entry({ match: ["therefore"], suggest: "\"thus\" or \"as a result\"" }),
|
|
64
|
+
entry({ match: ["whether or not", "whether"], suggest: "\"if\"" }),
|
|
65
|
+
// Verbs that have a simpler equivalent.
|
|
66
|
+
entry({ match: ["allow", "allows", "allowed", "allowing"], suggest: "\"let\" or \"lets\"", note: "For an adjective, write \"permitted\"." }),
|
|
67
|
+
entry({ match: ["require", "requires", "required", "requiring"], suggest: "\"necessary\"", note: "For example, write \"X is necessary for Y\", or use the imperative." }),
|
|
68
|
+
entry({ match: ["provided that"], suggest: "\"if\"" }),
|
|
69
|
+
entry({ match: ["provide", "provides", "provided", "providing"], suggest: "\"give\" or \"gives\"" }),
|
|
70
|
+
entry({ match: ["execute", "executes", "executed", "executing"], suggest: "\"do\", \"does\" or \"start\"" }),
|
|
71
|
+
entry({ match: ["create", "creates", "created", "creating"], suggest: "\"make\" or \"makes\"" }),
|
|
72
|
+
entry({ match: ["kill", "kills", "killed", "killing"], suggest: "\"stop\"" }),
|
|
73
|
+
entry({ id: "displays", match: ["displayed", "displaying"], suggest: "\"show\" or \"shows\"", severity: "warning" }),
|
|
74
|
+
entry({ id: "display", match: ["display", "displays"], suggest: "\"show\" or \"shows\"", severity: "warning", verbOnly: true }),
|
|
75
|
+
entry({ id: "returns", match: ["returns", "returned", "returning"], suggest: "\"gives\"", severity: "warning", note: "For a function, write \"This function gives ...\"." }),
|
|
76
|
+
entry({ id: "return", match: ["return"], suggest: "\"give\" or \"gives\"", severity: "warning", verbOnly: true }),
|
|
77
|
+
entry({ id: "call", match: ["call", "calls", "called", "calling"], suggest: "\"use\" or \"start\"", severity: "warning", verbOnly: true, note: "This applies when the verb means to start a function." }),
|
|
78
|
+
entry({ id: "ran", match: ["ran"], suggest: "\"started\" or \"operated\"", severity: "warning" }),
|
|
79
|
+
entry({ id: "run", match: ["run", "runs", "running"], suggest: "\"start\", \"starts\" or \"operates\"", severity: "warning", verbOnly: true }),
|
|
80
|
+
entry({ id: "see", match: ["see"], suggest: "\"refer to\"", severity: "warning", context: "reference" }),
|
|
81
|
+
// Words that do not add information.
|
|
82
|
+
entry({ match: ["simple", "simply", "easily"], severity: "warning", note: "The word tells the reader what to think. Tell the reader what to do." }),
|
|
83
|
+
entry({ match: ["just"], suggest: "\"only\"", severity: "warning", note: "Or remove the word." }),
|
|
84
|
+
entry({ match: ["basically", "obviously", "of course"], severity: "warning", note: "The word does not add information." }),
|
|
85
|
+
entry({ match: ["please"], severity: "warning", note: "Write the instruction in the imperative." }),
|
|
86
|
+
// Time and negation.
|
|
87
|
+
entry({ match: ["currently", "now"], suggest: "\"at this time\"", note: "Or remove the word if the time is clear." }),
|
|
88
|
+
entry({ match: ["never"], suggest: "\"do not\"", note: "For a description, write \"not ... at any time\"." }),
|
|
89
|
+
];
|
|
90
|
+
//# sourceMappingURL=word-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"word-list.js","sourceRoot":"","sources":["../src/word-list.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,49 @@
|
|
|
1
1
|
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package",
|
|
2
3
|
"name": "@mark1russell7/ste-lint",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
4
|
+
"version": "0.1.1",
|
|
5
|
+
"description": "A linter for the writing rules of ASD-STE100 Simplified Technical English in Markdown, MDX and TypeScript doc comments",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=22"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./ste.config.schema.json": "./ste.config.schema.json"
|
|
18
|
+
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"ste-lint": "./dist/cli.js"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"src",
|
|
25
|
+
"ste.config.schema.json"
|
|
26
|
+
],
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/mark1russell7/ste-lint.git"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"typescript": "^6.0.3"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@mark1russell7/cue": "^1.0.2",
|
|
39
|
+
"@types/node": "^26.6.4",
|
|
40
|
+
"tsx": "^4.23.15",
|
|
41
|
+
"vitest": "^5.0.3"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc -b",
|
|
45
|
+
"typecheck": "tsc -p tsconfig.test.json",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"lint:ste": "tsx src/cli.ts"
|
|
48
|
+
}
|
|
6
49
|
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir, tmpdir } from "node:os";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
|
+
import {
|
|
6
|
+
ConfigError,
|
|
7
|
+
DEFAULT_IGNORE,
|
|
8
|
+
DEFAULT_INCLUDE,
|
|
9
|
+
DEFAULT_LIMITS,
|
|
10
|
+
findConfigFile,
|
|
11
|
+
loadConfig,
|
|
12
|
+
mergeWordList,
|
|
13
|
+
resolveConfig,
|
|
14
|
+
resolvePath,
|
|
15
|
+
validateConfig,
|
|
16
|
+
} from "./config.js";
|
|
17
|
+
import { DEFAULT_WORD_LIST } from "./word-list.js";
|
|
18
|
+
|
|
19
|
+
let directory : string;
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
directory = mkdtempSync(join(tmpdir(), "ste-config-"));
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
rmSync(directory, { recursive : true, force : true });
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
describe("validateConfig", () => {
|
|
30
|
+
it("accepts a full configuration", () => {
|
|
31
|
+
const file = {
|
|
32
|
+
$schema : "./schema.json",
|
|
33
|
+
include : ["README.md"],
|
|
34
|
+
ignore : ["**/dist/**"],
|
|
35
|
+
technicalNouns : ["monitor"],
|
|
36
|
+
technicalVerbs : ["flush"],
|
|
37
|
+
properNouns : ["Grafana"],
|
|
38
|
+
allowedWords : ["okay"],
|
|
39
|
+
rules : { "modal-verb" : "warning", "noun-cluster" : "off" },
|
|
40
|
+
wordList : [{ match : ["blazingly fast"], suggest : "\"fast\"", severity : "warning", verbOnly : false, note : null }, { id : "via", severity : "off" }],
|
|
41
|
+
limits : { instructionWords : 18 },
|
|
42
|
+
dictionaryPath : null,
|
|
43
|
+
};
|
|
44
|
+
expect(validateConfig(file, "ste.config.json")).toBe(file);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("lists all problems in one error", () => {
|
|
48
|
+
const bad = {
|
|
49
|
+
unknown : 1,
|
|
50
|
+
include : "README.md",
|
|
51
|
+
rules : { "no-such-rule" : "error", "semicolon" : "fatal", "constructor" : "off" },
|
|
52
|
+
limits : { instructionWords : 0, constructor : 5, wordCount : 2 },
|
|
53
|
+
dictionaryPath : 3,
|
|
54
|
+
wordList : [{}, "x", { match : [], severity : "loud", verbOnly : "yes", id : 4, suggest : 5, extra : true }],
|
|
55
|
+
};
|
|
56
|
+
let message = "";
|
|
57
|
+
try {
|
|
58
|
+
validateConfig(bad, "ste.config.json");
|
|
59
|
+
} catch (error) {
|
|
60
|
+
expect(error).toBeInstanceOf(ConfigError);
|
|
61
|
+
message = (error as Error).message;
|
|
62
|
+
}
|
|
63
|
+
for (const part of [
|
|
64
|
+
"\"unknown\" is not a known property",
|
|
65
|
+
"\"include\" must be an array of strings",
|
|
66
|
+
"\"rules.no-such-rule\" is not a known rule",
|
|
67
|
+
"\"rules.semicolon\" must be \"error\", \"warning\" or \"off\"",
|
|
68
|
+
"\"rules.constructor\" is not a known rule",
|
|
69
|
+
"\"limits.instructionWords\" must be an integer of 1 or more",
|
|
70
|
+
"\"limits.constructor\" is not a known limit",
|
|
71
|
+
"\"limits.wordCount\" is not a known limit",
|
|
72
|
+
"\"dictionaryPath\" must be a string or null",
|
|
73
|
+
"\"wordList[0]\" must have \"id\" or \"match\"",
|
|
74
|
+
"\"wordList[1]\" must be an object",
|
|
75
|
+
"\"wordList[2].match\" must be a string or an array of strings",
|
|
76
|
+
"\"wordList[2].severity\"",
|
|
77
|
+
"\"wordList[2].verbOnly\" must be true or false",
|
|
78
|
+
"\"wordList[2].id\" must be a string",
|
|
79
|
+
"\"wordList[2].suggest\" must be a string or null",
|
|
80
|
+
"\"wordList[2].extra\" is not a known property",
|
|
81
|
+
]) {
|
|
82
|
+
expect(message).toContain(part);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("rejects values that are not objects", () => {
|
|
87
|
+
expect(() => validateConfig([], "x")).toThrow(ConfigError);
|
|
88
|
+
expect(() => validateConfig(null, "x")).toThrow("must be a JSON object");
|
|
89
|
+
expect(() => validateConfig({ rules : [] }, "x")).toThrow("\"rules\" must be an object");
|
|
90
|
+
expect(() => validateConfig({ limits : 3 }, "x")).toThrow("\"limits\" must be an object");
|
|
91
|
+
expect(() => validateConfig({ wordList : {} }, "x")).toThrow("\"wordList\" must be an array");
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe("resolveConfig", () => {
|
|
96
|
+
it("applies the defaults", () => {
|
|
97
|
+
const config = resolveConfig({}, { root : directory });
|
|
98
|
+
expect(config.include).toBe(DEFAULT_INCLUDE);
|
|
99
|
+
expect(config.ignore).toBe(DEFAULT_IGNORE);
|
|
100
|
+
expect(config.limits).toEqual(DEFAULT_LIMITS);
|
|
101
|
+
expect(config.wordList).toEqual(DEFAULT_WORD_LIST);
|
|
102
|
+
expect(config.dictionaryPath).toBeNull();
|
|
103
|
+
expect(config.dictionarySource).toBeNull();
|
|
104
|
+
expect(config.configFile).toBeNull();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("keeps known rule settings and merges the limits", () => {
|
|
108
|
+
const config = resolveConfig({ rules : { "modal-verb" : "warning" }, limits : { paragraphSentences : 4 } }, { root : directory });
|
|
109
|
+
expect(config.rules).toEqual({ "modal-verb" : "warning" });
|
|
110
|
+
expect(config.limits).toEqual({ ...DEFAULT_LIMITS, paragraphSentences : 4 });
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("resolves the dictionary path from the configuration, relative to the root", () => {
|
|
114
|
+
const config = resolveConfig({ dictionaryPath : ".ste/dictionary.json" }, { root : directory });
|
|
115
|
+
expect(config.dictionaryPath).toBe(resolve(directory, ".ste/dictionary.json"));
|
|
116
|
+
expect(config.dictionarySource).toBe("config");
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it("gives the environment variable priority, relative to the working directory", () => {
|
|
120
|
+
const config = resolveConfig({ dictionaryPath : "a.json" }, { root : directory, cwd : "/work", env : { STE_DICTIONARY : "b.json" } });
|
|
121
|
+
expect(config.dictionaryPath).toBe(resolve("/work", "b.json"));
|
|
122
|
+
expect(config.dictionarySource).toBe("env");
|
|
123
|
+
expect(resolveConfig({}, { root : directory, env : { STE_DICTIONARY : " " } }).dictionaryPath).toBeNull();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it("expands ~ to the home directory", () => {
|
|
127
|
+
expect(resolvePath("~/ste/dictionary.json", "/base")).toBe(join(homedir(), "ste/dictionary.json"));
|
|
128
|
+
expect(resolvePath("~", "/base")).toBe(homedir());
|
|
129
|
+
expect(resolvePath("/abs/file.json", "/base")).toBe(resolve("/abs/file.json"));
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe("mergeWordList", () => {
|
|
134
|
+
it("changes, adds and removes entries", () => {
|
|
135
|
+
const merged = mergeWordList(DEFAULT_WORD_LIST, [
|
|
136
|
+
{ id : "via", suggest : "\"by\"", severity : "warning" },
|
|
137
|
+
{ match : "blazingly fast", suggest : "\"fast\"" },
|
|
138
|
+
{ id : "utilize", severity : "off" },
|
|
139
|
+
{ match : ["easily"], severity : "off" },
|
|
140
|
+
]);
|
|
141
|
+
const byId = new Map(merged.map((entry) => [entry.id, entry]));
|
|
142
|
+
expect(byId.get("via")).toMatchObject({ suggest : "\"by\"", severity : "warning", match : ["via"] });
|
|
143
|
+
expect(byId.get("blazingly fast")).toMatchObject({ match : ["blazingly fast"], suggest : "\"fast\"", severity : "error", verbOnly : false, note : null });
|
|
144
|
+
expect(byId.has("utilize")).toBe(false);
|
|
145
|
+
expect(byId.get("simple")!.match).toEqual(["simple", "simply"]);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("removes an entry that has no words left", () => {
|
|
149
|
+
const merged = mergeWordList(DEFAULT_WORD_LIST, [{ match : ["numerous"], severity : "off" }]);
|
|
150
|
+
expect(merged.some((entry) => entry.id === "numerous")).toBe(false);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it("keeps the fields of a default entry that the override does not give", () => {
|
|
154
|
+
const merged = mergeWordList(DEFAULT_WORD_LIST, [{ id : "run", note : "Extra." }]);
|
|
155
|
+
expect(merged.find((entry) => entry.id === "run")).toMatchObject({ verbOnly : true, severity : "warning", note : "Extra." });
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
describe("loadConfig", () => {
|
|
160
|
+
it("finds ste.config.json in a parent directory and uses its directory as the root", () => {
|
|
161
|
+
writeFileSync(join(directory, "ste.config.json"), JSON.stringify({ technicalNouns : ["monitor"], dictionaryPath : "dict.json" }));
|
|
162
|
+
const nested = join(directory, "a", "b");
|
|
163
|
+
mkdirSync(nested, { recursive : true });
|
|
164
|
+
expect(findConfigFile(nested)).toBe(join(directory, "ste.config.json"));
|
|
165
|
+
const config = loadConfig({ cwd : nested });
|
|
166
|
+
expect(config.root).toBe(directory);
|
|
167
|
+
expect(config.technicalNouns).toEqual(["monitor"]);
|
|
168
|
+
expect(config.dictionaryPath).toBe(join(directory, "dict.json"));
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("uses the defaults without a configuration file", () => {
|
|
172
|
+
const config = loadConfig({ cwd : directory, env : {} });
|
|
173
|
+
expect(config.configFile === null || !config.configFile.startsWith(directory)).toBe(true);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("reads an explicit configuration file", () => {
|
|
177
|
+
writeFileSync(join(directory, "custom.json"), JSON.stringify({ rules : { semicolon : "warning" } }));
|
|
178
|
+
expect(loadConfig({ cwd : directory, configPath : "custom.json" }).rules).toEqual({ semicolon : "warning" });
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it("gives clear errors for a missing file, a file that is not JSON and a configuration that is not valid", () => {
|
|
182
|
+
expect(() => loadConfig({ cwd : directory, configPath : "missing.json" })).toThrow("Cannot read the configuration file");
|
|
183
|
+
writeFileSync(join(directory, "broken.json"), "{ nope");
|
|
184
|
+
expect(() => loadConfig({ cwd : directory, configPath : "broken.json" })).toThrow("is not valid JSON");
|
|
185
|
+
writeFileSync(join(directory, "invalid.json"), JSON.stringify({ rules : { nope : "error" } }));
|
|
186
|
+
expect(() => loadConfig({ cwd : directory, configPath : "invalid.json" })).toThrow("is not a known rule");
|
|
187
|
+
});
|
|
188
|
+
});
|