Skip to content

Commit

Permalink
test: fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Dec 9, 2019
1 parent 773406a commit a4148c8
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 73 deletions.
102 changes: 30 additions & 72 deletions packages/runtime-dom/__tests__/modules/class.spec.ts
@@ -1,6 +1,10 @@
// https://github.com/vuejs/vue/blob/dev/test/unit/features/directives/class.spec.js

import { h, render, ComponentOptions } from '../../src'
import { h, render, createComponent } from '../../src'

type ClassItem = {
value: string | object | string[]
}

function assertClass(assertions: Array<Array<any>>) {
const root = document.createElement('div')
Expand Down Expand Up @@ -63,121 +67,75 @@ describe('class', () => {

test('class merge between parent and child', () => {
const root = document.createElement('div')
type ClassItem = {
value: string | object | string[]
}
const childClass: ClassItem = { value: 'd' }

const child = () => h('div', { class: ['c', childClass.value] })

const parentClass: ClassItem = { value: 'b' }
const parent = () => h(child, { class: ['a', parentClass.value] })

render(h(parent), root)
expect(root.children[0].className).toBe('c a d b')

parentClass.value = 'e'
render(h(parent), root)
expect(root.children[0].className).toBe('c a d e')

parentClass.value = 'f'
render(h(parent), root)
expect(root.children[0].className).toBe('c a f e')

parentClass.value = { foo: true }
childClass.value = ['bar', 'baz']
expect(root.children[0].className).toBe('c a bar baz foo')
})

test('class merge between parent and child with props', () => {
const root = document.createElement('div')
type ClassItem = {
value: string | object | string[]
}
const childClass: ClassItem = { value: 'd' }

const child = {
setup() {
return () => h('div', { class: ['c', childClass.value] })
}
props: {},
render: () => h('div', { class: ['c', childClass.value] })
}

const parentClass: ClassItem = { value: 'b' }
const parent = {
setup() {
return () => h(child, { class: ['a', parentClass.value] })
}
}

const child2 = {
props: [],
setup() {
return () => h('div', { class: ['c', childClass.value] })
}
}
const parent2 = {
setup() {
return () => h(child2, { class: ['a', parentClass.value] })
}
props: {},
render: () => h(child, { class: ['a', parentClass.value] })
}

render(h(parent2), root)
expect(root.children[0].className).toBe('c d a b')

render(h(parent), root)
expect(root.children[0].className).toBe('c d a b')

parentClass.value = 'e'
render(h(parent), root)
// the `foo` here is just for forcing parent to be updated
// (otherwise it's skipped since its props never change)
render(h(parent, { foo: 1 }), root)
expect(root.children[0].className).toBe('c d a e')

parentClass.value = 'f'
render(h(parent), root)
expect(root.children[0].className).toBe('c f a e')
render(h(parent, { foo: 2 }), root)
expect(root.children[0].className).toBe('c d a f')

parentClass.value = { foo: true }
childClass.value = ['bar', 'baz']
render(h(parent, { foo: 3 }), root)
expect(root.children[0].className).toBe('c bar baz a foo')
})

test('class merge between multiple nested components sharing same element', () => {
const component1: ComponentOptions = {
const component1 = createComponent({
props: {},
render() {
// FIXME: how to type this?
// @ts-ignore
return this.$slots.default()
return this.$slots.default()[0]
}
}
})

const component2: ComponentOptions = {
const component2 = createComponent({
props: {},
render() {
// @ts-ignore
return this.$slots.default()
return this.$slots.default()[0]
}
}
})

const component3: ComponentOptions = {
const component3 = createComponent({
props: {},
render() {
return h(
'div',
{
class: 'staticClass'
},
// @ts-ignore
[this.$slots.default()]
)
}
}
})

const root = document.createElement('div')
const componentClass1 = { value: 'componentClass1' }
const componentClass2 = { value: 'componentClass2' }
const componentClass3 = { value: 'componentClass3' }

const wrapper = () =>
h(component1, { class: componentClass1.value }, [
h(component2, { class: componentClass2.value }, [
h(component3, { class: componentClass3.value }, ['some text'])
h(component1, { class: componentClass1.value }, () => [
h(component2, { class: componentClass2.value }, () => [
h(component3, { class: componentClass3.value }, () => ['some text'])
])
])

Expand Down Expand Up @@ -219,7 +177,7 @@ describe('class', () => {

// a vdom patch edge case where the user has several un-keyed elements of the
// same tag next to each other, and toggling them.
test('properly remove staticClass for toggling un-keyed children', done => {
test('properly remove staticClass for toggling un-keyed children', () => {
const root = document.createElement('div')
const ok = { value: true }
const wrapper = () =>
Expand Down
5 changes: 4 additions & 1 deletion packages/runtime-dom/src/modules/class.ts
Expand Up @@ -2,7 +2,10 @@ import { ElementWithTransition } from '../components/Transition'

// compiler should normalize class + :class bindings on the same element
// into a single binding ['staticClass', dynamic]
export function patchClass(el: Element, value: string, isSVG: boolean) {
export function patchClass(el: Element, value: string | null, isSVG: boolean) {
if (value == null) {
value = ''
}
// directly setting className should be faster than setAttribute in theory
if (isSVG) {
el.setAttribute('class', value)
Expand Down

0 comments on commit a4148c8

Please sign in to comment.