Skip to content
This repository has been archived by the owner on Dec 4, 2024. It is now read-only.

Support vue-jest@v5 #43

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@
"@vue/test-utils": "^1.0.4",
"jest": "^26.x",
"vue-i18n-jest": "file:../",
"vue-jest": "^4.0.0-beta.3"
"vue-jest": "^5.0.0-alpha.10"
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"main": "./lib/index.js",
"peerDependencies": {
"vue": "^2.5",
"vue-jest": "^4.0.0-beta.3",
"vue-jest": "^5.0.0-alpha.10",
"vue-template-compiler": "^2.5"
},
"repository": {
Expand Down
64 changes: 31 additions & 33 deletions src/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,74 +14,72 @@ type ProcessParameter = {
/** All of the blocks matching your type, returned from `@vue/component-compiler-utils` */
blocks: SFCCustomBlock[]
/** The internal namespace for a component's Vue Options in vue-jest */
vueOptionsNamespace: string
componentNamespace: string
/** The SFC file being processed */
filename: string
}

const VUE_I18N_OPTION = '__i18n'
const VUE_I18N_BLOCK_TYPE = 'i18n'

type JsonI18nBlockMessages = Record<string, unknown>

/**
* Process vue-i18n contents inside of a custom block and prepare it for execution in a testing environment.
*/
export default function process ({ blocks, vueOptionsNamespace, filename }: ProcessParameter) : string {
const i18nResources = blocks.map(block => {
if (block.type !== 'i18n') return

const value = parseI18nBlockToJSON(block, filename)
.replace(/\u2028/g, '\\u2028') // LINE SEPARATOR
.replace(/\u2029/g, '\\u2029') // PARAGRAPH SEPARATOR
.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'")
return `'${value}'`
}).filter((s): s is string => !!s)

// vueOptions.__i18n = [
// '<json encoded block 1>',
// '<json encoded block 2>'
// ]
const i18nOption = `${vueOptionsNamespace}.${VUE_I18N_OPTION}`
const code = i18nResources.length ? `${i18nOption} = [\n${i18nResources.join(',\n')}\n]` : ''
debug('generatedCode', code)
return code
export default function process ({ blocks, componentNamespace, filename }: ProcessParameter): string[] {
const i18nOption = `${componentNamespace}.${VUE_I18N_OPTION}`
const generatedCode = blocks
.reduce((blocksValues, block) => {
if (block.type !== VUE_I18N_BLOCK_TYPE) return blocksValues

const i18nBlockConfig = {
locale: (block.attrs && block.attrs.locale) || '',
resource: parseI18nBlockToJSON(block, filename)
}

return blocksValues.concat(`${i18nOption}.push(${JSON.stringify(i18nBlockConfig)});`)
}, [] as string[])

if (generatedCode.length > 0) {
generatedCode.unshift(`${i18nOption} = ${i18nOption} || [];`)
}

debug('generatedCode', generatedCode)

return generatedCode
}

/**
* Parse custom `<i18n>` block content to JSON string.
* @param block SFC block returned from `@vue/component-compiler-utils`
* @param filename The SFC file being processed
*/
function parseI18nBlockToJSON (block: SFCCustomBlock, filename: string): string {
function parseI18nBlockToJSON (block: SFCCustomBlock, filename: string): JsonI18nBlockMessages {
const lang = block.attrs && block.attrs.lang
const locale = block.attrs && block.attrs.locale
const src = block.attrs && block.attrs.src
const content = src
? readFileSync(getAbsolutePath(src, filename)).toString()
: block.content

return convertToJSON(content, lang, locale)
return convertToJSON(content, lang)
}

/**
* Convert JSON/YAML/JSON5 to minified JSON string.
* @param source JSON/YAML/JSON5 encoded string
* @param lang Language used in `source`. Supported JSON, YAML or JSON5.
* @param locale Attribute "locale" on <i18n> block will be added.
* @returns {string} A minified JSON string
*/
function convertToJSON (source: string, lang: string, locale: string): string {
const stringify = locale
? (parseResult: any) => JSON.stringify({ [locale]: parseResult })
: JSON.stringify

function convertToJSON (source: string, lang: string): JsonI18nBlockMessages {
switch (lang) {
case 'yaml':
case 'yml':
return stringify(parseYAML(source))
return parseYAML(source) as JsonI18nBlockMessages
case 'json5':
return stringify(parseJSON5(source))
return parseJSON5(source)
default: // fallback to 'json'
return stringify(JSON.parse(source))
return JSON.parse(source)
}
}

Expand Down
78 changes: 44 additions & 34 deletions test/__snapshots__/process.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,66 +1,76 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

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

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

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

exports[`process (json-src-import.vue) returns expected string: json-src-import.vue 1`] = `
"__vue__options__.__i18n = [
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}'
]"
Array [
"Component.__i18n = Component.__i18n || [];",
"Component.__i18n.push({\\"locale\\":\\"\\",\\"resource\\":{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}});",
]
`;

exports[`process (json5.vue) returns expected string: json5.vue 1`] = `
"__vue__options__.__i18n = [
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}'
]"
Array [
"Component.__i18n = Component.__i18n || [];",
"Component.__i18n.push({\\"locale\\":\\"\\",\\"resource\\":{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}});",
]
`;

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

exports[`process (json5-src-import.vue) returns expected string: json5-src-import.vue 1`] = `
"__vue__options__.__i18n = [
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}'
]"
Array [
"Component.__i18n = Component.__i18n || [];",
"Component.__i18n.push({\\"locale\\":\\"\\",\\"resource\\":{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}});",
]
`;

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

exports[`process (yaml.vue) returns expected string: yaml.vue 1`] = `
"__vue__options__.__i18n = [
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}'
]"
Array [
"Component.__i18n = Component.__i18n || [];",
"Component.__i18n.push({\\"locale\\":\\"\\",\\"resource\\":{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}});",
]
`;

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

exports[`process (yaml-src-import.vue) returns expected string: yaml-src-import.vue 1`] = `
"__vue__options__.__i18n = [
'{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}'
]"
Array [
"Component.__i18n = Component.__i18n || [];",
"Component.__i18n.push({\\"locale\\":\\"\\",\\"resource\\":{\\"ja\\":{\\"hello\\":\\"こんにちは!\\"},\\"en\\":{\\"hello\\":\\"hello!\\"}}});",
]
`;
2 changes: 1 addition & 1 deletion test/process.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('process', () => {
const fileContent = readFileSync(filePath).toString()
const { customBlocks: blocks } = parseComponent(fileContent)

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

expect(code).toMatchSnapshot(file)
})
Expand Down