]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
test: test for attrs fallthrough
authorEvan You <yyx990803@gmail.com>
Tue, 25 Sep 2018 01:13:06 +0000 (21:13 -0400)
committerEvan You <yyx990803@gmail.com>
Tue, 25 Sep 2018 01:13:06 +0000 (21:13 -0400)
jest.config.js
packages/core/__tests__/attrsFallthrough.spec.ts [new file with mode: 0644]
packages/global.d.ts
packages/renderer-dom/src/modules/events.ts
rollup.config.js

index 4eb301058abf702bd9f4027b70d86cf653383ce1..d92d388646399514a39004a62881307706523f6f 100644 (file)
@@ -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 (file)
index 0000000..a962db5
--- /dev/null
@@ -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')
+  })
+})
index 11614e940d337e6b3ed58ec071c571a0f678950d..f82292626ed2a56e4a2707ba3355185065a495e4 100644 (file)
@@ -1,3 +1,4 @@
 // Global compile-time constants
 declare var __DEV__: boolean
 declare var __COMPAT__: boolean
+declare var __JSDOM__: boolean
index 452ff001406a9b26163544f2c720eb6cd1778a03..fda02d46dc9cce7bc8a2e0a4d30291a1dc4bcafe 100644 (file)
@@ -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)
index 6e4690543873eebf4dd0a175834095d1e84a702a..a7dd1924b872070b95376039cc880c778e3f7e65 100644 (file)
@@ -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
   })
 }