@api-extractor-tools/eslint-plugin 0.1.0-alpha.0 → 0.1.0-alpha.2
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/ARCHITECTURE.md +204 -0
- package/CHANGELOG.md +32 -0
- package/README.md +306 -10
- package/api-extractor.json +1 -0
- package/dist/configs/recommended.d.ts +1 -1
- package/dist/configs/recommended.d.ts.map +1 -1
- package/dist/configs/recommended.js +7 -1
- package/dist/configs/recommended.js.map +1 -1
- package/dist/index.d.ts +9 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -15
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +28 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +41 -0
- package/dist/node.js.map +1 -0
- package/dist/rules/extra-release-tag.d.ts +24 -0
- package/dist/rules/extra-release-tag.d.ts.map +1 -0
- package/dist/rules/extra-release-tag.js +141 -0
- package/dist/rules/extra-release-tag.js.map +1 -0
- package/dist/rules/forgotten-export.d.ts +24 -0
- package/dist/rules/forgotten-export.d.ts.map +1 -0
- package/dist/rules/forgotten-export.js +212 -0
- package/dist/rules/forgotten-export.js.map +1 -0
- package/dist/rules/incompatible-release-tags.d.ts +25 -0
- package/dist/rules/incompatible-release-tags.d.ts.map +1 -0
- package/dist/rules/incompatible-release-tags.js +237 -0
- package/dist/rules/incompatible-release-tags.js.map +1 -0
- package/dist/rules/index.d.ts +8 -2
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/index.js +13 -1
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/missing-release-tag.d.ts +4 -0
- package/dist/rules/missing-release-tag.d.ts.map +1 -1
- package/dist/rules/missing-release-tag.js +14 -21
- package/dist/rules/missing-release-tag.js.map +1 -1
- package/dist/rules/override-keyword.d.ts +4 -0
- package/dist/rules/override-keyword.d.ts.map +1 -1
- package/dist/rules/override-keyword.js +9 -11
- package/dist/rules/override-keyword.js.map +1 -1
- package/dist/rules/package-documentation.d.ts +5 -2
- package/dist/rules/package-documentation.d.ts.map +1 -1
- package/dist/rules/package-documentation.js +45 -35
- package/dist/rules/package-documentation.js.map +1 -1
- package/dist/rules/public-on-non-exported.d.ts +24 -0
- package/dist/rules/public-on-non-exported.d.ts.map +1 -0
- package/dist/rules/public-on-non-exported.js +191 -0
- package/dist/rules/public-on-non-exported.js.map +1 -0
- package/dist/rules/public-on-private-member.d.ts +24 -0
- package/dist/rules/public-on-private-member.d.ts.map +1 -0
- package/dist/rules/public-on-private-member.js +111 -0
- package/dist/rules/public-on-private-member.js.map +1 -0
- package/dist/rules/valid-enum-type.d.ts +17 -0
- package/dist/rules/valid-enum-type.d.ts.map +1 -0
- package/dist/rules/valid-enum-type.js +206 -0
- package/dist/rules/valid-enum-type.js.map +1 -0
- package/dist/types.d.ts +66 -24
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/tsdoc-parser.d.ts +37 -6
- package/dist/utils/tsdoc-parser.d.ts.map +1 -1
- package/dist/utils/tsdoc-parser.js +40 -0
- package/dist/utils/tsdoc-parser.js.map +1 -1
- package/docs/rules/valid-enum-type.md +153 -0
- package/package.json +22 -8
- package/src/configs/recommended.ts +7 -1
- package/src/index.ts +21 -15
- package/src/node.ts +50 -0
- package/src/rules/extra-release-tag.ts +201 -0
- package/src/rules/forgotten-export.ts +274 -0
- package/src/rules/incompatible-release-tags.ts +331 -0
- package/src/rules/index.ts +13 -1
- package/src/rules/missing-release-tag.ts +11 -26
- package/src/rules/override-keyword.ts +6 -8
- package/src/rules/package-documentation.ts +54 -40
- package/src/rules/public-on-non-exported.ts +265 -0
- package/src/rules/public-on-private-member.ts +157 -0
- package/src/rules/valid-enum-type.ts +252 -0
- package/src/types.ts +60 -17
- package/src/utils/config-loader.ts +1 -0
- package/src/utils/entry-point.ts +1 -0
- package/src/utils/tsdoc-parser.ts +67 -0
- package/temp/eslint-plugin.api.md +101 -32
- package/test/index.test.ts +1 -0
- package/test/rules/extra-release-tag.test.ts +276 -0
- package/test/rules/forgotten-export.test.ts +190 -0
- package/test/rules/incompatible-release-tags.test.ts +340 -0
- package/test/rules/missing-release-tag.test.ts +2 -1
- package/test/rules/override-keyword.test.ts +2 -1
- package/test/rules/package-documentation.test.ts +113 -64
- package/test/rules/public-on-non-exported.test.ts +201 -0
- package/test/rules/public-on-private-member.test.ts +207 -0
- package/test/rules/valid-enum-type.test.ts +409 -0
- package/test/types.test-d.ts +20 -0
- package/test/utils/config-loader.test.ts +1 -0
- package/test/utils/tsdoc-parser.test.ts +117 -9
- package/tsconfig.json +1 -0
- package/vitest.config.mts +1 -0
- package/dist/utils/index.d.ts +0 -8
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -21
- package/dist/utils/index.js.map +0 -1
- package/src/utils/index.ts +0 -17
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { RuleTester } from '@typescript-eslint/rule-tester'
|
|
2
|
+
import { describe, it, afterAll } from 'vitest'
|
|
3
|
+
import * as tseslintParser from '@typescript-eslint/parser'
|
|
4
|
+
import { incompatibleReleaseTags } from '../../src/rules/incompatible-release-tags'
|
|
5
|
+
|
|
6
|
+
RuleTester.afterAll = afterAll
|
|
7
|
+
RuleTester.describe = describe
|
|
8
|
+
RuleTester.it = it
|
|
9
|
+
|
|
10
|
+
const ruleTester = new RuleTester({
|
|
11
|
+
languageOptions: {
|
|
12
|
+
parser: tseslintParser,
|
|
13
|
+
parserOptions: {
|
|
14
|
+
ecmaVersion: 2022,
|
|
15
|
+
sourceType: 'module',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
describe('incompatible-release-tags', () => {
|
|
21
|
+
ruleTester.run('incompatible-release-tags', incompatibleReleaseTags, {
|
|
22
|
+
valid: [
|
|
23
|
+
// Public API using public type
|
|
24
|
+
{
|
|
25
|
+
code: `
|
|
26
|
+
/**
|
|
27
|
+
* A public interface.
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export interface MyInterface {
|
|
31
|
+
name: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A public function.
|
|
36
|
+
* @public
|
|
37
|
+
*/
|
|
38
|
+
export function myFunction(param: MyInterface): void {}
|
|
39
|
+
`,
|
|
40
|
+
},
|
|
41
|
+
// Public API using beta type (beta is less visible, but this is OK since beta >= beta in some interpretations)
|
|
42
|
+
// Actually, let's make this more strict - public should only use public
|
|
43
|
+
{
|
|
44
|
+
code: `
|
|
45
|
+
/**
|
|
46
|
+
* A beta interface.
|
|
47
|
+
* @beta
|
|
48
|
+
*/
|
|
49
|
+
export interface MyInterface {
|
|
50
|
+
name: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A beta function.
|
|
55
|
+
* @beta
|
|
56
|
+
*/
|
|
57
|
+
export function myFunction(param: MyInterface): void {}
|
|
58
|
+
`,
|
|
59
|
+
},
|
|
60
|
+
// Alpha API using alpha type
|
|
61
|
+
{
|
|
62
|
+
code: `
|
|
63
|
+
/**
|
|
64
|
+
* An alpha interface.
|
|
65
|
+
* @alpha
|
|
66
|
+
*/
|
|
67
|
+
export interface MyInterface {
|
|
68
|
+
name: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* An alpha function.
|
|
73
|
+
* @alpha
|
|
74
|
+
*/
|
|
75
|
+
export function myFunction(param: MyInterface): void {}
|
|
76
|
+
`,
|
|
77
|
+
},
|
|
78
|
+
// Internal API using internal type
|
|
79
|
+
{
|
|
80
|
+
code: `
|
|
81
|
+
/**
|
|
82
|
+
* An internal interface.
|
|
83
|
+
* @internal
|
|
84
|
+
*/
|
|
85
|
+
export interface MyInterface {
|
|
86
|
+
name: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* An internal function.
|
|
91
|
+
* @internal
|
|
92
|
+
*/
|
|
93
|
+
export function myFunction(param: MyInterface): void {}
|
|
94
|
+
`,
|
|
95
|
+
},
|
|
96
|
+
// Beta API using public type (more visible)
|
|
97
|
+
{
|
|
98
|
+
code: `
|
|
99
|
+
/**
|
|
100
|
+
* A public interface.
|
|
101
|
+
* @public
|
|
102
|
+
*/
|
|
103
|
+
export interface MyInterface {
|
|
104
|
+
name: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* A beta function.
|
|
109
|
+
* @beta
|
|
110
|
+
*/
|
|
111
|
+
export function myFunction(param: MyInterface): void {}
|
|
112
|
+
`,
|
|
113
|
+
},
|
|
114
|
+
// Alpha API using public type (more visible)
|
|
115
|
+
{
|
|
116
|
+
code: `
|
|
117
|
+
/**
|
|
118
|
+
* A public interface.
|
|
119
|
+
* @public
|
|
120
|
+
*/
|
|
121
|
+
export interface MyInterface {
|
|
122
|
+
name: string;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* An alpha function.
|
|
127
|
+
* @alpha
|
|
128
|
+
*/
|
|
129
|
+
export function myFunction(param: MyInterface): void {}
|
|
130
|
+
`,
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
invalid: [
|
|
134
|
+
// Public API using internal type
|
|
135
|
+
{
|
|
136
|
+
code: `
|
|
137
|
+
/**
|
|
138
|
+
* An internal interface.
|
|
139
|
+
* @internal
|
|
140
|
+
*/
|
|
141
|
+
interface MyInterface {
|
|
142
|
+
name: string;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* A public function.
|
|
147
|
+
* @public
|
|
148
|
+
*/
|
|
149
|
+
export function myFunction(param: MyInterface): void {}
|
|
150
|
+
`,
|
|
151
|
+
errors: [
|
|
152
|
+
{
|
|
153
|
+
messageId: 'incompatibleReleaseTags',
|
|
154
|
+
data: {
|
|
155
|
+
exportedName: 'myFunction',
|
|
156
|
+
exportedTag: '@public',
|
|
157
|
+
referencedName: 'MyInterface',
|
|
158
|
+
referencedTag: '@internal',
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
// Public API using alpha type
|
|
164
|
+
{
|
|
165
|
+
code: `
|
|
166
|
+
/**
|
|
167
|
+
* An alpha interface.
|
|
168
|
+
* @alpha
|
|
169
|
+
*/
|
|
170
|
+
interface MyInterface {
|
|
171
|
+
name: string;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* A public function.
|
|
176
|
+
* @public
|
|
177
|
+
*/
|
|
178
|
+
export function myFunction(param: MyInterface): void {}
|
|
179
|
+
`,
|
|
180
|
+
errors: [
|
|
181
|
+
{
|
|
182
|
+
messageId: 'incompatibleReleaseTags',
|
|
183
|
+
data: {
|
|
184
|
+
exportedName: 'myFunction',
|
|
185
|
+
exportedTag: '@public',
|
|
186
|
+
referencedName: 'MyInterface',
|
|
187
|
+
referencedTag: '@alpha',
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
// Beta API using internal type
|
|
193
|
+
{
|
|
194
|
+
code: `
|
|
195
|
+
/**
|
|
196
|
+
* An internal interface.
|
|
197
|
+
* @internal
|
|
198
|
+
*/
|
|
199
|
+
interface MyInterface {
|
|
200
|
+
name: string;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* A beta function.
|
|
205
|
+
* @beta
|
|
206
|
+
*/
|
|
207
|
+
export function myFunction(param: MyInterface): void {}
|
|
208
|
+
`,
|
|
209
|
+
errors: [
|
|
210
|
+
{
|
|
211
|
+
messageId: 'incompatibleReleaseTags',
|
|
212
|
+
data: {
|
|
213
|
+
exportedName: 'myFunction',
|
|
214
|
+
exportedTag: '@beta',
|
|
215
|
+
referencedName: 'MyInterface',
|
|
216
|
+
referencedTag: '@internal',
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
// Beta API using alpha type
|
|
222
|
+
{
|
|
223
|
+
code: `
|
|
224
|
+
/**
|
|
225
|
+
* An alpha interface.
|
|
226
|
+
* @alpha
|
|
227
|
+
*/
|
|
228
|
+
interface MyInterface {
|
|
229
|
+
name: string;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* A beta function.
|
|
234
|
+
* @beta
|
|
235
|
+
*/
|
|
236
|
+
export function myFunction(param: MyInterface): void {}
|
|
237
|
+
`,
|
|
238
|
+
errors: [
|
|
239
|
+
{
|
|
240
|
+
messageId: 'incompatibleReleaseTags',
|
|
241
|
+
data: {
|
|
242
|
+
exportedName: 'myFunction',
|
|
243
|
+
exportedTag: '@beta',
|
|
244
|
+
referencedName: 'MyInterface',
|
|
245
|
+
referencedTag: '@alpha',
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
],
|
|
249
|
+
},
|
|
250
|
+
// Alpha API using internal type
|
|
251
|
+
{
|
|
252
|
+
code: `
|
|
253
|
+
/**
|
|
254
|
+
* An internal interface.
|
|
255
|
+
* @internal
|
|
256
|
+
*/
|
|
257
|
+
interface MyInterface {
|
|
258
|
+
name: string;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* An alpha function.
|
|
263
|
+
* @alpha
|
|
264
|
+
*/
|
|
265
|
+
export function myFunction(param: MyInterface): void {}
|
|
266
|
+
`,
|
|
267
|
+
errors: [
|
|
268
|
+
{
|
|
269
|
+
messageId: 'incompatibleReleaseTags',
|
|
270
|
+
data: {
|
|
271
|
+
exportedName: 'myFunction',
|
|
272
|
+
exportedTag: '@alpha',
|
|
273
|
+
referencedName: 'MyInterface',
|
|
274
|
+
referencedTag: '@internal',
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
],
|
|
278
|
+
},
|
|
279
|
+
// Public interface with internal type property
|
|
280
|
+
{
|
|
281
|
+
code: `
|
|
282
|
+
/**
|
|
283
|
+
* An internal type.
|
|
284
|
+
* @internal
|
|
285
|
+
*/
|
|
286
|
+
type InternalType = string;
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* A public interface.
|
|
290
|
+
* @public
|
|
291
|
+
*/
|
|
292
|
+
export interface MyInterface {
|
|
293
|
+
value: InternalType;
|
|
294
|
+
}
|
|
295
|
+
`,
|
|
296
|
+
errors: [
|
|
297
|
+
{
|
|
298
|
+
messageId: 'incompatibleReleaseTags',
|
|
299
|
+
data: {
|
|
300
|
+
exportedName: 'MyInterface',
|
|
301
|
+
exportedTag: '@public',
|
|
302
|
+
referencedName: 'InternalType',
|
|
303
|
+
referencedTag: '@internal',
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
],
|
|
307
|
+
},
|
|
308
|
+
],
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
// Test with severity option
|
|
312
|
+
ruleTester.run(
|
|
313
|
+
'incompatible-release-tags with severity=none',
|
|
314
|
+
incompatibleReleaseTags,
|
|
315
|
+
{
|
|
316
|
+
valid: [
|
|
317
|
+
// Should not report when severity is 'none'
|
|
318
|
+
{
|
|
319
|
+
code: `
|
|
320
|
+
/**
|
|
321
|
+
* An internal interface.
|
|
322
|
+
* @internal
|
|
323
|
+
*/
|
|
324
|
+
interface MyInterface {
|
|
325
|
+
name: string;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* A public function.
|
|
330
|
+
* @public
|
|
331
|
+
*/
|
|
332
|
+
export function myFunction(param: MyInterface): void {}
|
|
333
|
+
`,
|
|
334
|
+
options: [{ severity: 'none' }],
|
|
335
|
+
},
|
|
336
|
+
],
|
|
337
|
+
invalid: [],
|
|
338
|
+
},
|
|
339
|
+
)
|
|
340
|
+
})
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RuleTester } from '@typescript-eslint/rule-tester'
|
|
2
2
|
import { describe, it, afterAll } from 'vitest'
|
|
3
|
+
import * as tseslintParser from '@typescript-eslint/parser'
|
|
3
4
|
import { missingReleaseTag } from '../../src/rules/missing-release-tag'
|
|
4
5
|
|
|
5
6
|
RuleTester.afterAll = afterAll
|
|
@@ -8,7 +9,7 @@ RuleTester.it = it
|
|
|
8
9
|
|
|
9
10
|
const ruleTester = new RuleTester({
|
|
10
11
|
languageOptions: {
|
|
11
|
-
parser:
|
|
12
|
+
parser: tseslintParser,
|
|
12
13
|
parserOptions: {
|
|
13
14
|
ecmaVersion: 2022,
|
|
14
15
|
sourceType: 'module',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RuleTester } from '@typescript-eslint/rule-tester'
|
|
2
2
|
import { describe, it, afterAll } from 'vitest'
|
|
3
|
+
import * as tseslintParser from '@typescript-eslint/parser'
|
|
3
4
|
import { overrideKeyword } from '../../src/rules/override-keyword'
|
|
4
5
|
|
|
5
6
|
RuleTester.afterAll = afterAll
|
|
@@ -8,7 +9,7 @@ RuleTester.it = it
|
|
|
8
9
|
|
|
9
10
|
const ruleTester = new RuleTester({
|
|
10
11
|
languageOptions: {
|
|
11
|
-
parser:
|
|
12
|
+
parser: tseslintParser,
|
|
12
13
|
parserOptions: {
|
|
13
14
|
ecmaVersion: 2022,
|
|
14
15
|
sourceType: 'module',
|
|
@@ -1,18 +1,63 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RuleTester } from '@typescript-eslint/rule-tester'
|
|
2
|
+
import { describe, it, expect, afterAll, afterEach, beforeEach } from 'vitest'
|
|
3
|
+
import * as tseslintParser from '@typescript-eslint/parser'
|
|
2
4
|
import * as path from 'path'
|
|
3
5
|
import * as fs from 'fs'
|
|
4
6
|
import * as os from 'os'
|
|
5
|
-
import {
|
|
7
|
+
import { packageDocumentation } from '../../src/rules/package-documentation.js'
|
|
6
8
|
import {
|
|
7
9
|
findPackageJson,
|
|
8
10
|
isEntryPoint,
|
|
11
|
+
clearPackageJsonCache,
|
|
12
|
+
} from '../../src/utils/entry-point.js'
|
|
13
|
+
import {
|
|
9
14
|
hasPackageDocumentation,
|
|
10
15
|
parseTSDocComment,
|
|
11
|
-
} from '../../src/utils'
|
|
16
|
+
} from '../../src/utils/tsdoc-parser.js'
|
|
17
|
+
|
|
18
|
+
// Wire up vitest for RuleTester
|
|
19
|
+
RuleTester.afterAll = afterAll
|
|
20
|
+
RuleTester.describe = describe
|
|
21
|
+
RuleTester.it = it
|
|
22
|
+
|
|
23
|
+
// Create a temp directory for RuleTester tests (must exist at module eval time)
|
|
24
|
+
const ruleTestDir = fs.mkdtempSync(path.join(os.tmpdir(), 'eslint-pd-rule-'))
|
|
25
|
+
const ruleTestSrcDir = path.join(ruleTestDir, 'src')
|
|
26
|
+
fs.mkdirSync(ruleTestSrcDir, { recursive: true })
|
|
27
|
+
fs.mkdirSync(path.join(ruleTestSrcDir, 'utils'), { recursive: true })
|
|
28
|
+
|
|
29
|
+
fs.writeFileSync(
|
|
30
|
+
path.join(ruleTestDir, 'package.json'),
|
|
31
|
+
JSON.stringify({ name: 'test-package', main: './src/index.ts' }, null, 2),
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
// Create placeholder files so paths resolve correctly
|
|
35
|
+
fs.writeFileSync(path.join(ruleTestSrcDir, 'index.ts'), '')
|
|
36
|
+
fs.writeFileSync(path.join(ruleTestSrcDir, 'helper.ts'), '')
|
|
37
|
+
fs.writeFileSync(path.join(ruleTestSrcDir, 'utils', 'deep.ts'), '')
|
|
38
|
+
|
|
39
|
+
const entryFile = path.join(ruleTestSrcDir, 'index.ts')
|
|
40
|
+
const helperFile = path.join(ruleTestSrcDir, 'helper.ts')
|
|
41
|
+
const deepFile = path.join(ruleTestSrcDir, 'utils', 'deep.ts')
|
|
42
|
+
|
|
43
|
+
const ruleTester = new RuleTester({
|
|
44
|
+
languageOptions: {
|
|
45
|
+
parser: tseslintParser,
|
|
46
|
+
parserOptions: {
|
|
47
|
+
ecmaVersion: 2022,
|
|
48
|
+
sourceType: 'module',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
})
|
|
12
52
|
|
|
13
53
|
describe('package-documentation', () => {
|
|
14
54
|
let tempDir: string
|
|
15
55
|
|
|
56
|
+
afterAll(() => {
|
|
57
|
+
fs.rmSync(ruleTestDir, { recursive: true, force: true })
|
|
58
|
+
clearPackageJsonCache()
|
|
59
|
+
})
|
|
60
|
+
|
|
16
61
|
beforeEach(() => {
|
|
17
62
|
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'eslint-plugin-test-'))
|
|
18
63
|
clearPackageJsonCache()
|
|
@@ -72,7 +117,7 @@ describe('package-documentation', () => {
|
|
|
72
117
|
*/`
|
|
73
118
|
const parsed = parseTSDocComment(comment)
|
|
74
119
|
expect(parsed.docComment).toBeDefined()
|
|
75
|
-
expect(hasPackageDocumentation(parsed.docComment
|
|
120
|
+
expect(hasPackageDocumentation(parsed.docComment)).toBe(true)
|
|
76
121
|
})
|
|
77
122
|
|
|
78
123
|
it('should return false when @packageDocumentation is missing', () => {
|
|
@@ -81,72 +126,76 @@ describe('package-documentation', () => {
|
|
|
81
126
|
*/`
|
|
82
127
|
const parsed = parseTSDocComment(comment)
|
|
83
128
|
expect(parsed.docComment).toBeDefined()
|
|
84
|
-
expect(hasPackageDocumentation(parsed.docComment
|
|
129
|
+
expect(hasPackageDocumentation(parsed.docComment)).toBe(false)
|
|
85
130
|
})
|
|
86
131
|
})
|
|
87
132
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const code = `/**
|
|
95
|
-
* This is the main entry point.
|
|
133
|
+
ruleTester.run('package-documentation', packageDocumentation, {
|
|
134
|
+
valid: [
|
|
135
|
+
// Entry point with @packageDocumentation — should pass
|
|
136
|
+
{
|
|
137
|
+
code: `/**
|
|
138
|
+
* Package entry point.
|
|
96
139
|
* @packageDocumentation
|
|
97
140
|
*/
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
141
|
+
export function foo() {}`,
|
|
142
|
+
filename: entryFile,
|
|
143
|
+
},
|
|
144
|
+
// Non-entry-point without @packageDocumentation — should pass
|
|
145
|
+
{
|
|
146
|
+
code: `/**
|
|
147
|
+
* A helper function.
|
|
148
|
+
*/
|
|
149
|
+
export function helper() {}`,
|
|
150
|
+
filename: helperFile,
|
|
151
|
+
},
|
|
152
|
+
// Non-entry-point with no comments at all — should pass
|
|
153
|
+
{
|
|
154
|
+
code: `export function helper() {}`,
|
|
155
|
+
filename: helperFile,
|
|
156
|
+
},
|
|
157
|
+
// Deep non-entry-point without @packageDocumentation — should pass
|
|
158
|
+
{
|
|
159
|
+
code: `export const x = 1`,
|
|
160
|
+
filename: deepFile,
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
invalid: [
|
|
164
|
+
// Entry point without @packageDocumentation — should fail
|
|
165
|
+
{
|
|
166
|
+
code: `/**
|
|
167
|
+
* Missing package documentation.
|
|
168
|
+
*/
|
|
169
|
+
export function foo() {}`,
|
|
170
|
+
filename: entryFile,
|
|
171
|
+
errors: [{ messageId: 'missingPackageDocumentation' as const }],
|
|
172
|
+
},
|
|
173
|
+
// Entry point with no comments at all — should fail
|
|
174
|
+
{
|
|
175
|
+
code: `export function foo() {}`,
|
|
176
|
+
filename: entryFile,
|
|
177
|
+
errors: [{ messageId: 'missingPackageDocumentation' as const }],
|
|
178
|
+
},
|
|
179
|
+
// Non-entry-point with @packageDocumentation — should fail
|
|
180
|
+
{
|
|
181
|
+
code: `/**
|
|
182
|
+
* This shouldn't be here.
|
|
109
183
|
* @packageDocumentation
|
|
110
|
-
*/`)
|
|
111
|
-
expect(hasPackageDocumentation(parsed.docComment!)).toBe(true)
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
it('should fail when entry point lacks @packageDocumentation', () => {
|
|
115
|
-
createPackageJson('./src/index.ts')
|
|
116
|
-
const srcDir = createSourceDir()
|
|
117
|
-
const indexPath = path.join(srcDir, 'index.ts')
|
|
118
|
-
|
|
119
|
-
const code = `/**
|
|
120
|
-
* This is the main entry point.
|
|
121
184
|
*/
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
it('should not require @packageDocumentation for non-entry points', () => {
|
|
138
|
-
createPackageJson('./src/index.ts')
|
|
139
|
-
const srcDir = createSourceDir()
|
|
140
|
-
|
|
141
|
-
const indexPath = path.join(srcDir, 'index.ts')
|
|
142
|
-
fs.writeFileSync(indexPath, '/** @packageDocumentation */ export {}')
|
|
143
|
-
|
|
144
|
-
const helperPath = path.join(srcDir, 'helper.ts')
|
|
145
|
-
fs.writeFileSync(helperPath, '// No package documentation needed')
|
|
146
|
-
|
|
147
|
-
const pkgPath = findPackageJson(srcDir)
|
|
148
|
-
// Helper is not an entry point, so no check needed
|
|
149
|
-
expect(isEntryPoint(helperPath, pkgPath!)).toBe(false)
|
|
150
|
-
})
|
|
185
|
+
export function helper() {}`,
|
|
186
|
+
filename: helperFile,
|
|
187
|
+
errors: [{ messageId: 'unexpectedPackageDocumentation' as const }],
|
|
188
|
+
},
|
|
189
|
+
// Deep non-entry-point with @packageDocumentation — should fail
|
|
190
|
+
{
|
|
191
|
+
code: `/**
|
|
192
|
+
* Wrong place for package docs.
|
|
193
|
+
* @packageDocumentation
|
|
194
|
+
*/
|
|
195
|
+
export const x = 1`,
|
|
196
|
+
filename: deepFile,
|
|
197
|
+
errors: [{ messageId: 'unexpectedPackageDocumentation' as const }],
|
|
198
|
+
},
|
|
199
|
+
],
|
|
151
200
|
})
|
|
152
201
|
})
|