jsdoczoom 0.4.11 → 0.4.13

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 (61) hide show
  1. package/dist/{src/drilldown.js → drilldown.js} +9 -6
  2. package/package.json +2 -2
  3. package/dist/test/barrel.test.js +0 -77
  4. package/dist/test/cache.test.js +0 -222
  5. package/dist/test/cli.test.js +0 -479
  6. package/dist/test/drilldown-barrel.test.js +0 -383
  7. package/dist/test/drilldown.test.js +0 -469
  8. package/dist/test/errors.test.js +0 -26
  9. package/dist/test/eslint-engine.test.js +0 -130
  10. package/dist/test/eslint-plugin.test.js +0 -291
  11. package/dist/test/file-discovery.test.js +0 -72
  12. package/dist/test/jsdoc-parser.test.js +0 -353
  13. package/dist/test/lint.test.js +0 -413
  14. package/dist/test/selector.test.js +0 -93
  15. package/dist/test/type-declarations.test.js +0 -321
  16. package/dist/test/validate.test.js +0 -361
  17. package/types/test/barrel.test.d.ts +0 -1
  18. package/types/test/cache.test.d.ts +0 -8
  19. package/types/test/cli.test.d.ts +0 -1
  20. package/types/test/drilldown-barrel.test.d.ts +0 -1
  21. package/types/test/drilldown.test.d.ts +0 -1
  22. package/types/test/errors.test.d.ts +0 -1
  23. package/types/test/eslint-engine.test.d.ts +0 -6
  24. package/types/test/eslint-plugin.test.d.ts +0 -1
  25. package/types/test/file-discovery.test.d.ts +0 -1
  26. package/types/test/jsdoc-parser.test.d.ts +0 -1
  27. package/types/test/lint.test.d.ts +0 -9
  28. package/types/test/selector.test.d.ts +0 -1
  29. package/types/test/type-declarations.test.d.ts +0 -1
  30. package/types/test/validate.test.d.ts +0 -1
  31. /package/dist/{src/barrel.js → barrel.js} +0 -0
  32. /package/dist/{src/cache.js → cache.js} +0 -0
  33. /package/dist/{src/cli.js → cli.js} +0 -0
  34. /package/dist/{src/errors.js → errors.js} +0 -0
  35. /package/dist/{src/eslint-engine.js → eslint-engine.js} +0 -0
  36. /package/dist/{src/eslint-plugin.js → eslint-plugin.js} +0 -0
  37. /package/dist/{src/file-discovery.js → file-discovery.js} +0 -0
  38. /package/dist/{src/index.js → index.js} +0 -0
  39. /package/dist/{src/jsdoc-parser.js → jsdoc-parser.js} +0 -0
  40. /package/dist/{src/lint.js → lint.js} +0 -0
  41. /package/dist/{src/selector.js → selector.js} +0 -0
  42. /package/dist/{src/skill-text.js → skill-text.js} +0 -0
  43. /package/dist/{src/type-declarations.js → type-declarations.js} +0 -0
  44. /package/dist/{src/types.js → types.js} +0 -0
  45. /package/dist/{src/validate.js → validate.js} +0 -0
  46. /package/types/{src/barrel.d.ts → barrel.d.ts} +0 -0
  47. /package/types/{src/cache.d.ts → cache.d.ts} +0 -0
  48. /package/types/{src/cli.d.ts → cli.d.ts} +0 -0
  49. /package/types/{src/drilldown.d.ts → drilldown.d.ts} +0 -0
  50. /package/types/{src/errors.d.ts → errors.d.ts} +0 -0
  51. /package/types/{src/eslint-engine.d.ts → eslint-engine.d.ts} +0 -0
  52. /package/types/{src/eslint-plugin.d.ts → eslint-plugin.d.ts} +0 -0
  53. /package/types/{src/file-discovery.d.ts → file-discovery.d.ts} +0 -0
  54. /package/types/{src/index.d.ts → index.d.ts} +0 -0
  55. /package/types/{src/jsdoc-parser.d.ts → jsdoc-parser.d.ts} +0 -0
  56. /package/types/{src/lint.d.ts → lint.d.ts} +0 -0
  57. /package/types/{src/selector.d.ts → selector.d.ts} +0 -0
  58. /package/types/{src/skill-text.d.ts → skill-text.d.ts} +0 -0
  59. /package/types/{src/type-declarations.d.ts → type-declarations.d.ts} +0 -0
  60. /package/types/{src/types.d.ts → types.d.ts} +0 -0
  61. /package/types/{src/validate.d.ts → validate.d.ts} +0 -0
@@ -1,291 +0,0 @@
1
- import { Linter } from "eslint";
2
- import { describe, expect, it } from "vitest";
3
- import plugin from "../src/eslint-plugin.js";
4
-
5
- /**
6
- * Tests for the custom jsdoczoom ESLint plugin rules that validate
7
- * file-level JSDoc presence, @summary tags, and descriptions.
8
- *
9
- * @summary Tests for custom jsdoczoom ESLint plugin rules
10
- */
11
- const linter = new Linter();
12
- const config = {
13
- plugins: { jsdoczoom: plugin },
14
- rules: {
15
- "jsdoczoom/require-file-jsdoc": "error",
16
- "jsdoczoom/require-file-summary": "error",
17
- "jsdoczoom/require-file-description": "error",
18
- "jsdoczoom/require-file-ordering": "warn",
19
- },
20
- languageOptions: {
21
- ecmaVersion: "latest",
22
- sourceType: "module",
23
- },
24
- };
25
- function verify(code) {
26
- return linter.verify(code, config);
27
- }
28
- function ruleIds(messages) {
29
- return messages.filter((m) => m.ruleId !== null).map((m) => m.ruleId);
30
- }
31
- function messageIds(messages) {
32
- return messages
33
- .filter((m) => m.messageId !== undefined)
34
- .map((m) => m.messageId);
35
- }
36
- // ---------------------------------------------------------------------------
37
- // require-file-jsdoc
38
- // ---------------------------------------------------------------------------
39
- describe("jsdoczoom/require-file-jsdoc", () => {
40
- it("valid file passes all rules", () => {
41
- const code = [
42
- "/** Description.",
43
- " * @summary Summary */",
44
- "export const x = 1;",
45
- ].join("\n");
46
- const messages = verify(code);
47
- expect(messages).toHaveLength(0);
48
- });
49
- it("missing JSDoc fails require-file-jsdoc", () => {
50
- const code = "export const x = 1;";
51
- const messages = verify(code);
52
- expect(ruleIds(messages)).toContain("jsdoczoom/require-file-jsdoc");
53
- expect(messageIds(messages)).toContain("missingFileJsdoc");
54
- });
55
- it("JSDoc after imports is valid", () => {
56
- const code = [
57
- 'import { x } from "y";',
58
- "/** Desc",
59
- " * @summary S */",
60
- "export const z = 1;",
61
- ].join("\n");
62
- const messages = verify(code);
63
- expect(messages).toHaveLength(0);
64
- });
65
- it("file with only imports and JSDoc passes", () => {
66
- const code = [
67
- "/** Desc",
68
- " * @summary S */",
69
- 'import { x } from "y";',
70
- ].join("\n");
71
- const messages = verify(code);
72
- expect(messages).toHaveLength(0);
73
- });
74
- it("/*** triple-asterisk block is ignored", () => {
75
- const code = ["/*** Desc", " * @summary S */", "export const x = 1;"].join(
76
- "\n",
77
- );
78
- const messages = verify(code);
79
- expect(ruleIds(messages)).toContain("jsdoczoom/require-file-jsdoc");
80
- expect(messageIds(messages)).toContain("missingFileJsdoc");
81
- });
82
- });
83
- // ---------------------------------------------------------------------------
84
- // require-file-summary
85
- // ---------------------------------------------------------------------------
86
- describe("jsdoczoom/require-file-summary", () => {
87
- it("missing @summary fails require-file-summary", () => {
88
- const code = ["/** Description only */", "export const x = 1;"].join("\n");
89
- const messages = verify(code);
90
- expect(ruleIds(messages)).toContain("jsdoczoom/require-file-summary");
91
- expect(messageIds(messages)).toContain("missingSummary");
92
- });
93
- it("multiple @summary fails require-file-summary", () => {
94
- const code = [
95
- "/** Desc",
96
- " * @summary First",
97
- " * @summary Second */",
98
- "export const x = 1;",
99
- ].join("\n");
100
- const messages = verify(code);
101
- expect(ruleIds(messages)).toContain("jsdoczoom/require-file-summary");
102
- expect(messageIds(messages)).toContain("multipleSummary");
103
- });
104
- it("whitespace-only @summary is skipped", () => {
105
- const code = [
106
- "/** Desc",
107
- " * @summary ",
108
- " * @summary Real summary */",
109
- "export const x = 1;",
110
- ].join("\n");
111
- const messages = verify(code);
112
- // Only one non-whitespace @summary, so should pass (no multipleSummary)
113
- const summaryMessages = messages.filter(
114
- (m) => m.ruleId === "jsdoczoom/require-file-summary",
115
- );
116
- expect(summaryMessages).toHaveLength(0);
117
- });
118
- it("case-sensitive @summary enforcement — @Summary not recognized", () => {
119
- const code = [
120
- "/** Desc",
121
- " * @Summary Not recognized */",
122
- "export const x = 1;",
123
- ].join("\n");
124
- const messages = verify(code);
125
- expect(ruleIds(messages)).toContain("jsdoczoom/require-file-summary");
126
- expect(messageIds(messages)).toContain("missingSummary");
127
- });
128
- it("multi-line @summary content is joined — counts as one summary", () => {
129
- const code = [
130
- "/** Desc.",
131
- " * @summary Multi",
132
- " * line summary */",
133
- "export const x = 1;",
134
- ].join("\n");
135
- const messages = verify(code);
136
- // One @summary with multi-line content — should pass
137
- const summaryMessages = messages.filter(
138
- (m) => m.ruleId === "jsdoczoom/require-file-summary",
139
- );
140
- expect(summaryMessages).toHaveLength(0);
141
- });
142
- it("no report when file-level JSDoc is missing (rule 1 handles that)", () => {
143
- const code = "export const x = 1;";
144
- const messages = verify(code);
145
- // require-file-summary should NOT report — only require-file-jsdoc reports
146
- expect(ruleIds(messages)).not.toContain("jsdoczoom/require-file-summary");
147
- });
148
- });
149
- // ---------------------------------------------------------------------------
150
- // require-file-description
151
- // ---------------------------------------------------------------------------
152
- describe("jsdoczoom/require-file-description", () => {
153
- it("missing description fails require-file-description", () => {
154
- const code = ["/** @summary Summary only */", "export const x = 1;"].join(
155
- "\n",
156
- );
157
- const messages = verify(code);
158
- expect(ruleIds(messages)).toContain("jsdoczoom/require-file-description");
159
- expect(messageIds(messages)).toContain("missingDescription");
160
- });
161
- it("@desc tag counts as description", () => {
162
- const code = [
163
- "/** @desc Description here",
164
- " * @summary Summary */",
165
- "export const x = 1;",
166
- ].join("\n");
167
- const messages = verify(code);
168
- expect(ruleIds(messages)).not.toContain(
169
- "jsdoczoom/require-file-description",
170
- );
171
- });
172
- it("@description tag counts as description", () => {
173
- const code = [
174
- "/** @description Desc",
175
- " * @summary S */",
176
- "export const x = 1;",
177
- ].join("\n");
178
- const messages = verify(code);
179
- expect(ruleIds(messages)).not.toContain(
180
- "jsdoczoom/require-file-description",
181
- );
182
- });
183
- it("@file tag counts as description", () => {
184
- const code = [
185
- "/** @file Desc",
186
- " * @summary S */",
187
- "export const x = 1;",
188
- ].join("\n");
189
- const messages = verify(code);
190
- expect(ruleIds(messages)).not.toContain(
191
- "jsdoczoom/require-file-description",
192
- );
193
- });
194
- it("@fileoverview tag counts as description (case-insensitive)", () => {
195
- const code = [
196
- "/** @fileoverview Desc",
197
- " * @summary S */",
198
- "export const x = 1;",
199
- ].join("\n");
200
- const messages = verify(code);
201
- expect(ruleIds(messages)).not.toContain(
202
- "jsdoczoom/require-file-description",
203
- );
204
- });
205
- it("free-text before @tags counts as description", () => {
206
- const code = [
207
- "/** This is a description.",
208
- " * @summary Summary */",
209
- "export const x = 1;",
210
- ].join("\n");
211
- const messages = verify(code);
212
- expect(ruleIds(messages)).not.toContain(
213
- "jsdoczoom/require-file-description",
214
- );
215
- });
216
- it("no report when file-level JSDoc is missing (rule 1 handles that)", () => {
217
- const code = "export const x = 1;";
218
- const messages = verify(code);
219
- // require-file-description should NOT report
220
- expect(ruleIds(messages)).not.toContain(
221
- "jsdoczoom/require-file-description",
222
- );
223
- });
224
- });
225
- // ---------------------------------------------------------------------------
226
- // require-file-ordering
227
- // ---------------------------------------------------------------------------
228
- describe("jsdoczoom/require-file-ordering", () => {
229
- it("valid: description before tags produces no ordering messages", () => {
230
- const code = [
231
- "/** Description here.",
232
- " * @summary Summary */",
233
- "export const x = 1;",
234
- ].join("\n");
235
- const messages = verify(code);
236
- const orderingMessages = messages.filter(
237
- (m) => m.ruleId === "jsdoczoom/require-file-ordering",
238
- );
239
- expect(orderingMessages).toHaveLength(0);
240
- });
241
- it("invalid: description after tags produces descriptionAfterTags", () => {
242
- const code = [
243
- "/** @summary Summary",
244
- " * Description after tag */",
245
- "export const x = 1;",
246
- ].join("\n");
247
- const messages = verify(code);
248
- expect(ruleIds(messages)).toContain("jsdoczoom/require-file-ordering");
249
- expect(messageIds(messages)).toContain("descriptionAfterTags");
250
- });
251
- it("invalid: duplicate file-level JSDoc blocks produces duplicateFileJsdoc", () => {
252
- const code = [
253
- "/** First block.",
254
- " * @summary S1 */",
255
- "/** Second block.",
256
- " * @summary S2 */",
257
- "export const x = 1;",
258
- ].join("\n");
259
- const messages = verify(code);
260
- expect(ruleIds(messages)).toContain("jsdoczoom/require-file-ordering");
261
- expect(messageIds(messages)).toContain("duplicateFileJsdoc");
262
- });
263
- it("valid: tag continuation lines are not false positives", () => {
264
- const code = [
265
- "/** Description.",
266
- " * @summary Multi-line",
267
- " * summary continuation */",
268
- "export const x = 1;",
269
- ].join("\n");
270
- const messages = verify(code);
271
- const orderingMessages = messages.filter(
272
- (m) => m.ruleId === "jsdoczoom/require-file-ordering",
273
- );
274
- expect(orderingMessages).toHaveLength(0);
275
- });
276
- it("valid: single JSDoc block with correct ordering produces no messages", () => {
277
- const code = [
278
- "/** This file does something important.",
279
- " *",
280
- " * It has multiple description lines.",
281
- " *",
282
- " * @summary Important file */",
283
- "export const x = 1;",
284
- ].join("\n");
285
- const messages = verify(code);
286
- const orderingMessages = messages.filter(
287
- (m) => m.ruleId === "jsdoczoom/require-file-ordering",
288
- );
289
- expect(orderingMessages).toHaveLength(0);
290
- });
291
- });
@@ -1,72 +0,0 @@
1
- import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
- import { tmpdir } from "node:os";
3
- import { dirname, resolve } from "node:path";
4
- import { fileURLToPath } from "node:url";
5
- import { describe, expect, it } from "vitest";
6
- import { JsdocError } from "../src/errors.js";
7
- import { discoverFiles } from "../src/file-discovery.js";
8
-
9
- /**
10
- * Verifies glob matching, .d.ts exclusion, single-path resolution, and
11
- * FILE_NOT_FOUND error behavior for the file discovery module.
12
- *
13
- * @summary Tests for file discovery via glob patterns and direct paths
14
- */
15
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
- const fixturesDir = resolve(__dirname, "fixtures");
17
- const leafFilesDir = resolve(fixturesDir, "leaf-files");
18
- describe("discoverFiles", () => {
19
- it("glob matches .ts and .tsx files", () => {
20
- const results = discoverFiles("**/*.ts", leafFilesDir);
21
- expect(results.length).toBeGreaterThan(0);
22
- for (const f of results) {
23
- expect(f).toMatch(/\.ts$/);
24
- }
25
- });
26
- it("glob excludes .d.ts files", () => {
27
- // Create a temp directory with .ts, .tsx, and .d.ts files
28
- const tmpDir = mkdtempSync(resolve(tmpdir(), "jsdoczoom-test-"));
29
- try {
30
- writeFileSync(resolve(tmpDir, "real.ts"), "export const a = 1;");
31
- writeFileSync(resolve(tmpDir, "component.tsx"), "export const b = 2;");
32
- writeFileSync(resolve(tmpDir, "real.d.ts"), "declare const a: number;");
33
- const results = discoverFiles("**/*.ts", tmpDir);
34
- expect(results).toHaveLength(1);
35
- expect(results[0]).toMatch(/real\.ts$/);
36
- expect(results[0]).not.toMatch(/\.d\.ts$/);
37
- // Also check .tsx is matched with its own pattern
38
- const tsxResults = discoverFiles("**/*.tsx", tmpDir);
39
- expect(tsxResults).toHaveLength(1);
40
- expect(tsxResults[0]).toMatch(/component\.tsx$/);
41
- } finally {
42
- rmSync(tmpDir, { recursive: true });
43
- }
44
- });
45
- it("glob returns empty array when no matches", () => {
46
- const results = discoverFiles("nonexistent/**/*.ts", leafFilesDir);
47
- expect(results).toEqual([]);
48
- });
49
- it("path resolves to single-element array", () => {
50
- const filePath = "one-summary.ts";
51
- const results = discoverFiles(filePath, leafFilesDir);
52
- expect(results).toHaveLength(1);
53
- expect(results[0]).toBe(resolve(leafFilesDir, filePath));
54
- });
55
- it("directory path returns discovered .ts/.tsx files within it", () => {
56
- const dirResults = discoverFiles(leafFilesDir, "/");
57
- const globResults = discoverFiles(`${leafFilesDir}/**`, "/");
58
- expect(dirResults.length).toBeGreaterThan(0);
59
- expect(dirResults).toEqual(globResults);
60
- });
61
- it("path throws FILE_NOT_FOUND for missing file", () => {
62
- expect(() => discoverFiles("does-not-exist.ts", leafFilesDir)).toThrow(
63
- JsdocError,
64
- );
65
- try {
66
- discoverFiles("does-not-exist.ts", leafFilesDir);
67
- } catch (error) {
68
- expect(error).toBeInstanceOf(JsdocError);
69
- expect(error.code).toBe("FILE_NOT_FOUND");
70
- }
71
- });
72
- });