Skip to content

Commit b3aa588

Browse files
committed
Merge branch 'master' of https://github.com/vuejs/vue-jest into update-jest
2 parents c41ce59 + 0b0d5e2 commit b3aa588

File tree

10 files changed

+1646
-2525
lines changed

10 files changed

+1646
-2525
lines changed

README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,65 @@ vue-jest compiles the script and template of SFCs into a JavaScript file that Je
5858

5959
You can change the behavior of `vue-jest` by using `jest.globals`.
6060

61+
#### Supporting custom blocks
62+
63+
A great feature of the Vue SFC compiler is that it can support custom blocks. You might want to use those blocks in your tests. To render out custom blocks for testing purposes, you'll need to write a transformer. Once you have your transformer, you'll add an entry to vue-jest's transform map. This is how [vue-i18n's](https://github.com/kazupon/vue-i18n) `<i18n>` custom blocks are supported in unit tests.
64+
65+
A `package.json` Example
66+
67+
```json
68+
{
69+
"jest": {
70+
"moduleFileExtensions": ["js", "json", "vue"],
71+
"transform": {
72+
"^.+\\.js$": "babel-jest",
73+
"^.+\\.vue$": "vue-jest"
74+
},
75+
"globals": {
76+
"vue-jest": {
77+
"transform": {
78+
"your-custom-block": "./custom-block-processor.js"
79+
}
80+
}
81+
}
82+
}
83+
}
84+
```
85+
6186
> _Tip:_ Need programmatic configuration? Use the [--config](https://jestjs.io/docs/en/cli.html#config-path) option in Jest CLI, and export a `.js` file
6287
88+
A `jest.config.js` Example - If you're using a dedicated configuration file like you can reference and require your processor in the config file instead of using a file reference.
89+
90+
```js
91+
module.exports = {
92+
globals: {
93+
'vue-jest': {
94+
transform: {
95+
'your-custom-block': require('./custom-block-processor')
96+
}
97+
}
98+
}
99+
}
100+
```
101+
102+
#### Writing a processor
103+
104+
Processors must return an object with a "process" method, like so...
105+
106+
```js
107+
module.exports = {
108+
/**
109+
* Process the content inside of a custom block and prepare it for execution in a testing environment
110+
* @param {SFCCustomBlock[]} blocks All of the blocks matching your type, returned from `@vue/component-compiler-utils`
111+
* @param {string} vueOptionsNamespace The internal namespace for a component's Vue Options in vue-jest
112+
* @param {string} filename The SFC file being processed
113+
* @param {Object} config The full Jest config
114+
* @returns {string} The code to be output after processing all of the blocks matched by this type
115+
*/
116+
process(blocks, vueOptionsNamepsace, filename, config) {}
117+
}
118+
```
119+
63120
#### babelConfig
64121

65122
Provide `babelConfig` in one of the following formats:

lib/constants.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
vueOptionsNamespace: '__options__',
3+
defaultVueJestConfig: {
4+
transform: {}
5+
}
6+
}

lib/generate-code.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
const namespace = require('./constants').vueOptionsNamespace
2+
13
const splitRE = /\r?\n/g
24

35
module.exports = function generateCode(
46
scriptResult,
57
templateResult,
68
stylesResult,
9+
customBlocksResult,
710
isFunctional
811
) {
912
let output = ''
@@ -21,7 +24,7 @@ module.exports = function generateCode(
2124
}
2225

2326
output +=
24-
`var __options__ = typeof exports.default === 'function' ` +
27+
`var ${namespace} = typeof exports.default === 'function' ` +
2528
`? exports.default.options ` +
2629
`: exports.default\n`
2730

@@ -37,11 +40,11 @@ module.exports = function generateCode(
3740

3841
output +=
3942
`__options__.render = render\n` +
40-
`__options__.staticRenderFns = staticRenderFns\n`
43+
`${namespace}.staticRenderFns = staticRenderFns\n`
4144

4245
if (isFunctional) {
43-
output += '__options__.functional = true\n'
44-
output += '__options__._compiled = true\n'
46+
output += `${namespace}.functional = true\n`
47+
output += `${namespace}._compiled = true\n`
4548
}
4649
}
4750

@@ -59,22 +62,26 @@ module.exports = function generateCode(
5962
if (isFunctional) {
6063
output +=
6164
`;(function() {\n` +
62-
` var originalRender = __options__.render\n` +
65+
` var originalRender = ${namespace}.render\n` +
6366
` var styleFn = function () { ${styleStr} }\n` +
64-
` __options__.render = function renderWithStyleInjection (h, context) {\n` +
67+
` ${namespace}.render = function renderWithStyleInjection (h, context) {\n` +
6568
` styleFn.call(context)\n` +
6669
` return originalRender(h, context)\n` +
6770
` }\n` +
6871
`})()\n`
6972
} else {
7073
output +=
7174
`;(function() {\n` +
72-
` var beforeCreate = __options__.beforeCreate\n` +
75+
` var beforeCreate = ${namespace}.beforeCreate\n` +
7376
` var styleFn = function () { ${styleStr} }\n` +
74-
` __options__.beforeCreate = beforeCreate ? [].concat(beforeCreate, styleFn) : [styleFn]\n` +
77+
` ${namespace}.beforeCreate = beforeCreate ? [].concat(beforeCreate, styleFn) : [styleFn]\n` +
7578
`})()\n`
7679
}
7780
}
81+
82+
if (customBlocksResult) {
83+
output += `;\n ${customBlocksResult}`
84+
}
7885
return {
7986
code: output,
8087
renderFnStartLine,

lib/process-custom-blocks.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
const { getVueJestConfig, getCustomTransformer } = require('./utils')
2+
const vueOptionsNamespace = require('./constants').vueOptionsNamespace
3+
4+
function applyTransformer(
5+
transformer,
6+
blocks,
7+
vueOptionsNamespace,
8+
filename,
9+
config
10+
) {
11+
return transformer.process({ blocks, vueOptionsNamespace, filename, config })
12+
}
13+
14+
function groupByType(acc, block) {
15+
acc[block.type] = acc[block.type] || []
16+
acc[block.type].push(block)
17+
return acc
18+
}
19+
20+
module.exports = function(allBlocks, filename, config) {
21+
const blocksByType = allBlocks.reduce(groupByType, {})
22+
const code = []
23+
for (const [type, blocks] of Object.entries(blocksByType)) {
24+
const transformer = getCustomTransformer(
25+
getVueJestConfig(config).transform,
26+
type
27+
)
28+
if (transformer) {
29+
const codeStr = applyTransformer(
30+
transformer,
31+
blocks,
32+
vueOptionsNamespace,
33+
filename,
34+
config
35+
)
36+
code.push(codeStr)
37+
}
38+
}
39+
40+
return code.length ? code.join('\n') : ''
41+
}

lib/process.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ const splitRE = /\r?\n/g
22

33
const VueTemplateCompiler = require('vue-template-compiler')
44
const generateSourceMap = require('./generate-source-map')
5-
const typescriptTransformer = require('./typescript-transformer')
6-
const coffeescriptTransformer = require('./coffee-transformer')
5+
const typescriptTransformer = require('./transformers/typescript')
6+
const coffeescriptTransformer = require('./transformers/coffee')
77
const _processStyle = require('./process-style')
8+
const processCustomBlocks = require('./process-custom-blocks')
89
const getVueJestConfig = require('./utils').getVueJestConfig
910
const logResultErrors = require('./utils').logResultErrors
1011
const stripInlineSourceMap = require('./utils').stripInlineSourceMap
@@ -99,6 +100,11 @@ module.exports = function(src, filename, config) {
99100
const templateResult = processTemplate(descriptor.template, filename, config)
100101
const scriptResult = processScript(descriptor.script, filename, config)
101102
const stylesResult = processStyle(descriptor.styles, filename, config)
103+
const customBlocksResult = processCustomBlocks(
104+
descriptor.customBlocks,
105+
filename,
106+
config
107+
)
102108

103109
const isFunctional =
104110
descriptor.template &&
@@ -112,6 +118,7 @@ module.exports = function(src, filename, config) {
112118
scriptResult,
113119
templateResult,
114120
stylesResult,
121+
customBlocksResult,
115122
isFunctional
116123
)
117124

lib/coffee-transformer.js renamed to lib/transformers/coffee.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
const ensureRequire = require('./ensure-require.js')
2-
const throwError = require('./utils').throwError
3-
const getBabelOptions = require('./utils').getBabelOptions
1+
const ensureRequire = require('../ensure-require.js')
2+
const throwError = require('../utils').throwError
3+
const getBabelOptions = require('../utils').getBabelOptions
44

55
module.exports = {
66
process(src, filename, config) {

lib/typescript-transformer.js renamed to lib/transformers/typescript.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
const ensureRequire = require('./ensure-require')
1+
const ensureRequire = require('../ensure-require')
22
const babelJest = require('babel-jest')
3-
const getBabelOptions = require('./utils').getBabelOptions
4-
const getTsJestConfig = require('./utils').getTsJestConfig
5-
const stripInlineSourceMap = require('./utils').stripInlineSourceMap
6-
const getCustomTransformer = require('./utils').getCustomTransformer
7-
const getVueJestConfig = require('./utils').getVueJestConfig
3+
const {
4+
getBabelOptions,
5+
getTsJestConfig,
6+
stripInlineSourceMap,
7+
getCustomTransformer,
8+
getVueJestConfig
9+
} = require('../utils')
810

911
module.exports = {
1012
process(scriptContent, filePath, config) {

lib/utils.js

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const constants = require('./constants')
12
const loadPartialConfig = require('@babel/core').loadPartialConfig
23
const chalk = require('chalk')
34
const path = require('path')
@@ -83,19 +84,32 @@ const getCustomTransformer = function getCustomTransformer(
8384
transform = {},
8485
lang
8586
) {
86-
let transformerPath = fetchTransformer(lang, transform)
87-
if (transformerPath) {
88-
const transformer = require(resolvePath(transformerPath))
89-
90-
if (!isValidTransformer(transformer)) {
91-
throwError(
92-
`transformer must contain at least one process, preprocess, or ` +
93-
`postprocess method`
94-
)
95-
}
96-
return transformer
87+
transform = { ...constants.defaultVueJestConfig.transform, ...transform }
88+
89+
const transformerPath = fetchTransformer(lang, transform)
90+
91+
if (!transformerPath) {
92+
return null
9793
}
98-
return null
94+
95+
let transformer
96+
if (
97+
typeof transformerPath === 'string' &&
98+
require(resolvePath(transformerPath))
99+
) {
100+
transformer = require(resolvePath(transformerPath))
101+
} else if (typeof transformerPath === 'object') {
102+
transformer = transformerPath
103+
}
104+
105+
if (!isValidTransformer(transformer)) {
106+
throwError(
107+
`transformer must contain at least one process, preprocess, or ` +
108+
`postprocess method`
109+
)
110+
}
111+
112+
return transformer
99113
}
100114

101115
const throwError = function error(msg) {

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@
7272
"chalk": "^2.1.0",
7373
"convert-source-map": "^1.6.0",
7474
"extract-from-css": "^0.4.4",
75-
"source-map": "^0.5.6",
7675
"ts-jest": "^25.2.1"
7776
},
7877
"repository": {

0 commit comments

Comments
 (0)