@codeperfect/eslint-plugin 1.0.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.
Files changed (248) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +128 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/architecture/consistent-barrel-files/consistent-barrel-files-listeners.d.ts +16 -0
  5. package/dist/architecture/consistent-barrel-files/consistent-barrel-files-listeners.d.ts.map +1 -0
  6. package/dist/architecture/consistent-barrel-files/consistent-barrel-files-listeners.js +131 -0
  7. package/dist/architecture/consistent-barrel-files/consistent-barrel-files-options.d.ts +48 -0
  8. package/dist/architecture/consistent-barrel-files/consistent-barrel-files-options.d.ts.map +1 -0
  9. package/dist/architecture/consistent-barrel-files/consistent-barrel-files-options.js +126 -0
  10. package/dist/architecture/consistent-barrel-files/exports-only-rule-test-utilities.d.ts +40 -0
  11. package/dist/architecture/consistent-barrel-files/exports-only-rule-test-utilities.d.ts.map +1 -0
  12. package/dist/architecture/consistent-barrel-files/exports-only-rule-test-utilities.js +90 -0
  13. package/dist/architecture/consistent-barrel-files/exports-only-rule.d.ts +11 -0
  14. package/dist/architecture/consistent-barrel-files/exports-only-rule.d.ts.map +1 -0
  15. package/dist/architecture/consistent-barrel-files/exports-only-rule.js +218 -0
  16. package/dist/architecture/consistent-barrel-files/index.d.ts +5 -0
  17. package/dist/architecture/consistent-barrel-files/index.d.ts.map +1 -0
  18. package/dist/architecture/consistent-barrel-files/index.js +4 -0
  19. package/dist/architecture/consistent-barrel-files/no-reexports-outside-barrels-rule.d.ts +11 -0
  20. package/dist/architecture/consistent-barrel-files/no-reexports-outside-barrels-rule.d.ts.map +1 -0
  21. package/dist/architecture/consistent-barrel-files/no-reexports-outside-barrels-rule.js +100 -0
  22. package/dist/architecture/consistent-barrel-files/no-reexports-outside-barrels-test-utilities.d.ts +40 -0
  23. package/dist/architecture/consistent-barrel-files/no-reexports-outside-barrels-test-utilities.d.ts.map +1 -0
  24. package/dist/architecture/consistent-barrel-files/no-reexports-outside-barrels-test-utilities.js +90 -0
  25. package/dist/architecture/consistent-barrel-files/no-reexports-outside-barrels-utilities.d.ts +65 -0
  26. package/dist/architecture/consistent-barrel-files/no-reexports-outside-barrels-utilities.d.ts.map +1 -0
  27. package/dist/architecture/consistent-barrel-files/no-reexports-outside-barrels-utilities.js +154 -0
  28. package/dist/architecture/consistent-barrel-files/rule.d.ts +11 -0
  29. package/dist/architecture/consistent-barrel-files/rule.d.ts.map +1 -0
  30. package/dist/architecture/consistent-barrel-files/rule.js +58 -0
  31. package/dist/architecture/consistent-barrel-files/test-helpers.d.ts +141 -0
  32. package/dist/architecture/consistent-barrel-files/test-helpers.d.ts.map +1 -0
  33. package/dist/architecture/consistent-barrel-files/test-helpers.js +229 -0
  34. package/dist/architecture/consistent-barrel-files/types.d.ts +25 -0
  35. package/dist/architecture/consistent-barrel-files/types.d.ts.map +1 -0
  36. package/dist/architecture/consistent-barrel-files/types.js +2 -0
  37. package/dist/architecture/index.d.ts +2 -0
  38. package/dist/architecture/index.d.ts.map +1 -0
  39. package/dist/architecture/index.js +2 -0
  40. package/dist/benchmark-rules.d.ts +83 -0
  41. package/dist/benchmark-rules.d.ts.map +1 -0
  42. package/dist/benchmark-rules.js +175 -0
  43. package/dist/codeperfect-eslint-plugin-1.0.0.tgz +0 -0
  44. package/dist/codeperfect-plugin.d.ts +46 -0
  45. package/dist/codeperfect-plugin.d.ts.map +1 -0
  46. package/dist/codeperfect-plugin.js +29 -0
  47. package/dist/core/index.d.ts +3 -0
  48. package/dist/core/index.d.ts.map +1 -0
  49. package/dist/core/index.js +3 -0
  50. package/dist/core/no-multiple-declarators/index.d.ts +2 -0
  51. package/dist/core/no-multiple-declarators/index.d.ts.map +1 -0
  52. package/dist/core/no-multiple-declarators/index.js +2 -0
  53. package/dist/core/no-multiple-declarators/rule.d.ts +4 -0
  54. package/dist/core/no-multiple-declarators/rule.d.ts.map +1 -0
  55. package/dist/core/no-multiple-declarators/rule.js +100 -0
  56. package/dist/core/prefer-interface-types/index.d.ts +2 -0
  57. package/dist/core/prefer-interface-types/index.d.ts.map +1 -0
  58. package/dist/core/prefer-interface-types/index.js +2 -0
  59. package/dist/core/prefer-interface-types/rule.d.ts +5 -0
  60. package/dist/core/prefer-interface-types/rule.d.ts.map +1 -0
  61. package/dist/core/prefer-interface-types/rule.js +145 -0
  62. package/dist/core/prefer-interface-types/test-helpers.d.ts +110 -0
  63. package/dist/core/prefer-interface-types/test-helpers.d.ts.map +1 -0
  64. package/dist/core/prefer-interface-types/test-helpers.js +116 -0
  65. package/dist/custom-rule-documentation.d.ts +36 -0
  66. package/dist/custom-rule-documentation.d.ts.map +1 -0
  67. package/dist/custom-rule-documentation.js +35 -0
  68. package/dist/custom-rules.d.ts +61 -0
  69. package/dist/custom-rules.d.ts.map +1 -0
  70. package/dist/custom-rules.js +70 -0
  71. package/dist/docs/index.d.ts +4 -0
  72. package/dist/docs/index.d.ts.map +1 -0
  73. package/dist/docs/index.js +4 -0
  74. package/dist/docs/no-interface-member-docs/comment-utilities-test-helpers.d.ts +89 -0
  75. package/dist/docs/no-interface-member-docs/comment-utilities-test-helpers.d.ts.map +1 -0
  76. package/dist/docs/no-interface-member-docs/comment-utilities-test-helpers.js +129 -0
  77. package/dist/docs/no-interface-member-docs/comment-utilities.d.ts +48 -0
  78. package/dist/docs/no-interface-member-docs/comment-utilities.d.ts.map +1 -0
  79. package/dist/docs/no-interface-member-docs/comment-utilities.js +146 -0
  80. package/dist/docs/no-interface-member-docs/index.d.ts +2 -0
  81. package/dist/docs/no-interface-member-docs/index.d.ts.map +1 -0
  82. package/dist/docs/no-interface-member-docs/index.js +2 -0
  83. package/dist/docs/no-interface-member-docs/parameter-tags.d.ts +13 -0
  84. package/dist/docs/no-interface-member-docs/parameter-tags.d.ts.map +1 -0
  85. package/dist/docs/no-interface-member-docs/parameter-tags.js +101 -0
  86. package/dist/docs/no-interface-member-docs/parameter-utilities.d.ts +24 -0
  87. package/dist/docs/no-interface-member-docs/parameter-utilities.d.ts.map +1 -0
  88. package/dist/docs/no-interface-member-docs/parameter-utilities.js +125 -0
  89. package/dist/docs/no-interface-member-docs/rule.d.ts +5 -0
  90. package/dist/docs/no-interface-member-docs/rule.d.ts.map +1 -0
  91. package/dist/docs/no-interface-member-docs/rule.js +168 -0
  92. package/dist/docs/no-interface-member-docs/test-helpers.d.ts +103 -0
  93. package/dist/docs/no-interface-member-docs/test-helpers.d.ts.map +1 -0
  94. package/dist/docs/no-interface-member-docs/test-helpers.js +157 -0
  95. package/dist/docs/no-interface-member-docs/types.d.ts +30 -0
  96. package/dist/docs/no-interface-member-docs/types.d.ts.map +1 -0
  97. package/dist/docs/no-interface-member-docs/types.js +2 -0
  98. package/dist/docs/require-example-language/empty-fence-fixes.d.ts +29 -0
  99. package/dist/docs/require-example-language/empty-fence-fixes.d.ts.map +1 -0
  100. package/dist/docs/require-example-language/empty-fence-fixes.js +169 -0
  101. package/dist/docs/require-example-language/example-utilities.d.ts +70 -0
  102. package/dist/docs/require-example-language/example-utilities.d.ts.map +1 -0
  103. package/dist/docs/require-example-language/example-utilities.js +76 -0
  104. package/dist/docs/require-example-language/examples.d.ts +36 -0
  105. package/dist/docs/require-example-language/examples.d.ts.map +1 -0
  106. package/dist/docs/require-example-language/examples.js +181 -0
  107. package/dist/docs/require-example-language/fixes.d.ts +49 -0
  108. package/dist/docs/require-example-language/fixes.d.ts.map +1 -0
  109. package/dist/docs/require-example-language/fixes.js +182 -0
  110. package/dist/docs/require-example-language/index.d.ts +3 -0
  111. package/dist/docs/require-example-language/index.d.ts.map +1 -0
  112. package/dist/docs/require-example-language/index.js +2 -0
  113. package/dist/docs/require-example-language/reporting.d.ts +60 -0
  114. package/dist/docs/require-example-language/reporting.d.ts.map +1 -0
  115. package/dist/docs/require-example-language/reporting.js +145 -0
  116. package/dist/docs/require-example-language/rule.d.ts +7 -0
  117. package/dist/docs/require-example-language/rule.d.ts.map +1 -0
  118. package/dist/docs/require-example-language/rule.js +34 -0
  119. package/dist/docs/require-example-language/types.d.ts +22 -0
  120. package/dist/docs/require-example-language/types.d.ts.map +1 -0
  121. package/dist/docs/require-example-language/types.js +2 -0
  122. package/dist/docs/single-line-jsdoc/index.d.ts +2 -0
  123. package/dist/docs/single-line-jsdoc/index.d.ts.map +1 -0
  124. package/dist/docs/single-line-jsdoc/index.js +2 -0
  125. package/dist/docs/single-line-jsdoc/rule.d.ts +5 -0
  126. package/dist/docs/single-line-jsdoc/rule.d.ts.map +1 -0
  127. package/dist/docs/single-line-jsdoc/rule.js +196 -0
  128. package/dist/docs/single-line-jsdoc/single-line-jsdoc-content.d.ts +16 -0
  129. package/dist/docs/single-line-jsdoc/single-line-jsdoc-content.d.ts.map +1 -0
  130. package/dist/docs/single-line-jsdoc/single-line-jsdoc-content.js +95 -0
  131. package/dist/docs/single-line-jsdoc/single-line-jsdoc-utilities.d.ts +25 -0
  132. package/dist/docs/single-line-jsdoc/single-line-jsdoc-utilities.d.ts.map +1 -0
  133. package/dist/docs/single-line-jsdoc/single-line-jsdoc-utilities.js +140 -0
  134. package/dist/docs/test-helpers.d.ts +50 -0
  135. package/dist/docs/test-helpers.d.ts.map +1 -0
  136. package/dist/docs/test-helpers.js +107 -0
  137. package/dist/index.d.ts +6 -0
  138. package/dist/index.d.ts.map +1 -0
  139. package/dist/index.js +6 -0
  140. package/dist/presets.d.ts +10 -0
  141. package/dist/presets.d.ts.map +1 -0
  142. package/dist/presets.js +50 -0
  143. package/dist/rules/index.d.ts +5 -0
  144. package/dist/rules/index.d.ts.map +1 -0
  145. package/dist/rules/index.js +6 -0
  146. package/dist/testing/aaa/analyzer.d.ts +36 -0
  147. package/dist/testing/aaa/analyzer.d.ts.map +1 -0
  148. package/dist/testing/aaa/analyzer.js +490 -0
  149. package/dist/testing/aaa/index.d.ts +3 -0
  150. package/dist/testing/aaa/index.d.ts.map +1 -0
  151. package/dist/testing/aaa/index.js +2 -0
  152. package/dist/testing/aaa/types.d.ts +31 -0
  153. package/dist/testing/aaa/types.d.ts.map +1 -0
  154. package/dist/testing/aaa/types.js +2 -0
  155. package/dist/testing/assert-actual-expected-names/index.d.ts +2 -0
  156. package/dist/testing/assert-actual-expected-names/index.d.ts.map +1 -0
  157. package/dist/testing/assert-actual-expected-names/index.js +2 -0
  158. package/dist/testing/assert-actual-expected-names/rule.d.ts +4 -0
  159. package/dist/testing/assert-actual-expected-names/rule.d.ts.map +1 -0
  160. package/dist/testing/assert-actual-expected-names/rule.js +54 -0
  161. package/dist/testing/enforce-aaa-phase-purity/index.d.ts +2 -0
  162. package/dist/testing/enforce-aaa-phase-purity/index.d.ts.map +1 -0
  163. package/dist/testing/enforce-aaa-phase-purity/index.js +2 -0
  164. package/dist/testing/enforce-aaa-phase-purity/rule.d.ts +4 -0
  165. package/dist/testing/enforce-aaa-phase-purity/rule.d.ts.map +1 -0
  166. package/dist/testing/enforce-aaa-phase-purity/rule.js +110 -0
  167. package/dist/testing/enforce-aaa-structure/index.d.ts +2 -0
  168. package/dist/testing/enforce-aaa-structure/index.d.ts.map +1 -0
  169. package/dist/testing/enforce-aaa-structure/index.js +2 -0
  170. package/dist/testing/enforce-aaa-structure/rule.d.ts +4 -0
  171. package/dist/testing/enforce-aaa-structure/rule.d.ts.map +1 -0
  172. package/dist/testing/enforce-aaa-structure/rule.js +48 -0
  173. package/dist/testing/index.d.ts +9 -0
  174. package/dist/testing/index.d.ts.map +1 -0
  175. package/dist/testing/index.js +9 -0
  176. package/dist/testing/prefer-vi-mocked-import/fix.d.ts +16 -0
  177. package/dist/testing/prefer-vi-mocked-import/fix.d.ts.map +1 -0
  178. package/dist/testing/prefer-vi-mocked-import/fix.js +224 -0
  179. package/dist/testing/prefer-vi-mocked-import/index.d.ts +2 -0
  180. package/dist/testing/prefer-vi-mocked-import/index.d.ts.map +1 -0
  181. package/dist/testing/prefer-vi-mocked-import/index.js +2 -0
  182. package/dist/testing/prefer-vi-mocked-import/match-bindings.d.ts +16 -0
  183. package/dist/testing/prefer-vi-mocked-import/match-bindings.d.ts.map +1 -0
  184. package/dist/testing/prefer-vi-mocked-import/match-bindings.js +52 -0
  185. package/dist/testing/prefer-vi-mocked-import/match-declarations.d.ts +16 -0
  186. package/dist/testing/prefer-vi-mocked-import/match-declarations.d.ts.map +1 -0
  187. package/dist/testing/prefer-vi-mocked-import/match-declarations.js +99 -0
  188. package/dist/testing/prefer-vi-mocked-import/match-helpers.d.ts +66 -0
  189. package/dist/testing/prefer-vi-mocked-import/match-helpers.d.ts.map +1 -0
  190. package/dist/testing/prefer-vi-mocked-import/match-helpers.js +102 -0
  191. package/dist/testing/prefer-vi-mocked-import/match-imports.d.ts +17 -0
  192. package/dist/testing/prefer-vi-mocked-import/match-imports.d.ts.map +1 -0
  193. package/dist/testing/prefer-vi-mocked-import/match-imports.js +156 -0
  194. package/dist/testing/prefer-vi-mocked-import/match-rewrites.d.ts +42 -0
  195. package/dist/testing/prefer-vi-mocked-import/match-rewrites.d.ts.map +1 -0
  196. package/dist/testing/prefer-vi-mocked-import/match-rewrites.js +119 -0
  197. package/dist/testing/prefer-vi-mocked-import/match-walk.d.ts +13 -0
  198. package/dist/testing/prefer-vi-mocked-import/match-walk.d.ts.map +1 -0
  199. package/dist/testing/prefer-vi-mocked-import/match-walk.js +62 -0
  200. package/dist/testing/prefer-vi-mocked-import/match.d.ts +15 -0
  201. package/dist/testing/prefer-vi-mocked-import/match.d.ts.map +1 -0
  202. package/dist/testing/prefer-vi-mocked-import/match.js +193 -0
  203. package/dist/testing/prefer-vi-mocked-import/rule.d.ts +5 -0
  204. package/dist/testing/prefer-vi-mocked-import/rule.d.ts.map +1 -0
  205. package/dist/testing/prefer-vi-mocked-import/rule.js +32 -0
  206. package/dist/testing/prefer-vi-mocked-import/types.d.ts +83 -0
  207. package/dist/testing/prefer-vi-mocked-import/types.d.ts.map +1 -0
  208. package/dist/testing/prefer-vi-mocked-import/types.js +2 -0
  209. package/dist/testing/require-aaa-sections/index.d.ts +2 -0
  210. package/dist/testing/require-aaa-sections/index.d.ts.map +1 -0
  211. package/dist/testing/require-aaa-sections/index.js +2 -0
  212. package/dist/testing/require-aaa-sections/rule.d.ts +4 -0
  213. package/dist/testing/require-aaa-sections/rule.d.ts.map +1 -0
  214. package/dist/testing/require-aaa-sections/rule.js +111 -0
  215. package/dist/testing/require-act-result-capture/index.d.ts +2 -0
  216. package/dist/testing/require-act-result-capture/index.d.ts.map +1 -0
  217. package/dist/testing/require-act-result-capture/index.js +2 -0
  218. package/dist/testing/require-act-result-capture/rule.d.ts +4 -0
  219. package/dist/testing/require-act-result-capture/rule.d.ts.map +1 -0
  220. package/dist/testing/require-act-result-capture/rule.js +34 -0
  221. package/dist/testing/require-test-companion/index.d.ts +3 -0
  222. package/dist/testing/require-test-companion/index.d.ts.map +1 -0
  223. package/dist/testing/require-test-companion/index.js +3 -0
  224. package/dist/testing/require-test-companion/require-test-companion-listeners.d.ts +16 -0
  225. package/dist/testing/require-test-companion/require-test-companion-listeners.d.ts.map +1 -0
  226. package/dist/testing/require-test-companion/require-test-companion-listeners.js +145 -0
  227. package/dist/testing/require-test-companion/require-test-companion-options.d.ts +54 -0
  228. package/dist/testing/require-test-companion/require-test-companion-options.d.ts.map +1 -0
  229. package/dist/testing/require-test-companion/require-test-companion-options.js +112 -0
  230. package/dist/testing/require-test-companion/require-test-companion-test-helpers.d.ts +51 -0
  231. package/dist/testing/require-test-companion/require-test-companion-test-helpers.d.ts.map +1 -0
  232. package/dist/testing/require-test-companion/require-test-companion-test-helpers.js +183 -0
  233. package/dist/testing/require-test-companion/require-test-companion-utilities.d.ts +28 -0
  234. package/dist/testing/require-test-companion/require-test-companion-utilities.d.ts.map +1 -0
  235. package/dist/testing/require-test-companion/require-test-companion-utilities.js +26 -0
  236. package/dist/testing/require-test-companion/rule.d.ts +5 -0
  237. package/dist/testing/require-test-companion/rule.d.ts.map +1 -0
  238. package/dist/testing/require-test-companion/rule.js +57 -0
  239. package/dist/testing/require-test-companion/types.d.ts +11 -0
  240. package/dist/testing/require-test-companion/types.d.ts.map +1 -0
  241. package/dist/testing/require-test-companion/types.js +2 -0
  242. package/dist/testing/single-act-statement/index.d.ts +2 -0
  243. package/dist/testing/single-act-statement/index.d.ts.map +1 -0
  244. package/dist/testing/single-act-statement/index.js +2 -0
  245. package/dist/testing/single-act-statement/rule.d.ts +4 -0
  246. package/dist/testing/single-act-statement/rule.d.ts.map +1 -0
  247. package/dist/testing/single-act-statement/rule.js +33 -0
  248. package/package.json +106 -0
@@ -0,0 +1,183 @@
1
+ import { SourceCode } from "eslint";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { requireTestCompanionRule } from "./rule";
5
+ /** Tracks temporary directories so tests can clean them up. */
6
+ const temporaryDirectories = [];
7
+ /**
8
+ * Creates createRepoDirectory.
9
+ * @param root Input root value.
10
+ * @returns Return value output.
11
+ * @example
12
+ * ```typescript
13
+ * createRepoDirectory();
14
+ * ```
15
+ */
16
+ const createRepoDirectory = (root) => {
17
+ const baseDirectory = path.join(process.cwd(), root);
18
+ fs.mkdirSync(baseDirectory, { recursive: true });
19
+ return fs.mkdtempSync(path.join(baseDirectory, "test-companion-"));
20
+ };
21
+ /**
22
+ * Writes a simple TypeScript file at the provided path.
23
+ * @param filePath Input filePath value.
24
+ * @example
25
+ * ```typescript
26
+ * writeFile("/tmp/feature.ts");
27
+ * ```
28
+ */
29
+ const writeFile = (filePath) => {
30
+ fs.writeFileSync(filePath, "export const value = 1;", "utf8");
31
+ };
32
+ /**
33
+ * Creates createTemporaryFile.
34
+ * @param root Input root value.
35
+ * @param filename Input filename value.
36
+ * @returns Return value output.
37
+ * @example
38
+ * ```typescript
39
+ * createTemporaryFile();
40
+ * ```
41
+ */
42
+ const createTemporaryFile = (root, filename) => {
43
+ const directory = createRepoDirectory(root);
44
+ temporaryDirectories.push(directory);
45
+ const filePath = path.join(directory, filename);
46
+ writeFile(filePath);
47
+ return filePath;
48
+ };
49
+ /**
50
+ * Creates multiple temporary files under the given root.
51
+ * @param root Input root value.
52
+ * @param filenames Input filenames value.
53
+ * @returns Paths to the created files.
54
+ * @example
55
+ * ```typescript
56
+ * const paths = createTemporaryFiles("tmp", ["a.ts", "b.ts"]);
57
+ * ```
58
+ */
59
+ const createTemporaryFiles = (root, filenames) => {
60
+ const directory = createRepoDirectory(root);
61
+ temporaryDirectories.push(directory);
62
+ return filenames.map((filename) => {
63
+ const filePath = path.join(directory, filename);
64
+ writeFile(filePath);
65
+ return filePath;
66
+ });
67
+ };
68
+ /**
69
+ * Creates a temporary file pair for test/source combinations.
70
+ * @param root Input root value.
71
+ * @param first Input first value.
72
+ * @param second Input second value.
73
+ * @returns Tuple of created file paths.
74
+ * @throws {Error} When the file paths are missing.
75
+ * @example
76
+ * ```typescript
77
+ * const [source, test] = createTemporaryPair("tmp", "a.ts", "a.spec.ts");
78
+ * ```
79
+ */
80
+ const createTemporaryPair = (root, first, second) => {
81
+ const [firstPath, secondPath] = createTemporaryFiles(root, [
82
+ first,
83
+ second,
84
+ ]);
85
+ return [firstPath, secondPath];
86
+ };
87
+ /**
88
+ * Creates createProgramAst.
89
+ * @returns Return value output.
90
+ * @example
91
+ * ```typescript
92
+ * createProgramAst();
93
+ * ```
94
+ */
95
+ const createProgramAst = () => ({
96
+ body: [],
97
+ comments: [],
98
+ loc: {
99
+ end: { column: 0, line: 1 },
100
+ start: { column: 0, line: 1 },
101
+ },
102
+ range: [0, 0],
103
+ sourceType: "module",
104
+ tokens: [],
105
+ type: "Program",
106
+ });
107
+ /**
108
+ * Creates a rule context for the given filename.
109
+ * @param filename Input filename value.
110
+ * @param reports Input reports value.
111
+ * @param sourceCode Input sourceCode value.
112
+ * @returns Rule context for tests.
113
+ * @example
114
+ * ```typescript
115
+ * const context = createRuleContext(file, reports, sourceCode);
116
+ * ```
117
+ */
118
+ const createRuleContext = (filename, reports, sourceCode) => ({
119
+ cwd: process.cwd(),
120
+ filename,
121
+ id: "require-test-companion",
122
+ languageOptions: {
123
+ ecmaVersion: "latest",
124
+ sourceType: "module",
125
+ },
126
+ options: [],
127
+ parserOptions: {},
128
+ parserPath: void 0,
129
+ physicalFilename: filename,
130
+ report: (report) => {
131
+ const { messageId } = report;
132
+ reports.push({ messageId });
133
+ },
134
+ settings: {},
135
+ sourceCode,
136
+ });
137
+ /**
138
+ * Runs the rule listeners for a context.
139
+ * @param context Input context value.
140
+ * @example
141
+ * ```typescript
142
+ * runListeners(context);
143
+ * ```
144
+ */
145
+ const runListeners = (context) => {
146
+ const listeners = requireTestCompanionRule.create(context);
147
+ const programNode = context.sourceCode.ast;
148
+ const programListener = listeners.Program;
149
+ programListener?.(programNode);
150
+ };
151
+ /**
152
+ * Runs the rule with the given options.
153
+ * @param filename Input filename value.
154
+ * @param options Input options value.
155
+ * @returns Collected rule reports.
156
+ * @example
157
+ * ```typescript
158
+ * const reports = runRule("/tmp/feature.ts");
159
+ * ```
160
+ */
161
+ const runRule = (filename, options) => {
162
+ const reports = [];
163
+ const programAst = createProgramAst();
164
+ const sourceCode = new SourceCode("", programAst);
165
+ const context = createRuleContext(filename, reports, sourceCode);
166
+ context.options = options === void 0 ? [] : [options];
167
+ runListeners(context);
168
+ return reports;
169
+ };
170
+ /**
171
+ * Cleans up temporary directories created by tests.
172
+ * @example
173
+ * ```typescript
174
+ * cleanupTemporaryDirectories();
175
+ * ```
176
+ */
177
+ const cleanupTemporaryDirectories = () => {
178
+ for (const directory of temporaryDirectories.splice(0)) {
179
+ fs.rmSync(directory, { force: true, recursive: true });
180
+ }
181
+ };
182
+ export { cleanupTemporaryDirectories, createTemporaryFile, createTemporaryPair, runRule, };
183
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWlyZS10ZXN0LWNvbXBhbmlvbi10ZXN0LWhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy9yZXF1aXJlLXRlc3QtY29tcGFuaW9uL3JlcXVpcmUtdGVzdC1jb21wYW5pb24tdGVzdC1oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDcEMsT0FBTyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ3pCLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUk3QixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFjbEQsK0RBQStEO0FBQy9ELE1BQU0sb0JBQW9CLEdBQWEsRUFBRSxDQUFDO0FBRTFDOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLElBQW1CLEVBQVUsRUFBRTtJQUMxRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNyRCxFQUFFLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ2pELE9BQU8sRUFBRSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7QUFDckUsQ0FBQyxDQUFDO0FBRUY7Ozs7Ozs7R0FPRztBQUNILE1BQU0sU0FBUyxHQUFHLENBQUMsUUFBZ0IsRUFBUSxFQUFFO0lBQzNDLEVBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLHlCQUF5QixFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ2hFLENBQUMsQ0FBQztBQUVGOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxJQUFtQixFQUFFLFFBQWdCLEVBQVUsRUFBRTtJQUM1RSxNQUFNLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1QyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDckMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDaEQsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3BCLE9BQU8sUUFBUSxDQUFDO0FBQ2xCLENBQUMsQ0FBQztBQUVGOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sb0JBQW9CLEdBQUcsQ0FDM0IsSUFBbUIsRUFDbkIsU0FBbUIsRUFDVCxFQUFFO0lBQ1osTUFBTSxTQUFTLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3JDLE9BQU8sU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFO1FBQ2hDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2hELFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNwQixPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQztBQUVGOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxtQkFBbUIsR0FBRyxDQUMxQixJQUFtQixFQUNuQixLQUFhLEVBQ2IsTUFBYyxFQUNJLEVBQUU7SUFDcEIsTUFBTSxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsR0FBRyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUU7UUFDekQsS0FBSztRQUNMLE1BQU07S0FDUCxDQUFxQixDQUFDO0lBRXZCLE9BQU8sQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDLENBQUM7QUFDakMsQ0FBQyxDQUFDO0FBRUY7Ozs7Ozs7R0FPRztBQUNILE1BQU0sZ0JBQWdCLEdBQUcsR0FBZ0IsRUFBRSxDQUFDLENBQUM7SUFDM0MsSUFBSSxFQUFFLEVBQUU7SUFDUixRQUFRLEVBQUUsRUFBRTtJQUNaLEdBQUcsRUFBRTtRQUNILEdBQUcsRUFBRSxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtRQUMzQixLQUFLLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUU7S0FDOUI7SUFDRCxLQUFLLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ2IsVUFBVSxFQUFFLFFBQVE7SUFDcEIsTUFBTSxFQUFFLEVBQUU7SUFDVixJQUFJLEVBQUUsU0FBUztDQUNoQixDQUFDLENBQUM7QUFFSDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxpQkFBaUIsR0FBRyxDQUN4QixRQUFnQixFQUNoQixPQUFxQixFQUNyQixVQUFzQixFQUNKLEVBQUUsQ0FDcEIsQ0FBQztJQUNDLEdBQUcsRUFBRSxPQUFPLENBQUMsR0FBRyxFQUFFO0lBQ2xCLFFBQVE7SUFDUixFQUFFLEVBQUUsd0JBQXdCO0lBQzVCLGVBQWUsRUFBRTtRQUNmLFdBQVcsRUFBRSxRQUFRO1FBQ3JCLFVBQVUsRUFBRSxRQUFRO0tBQ3JCO0lBQ0QsT0FBTyxFQUFFLEVBQUU7SUFDWCxhQUFhLEVBQUUsRUFBRTtJQUNqQixVQUFVLEVBQUUsS0FBSyxDQUFDO0lBQ2xCLGdCQUFnQixFQUFFLFFBQVE7SUFDMUIsTUFBTSxFQUFFLENBQUMsTUFBNkIsRUFBUSxFQUFFO1FBQzlDLE1BQU0sRUFBRSxTQUFTLEVBQUUsR0FBRyxNQUF1QyxDQUFDO1FBQzlELE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFDRCxRQUFRLEVBQUUsRUFBRTtJQUNaLFVBQVU7Q0FDWCxDQUFnQyxDQUFDO0FBRXBDOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFlBQVksR0FBRyxDQUFDLE9BQXlCLEVBQVEsRUFBRTtJQUN2RCxNQUFNLFNBQVMsR0FBRyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDM0QsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUM7SUFDM0MsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQztJQUUxQyxlQUFlLEVBQUUsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUNqQyxDQUFDLENBQUM7QUFFRjs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLE9BQU8sR0FBRyxDQUNkLFFBQWdCLEVBQ2hCLE9BQXFDLEVBQ3ZCLEVBQUU7SUFDaEIsTUFBTSxPQUFPLEdBQWlCLEVBQUUsQ0FBQztJQUNqQyxNQUFNLFVBQVUsR0FBRyxnQkFBZ0IsRUFBRSxDQUFDO0lBQ3RDLE1BQU0sVUFBVSxHQUFHLElBQUksVUFBVSxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNsRCxNQUFNLE9BQU8sR0FBRyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ2pFLE9BQU8sQ0FBQyxPQUFPLEdBQUcsT0FBTyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFdEQsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRXRCLE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUMsQ0FBQztBQUVGOzs7Ozs7R0FNRztBQUNILE1BQU0sMkJBQTJCLEdBQUcsR0FBUyxFQUFFO0lBQzdDLEtBQUssTUFBTSxTQUFTLElBQUksb0JBQW9CLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdkQsRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3pELENBQUM7QUFDSCxDQUFDLENBQUM7QUFFRixPQUFPLEVBQ0wsMkJBQTJCLEVBQzNCLG1CQUFtQixFQUNuQixtQkFBbUIsRUFDbkIsT0FBTyxHQUNSLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEFTVCwgUnVsZSB9IGZyb20gXCJlc2xpbnRcIjtcblxuaW1wb3J0IHsgU291cmNlQ29kZSB9IGZyb20gXCJlc2xpbnRcIjtcbmltcG9ydCBmcyBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuXG5pbXBvcnQgdHlwZSB7IFJlcXVpcmVUZXN0Q29tcGFuaW9uT3B0aW9ucyB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmltcG9ydCB7IHJlcXVpcmVUZXN0Q29tcGFuaW9uUnVsZSB9IGZyb20gXCIuL3J1bGVcIjtcblxuLyoqIFR5cGUgZGVmaW5pdGlvbiBmb3IgcnVsZSBkYXRhLiAqL1xuaW50ZXJmYWNlIFJlcG9ydERlc2NyaXB0b3JXaXRoTWVzc2FnZUlkIHtcbiAgLyoqIE1lc3NhZ2VJZCBmaWVsZCB2YWx1ZS4gKi9cbiAgbWVzc2FnZUlkPzogc3RyaW5nO1xufVxuXG4vKiogVHlwZSBkZWZpbml0aW9uIGZvciBydWxlIGRhdGEuICovXG5pbnRlcmZhY2UgUnVsZVJlcG9ydCB7XG4gIC8qKiBNZXNzYWdlSWQgaGVscGVyIHZhbHVlLiAqL1xuICBtZXNzYWdlSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqIFRyYWNrcyB0ZW1wb3JhcnkgZGlyZWN0b3JpZXMgc28gdGVzdHMgY2FuIGNsZWFuIHRoZW0gdXAuICovXG5jb25zdCB0ZW1wb3JhcnlEaXJlY3Rvcmllczogc3RyaW5nW10gPSBbXTtcblxuLyoqXG4gKiBDcmVhdGVzIGNyZWF0ZVJlcG9EaXJlY3RvcnkuXG4gKiBAcGFyYW0gcm9vdCBJbnB1dCByb290IHZhbHVlLlxuICogQHJldHVybnMgUmV0dXJuIHZhbHVlIG91dHB1dC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjcmVhdGVSZXBvRGlyZWN0b3J5KCk7XG4gKiBgYGBcbiAqL1xuY29uc3QgY3JlYXRlUmVwb0RpcmVjdG9yeSA9IChyb290OiBcInNyY1wiIHwgXCJ0bXBcIik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGJhc2VEaXJlY3RvcnkgPSBwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgcm9vdCk7XG4gIGZzLm1rZGlyU3luYyhiYXNlRGlyZWN0b3J5LCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgcmV0dXJuIGZzLm1rZHRlbXBTeW5jKHBhdGguam9pbihiYXNlRGlyZWN0b3J5LCBcInRlc3QtY29tcGFuaW9uLVwiKSk7XG59O1xuXG4vKipcbiAqIFdyaXRlcyBhIHNpbXBsZSBUeXBlU2NyaXB0IGZpbGUgYXQgdGhlIHByb3ZpZGVkIHBhdGguXG4gKiBAcGFyYW0gZmlsZVBhdGggSW5wdXQgZmlsZVBhdGggdmFsdWUuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogd3JpdGVGaWxlKFwiL3RtcC9mZWF0dXJlLnRzXCIpO1xuICogYGBgXG4gKi9cbmNvbnN0IHdyaXRlRmlsZSA9IChmaWxlUGF0aDogc3RyaW5nKTogdm9pZCA9PiB7XG4gIGZzLndyaXRlRmlsZVN5bmMoZmlsZVBhdGgsIFwiZXhwb3J0IGNvbnN0IHZhbHVlID0gMTtcIiwgXCJ1dGY4XCIpO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGNyZWF0ZVRlbXBvcmFyeUZpbGUuXG4gKiBAcGFyYW0gcm9vdCBJbnB1dCByb290IHZhbHVlLlxuICogQHBhcmFtIGZpbGVuYW1lIElucHV0IGZpbGVuYW1lIHZhbHVlLlxuICogQHJldHVybnMgUmV0dXJuIHZhbHVlIG91dHB1dC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjcmVhdGVUZW1wb3JhcnlGaWxlKCk7XG4gKiBgYGBcbiAqL1xuY29uc3QgY3JlYXRlVGVtcG9yYXJ5RmlsZSA9IChyb290OiBcInNyY1wiIHwgXCJ0bXBcIiwgZmlsZW5hbWU6IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGRpcmVjdG9yeSA9IGNyZWF0ZVJlcG9EaXJlY3Rvcnkocm9vdCk7XG4gIHRlbXBvcmFyeURpcmVjdG9yaWVzLnB1c2goZGlyZWN0b3J5KTtcbiAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oZGlyZWN0b3J5LCBmaWxlbmFtZSk7XG4gIHdyaXRlRmlsZShmaWxlUGF0aCk7XG4gIHJldHVybiBmaWxlUGF0aDtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBtdWx0aXBsZSB0ZW1wb3JhcnkgZmlsZXMgdW5kZXIgdGhlIGdpdmVuIHJvb3QuXG4gKiBAcGFyYW0gcm9vdCBJbnB1dCByb290IHZhbHVlLlxuICogQHBhcmFtIGZpbGVuYW1lcyBJbnB1dCBmaWxlbmFtZXMgdmFsdWUuXG4gKiBAcmV0dXJucyBQYXRocyB0byB0aGUgY3JlYXRlZCBmaWxlcy5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBwYXRocyA9IGNyZWF0ZVRlbXBvcmFyeUZpbGVzKFwidG1wXCIsIFtcImEudHNcIiwgXCJiLnRzXCJdKTtcbiAqIGBgYFxuICovXG5jb25zdCBjcmVhdGVUZW1wb3JhcnlGaWxlcyA9IChcbiAgcm9vdDogXCJzcmNcIiB8IFwidG1wXCIsXG4gIGZpbGVuYW1lczogc3RyaW5nW10sXG4pOiBzdHJpbmdbXSA9PiB7XG4gIGNvbnN0IGRpcmVjdG9yeSA9IGNyZWF0ZVJlcG9EaXJlY3Rvcnkocm9vdCk7XG4gIHRlbXBvcmFyeURpcmVjdG9yaWVzLnB1c2goZGlyZWN0b3J5KTtcbiAgcmV0dXJuIGZpbGVuYW1lcy5tYXAoKGZpbGVuYW1lKSA9PiB7XG4gICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oZGlyZWN0b3J5LCBmaWxlbmFtZSk7XG4gICAgd3JpdGVGaWxlKGZpbGVQYXRoKTtcbiAgICByZXR1cm4gZmlsZVBhdGg7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgdGVtcG9yYXJ5IGZpbGUgcGFpciBmb3IgdGVzdC9zb3VyY2UgY29tYmluYXRpb25zLlxuICogQHBhcmFtIHJvb3QgSW5wdXQgcm9vdCB2YWx1ZS5cbiAqIEBwYXJhbSBmaXJzdCBJbnB1dCBmaXJzdCB2YWx1ZS5cbiAqIEBwYXJhbSBzZWNvbmQgSW5wdXQgc2Vjb25kIHZhbHVlLlxuICogQHJldHVybnMgVHVwbGUgb2YgY3JlYXRlZCBmaWxlIHBhdGhzLlxuICogQHRocm93cyB7RXJyb3J9IFdoZW4gdGhlIGZpbGUgcGF0aHMgYXJlIG1pc3NpbmcuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgW3NvdXJjZSwgdGVzdF0gPSBjcmVhdGVUZW1wb3JhcnlQYWlyKFwidG1wXCIsIFwiYS50c1wiLCBcImEuc3BlYy50c1wiKTtcbiAqIGBgYFxuICovXG5jb25zdCBjcmVhdGVUZW1wb3JhcnlQYWlyID0gKFxuICByb290OiBcInNyY1wiIHwgXCJ0bXBcIixcbiAgZmlyc3Q6IHN0cmluZyxcbiAgc2Vjb25kOiBzdHJpbmcsXG4pOiBbc3RyaW5nLCBzdHJpbmddID0+IHtcbiAgY29uc3QgW2ZpcnN0UGF0aCwgc2Vjb25kUGF0aF0gPSBjcmVhdGVUZW1wb3JhcnlGaWxlcyhyb290LCBbXG4gICAgZmlyc3QsXG4gICAgc2Vjb25kLFxuICBdKSBhcyBbc3RyaW5nLCBzdHJpbmddO1xuXG4gIHJldHVybiBbZmlyc3RQYXRoLCBzZWNvbmRQYXRoXTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBjcmVhdGVQcm9ncmFtQXN0LlxuICogQHJldHVybnMgUmV0dXJuIHZhbHVlIG91dHB1dC5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjcmVhdGVQcm9ncmFtQXN0KCk7XG4gKiBgYGBcbiAqL1xuY29uc3QgY3JlYXRlUHJvZ3JhbUFzdCA9ICgpOiBBU1QuUHJvZ3JhbSA9PiAoe1xuICBib2R5OiBbXSxcbiAgY29tbWVudHM6IFtdLFxuICBsb2M6IHtcbiAgICBlbmQ6IHsgY29sdW1uOiAwLCBsaW5lOiAxIH0sXG4gICAgc3RhcnQ6IHsgY29sdW1uOiAwLCBsaW5lOiAxIH0sXG4gIH0sXG4gIHJhbmdlOiBbMCwgMF0sXG4gIHNvdXJjZVR5cGU6IFwibW9kdWxlXCIsXG4gIHRva2VuczogW10sXG4gIHR5cGU6IFwiUHJvZ3JhbVwiLFxufSk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHJ1bGUgY29udGV4dCBmb3IgdGhlIGdpdmVuIGZpbGVuYW1lLlxuICogQHBhcmFtIGZpbGVuYW1lIElucHV0IGZpbGVuYW1lIHZhbHVlLlxuICogQHBhcmFtIHJlcG9ydHMgSW5wdXQgcmVwb3J0cyB2YWx1ZS5cbiAqIEBwYXJhbSBzb3VyY2VDb2RlIElucHV0IHNvdXJjZUNvZGUgdmFsdWUuXG4gKiBAcmV0dXJucyBSdWxlIGNvbnRleHQgZm9yIHRlc3RzLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGNvbnRleHQgPSBjcmVhdGVSdWxlQ29udGV4dChmaWxlLCByZXBvcnRzLCBzb3VyY2VDb2RlKTtcbiAqIGBgYFxuICovXG5jb25zdCBjcmVhdGVSdWxlQ29udGV4dCA9IChcbiAgZmlsZW5hbWU6IHN0cmluZyxcbiAgcmVwb3J0czogUnVsZVJlcG9ydFtdLFxuICBzb3VyY2VDb2RlOiBTb3VyY2VDb2RlLFxuKTogUnVsZS5SdWxlQ29udGV4dCA9PlxuICAoe1xuICAgIGN3ZDogcHJvY2Vzcy5jd2QoKSxcbiAgICBmaWxlbmFtZSxcbiAgICBpZDogXCJyZXF1aXJlLXRlc3QtY29tcGFuaW9uXCIsXG4gICAgbGFuZ3VhZ2VPcHRpb25zOiB7XG4gICAgICBlY21hVmVyc2lvbjogXCJsYXRlc3RcIixcbiAgICAgIHNvdXJjZVR5cGU6IFwibW9kdWxlXCIsXG4gICAgfSxcbiAgICBvcHRpb25zOiBbXSxcbiAgICBwYXJzZXJPcHRpb25zOiB7fSxcbiAgICBwYXJzZXJQYXRoOiB2b2lkIDAsXG4gICAgcGh5c2ljYWxGaWxlbmFtZTogZmlsZW5hbWUsXG4gICAgcmVwb3J0OiAocmVwb3J0OiBSdWxlLlJlcG9ydERlc2NyaXB0b3IpOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IHsgbWVzc2FnZUlkIH0gPSByZXBvcnQgYXMgUmVwb3J0RGVzY3JpcHRvcldpdGhNZXNzYWdlSWQ7XG4gICAgICByZXBvcnRzLnB1c2goeyBtZXNzYWdlSWQgfSk7XG4gICAgfSxcbiAgICBzZXR0aW5nczoge30sXG4gICAgc291cmNlQ29kZSxcbiAgfSkgYXMgdW5rbm93biBhcyBSdWxlLlJ1bGVDb250ZXh0O1xuXG4vKipcbiAqIFJ1bnMgdGhlIHJ1bGUgbGlzdGVuZXJzIGZvciBhIGNvbnRleHQuXG4gKiBAcGFyYW0gY29udGV4dCBJbnB1dCBjb250ZXh0IHZhbHVlLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHJ1bkxpc3RlbmVycyhjb250ZXh0KTtcbiAqIGBgYFxuICovXG5jb25zdCBydW5MaXN0ZW5lcnMgPSAoY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCk6IHZvaWQgPT4ge1xuICBjb25zdCBsaXN0ZW5lcnMgPSByZXF1aXJlVGVzdENvbXBhbmlvblJ1bGUuY3JlYXRlKGNvbnRleHQpO1xuICBjb25zdCBwcm9ncmFtTm9kZSA9IGNvbnRleHQuc291cmNlQ29kZS5hc3Q7XG4gIGNvbnN0IHByb2dyYW1MaXN0ZW5lciA9IGxpc3RlbmVycy5Qcm9ncmFtO1xuXG4gIHByb2dyYW1MaXN0ZW5lcj8uKHByb2dyYW1Ob2RlKTtcbn07XG5cbi8qKlxuICogUnVucyB0aGUgcnVsZSB3aXRoIHRoZSBnaXZlbiBvcHRpb25zLlxuICogQHBhcmFtIGZpbGVuYW1lIElucHV0IGZpbGVuYW1lIHZhbHVlLlxuICogQHBhcmFtIG9wdGlvbnMgSW5wdXQgb3B0aW9ucyB2YWx1ZS5cbiAqIEByZXR1cm5zIENvbGxlY3RlZCBydWxlIHJlcG9ydHMuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmVwb3J0cyA9IHJ1blJ1bGUoXCIvdG1wL2ZlYXR1cmUudHNcIik7XG4gKiBgYGBcbiAqL1xuY29uc3QgcnVuUnVsZSA9IChcbiAgZmlsZW5hbWU6IHN0cmluZyxcbiAgb3B0aW9ucz86IFJlcXVpcmVUZXN0Q29tcGFuaW9uT3B0aW9ucyxcbik6IFJ1bGVSZXBvcnRbXSA9PiB7XG4gIGNvbnN0IHJlcG9ydHM6IFJ1bGVSZXBvcnRbXSA9IFtdO1xuICBjb25zdCBwcm9ncmFtQXN0ID0gY3JlYXRlUHJvZ3JhbUFzdCgpO1xuICBjb25zdCBzb3VyY2VDb2RlID0gbmV3IFNvdXJjZUNvZGUoXCJcIiwgcHJvZ3JhbUFzdCk7XG4gIGNvbnN0IGNvbnRleHQgPSBjcmVhdGVSdWxlQ29udGV4dChmaWxlbmFtZSwgcmVwb3J0cywgc291cmNlQ29kZSk7XG4gIGNvbnRleHQub3B0aW9ucyA9IG9wdGlvbnMgPT09IHZvaWQgMCA/IFtdIDogW29wdGlvbnNdO1xuXG4gIHJ1bkxpc3RlbmVycyhjb250ZXh0KTtcblxuICByZXR1cm4gcmVwb3J0cztcbn07XG5cbi8qKlxuICogQ2xlYW5zIHVwIHRlbXBvcmFyeSBkaXJlY3RvcmllcyBjcmVhdGVkIGJ5IHRlc3RzLlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNsZWFudXBUZW1wb3JhcnlEaXJlY3RvcmllcygpO1xuICogYGBgXG4gKi9cbmNvbnN0IGNsZWFudXBUZW1wb3JhcnlEaXJlY3RvcmllcyA9ICgpOiB2b2lkID0+IHtcbiAgZm9yIChjb25zdCBkaXJlY3Rvcnkgb2YgdGVtcG9yYXJ5RGlyZWN0b3JpZXMuc3BsaWNlKDApKSB7XG4gICAgZnMucm1TeW5jKGRpcmVjdG9yeSwgeyBmb3JjZTogdHJ1ZSwgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICB9XG59O1xuXG5leHBvcnQge1xuICBjbGVhbnVwVGVtcG9yYXJ5RGlyZWN0b3JpZXMsXG4gIGNyZWF0ZVRlbXBvcmFyeUZpbGUsXG4gIGNyZWF0ZVRlbXBvcmFyeVBhaXIsXG4gIHJ1blJ1bGUsXG59O1xuIl19
@@ -0,0 +1,28 @@
1
+ import type { Rule } from "eslint";
2
+ import { getOptions as getOptionsImpl } from "./require-test-companion-options";
3
+ /** Normalized options state type. */
4
+ type RequireTestCompanionState = ReturnType<typeof getOptionsImpl>;
5
+ /**
6
+ * Build a rule listener for a source filename.
7
+ * @param context Rule execution context.
8
+ * @param filename Source file path.
9
+ * @param options Normalized rule options state.
10
+ * @returns Rule listener for the file.
11
+ * @example
12
+ * ```typescript
13
+ * const listener = buildListenerForFilename(context, filename, options);
14
+ * ```
15
+ */
16
+ declare const buildListenerForFilename: (context: Rule.RuleContext, filename: string, options: RequireTestCompanionState) => Rule.RuleListener;
17
+ /**
18
+ * Normalize rule options for the listener.
19
+ * @param options Raw rule options.
20
+ * @returns Normalized rule options state.
21
+ * @example
22
+ * ```typescript
23
+ * const options = getOptions([]);
24
+ * ```
25
+ */
26
+ declare const getOptions: (options: readonly unknown[]) => RequireTestCompanionState;
27
+ export { buildListenerForFilename, getOptions };
28
+ //# sourceMappingURL=require-test-companion-utilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-test-companion-utilities.d.ts","sourceRoot":"","sources":["../../../src/testing/require-test-companion/require-test-companion-utilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAGnC,OAAO,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAEhF,qCAAqC;AACrC,KAAK,yBAAyB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAEnE;;;;;;;;;;GAUG;AACH,QAAA,MAAM,wBAAwB,GAC5B,SAAS,IAAI,CAAC,WAAW,EACzB,UAAU,MAAM,EAChB,SAAS,yBAAyB,KACjC,IAAI,CAAC,YACkD,CAAC;AAE3D;;;;;;;;GAQG;AACH,QAAA,MAAM,UAAU,GAAI,SAAS,SAAS,OAAO,EAAE,KAAG,yBACzB,CAAC;AAE1B,OAAO,EAAE,wBAAwB,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { buildListenerForFilename as buildListenerForFilenameImpl } from "./require-test-companion-listeners";
2
+ import { getOptions as getOptionsImpl } from "./require-test-companion-options";
3
+ /**
4
+ * Build a rule listener for a source filename.
5
+ * @param context Rule execution context.
6
+ * @param filename Source file path.
7
+ * @param options Normalized rule options state.
8
+ * @returns Rule listener for the file.
9
+ * @example
10
+ * ```typescript
11
+ * const listener = buildListenerForFilename(context, filename, options);
12
+ * ```
13
+ */
14
+ const buildListenerForFilename = (context, filename, options) => buildListenerForFilenameImpl(context, filename, options);
15
+ /**
16
+ * Normalize rule options for the listener.
17
+ * @param options Raw rule options.
18
+ * @returns Normalized rule options state.
19
+ * @example
20
+ * ```typescript
21
+ * const options = getOptions([]);
22
+ * ```
23
+ */
24
+ const getOptions = (options) => getOptionsImpl(options);
25
+ export { buildListenerForFilename, getOptions };
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWlyZS10ZXN0LWNvbXBhbmlvbi11dGlsaXRpZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy9yZXF1aXJlLXRlc3QtY29tcGFuaW9uL3JlcXVpcmUtdGVzdC1jb21wYW5pb24tdXRpbGl0aWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSx3QkFBd0IsSUFBSSw0QkFBNEIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQzlHLE9BQU8sRUFBRSxVQUFVLElBQUksY0FBYyxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFLaEY7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sd0JBQXdCLEdBQUcsQ0FDL0IsT0FBeUIsRUFDekIsUUFBZ0IsRUFDaEIsT0FBa0MsRUFDZixFQUFFLENBQ3JCLDRCQUE0QixDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFFM0Q7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsR0FBRyxDQUFDLE9BQTJCLEVBQTZCLEVBQUUsQ0FDNUUsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBRTFCLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxVQUFVLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgUnVsZSB9IGZyb20gXCJlc2xpbnRcIjtcblxuaW1wb3J0IHsgYnVpbGRMaXN0ZW5lckZvckZpbGVuYW1lIGFzIGJ1aWxkTGlzdGVuZXJGb3JGaWxlbmFtZUltcGwgfSBmcm9tIFwiLi9yZXF1aXJlLXRlc3QtY29tcGFuaW9uLWxpc3RlbmVyc1wiO1xuaW1wb3J0IHsgZ2V0T3B0aW9ucyBhcyBnZXRPcHRpb25zSW1wbCB9IGZyb20gXCIuL3JlcXVpcmUtdGVzdC1jb21wYW5pb24tb3B0aW9uc1wiO1xuXG4vKiogTm9ybWFsaXplZCBvcHRpb25zIHN0YXRlIHR5cGUuICovXG50eXBlIFJlcXVpcmVUZXN0Q29tcGFuaW9uU3RhdGUgPSBSZXR1cm5UeXBlPHR5cGVvZiBnZXRPcHRpb25zSW1wbD47XG5cbi8qKlxuICogQnVpbGQgYSBydWxlIGxpc3RlbmVyIGZvciBhIHNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSBjb250ZXh0IFJ1bGUgZXhlY3V0aW9uIGNvbnRleHQuXG4gKiBAcGFyYW0gZmlsZW5hbWUgU291cmNlIGZpbGUgcGF0aC5cbiAqIEBwYXJhbSBvcHRpb25zIE5vcm1hbGl6ZWQgcnVsZSBvcHRpb25zIHN0YXRlLlxuICogQHJldHVybnMgUnVsZSBsaXN0ZW5lciBmb3IgdGhlIGZpbGUuXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgbGlzdGVuZXIgPSBidWlsZExpc3RlbmVyRm9yRmlsZW5hbWUoY29udGV4dCwgZmlsZW5hbWUsIG9wdGlvbnMpO1xuICogYGBgXG4gKi9cbmNvbnN0IGJ1aWxkTGlzdGVuZXJGb3JGaWxlbmFtZSA9IChcbiAgY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCxcbiAgZmlsZW5hbWU6IHN0cmluZyxcbiAgb3B0aW9uczogUmVxdWlyZVRlc3RDb21wYW5pb25TdGF0ZSxcbik6IFJ1bGUuUnVsZUxpc3RlbmVyID0+XG4gIGJ1aWxkTGlzdGVuZXJGb3JGaWxlbmFtZUltcGwoY29udGV4dCwgZmlsZW5hbWUsIG9wdGlvbnMpO1xuXG4vKipcbiAqIE5vcm1hbGl6ZSBydWxlIG9wdGlvbnMgZm9yIHRoZSBsaXN0ZW5lci5cbiAqIEBwYXJhbSBvcHRpb25zIFJhdyBydWxlIG9wdGlvbnMuXG4gKiBAcmV0dXJucyBOb3JtYWxpemVkIHJ1bGUgb3B0aW9ucyBzdGF0ZS5cbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBvcHRpb25zID0gZ2V0T3B0aW9ucyhbXSk7XG4gKiBgYGBcbiAqL1xuY29uc3QgZ2V0T3B0aW9ucyA9IChvcHRpb25zOiByZWFkb25seSB1bmtub3duW10pOiBSZXF1aXJlVGVzdENvbXBhbmlvblN0YXRlID0+XG4gIGdldE9wdGlvbnNJbXBsKG9wdGlvbnMpO1xuXG5leHBvcnQgeyBidWlsZExpc3RlbmVyRm9yRmlsZW5hbWUsIGdldE9wdGlvbnMgfTtcbiJdfQ==
@@ -0,0 +1,5 @@
1
+ import type { Rule } from "eslint";
2
+ /** ESLint rule enforcing 1:1 test companions for TypeScript files. */
3
+ declare const requireTestCompanionRule: Rule.RuleModule;
4
+ export { requireTestCompanionRule };
5
+ //# sourceMappingURL=rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../../src/testing/require-test-companion/rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAMnC,sEAAsE;AACtE,QAAA,MAAM,wBAAwB,EAAE,IAAI,CAAC,UA2DpC,CAAC;AAEF,OAAO,EAAE,wBAAwB,EAAE,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { createRuleDocumentation } from "../../custom-rule-documentation";
2
+ import { buildListenerForFilename } from "./require-test-companion-listeners";
3
+ import { getOptions } from "./require-test-companion-options";
4
+ /** ESLint rule enforcing 1:1 test companions for TypeScript files. */
5
+ const requireTestCompanionRule = {
6
+ create(context) {
7
+ return buildListenerForFilename(context, context.filename, getOptions(context.options));
8
+ },
9
+ meta: {
10
+ docs: createRuleDocumentation("require-test-companion", "Require a matching test file for each TypeScript file and vice versa."),
11
+ messages: {
12
+ missingSource: "Test file requires a matching source file '{{sourceFile}}' in the same folder.",
13
+ missingTest: "Source file requires a matching test file ({{testFiles}}) in the same folder.",
14
+ },
15
+ schema: [
16
+ {
17
+ additionalProperties: false,
18
+ properties: {
19
+ enforceIn: {
20
+ oneOf: [
21
+ { type: "string" },
22
+ {
23
+ items: { type: "string" },
24
+ minItems: 1,
25
+ type: "array",
26
+ },
27
+ ],
28
+ },
29
+ ignorePatterns: {
30
+ oneOf: [
31
+ { type: "string" },
32
+ {
33
+ items: { type: "string" },
34
+ minItems: 1,
35
+ type: "array",
36
+ },
37
+ ],
38
+ },
39
+ testSuffixes: {
40
+ oneOf: [
41
+ { type: "string" },
42
+ {
43
+ items: { type: "string" },
44
+ minItems: 1,
45
+ type: "array",
46
+ },
47
+ ],
48
+ },
49
+ },
50
+ type: "object",
51
+ },
52
+ ],
53
+ type: "problem",
54
+ },
55
+ };
56
+ export { requireTestCompanionRule };
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0aW5nL3JlcXVpcmUtdGVzdC1jb21wYW5pb24vcnVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUM5RSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFOUQsc0VBQXNFO0FBQ3RFLE1BQU0sd0JBQXdCLEdBQW9CO0lBQ2hELE1BQU0sQ0FBQyxPQUF5QjtRQUM5QixPQUFPLHdCQUF3QixDQUM3QixPQUFPLEVBQ1AsT0FBTyxDQUFDLFFBQVEsRUFDaEIsVUFBVSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FDNUIsQ0FBQztJQUNKLENBQUM7SUFDRCxJQUFJLEVBQUU7UUFDSixJQUFJLEVBQUUsdUJBQXVCLENBQzNCLHdCQUF3QixFQUN4Qix1RUFBdUUsQ0FDeEU7UUFDRCxRQUFRLEVBQUU7WUFDUixhQUFhLEVBQ1gsZ0ZBQWdGO1lBQ2xGLFdBQVcsRUFDVCwrRUFBK0U7U0FDbEY7UUFDRCxNQUFNLEVBQUU7WUFDTjtnQkFDRSxvQkFBb0IsRUFBRSxLQUFLO2dCQUMzQixVQUFVLEVBQUU7b0JBQ1YsU0FBUyxFQUFFO3dCQUNULEtBQUssRUFBRTs0QkFDTCxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7NEJBQ2xCO2dDQUNFLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7Z0NBQ3pCLFFBQVEsRUFBRSxDQUFDO2dDQUNYLElBQUksRUFBRSxPQUFPOzZCQUNkO3lCQUNGO3FCQUNGO29CQUNELGNBQWMsRUFBRTt3QkFDZCxLQUFLLEVBQUU7NEJBQ0wsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFOzRCQUNsQjtnQ0FDRSxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO2dDQUN6QixRQUFRLEVBQUUsQ0FBQztnQ0FDWCxJQUFJLEVBQUUsT0FBTzs2QkFDZDt5QkFDRjtxQkFDRjtvQkFDRCxZQUFZLEVBQUU7d0JBQ1osS0FBSyxFQUFFOzRCQUNMLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTs0QkFDbEI7Z0NBQ0UsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtnQ0FDekIsUUFBUSxFQUFFLENBQUM7Z0NBQ1gsSUFBSSxFQUFFLE9BQU87NkJBQ2Q7eUJBQ0Y7cUJBQ0Y7aUJBQ0Y7Z0JBQ0QsSUFBSSxFQUFFLFFBQVE7YUFDZjtTQUNGO1FBQ0QsSUFBSSxFQUFFLFNBQVM7S0FDaEI7Q0FDRixDQUFDO0FBRUYsT0FBTyxFQUFFLHdCQUF3QixFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFJ1bGUgfSBmcm9tIFwiZXNsaW50XCI7XG5cbmltcG9ydCB7IGNyZWF0ZVJ1bGVEb2N1bWVudGF0aW9uIH0gZnJvbSBcIi4uLy4uL2N1c3RvbS1ydWxlLWRvY3VtZW50YXRpb25cIjtcbmltcG9ydCB7IGJ1aWxkTGlzdGVuZXJGb3JGaWxlbmFtZSB9IGZyb20gXCIuL3JlcXVpcmUtdGVzdC1jb21wYW5pb24tbGlzdGVuZXJzXCI7XG5pbXBvcnQgeyBnZXRPcHRpb25zIH0gZnJvbSBcIi4vcmVxdWlyZS10ZXN0LWNvbXBhbmlvbi1vcHRpb25zXCI7XG5cbi8qKiBFU0xpbnQgcnVsZSBlbmZvcmNpbmcgMToxIHRlc3QgY29tcGFuaW9ucyBmb3IgVHlwZVNjcmlwdCBmaWxlcy4gKi9cbmNvbnN0IHJlcXVpcmVUZXN0Q29tcGFuaW9uUnVsZTogUnVsZS5SdWxlTW9kdWxlID0ge1xuICBjcmVhdGUoY29udGV4dDogUnVsZS5SdWxlQ29udGV4dCk6IFJ1bGUuUnVsZUxpc3RlbmVyIHtcbiAgICByZXR1cm4gYnVpbGRMaXN0ZW5lckZvckZpbGVuYW1lKFxuICAgICAgY29udGV4dCxcbiAgICAgIGNvbnRleHQuZmlsZW5hbWUsXG4gICAgICBnZXRPcHRpb25zKGNvbnRleHQub3B0aW9ucyksXG4gICAgKTtcbiAgfSxcbiAgbWV0YToge1xuICAgIGRvY3M6IGNyZWF0ZVJ1bGVEb2N1bWVudGF0aW9uKFxuICAgICAgXCJyZXF1aXJlLXRlc3QtY29tcGFuaW9uXCIsXG4gICAgICBcIlJlcXVpcmUgYSBtYXRjaGluZyB0ZXN0IGZpbGUgZm9yIGVhY2ggVHlwZVNjcmlwdCBmaWxlIGFuZCB2aWNlIHZlcnNhLlwiLFxuICAgICksXG4gICAgbWVzc2FnZXM6IHtcbiAgICAgIG1pc3NpbmdTb3VyY2U6XG4gICAgICAgIFwiVGVzdCBmaWxlIHJlcXVpcmVzIGEgbWF0Y2hpbmcgc291cmNlIGZpbGUgJ3t7c291cmNlRmlsZX19JyBpbiB0aGUgc2FtZSBmb2xkZXIuXCIsXG4gICAgICBtaXNzaW5nVGVzdDpcbiAgICAgICAgXCJTb3VyY2UgZmlsZSByZXF1aXJlcyBhIG1hdGNoaW5nIHRlc3QgZmlsZSAoe3t0ZXN0RmlsZXN9fSkgaW4gdGhlIHNhbWUgZm9sZGVyLlwiLFxuICAgIH0sXG4gICAgc2NoZW1hOiBbXG4gICAgICB7XG4gICAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIGVuZm9yY2VJbjoge1xuICAgICAgICAgICAgb25lT2Y6IFtcbiAgICAgICAgICAgICAgeyB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBpdGVtczogeyB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgICAgICAgICAgICAgbWluSXRlbXM6IDEsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJhcnJheVwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGlnbm9yZVBhdHRlcm5zOiB7XG4gICAgICAgICAgICBvbmVPZjogW1xuICAgICAgICAgICAgICB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGl0ZW1zOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICAgICAgICBtaW5JdGVtczogMSxcbiAgICAgICAgICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGVzdFN1ZmZpeGVzOiB7XG4gICAgICAgICAgICBvbmVPZjogW1xuICAgICAgICAgICAgICB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGl0ZW1zOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICAgICAgICBtaW5JdGVtczogMSxcbiAgICAgICAgICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICB9LFxuICAgIF0sXG4gICAgdHlwZTogXCJwcm9ibGVtXCIsXG4gIH0sXG59O1xuXG5leHBvcnQgeyByZXF1aXJlVGVzdENvbXBhbmlvblJ1bGUgfTtcbiJdfQ==
@@ -0,0 +1,11 @@
1
+ /** Type definition for rule data. */
2
+ interface RequireTestCompanionOptions {
3
+ /** EnforceIn helper value. */
4
+ enforceIn?: string | string[];
5
+ /** IgnorePatterns helper value. */
6
+ ignorePatterns?: string | string[];
7
+ /** TestSuffixes helper value. */
8
+ testSuffixes?: string | string[];
9
+ }
10
+ export type { RequireTestCompanionOptions };
11
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/testing/require-test-companion/types.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,UAAU,2BAA2B;IACnC,8BAA8B;IAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE9B,mCAAmC;IACnC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAEnC,iCAAiC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAClC;AAED,YAAY,EAAE,2BAA2B,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy9yZXF1aXJlLXRlc3QtY29tcGFuaW9uL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIvKiogVHlwZSBkZWZpbml0aW9uIGZvciBydWxlIGRhdGEuICovXG5pbnRlcmZhY2UgUmVxdWlyZVRlc3RDb21wYW5pb25PcHRpb25zIHtcbiAgLyoqIEVuZm9yY2VJbiBoZWxwZXIgdmFsdWUuICovXG4gIGVuZm9yY2VJbj86IHN0cmluZyB8IHN0cmluZ1tdO1xuXG4gIC8qKiBJZ25vcmVQYXR0ZXJucyBoZWxwZXIgdmFsdWUuICovXG4gIGlnbm9yZVBhdHRlcm5zPzogc3RyaW5nIHwgc3RyaW5nW107XG5cbiAgLyoqIFRlc3RTdWZmaXhlcyBoZWxwZXIgdmFsdWUuICovXG4gIHRlc3RTdWZmaXhlcz86IHN0cmluZyB8IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgdHlwZSB7IFJlcXVpcmVUZXN0Q29tcGFuaW9uT3B0aW9ucyB9O1xuIl19
@@ -0,0 +1,2 @@
1
+ export { singleActStatementRule } from "./rule";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testing/single-act-statement/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { singleActStatementRule } from "./rule";
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy9zaW5nbGUtYWN0LXN0YXRlbWVudC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBzaW5nbGVBY3RTdGF0ZW1lbnRSdWxlIH0gZnJvbSBcIi4vcnVsZVwiO1xuIl19
@@ -0,0 +1,4 @@
1
+ import type { Rule } from "eslint";
2
+ declare const singleActStatementRule: Rule.RuleModule;
3
+ export { singleActStatementRule };
4
+ //# sourceMappingURL=rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../../src/testing/single-act-statement/rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAKnC,QAAA,MAAM,sBAAsB,EAAE,IAAI,CAAC,UAkClC,CAAC;AAEF,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { createRuleDocumentation } from "../../custom-rule-documentation";
2
+ import { analyzeTestBlock, countActStatements } from "../aaa";
3
+ const singleActStatementRule = {
4
+ create(context) {
5
+ return {
6
+ CallExpression(node) {
7
+ const analysis = analyzeTestBlock(context, node);
8
+ if (analysis === void 0) {
9
+ return;
10
+ }
11
+ const actStatementCount = countActStatements(analysis);
12
+ if (actStatementCount <= 1) {
13
+ return;
14
+ }
15
+ context.report({
16
+ data: { count: String(actStatementCount) },
17
+ messageId: "multipleActStatements",
18
+ node: analysis.callExpression,
19
+ });
20
+ },
21
+ };
22
+ },
23
+ meta: {
24
+ docs: createRuleDocumentation("single-act-statement", "Require the // Act section to contain a single top-level statement or declaration."),
25
+ messages: {
26
+ multipleActStatements: "Reduce the // Act section to a single top-level statement or variable declaration; found {{count}}.",
27
+ },
28
+ schema: [],
29
+ type: "suggestion",
30
+ },
31
+ };
32
+ export { singleActStatementRule };
33
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZXN0aW5nL3NpbmdsZS1hY3Qtc3RhdGVtZW50L3J1bGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDMUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRTlELE1BQU0sc0JBQXNCLEdBQW9CO0lBQzlDLE1BQU0sQ0FBQyxPQUF5QjtRQUM5QixPQUFPO1lBQ0wsY0FBYyxDQUFDLElBQUk7Z0JBQ2pCLE1BQU0sUUFBUSxHQUFHLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDakQsSUFBSSxRQUFRLEtBQUssS0FBSyxDQUFDLEVBQUUsQ0FBQztvQkFDeEIsT0FBTztnQkFDVCxDQUFDO2dCQUVELE1BQU0saUJBQWlCLEdBQUcsa0JBQWtCLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3ZELElBQUksaUJBQWlCLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQzNCLE9BQU87Z0JBQ1QsQ0FBQztnQkFFRCxPQUFPLENBQUMsTUFBTSxDQUFDO29CQUNiLElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsaUJBQWlCLENBQUMsRUFBRTtvQkFDMUMsU0FBUyxFQUFFLHVCQUF1QjtvQkFDbEMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxjQUFjO2lCQUM5QixDQUFDLENBQUM7WUFDTCxDQUFDO1NBQzBCLENBQUM7SUFDaEMsQ0FBQztJQUNELElBQUksRUFBRTtRQUNKLElBQUksRUFBRSx1QkFBdUIsQ0FDM0Isc0JBQXNCLEVBQ3RCLG9GQUFvRixDQUNyRjtRQUNELFFBQVEsRUFBRTtZQUNSLHFCQUFxQixFQUNuQixxR0FBcUc7U0FDeEc7UUFDRCxNQUFNLEVBQUUsRUFBRTtRQUNWLElBQUksRUFBRSxZQUFZO0tBQ25CO0NBQ0YsQ0FBQztBQUVGLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBSdWxlIH0gZnJvbSBcImVzbGludFwiO1xuXG5pbXBvcnQgeyBjcmVhdGVSdWxlRG9jdW1lbnRhdGlvbiB9IGZyb20gXCIuLi8uLi9jdXN0b20tcnVsZS1kb2N1bWVudGF0aW9uXCI7XG5pbXBvcnQgeyBhbmFseXplVGVzdEJsb2NrLCBjb3VudEFjdFN0YXRlbWVudHMgfSBmcm9tIFwiLi4vYWFhXCI7XG5cbmNvbnN0IHNpbmdsZUFjdFN0YXRlbWVudFJ1bGU6IFJ1bGUuUnVsZU1vZHVsZSA9IHtcbiAgY3JlYXRlKGNvbnRleHQ6IFJ1bGUuUnVsZUNvbnRleHQpOiBSdWxlLlJ1bGVMaXN0ZW5lciB7XG4gICAgcmV0dXJuIHtcbiAgICAgIENhbGxFeHByZXNzaW9uKG5vZGUpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgYW5hbHlzaXMgPSBhbmFseXplVGVzdEJsb2NrKGNvbnRleHQsIG5vZGUpO1xuICAgICAgICBpZiAoYW5hbHlzaXMgPT09IHZvaWQgMCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFjdFN0YXRlbWVudENvdW50ID0gY291bnRBY3RTdGF0ZW1lbnRzKGFuYWx5c2lzKTtcbiAgICAgICAgaWYgKGFjdFN0YXRlbWVudENvdW50IDw9IDEpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICAgICAgZGF0YTogeyBjb3VudDogU3RyaW5nKGFjdFN0YXRlbWVudENvdW50KSB9LFxuICAgICAgICAgIG1lc3NhZ2VJZDogXCJtdWx0aXBsZUFjdFN0YXRlbWVudHNcIixcbiAgICAgICAgICBub2RlOiBhbmFseXNpcy5jYWxsRXhwcmVzc2lvbixcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgIH0gc2F0aXNmaWVzIFJ1bGUuUnVsZUxpc3RlbmVyO1xuICB9LFxuICBtZXRhOiB7XG4gICAgZG9jczogY3JlYXRlUnVsZURvY3VtZW50YXRpb24oXG4gICAgICBcInNpbmdsZS1hY3Qtc3RhdGVtZW50XCIsXG4gICAgICBcIlJlcXVpcmUgdGhlIC8vIEFjdCBzZWN0aW9uIHRvIGNvbnRhaW4gYSBzaW5nbGUgdG9wLWxldmVsIHN0YXRlbWVudCBvciBkZWNsYXJhdGlvbi5cIixcbiAgICApLFxuICAgIG1lc3NhZ2VzOiB7XG4gICAgICBtdWx0aXBsZUFjdFN0YXRlbWVudHM6XG4gICAgICAgIFwiUmVkdWNlIHRoZSAvLyBBY3Qgc2VjdGlvbiB0byBhIHNpbmdsZSB0b3AtbGV2ZWwgc3RhdGVtZW50IG9yIHZhcmlhYmxlIGRlY2xhcmF0aW9uOyBmb3VuZCB7e2NvdW50fX0uXCIsXG4gICAgfSxcbiAgICBzY2hlbWE6IFtdLFxuICAgIHR5cGU6IFwic3VnZ2VzdGlvblwiLFxuICB9LFxufTtcblxuZXhwb3J0IHsgc2luZ2xlQWN0U3RhdGVtZW50UnVsZSB9O1xuIl19
package/package.json ADDED
@@ -0,0 +1,106 @@
1
+ {
2
+ "name": "@codeperfect/eslint-plugin",
3
+ "version": "1.0.0",
4
+ "description": "Custom ESLint rules for TypeScript repositories",
5
+ "keywords": [
6
+ "eslint",
7
+ "eslintplugin",
8
+ "eslint-plugin",
9
+ "custom-rules",
10
+ "typescript",
11
+ "linting"
12
+ ],
13
+ "homepage": "https://github.com/codeperfect/eslint-plugin#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/codeperfect/eslint-plugin/issues"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/codeperfect/eslint-plugin.git"
20
+ },
21
+ "license": "MIT",
22
+ "author": "CodePerfect",
23
+ "type": "module",
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "import": "./dist/index.js",
28
+ "default": "./dist/index.js"
29
+ }
30
+ },
31
+ "main": "./dist/index.js",
32
+ "types": "./dist/index.d.ts",
33
+ "files": [
34
+ "dist"
35
+ ],
36
+ "scripts": {
37
+ "\n# --------------- SCM --------------- #": "",
38
+ "commit": "npx --yes git-cz",
39
+ "prepare": "husky",
40
+ "\n# --------------- BUILDING --------------- #": "",
41
+ "build": "npm run clean && npm run compile",
42
+ "clean": "npx --yes rimraf dist",
43
+ "compile": "tsc -b -f ./tsconfig.build.json",
44
+ "pack": "npm pack --pack-destination dist",
45
+ "\n# --------------- LINTING --------------- #": "",
46
+ "\t• --------------- checking --------------- •": "",
47
+ "eslint": "npx --yes eslint --max-warnings=0",
48
+ "lint": "npm run lint:run",
49
+ "lint:run": "npm run prettier && npm run eslint",
50
+ "lint:staged": "npx --yes tsx scripts/lint-staged.ts",
51
+ "prettier": "npx --yes prettier --ignore-unknown --check .",
52
+ "\n\t• --------------- fixing --------------- •": "",
53
+ "eslint:fix": "npm run check:rules && npm run eslint -- --fix",
54
+ "lint:fix": "npm run prettier:write && npm run eslint:fix",
55
+ "prettier:write": "npm run prettier -- --write",
56
+ "\n\t• --------------- helpers --------------- •": "",
57
+ "check:rules": "npx --yes eslint-config-prettier eslint.config.ts",
58
+ "benchmark:rules": "npx --yes tsx src/benchmark-rules.ts",
59
+ "eslint:inspect": "npx --yes @eslint/config-inspector",
60
+ "\n# --------------- TESTING --------------- #": "",
61
+ "typecheck": "tsc --noEmit",
62
+ "typecheck:spec": "tsc -p tsconfig.spec.json --noEmit",
63
+ "validate": "npm run lint && npm run typecheck && npm run typecheck:spec && npm run test && npm run build && npm run pack",
64
+ "\n\t• --------------- unit --------------- •": "",
65
+ "tdd": "npx --yes vitest run --watch --silent=true --coverage.enabled=false",
66
+ "tdd:notify": "npm run tdd -- --notify",
67
+ "test": "npx --yes vitest run"
68
+ },
69
+ "dependencies": {
70
+ "minimatch": "^9.0.5"
71
+ },
72
+ "peerDependencies": {
73
+ "eslint": ">=9.0.0"
74
+ },
75
+ "devDependencies": {
76
+ "@codeperfect/eslint-config": "file:../eslint-config/dist/codeperfect-eslint-config-1.0.0.tgz",
77
+ "@commitlint/cli": "^20.4.1",
78
+ "@commitlint/config-conventional": "^20.4.1",
79
+ "@commitlint/cz-commitlint": "^20.4.1",
80
+ "@eslint/js": "^9.39.2",
81
+ "@types/lodash-es": "^4.17.12",
82
+ "@types/node": "^25.2.1",
83
+ "@typescript-eslint/rule-tester": "^8.46.2",
84
+ "@vitest/coverage-v8": "^4.0.18",
85
+ "chalk": "^5.6.2",
86
+ "conventional-changelog-conventionalcommits": "^9.1.0",
87
+ "eslint": "^9.39.2",
88
+ "globals": "^17.3.0",
89
+ "husky": "^9.1.7",
90
+ "lint-staged": "^16.2.7",
91
+ "lodash-es": "^4.17.23",
92
+ "memfs": "^4.56.11",
93
+ "prettier": "^3.8.1",
94
+ "rimraf": "^6.1.2",
95
+ "typescript": "^5.9.3",
96
+ "typescript-eslint": "^8.46.2",
97
+ "vite-tsconfig-paths": "^6.1.1",
98
+ "vitest": "^4.0.18"
99
+ },
100
+ "engines": {
101
+ "node": ">=20.0.0"
102
+ },
103
+ "publishConfig": {
104
+ "access": "public"
105
+ }
106
+ }