You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

670 lines
18 KiB

import * as framework from '../../../packages/weex-vue-framework'
import { DEFAULT_ENV, Runtime, Instance } from 'weex-vdom-tester'
import { config } from 'weex-js-runtime'
import {
syncPromise,
checkRefresh
} from '../helpers/index'
let sendTasksHandler = () => {}
const { Document, Element, Comment } = config
function sendTasks () {
sendTasksHandler.apply(null, arguments)
}
describe('framework APIs', () => {
let runtime
beforeEach(() => {
Document.handler = sendTasks
framework.init({ Document, Element, Comment, sendTasks })
runtime = new Runtime(framework)
sendTasksHandler = function () {
runtime.target.callNative(...arguments)
}
})
afterEach(() => {
delete Document.handler
framework.reset()
})
it('createInstance', () => {
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
new Vue({
render: function (createElement) {
return createElement('div', {}, [
createElement('text', { attrs: { value: 'Hello' }}, [])
])
},
el: "body"
})
`)
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{ type: 'text', attr: { value: 'Hello' }}]
})
})
it('createInstance with config', () => {
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
new Vue({
render: function (createElement) {
return createElement('div', {}, [
createElement('text', { attrs: { value: JSON.stringify(this.$getConfig()) }}, [])
])
},
el: "body"
})
`, { bundleUrl: 'http://example.com/', a: 1, b: 2 })
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{ type: 'text', attr: { value: '{"bundleUrl":"http://example.com/","a":1,"b":2}' }}]
})
})
it('createInstance with external data', () => {
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
new Vue({
data: {
a: 1,
b: 2
},
render: function (createElement) {
return createElement('div', {}, [
createElement('text', { attrs: { value: this.a + '-' + this.b }}, [])
])
},
el: "body"
})
`, undefined, { a: 111 })
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{ type: 'text', attr: { value: '111-2' }}]
})
})
it('destroyInstance', (done) => {
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
new Vue({
data: {
x: 'Hello'
},
render: function (createElement) {
return createElement('div', {}, [
createElement('text', { attrs: { value: this.x }}, [])
])
},
el: "body"
})
`)
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{ type: 'text', attr: { value: 'Hello' }}]
})
syncPromise([
checkRefresh(instance, { x: 'World' }, result => {
expect(result).toEqual({
type: 'div',
children: [{ type: 'text', attr: { value: 'World' }}]
})
framework.destroyInstance(instance.id)
}),
checkRefresh(instance, { x: 'Weex' }, result => {
expect(result).toEqual({
type: 'div',
children: [{ type: 'text', attr: { value: 'World' }}]
})
done()
})
])
})
it('refreshInstance', (done) => {
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
new Vue({
data: {
x: 'Hello'
},
render: function (createElement) {
return createElement('div', {}, [
createElement('text', { attrs: { value: this.x }}, [])
])
},
el: "body"
})
`)
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{ type: 'text', attr: { value: 'Hello' }}]
})
framework.refreshInstance(instance.id, { x: 'World' })
setTimeout(() => {
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{ type: 'text', attr: { value: 'World' }}]
})
framework.destroyInstance(instance.id)
const result = framework.refreshInstance(instance.id, { x: 'Weex' })
expect(result instanceof Error).toBe(true)
expect(result).toMatch(/refreshInstance/)
expect(result).toMatch(/not found/)
setTimeout(() => {
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{ type: 'text', attr: { value: 'World' }}]
})
done()
})
})
})
it('getRoot', () => {
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
new Vue({
data: {
x: 'Hello'
},
render: function (createElement) {
return createElement('div', {}, [
createElement('text', { attrs: { value: this.x }}, [])
])
},
el: "body"
})
`)
let root = framework.getRoot(instance.id)
expect(root.ref).toEqual('_root')
expect(root.type).toEqual('div')
expect(root.children.length).toEqual(1)
expect(root.children[0].type).toEqual('text')
expect(root.children[0].attr).toEqual({ value: 'Hello' })
framework.destroyInstance(instance.id)
root = framework.getRoot(instance.id)
expect(root instanceof Error).toBe(true)
expect(root).toMatch(/getRoot/)
expect(root).toMatch(/not found/)
})
it('reveiveTasks: fireEvent', (done) => {
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
new Vue({
data: {
x: 'Hello'
},
methods: {
update: function (e) {
this.x = 'World'
}
},
render: function (createElement) {
return createElement('div', {}, [
createElement('text', { attrs: { value: this.x }, on: { click: this.update }}, [])
])
},
el: "body"
})
`)
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{
type: 'text',
attr: { value: 'Hello' },
event: ['click']
}]
})
const textRef = framework.getRoot(instance.id).children[0].ref
framework.receiveTasks(instance.id, [
{ method: 'fireEvent', args: [textRef, 'click'] }
])
setTimeout(() => {
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{
type: 'text',
attr: { value: 'World' },
event: ['click']
}]
})
framework.destroyInstance(instance.id)
const result = framework.receiveTasks(instance.id, [
{ method: 'fireEvent', args: [textRef, 'click'] }
])
expect(result instanceof Error).toBe(true)
expect(result).toMatch(/receiveTasks/)
expect(result).toMatch(/not found/)
done()
})
})
it('reveiveTasks: callback', (done) => {
framework.registerModules({
foo: ['a', 'b', 'c']
})
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
const moduleFoo = __weex_require_module__('foo')
new Vue({
data: {
x: 'Hello'
},
methods: {
update: function (data = {}) {
this.x = data.value || 'World'
}
},
mounted: function () {
moduleFoo.a(data => {
this.update(data)
})
},
render: function (createElement) {
return createElement('div', {}, [
createElement('text', { attrs: { value: this.x }}, [])
])
},
el: "body"
})
`)
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{
type: 'text',
attr: { value: 'Hello' }
}]
})
let callbackId
instance.history.callNative.some(task => {
if (task.module === 'foo' && task.method === 'a') {
callbackId = task.args[0]
return true
}
})
framework.receiveTasks(instance.id, [
{ method: 'callback', args: [callbackId, undefined, true] }
])
setTimeout(() => {
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{
type: 'text',
attr: { value: 'World' }
}]
})
framework.receiveTasks(instance.id, [
{ method: 'callback', args: [callbackId, { value: 'Weex' }, true] }
])
setTimeout(() => {
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{
type: 'text',
attr: { value: 'Weex' }
}]
})
framework.receiveTasks(instance.id, [
{ method: 'callback', args: [callbackId] }
])
setTimeout(() => {
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{
type: 'text',
attr: { value: 'World' }
}]
})
framework.destroyInstance(instance.id)
const result = framework.receiveTasks(instance.id, [
{ method: 'callback', args: [callbackId] }
])
expect(result instanceof Error).toBe(true)
expect(result).toMatch(/receiveTasks/)
expect(result).toMatch(/not found/)
done()
})
})
})
})
it('registerModules', () => {
framework.registerModules({
foo: ['a', 'b', 'c'],
bar: [
{ name: 'a', args: ['string'] },
{ name: 'b', args: ['number'] },
{ name: 'c', args: ['string', 'number'] }
]
})
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
const moduleFoo = __weex_require_module__('foo')
const moduleBar = __weex_require_module__('bar')
const moduleBaz = __weex_require_module__('baz')
new Vue({
render: function (createElement) {
const value = []
if (typeof moduleFoo === 'object') {
value.push('foo')
value.push(Object.keys(moduleFoo))
}
if (typeof moduleBar === 'object') {
value.push('bar')
value.push(Object.keys(moduleBar))
}
if (typeof moduleBaz === 'object') {
value.push('baz')
value.push(Object.keys(moduleBaz))
}
return createElement('div', {}, [
createElement('text', { attrs: { value: value.toString() }}, [])
])
},
mounted: function () {
moduleFoo.a(1, '2', true)
moduleBar.b(1)
},
el: "body"
})
`)
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{
type: 'text',
attr: { value: 'foo,a,b,c,bar,a,b,c,baz,' }
}]
})
expect(instance.history.callNative
.filter(task => task.module === 'foo')
.map(task => `${task.method}(${task.args})`)
).toEqual(['a(1,2,true)'])
expect(instance.history.callNative
.filter(task => task.module === 'bar')
.map(task => `${task.method}(${task.args})`)
).toEqual(['b(1)'])
})
it('registerComponents', () => {
framework.registerComponents(['foo', { type: 'bar' }, 'text'])
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
new Vue({
render: function (createElement) {
return createElement('div', {}, [
createElement('text', {}, []),
createElement('foo', {}, []),
createElement('bar', {}, []),
createElement('baz', {}, [])
])
},
el: "body"
})
`)
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{ type: 'text' }, { type: 'foo' }, { type: 'bar' }, { type: 'baz' }]
})
})
it('vm.$getConfig', () => {
const instance = new Instance(runtime)
instance.$create(`
new Vue({
render: function (createElement) {
return createElement('div', {}, [
createElement('text', { attrs: { value: JSON.stringify(this.$getConfig()) }}, [])
])
},
el: "body"
})
`)
expect(JSON.parse(instance.getRealRoot().children[0].attr.value)).toEqual({ env: DEFAULT_ENV })
const instance2 = new Instance(runtime)
instance2.$create(`
new Vue({
render: function (createElement) {
return createElement('div', {}, [
createElement('text', { attrs: { value: JSON.stringify(this.$getConfig()) }}, [])
])
},
el: "body"
})
`, { a: 1, b: 2 })
expect(JSON.parse(instance2.getRealRoot().children[0].attr.value)).toEqual({ a: 1, b: 2, env: DEFAULT_ENV })
})
it('Timer', (done) => {
const instance = new Instance(runtime)
instance.$create(`
new Vue({
data: {
x: 0,
y: 0
},
render: function (createElement) {
return createElement('div', {}, [
createElement('text', { attrs: { value: this.x + '-' + this.y }}, [])
])
},
mounted: function () {
const now = Date.now()
let timer, timer2
setTimeout(() => {
this.x = 1
clearTimeout(timer)
clearInterval(timer2)
setInterval(() => {
this.y++
}, 600)
}, 2000)
timer = setTimeout(() => {
this.x = 3
}, 3000)
setTimeout(() => {
this.x = 3
}, 4000)
timer2 = setInterval(() => {
this.y++
}, 900)
},
el: "body"
})
`)
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{ type: 'text', attr: { value: '0-0' }}]
})
setTimeout(() => {
expect(instance.getRealRoot().children[0].attr.value).toEqual('0-1')
}, 950)
setTimeout(() => {
expect(instance.getRealRoot().children[0].attr.value).toEqual('0-2')
}, 1850)
setTimeout(() => {
expect(instance.getRealRoot().children[0].attr.value).toEqual('1-2')
}, 2050)
setTimeout(() => {
expect(instance.getRealRoot().children[0].attr.value).toEqual('1-3')
}, 2650)
setTimeout(() => {
expect(instance.getRealRoot().children[0].attr.value).toEqual('1-4')
}, 3250)
setTimeout(() => {
framework.destroyInstance(instance.id)
}, 3500)
setTimeout(() => {
expect(instance.getRealRoot().children[0].attr.value).toEqual('1-4')
done()
}, 4100)
})
it('send function param', () => {
framework.registerModules({
foo: ['a']
})
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
const moduleFoo = __weex_require_module__('foo')
new Vue({
mounted: function () {
moduleFoo.a(a => a + 1)
},
render: function (createElement) {
return createElement('div', {}, [
createElement('text', { attrs: { value: 'Hello' }}, [])
])
},
el: "body"
})
`)
let callbackId
instance.history.callNative.some(task => {
if (task.module === 'foo' && task.method === 'a') {
callbackId = task.args[0]
return true
}
})
expect(typeof callbackId).toEqual('string')
})
it('send Element param', () => {
framework.registerModules({
foo: ['a']
})
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
const moduleFoo = __weex_require_module__('foo')
new Vue({
mounted: function () {
moduleFoo.a(this.$refs.x)
},
render: function (createElement) {
return createElement('div', {}, [
createElement('text', { attrs: { value: 'Hello' }, ref: 'x' }, [])
])
},
el: "body"
})
`)
let callbackId
instance.history.callNative.some(task => {
if (task.module === 'foo' && task.method === 'a') {
callbackId = task.args[0]
return true
}
})
expect(typeof callbackId).toEqual('string')
})
it('registering global assets', () => {
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
Vue.component('test', {
render (h) {
return h('div', 'Hello')
}
})
new Vue({
render (h) {
return h('test')
},
el: 'body'
})
`)
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{ type: 'text', attr: { value: 'Hello' }}]
})
// ensure base Vue is unaffected
expect(framework.Vue.options.components.test).toBeUndefined()
})
it('adding prototype methods', () => {
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
Vue.prototype.$test = () => 'Hello'
const Test = {
render (h) {
return h('div', this.$test())
}
}
new Vue({
render (h) {
return h(Test)
},
el: 'body'
})
`)
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{ type: 'text', attr: { value: 'Hello' }}]
})
// ensure base Vue is unaffected
expect(framework.Vue.prototype.$test).toBeUndefined()
})
it('using global mixins', () => {
const instance = new Instance(runtime)
framework.createInstance(instance.id, `
Vue.mixin({
created () {
this.test = true
}
})
const Test = {
data: () => ({ test: false }),
render (h) {
return h('div', this.test ? 'Hello' : 'nope')
}
}
new Vue({
data: { test: false },
render (h) {
return this.test ? h(Test) : h('p')
},
el: 'body'
})
`)
expect(instance.getRealRoot()).toEqual({
type: 'div',
children: [{ type: 'text', attr: { value: 'Hello' }}]
})
const vm = new framework.Vue({
data: { test: false }
})
expect(vm.test).toBe(false)
})
})