test: improve coverage

This commit is contained in:
Evan You 2020-07-15 10:38:45 -04:00
parent 056a13142f
commit 32a4cb804b
7 changed files with 89 additions and 4 deletions

View File

@ -40,7 +40,7 @@ function shuffle(array: Array<any>) {
return array return array
} }
it('should patch previously empty children', () => { test('should patch previously empty children', () => {
const root = nodeOps.createElement('div') const root = nodeOps.createElement('div')
render(h('div', []), root) render(h('div', []), root)
@ -50,7 +50,7 @@ it('should patch previously empty children', () => {
expect(inner(root)).toBe('<div>hello</div>') expect(inner(root)).toBe('<div>hello</div>')
}) })
it('should patch previously null children', () => { test('should patch previously null children', () => {
const root = nodeOps.createElement('div') const root = nodeOps.createElement('div')
render(h('div'), root) render(h('div'), root)
@ -60,6 +60,15 @@ it('should patch previously null children', () => {
expect(inner(root)).toBe('<div>hello</div>') expect(inner(root)).toBe('<div>hello</div>')
}) })
test('array children -> text children', () => {
const root = nodeOps.createElement('div')
render(h('div', [h('div')]), root)
expect(inner(root)).toBe('<div><div></div></div>')
render(h('div', 'hello'), root)
expect(inner(root)).toBe('<div>hello</div>')
})
describe('renderer: keyed children', () => { describe('renderer: keyed children', () => {
let root: TestElement let root: TestElement
let elm: TestElement let elm: TestElement

View File

@ -129,6 +129,20 @@ describe('renderer: fragment', () => {
root root
) )
expect(serializeInner(root)).toBe(`<div>foo</div>barbaz`) expect(serializeInner(root)).toBe(`<div>foo</div>barbaz`)
render(
createVNode(
Fragment,
null,
[
createTextVNode('baz'),
createVNode('div', null, 'foo', PatchFlags.TEXT)
],
PatchFlags.UNKEYED_FRAGMENT
),
root
)
expect(serializeInner(root)).toBe(`baz<div>foo</div>`)
}) })
it('patch fragment children (compiler generated, keyed)', () => { it('patch fragment children (compiler generated, keyed)', () => {

View File

@ -690,6 +690,7 @@ const classifyRE = /(?:^|[-_])(\w)/g
const classify = (str: string): string => const classify = (str: string): string =>
str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '') str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '')
/* istanbul ignore next */
export function formatComponentName( export function formatComponentName(
instance: ComponentInternalInstance | null, instance: ComponentInternalInstance | null,
Component: Component, Component: Component,

View File

@ -57,6 +57,7 @@ export function warn(msg: string, ...args: any[]) {
) )
} else { } else {
const warnArgs = [`[Vue warn]: ${msg}`, ...args] const warnArgs = [`[Vue warn]: ${msg}`, ...args]
/* istanbul ignore if */
if ( if (
trace.length && trace.length &&
// avoid spamming console during tests // avoid spamming console during tests
@ -99,6 +100,7 @@ function getComponentTrace(): ComponentTraceStack {
return normalizedStack return normalizedStack
} }
/* istanbul ignore next */
function formatTrace(trace: ComponentTraceStack): any[] { function formatTrace(trace: ComponentTraceStack): any[] {
const logs: any[] = [] const logs: any[] = []
trace.forEach((entry, i) => { trace.forEach((entry, i) => {
@ -122,6 +124,7 @@ function formatTraceEntry({ vnode, recurseCount }: TraceEntry): any[] {
: [open + close] : [open + close]
} }
/* istanbul ignore next */
function formatProps(props: Data): any[] { function formatProps(props: Data): any[] {
const res: any[] = [] const res: any[] = []
const keys = Object.keys(props) const keys = Object.keys(props)
@ -136,6 +139,7 @@ function formatProps(props: Data): any[] {
function formatProp(key: string, value: unknown): any[] function formatProp(key: string, value: unknown): any[]
function formatProp(key: string, value: unknown, raw: true): any function formatProp(key: string, value: unknown, raw: true): any
/* istanbul ignore next */
function formatProp(key: string, value: unknown, raw?: boolean): any { function formatProp(key: string, value: unknown, raw?: boolean): any {
if (isString(value)) { if (isString(value)) {
value = JSON.stringify(value) value = JSON.stringify(value)

View File

@ -0,0 +1,55 @@
import { render, h, nodeOps } from '@vue/runtime-test'
import { useCssModule } from '../../src/helpers/useCssModule'
import { mockWarn } from '@vue/shared'
describe('useCssModule', () => {
mockWarn()
function mountWithModule(modules: any, name?: string) {
let res
render(
h({
render() {},
__cssModules: modules,
setup() {
res = useCssModule(name)
}
}),
nodeOps.createElement('div')
)
return res
}
test('basic usage', () => {
const modules = {
$style: {
red: 'red'
}
}
expect(mountWithModule(modules)).toMatchObject(modules.$style)
})
test('basic usage', () => {
const modules = {
foo: {
red: 'red'
}
}
expect(mountWithModule(modules, 'foo')).toMatchObject(modules.foo)
})
test('warn out of setup usage', () => {
useCssModule()
expect('must be called inside setup').toHaveBeenWarned()
})
test('warn missing injection', () => {
mountWithModule(undefined)
expect('instance does not have CSS modules').toHaveBeenWarned()
})
test('warn missing injection', () => {
mountWithModule({ $style: { red: 'red' } }, 'foo')
expect('instance does not have CSS module named "foo"').toHaveBeenWarned()
})
})

View File

@ -2,10 +2,11 @@ import { warn, getCurrentInstance } from '@vue/runtime-core'
import { EMPTY_OBJ } from '@vue/shared' import { EMPTY_OBJ } from '@vue/shared'
export function useCssModule(name = '$style'): Record<string, string> { export function useCssModule(name = '$style'): Record<string, string> {
/* istanbul ignore else */
if (!__GLOBAL__) { if (!__GLOBAL__) {
const instance = getCurrentInstance()! const instance = getCurrentInstance()!
if (!instance) { if (!instance) {
__DEV__ && warn(`useCSSModule must be called inside setup()`) __DEV__ && warn(`useCssModule must be called inside setup()`)
return EMPTY_OBJ return EMPTY_OBJ
} }
const modules = instance.type.__cssModules const modules = instance.type.__cssModules
@ -22,7 +23,7 @@ export function useCssModule(name = '$style'): Record<string, string> {
return mod as Record<string, string> return mod as Record<string, string>
} else { } else {
if (__DEV__) { if (__DEV__) {
warn(`useCSSModule() is not supported in the global build.`) warn(`useCssModule() is not supported in the global build.`)
} }
return EMPTY_OBJ return EMPTY_OBJ
} }

View File

@ -14,6 +14,7 @@ export function useCssVars(
scoped = false scoped = false
) { ) {
const instance = getCurrentInstance() const instance = getCurrentInstance()
/* istanbul ignore next */
if (!instance) { if (!instance) {
__DEV__ && __DEV__ &&
warn(`useCssVars is called without current active component instance.`) warn(`useCssVars is called without current active component instance.`)