eslint-plugin-smarthr 0.2.0 → 0.2.1
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 +7 -0
- package/README.md +15 -574
- package/index.js +3 -6
- package/package.json +1 -1
- package/rules/a11y-clickable-element-has-text/README.md +61 -0
- package/rules/{a11y-clickable-element-has-text.js → a11y-clickable-element-has-text/index.js} +1 -1
- package/rules/a11y-image-has-alt-attribute/README.md +55 -0
- package/rules/{a11y-image-has-alt-attribute.js → a11y-image-has-alt-attribute/index.js} +1 -1
- package/rules/a11y-trigger-has-button/README.md +57 -0
- package/rules/{a11y-trigger-has-button.js → a11y-trigger-has-button/index.js} +1 -1
- package/rules/best-practice-for-date/README.md +40 -0
- package/rules/best-practice-for-date/index.js +42 -0
- package/rules/format-import-path/README.md +99 -0
- package/rules/{format-import-path.js → format-import-path/index.js} +2 -2
- package/rules/format-translate-component/README.md +58 -0
- package/rules/{format-translate-component.js → format-translate-component/index.js} +0 -0
- package/rules/jsx-start-with-spread-attributes/README.md +31 -0
- package/rules/{jsx-start-with-spread-attributes.js → jsx-start-with-spread-attributes/index.js} +0 -0
- package/rules/no-import-other-domain/README.md +85 -0
- package/rules/{no-import-other-domain.js → no-import-other-domain/index.js} +2 -2
- package/rules/prohibit-export-array-type/README.md +28 -0
- package/rules/prohibit-export-array-type/index.js +28 -0
- package/rules/prohibit-file-name/README.md +35 -0
- package/rules/prohibit-file-name/index.js +61 -0
- package/rules/prohibit-import/README.md +44 -0
- package/rules/{prohibit-import.js → prohibit-import/index.js} +0 -0
- package/rules/redundant-name/README.md +94 -0
- package/rules/{redundant-name.js → redundant-name/index.js} +1 -1
- package/rules/require-barrel-import/README.md +39 -0
- package/rules/{require-barrel-import.js → require-barrel-import/index.js} +1 -1
- package/rules/require-export/README.md +43 -0
- package/rules/require-export/index.js +90 -0
- package/rules/require-import/README.md +51 -0
- package/rules/{require-import.js → require-import/index.js} +0 -0
- package/test/best-practice-for-date.js +31 -0
- package/test/prohibit-file-name.js +45 -0
- package/test/require-export.js +83 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# smarthr/prohibit-import
|
|
2
|
+
|
|
3
|
+
- 例えば特定の module にバグが発見されたなど、importさせたくない場合に利用するルールです
|
|
4
|
+
|
|
5
|
+
## rules
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
{
|
|
9
|
+
rules: {
|
|
10
|
+
'smarthr/prohibit-import': [
|
|
11
|
+
'error', // 'warn', 'off'
|
|
12
|
+
{
|
|
13
|
+
'^.+$': {
|
|
14
|
+
'smarthr-ui': {
|
|
15
|
+
imported: ['SecondaryButtonAnchor'],
|
|
16
|
+
reportMessage: `{{module}}/{{export}} はXxxxxxなので利用せず yyyy/zzzz を利用してください`
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
'\/pages\/views\/': {
|
|
20
|
+
'query-string': {
|
|
21
|
+
imported: true,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## ❌ Incorrect
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
// src/pages/views/Page.tsx
|
|
34
|
+
import queryString from 'query-string'
|
|
35
|
+
import { SecondaryButtonAnchor } from 'smarthr-ui'
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## ✅ Correct
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
// src/pages/views/Page.tsx
|
|
43
|
+
import { PrimaryButton, SecondaryButton } from 'smarthr-ui'
|
|
44
|
+
```
|
|
File without changes
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# smarthr/redundant-name
|
|
2
|
+
|
|
3
|
+
- ファイル、コードの冗長な部分を取り除くことを提案するruleです
|
|
4
|
+
- ファイルが設置されているディレクトリ構造からキーワードを生成し、取り除く文字列を生成します
|
|
5
|
+
|
|
6
|
+
## config
|
|
7
|
+
|
|
8
|
+
- tsconfig.json の compilerOptions.pathsに '@/*' としてroot path を指定する必要があります
|
|
9
|
+
- 以下の設定を行えます。全て省略可能です。
|
|
10
|
+
- ignoreKeywords
|
|
11
|
+
- ディレクトリ名から生成されるキーワードに含めたくない文字列を指定します
|
|
12
|
+
- betterNames
|
|
13
|
+
- 対象の名前を修正する候補を指定します
|
|
14
|
+
- allowedNames
|
|
15
|
+
- 許可する名前を指定します
|
|
16
|
+
- suffix:
|
|
17
|
+
- type のみ指定出来ます
|
|
18
|
+
- type のsuffixを指定します
|
|
19
|
+
|
|
20
|
+
### ファイル例
|
|
21
|
+
- `@/crews/index/views/page.tsx` の場合
|
|
22
|
+
- 生成されるキーワードは `['crews', 'crew', 'index', 'page']`
|
|
23
|
+
- `@/crews/index/views/parts/Abc.tsx` の場合
|
|
24
|
+
- 生成されるキーワードは `['crews', 'crew', 'index', 'Abc']`
|
|
25
|
+
- `@/crews/index/repositories/index.ts` の場合
|
|
26
|
+
- 生成されるキーワードは `['crews', 'crew', 'index', 'repositories', 'repository']`
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
## rules
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
const ignorekeywords = ['views', 'parts']
|
|
33
|
+
const betterNames = {
|
|
34
|
+
'\/repositories\/': {
|
|
35
|
+
operator: '-',
|
|
36
|
+
names: ['repository', 'Repository'],
|
|
37
|
+
},
|
|
38
|
+
'\/entities\/': {
|
|
39
|
+
operator: '+',
|
|
40
|
+
names: ['entity'],
|
|
41
|
+
},
|
|
42
|
+
'\/slices\/': {
|
|
43
|
+
operator: '=',
|
|
44
|
+
names: ['index'],
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
// const allowedNames = {
|
|
48
|
+
// '\/views\/crews\/histories\/': ['crewId'],
|
|
49
|
+
// }
|
|
50
|
+
|
|
51
|
+
{
|
|
52
|
+
rules: {
|
|
53
|
+
'smarthr/redundant-name': [
|
|
54
|
+
'error', // 'warn', 'off'
|
|
55
|
+
{
|
|
56
|
+
type: { ignorekeywords, suffix: ['Props', 'Type'] },
|
|
57
|
+
file: { ignorekeywords, betternames },
|
|
58
|
+
// property: { ignorekeywords, allowedNames },
|
|
59
|
+
// function: { ignorekeywords },
|
|
60
|
+
// variable: { ignorekeywords },
|
|
61
|
+
// class: { ignorekeywords },
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## ❌ Incorrect
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
// @/crews/index/views/page.tsx
|
|
72
|
+
|
|
73
|
+
type CrewIndexPage = { hoge: string }
|
|
74
|
+
type CrewsView = { hoge: string }
|
|
75
|
+
```
|
|
76
|
+
```js
|
|
77
|
+
// @/crews/show/repositories/index.tsx
|
|
78
|
+
|
|
79
|
+
type CrewIndexRepository = { hoge: () => any }
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## ✅ Correct
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
// @/crews/index/views/page.tsx
|
|
86
|
+
|
|
87
|
+
type ItemProps = { hoge: string }
|
|
88
|
+
```
|
|
89
|
+
```js
|
|
90
|
+
// @/crews/show/repositories/index.tsx
|
|
91
|
+
|
|
92
|
+
type IndexProps = { hoge: () => any }
|
|
93
|
+
type ResponseType = { hoge: () => any }
|
|
94
|
+
```
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
2
|
const Inflector = require('inflected')
|
|
3
3
|
|
|
4
|
-
const { rootPath } = require('
|
|
4
|
+
const { rootPath } = require('../../libs/common')
|
|
5
5
|
|
|
6
6
|
const uniq = (array) => array.filter((elem, index, self) => self.indexOf(elem) === index)
|
|
7
7
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# smarthr/require-barrel-import
|
|
2
|
+
|
|
3
|
+
- tsconfig.json の compilerOptions.pathsに '@/*' としてroot path を指定する必要があります
|
|
4
|
+
- importした対象が本来exportされているべきであるbarrel(index.tsなど)が有る場合、import pathの変更を促します
|
|
5
|
+
- 例: Page/parts/Menu/Item の import は Page/parts/Menu から行わせたい
|
|
6
|
+
- ディレクトリ内のindexファイルを捜査し、対象を決定します
|
|
7
|
+
|
|
8
|
+
## rules
|
|
9
|
+
|
|
10
|
+
```js
|
|
11
|
+
{
|
|
12
|
+
rules: {
|
|
13
|
+
'smarthr/require-barrel-import': 'error',
|
|
14
|
+
},
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## ❌ Incorrect
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
// client/src/views/Page/parts/Menu/index.ts
|
|
22
|
+
export { Menu } from './Menu'
|
|
23
|
+
export { Item } from './Item'
|
|
24
|
+
|
|
25
|
+
// client/src/App.tsx
|
|
26
|
+
import { Item } from './Page/parts/Menu/Item'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## ✅ Correct
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
// client/src/views/Page/parts/Menu/index.ts
|
|
34
|
+
export { Menu } from './Menu'
|
|
35
|
+
export { Item } from './Item'
|
|
36
|
+
|
|
37
|
+
// client/src/App.tsx
|
|
38
|
+
import { Item } from './Page/parts/Menu'
|
|
39
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const path = require('path')
|
|
2
2
|
const fs = require('fs')
|
|
3
|
-
const { replacePaths, rootPath } = require('
|
|
3
|
+
const { replacePaths, rootPath } = require('../../libs/common')
|
|
4
4
|
const calculateAbsoluteImportPath = (source) => {
|
|
5
5
|
if (source[0] === '/') {
|
|
6
6
|
return source
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# smarthr/require-export
|
|
2
|
+
|
|
3
|
+
- 対象ファイルにexportを強制させたい場合に利用します
|
|
4
|
+
- 例: Page.tsx ではページタイトルを設定させたいので useTitle を必ずexportさせたい
|
|
5
|
+
|
|
6
|
+
## rules
|
|
7
|
+
|
|
8
|
+
```js
|
|
9
|
+
{
|
|
10
|
+
rules: {
|
|
11
|
+
'smarthr/require-export': [
|
|
12
|
+
'error',
|
|
13
|
+
{
|
|
14
|
+
'adapter\/.+\.ts': ['Props', 'generator'],
|
|
15
|
+
// slice以下のファイルかつmodulesディレクトリに属さずファイル名にmockを含まないもの
|
|
16
|
+
'^(?=.*\/slices\/[a-zA-Z0-9]+\.ts)(?!.*(\/modules\/|mock\.)).*$': [ 'default' ],
|
|
17
|
+
},
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## ❌ Incorrect
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
// adapter/index.ts
|
|
27
|
+
export type Type = { abc: string }
|
|
28
|
+
|
|
29
|
+
// slice/index.ts
|
|
30
|
+
export const slice = { method: () => 'any action' }
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## ✅ Correct
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
// adapter/index.ts
|
|
38
|
+
export type Props = { abc: string }
|
|
39
|
+
|
|
40
|
+
// slice/index.ts
|
|
41
|
+
const slice = { method: () => 'any action' }
|
|
42
|
+
export default slice
|
|
43
|
+
```
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
const SCHEMA = [{
|
|
2
|
+
type: 'object',
|
|
3
|
+
patternProperties: {
|
|
4
|
+
'.+': {
|
|
5
|
+
type: 'array',
|
|
6
|
+
items: { type: 'string' },
|
|
7
|
+
additionalProperties: true,
|
|
8
|
+
},
|
|
9
|
+
},
|
|
10
|
+
additionalProperties: true,
|
|
11
|
+
}]
|
|
12
|
+
|
|
13
|
+
const fetchEdgeDeclaration = (node) => {
|
|
14
|
+
const { declaration } = node
|
|
15
|
+
|
|
16
|
+
if (!declaration) {
|
|
17
|
+
return node
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return fetchEdgeDeclaration(declaration)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = {
|
|
24
|
+
meta: {
|
|
25
|
+
type: 'suggestion',
|
|
26
|
+
messages: {
|
|
27
|
+
'require-export': '{{ message }}',
|
|
28
|
+
},
|
|
29
|
+
schema: SCHEMA,
|
|
30
|
+
},
|
|
31
|
+
create(context) {
|
|
32
|
+
const options = context.options[0]
|
|
33
|
+
const filename = context.getFilename()
|
|
34
|
+
const targetPathRegexs = Object.keys(options)
|
|
35
|
+
const targetRequires = targetPathRegexs.filter((regex) => !!filename.match(new RegExp(regex)))
|
|
36
|
+
|
|
37
|
+
if (targetRequires.length === 0) {
|
|
38
|
+
return {}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
Program: (node) => {
|
|
43
|
+
targetRequires.forEach((requireKey) => {
|
|
44
|
+
const option = options[requireKey]
|
|
45
|
+
let existDefault = false
|
|
46
|
+
const exports =
|
|
47
|
+
node.body
|
|
48
|
+
.filter((i) => {
|
|
49
|
+
if (i.type == 'ExportDefaultDeclaration') {
|
|
50
|
+
existDefault = true
|
|
51
|
+
|
|
52
|
+
return false
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return i.type == 'ExportNamedDeclaration'
|
|
56
|
+
})
|
|
57
|
+
.map((i) => {
|
|
58
|
+
const declaration = fetchEdgeDeclaration(i)
|
|
59
|
+
|
|
60
|
+
if (declaration.id) {
|
|
61
|
+
return declaration.id.name
|
|
62
|
+
}
|
|
63
|
+
if (declaration.specifiers) {
|
|
64
|
+
return declaration.specifiers.map((s) => s.exported.name)
|
|
65
|
+
}
|
|
66
|
+
if (declaration.declarations) {
|
|
67
|
+
return declaration.declarations.map((d) => d.id.name || d.id.properties.map((p) => p.key.name))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return declaration
|
|
71
|
+
})
|
|
72
|
+
.flat(2)
|
|
73
|
+
|
|
74
|
+
let notExistsExports = [...(!existDefault && option.includes('default') ? ['default'] : []), ...option.filter((o) => o !== 'default' && !exports.includes(o))]
|
|
75
|
+
|
|
76
|
+
if (notExistsExports.length) {
|
|
77
|
+
context.report({
|
|
78
|
+
node,
|
|
79
|
+
messageId: 'require-export',
|
|
80
|
+
data: {
|
|
81
|
+
message: `${notExistsExports.join(', ')} をexportしてください`,
|
|
82
|
+
},
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
},
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
}
|
|
90
|
+
module.exports.schema = SCHEMA
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# smarthr/require-import
|
|
2
|
+
|
|
3
|
+
- 対象ファイルにimportを強制させたい場合に利用します
|
|
4
|
+
- 例: Page.tsx ではページタイトルを設定させたいので useTitle を必ずimportさせたい
|
|
5
|
+
|
|
6
|
+
## rules
|
|
7
|
+
|
|
8
|
+
```js
|
|
9
|
+
{
|
|
10
|
+
rules: {
|
|
11
|
+
'smarthr/require-import': [
|
|
12
|
+
'error',
|
|
13
|
+
{
|
|
14
|
+
'Buttons\/.+\.tsx': {
|
|
15
|
+
'smarthr-ui': {
|
|
16
|
+
imported: ['SecondaryButton'],
|
|
17
|
+
reportMessage: 'Buttons以下のコンポーネントでは {{module}}/{{export}} を拡張するようにしてください',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
'Page.tsx$': {
|
|
21
|
+
'./client/src/hooks/useTitle': {
|
|
22
|
+
imported: true,
|
|
23
|
+
reportMessage: '{{module}} を利用してください(ページタイトルを設定するため必要です)',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## ❌ Incorrect
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
// client/src/Buttons/SecondaryButton.tsx
|
|
36
|
+
import { SecondaryButtonAnchor } from 'smarthr-ui'
|
|
37
|
+
|
|
38
|
+
// client/src/Page.tsx
|
|
39
|
+
import { SecondaryButton } from 'smarthr-ui'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## ✅ Correct
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
// client/src/Buttons/SecondaryButton.tsx
|
|
47
|
+
import { SecondaryButton } from 'smarthr-ui'
|
|
48
|
+
|
|
49
|
+
// client/src/Page.tsx
|
|
50
|
+
import useTitle from '.hooks/useTitle'
|
|
51
|
+
```
|
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const rule = require('../rules/best-practice-for-date')
|
|
2
|
+
const RuleTester = require('eslint').RuleTester
|
|
3
|
+
|
|
4
|
+
const ruleTester = new RuleTester({
|
|
5
|
+
parserOptions: {
|
|
6
|
+
ecmaVersion: 2018,
|
|
7
|
+
ecmaFeatures: {
|
|
8
|
+
experimentalObjectRestSpread: true,
|
|
9
|
+
jsx: true,
|
|
10
|
+
},
|
|
11
|
+
sourceType: 'module',
|
|
12
|
+
},
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const errorNewDate = "'new Date(arg)' のように引数一つのみの指定方は実行環境により結果が変わる可能性があるため 'new Date(2022, 12 - 1, 31)' のようにparseするなど他の方法を検討してください。"
|
|
16
|
+
const errorDateParse = 'Date.parse は日付形式の解釈がブラウザによって異なるため、他の手段を検討してください'
|
|
17
|
+
|
|
18
|
+
ruleTester.run('best-practice-for-date', rule, {
|
|
19
|
+
valid: [
|
|
20
|
+
{ code: `new Date()` },
|
|
21
|
+
{ code: `new Date(2022, 11, 31)` },
|
|
22
|
+
{ code: `new Date('2022', '11', '31')` },
|
|
23
|
+
{ code: `const year = 2022; const month = 11; const date = 31; new Date(year, month, date)` },
|
|
24
|
+
],
|
|
25
|
+
invalid: [
|
|
26
|
+
{ code: 'new Date("2022/12/31")', errors: [ { message: errorNewDate } ] },
|
|
27
|
+
{ code: 'const arg = "2022/12/31"; new Date(arg)', errors: [ { message: errorNewDate } ] },
|
|
28
|
+
{ code: 'Date.parse("2022/12/31")', errors: [ { message: errorDateParse } ] },
|
|
29
|
+
{ code: 'const arg = "2022/12/31"; Date.parse(arg)', errors: [ { message: errorDateParse } ] },
|
|
30
|
+
]
|
|
31
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const rule = require('../rules/prohibit-file-name')
|
|
2
|
+
const RuleTester = require('eslint').RuleTester
|
|
3
|
+
|
|
4
|
+
const ruleTester = new RuleTester({
|
|
5
|
+
parserOptions: {
|
|
6
|
+
sourceType: 'module',
|
|
7
|
+
ecmaVersion: 2015
|
|
8
|
+
},
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
ruleTester.run('prohibit-file-name', rule, {
|
|
12
|
+
valid: [
|
|
13
|
+
{
|
|
14
|
+
code: 'const any = "code"',
|
|
15
|
+
filename: 'hoge.js',
|
|
16
|
+
options: [
|
|
17
|
+
{
|
|
18
|
+
'fuga\.js': 'any message.',
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
invalid: [
|
|
24
|
+
{
|
|
25
|
+
code: 'const any = "code"',
|
|
26
|
+
filename: 'hoge.js',
|
|
27
|
+
options: [
|
|
28
|
+
{
|
|
29
|
+
'hoge\.js': 'any message.',
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
errors: [{ message: 'any message.' }]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
code: 'const any = "code"',
|
|
36
|
+
filename: 'hoge.js',
|
|
37
|
+
options: [
|
|
38
|
+
{
|
|
39
|
+
'(hoge|fuga)\.js': '$1.jsは作成しないで!',
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
errors: [{ message: 'hoge.jsは作成しないで!' }]
|
|
43
|
+
},
|
|
44
|
+
]
|
|
45
|
+
})
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
const rule = require('../rules/require-export')
|
|
2
|
+
const RuleTester = require('eslint').RuleTester
|
|
3
|
+
|
|
4
|
+
const ruleTester = new RuleTester({
|
|
5
|
+
parserOptions: {
|
|
6
|
+
sourceType: 'module',
|
|
7
|
+
ecmaVersion: 2015
|
|
8
|
+
},
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
ruleTester.run('require-export', rule, {
|
|
12
|
+
valid: [
|
|
13
|
+
{
|
|
14
|
+
code: `const hoge = {}; export { hoge }`,
|
|
15
|
+
options: [
|
|
16
|
+
{
|
|
17
|
+
'^.+$': ['hoge'],
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
code: `const hoge = {}, fuga = {}; export { hoge, fuga }`,
|
|
23
|
+
options: [
|
|
24
|
+
{
|
|
25
|
+
'^.+$': ['hoge', 'fuga'],
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
code: `const hoge = {}, fuga = {}; export { hoge, fuga }`,
|
|
31
|
+
options: [
|
|
32
|
+
{
|
|
33
|
+
'^.+$': ['fuga'],
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
code: `export const hoge = {}`,
|
|
39
|
+
options: [
|
|
40
|
+
{
|
|
41
|
+
'^.+$': ['hoge'],
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
code: `const hoge = {}; export default hoge`,
|
|
47
|
+
options: [
|
|
48
|
+
{
|
|
49
|
+
'^.+$': ['default'],
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
invalid: [
|
|
55
|
+
{
|
|
56
|
+
code: `const hoge ={}; export { hoge }`,
|
|
57
|
+
options: [
|
|
58
|
+
{
|
|
59
|
+
'^.+$': ['fuga'],
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
errors: [{ message: 'fuga をexportしてください' }],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
code: `export const hoge = {}`,
|
|
66
|
+
options: [
|
|
67
|
+
{
|
|
68
|
+
'^.+$': ['fuga'],
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
errors: [{ message: 'fuga をexportしてください' }],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
code: `const hoge = {}; export { hoge }`,
|
|
75
|
+
options: [
|
|
76
|
+
{
|
|
77
|
+
'^.+$': ['default'],
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
errors: [{ message: 'default をexportしてください' }],
|
|
81
|
+
},
|
|
82
|
+
]
|
|
83
|
+
})
|