From: Evan You Date: Tue, 25 Sep 2018 01:13:06 +0000 (-0400) Subject: test: test for attrs fallthrough X-Git-Tag: v3.0.0-alpha.0~1196 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a848466f07efd26060747d61dc9bda0d1754ad4f;p=thirdparty%2Fvuejs%2Fcore.git test: test for attrs fallthrough --- diff --git a/jest.config.js b/jest.config.js index 4eb301058a..d92d388646 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,7 +2,8 @@ module.exports = { preset: 'ts-jest', globals: { __DEV__: true, - __COMPAT__: false + __COMPAT__: false, + __JSDOM__: true }, coverageDirectory: 'coverage', coverageReporters: ['html', 'lcov', 'text'], diff --git a/packages/core/__tests__/attrsFallthrough.spec.ts b/packages/core/__tests__/attrsFallthrough.spec.ts new file mode 100644 index 0000000000..a962db53cf --- /dev/null +++ b/packages/core/__tests__/attrsFallthrough.spec.ts @@ -0,0 +1,143 @@ +import { h, render, Component, nextTick } from '@vue/renderer-dom' + +describe('attribute fallthrough', () => { + it('should not fallthrough on components with no declared props', async () => { + const nativeClick = jest.fn() + const childUpdated = jest.fn() + + class Hello extends Component { + data() { + return { + count: 0 + } + } + inc() { + this.count++ + nativeClick() + } + render() { + return h(Child, { + foo: 1, + id: 'test', + class: 'c' + this.count, + style: { color: this.count ? 'red' : 'green' }, + nativeOnClick: this.inc + }) + } + } + + class Child extends Component { + updated() { + childUpdated() + } + render(props: any) { + return h( + 'div', + { + class: 'c2', + style: { fontWeight: 'bold' } + }, + props.foo + ) + } + } + + const root = document.createElement('div') + document.body.appendChild(root) + render(h(Hello), root) + + const node = root.children[0] as HTMLElement + + // attrs do not fallthrough because no props are declared + expect(node.hasAttribute('id')).toBe(false) + expect(node.hasAttribute('foo')).toBe(false) + + // class, style and nativeOn* always fallthrough + expect(node.getAttribute('class')).toBe('c2 c0') + expect(node.style.color).toBe('green') + expect(node.style.fontWeight).toBe('bold') + node.dispatchEvent(new CustomEvent('click')) + expect(nativeClick).toHaveBeenCalled() + + await nextTick() + expect(childUpdated).toHaveBeenCalled() + expect(node.hasAttribute('id')).toBe(false) + expect(node.hasAttribute('foo')).toBe(false) + expect(node.getAttribute('class')).toBe('c2 c1') + expect(node.style.color).toBe('red') + expect(node.style.fontWeight).toBe('bold') + }) + + it('should fallthrough on components with declared props', async () => { + const nativeClick = jest.fn() + const childUpdated = jest.fn() + + class Hello extends Component { + data() { + return { + count: 0 + } + } + inc() { + this.count++ + nativeClick() + } + render() { + return h(Child, { + foo: 1, + id: 'test', + class: 'c' + this.count, + style: { color: this.count ? 'red' : 'green' }, + nativeOnClick: this.inc + }) + } + } + + class Child extends Component { + static options = { + props: { + foo: Number + } + } + updated() { + childUpdated() + } + render(props: any) { + return h( + 'div', + { + class: 'c2', + style: { fontWeight: 'bold' } + }, + props.foo + ) + } + } + + const root = document.createElement('div') + document.body.appendChild(root) + render(h(Hello), root) + + const node = root.children[0] as HTMLElement + + // with declared props, any parent attr that isn't a prop falls through + expect(node.getAttribute('id')).toBe('test') + // ...while declared ones remain props + expect(node.hasAttribute('foo')).toBe(false) + + // class, style and nativeOn* always fallthrough + expect(node.getAttribute('class')).toBe('c2 c0') + expect(node.style.color).toBe('green') + expect(node.style.fontWeight).toBe('bold') + node.dispatchEvent(new CustomEvent('click')) + expect(nativeClick).toHaveBeenCalled() + + await nextTick() + expect(childUpdated).toHaveBeenCalled() + expect(node.getAttribute('id')).toBe('test') + expect(node.hasAttribute('foo')).toBe(false) + expect(node.getAttribute('class')).toBe('c2 c1') + expect(node.style.color).toBe('red') + expect(node.style.fontWeight).toBe('bold') + }) +}) diff --git a/packages/global.d.ts b/packages/global.d.ts index 11614e940d..f82292626e 100644 --- a/packages/global.d.ts +++ b/packages/global.d.ts @@ -1,3 +1,4 @@ // Global compile-time constants declare var __DEV__: boolean declare var __COMPAT__: boolean +declare var __JSDOM__: boolean diff --git a/packages/renderer-dom/src/modules/events.ts b/packages/renderer-dom/src/modules/events.ts index 452ff00140..fda02d46dc 100644 --- a/packages/renderer-dom/src/modules/events.ts +++ b/packages/renderer-dom/src/modules/events.ts @@ -9,7 +9,7 @@ export function patchEvent( prevValue: EventValue | null, nextValue: EventValue | null ) { - if (delegateRE.test(name)) { + if (delegateRE.test(name) && !__JSDOM__) { handleDelegatedEvent(el, name, nextValue) } else { handleNormalEvent(el, name, prevValue, nextValue) diff --git a/rollup.config.js b/rollup.config.js index 6e46905438..a7dd1924b8 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -124,7 +124,9 @@ function createReplacePlugin(isProduction, isBunlderESMBuild, isCompat) { : // hard coded dev/prod builds !isProduction, // compatibility builds - __COMPAT__: !!packageOptions.compat + __COMPAT__: !!packageOptions.compat, + // this is only used during tests + __JSDOM__: false }) }