@nextcloud/eslint-config 8.2.1 → 8.3.0-beta.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.
- package/CHANGELOG.md +8 -0
- package/index.js +2 -2
- package/package.json +18 -7
- package/tests/eslint-config.test.ts +31 -0
- package/tests/eslint.d.ts +11 -0
- package/tests/fixtures/example-fail.js +3 -0
- package/tests/fixtures/some.tsx +7 -0
- package/tests/setup-jest.ts +128 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [v8.3.0-beta.0](https://github.com/nextcloud/eslint-config/tree/v8.3.0-beta.0) (2023-05-12)
|
|
4
|
+
|
|
5
|
+
[Full Changelog](https://github.com/nextcloud/eslint-config/compare/v8.2.1...v8.3.0-beta.0)
|
|
6
|
+
|
|
7
|
+
**Merged pull requests:**
|
|
8
|
+
- Typescript 5 support
|
|
9
|
+
- Various dependencies upgrades
|
|
10
|
+
|
|
3
11
|
## [v8.2.1](https://github.com/nextcloud/eslint-config/tree/v8.2.1) (2023-01-30)
|
|
4
12
|
|
|
5
13
|
[Full Changelog](https://github.com/nextcloud/eslint-config/compare/v8.2.0...v8.2.1)
|
package/index.js
CHANGED
|
@@ -121,7 +121,7 @@ module.exports = {
|
|
|
121
121
|
},
|
|
122
122
|
overrides: [
|
|
123
123
|
{
|
|
124
|
-
files: ['**/*.ts'],
|
|
124
|
+
files: ['**/*.ts', '**/*.tsx'],
|
|
125
125
|
extends: [
|
|
126
126
|
'@vue/eslint-config-typescript/recommended',
|
|
127
127
|
'plugin:import/typescript',
|
|
@@ -148,7 +148,7 @@ module.exports = {
|
|
|
148
148
|
'import/resolver': {
|
|
149
149
|
node: {
|
|
150
150
|
paths: ['src'],
|
|
151
|
-
extensions: ['.js', '.ts', '.vue'],
|
|
151
|
+
extensions: ['.(m|c)?js', '.ts', '.tsx', '.vue'],
|
|
152
152
|
},
|
|
153
153
|
},
|
|
154
154
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextcloud/eslint-config",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.3.0-beta.0",
|
|
4
4
|
"description": "Eslint shared config for nextcloud vue.js apps",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"lint": "eslint -c index.js *.js",
|
|
12
|
-
"lint:fix": "eslint -c index.js --fix *.js"
|
|
12
|
+
"lint:fix": "eslint -c index.js --fix *.js",
|
|
13
|
+
"test": "jest"
|
|
13
14
|
},
|
|
14
15
|
"peerDependencies": {
|
|
15
16
|
"@babel/core": "^7.13.10",
|
|
@@ -20,27 +21,30 @@
|
|
|
20
21
|
"eslint-config-standard": "^17.0.0",
|
|
21
22
|
"eslint-import-resolver-exports": "^1.0.0-beta.4",
|
|
22
23
|
"eslint-plugin-import": "^2.26.0",
|
|
23
|
-
"eslint-plugin-jsdoc": "^
|
|
24
|
+
"eslint-plugin-jsdoc": "^43.0.3",
|
|
24
25
|
"eslint-plugin-n": "^15.5.1",
|
|
25
26
|
"eslint-plugin-promise": "^6.1.1",
|
|
26
27
|
"eslint-plugin-vue": "^9.7.0",
|
|
27
|
-
"typescript": "^
|
|
28
|
+
"typescript": "^5.0.2",
|
|
28
29
|
"webpack": "^5.4.0"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
31
32
|
"@babel/core": "^7.13.10",
|
|
32
33
|
"@babel/eslint-parser": "^7.16.5",
|
|
33
34
|
"@nextcloud/eslint-plugin": "^2.0.0",
|
|
35
|
+
"@types/jest": "^29.4.0",
|
|
34
36
|
"@vue/eslint-config-typescript": "^11.0.2",
|
|
35
37
|
"eslint": "^8.27.0",
|
|
36
|
-
"eslint-import-resolver-exports": "^1.0.0-beta.4",
|
|
37
38
|
"eslint-config-standard": "^17.0.0",
|
|
39
|
+
"eslint-import-resolver-exports": "^1.0.0-beta.4",
|
|
38
40
|
"eslint-plugin-import": "^2.26.0",
|
|
39
|
-
"eslint-plugin-jsdoc": "^
|
|
41
|
+
"eslint-plugin-jsdoc": "^43.0.3",
|
|
40
42
|
"eslint-plugin-n": "^15.5.1",
|
|
41
43
|
"eslint-plugin-promise": "^6.1.1",
|
|
42
44
|
"eslint-plugin-vue": "^9.7.0",
|
|
43
|
-
"
|
|
45
|
+
"jest": "^29.4.1",
|
|
46
|
+
"ts-jest": "^29.0.5",
|
|
47
|
+
"typescript": "^5.0.2",
|
|
44
48
|
"webpack": "^5.4.0"
|
|
45
49
|
},
|
|
46
50
|
"keywords": [
|
|
@@ -59,5 +63,12 @@
|
|
|
59
63
|
"engines": {
|
|
60
64
|
"node": "^16.0.0",
|
|
61
65
|
"npm": "^7.0.0 || ^8.0.0"
|
|
66
|
+
},
|
|
67
|
+
"jest": {
|
|
68
|
+
"preset": "ts-jest",
|
|
69
|
+
"testEnvironment": "node",
|
|
70
|
+
"setupFilesAfterEnv": [
|
|
71
|
+
"./tests/setup-jest.ts"
|
|
72
|
+
]
|
|
62
73
|
}
|
|
63
74
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ESLint } from "eslint"
|
|
2
|
+
import type { Linter } from "eslint"
|
|
3
|
+
import * as path from 'path'
|
|
4
|
+
import * as eslintConfig from '../index.js'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const eslint = new ESLint({
|
|
8
|
+
baseConfig: eslintConfig as unknown as Linter.Config<Linter.RulesRecord>
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const lintFile = async (file) => {
|
|
12
|
+
const real = path.resolve(path.join(__dirname, file))
|
|
13
|
+
return await eslint.lintFiles(real)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
test('some basic issues should fail', async () => {
|
|
17
|
+
const results = await lintFile('fixtures/example-fail.js')
|
|
18
|
+
expect(results).toHaveIssueCount(3)
|
|
19
|
+
expect(results).toHaveIssue('spaced-comment')
|
|
20
|
+
expect(results).toHaveIssue({ ruleId: 'no-console', line: 3 })
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
test('TSX is linted', async () => {
|
|
24
|
+
const ignored = await eslint.isPathIgnored('./fixtures/some.tsx')
|
|
25
|
+
expect(ignored).toBe(false)
|
|
26
|
+
|
|
27
|
+
const results = await lintFile('fixtures/some.tsx')
|
|
28
|
+
expect(results).toHaveIssue({ruleId: 'jsdoc/check-tag-names', line: 5})
|
|
29
|
+
expect(results).toHaveIssue({ruleId: '@typescript-eslint/no-unused-vars', line: 7})
|
|
30
|
+
expect(results).toHaveIssueCount(2)
|
|
31
|
+
})
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { ESLint, Linter } from "eslint"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Add some custom matchers for ESLint to jest
|
|
5
|
+
*/
|
|
6
|
+
expect.extend({
|
|
7
|
+
toPass: assertLintingPassed,
|
|
8
|
+
toHaveIssueCount: assertHavingNIssues,
|
|
9
|
+
toHaveIssue: assertHavingIssue
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Check if linting a file did not throw any errors or warnings
|
|
14
|
+
*
|
|
15
|
+
* @param received Lint result
|
|
16
|
+
*/
|
|
17
|
+
function hasNoIssues(received: ESLint.LintResult) {
|
|
18
|
+
// dirty type check
|
|
19
|
+
if (received?.errorCount === undefined) throw new Error('Expected ESLintResult')
|
|
20
|
+
|
|
21
|
+
return received.errorCount === 0 && received.warningCount === 0
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Check if linting of multiple fils
|
|
26
|
+
*
|
|
27
|
+
* @param received
|
|
28
|
+
* @returns {}
|
|
29
|
+
*/
|
|
30
|
+
function assertLintingPassed(received: ESLint.LintResult | ESLint.LintResult[]) {
|
|
31
|
+
// allow single ESLintResult
|
|
32
|
+
if (!Array.isArray(received)) {
|
|
33
|
+
received = [received]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const errors = [] as {file: string, errors: Linter.LintMessage[]}[]
|
|
37
|
+
const pass = received.every((result) => {
|
|
38
|
+
// save issues
|
|
39
|
+
errors.push({file: result.filePath, errors: result.messages})
|
|
40
|
+
return hasNoIssues(result)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
pass,
|
|
45
|
+
message: () => {
|
|
46
|
+
if (pass) {
|
|
47
|
+
return 'Expected file to not pass eslint, but got no issues'
|
|
48
|
+
} else {
|
|
49
|
+
const errorMessages = errors.map((m) =>
|
|
50
|
+
`file: ${m.file}\n` + m.errors.map((e) => 'line: ' + e.line + ': ' + (e.ruleId || e.message))
|
|
51
|
+
)
|
|
52
|
+
return 'Expected file to pass eslint, got issues:\n' + errorMessages.join('\n')
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Count the total amount of issues
|
|
60
|
+
*
|
|
61
|
+
* @param received lint result
|
|
62
|
+
* @returns total amount of issues
|
|
63
|
+
*/
|
|
64
|
+
function countIssues(received: ESLint.LintResult) {
|
|
65
|
+
return received.errorCount + received.warningCount
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Check if exactly the same number of issues is reported
|
|
70
|
+
*
|
|
71
|
+
* @param received the lint result
|
|
72
|
+
* @param expected number of expected issues
|
|
73
|
+
* @returns jest matcher result
|
|
74
|
+
*/
|
|
75
|
+
function assertHavingNIssues(received: ESLint.LintResult | ESLint.LintResult[], expected: number) {
|
|
76
|
+
if (!(typeof expected === 'number')) throw new Error('Expected a number as expected value')
|
|
77
|
+
|
|
78
|
+
if (!Array.isArray(received)) {
|
|
79
|
+
received = [received]
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const issues = received.map(countIssues).reduce((p, c) => p + c)
|
|
83
|
+
const pass = issues === expected
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
pass,
|
|
87
|
+
message: () => pass ? `Expected not to find exactly ${expected} issues.` : `Expected ${expected} issues, found ${issues}`
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Check if result contains the expected issue
|
|
93
|
+
*
|
|
94
|
+
* @param received the lint result
|
|
95
|
+
* @param issue the expected issue
|
|
96
|
+
* @returns jest matcher result
|
|
97
|
+
*/
|
|
98
|
+
function assertHavingIssue(received: ESLint.LintResult | ESLint.LintResult[], issue: string | {ruleId: string, line?: number}) {
|
|
99
|
+
if (!Array.isArray(received)) {
|
|
100
|
+
received = [received]
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Should not pass
|
|
104
|
+
if (assertLintingPassed(received).pass) {
|
|
105
|
+
return {
|
|
106
|
+
pass: false,
|
|
107
|
+
message: () => 'Expected issue, but no linting issues found.'
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const name = typeof issue === 'string' ? issue : issue.ruleId
|
|
112
|
+
const result = received.some((result) => {
|
|
113
|
+
return result.messages.some((message) => {
|
|
114
|
+
// ensure name matches
|
|
115
|
+
if (message.ruleId !== name) return false
|
|
116
|
+
// if line is requested ignore not matching ones
|
|
117
|
+
if (typeof issue === 'object' && issue.line !== undefined && issue.line !== message.line) return false
|
|
118
|
+
// otherwise matched
|
|
119
|
+
return true
|
|
120
|
+
})
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
const onLine = typeof issue === 'string' ? '' : ` on line ${issue.line}`
|
|
124
|
+
return {
|
|
125
|
+
pass: result,
|
|
126
|
+
message: () => result ? `Unexpected error '${name}'${onLine} found.` : `Expected error '${name}'${onLine} not found.`
|
|
127
|
+
}
|
|
128
|
+
}
|