Skip to content

Commit d21ed55

Browse files
author
XavierChevalier
committed
feat: support vue-jest@v5 (intlify#23)
Refs: intlify#23
1 parent afaa5c3 commit d21ed55

File tree

5 files changed

+78
-70
lines changed

5 files changed

+78
-70
lines changed

e2e/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@
1616
"@vue/test-utils": "^1.0.4",
1717
"jest": "^26.x",
1818
"vue-i18n-jest": "file:../",
19-
"vue-jest": "^4.0.0-beta.3"
19+
"vue-jest": "^5.0.0-alpha.10"
2020
}
2121
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"main": "./lib/index.js",
6767
"peerDependencies": {
6868
"vue": "^2.5",
69-
"vue-jest": "^4.0.0-beta.3",
69+
"vue-jest": "^5.0.0-alpha.10",
7070
"vue-template-compiler": "^2.5"
7171
},
7272
"repository": {

src/process.ts

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14,74 +14,72 @@ type ProcessParameter = {
1414
/** All of the blocks matching your type, returned from `@vue/component-compiler-utils` */
1515
blocks: SFCCustomBlock[]
1616
/** The internal namespace for a component's Vue Options in vue-jest */
17-
vueOptionsNamespace: string
17+
componentNamespace: string
1818
/** The SFC file being processed */
1919
filename: string
2020
}
2121

2222
const VUE_I18N_OPTION = '__i18n'
23+
const VUE_I18N_BLOCK_TYPE = 'i18n'
24+
25+
type JsonI18nBlockMessages = Record<string, unknown>
2326

2427
/**
2528
* Process vue-i18n contents inside of a custom block and prepare it for execution in a testing environment.
2629
*/
27-
export default function process ({ blocks, vueOptionsNamespace, filename }: ProcessParameter) : string {
28-
const i18nResources = blocks.map(block => {
29-
if (block.type !== 'i18n') return
30-
31-
const value = parseI18nBlockToJSON(block, filename)
32-
.replace(/\u2028/g, '\\u2028') // LINE SEPARATOR
33-
.replace(/\u2029/g, '\\u2029') // PARAGRAPH SEPARATOR
34-
.replace(/\\/g, '\\\\')
35-
.replace(/'/g, "\\'")
36-
return `'${value}'`
37-
}).filter((s): s is string => !!s)
38-
39-
// vueOptions.__i18n = [
40-
// '<json encoded block 1>',
41-
// '<json encoded block 2>'
42-
// ]
43-
const i18nOption = `${vueOptionsNamespace}.${VUE_I18N_OPTION}`
44-
const code = i18nResources.length ? `${i18nOption} = [\n${i18nResources.join(',\n')}\n]` : ''
45-
debug('generatedCode', code)
46-
return code
30+
export default function process ({ blocks, componentNamespace, filename }: ProcessParameter): string[] {
31+
const i18nOption = `${componentNamespace}.${VUE_I18N_OPTION}`
32+
const generatedCode = blocks
33+
.reduce((blocksValues, block) => {
34+
if (block.type !== VUE_I18N_BLOCK_TYPE) return blocksValues
35+
36+
const i18nBlockConfig = {
37+
locale: (block.attrs && block.attrs.locale) || '',
38+
resource: parseI18nBlockToJSON(block, filename)
39+
}
40+
41+
return blocksValues.concat(`${i18nOption}.push(${JSON.stringify(i18nBlockConfig)});`)
42+
}, [] as string[])
43+
44+
if (generatedCode.length > 0) {
45+
generatedCode.unshift(`${i18nOption} = ${i18nOption} || [];`)
46+
}
47+
48+
debug('generatedCode', generatedCode)
49+
50+
return generatedCode
4751
}
4852

4953
/**
5054
* Parse custom `<i18n>` block content to JSON string.
5155
* @param block SFC block returned from `@vue/component-compiler-utils`
5256
* @param filename The SFC file being processed
5357
*/
54-
function parseI18nBlockToJSON (block: SFCCustomBlock, filename: string): string {
58+
function parseI18nBlockToJSON (block: SFCCustomBlock, filename: string): JsonI18nBlockMessages {
5559
const lang = block.attrs && block.attrs.lang
56-
const locale = block.attrs && block.attrs.locale
5760
const src = block.attrs && block.attrs.src
5861
const content = src
5962
? readFileSync(getAbsolutePath(src, filename)).toString()
6063
: block.content
6164

62-
return convertToJSON(content, lang, locale)
65+
return convertToJSON(content, lang)
6366
}
6467

6568
/**
6669
* Convert JSON/YAML/JSON5 to minified JSON string.
6770
* @param source JSON/YAML/JSON5 encoded string
6871
* @param lang Language used in `source`. Supported JSON, YAML or JSON5.
69-
* @param locale Attribute "locale" on <i18n> block will be added.
7072
* @returns {string} A minified JSON string
7173
*/
72-
function convertToJSON (source: string, lang: string, locale: string): string {
73-
const stringify = locale
74-
? (parseResult: any) => JSON.stringify({ [locale]: parseResult })
75-
: JSON.stringify
76-
74+
function convertToJSON (source: string, lang: string): JsonI18nBlockMessages {
7775
switch (lang) {
7876
case 'yaml':
7977
case 'yml':
80-
return stringify(parseYAML(source))
78+
return parseYAML(source) as JsonI18nBlockMessages
8179
case 'json5':
82-
return stringify(parseJSON5(source))
80+
return parseJSON5(source)
8381
default: // fallback to 'json'
84-
return stringify(JSON.parse(source))
82+
return JSON.parse(source)
8583
}
8684
}
8785

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,76 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

33
exports[`process (default.vue) returns expected string: default.vue 1`] = `
4-
"__vue__options__.__i18n = [
5-
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}'
6-
]"
4+
Array [
5+
"Component.__i18n = Component.__i18n || [];",
6+
"Component.__i18n.push({\\"locale\\":\\"\\",\\"resource\\":{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}});",
7+
]
78
`;
89

910
exports[`process (json.vue) returns expected string: json.vue 1`] = `
10-
"__vue__options__.__i18n = [
11-
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}'
12-
]"
11+
Array [
12+
"Component.__i18n = Component.__i18n || [];",
13+
"Component.__i18n.push({\\"locale\\":\\"\\",\\"resource\\":{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}});",
14+
]
1315
`;
1416

1517
exports[`process (json-locale.vue) returns expected string: json-locale.vue 1`] = `
16-
"__vue__options__.__i18n = [
17-
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"}}',
18-
'{\\"en\\":{\\"hello\\":\\"hello!\\"}}'
19-
]"
18+
Array [
19+
"Component.__i18n = Component.__i18n || [];",
20+
"Component.__i18n.push({\\"locale\\":\\"ja\\",\\"resource\\":{\\"hello\\":\\"こんにちは!\\"}});",
21+
"Component.__i18n.push({\\"locale\\":\\"en\\",\\"resource\\":{\\"hello\\":\\"hello!\\"}});",
22+
]
2023
`;
2124

2225
exports[`process (json-src-import.vue) returns expected string: json-src-import.vue 1`] = `
23-
"__vue__options__.__i18n = [
24-
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}'
25-
]"
26+
Array [
27+
"Component.__i18n = Component.__i18n || [];",
28+
"Component.__i18n.push({\\"locale\\":\\"\\",\\"resource\\":{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}});",
29+
]
2630
`;
2731

2832
exports[`process (json5.vue) returns expected string: json5.vue 1`] = `
29-
"__vue__options__.__i18n = [
30-
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}'
31-
]"
33+
Array [
34+
"Component.__i18n = Component.__i18n || [];",
35+
"Component.__i18n.push({\\"locale\\":\\"\\",\\"resource\\":{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}});",
36+
]
3237
`;
3338

3439
exports[`process (json5-locale.vue) returns expected string: json5-locale.vue 1`] = `
35-
"__vue__options__.__i18n = [
36-
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"}}',
37-
'{\\"en\\":{\\"hello\\":\\"hello!\\"}}'
38-
]"
40+
Array [
41+
"Component.__i18n = Component.__i18n || [];",
42+
"Component.__i18n.push({\\"locale\\":\\"ja\\",\\"resource\\":{\\"hello\\":\\"こんにちは!\\"}});",
43+
"Component.__i18n.push({\\"locale\\":\\"en\\",\\"resource\\":{\\"hello\\":\\"hello!\\"}});",
44+
]
3945
`;
4046

4147
exports[`process (json5-src-import.vue) returns expected string: json5-src-import.vue 1`] = `
42-
"__vue__options__.__i18n = [
43-
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}'
44-
]"
48+
Array [
49+
"Component.__i18n = Component.__i18n || [];",
50+
"Component.__i18n.push({\\"locale\\":\\"\\",\\"resource\\":{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}});",
51+
]
4552
`;
4653

47-
exports[`process (no-i18n.vue) returns expected string: no-i18n.vue 1`] = `""`;
54+
exports[`process (no-i18n.vue) returns expected string: no-i18n.vue 1`] = `Array []`;
4855

4956
exports[`process (yaml.vue) returns expected string: yaml.vue 1`] = `
50-
"__vue__options__.__i18n = [
51-
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}'
52-
]"
57+
Array [
58+
"Component.__i18n = Component.__i18n || [];",
59+
"Component.__i18n.push({\\"locale\\":\\"\\",\\"resource\\":{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}});",
60+
]
5361
`;
5462

5563
exports[`process (yaml-locale.vue) returns expected string: yaml-locale.vue 1`] = `
56-
"__vue__options__.__i18n = [
57-
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"}}',
58-
'{\\"en\\":{\\"hello\\":\\"hello!\\"}}'
59-
]"
64+
Array [
65+
"Component.__i18n = Component.__i18n || [];",
66+
"Component.__i18n.push({\\"locale\\":\\"ja\\",\\"resource\\":{\\"hello\\":\\"こんにちは!\\"}});",
67+
"Component.__i18n.push({\\"locale\\":\\"en\\",\\"resource\\":{\\"hello\\":\\"hello!\\"}});",
68+
]
6069
`;
6170

6271
exports[`process (yaml-src-import.vue) returns expected string: yaml-src-import.vue 1`] = `
63-
"__vue__options__.__i18n = [
64-
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}'
65-
]"
72+
Array [
73+
"Component.__i18n = Component.__i18n || [];",
74+
"Component.__i18n.push({\\"locale\\":\\"\\",\\"resource\\":{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}});",
75+
]
6676
`;

test/process.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ describe('process', () => {
2424
const fileContent = readFileSync(filePath).toString()
2525
const { customBlocks: blocks } = parseComponent(fileContent)
2626

27-
const code = process({ blocks, vueOptionsNamespace: '__vue__options__', filename: filePath })
27+
const code = process({ blocks, componentNamespace: 'Component', filename: filePath })
2828

2929
expect(code).toMatchSnapshot(file)
3030
})

0 commit comments

Comments
 (0)