import { h, render, nodeOps, NodeTypes, TestElement, TestText, ref, reactive, dumpOps, resetOps, NodeOpTypes, nextTick, serialize, triggerEvent } from '../src' import { mockWarn } from '@vue/shared' describe('test renderer', () => { mockWarn() it('should work', () => { const root = nodeOps.createElement('div') render( h( 'div', { id: 'test' }, 'hello' ), root ) expect(root.children.length).toBe(1) const el = root.children[0] as TestElement expect(el.type).toBe(NodeTypes.ELEMENT) expect(el.props.id).toBe('test') expect(el.children.length).toBe(1) const text = el.children[0] as TestText expect(text.type).toBe(NodeTypes.TEXT) expect(text.text).toBe('hello') }) it('should record ops', async () => { const state = reactive({ id: 'test', text: 'hello' }) const App = { render() { return h( 'div', { id: state.id }, state.text ) } } const root = nodeOps.createElement('div') resetOps() render(h(App), root) const ops = dumpOps() expect(ops.length).toBe(4) expect(ops[0]).toEqual({ type: NodeOpTypes.CREATE, nodeType: NodeTypes.ELEMENT, tag: 'div', targetNode: root.children[0] }) expect(ops[1]).toEqual({ type: NodeOpTypes.SET_ELEMENT_TEXT, text: 'hello', targetNode: root.children[0] }) expect(ops[2]).toEqual({ type: NodeOpTypes.PATCH, targetNode: root.children[0], propKey: 'id', propPrevValue: null, propNextValue: 'test' }) expect(ops[3]).toEqual({ type: NodeOpTypes.INSERT, targetNode: root.children[0], parentNode: root, refNode: null }) // test update ops state.id = 'foo' state.text = 'bar' await nextTick() const updateOps = dumpOps() expect(updateOps.length).toBe(2) expect(updateOps[0]).toEqual({ type: NodeOpTypes.PATCH, targetNode: root.children[0], propKey: 'id', propPrevValue: 'test', propNextValue: 'foo' }) expect(updateOps[1]).toEqual({ type: NodeOpTypes.SET_ELEMENT_TEXT, targetNode: root.children[0], text: 'bar' }) }) it('should be able to serialize nodes', () => { const App = { render() { return h( 'div', { id: 'test', boolean: '' }, [h('span', 'foo'), 'hello'] ) } } const root = nodeOps.createElement('div') render(h(App), root) expect(serialize(root)).toEqual( `
foohello
` ) // indented output expect(serialize(root, 2)).toEqual( `
foo hello
` ) }) it('should be able to trigger events', async () => { const count = ref(0) const App = () => { return h( 'span', { onClick: () => { count.value++ } }, count.value ) } const root = nodeOps.createElement('div') render(h(App), root) triggerEvent(root.children[0] as TestElement, 'click') expect(count.value).toBe(1) await nextTick() expect(serialize(root)).toBe(`
1
`) }) it('should be able to trigger events with multiple listeners', async () => { const count = ref(0) const count2 = ref(1) const App = () => { return h( 'span', { onClick: [ () => { count.value++ }, () => { count2.value++ } ] }, `${count.value}, ${count2.value}` ) } const root = nodeOps.createElement('div') render(h(App), root) triggerEvent(root.children[0] as TestElement, 'click') expect(count.value).toBe(1) expect(count2.value).toBe(2) await nextTick() expect(serialize(root)).toBe(`
1, 2
`) }) it('should mock warn', () => { console.warn('warn!!!') expect('warn!!!').toHaveBeenWarned() expect('warn!!!').toHaveBeenWarnedTimes(1) console.warn('warn!!!') expect('warn!!!').toHaveBeenWarnedTimes(2) console.warn('warning') expect('warn!!!').toHaveBeenWarnedTimes(2) expect('warning').toHaveBeenWarnedLast() }) })