Skip to content

Commit

Permalink
refactor: adjust createApp related API signatures
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `createApp` API has been adjusted.

  - `createApp()` now accepts the root component, and optionally a props
  object to pass to the root component.
  - `app.mount()` now accepts a single argument (the root container)
  - `app.unmount()` no longer requires arguments.

  New behavior looks like the following:

  ``` js
  const app = createApp(RootComponent)
  app.mount('#app')
  app.unmount()
  ```
  • Loading branch information
yyx990803 committed Jan 27, 2020
1 parent eacd390 commit c07751f
Show file tree
Hide file tree
Showing 25 changed files with 276 additions and 326 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,18 @@ describe('api: createApp', () => {
}

const root1 = nodeOps.createElement('div')
createApp().mount(Comp, root1)
createApp(Comp).mount(root1)
expect(serializeInner(root1)).toBe(`0`)

// mount with props
const root2 = nodeOps.createElement('div')
const app2 = createApp()
app2.mount(Comp, root2, { count: 1 })
const app2 = createApp(Comp, { count: 1 })
app2.mount(root2)
expect(serializeInner(root2)).toBe(`1`)

// remount warning
const root3 = nodeOps.createElement('div')
app2.mount(Comp, root3)
app2.mount(root3)
expect(serializeInner(root3)).toBe(``)
expect(`already been mounted`).toHaveBeenWarned()
})
Expand All @@ -59,18 +59,14 @@ describe('api: createApp', () => {
}

const root = nodeOps.createElement('div')
const app = createApp()
app.mount(Comp, root)
const app = createApp(Comp)
app.mount(root)

app.unmount(root)
expect(serializeInner(root)).toBe(``)
})

test('provide', () => {
const app = createApp()
app.provide('foo', 1)
app.provide('bar', 2)

const Root = {
setup() {
// test override
Expand All @@ -87,25 +83,16 @@ describe('api: createApp', () => {
}
}

const app = createApp(Root)
app.provide('foo', 1)
app.provide('bar', 2)

const root = nodeOps.createElement('div')
app.mount(Root, root)
app.mount(root)
expect(serializeInner(root)).toBe(`3,2`)
})

test('component', () => {
const app = createApp()

const FooBar = () => 'foobar!'
app.component('FooBar', FooBar)
expect(app.component('FooBar')).toBe(FooBar)

app.component('BarBaz', () => 'barbaz!')

app.component('BarBaz', () => 'barbaz!')
expect(
'Component "BarBaz" has already been registered in target app.'
).toHaveBeenWarnedTimes(1)

const Root = {
// local override
components: {
Expand All @@ -122,33 +109,29 @@ describe('api: createApp', () => {
}
}

const app = createApp(Root)

const FooBar = () => 'foobar!'
app.component('FooBar', FooBar)
expect(app.component('FooBar')).toBe(FooBar)

app.component('BarBaz', () => 'barbaz!')

app.component('BarBaz', () => 'barbaz!')
expect(
'Component "BarBaz" has already been registered in target app.'
).toHaveBeenWarnedTimes(1)

const root = nodeOps.createElement('div')
app.mount(Root, root)
app.mount(root)
expect(serializeInner(root)).toBe(`<div>foobar!barbaz-local!</div>`)
})

test('directive', () => {
const app = createApp()

const spy1 = jest.fn()
const spy2 = jest.fn()
const spy3 = jest.fn()

const FooBar = { mounted: spy1 }
app.directive('FooBar', FooBar)
expect(app.directive('FooBar')).toBe(FooBar)

app.directive('BarBaz', {
mounted: spy2
})

app.directive('BarBaz', {
mounted: spy2
})
expect(
'Directive "BarBaz" has already been registered in target app.'
).toHaveBeenWarnedTimes(1)

const Root = {
// local override
directives: {
Expand All @@ -165,8 +148,25 @@ describe('api: createApp', () => {
}
}

const app = createApp(Root)

const FooBar = { mounted: spy1 }
app.directive('FooBar', FooBar)
expect(app.directive('FooBar')).toBe(FooBar)

app.directive('BarBaz', {
mounted: spy2
})

app.directive('BarBaz', {
mounted: spy2
})
expect(
'Directive "BarBaz" has already been registered in target app.'
).toHaveBeenWarnedTimes(1)

const root = nodeOps.createElement('div')
app.mount(Root, root)
app.mount(root)
expect(spy1).toHaveBeenCalled()
expect(spy2).not.toHaveBeenCalled()
expect(spy3).toHaveBeenCalled()
Expand Down Expand Up @@ -232,7 +232,7 @@ describe('api: createApp', () => {
}
}

const app = createApp()
const app = createApp(Comp)
app.mixin(mixinA)
app.mixin(mixinB)

Expand All @@ -246,7 +246,7 @@ describe('api: createApp', () => {
).toHaveBeenWarnedTimes(1)

const root = nodeOps.createElement('div')
app.mount(Comp, root)
app.mount(root)

expect(serializeInner(root)).toBe(`123`)
expect(calls).toEqual([
Expand All @@ -272,20 +272,21 @@ describe('api: createApp', () => {
}
const PluginD: any = undefined

const app = createApp()
app.use(PluginA)
app.use(PluginB, 1, 1)
app.use(PluginC)

const Root = {
setup() {
const foo = inject('foo')
const bar = inject('bar')
return () => `${foo},${bar}`
}
}

const app = createApp(Root)
app.use(PluginA)
app.use(PluginB, 1, 1)
app.use(PluginC)

const root = nodeOps.createElement('div')
app.mount(Root, root)
app.mount(root)
expect(serializeInner(root)).toBe(`1,2`)

app.use(PluginA)
Expand All @@ -301,18 +302,14 @@ describe('api: createApp', () => {
})

test('config.errorHandler', () => {
const app = createApp()

const error = new Error()
const count = ref(0)

const handler = (app.config.errorHandler = jest.fn(
(err, instance, info) => {
expect(err).toBe(error)
expect((instance as any).count).toBe(count.value)
expect(info).toBe(`render function`)
}
))
const handler = jest.fn((err, instance, info) => {
expect(err).toBe(error)
expect((instance as any).count).toBe(count.value)
expect(info).toBe(`render function`)
})

const Root = {
setup() {
Expand All @@ -326,21 +323,19 @@ describe('api: createApp', () => {
}
}

app.mount(Root, nodeOps.createElement('div'))
const app = createApp(Root)
app.config.errorHandler = handler
app.mount(nodeOps.createElement('div'))
expect(handler).toHaveBeenCalled()
})

test('config.warnHandler', () => {
const app = createApp()
let ctx: any

const handler = (app.config.warnHandler = jest.fn(
(msg, instance, trace) => {
expect(msg).toMatch(`Component is missing template or render function`)
expect(instance).toBe(ctx.proxy)
expect(trace).toMatch(`Hello`)
}
))
const handler = jest.fn((msg, instance, trace) => {
expect(msg).toMatch(`Component is missing template or render function`)
expect(instance).toBe(ctx.proxy)
expect(trace).toMatch(`Hello`)
})

const Root = {
name: 'Hello',
Expand All @@ -349,112 +344,92 @@ describe('api: createApp', () => {
}
}

app.mount(Root, nodeOps.createElement('div'))
const app = createApp(Root)
app.config.warnHandler = handler
app.mount(nodeOps.createElement('div'))
expect(handler).toHaveBeenCalledTimes(1)
})

describe('config.isNativeTag', () => {
const isNativeTag = jest.fn(tag => tag === 'div')

test('Component.name', () => {
const app = createApp()
Object.defineProperty(app.config, 'isNativeTag', {
value: isNativeTag,
writable: false
})

const Root = {
name: 'div',
setup() {
return {
count: ref(0)
}
},
render() {
return null
}
}

app.mount(Root, nodeOps.createElement('div'))
expect(
`Do not use built-in or reserved HTML elements as component id: div`
).toHaveBeenWarned()
})
const app = createApp(Root)

test('Component.components', () => {
const app = createApp()
Object.defineProperty(app.config, 'isNativeTag', {
value: isNativeTag,
writable: false
})

app.mount(nodeOps.createElement('div'))
expect(
`Do not use built-in or reserved HTML elements as component id: div`
).toHaveBeenWarned()
})

test('Component.components', () => {
const Root = {
components: {
div: () => 'div'
},
setup() {
return {
count: ref(0)
}
},
render() {
return null
}
}

app.mount(Root, nodeOps.createElement('div'))
const app = createApp(Root)
Object.defineProperty(app.config, 'isNativeTag', {
value: isNativeTag,
writable: false
})

app.mount(nodeOps.createElement('div'))
expect(
`Do not use built-in or reserved HTML elements as component id: div`
).toHaveBeenWarned()
})

test('Component.directives', () => {
const app = createApp()
Object.defineProperty(app.config, 'isNativeTag', {
value: isNativeTag,
writable: false
})

const Root = {
directives: {
bind: () => {}
},
setup() {
return {
count: ref(0)
}
},
render() {
return null
}
}

app.mount(Root, nodeOps.createElement('div'))
const app = createApp(Root)
Object.defineProperty(app.config, 'isNativeTag', {
value: isNativeTag,
writable: false
})

app.mount(nodeOps.createElement('div'))
expect(
`Do not use built-in directive ids as custom directive id: bind`
).toHaveBeenWarned()
})

test('register using app.component', () => {
const app = createApp()
const app = createApp({
render() {}
})

Object.defineProperty(app.config, 'isNativeTag', {
value: isNativeTag,
writable: false
})

const Root = {
setup() {
return {
count: ref(0)
}
},
render() {
return null
}
}

app.component('div', () => 'div')
app.mount(Root, nodeOps.createElement('div'))
app.mount(nodeOps.createElement('div'))
expect(
`Do not use built-in or reserved HTML elements as component id: div`
).toHaveBeenWarned()
Expand Down
Loading

0 comments on commit c07751f

Please sign in to comment.