eslint-plugin-smarthr 6.10.3 → 6.10.4

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 CHANGED
@@ -2,6 +2,13 @@
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
+ ## [6.10.4](https://github.com/kufu/tamatebako/compare/eslint-plugin-smarthr-v6.10.3...eslint-plugin-smarthr-v6.10.4) (2026-04-13)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **require-i18n-text:** 許容する記号の拡充と、テストコードでの除外設定を追加 ([#1225](https://github.com/kufu/tamatebako/issues/1225)) ([705113f](https://github.com/kufu/tamatebako/commit/705113f9b599bb77bec35b2c9b28825603d581ea))
11
+
5
12
  ## [6.10.3](https://github.com/kufu/tamatebako/compare/eslint-plugin-smarthr-v6.10.2...eslint-plugin-smarthr-v6.10.3) (2026-04-10)
6
13
 
7
14
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-smarthr",
3
- "version": "6.10.3",
3
+ "version": "6.10.4",
4
4
  "author": "SmartHR",
5
5
  "license": "MIT",
6
6
  "description": "A sharable ESLint plugin for SmartHR",
@@ -37,5 +37,5 @@
37
37
  "eslintplugin",
38
38
  "smarthr"
39
39
  ],
40
- "gitHead": "e1a8159fdc6396bb83fdf7f616f52f3c714ff390"
40
+ "gitHead": "5e89902850d7084a12d50400dad9d1b0e5764e00"
41
41
  }
@@ -28,8 +28,9 @@ const generateAttributeSelector = (attributes) =>
28
28
  const generateTemplateLiteralSelector = (attributes) =>
29
29
  `JSXAttribute[name.name=/^(${attributes.join('|')})$/][value.type="JSXExpressionContainer"][value.expression.type="TemplateLiteral"]`
30
30
 
31
- const IGNORE_TEXT_REGEX = /^ *(\.|\+|\-|\*|\/|[0-9]+) *$/
32
- const checkIgnoreText = (text) => !IGNORE_TEXT_REGEX.test(text)
31
+ const REGEX_IGNORE_FILENAME = /\.(spec|test|stories)\./
32
+ const REGEX_IGNORE_TEXT = /^\s*(\.|\+|\-|〜|:|:|(|)|\(|\)|,|\*|\/|[0-9]+)\s*$/
33
+ const checkIgnoreText = (text) => !REGEX_IGNORE_TEXT.test(text)
33
34
 
34
35
  const someReportTemplateLiteralError = (quasi) => quasi.value.cooked && quasi.value.cooked.trim() !== '' && checkIgnoreText(quasi.value.cooked)
35
36
 
@@ -42,6 +43,10 @@ module.exports = {
42
43
  schema: SCHEMA,
43
44
  },
44
45
  create(context) {
46
+ if (REGEX_IGNORE_FILENAME.test(context.getFilename())) {
47
+ return {}
48
+ }
49
+
45
50
  const elementsObj = (context.options[0] || {}).elements || {}
46
51
  // ユーザーが'*'を設定していない場合のみデフォルトを適用
47
52
  const wildcardAttributes = elementsObj['*'] || DEFAULT_WILDCARD_ATTRIBUTES
@@ -57,7 +62,7 @@ module.exports = {
57
62
  if (checkIgnoreText(node.value.value)) {
58
63
  context.report({
59
64
  node,
60
- message: `${node.parent.name.name}の${node.name.name}属性に文字列リテラルが指定されています。多言語化対応のため、翻訳関数を使用してください
65
+ message: `${node.parent.name.name}の${node.name.name}属性に文字列リテラル "${node.value.value.trim()}" が指定されています。多言語化対応のため、翻訳関数を使用してください
61
66
  - 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/require-i18n-text`,
62
67
  })
63
68
  }
@@ -101,7 +106,7 @@ module.exports = {
101
106
  if (checkIgnoreText(node.value)) {
102
107
  context.report({
103
108
  node,
104
- message: `子要素に文字列リテラルが指定されています。多言語化対応のため、翻訳関数を使用してください
109
+ message: `子要素に文字列リテラル "${node.value.trim()}" が指定されています。多言語化対応のため、翻訳関数を使用してください
105
110
  - 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/require-i18n-text`,
106
111
  })
107
112
  }
@@ -11,9 +11,9 @@ const ruleTester = new RuleTester({
11
11
  },
12
12
  })
13
13
 
14
- const attributeError = (element, attr) => `${element}の${attr}属性に文字列リテラルが指定されています。多言語化対応のため、翻訳関数を使用してください
14
+ const attributeError = (element, attr, text) => `${element}の${attr}属性に文字列リテラル "${text}" が指定されています。多言語化対応のため、翻訳関数を使用してください
15
15
  - 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/require-i18n-text`
16
- const childTextError = `子要素に文字列リテラルが指定されています。多言語化対応のため、翻訳関数を使用してください
16
+ const childTextError = (text) => `子要素に文字列リテラル "${text}" が指定されています。多言語化対応のため、翻訳関数を使用してください
17
17
  - 詳細: https://github.com/kufu/tamatebako/tree/master/packages/eslint-plugin-smarthr/rules/require-i18n-text`
18
18
 
19
19
  const options = [
@@ -61,6 +61,14 @@ ruleTester.run('require-i18n-text', rule, {
61
61
  { code: `<img alt="-" />` },
62
62
  { code: `<i>*</i>` },
63
63
  { code: `<i>/</i>` },
64
+ { code: `<div>〜</div>` },
65
+ { code: `<div>:</div>` },
66
+ { code: `<div>:</div>` },
67
+ { code: `<div>(</div>` },
68
+ { code: `<div>)</div>` },
69
+ { code: `<div>(</div>` },
70
+ { code: `<div>)</div>` },
71
+ { code: `<div>,</div>` },
64
72
 
65
73
  // ワイルドカード - 空配列で除外
66
74
  {
@@ -96,41 +104,41 @@ ruleTester.run('require-i18n-text', rule, {
96
104
  // 属性エラー: デフォルト設定
97
105
  {
98
106
  code: `<img alt="Profile picture" />`,
99
- errors: [{ message: attributeError('img', 'alt') }],
107
+ errors: [{ message: attributeError('img', 'alt', 'Profile picture') }],
100
108
  },
101
109
  {
102
110
  code: `<CustomComponent aria-label="Label" />`,
103
- errors: [{ message: attributeError('CustomComponent', 'aria-label') }],
111
+ errors: [{ message: attributeError('CustomComponent', 'aria-label', 'Label') }],
104
112
  },
105
113
  {
106
114
  code: `<DefinitionListItem term="Label" />`,
107
- errors: [{ message: attributeError('DefinitionListItem', 'term') }],
115
+ errors: [{ message: attributeError('DefinitionListItem', 'term', 'Label') }],
108
116
  },
109
117
  {
110
118
  code: `<button title="Click me" />`,
111
- errors: [{ message: attributeError('button', 'title') }],
119
+ errors: [{ message: attributeError('button', 'title', 'Click me') }],
112
120
  },
113
121
 
114
122
  // 数値、.と演算記号の場合でも他の文字列が含まれていればエラー
115
- { code: `<Any aria-label="1234 あ" />`, errors: [{ message: attributeError('Any', 'aria-label') }] },
116
- { code: `<div>a.</div>`, errors: [{ message: childTextError }] },
117
- { code: `<a> + b</a>`, errors: [{ message: childTextError }] },
118
- { code: `<img alt="-zod" />`, errors: [{ message: attributeError('img', 'alt') }] },
119
- { code: `<i>*1</i>`, errors: [{ message: childTextError }] },
120
- { code: `<i>a/</i>`, errors: [{ message: childTextError }] },
123
+ { code: `<Any aria-label="1234 あ" />`, errors: [{ message: attributeError('Any', 'aria-label', '1234 あ') }] },
124
+ { code: `<div>a.</div>`, errors: [{ message: childTextError('a.') }] },
125
+ { code: `<a> + b</a>`, errors: [{ message: childTextError('+ b') }] },
126
+ { code: `<img alt="-zod" />`, errors: [{ message: attributeError('img', 'alt', '-zod') }] },
127
+ { code: `<i>*1</i>`, errors: [{ message: childTextError('*1') }] },
128
+ { code: `<i>a/</i>`, errors: [{ message: childTextError('a/') }] },
121
129
 
122
130
  // 属性エラー: カスタムオプション
123
131
  {
124
132
  code: `<img alt="Profile picture" />`,
125
133
  options,
126
- errors: [{ message: attributeError('img', 'alt') }],
134
+ errors: [{ message: attributeError('img', 'alt', 'Profile picture') }],
127
135
  },
128
136
 
129
137
  // 属性エラー: 同一要素の複数属性
130
138
  {
131
139
  code: `<img alt="Profile" title="User profile" />`,
132
140
  options,
133
- errors: [{ message: attributeError('img', 'alt') }, { message: attributeError('img', 'title') }],
141
+ errors: [{ message: attributeError('img', 'alt', 'Profile') }, { message: attributeError('img', 'title', 'User profile') }],
134
142
  },
135
143
 
136
144
  // 属性エラー: ワイルドカード
@@ -143,7 +151,7 @@ ruleTester.run('require-i18n-text', rule, {
143
151
  },
144
152
  },
145
153
  ],
146
- errors: [{ message: attributeError('CustomComponent', 'label') }],
154
+ errors: [{ message: attributeError('CustomComponent', 'label', 'Text') }],
147
155
  },
148
156
 
149
157
  // 属性エラー: 個別設定がワイルドカードより優先
@@ -157,20 +165,20 @@ ruleTester.run('require-i18n-text', rule, {
157
165
  },
158
166
  },
159
167
  ],
160
- errors: [{ message: attributeError('Button', 'label') }, { message: attributeError('Button', 'helperText') }],
168
+ errors: [{ message: attributeError('Button', 'label', 'Submit') }, { message: attributeError('Button', 'helperText', 'Help') }],
161
169
  },
162
170
 
163
171
  // 子要素エラー(オプション未設定時でもチェックされる)
164
172
  {
165
173
  code: `<div>Hello World</div>`,
166
- errors: [{ message: childTextError }],
174
+ errors: [{ message: childTextError('Hello World') }],
167
175
  },
168
176
 
169
177
  // 複合エラー: 属性と子要素
170
178
  {
171
179
  code: `<Button label="Submit">Click here</Button>`,
172
180
  options,
173
- errors: [{ message: attributeError('Button', 'label') }, { message: childTextError }],
181
+ errors: [{ message: attributeError('Button', 'label', 'Submit') }, { message: childTextError('Click here') }],
174
182
  },
175
183
 
176
184
  // 複合エラー: 入れ子構造
@@ -178,22 +186,10 @@ ruleTester.run('require-i18n-text', rule, {
178
186
  code: `<div title="Parent"><Button label="Child">Grandchild text</Button></div>`,
179
187
  options,
180
188
  errors: [
181
- { message: attributeError('div', 'title') },
182
- { message: attributeError('Button', 'label') },
183
- { message: childTextError },
189
+ { message: attributeError('div', 'title', 'Parent') },
190
+ { message: attributeError('Button', 'label', 'Child') },
191
+ { message: childTextError('Grandchild text') },
184
192
  ],
185
193
  },
186
-
187
- // TemplateLiteral - 変数を含み、文字列リテラル部分がある
188
- {
189
- code: `<img alt={\`Profile \${name}\`} />`,
190
- options,
191
- errors: [{ message: attributeError('img', 'alt') }],
192
- },
193
- {
194
- code: `<div title={\`\${prefix} title\`} />`,
195
- options,
196
- errors: [{ message: attributeError('div', 'title') }],
197
- },
198
194
  ],
199
195
  })