Skip to content

Commit 184af78

Browse files
authored
Fix bug when using delimited-like path. (#256)
* Fix bug when using delimited-like path. * Add testcase
1 parent d0b890f commit 184af78

File tree

4 files changed

+97
-14
lines changed

4 files changed

+97
-14
lines changed

Diff for: lib/rules/no-unused-keys.ts

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ function getUsedKeysMap(
5555
const usedKeysMap: UsedKeys = {}
5656

5757
for (const key of [...usedkeys, ...collectLinkedKeys(values, context)]) {
58+
usedKeysMap[key] = {} // Set original key.
5859
const paths = parsePath(key)
5960
let map = usedKeysMap
6061
while (paths.length) {

Diff for: lib/utils/locale-messages.ts

+21-13
Original file line numberDiff line numberDiff line change
@@ -253,31 +253,39 @@ export class LocaleMessages {
253253
findMissingPath(key: string): string | null {
254254
let missingPath: string[] = []
255255
for (const locale of this.locales) {
256-
const paths = parsePath(key)
257-
const length = paths.length
258-
let lasts: I18nLocaleMessageValue[] = this.localeMessages.map(lm =>
259-
lm.getMessagesFromLocale(locale)
256+
const localeMessages: I18nLocaleMessageValue[] = this.localeMessages.map(
257+
lm => lm.getMessagesFromLocale(locale)
260258
)
261-
let i = 0
262-
let missing = false
263-
while (i < length) {
259+
if (
260+
localeMessages.some(last => {
261+
return last && typeof last !== 'string' ? last[key] != null : false
262+
})
263+
) {
264+
// Hit the original key.
265+
return null
266+
}
267+
268+
const paths = [...parsePath(key)]
269+
let lasts = localeMessages
270+
const targetPaths = []
271+
while (paths.length) {
272+
const path = paths.shift()!
273+
targetPaths.push(path)
264274
const values: I18nLocaleMessageValue[] = lasts
265275
.map(last => {
266-
return last && typeof last !== 'string' ? last[paths[i]] : undefined
276+
return last && typeof last !== 'string' ? last[path] : undefined
267277
})
268278
.filter((val): val is I18nLocaleMessageValue => val != null)
269279

270280
if (values.length === 0) {
271-
if (missingPath.length <= i) {
272-
missingPath = paths.slice(0, i + 1)
281+
if (missingPath.length <= targetPaths.length) {
282+
missingPath = targetPaths
273283
}
274-
missing = true
275284
break
276285
}
277286
lasts = values
278-
i++
279287
}
280-
if (!missing) {
288+
if (!missingPath.length) {
281289
return null
282290
}
283291
}

Diff for: tests/lib/rules/no-missing-keys.ts

+31
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,30 @@ tester.run('no-missing-keys', rule as never, {
169169
<template>
170170
<i18n-t keypath="'hello'"></i18n-t>
171171
</template>`
172+
},
173+
{
174+
filename: 'test.vue',
175+
code: `
176+
<i18n locale="en">
177+
{
178+
"Usage: $0 <command> [options]": "Usage: $0 <command> [options]"
179+
}
180+
</i18n>
181+
<script>
182+
t('Usage: $0 <command> [options]')
183+
</script>`
184+
},
185+
{
186+
filename: 'test.vue',
187+
code: `
188+
<i18n locale="en">
189+
{
190+
"foo.bar": "Message"
191+
}
192+
</i18n>
193+
<script>
194+
t('foo.bar')
195+
</script>`
172196
}
173197
]
174198
),
@@ -217,6 +241,13 @@ tester.run('no-missing-keys', rule as never, {
217241
code: `$t('missing.path')`,
218242
errors: [`'missing' does not exist in localization message resources`]
219243
},
244+
{
245+
// nested missing
246+
code: `$t('messages.missing')`,
247+
errors: [
248+
`'messages.missing' does not exist in localization message resources`
249+
]
250+
},
220251
{
221252
// nested missing
222253
code: `$t('messages.missing')`,

Diff for: tests/lib/rules/no-unused-keys.ts

+44-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,50 @@ new RuleTester({
148148
]
149149
})
150150
]
151-
: [])
151+
: []),
152+
{
153+
filename: 'test.vue',
154+
code: `
155+
<i18n locale="en">
156+
{
157+
"Usage: $0 <command> [options]": "Usage: $0 <command> [options]"
158+
}
159+
</i18n>
160+
<script>
161+
t('Usage: $0 <command> [options]')
162+
</script>`
163+
},
164+
{
165+
filename: 'test.vue',
166+
code: `
167+
<i18n locale="en">
168+
{
169+
"foo.bar": "Message"
170+
}
171+
</i18n>
172+
<script>
173+
t('foo.bar')
174+
</script>`
175+
},
176+
{
177+
// https://github.com/intlify/eslint-plugin-vue-i18n/issues/260
178+
filename: 'test.vue',
179+
code: `
180+
<i18n locale="en">
181+
{
182+
"hello {name}.": "hello {name}!"
183+
}
184+
</i18n>
185+
<script>
186+
export default {
187+
methods: {
188+
fn () {
189+
this.$i18n.t('hello {name}.', { name: 'DIO' })
190+
}
191+
}
192+
}
193+
</script>`
194+
}
152195
],
153196
invalid: [
154197
{

0 commit comments

Comments
 (0)