eslint-plugin-smarthr 0.5.20 → 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.
- package/CHANGELOG.md +11 -0
- package/index.js +9 -5
- package/package.json +10 -7
- package/rules/a11y-prohibit-sectioning-content-in-form/index.js +1 -1
- package/rules/format-import-path/index.js +2 -2
- package/rules/jsx-start-with-spread-attributes/index.js +3 -4
- package/rules/prohibit-file-name/index.js +2 -3
- package/rules/prohibit-import/index.js +2 -3
- package/rules/require-barrel-import/index.js +3 -4
- package/rules/require-declaration/index.js +3 -4
- package/rules/require-export/index.js +1 -2
- package/rules/require-import/index.js +3 -4
- package/test/a11y-anchor-has-href-attribute.js +5 -7
- package/test/a11y-clickable-element-has-text.js +5 -8
- package/test/a11y-delegate-element-has-role-presantation.js +6 -7
- package/test/a11y-form-control-in-form.js +5 -7
- package/test/a11y-heading-in-sectioning-content.js +6 -7
- package/test/a11y-image-has-alt-attribute.js +5 -7
- package/test/a11y-input-has-name-attribute.js +6 -7
- package/test/a11y-input-in-form-control.js +5 -7
- package/test/a11y-numbered-text-within-ol.js +5 -7
- package/test/a11y-prohhibit-input-placeholder.js +5 -7
- package/test/a11y-prohibit-input-maxlength-attribute.js +5 -7
- package/test/a11y-prohibit-useless-sectioning-fragment.js +5 -7
- package/test/a11y-replace-unreadable-symbol.js +5 -6
- package/test/a11y-trigger-has-button.js +5 -7
- package/test/best-practice-for-button-element.js +5 -7
- package/test/best-practice-for-data-test-attribute.js +5 -7
- package/test/best-practice-for-date.js +5 -7
- package/test/best-practice-for-layouts.js +5 -7
- package/test/best-practice-for-remote-trigger-dialog.js +5 -7
- package/test/design-system-guideline-prohibit-double-icons.js +5 -7
- package/test/format-translate-component.js +5 -7
- package/test/prohibit-file-name.js +6 -3
- package/test/prohibit-import.js +6 -3
- package/test/prohibit-path-within-template-literal.js +6 -3
- package/test/require-declaration.js +5 -7
- package/test/require-export.js +6 -3
- package/test/require-import.js +6 -3
- package/test/trim-props.js +5 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [1.0.0](https://github.com/kufu/eslint-plugin-smarthr/compare/v0.5.20...v1.0.0) (2024-12-12)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ⚠ BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
ESLint v9 及び FlatConfig への対応をしました。
|
|
11
|
+
|
|
12
|
+
これにともない、ESLint v8 以下及び LegacyConfig では利用できなくなりました。
|
|
13
|
+
|
|
14
|
+
* ESLint v9 ([#154](https://github.com/kufu/eslint-plugin-smarthr/issues/154)) ([a0b79fd](https://github.com/kufu/eslint-plugin-smarthr/commit/a0b79fd39fcab103008f9a257fb29d7d0e9c662b))
|
|
15
|
+
|
|
5
16
|
### [0.5.20](https://github.com/kufu/eslint-plugin-smarthr/compare/v0.5.18...v0.5.20) (2024-11-25)
|
|
6
17
|
|
|
7
18
|
|
package/index.js
CHANGED
|
@@ -5,12 +5,16 @@ const path = require('path');
|
|
|
5
5
|
|
|
6
6
|
const rules = generateRulesMap();
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* @type {import('eslint').Linter.Config}
|
|
10
|
+
*/
|
|
8
11
|
module.exports = {
|
|
9
|
-
|
|
10
|
-
recommended: generateRecommendedConfig(rules),
|
|
11
|
-
},
|
|
12
|
+
name: 'eslint-plugin-smarthr',
|
|
12
13
|
rules,
|
|
13
|
-
|
|
14
|
+
plugins: {
|
|
15
|
+
recommended: generateRecommendedConfig(rules),
|
|
16
|
+
}
|
|
17
|
+
}
|
|
14
18
|
|
|
15
19
|
function generateRulesMap() {
|
|
16
20
|
let rulesPath = path.join(__dirname, 'rules');
|
|
@@ -25,7 +29,7 @@ function generateRulesMap() {
|
|
|
25
29
|
|
|
26
30
|
function generateRecommendedConfig(rules) {
|
|
27
31
|
let config = {
|
|
28
|
-
|
|
32
|
+
name: 'eslint-plugin-smarthr/recommended',
|
|
29
33
|
rules: {},
|
|
30
34
|
};
|
|
31
35
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-smarthr",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"author": "SmartHR",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "A sharable ESLint plugin for SmartHR",
|
|
7
7
|
"main": "index.js",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=20.9.0"
|
|
10
|
+
},
|
|
8
11
|
"scripts": {
|
|
9
12
|
"test": "jest",
|
|
10
13
|
"release:dryrun": "standard-version --dry-run",
|
|
@@ -22,16 +25,16 @@
|
|
|
22
25
|
"url": "https://github.com/kufu/eslint-plugin-smarthr/issues"
|
|
23
26
|
},
|
|
24
27
|
"dependencies": {
|
|
25
|
-
"json5": "^2.2.
|
|
28
|
+
"json5": "^2.2.3"
|
|
26
29
|
},
|
|
27
30
|
"devDependencies": {
|
|
28
|
-
"eslint": "^
|
|
29
|
-
"jest": "^
|
|
30
|
-
"standard-version": "^9.
|
|
31
|
-
"typescript-eslint": "^
|
|
31
|
+
"eslint": "^9.15.0",
|
|
32
|
+
"jest": "^29.7.0",
|
|
33
|
+
"standard-version": "^9.5.0",
|
|
34
|
+
"typescript-eslint": "^8.14.0"
|
|
32
35
|
},
|
|
33
36
|
"peerDependencies": {
|
|
34
|
-
"eslint": "^
|
|
37
|
+
"eslint": "^9"
|
|
35
38
|
},
|
|
36
39
|
"keywords": [
|
|
37
40
|
"eslint",
|
|
@@ -141,7 +141,7 @@ module.exports = {
|
|
|
141
141
|
schema: [],
|
|
142
142
|
},
|
|
143
143
|
create(context) {
|
|
144
|
-
const filenames = context.
|
|
144
|
+
const filenames = context.filename.replace(rootPathSlashed, '').replace(extRegex, '').split('/')
|
|
145
145
|
const isInnerForm = filenames.some(includeWrapper)
|
|
146
146
|
const notified = []
|
|
147
147
|
|
|
@@ -125,12 +125,12 @@ module.exports = {
|
|
|
125
125
|
message: `${fixedImportPath} に修正してください`,
|
|
126
126
|
fix: (fixer) => fixer.replaceText(
|
|
127
127
|
node,
|
|
128
|
-
context.
|
|
128
|
+
context.sourceCode.getText(node).replace(new RegExp(`from '${importPath}'$`), `from '${fixedImportPath}'`)
|
|
129
129
|
),
|
|
130
130
|
})
|
|
131
131
|
}
|
|
132
132
|
},
|
|
133
|
-
}
|
|
133
|
+
};
|
|
134
134
|
},
|
|
135
135
|
}
|
|
136
136
|
module.exports.schema = SCHEMA
|
|
@@ -35,8 +35,7 @@ module.exports = {
|
|
|
35
35
|
|
|
36
36
|
if (insertIndex >= 0) {
|
|
37
37
|
const option = context.options[0]
|
|
38
|
-
const
|
|
39
|
-
const attributeCode = sourceCode.getText(node)
|
|
38
|
+
const attributeCode = context.sourceCode.getText(node)
|
|
40
39
|
|
|
41
40
|
context.report({
|
|
42
41
|
node,
|
|
@@ -49,7 +48,7 @@ module.exports = {
|
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
if (a !== node) {
|
|
52
|
-
p = [...p, sourceCode.getText(a)]
|
|
51
|
+
p = [...p, context.sourceCode.getText(a)]
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
return p
|
|
@@ -63,7 +62,7 @@ module.exports = {
|
|
|
63
62
|
});
|
|
64
63
|
}
|
|
65
64
|
},
|
|
66
|
-
}
|
|
65
|
+
};
|
|
67
66
|
},
|
|
68
67
|
}
|
|
69
68
|
module.exports.schema = SCHEMA
|
|
@@ -19,8 +19,7 @@ module.exports = {
|
|
|
19
19
|
},
|
|
20
20
|
create(context) {
|
|
21
21
|
const options = context.options[0]
|
|
22
|
-
const
|
|
23
|
-
const targetPaths = Object.keys(options).filter((regex) => !!filename.match(new RegExp(regex)))
|
|
22
|
+
const targetPaths = Object.keys(options).filter((regex) => !!context.filename.match(new RegExp(regex)))
|
|
24
23
|
|
|
25
24
|
|
|
26
25
|
if (targetPaths.length === 0) {
|
|
@@ -32,7 +31,7 @@ module.exports = {
|
|
|
32
31
|
targetPaths.forEach((path) => {
|
|
33
32
|
const message = options[path]
|
|
34
33
|
|
|
35
|
-
matcher = filename.match(new RegExp(path))
|
|
34
|
+
matcher = context.filename.match(new RegExp(path))
|
|
36
35
|
|
|
37
36
|
if (matcher) {
|
|
38
37
|
messages.push([...matcher].reduce(((prev, k, index) => prev.replaceAll(`\$${index}`, k)), message))
|
|
@@ -42,15 +42,14 @@ module.exports = {
|
|
|
42
42
|
},
|
|
43
43
|
create(context) {
|
|
44
44
|
const options = context.options[0]
|
|
45
|
-
const filename = context.getFilename()
|
|
46
45
|
const parentDir = (() => {
|
|
47
|
-
const dir = filename.match(/^(.+?)\..+?$/)[1].split('/')
|
|
46
|
+
const dir = context.filename.match(/^(.+?)\..+?$/)[1].split('/')
|
|
48
47
|
dir.pop()
|
|
49
48
|
|
|
50
49
|
return dir.join('/')
|
|
51
50
|
})()
|
|
52
51
|
const targetPathRegexs = Object.keys(options)
|
|
53
|
-
const targetProhibits = targetPathRegexs.filter((regex) => !!filename.match(new RegExp(regex)))
|
|
52
|
+
const targetProhibits = targetPathRegexs.filter((regex) => !!context.filename.match(new RegExp(regex)))
|
|
54
53
|
|
|
55
54
|
if (targetProhibits.length === 0) {
|
|
56
55
|
return {}
|
|
@@ -93,17 +93,16 @@ module.exports = {
|
|
|
93
93
|
},
|
|
94
94
|
create(context) {
|
|
95
95
|
const option = context.options[0] || {}
|
|
96
|
-
const filename = context.getFilename()
|
|
97
96
|
|
|
98
|
-
if (option.ignores && option.ignores.some((i) => !!filename.match(new RegExp(i)))) {
|
|
97
|
+
if (option.ignores && option.ignores.some((i) => !!context.filename.match(new RegExp(i)))) {
|
|
99
98
|
return {}
|
|
100
99
|
}
|
|
101
100
|
|
|
102
|
-
let d = filename.split('/')
|
|
101
|
+
let d = context.filename.split('/')
|
|
103
102
|
d.pop()
|
|
104
103
|
const dir = d.join('/')
|
|
105
104
|
const targetPathRegexs = Object.keys(option?.allowedImports || {})
|
|
106
|
-
const targetAllowedImports = targetPathRegexs.filter((regex) => !!filename.match(new RegExp(regex)))
|
|
105
|
+
const targetAllowedImports = targetPathRegexs.filter((regex) => !!context.filename.match(new RegExp(regex)))
|
|
107
106
|
|
|
108
107
|
return {
|
|
109
108
|
ImportDeclaration: (node) => {
|
|
@@ -50,9 +50,8 @@ module.exports = {
|
|
|
50
50
|
},
|
|
51
51
|
create(context) {
|
|
52
52
|
const options = context.options[0]
|
|
53
|
-
const filename = context.getFilename()
|
|
54
53
|
const targetPathRegexs = Object.keys(options)
|
|
55
|
-
const targetRequires = targetPathRegexs.filter((regex) => !!filename.match(new RegExp(regex)))
|
|
54
|
+
const targetRequires = targetPathRegexs.filter((regex) => !!context.filename.match(new RegExp(regex)))
|
|
56
55
|
|
|
57
56
|
if (targetRequires.length === 0) {
|
|
58
57
|
return {}
|
|
@@ -105,7 +104,7 @@ module.exports = {
|
|
|
105
104
|
message: localOption.reportMessage || `${localOption.type} ${requireDeclaration}が宣言されていません`,
|
|
106
105
|
})
|
|
107
106
|
} else if (localOption.use) {
|
|
108
|
-
const code = context.
|
|
107
|
+
const code = context.sourceCode.getText(hit)
|
|
109
108
|
let reported = false
|
|
110
109
|
|
|
111
110
|
localOption.use.forEach((u) => {
|
|
@@ -121,7 +120,7 @@ module.exports = {
|
|
|
121
120
|
})
|
|
122
121
|
})
|
|
123
122
|
},
|
|
124
|
-
}
|
|
123
|
+
};
|
|
125
124
|
},
|
|
126
125
|
}
|
|
127
126
|
|
|
@@ -30,9 +30,8 @@ module.exports = {
|
|
|
30
30
|
},
|
|
31
31
|
create(context) {
|
|
32
32
|
const options = context.options[0]
|
|
33
|
-
const filename = context.getFilename()
|
|
34
33
|
const targetPathRegexs = Object.keys(options)
|
|
35
|
-
const targetRequires = targetPathRegexs.filter((regex) => !!filename.match(new RegExp(regex)))
|
|
34
|
+
const targetRequires = targetPathRegexs.filter((regex) => !!context.filename.match(new RegExp(regex)))
|
|
36
35
|
|
|
37
36
|
if (targetRequires.length === 0) {
|
|
38
37
|
return {}
|
|
@@ -42,9 +42,8 @@ module.exports = {
|
|
|
42
42
|
},
|
|
43
43
|
create(context) {
|
|
44
44
|
const options = context.options[0]
|
|
45
|
-
const filename = context.getFilename()
|
|
46
45
|
const targetPathRegexs = Object.keys(options)
|
|
47
|
-
const targetRequires = targetPathRegexs.filter((regex) => !!filename.match(new RegExp(regex)))
|
|
46
|
+
const targetRequires = targetPathRegexs.filter((regex) => !!context.filename.match(new RegExp(regex)))
|
|
48
47
|
|
|
49
48
|
if (targetRequires.length === 0) {
|
|
50
49
|
return {}
|
|
@@ -54,7 +53,7 @@ module.exports = {
|
|
|
54
53
|
Program: (node) => {
|
|
55
54
|
const importDeclarations = node.body.filter((item) => item.type === 'ImportDeclaration')
|
|
56
55
|
const parentDir = (() => {
|
|
57
|
-
const dir = filename.match(/^(.+?)\..+?$/)[1].split('/')
|
|
56
|
+
const dir = context.filename.match(/^(.+?)\..+?$/)[1].split('/')
|
|
58
57
|
dir.pop()
|
|
59
58
|
|
|
60
59
|
return dir.join('/')
|
|
@@ -66,7 +65,7 @@ module.exports = {
|
|
|
66
65
|
Object.keys(option).forEach((targetModule) => {
|
|
67
66
|
const { imported, reportMessage, targetRegex } = Object.assign({imported: true}, option[targetModule])
|
|
68
67
|
|
|
69
|
-
if (targetRegex && !filename.match(new RegExp(targetRegex))) {
|
|
68
|
+
if (targetRegex && !context.filename.match(new RegExp(targetRegex))) {
|
|
70
69
|
return
|
|
71
70
|
}
|
|
72
71
|
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/a11y-anchor-has-href-attribute')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const generateErrorText = (name) => `${name} に href 属性を正しく設定してください
|
|
16
14
|
- onClickなどでページ遷移する場合でもhref属性に遷移先のURIを設定してください
|
|
17
15
|
- Cmd + clickなどのキーボードショートカットに対応出来ます
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/a11y-clickable-element-has-text')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const defaultErrorMessage = `a, buttonなどのクリッカブルな要素内にはテキストを設定してください
|
|
16
14
|
- 要素内にアイコン、画像のみを設置する場合はaltなどの代替テキスト用属性を指定してください
|
|
17
15
|
- SVG component の場合、altを属性として受け取れるようにした上で '<svg role="img" aria-label={alt}>' のように指定してください
|
|
@@ -149,7 +147,6 @@ ruleTester.run('a11y-clickable-element-has-text', rule, {
|
|
|
149
147
|
{ code: 'const Hoge = styled(Link)``', errors: [ { message: `Hogeを正規表現 "/Link$/" がmatchする名称に変更してください。` } ] },
|
|
150
148
|
{ code: 'const Hoge = styled(Button)``', errors: [ { message: `Hogeを正規表現 "/Button$/" がmatchする名称に変更してください。` } ] },
|
|
151
149
|
{ code: 'const Fuga = styled(HogeAnchor)``', errors: [ { message: `Fugaを正規表現 "/Anchor$/" がmatchする名称に変更してください。` } ] },
|
|
152
|
-
{ code: 'const Fuga = styled(HogeAnchor)``', errors: [ { message: `Fugaを正規表現 "/Anchor$/" がmatchする名称に変更してください。` } ] },
|
|
153
150
|
{ code: 'const Fuga = styled(SmartHRLogo)``', errors: [ { message: `Fugaを正規表現 "/SmartHRLogo$/" がmatchする名称に変更してください。` } ] },
|
|
154
151
|
{ code: 'const Piyo = styled.a(() => ``)', errors: [ { message: `Piyoを正規表現 "/(Anchor|Link)$/" がmatchする名称に変更してください。` } ] },
|
|
155
152
|
{ code: 'const Piyo = styled("a")(() => ``)', errors: [ { message: `Piyoを正規表現 "/(Anchor|Link)$/" がmatchする名称に変更してください。` } ] },
|
|
@@ -2,15 +2,14 @@ const rule = require('../rules/a11y-delegate-element-has-role-presentation');
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester;
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
|
-
})
|
|
12
|
+
})
|
|
14
13
|
|
|
15
14
|
const defaultInteractiveRegex = '/((i|I)nput$|(t|T)extarea$|(s|S)elect$|InputFile$|RadioButtonPanel$|Check(b|B)ox$|Combo(b|B)ox$|DatePicker$|TimePicker$|DropZone$|Switch$|SegmentedControl$|RightFixedNote$|FieldSet$|Fieldset$|FormControl$|FormGroup$|(b|B)utton$|Anchor$|Link$|TabItem$|^a$|(f|F)orm$|ActionDialogWithTrigger$|RemoteDialogTrigger$|RemoteTrigger(.+)Dialog$|FormDialog$|Pagination$|SideNav$|AccordionPanel$|FilterDropdown$)/'
|
|
16
15
|
const messageNonInteractiveEventHandler = (nodeName, onAttrs, interactiveComponentRegex = defaultInteractiveRegex) => {
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/a11y-form-control-in-form')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const generateErrorText = (elementName) => `${elementName}をform要素で囲むようにマークアップしてください。
|
|
16
14
|
- form要素で囲むことでスクリーンリーダーに入力フォームであることが正しく伝わる、入力要素にfocusした状態でEnterを押せばsubmitできる、inputのpattern属性を利用できるなどのメリットがあります
|
|
17
15
|
- 以下のいずれかの方法で修正をおこなってください
|
|
@@ -2,15 +2,14 @@ const rule = require('../rules/a11y-heading-in-sectioning-content');
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester;
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
|
-
})
|
|
12
|
+
})
|
|
14
13
|
|
|
15
14
|
const lowerMessage = `smarthr-ui/Headingと紐づく内容の範囲(アウトライン)が曖昧になっています。
|
|
16
15
|
- smarthr-uiのArticle, Aside, Nav, SectionのいずれかでHeadingコンポーネントと内容をラップしてHeadingに対応する範囲を明確に指定してください。`
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/a11y-image-has-alt-attribute')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const messageNotExistAlt = `画像にはalt属性を指定してください。
|
|
16
14
|
- コンポーネントが画像ではない場合、img or image を末尾に持たない名称に変更してください。
|
|
17
15
|
- ボタンやリンクの先頭・末尾などに設置するアイコンとしての役割を持つ画像の場合、コンポーネント名の末尾を "Icon" に変更してください。
|
|
@@ -2,15 +2,14 @@ const rule = require('../rules/a11y-input-has-name-attribute');
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester;
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
|
-
})
|
|
12
|
+
})
|
|
14
13
|
|
|
15
14
|
const MESSAGE_SUFFIX = `
|
|
16
15
|
- ブラウザの自動補完が有効化されるなどのメリットがあります
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/a11y-input-in-form-control')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const noLabeledInput = (name) => `${name} を、smarthr-ui/FormControl もしくはそれを拡張したコンポーネントが囲むようマークアップを変更してください。
|
|
16
14
|
- FormControlで入力要素を囲むことでラベルと入力要素が適切に紐づき、操作性が高まります
|
|
17
15
|
- ${name}が入力要素とラベル・タイトル・説明など含む概念を表示するコンポーネントの場合、コンポーネント名を/((FormGroup)$|(FormControl)$|((F|^f)ieldset)$)/とマッチするように修正してください
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/a11y-numbered-text-within-ol')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
ruleTester.run('a11y-numbered-text-within-ol', rule, {
|
|
16
14
|
valid: [
|
|
17
15
|
{ code: `const HogeOrderedFugaList = styled.ol` },
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/a11y-prohibit-input-placeholder')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
ruleTester.run('a11y-prohibit-input-placeholder', rule, {
|
|
16
14
|
valid: [
|
|
17
15
|
{ code: `import styled from 'styled-components'` },
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/a11y-prohibit-input-maxlength-attribute')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const expectedErrorMessage = (elName) => `${elName}にmaxLength属性を設定しないでください。
|
|
16
14
|
- maxLength属性がついた要素に、テキストをペーストすると、maxLength属性の値を超えた範囲が意図せず切り捨てられてしまう場合があります
|
|
17
15
|
- 以下のいずれかの方法で修正をおこなってください
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/a11y-prohibit-useless-sectioning-fragment')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const error = (tag) => `無意味なSectioningFragmentが記述されています。子要素である${tag}で問題なくセクションは設定されているため、このSectioningFragmentは削除してください`
|
|
16
14
|
|
|
17
15
|
ruleTester.run('a11y-prohibit-useless-sectioning-fragment', rule, {
|
|
@@ -7,13 +7,12 @@ const generateErrorText = (symbol, replaced, read) => `"${symbol}"はスクリ
|
|
|
7
7
|
- 前後の文脈などで "${read}" と読まれることが不適切な場合 \`<RangeSeparator decorators={{ visuallyHiddenText: () => "ANY" }} />\` のようにdecoratorsを指定してください`
|
|
8
8
|
|
|
9
9
|
const ruleTester = new RuleTester({
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
languageOptions: {
|
|
11
|
+
parserOptions: {
|
|
12
|
+
ecmaFeatures: {
|
|
13
|
+
jsx: true,
|
|
14
|
+
},
|
|
15
15
|
},
|
|
16
|
-
sourceType: 'module',
|
|
17
16
|
},
|
|
18
17
|
})
|
|
19
18
|
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/a11y-trigger-has-button')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
ruleTester.run('a11y-trigger-has-button', rule, {
|
|
16
14
|
valid: [
|
|
17
15
|
{ code: `import styled from 'styled-components'` },
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/best-practice-for-button-element')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const ERRORMESSAGE_REQUIRED_TYPE_ATTR = `button要素を利用する場合、type属性に "button" もしくは "submit" を指定してください
|
|
16
14
|
- button要素のtype属性のデフォルトは "submit" のため、button要素がformでラップされていると意図しないsubmitを引き起こす可能性があります
|
|
17
15
|
- smarthr-ui/Button, smarthr-ui/UnstyledButtonのtype属性のデフォルトは "button" になっているため、buttonから置き換えることをおすすめします`
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/best-practice-for-data-test-attribute')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const generateErrorMessage = (attr) => `テストのために要素を指定するために、${attr} 属性を利用するのではなく、他の方法で要素を指定することを検討してください。
|
|
16
14
|
- 方法1: click_link, click_button等を利用したりすることで、利用しているテスト環境に準じた方法で要素を指定することを検討してください。
|
|
17
15
|
- 参考(Testing Library): https://testing-library.com/docs/queries/about
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/best-practice-for-date')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const errorNewDate = `'new Date(arg)' のように引数を一つだけ指定したDate instanceの生成は実行環境によって結果が異なるため、以下のいずれかの方法に変更してください
|
|
16
14
|
- 'new Date(2022, 12 - 1, 31)' のように数値を個別に指定する
|
|
17
15
|
- dayjsなど、日付系ライブラリを利用する (例: 'dayjs(arg).toDate()')`
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/best-practice-for-layouts')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const errorMessage = (type, name) => `${name}には子要素が一つしか無いため、${type}でマークアップする意味がありません。
|
|
16
14
|
- styleを確認し、div・spanなど、別要素でマークアップし直すか、${name}を削除してください
|
|
17
15
|
- as, forwardedAsなどでSectioningContent系要素に変更している場合、対応するsmarthr-ui/Section, Aside, Nav, Article のいずれかに差し替えてください`
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/best-practice-for-remote-trigger-dialog')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
ruleTester.run('best-practice-for-remote-trigger-dialog', rule, {
|
|
16
14
|
valid: [
|
|
17
15
|
{ code: `import styled from 'styled-components'` },
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/design-system-guideline-prohibit-double-icons')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const generateErrorText = (name) => `${name} には prefix と suffix は同時に設定できません。
|
|
16
14
|
- prefix または suffix のみを設定してください。
|
|
17
15
|
- どちらにもアイコンをつけられそうな場合は、アイコン付き(右)(サフィックス)を優先し、アイコン付き(左)(プレフィックス)には指定しないでください。
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/format-translate-component')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const options = [
|
|
16
14
|
{
|
|
17
15
|
componentPath: '@/any/path/Translate',
|
|
@@ -2,9 +2,12 @@ const rule = require('../rules/prohibit-file-name')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
|
+
},
|
|
8
11
|
},
|
|
9
12
|
})
|
|
10
13
|
|
package/test/prohibit-import.js
CHANGED
|
@@ -2,9 +2,12 @@ const rule = require('../rules/prohibit-import')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
|
+
},
|
|
8
11
|
},
|
|
9
12
|
})
|
|
10
13
|
|
|
@@ -2,9 +2,12 @@ const rule = require('../rules/prohibit-path-within-template-literal')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
|
+
},
|
|
8
11
|
},
|
|
9
12
|
})
|
|
10
13
|
|
|
@@ -2,16 +2,14 @@ const rule = require('../rules/require-declaration')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
10
|
},
|
|
11
|
-
sourceType: 'module',
|
|
12
11
|
},
|
|
13
12
|
})
|
|
14
|
-
|
|
15
13
|
const options = [
|
|
16
14
|
{
|
|
17
15
|
'^.+$': {
|
package/test/require-export.js
CHANGED
|
@@ -2,9 +2,12 @@ const rule = require('../rules/require-export')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
|
+
},
|
|
8
11
|
},
|
|
9
12
|
})
|
|
10
13
|
|
package/test/require-import.js
CHANGED
|
@@ -2,9 +2,12 @@ const rule = require('../rules/require-import')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
10
|
+
},
|
|
8
11
|
},
|
|
9
12
|
})
|
|
10
13
|
|
package/test/trim-props.js
CHANGED
|
@@ -2,9 +2,11 @@ const rule = require('../rules/trim-props')
|
|
|
2
2
|
const RuleTester = require('eslint').RuleTester
|
|
3
3
|
|
|
4
4
|
const ruleTester = new RuleTester({
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
languageOptions: {
|
|
6
|
+
parserOptions: {
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
jsx: true,
|
|
9
|
+
},
|
|
8
10
|
},
|
|
9
11
|
},
|
|
10
12
|
})
|