diff --git a/package.json b/package.json
index 09af3ed7f70..085e2890989 100644
--- a/package.json
+++ b/package.json
@@ -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": {
diff --git a/test/weex/cases/cases.spec.js b/test/weex/cases/cases.spec.js
new file mode 100644
index 00000000000..291600dfb24
--- /dev/null
+++ b/test/weex/cases/cases.spec.js
@@ -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'))
+ })
+})
+
diff --git a/test/weex/cases/event/click.after.vdom.js b/test/weex/cases/event/click.after.vdom.js
new file mode 100644
index 00000000000..eab1a36e7a3
--- /dev/null
+++ b/test/weex/cases/event/click.after.vdom.js
@@ -0,0 +1,10 @@
+({
+ type: 'div',
+ event: ['click'],
+ children: [{
+ type: 'text',
+ attr: {
+ value: '43'
+ }
+ }]
+})
diff --git a/test/weex/cases/event/click.before.vdom.js b/test/weex/cases/event/click.before.vdom.js
new file mode 100644
index 00000000000..de278b3a100
--- /dev/null
+++ b/test/weex/cases/event/click.before.vdom.js
@@ -0,0 +1,10 @@
+({
+ type: 'div',
+ event: ['click'],
+ children: [{
+ type: 'text',
+ attr: {
+ value: '42'
+ }
+ }]
+})
diff --git a/test/weex/cases/event/click.vue b/test/weex/cases/event/click.vue
new file mode 100644
index 00000000000..508782c59e7
--- /dev/null
+++ b/test/weex/cases/event/click.vue
@@ -0,0 +1,20 @@
+
+
+ {{count}}
+
+
+
+
diff --git a/test/weex/cases/render/sample.vdom.js b/test/weex/cases/render/sample.vdom.js
new file mode 100644
index 00000000000..6e213a506d9
--- /dev/null
+++ b/test/weex/cases/render/sample.vdom.js
@@ -0,0 +1,17 @@
+({
+ type: 'div',
+ style: {
+ justifyContent: 'center'
+ },
+ children: [{
+ type: 'text',
+ attr: {
+ value: 'Yo'
+ },
+ style: {
+ color: '#41B883',
+ fontSize: '233px',
+ textAlign: 'center'
+ }
+ }]
+})
diff --git a/test/weex/cases/render/sample.vue b/test/weex/cases/render/sample.vue
new file mode 100644
index 00000000000..0251b3d6fba
--- /dev/null
+++ b/test/weex/cases/render/sample.vue
@@ -0,0 +1,23 @@
+
+
+ {{string}}
+
+
+
+
+
+
diff --git a/test/weex/helpers/index.js b/test/weex/helpers/index.js
index ca4b3436b60..653ded34c16 100644
--- a/test/weex/helpers/index.js
+++ b/test/weex/helpers/index.js
@@ -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) {