mirror of
https://gitee.com/vuejs/vue.git
synced 2024-12-03 12:38:24 +08:00
test(weex): support testing the virtual dom generated form *.vue files (#6944)
Compile the *.vue file into js code, then run it in Weex context, and compare the generate virtual dom. It’s a black-box testing for `weex-template-compiler`, `weex-styler`,`weex-vue-framework` and `weex-js-runtime`.
This commit is contained in:
parent
8a784d8d23
commit
232dd85f85
@ -125,7 +125,8 @@
|
||||
"typescript": "^2.5.2",
|
||||
"uglify-js": "^3.0.15",
|
||||
"webpack": "^2.6.1",
|
||||
"weex-js-runtime": "^0.23.0"
|
||||
"weex-js-runtime": "^0.23.0",
|
||||
"weex-styler": "^0.3.0"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
|
72
test/weex/cases/cases.spec.js
Normal file
72
test/weex/cases/cases.spec.js
Normal file
@ -0,0 +1,72 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import {
|
||||
compileVue,
|
||||
createInstance,
|
||||
getRoot,
|
||||
getEvents,
|
||||
fireEvent
|
||||
} from '../helpers'
|
||||
|
||||
function readFile (filename) {
|
||||
return fs.readFileSync(path.resolve(__dirname, filename), 'utf8')
|
||||
}
|
||||
|
||||
function readObject (filename) {
|
||||
return (new Function(`return ${readFile(filename)}`))()
|
||||
}
|
||||
|
||||
// Create one-off render test case
|
||||
function createRenderTestCase (name) {
|
||||
const source = readFile(`${name}.vue`)
|
||||
const target = readObject(`${name}.vdom.js`)
|
||||
return done => {
|
||||
compileVue(source).then(code => {
|
||||
const id = String(Date.now() * Math.random())
|
||||
const instance = createInstance(id, code)
|
||||
setTimeout(() => {
|
||||
expect(getRoot(instance)).toEqual(target)
|
||||
done()
|
||||
}, 50)
|
||||
}).catch(err => {
|
||||
expect(err).toBe(null)
|
||||
done()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Create event test case, will trigger the first bind event
|
||||
function createEventTestCase (name) {
|
||||
const source = readFile(`${name}.vue`)
|
||||
const before = readObject(`${name}.before.vdom.js`)
|
||||
const after = readObject(`${name}.after.vdom.js`)
|
||||
return done => {
|
||||
compileVue(source).then(code => {
|
||||
const id = String(Date.now() * Math.random())
|
||||
const instance = createInstance(id, code)
|
||||
setTimeout(() => {
|
||||
expect(getRoot(instance)).toEqual(before)
|
||||
const event = getEvents(instance)[0]
|
||||
fireEvent(instance, event.ref, event.type, {})
|
||||
setTimeout(() => {
|
||||
expect(getRoot(instance)).toEqual(after)
|
||||
done()
|
||||
}, 50)
|
||||
}, 50)
|
||||
}).catch(err => {
|
||||
expect(err).toBe(null)
|
||||
done()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
describe('Usage', () => {
|
||||
describe('render', () => {
|
||||
it('sample', createRenderTestCase('render/sample'))
|
||||
})
|
||||
|
||||
describe('event', () => {
|
||||
it('click', createEventTestCase('event/click'))
|
||||
})
|
||||
})
|
||||
|
10
test/weex/cases/event/click.after.vdom.js
Normal file
10
test/weex/cases/event/click.after.vdom.js
Normal file
@ -0,0 +1,10 @@
|
||||
({
|
||||
type: 'div',
|
||||
event: ['click'],
|
||||
children: [{
|
||||
type: 'text',
|
||||
attr: {
|
||||
value: '43'
|
||||
}
|
||||
}]
|
||||
})
|
10
test/weex/cases/event/click.before.vdom.js
Normal file
10
test/weex/cases/event/click.before.vdom.js
Normal file
@ -0,0 +1,10 @@
|
||||
({
|
||||
type: 'div',
|
||||
event: ['click'],
|
||||
children: [{
|
||||
type: 'text',
|
||||
attr: {
|
||||
value: '42'
|
||||
}
|
||||
}]
|
||||
})
|
20
test/weex/cases/event/click.vue
Normal file
20
test/weex/cases/event/click.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div @click="inc">
|
||||
<text>{{count}}</text>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
data () {
|
||||
return {
|
||||
count: 42
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
inc () {
|
||||
this.count++
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
17
test/weex/cases/render/sample.vdom.js
Normal file
17
test/weex/cases/render/sample.vdom.js
Normal file
@ -0,0 +1,17 @@
|
||||
({
|
||||
type: 'div',
|
||||
style: {
|
||||
justifyContent: 'center'
|
||||
},
|
||||
children: [{
|
||||
type: 'text',
|
||||
attr: {
|
||||
value: 'Yo'
|
||||
},
|
||||
style: {
|
||||
color: '#41B883',
|
||||
fontSize: '233px',
|
||||
textAlign: 'center'
|
||||
}
|
||||
}]
|
||||
})
|
23
test/weex/cases/render/sample.vue
Normal file
23
test/weex/cases/render/sample.vue
Normal file
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<div style="justify-content:center">
|
||||
<text class="freestyle">{{string}}</text>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.freestyle {
|
||||
color: #41B883;
|
||||
font-size: 233px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
data () {
|
||||
return {
|
||||
string: 'Yo'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,6 +1,11 @@
|
||||
import * as Vue from '../../../packages/weex-vue-framework'
|
||||
import { compile } from '../../../packages/weex-template-compiler'
|
||||
import WeexRuntime from 'weex-js-runtime'
|
||||
import styler from 'weex-styler'
|
||||
|
||||
const styleRE = /<\s*style\s*\w*>([^(<\/)]*)<\/\s*style\s*>/g
|
||||
const scriptRE = /<\s*script.*>([^]*)<\/\s*script\s*>/
|
||||
const templateRE = /<\s*template\s*>([^]*)<\/\s*template\s*>/
|
||||
|
||||
console.debug = () => {}
|
||||
|
||||
@ -10,6 +15,10 @@ export function strToRegExp (str) {
|
||||
return new RegExp(str.replace(matchOperatorsRe, '\\$&'))
|
||||
}
|
||||
|
||||
function parseStatic (fns) {
|
||||
return '[' + fns.map(fn => `function () { ${fn} }`).join(',') + ']'
|
||||
}
|
||||
|
||||
export function compileAndStringify (template) {
|
||||
const { render, staticRenderFns } = compile(template)
|
||||
return {
|
||||
@ -18,8 +27,48 @@ export function compileAndStringify (template) {
|
||||
}
|
||||
}
|
||||
|
||||
function parseStatic (fns) {
|
||||
return '[' + fns.map(fn => `function () { ${fn} }`).join(',') + ']'
|
||||
/**
|
||||
* Compile *.vue file into js code
|
||||
* @param {string} source raw text of *.vue file
|
||||
* @param {string} componentName whether compile to a component
|
||||
*/
|
||||
export function compileVue (source, componentName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!templateRE.test(source)) {
|
||||
return reject('No Template!')
|
||||
}
|
||||
const scriptMatch = scriptRE.exec(source)
|
||||
const script = scriptMatch ? scriptMatch[1] : ''
|
||||
const { render, staticRenderFns } = compile(templateRE.exec(source)[1])
|
||||
|
||||
const generateCode = styles => (`
|
||||
var test_case = Object.assign({
|
||||
style: ${JSON.stringify(styles)},
|
||||
render: function () { ${render} },
|
||||
staticRenderFns: ${parseStatic(staticRenderFns)},
|
||||
}, (function(){
|
||||
var module = { exports: {} };
|
||||
${script};
|
||||
return module.exports;
|
||||
})());
|
||||
` + (componentName
|
||||
? `Vue.component('${componentName}', test_case);\n`
|
||||
: `test_case.el = 'body';new Vue(test_case);`)
|
||||
)
|
||||
|
||||
let cssText = ''
|
||||
let styleMatch = null
|
||||
while ((styleMatch = styleRE.exec(source))) {
|
||||
cssText += `\n${styleMatch[1]}\n`
|
||||
}
|
||||
styler.parse(cssText, (error, result) => {
|
||||
if (error) {
|
||||
return reject(error)
|
||||
}
|
||||
resolve(generateCode(result.jsonStyle))
|
||||
})
|
||||
resolve(generateCode({}))
|
||||
})
|
||||
}
|
||||
|
||||
function isObject (object) {
|
||||
@ -47,6 +96,24 @@ export function getRoot (instance) {
|
||||
return omitUseless(instance.document.body.toJSON())
|
||||
}
|
||||
|
||||
// Get all binding events in the instance
|
||||
export function getEvents (instance) {
|
||||
const events = []
|
||||
const recordEvent = node => {
|
||||
if (!node) { return }
|
||||
if (Array.isArray(node.event)) {
|
||||
node.event.forEach(type => {
|
||||
events.push({ ref: node.ref, type })
|
||||
})
|
||||
}
|
||||
if (Array.isArray(node.children)) {
|
||||
node.children.forEach(recordEvent)
|
||||
}
|
||||
}
|
||||
recordEvent(instance.document.body.toJSON())
|
||||
return events
|
||||
}
|
||||
|
||||
export function fireEvent (instance, ref, type, event = {}) {
|
||||
const el = instance.document.getRef(ref)
|
||||
if (el) {
|
||||
|
Loading…
Reference in New Issue
Block a user