|
|
@@ -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')
|
|
|
+ })
|
|
|
+})
|