2019-11-23 07:09:26 +08:00
|
|
|
import {
|
|
|
|
describe,
|
|
|
|
h,
|
2019-12-22 23:58:12 +08:00
|
|
|
defineComponent,
|
2019-11-23 07:09:26 +08:00
|
|
|
ref,
|
|
|
|
Fragment,
|
2020-04-02 10:04:55 +08:00
|
|
|
Teleport,
|
2020-04-05 01:29:29 +08:00
|
|
|
Suspense,
|
2020-06-09 22:17:42 +08:00
|
|
|
Component,
|
|
|
|
expectError,
|
2020-10-21 03:56:29 +08:00
|
|
|
expectAssignable,
|
|
|
|
resolveComponent
|
2019-11-23 07:09:26 +08:00
|
|
|
} from './index'
|
2019-11-02 10:54:01 +08:00
|
|
|
|
2019-11-05 07:38:55 +08:00
|
|
|
describe('h inference w/ element', () => {
|
|
|
|
// key
|
|
|
|
h('div', { key: 1 })
|
|
|
|
h('div', { key: 'foo' })
|
2020-06-09 22:17:42 +08:00
|
|
|
// @ts-expect-error
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h('div', { key: [] }))
|
2020-06-09 22:17:42 +08:00
|
|
|
// @ts-expect-error
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h('div', { key: {} }))
|
|
|
|
// ref
|
|
|
|
h('div', { ref: 'foo' })
|
|
|
|
h('div', { ref: ref(null) })
|
2020-06-16 23:59:43 +08:00
|
|
|
h('div', { ref: _el => {} })
|
2020-06-09 22:17:42 +08:00
|
|
|
// @ts-expect-error
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h('div', { ref: [] }))
|
2020-06-09 22:17:42 +08:00
|
|
|
// @ts-expect-error
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h('div', { ref: {} }))
|
2020-06-09 22:17:42 +08:00
|
|
|
// @ts-expect-error
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h('div', { ref: 123 }))
|
2020-06-12 22:38:56 +08:00
|
|
|
// slots
|
|
|
|
const slots = { default: () => {} } // RawSlots
|
|
|
|
h('div', {}, slots)
|
2019-11-05 07:38:55 +08:00
|
|
|
})
|
2019-11-02 10:54:01 +08:00
|
|
|
|
2019-11-05 07:38:55 +08:00
|
|
|
describe('h inference w/ Fragment', () => {
|
|
|
|
// only accepts array children
|
|
|
|
h(Fragment, ['hello'])
|
|
|
|
h(Fragment, { key: 123 }, ['hello'])
|
2020-08-20 04:11:29 +08:00
|
|
|
// @ts-expect-error
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h(Fragment, 'foo'))
|
2020-06-09 22:17:42 +08:00
|
|
|
// @ts-expect-error
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h(Fragment, { key: 123 }, 'bar'))
|
|
|
|
})
|
2019-11-02 10:54:01 +08:00
|
|
|
|
2020-04-02 10:04:55 +08:00
|
|
|
describe('h inference w/ Teleport', () => {
|
|
|
|
h(Teleport, { to: '#foo' }, 'hello')
|
2020-08-20 04:11:29 +08:00
|
|
|
// @ts-expect-error
|
2020-04-02 10:04:55 +08:00
|
|
|
expectError(h(Teleport))
|
2020-08-20 04:11:29 +08:00
|
|
|
// @ts-expect-error
|
2020-04-02 10:04:55 +08:00
|
|
|
expectError(h(Teleport, {}))
|
2020-08-20 04:11:29 +08:00
|
|
|
// @ts-expect-error
|
2020-04-02 10:04:55 +08:00
|
|
|
expectError(h(Teleport, { to: '#foo' }))
|
2019-11-05 07:38:55 +08:00
|
|
|
})
|
2019-11-02 10:54:01 +08:00
|
|
|
|
2019-11-05 07:38:55 +08:00
|
|
|
describe('h inference w/ Suspense', () => {
|
|
|
|
h(Suspense, { onRecede: () => {}, onResolve: () => {} }, 'hello')
|
|
|
|
h(Suspense, 'foo')
|
|
|
|
h(Suspense, () => 'foo')
|
|
|
|
h(Suspense, null, {
|
|
|
|
default: () => 'foo'
|
|
|
|
})
|
2020-06-09 22:17:42 +08:00
|
|
|
// @ts-expect-error
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h(Suspense, { onResolve: 1 }))
|
2019-11-02 10:54:01 +08:00
|
|
|
})
|
|
|
|
|
2019-11-05 07:38:55 +08:00
|
|
|
describe('h inference w/ functional component', () => {
|
|
|
|
const Func = (_props: { foo: string; bar?: number }) => ''
|
|
|
|
h(Func, { foo: 'hello' })
|
|
|
|
h(Func, { foo: 'hello', bar: 123 })
|
2020-06-09 22:17:42 +08:00
|
|
|
// @ts-expect-error
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h(Func, { foo: 123 }))
|
2020-06-09 22:17:42 +08:00
|
|
|
// @ts-expect-error
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h(Func, {}))
|
2020-06-09 22:17:42 +08:00
|
|
|
// @ts-expect-error
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h(Func, { bar: 123 }))
|
|
|
|
})
|
2019-11-02 10:54:01 +08:00
|
|
|
|
2020-04-05 01:29:29 +08:00
|
|
|
describe('h support w/ plain object component', () => {
|
2019-11-05 07:38:55 +08:00
|
|
|
const Foo = {
|
|
|
|
props: {
|
|
|
|
foo: String
|
|
|
|
}
|
2019-11-02 10:54:01 +08:00
|
|
|
}
|
2019-11-05 07:38:55 +08:00
|
|
|
h(Foo, { foo: 'ok' })
|
|
|
|
h(Foo, { foo: 'ok', class: 'extra' })
|
2020-04-05 01:29:29 +08:00
|
|
|
// no inference in this case
|
2019-11-05 07:38:55 +08:00
|
|
|
})
|
2019-11-02 10:54:01 +08:00
|
|
|
|
2019-12-22 23:58:12 +08:00
|
|
|
describe('h inference w/ defineComponent', () => {
|
|
|
|
const Foo = defineComponent({
|
2019-11-05 07:38:55 +08:00
|
|
|
props: {
|
|
|
|
foo: String,
|
|
|
|
bar: {
|
|
|
|
type: Number,
|
|
|
|
required: true
|
|
|
|
}
|
2019-11-02 10:54:01 +08:00
|
|
|
}
|
2019-11-05 07:38:55 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
h(Foo, { bar: 1 })
|
|
|
|
h(Foo, { bar: 1, foo: 'ok' })
|
|
|
|
// should allow extraneous props (attrs fallthrough)
|
|
|
|
h(Foo, { bar: 1, foo: 'ok', class: 'extra' })
|
2020-06-09 22:17:42 +08:00
|
|
|
// @ts-expect-error should fail on missing required prop
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h(Foo, {}))
|
2020-06-09 22:17:42 +08:00
|
|
|
// @ts-expect-error
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h(Foo, { foo: 'ok' }))
|
2020-06-09 22:17:42 +08:00
|
|
|
// @ts-expect-error should fail on wrong type
|
2019-11-05 07:38:55 +08:00
|
|
|
expectError(h(Foo, { bar: 1, foo: 1 }))
|
2019-11-02 10:54:01 +08:00
|
|
|
})
|
|
|
|
|
2020-06-16 23:59:43 +08:00
|
|
|
// describe('h inference w/ defineComponent + optional props', () => {
|
|
|
|
// const Foo = defineComponent({
|
|
|
|
// setup(_props: { foo?: string; bar: number }) {}
|
|
|
|
// })
|
|
|
|
|
|
|
|
// h(Foo, { bar: 1 })
|
|
|
|
// h(Foo, { bar: 1, foo: 'ok' })
|
|
|
|
// // should allow extraneous props (attrs fallthrough)
|
|
|
|
// h(Foo, { bar: 1, foo: 'ok', class: 'extra' })
|
|
|
|
// // @ts-expect-error should fail on missing required prop
|
|
|
|
// expectError(h(Foo, {}))
|
|
|
|
// // @ts-expect-error
|
|
|
|
// expectError(h(Foo, { foo: 'ok' }))
|
|
|
|
// // @ts-expect-error should fail on wrong type
|
|
|
|
// expectError(h(Foo, { bar: 1, foo: 1 }))
|
|
|
|
// })
|
|
|
|
|
|
|
|
// describe('h inference w/ defineComponent + direct function', () => {
|
|
|
|
// const Foo = defineComponent((_props: { foo?: string; bar: number }) => {})
|
|
|
|
|
|
|
|
// h(Foo, { bar: 1 })
|
|
|
|
// h(Foo, { bar: 1, foo: 'ok' })
|
|
|
|
// // should allow extraneous props (attrs fallthrough)
|
|
|
|
// h(Foo, { bar: 1, foo: 'ok', class: 'extra' })
|
|
|
|
// // @ts-expect-error should fail on missing required prop
|
|
|
|
// expectError(h(Foo, {}))
|
|
|
|
// // @ts-expect-error
|
|
|
|
// expectError(h(Foo, { foo: 'ok' }))
|
|
|
|
// // @ts-expect-error should fail on wrong type
|
|
|
|
// expectError(h(Foo, { bar: 1, foo: 1 }))
|
|
|
|
// })
|
2020-04-05 01:29:29 +08:00
|
|
|
|
|
|
|
// #922
|
|
|
|
describe('h support for generic component type', () => {
|
|
|
|
function foo(bar: Component) {
|
|
|
|
h(bar)
|
|
|
|
h(bar, 'hello')
|
2020-08-20 04:11:29 +08:00
|
|
|
// @ts-expect-error
|
2020-04-05 01:29:29 +08:00
|
|
|
h(bar, { id: 'ok' }, 'hello')
|
|
|
|
}
|
|
|
|
foo({})
|
|
|
|
})
|
2020-04-25 01:22:58 +08:00
|
|
|
|
|
|
|
// #993
|
|
|
|
describe('describeComponent extends Component', () => {
|
|
|
|
// functional
|
|
|
|
expectAssignable<Component>(
|
|
|
|
defineComponent((_props: { foo?: string; bar: number }) => {})
|
|
|
|
)
|
|
|
|
|
|
|
|
// typed props
|
|
|
|
expectAssignable<Component>(defineComponent({}))
|
|
|
|
|
|
|
|
// prop arrays
|
|
|
|
expectAssignable<Component>(
|
|
|
|
defineComponent({
|
|
|
|
props: ['a', 'b']
|
|
|
|
})
|
|
|
|
)
|
|
|
|
|
|
|
|
// prop object
|
|
|
|
expectAssignable<Component>(
|
|
|
|
defineComponent({
|
|
|
|
props: {
|
|
|
|
foo: String,
|
|
|
|
bar: {
|
|
|
|
type: Number,
|
|
|
|
required: true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
)
|
|
|
|
})
|
2020-06-16 23:59:43 +08:00
|
|
|
|
|
|
|
// #1385
|
|
|
|
describe('component w/ props w/ default value', () => {
|
|
|
|
const MyComponent = defineComponent({
|
|
|
|
props: {
|
|
|
|
message: {
|
|
|
|
type: String,
|
|
|
|
default: 'hello'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
h(MyComponent, {})
|
|
|
|
})
|
2020-10-20 05:25:55 +08:00
|
|
|
|
|
|
|
// #2338
|
|
|
|
describe('Boolean prop implicit false', () => {
|
|
|
|
const MyComponent = defineComponent({
|
|
|
|
props: {
|
|
|
|
visible: Boolean
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
h(MyComponent, {})
|
|
|
|
|
|
|
|
const RequiredComponent = defineComponent({
|
|
|
|
props: {
|
|
|
|
visible: {
|
|
|
|
type: Boolean,
|
|
|
|
required: true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
h(RequiredComponent, {
|
|
|
|
visible: true
|
|
|
|
})
|
|
|
|
// @ts-expect-error
|
|
|
|
expectError(h(RequiredComponent, {}))
|
|
|
|
})
|
2020-10-21 03:56:29 +08:00
|
|
|
|
|
|
|
// #2357
|
|
|
|
describe('resolveComponent should work', () => {
|
|
|
|
h(resolveComponent('test'))
|
|
|
|
h(resolveComponent('test'), {
|
|
|
|
message: '1'
|
|
|
|
})
|
|
|
|
})
|