From b2128609ac8159a14224deba399144b3400c8c20 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Sun, 13 Nov 2016 08:16:12 +0100 Subject: Finally give in and use React, minor tweeks. Preact (a minimalistic React alternative) had too many bugs ... --- thirdparty/preact/test/browser/components.js | 712 ------------------------- thirdparty/preact/test/browser/context.js | 174 ------ thirdparty/preact/test/browser/devtools.js | 234 -------- thirdparty/preact/test/browser/keys.js | 85 --- thirdparty/preact/test/browser/lifecycle.js | 495 ----------------- thirdparty/preact/test/browser/linked-state.js | 110 ---- thirdparty/preact/test/browser/performance.js | 245 --------- thirdparty/preact/test/browser/refs.js | 305 ----------- thirdparty/preact/test/browser/render.js | 439 --------------- thirdparty/preact/test/browser/spec.js | 127 ----- thirdparty/preact/test/browser/svg.js | 112 ---- 11 files changed, 3038 deletions(-) delete mode 100644 thirdparty/preact/test/browser/components.js delete mode 100644 thirdparty/preact/test/browser/context.js delete mode 100644 thirdparty/preact/test/browser/devtools.js delete mode 100644 thirdparty/preact/test/browser/keys.js delete mode 100644 thirdparty/preact/test/browser/lifecycle.js delete mode 100644 thirdparty/preact/test/browser/linked-state.js delete mode 100644 thirdparty/preact/test/browser/performance.js delete mode 100644 thirdparty/preact/test/browser/refs.js delete mode 100644 thirdparty/preact/test/browser/render.js delete mode 100644 thirdparty/preact/test/browser/spec.js delete mode 100644 thirdparty/preact/test/browser/svg.js (limited to 'thirdparty/preact/test/browser') diff --git a/thirdparty/preact/test/browser/components.js b/thirdparty/preact/test/browser/components.js deleted file mode 100644 index 9ef43cb1c..000000000 --- a/thirdparty/preact/test/browser/components.js +++ /dev/null @@ -1,712 +0,0 @@ -import { h, render, rerender, Component } from '../../src/preact'; -/** @jsx h */ - -let spyAll = obj => Object.keys(obj).forEach( key => sinon.spy(obj,key) ); - -function getAttributes(node) { - let attrs = {}; - if (node.attributes) { - for (let i=node.attributes.length; i--; ) { - attrs[node.attributes[i].name] = node.attributes[i].value; - } - } - return attrs; -} - -// hacky normalization of attribute order across browsers. -function sortAttributes(html) { - return html.replace(/<([a-z0-9-]+)((?:\s[a-z0-9:_.-]+=".*?")+)((?:\s*\/)?>)/gi, (s, pre, attrs, after) => { - let list = attrs.match(/\s[a-z0-9:_.-]+=".*?"/gi).sort( (a, b) => a>b ? 1 : -1 ); - if (~after.indexOf('/')) after = '>'; - return '<' + pre + list.join('') + after; - }); -} - -const Empty = () => null; - -describe('Components', () => { - let scratch; - - before( () => { - scratch = document.createElement('div'); - (document.body || document.documentElement).appendChild(scratch); - }); - - beforeEach( () => { - let c = scratch.firstElementChild; - if (c) render(, scratch, c); - scratch.innerHTML = ''; - }); - - after( () => { - scratch.parentNode.removeChild(scratch); - scratch = null; - }); - - it('should render components', () => { - class C1 extends Component { - render() { - return
C1
; - } - } - sinon.spy(C1.prototype, 'render'); - render(, scratch); - - expect(C1.prototype.render) - .to.have.been.calledOnce - .and.to.have.been.calledWithMatch({}, {}) - .and.to.have.returned(sinon.match({ nodeName:'div' })); - - expect(scratch.innerHTML).to.equal('
C1
'); - }); - - - it('should render functional components', () => { - const PROPS = { foo:'bar', onBaz:()=>{} }; - - const C3 = sinon.spy( props =>
); - - render(, scratch); - - expect(C3) - .to.have.been.calledOnce - .and.to.have.been.calledWithMatch(PROPS) - .and.to.have.returned(sinon.match({ - nodeName: 'div', - attributes: PROPS - })); - - expect(scratch.innerHTML).to.equal('
'); - }); - - - it('should render components with props', () => { - const PROPS = { foo:'bar', onBaz:()=>{} }; - let constructorProps; - - class C2 extends Component { - constructor(props) { - super(props); - constructorProps = props; - } - render(props) { - return
; - } - } - sinon.spy(C2.prototype, 'render'); - - render(, scratch); - - expect(constructorProps).to.deep.equal(PROPS); - - expect(C2.prototype.render) - .to.have.been.calledOnce - .and.to.have.been.calledWithMatch(PROPS, {}) - .and.to.have.returned(sinon.match({ - nodeName: 'div', - attributes: PROPS - })); - - expect(scratch.innerHTML).to.equal('
'); - }); - - - // Test for Issue #73 - it('should remove orphaned elements replaced by Components', () => { - class Comp extends Component { - render() { - return span in a component; - } - } - - let root; - function test(content) { - root = render(content, scratch, root); - } - - test(); - test(
just a div
); - test(); - - expect(scratch.innerHTML).to.equal('span in a component'); - }); - - - // Test for Issue #176 - it('should remove children when root changes to text node', () => { - let comp; - - class Comp extends Component { - render(_, { alt }) { - return alt ? 'asdf' :
test
; - } - } - - render(comp=c} />, scratch); - - comp.setState({ alt:true }); - comp.forceUpdate(); - expect(scratch.innerHTML, 'switching to textnode').to.equal('asdf'); - - comp.setState({ alt:false }); - comp.forceUpdate(); - expect(scratch.innerHTML, 'switching to element').to.equal('
test
'); - - comp.setState({ alt:true }); - comp.forceUpdate(); - expect(scratch.innerHTML, 'switching to textnode 2').to.equal('asdf'); - }); - - - describe('props.children', () => { - it('should support passing children as a prop', () => { - const Foo = props =>
; - - render(bar, - '123', - 456 - ]} />, scratch); - - expect(scratch.innerHTML).to.equal('
bar123456
'); - }); - - it('should be ignored when explicit children exist', () => { - const Foo = props =>
a
; - - render(, scratch); - - expect(scratch.innerHTML).to.equal('
a
'); - }); - }); - - - describe('High-Order Components', () => { - it('should render nested functional components', () => { - const PROPS = { foo:'bar', onBaz:()=>{} }; - - const Outer = sinon.spy( - props => - ); - - const Inner = sinon.spy( - props =>
inner
- ); - - render(, scratch); - - expect(Outer) - .to.have.been.calledOnce - .and.to.have.been.calledWithMatch(PROPS) - .and.to.have.returned(sinon.match({ - nodeName: Inner, - attributes: PROPS - })); - - expect(Inner) - .to.have.been.calledOnce - .and.to.have.been.calledWithMatch(PROPS) - .and.to.have.returned(sinon.match({ - nodeName: 'div', - attributes: PROPS, - children: ['inner'] - })); - - expect(scratch.innerHTML).to.equal('
inner
'); - }); - - it('should re-render nested functional components', () => { - let doRender = null; - class Outer extends Component { - componentDidMount() { - let i = 1; - doRender = () => this.setState({ i: ++i }); - } - componentWillUnmount() {} - render(props, { i }) { - return ; - } - } - sinon.spy(Outer.prototype, 'render'); - sinon.spy(Outer.prototype, 'componentWillUnmount'); - - let j = 0; - const Inner = sinon.spy( - props =>
inner
- ); - - render(, scratch); - - // update & flush - doRender(); - rerender(); - - expect(Outer.prototype.componentWillUnmount) - .not.to.have.been.called; - - expect(Inner).to.have.been.calledTwice; - - expect(Inner.secondCall) - .to.have.been.calledWithMatch({ foo:'bar', i:2 }) - .and.to.have.returned(sinon.match({ - attributes: { - j: 2, - i: 2, - foo: 'bar' - } - })); - - expect(getAttributes(scratch.firstElementChild)).to.eql({ - j: '2', - i: '2', - foo: 'bar' - }); - - // update & flush - doRender(); - rerender(); - - expect(Inner).to.have.been.calledThrice; - - expect(Inner.thirdCall) - .to.have.been.calledWithMatch({ foo:'bar', i:3 }) - .and.to.have.returned(sinon.match({ - attributes: { - j: 3, - i: 3, - foo: 'bar' - } - })); - - expect(getAttributes(scratch.firstElementChild)).to.eql({ - j: '3', - i: '3', - foo: 'bar' - }); - }); - - it('should re-render nested components', () => { - let doRender = null, - alt = false; - - class Outer extends Component { - componentDidMount() { - let i = 1; - doRender = () => this.setState({ i: ++i }); - } - componentWillUnmount() {} - render(props, { i }) { - if (alt) return
; - return ; - } - } - sinon.spy(Outer.prototype, 'render'); - sinon.spy(Outer.prototype, 'componentDidMount'); - sinon.spy(Outer.prototype, 'componentWillUnmount'); - - let j = 0; - class Inner extends Component { - constructor(...args) { - super(); - this._constructor(...args); - } - _constructor() {} - componentWillMount() {} - componentDidMount() {} - componentWillUnmount() {} - componentDidUnmount() {} - render(props) { - return
inner
; - } - } - sinon.spy(Inner.prototype, '_constructor'); - sinon.spy(Inner.prototype, 'render'); - sinon.spy(Inner.prototype, 'componentWillMount'); - sinon.spy(Inner.prototype, 'componentDidMount'); - sinon.spy(Inner.prototype, 'componentDidUnmount'); - sinon.spy(Inner.prototype, 'componentWillUnmount'); - - render(, scratch); - - expect(Outer.prototype.componentDidMount).to.have.been.calledOnce; - - // update & flush - doRender(); - rerender(); - - expect(Outer.prototype.componentWillUnmount).not.to.have.been.called; - - expect(Inner.prototype._constructor).to.have.been.calledOnce; - expect(Inner.prototype.componentWillUnmount).not.to.have.been.called; - expect(Inner.prototype.componentDidUnmount).not.to.have.been.called; - expect(Inner.prototype.componentWillMount).to.have.been.calledOnce; - expect(Inner.prototype.componentDidMount).to.have.been.calledOnce; - expect(Inner.prototype.render).to.have.been.calledTwice; - - expect(Inner.prototype.render.secondCall) - .to.have.been.calledWithMatch({ foo:'bar', i:2 }) - .and.to.have.returned(sinon.match({ - attributes: { - j: 2, - i: 2, - foo: 'bar' - } - })); - - expect(getAttributes(scratch.firstElementChild)).to.eql({ - j: '2', - i: '2', - foo: 'bar' - }); - - expect(sortAttributes(scratch.innerHTML)).to.equal(sortAttributes('
inner
')); - - // update & flush - doRender(); - rerender(); - - expect(Inner.prototype.componentWillUnmount).not.to.have.been.called; - expect(Inner.prototype.componentDidUnmount).not.to.have.been.called; - expect(Inner.prototype.componentWillMount).to.have.been.calledOnce; - expect(Inner.prototype.componentDidMount).to.have.been.calledOnce; - expect(Inner.prototype.render).to.have.been.calledThrice; - - expect(Inner.prototype.render.thirdCall) - .to.have.been.calledWithMatch({ foo:'bar', i:3 }) - .and.to.have.returned(sinon.match({ - attributes: { - j: 3, - i: 3, - foo: 'bar' - } - })); - - expect(getAttributes(scratch.firstElementChild)).to.eql({ - j: '3', - i: '3', - foo: 'bar' - }); - - - // update & flush - alt = true; - doRender(); - rerender(); - - expect(Inner.prototype.componentWillUnmount).to.have.been.calledOnce; - expect(Inner.prototype.componentDidUnmount).to.have.been.calledOnce; - - expect(scratch.innerHTML).to.equal('
'); - - // update & flush - alt = false; - doRender(); - rerender(); - - expect(sortAttributes(scratch.innerHTML)).to.equal(sortAttributes('
inner
')); - }); - - it('should resolve intermediary functional component', () => { - let ctx = {}; - class Root extends Component { - getChildContext() { - return { ctx }; - } - render() { - return ; - } - } - const Func = sinon.spy( () => ); - class Inner extends Component { - componentWillMount() {} - componentDidMount() {} - componentWillUnmount() {} - componentDidUnmount() {} - render() { - return
inner
; - } - } - - spyAll(Inner.prototype); - - let root = render(, scratch); - - expect(Inner.prototype.componentWillMount).to.have.been.calledOnce; - expect(Inner.prototype.componentDidMount).to.have.been.calledOnce; - expect(Inner.prototype.componentWillMount).to.have.been.calledBefore(Inner.prototype.componentDidMount); - - render(, scratch, root); - - expect(Inner.prototype.componentWillUnmount).to.have.been.calledOnce; - expect(Inner.prototype.componentDidUnmount).to.have.been.calledOnce; - expect(Inner.prototype.componentWillUnmount).to.have.been.calledBefore(Inner.prototype.componentDidUnmount); - }); - - it('should unmount children of high-order components without unmounting parent', () => { - let outer, inner2, counter=0; - - class Outer extends Component { - constructor(props, context) { - super(props, context); - outer = this; - this.state = { - child: this.props.child - }; - } - componentWillUnmount(){} - componentDidUnmount(){} - componentWillMount(){} - componentDidMount(){} - render(_, { child:C }) { - return ; - } - } - spyAll(Outer.prototype); - - class Inner extends Component { - componentWillUnmount(){} - componentDidUnmount(){} - componentWillMount(){} - componentDidMount(){} - render() { - return h('element'+(++counter)); - } - } - spyAll(Inner.prototype); - - class Inner2 extends Component { - constructor(props, context) { - super(props, context); - inner2 = this; - } - componentWillUnmount(){} - componentDidUnmount(){} - componentWillMount(){} - componentDidMount(){} - render() { - return h('element'+(++counter)); - } - } - spyAll(Inner2.prototype); - - render(, scratch); - - // outer should only have been mounted once - expect(Outer.prototype.componentWillMount, 'outer initial').to.have.been.calledOnce; - expect(Outer.prototype.componentDidMount, 'outer initial').to.have.been.calledOnce; - expect(Outer.prototype.componentWillUnmount, 'outer initial').not.to.have.been.called; - expect(Outer.prototype.componentDidUnmount, 'outer initial').not.to.have.been.called; - - // inner should only have been mounted once - expect(Inner.prototype.componentWillMount, 'inner initial').to.have.been.calledOnce; - expect(Inner.prototype.componentDidMount, 'inner initial').to.have.been.calledOnce; - expect(Inner.prototype.componentWillUnmount, 'inner initial').not.to.have.been.called; - expect(Inner.prototype.componentDidUnmount, 'inner initial').not.to.have.been.called; - - outer.setState({ child:Inner2 }); - outer.forceUpdate(); - - expect(Inner2.prototype.render).to.have.been.calledOnce; - - // outer should still only have been mounted once - expect(Outer.prototype.componentWillMount, 'outer swap').to.have.been.calledOnce; - expect(Outer.prototype.componentDidMount, 'outer swap').to.have.been.calledOnce; - expect(Outer.prototype.componentWillUnmount, 'outer swap').not.to.have.been.called; - expect(Outer.prototype.componentDidUnmount, 'outer swap').not.to.have.been.called; - - // inner should only have been mounted once - expect(Inner2.prototype.componentWillMount, 'inner2 swap').to.have.been.calledOnce; - expect(Inner2.prototype.componentDidMount, 'inner2 swap').to.have.been.calledOnce; - expect(Inner2.prototype.componentWillUnmount, 'inner2 swap').not.to.have.been.called; - expect(Inner2.prototype.componentDidUnmount, 'inner2 swap').not.to.have.been.called; - - inner2.forceUpdate(); - - expect(Inner2.prototype.render, 'inner2 update').to.have.been.calledTwice; - expect(Inner2.prototype.componentWillMount, 'inner2 update').to.have.been.calledOnce; - expect(Inner2.prototype.componentDidMount, 'inner2 update').to.have.been.calledOnce; - expect(Inner2.prototype.componentWillUnmount, 'inner2 update').not.to.have.been.called; - expect(Inner2.prototype.componentDidUnmount, 'inner2 update').not.to.have.been.called; - }); - - it('should remount when swapping between HOC child types', () => { - class Outer extends Component { - render({ child: Child }) { - return ; - } - } - - class Inner extends Component { - componentWillMount() {} - componentWillUnmount() {} - render() { - return
foo
; - } - } - spyAll(Inner.prototype); - - const InnerFunc = () => ( -
bar
- ); - - let root = render(, scratch, root); - - expect(Inner.prototype.componentWillMount, 'initial mount').to.have.been.calledOnce; - expect(Inner.prototype.componentWillUnmount, 'initial mount').not.to.have.been.called; - - Inner.prototype.componentWillMount.reset(); - root = render(, scratch, root); - - expect(Inner.prototype.componentWillMount, 'unmount').not.to.have.been.called; - expect(Inner.prototype.componentWillUnmount, 'unmount').to.have.been.calledOnce; - - Inner.prototype.componentWillUnmount.reset(); - root = render(, scratch, root); - - expect(Inner.prototype.componentWillMount, 'remount').to.have.been.calledOnce; - expect(Inner.prototype.componentWillUnmount, 'remount').not.to.have.been.called; - }); - }); - - describe('Component Nesting', () => { - let useIntermediary = false; - - let createComponent = (Intermediary) => { - class C extends Component { - componentWillMount() {} - componentDidUnmount() {} - render({ children }) { - if (!useIntermediary) return children[0]; - let I = useIntermediary===true ? Intermediary : useIntermediary; - return {children}; - } - } - spyAll(C.prototype); - return C; - }; - - let createFunction = () => sinon.spy( ({ children }) => children[0] ); - - let root; - let rndr = n => root = render(n, scratch, root); - - let F1 = createFunction(); - let F2 = createFunction(); - let F3 = createFunction(); - - let C1 = createComponent(F1); - let C2 = createComponent(F2); - let C3 = createComponent(F3); - - let reset = () => [C1, C2, C3].reduce( - (acc, c) => acc.concat( Object.keys(c.prototype).map(key => c.prototype[key]) ), - [F1, F2, F3] - ).forEach( c => c.reset && c.reset() ); - - - it('should handle lifecycle for no intermediary in component tree', () => { - reset(); - rndr(Some Text); - - expect(C1.prototype.componentWillMount, 'initial mount').to.have.been.calledOnce; - expect(C2.prototype.componentWillMount, 'initial mount').to.have.been.calledOnce; - expect(C3.prototype.componentWillMount, 'initial mount').to.have.been.calledOnce; - - reset(); - rndr(Some Text); - - expect(C1.prototype.componentWillMount, 'unmount innermost, C1').not.to.have.been.called; - expect(C2.prototype.componentWillMount, 'unmount innermost, C2').not.to.have.been.called; - expect(C3.prototype.componentDidUnmount, 'unmount innermost, C3').to.have.been.calledOnce; - - reset(); - rndr(Some Text); - - expect(C1.prototype.componentWillMount, 'swap innermost').not.to.have.been.called; - expect(C2.prototype.componentDidUnmount, 'swap innermost').to.have.been.calledOnce; - expect(C3.prototype.componentWillMount, 'swap innermost').to.have.been.calledOnce; - - reset(); - rndr(Some Text); - - expect(C1.prototype.componentDidUnmount, 'inject between, C1').not.to.have.been.called; - expect(C1.prototype.componentWillMount, 'inject between, C1').not.to.have.been.called; - expect(C2.prototype.componentWillMount, 'inject between, C2').to.have.been.calledOnce; - expect(C3.prototype.componentDidUnmount, 'inject between, C3').to.have.been.calledOnce; - expect(C3.prototype.componentWillMount, 'inject between, C3').to.have.been.calledOnce; - }); - - - it('should handle lifecycle for nested intermediary functional components', () => { - useIntermediary = true; - - rndr(
); - reset(); - rndr(Some Text); - - expect(C1.prototype.componentWillMount, 'initial mount w/ intermediary fn, C1').to.have.been.calledOnce; - expect(C2.prototype.componentWillMount, 'initial mount w/ intermediary fn, C2').to.have.been.calledOnce; - expect(C3.prototype.componentWillMount, 'initial mount w/ intermediary fn, C3').to.have.been.calledOnce; - - reset(); - rndr(Some Text); - - expect(C1.prototype.componentWillMount, 'unmount innermost w/ intermediary fn, C1').not.to.have.been.called; - expect(C2.prototype.componentWillMount, 'unmount innermost w/ intermediary fn, C2').not.to.have.been.called; - expect(C3.prototype.componentDidUnmount, 'unmount innermost w/ intermediary fn, C3').to.have.been.calledOnce; - - reset(); - rndr(Some Text); - - expect(C1.prototype.componentWillMount, 'swap innermost w/ intermediary fn').not.to.have.been.called; - expect(C2.prototype.componentDidUnmount, 'swap innermost w/ intermediary fn').to.have.been.calledOnce; - expect(C3.prototype.componentWillMount, 'swap innermost w/ intermediary fn').to.have.been.calledOnce; - - reset(); - rndr(Some Text); - - expect(C1.prototype.componentDidUnmount, 'inject between, C1 w/ intermediary fn').not.to.have.been.called; - expect(C1.prototype.componentWillMount, 'inject between, C1 w/ intermediary fn').not.to.have.been.called; - expect(C2.prototype.componentWillMount, 'inject between, C2 w/ intermediary fn').to.have.been.calledOnce; - expect(C3.prototype.componentDidUnmount, 'inject between, C3 w/ intermediary fn').to.have.been.calledOnce; - expect(C3.prototype.componentWillMount, 'inject between, C3 w/ intermediary fn').to.have.been.calledOnce; - }); - - - it('should handle lifecycle for nested intermediary elements', () => { - useIntermediary = 'div'; - - rndr(
); - reset(); - rndr(Some Text); - - expect(C1.prototype.componentWillMount, 'initial mount w/ intermediary div, C1').to.have.been.calledOnce; - expect(C2.prototype.componentWillMount, 'initial mount w/ intermediary div, C2').to.have.been.calledOnce; - expect(C3.prototype.componentWillMount, 'initial mount w/ intermediary div, C3').to.have.been.calledOnce; - - reset(); - rndr(Some Text); - - expect(C1.prototype.componentWillMount, 'unmount innermost w/ intermediary div, C1').not.to.have.been.called; - expect(C2.prototype.componentDidUnmount, 'unmount innermost w/ intermediary div, C2 ummount').not.to.have.been.called; - expect(C2.prototype.componentWillMount, 'unmount innermost w/ intermediary div, C2').not.to.have.been.called; - expect(C3.prototype.componentDidUnmount, 'unmount innermost w/ intermediary div, C3').to.have.been.calledOnce; - - reset(); - rndr(Some Text); - - expect(C1.prototype.componentWillMount, 'swap innermost w/ intermediary div').not.to.have.been.called; - expect(C2.prototype.componentDidUnmount, 'swap innermost w/ intermediary div').to.have.been.calledOnce; - expect(C3.prototype.componentWillMount, 'swap innermost w/ intermediary div').to.have.been.calledOnce; - - reset(); - rndr(Some Text); - - expect(C1.prototype.componentDidUnmount, 'inject between, C1 w/ intermediary div').not.to.have.been.called; - expect(C1.prototype.componentWillMount, 'inject between, C1 w/ intermediary div').not.to.have.been.called; - expect(C2.prototype.componentWillMount, 'inject between, C2 w/ intermediary div').to.have.been.calledOnce; - expect(C3.prototype.componentDidUnmount, 'inject between, C3 w/ intermediary div').to.have.been.calledOnce; - expect(C3.prototype.componentWillMount, 'inject between, C3 w/ intermediary div').to.have.been.calledOnce; - }); - }); -}); diff --git a/thirdparty/preact/test/browser/context.js b/thirdparty/preact/test/browser/context.js deleted file mode 100644 index ed5f81471..000000000 --- a/thirdparty/preact/test/browser/context.js +++ /dev/null @@ -1,174 +0,0 @@ -import { h, render, Component } from '../../src/preact'; -/** @jsx h */ - -const CHILDREN_MATCHER = sinon.match( v => v==null || Array.isArray(v) && !v.length , '[empty children]'); - -describe('context', () => { - let scratch; - - before( () => { - scratch = document.createElement('div'); - (document.body || document.documentElement).appendChild(scratch); - }); - - beforeEach( () => { - scratch.innerHTML = ''; - }); - - after( () => { - scratch.parentNode.removeChild(scratch); - scratch = null; - }); - - it('should pass context to grandchildren', () => { - const CONTEXT = { a:'a' }; - const PROPS = { b:'b' }; - // let inner; - - class Outer extends Component { - getChildContext() { - return CONTEXT; - } - render(props) { - return
; - } - } - sinon.spy(Outer.prototype, 'getChildContext'); - - class Inner extends Component { - // constructor() { - // super(); - // inner = this; - // } - shouldComponentUpdate() { return true; } - componentWillReceiveProps() {} - componentWillUpdate() {} - componentDidUpdate() {} - render(props, state, context) { - return
{ context && context.a }
; - } - } - sinon.spy(Inner.prototype, 'shouldComponentUpdate'); - sinon.spy(Inner.prototype, 'componentWillReceiveProps'); - sinon.spy(Inner.prototype, 'componentWillUpdate'); - sinon.spy(Inner.prototype, 'componentDidUpdate'); - sinon.spy(Inner.prototype, 'render'); - - render(, scratch, scratch.lastChild); - - expect(Outer.prototype.getChildContext).to.have.been.calledOnce; - - // initial render does not invoke anything but render(): - expect(Inner.prototype.render).to.have.been.calledWith({ children:CHILDREN_MATCHER }, {}, CONTEXT); - - CONTEXT.foo = 'bar'; - render(, scratch, scratch.lastChild); - - expect(Outer.prototype.getChildContext).to.have.been.calledTwice; - - let props = { children: CHILDREN_MATCHER, ...PROPS }; - expect(Inner.prototype.shouldComponentUpdate).to.have.been.calledOnce.and.calledWith(props, {}, CONTEXT); - expect(Inner.prototype.componentWillReceiveProps).to.have.been.calledWith(props, CONTEXT); - expect(Inner.prototype.componentWillUpdate).to.have.been.calledWith(props, {}); - expect(Inner.prototype.componentDidUpdate).to.have.been.calledWith({ children:CHILDREN_MATCHER }, {}); - expect(Inner.prototype.render).to.have.been.calledWith(props, {}, CONTEXT); - - - /* Future: - * Newly created context objects are *not* currently cloned. - * This test checks that they *are* cloned. - */ - // Inner.prototype.render.reset(); - // CONTEXT.foo = 'baz'; - // inner.forceUpdate(); - // expect(Inner.prototype.render).to.have.been.calledWith(PROPS, {}, { a:'a', foo:'bar' }); - }); - - it('should pass context to direct children', () => { - const CONTEXT = { a:'a' }; - const PROPS = { b:'b' }; - - class Outer extends Component { - getChildContext() { - return CONTEXT; - } - render(props) { - return ; - } - } - sinon.spy(Outer.prototype, 'getChildContext'); - - class Inner extends Component { - shouldComponentUpdate() { return true; } - componentWillReceiveProps() {} - componentWillUpdate() {} - componentDidUpdate() {} - render(props, state, context) { - return
{ context && context.a }
; - } - } - sinon.spy(Inner.prototype, 'shouldComponentUpdate'); - sinon.spy(Inner.prototype, 'componentWillReceiveProps'); - sinon.spy(Inner.prototype, 'componentWillUpdate'); - sinon.spy(Inner.prototype, 'componentDidUpdate'); - sinon.spy(Inner.prototype, 'render'); - - render(, scratch, scratch.lastChild); - - expect(Outer.prototype.getChildContext).to.have.been.calledOnce; - - // initial render does not invoke anything but render(): - expect(Inner.prototype.render).to.have.been.calledWith({ children: CHILDREN_MATCHER }, {}, CONTEXT); - - CONTEXT.foo = 'bar'; - render(, scratch, scratch.lastChild); - - expect(Outer.prototype.getChildContext).to.have.been.calledTwice; - - let props = { children: CHILDREN_MATCHER, ...PROPS }; - expect(Inner.prototype.shouldComponentUpdate).to.have.been.calledOnce.and.calledWith(props, {}, CONTEXT); - expect(Inner.prototype.componentWillReceiveProps).to.have.been.calledWith(props, CONTEXT); - expect(Inner.prototype.componentWillUpdate).to.have.been.calledWith(props, {}); - expect(Inner.prototype.componentDidUpdate).to.have.been.calledWith({ children: CHILDREN_MATCHER }, {}); - expect(Inner.prototype.render).to.have.been.calledWith(props, {}, CONTEXT); - - // make sure render() could make use of context.a - expect(Inner.prototype.render).to.have.returned(sinon.match({ children:['a'] })); - }); - - it('should preserve existing context properties when creating child contexts', () => { - let outerContext = { outer:true }, - innerContext = { inner:true }; - class Outer extends Component { - getChildContext() { - return { outerContext }; - } - render() { - return
; - } - } - - class Inner extends Component { - getChildContext() { - return { innerContext }; - } - render() { - return ; - } - } - - class InnerMost extends Component { - render() { - return test; - } - } - - sinon.spy(Inner.prototype, 'render'); - sinon.spy(InnerMost.prototype, 'render'); - - render(, scratch); - - expect(Inner.prototype.render).to.have.been.calledWith({ children: CHILDREN_MATCHER }, {}, { outerContext }); - expect(InnerMost.prototype.render).to.have.been.calledWith({ children: CHILDREN_MATCHER }, {}, { outerContext, innerContext }); - }); -}); diff --git a/thirdparty/preact/test/browser/devtools.js b/thirdparty/preact/test/browser/devtools.js deleted file mode 100644 index 12c0e3369..000000000 --- a/thirdparty/preact/test/browser/devtools.js +++ /dev/null @@ -1,234 +0,0 @@ -import { h, Component, render } from '../../src/preact'; -import { initDevTools } from '../../devtools/devtools'; -import { unmountComponent } from '../../src/vdom/component'; - -class StatefulComponent extends Component { - constructor(props) { - super(props); - - this.state = {count: 0}; - } - - render() { - return h('span', {}, String(this.state.count)); - } -} - -function FunctionalComponent() { - return h('span', {class: 'functional'}, 'Functional'); -} - -function Label({label}) { - return label; -} - -class MultiChild extends Component { - constructor(props) { - super(props); - this.state = {count: props.initialCount}; - } - - render() { - return h('div', {}, Array(this.state.count).fill('child')); - } -} - -let describe_ = describe; -if (!('name' in Function.prototype)) { - // Skip these tests under Internet Explorer - describe_ = describe.skip; -} - -describe_('React Developer Tools integration', () => { - let cleanup; - let container; - let renderer; - - // Maps of DOM node to React*Component-like objects. - // For composite components, there will be two instances for each node, one - // for the composite component (instanceMap) and one for the root child DOM - // component rendered by that component (domInstanceMap) - let instanceMap = new Map(); - let domInstanceMap = new Map(); - - beforeEach(() => { - container = document.createElement('div'); - document.body.appendChild(container); - - const onMount = instance => { - if (instance._renderedChildren) { - domInstanceMap.set(instance.node, instance); - } else { - instanceMap.set(instance.node, instance); - } - }; - - const onUnmount = instance => { - instanceMap.delete(instance.node); - domInstanceMap.delete(instance.node); - }; - - global.__REACT_DEVTOOLS_GLOBAL_HOOK__ = { - inject: sinon.spy(_renderer => { - renderer = _renderer; - renderer.Mount._renderNewRootComponent = sinon.stub(); - renderer.Reconciler.mountComponent = sinon.spy(onMount); - renderer.Reconciler.unmountComponent = sinon.spy(onUnmount); - renderer.Reconciler.receiveComponent = sinon.stub(); - }) - }; - cleanup = initDevTools(); - }); - - afterEach(() => { - container.remove(); - cleanup(); - }); - - it('registers preact as a renderer with the React DevTools hook', () => { - expect(global.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject).to.be.called; - }); - - // Basic component addition/update/removal tests - it('notifies dev tools about new components', () => { - render(h(StatefulComponent), container); - expect(renderer.Reconciler.mountComponent).to.be.called; - }); - - it('notifies dev tools about component updates', () => { - const node = render(h(StatefulComponent), container); - node._component.forceUpdate(); - expect(renderer.Reconciler.receiveComponent).to.be.called; - }); - - it('notifies dev tools when components are removed', () => { - const node = render(h(StatefulComponent), container); - unmountComponent(node._component, true); - expect(renderer.Reconciler.unmountComponent).to.be.called; - }); - - // Test properties of DOM components exposed to devtools via - // ReactDOMComponent-like instances - it('exposes the tag name of DOM components', () => { - const node = render(h(StatefulComponent), container); - const domInstance = domInstanceMap.get(node); - expect(domInstance._currentElement.type).to.equal('span'); - }); - - it('exposes DOM component props', () => { - const node = render(h(FunctionalComponent), container); - const domInstance = domInstanceMap.get(node); - expect(domInstance._currentElement.props.class).to.equal('functional'); - }); - - it('exposes text component contents', () => { - const node = render(h(Label, {label: 'Text content'}), container); - const textInstance = domInstanceMap.get(node); - expect(textInstance._stringText).to.equal('Text content'); - }); - - // Test properties of composite components exposed to devtools via - // ReactCompositeComponent-like instances - it('exposes the name of composite component classes', () => { - const node = render(h(StatefulComponent), container); - expect(instanceMap.get(node).getName()).to.equal('StatefulComponent'); - }); - - it('exposes composite component props', () => { - const node = render(h(Label, {label: 'Text content'}), container); - const instance = instanceMap.get(node); - expect(instance._currentElement.props.label).to.equal('Text content'); - }); - - it('exposes composite component state', () => { - const node = render(h(StatefulComponent), container); - - node._component.setState({count: 42}); - node._component.forceUpdate(); - - expect(instanceMap.get(node).state).to.deep.equal({count: 42}); - }); - - // Test setting state via devtools - it('updates component when setting state from devtools', () => { - const node = render(h(StatefulComponent), container); - - instanceMap.get(node).setState({count: 10}); - instanceMap.get(node).forceUpdate(); - - expect(node.textContent).to.equal('10'); - }); - - // Test that the original instance is exposed via `_instance` so it can - // be accessed conveniently via `$r` in devtools - - // Functional component handling tests - it('wraps functional components with stateful ones', () => { - const vnode = h(FunctionalComponent); - expect(vnode.nodeName.prototype).to.have.property('render'); - }); - - it('exposes the name of functional components', () => { - const node = render(h(FunctionalComponent), container); - const instance = instanceMap.get(node); - expect(instance.getName()).to.equal('FunctionalComponent'); - }); - - it('exposes a fallback name if the component has no useful name', () => { - const node = render(h(() => h('div')), container); - const instance = instanceMap.get(node); - expect(instance.getName()).to.equal('(Function.name missing)'); - }); - - // Test handling of DOM children - it('notifies dev tools about DOM children', () => { - const node = render(h(StatefulComponent), container); - const domInstance = domInstanceMap.get(node); - expect(renderer.Reconciler.mountComponent).to.have.been.calledWith(domInstance); - }); - - it('notifies dev tools when a component update adds DOM children', () => { - const node = render(h(MultiChild, {initialCount: 2}), container); - - node._component.setState({count: 4}); - node._component.forceUpdate(); - - expect(renderer.Reconciler.mountComponent).to.have.been.called.twice; - }); - - it('notifies dev tools when a component update modifies DOM children', () => { - const node = render(h(StatefulComponent), container); - - instanceMap.get(node).setState({count: 10}); - instanceMap.get(node).forceUpdate(); - - const textInstance = domInstanceMap.get(node.childNodes[0]); - expect(textInstance._stringText).to.equal('10'); - }); - - it('notifies dev tools when a component update removes DOM children', () => { - const node = render(h(MultiChild, {initialCount: 1}), container); - - node._component.setState({count: 0}); - node._component.forceUpdate(); - - expect(renderer.Reconciler.unmountComponent).to.be.called; - }); - - // Root component info - it('exposes root components on the _instancesByReactRootID map', () => { - render(h(StatefulComponent), container); - expect(Object.keys(renderer.Mount._instancesByReactRootID).length).to.equal(1); - }); - - it('notifies dev tools when new root components are mounted', () => { - render(h(StatefulComponent), container); - expect(renderer.Mount._renderNewRootComponent).to.be.called; - }); - - it('removes root components when they are unmounted', () => { - const node = render(h(StatefulComponent), container); - unmountComponent(node._component, true); - expect(Object.keys(renderer.Mount._instancesByReactRootID).length).to.equal(0); - }); -}); diff --git a/thirdparty/preact/test/browser/keys.js b/thirdparty/preact/test/browser/keys.js deleted file mode 100644 index e0a6b9ae8..000000000 --- a/thirdparty/preact/test/browser/keys.js +++ /dev/null @@ -1,85 +0,0 @@ -import { h, Component, render } from '../../src/preact'; -/** @jsx h */ - -describe('keys', () => { - let scratch; - - before( () => { - scratch = document.createElement('div'); - (document.body || document.documentElement).appendChild(scratch); - }); - - beforeEach( () => { - scratch.innerHTML = ''; - }); - - after( () => { - scratch.parentNode.removeChild(scratch); - scratch = null; - }); - - // See developit/preact-compat#21 - it('should remove orphaned keyed nodes', () => { - let root = render(( -
-
1
-
  • a
  • -
    - ), scratch); - - root = render(( -
    -
    2
    -
  • b
  • -
    - ), scratch, root); - - expect(scratch.innerHTML).to.equal('
    2
  • b
  • '); - }); - - it('should set VNode#key property', () => { - expect(
    ).to.have.property('key').that.is.empty; - expect(
    ).to.have.property('key').that.is.empty; - expect(
    ).to.have.property('key', '1'); - }); - - it('should remove keyed nodes (#232)', () => { - class App extends Component { - componentDidMount() { - setTimeout(() => this.setState({opened: true,loading: true}), 10); - setTimeout(() => this.setState({opened: true,loading: false}), 20); - } - - render({ opened, loading }) { - return ( - -
    This div needs to be here for this to break
    - { opened && !loading &&
    {[]}
    } -
    - ); - } - } - - class BusyIndicator extends Component { - render({ children, busy }) { - return
    - { children && children.length ? children :
    } -
    -
    indicator
    -
    indicator
    -
    indicator
    -
    -
    ; - } - } - - let root; - - root = render(, scratch, root); - root = render(, scratch, root); - root = render(, scratch, root); - - let html = String(root.innerHTML).replace(/ class=""/g, ''); - expect(html).to.equal('
    This div needs to be here for this to break
    indicator
    indicator
    indicator
    '); - }); -}); diff --git a/thirdparty/preact/test/browser/lifecycle.js b/thirdparty/preact/test/browser/lifecycle.js deleted file mode 100644 index 4deb92163..000000000 --- a/thirdparty/preact/test/browser/lifecycle.js +++ /dev/null @@ -1,495 +0,0 @@ -import { h, render, rerender, Component } from '../../src/preact'; -/** @jsx h */ - -let spyAll = obj => Object.keys(obj).forEach( key => sinon.spy(obj,key) ); - -const EMPTY_CHILDREN = []; - -describe('Lifecycle methods', () => { - let scratch; - - before( () => { - scratch = document.createElement('div'); - (document.body || document.documentElement).appendChild(scratch); - }); - - beforeEach( () => { - scratch.innerHTML = ''; - }); - - after( () => { - scratch.parentNode.removeChild(scratch); - scratch = null; - }); - - - describe('#componentWillUpdate', () => { - it('should NOT be called on initial render', () => { - class ReceivePropsComponent extends Component { - componentWillUpdate() {} - render() { - return
    ; - } - } - sinon.spy(ReceivePropsComponent.prototype, 'componentWillUpdate'); - render(, scratch); - expect(ReceivePropsComponent.prototype.componentWillUpdate).not.to.have.been.called; - }); - - it('should be called when rerender with new props from parent', () => { - let doRender; - class Outer extends Component { - constructor(p, c) { - super(p, c); - this.state = { i: 0 }; - } - componentDidMount() { - doRender = () => this.setState({ i: this.state.i + 1 }); - } - render(props, { i }) { - return ; - } - } - class Inner extends Component { - componentWillUpdate(nextProps, nextState) { - expect(nextProps).to.be.deep.equal({ children:EMPTY_CHILDREN, i: 1 }); - expect(nextState).to.be.deep.equal({}); - } - render() { - return
    ; - } - } - sinon.spy(Inner.prototype, 'componentWillUpdate'); - sinon.spy(Outer.prototype, 'componentDidMount'); - - // Initial render - render(, scratch); - expect(Inner.prototype.componentWillUpdate).not.to.have.been.called; - - // Rerender inner with new props - doRender(); - rerender(); - expect(Inner.prototype.componentWillUpdate).to.have.been.called; - }); - - it('should be called on new state', () => { - let doRender; - class ReceivePropsComponent extends Component { - componentWillUpdate() {} - componentDidMount() { - doRender = () => this.setState({ i: this.state.i + 1 }); - } - render() { - return
    ; - } - } - sinon.spy(ReceivePropsComponent.prototype, 'componentWillUpdate'); - render(, scratch); - expect(ReceivePropsComponent.prototype.componentWillUpdate).not.to.have.been.called; - - doRender(); - rerender(); - expect(ReceivePropsComponent.prototype.componentWillUpdate).to.have.been.called; - }); - }); - - describe('#componentWillReceiveProps', () => { - it('should NOT be called on initial render', () => { - class ReceivePropsComponent extends Component { - componentWillReceiveProps() {} - render() { - return
    ; - } - } - sinon.spy(ReceivePropsComponent.prototype, 'componentWillReceiveProps'); - render(, scratch); - expect(ReceivePropsComponent.prototype.componentWillReceiveProps).not.to.have.been.called; - }); - - it('should be called when rerender with new props from parent', () => { - let doRender; - class Outer extends Component { - constructor(p, c) { - super(p, c); - this.state = { i: 0 }; - } - componentDidMount() { - doRender = () => this.setState({ i: this.state.i + 1 }); - } - render(props, { i }) { - return ; - } - } - class Inner extends Component { - componentWillMount() { - expect(this.props.i).to.be.equal(0); - } - componentWillReceiveProps(nextProps) { - expect(nextProps.i).to.be.equal(1); - } - render() { - return
    ; - } - } - sinon.spy(Inner.prototype, 'componentWillReceiveProps'); - sinon.spy(Outer.prototype, 'componentDidMount'); - - // Initial render - render(, scratch); - expect(Inner.prototype.componentWillReceiveProps).not.to.have.been.called; - - // Rerender inner with new props - doRender(); - rerender(); - expect(Inner.prototype.componentWillReceiveProps).to.have.been.called; - }); - - it('should be called in right execution order', () => { - let doRender; - class Outer extends Component { - constructor(p, c) { - super(p, c); - this.state = { i: 0 }; - } - componentDidMount() { - doRender = () => this.setState({ i: this.state.i + 1 }); - } - render(props, { i }) { - return ; - } - } - class Inner extends Component { - componentDidUpdate() { - expect(Inner.prototype.componentWillReceiveProps).to.have.been.called; - expect(Inner.prototype.componentWillUpdate).to.have.been.called; - } - componentWillReceiveProps() { - expect(Inner.prototype.componentWillUpdate).not.to.have.been.called; - expect(Inner.prototype.componentDidUpdate).not.to.have.been.called; - } - componentWillUpdate() { - expect(Inner.prototype.componentWillReceiveProps).to.have.been.called; - expect(Inner.prototype.componentDidUpdate).not.to.have.been.called; - } - render() { - return
    ; - } - } - sinon.spy(Inner.prototype, 'componentWillReceiveProps'); - sinon.spy(Inner.prototype, 'componentDidUpdate'); - sinon.spy(Inner.prototype, 'componentWillUpdate'); - sinon.spy(Outer.prototype, 'componentDidMount'); - - render(, scratch); - doRender(); - rerender(); - - expect(Inner.prototype.componentWillReceiveProps).to.have.been.calledBefore(Inner.prototype.componentWillUpdate); - expect(Inner.prototype.componentWillUpdate).to.have.been.calledBefore(Inner.prototype.componentDidUpdate); - }); - }); - - - let _it = it; - describe('#constructor and component(Did|Will)(Mount|Unmount)', () => { - /* global DISABLE_FLAKEY */ - let it = DISABLE_FLAKEY ? xit : _it; - - let setState; - class Outer extends Component { - constructor(p, c) { - super(p, c); - this.state = { show:true }; - setState = s => this.setState(s); - } - render(props, { show }) { - return ( -
    - { show && ( - - ) } -
    - ); - } - } - - class LifecycleTestComponent extends Component { - constructor(p, c) { super(p, c); this._constructor(); } - _constructor() {} - componentWillMount() {} - componentDidMount() {} - componentWillUnmount() {} - componentDidUnmount() {} - render() { return
    ; } - } - - class Inner extends LifecycleTestComponent { - render() { - return ( -
    - -
    - ); - } - } - - class InnerMost extends LifecycleTestComponent { - render() { return
    ; } - } - - let spies = ['_constructor', 'componentWillMount', 'componentDidMount', 'componentWillUnmount', 'componentDidUnmount']; - - let verifyLifycycleMethods = (TestComponent) => { - let proto = TestComponent.prototype; - spies.forEach( s => sinon.spy(proto, s) ); - let reset = () => spies.forEach( s => proto[s].reset() ); - - it('should be invoked for components on initial render', () => { - reset(); - render(, scratch); - expect(proto._constructor).to.have.been.called; - expect(proto.componentDidMount).to.have.been.called; - expect(proto.componentWillMount).to.have.been.calledBefore(proto.componentDidMount); - expect(proto.componentDidMount).to.have.been.called; - }); - - it('should be invoked for components on unmount', () => { - reset(); - setState({ show:false }); - rerender(); - - expect(proto.componentDidUnmount).to.have.been.called; - expect(proto.componentWillUnmount).to.have.been.calledBefore(proto.componentDidUnmount); - expect(proto.componentDidUnmount).to.have.been.called; - }); - - it('should be invoked for components on re-render', () => { - reset(); - setState({ show:true }); - rerender(); - - expect(proto._constructor).to.have.been.called; - expect(proto.componentDidMount).to.have.been.called; - expect(proto.componentWillMount).to.have.been.calledBefore(proto.componentDidMount); - expect(proto.componentDidMount).to.have.been.called; - }); - }; - - describe('inner components', () => { - verifyLifycycleMethods(Inner); - }); - - describe('innermost components', () => { - verifyLifycycleMethods(InnerMost); - }); - - describe('when shouldComponentUpdate() returns false', () => { - let setState; - - class Outer extends Component { - constructor() { - super(); - this.state = { show:true }; - setState = s => this.setState(s); - } - render(props, { show }) { - return ( -
    - { show && ( -
    - -
    - ) } -
    - ); - } - } - - class Inner extends Component { - shouldComponentUpdate(){ return false; } - componentWillMount() {} - componentDidMount() {} - componentWillUnmount() {} - componentDidUnmount() {} - render() { - return
    ; - } - } - - let proto = Inner.prototype; - let spies = ['componentWillMount', 'componentDidMount', 'componentWillUnmount', 'componentDidUnmount']; - spies.forEach( s => sinon.spy(proto, s) ); - - let reset = () => spies.forEach( s => proto[s].reset() ); - - beforeEach( () => reset() ); - - it('should be invoke normally on initial mount', () => { - render(, scratch); - expect(proto.componentWillMount).to.have.been.called; - expect(proto.componentWillMount).to.have.been.calledBefore(proto.componentDidMount); - expect(proto.componentDidMount).to.have.been.called; - }); - - it('should be invoked normally on unmount', () => { - setState({ show:false }); - rerender(); - - expect(proto.componentWillUnmount).to.have.been.called; - expect(proto.componentWillUnmount).to.have.been.calledBefore(proto.componentDidUnmount); - expect(proto.componentDidUnmount).to.have.been.called; - }); - - it('should still invoke mount for shouldComponentUpdate():false', () => { - setState({ show:true }); - rerender(); - - expect(proto.componentWillMount).to.have.been.called; - expect(proto.componentWillMount).to.have.been.calledBefore(proto.componentDidMount); - expect(proto.componentDidMount).to.have.been.called; - }); - - it('should still invoke unmount for shouldComponentUpdate():false', () => { - setState({ show:false }); - rerender(); - - expect(proto.componentWillUnmount).to.have.been.called; - expect(proto.componentWillUnmount).to.have.been.calledBefore(proto.componentDidUnmount); - expect(proto.componentDidUnmount).to.have.been.called; - }); - }); - }); - - describe('Lifecycle DOM Timing', () => { - it('should be invoked when dom does (DidMount, WillUnmount) or does not (WillMount, DidUnmount) exist', () => { - let setState; - class Outer extends Component { - constructor() { - super(); - this.state = { show:true }; - setState = s => { - this.setState(s); - this.forceUpdate(); - }; - } - componentWillMount() { - expect(document.getElementById('OuterDiv'), 'Outer componentWillMount').to.not.exist; - } - componentDidMount() { - expect(document.getElementById('OuterDiv'), 'Outer componentDidMount').to.exist; - } - componentWillUnmount() { - expect(document.getElementById('OuterDiv'), 'Outer componentWillUnmount').to.exist; - } - componentDidUnmount() { - expect(document.getElementById('OuterDiv'), 'Outer componentDidUnmount').to.not.exist; - } - render(props, { show }) { - return ( -
    - { show && ( -
    - -
    - ) } -
    - ); - } - } - - class Inner extends Component { - componentWillMount() { - expect(document.getElementById('InnerDiv'), 'Inner componentWillMount').to.not.exist; - } - componentDidMount() { - expect(document.getElementById('InnerDiv'), 'Inner componentDidMount').to.exist; - } - componentWillUnmount() { - // @TODO Component mounted into elements (non-components) - // are currently unmounted after those elements, so their - // DOM is unmounted prior to the method being called. - //expect(document.getElementById('InnerDiv'), 'Inner componentWillUnmount').to.exist; - } - componentDidUnmount() { - expect(document.getElementById('InnerDiv'), 'Inner componentDidUnmount').to.not.exist; - } - - render() { - return
    ; - } - } - - let proto = Inner.prototype; - let spies = ['componentWillMount', 'componentDidMount', 'componentWillUnmount', 'componentDidUnmount']; - spies.forEach( s => sinon.spy(proto, s) ); - - let reset = () => spies.forEach( s => proto[s].reset() ); - - render(, scratch); - expect(proto.componentWillMount).to.have.been.called; - expect(proto.componentWillMount).to.have.been.calledBefore(proto.componentDidMount); - expect(proto.componentDidMount).to.have.been.called; - - reset(); - setState({ show:false }); - - expect(proto.componentWillUnmount).to.have.been.called; - expect(proto.componentWillUnmount).to.have.been.calledBefore(proto.componentDidUnmount); - expect(proto.componentDidUnmount).to.have.been.called; - - reset(); - setState({ show:true }); - - expect(proto.componentWillMount).to.have.been.called; - expect(proto.componentWillMount).to.have.been.calledBefore(proto.componentDidMount); - expect(proto.componentDidMount).to.have.been.called; - }); - - it('should remove this.base for HOC', () => { - let createComponent = (name, fn) => { - class C extends Component { - componentWillUnmount() { - expect(this.base, `${name}.componentWillUnmount`).to.exist; - } - componentDidUnmount() { - expect(this.base, `${name}.componentDidUnmount`).not.to.exist; - } - render(props) { return fn(props); } - } - spyAll(C.prototype); - return C; - }; - - class Wrapper extends Component { - render({ children }) { - return
    {children}
    ; - } - } - - let One = createComponent('One', () => one ); - let Two = createComponent('Two', () => two ); - let Three = createComponent('Three', () => three ); - - let components = [One, Two, Three]; - - let Selector = createComponent('Selector', ({ page }) => { - let Child = components[page]; - return ; - }); - - class App extends Component { - render(_, { page }) { - return ; - } - } - - let app; - render( app=c } />, scratch); - - for (let i=0; i<20; i++) { - app.setState({ page: i%components.length }); - app.forceUpdate(); - } - }); - }); -}); diff --git a/thirdparty/preact/test/browser/linked-state.js b/thirdparty/preact/test/browser/linked-state.js deleted file mode 100644 index 03db2a7b8..000000000 --- a/thirdparty/preact/test/browser/linked-state.js +++ /dev/null @@ -1,110 +0,0 @@ -import { Component } from '../../src/preact'; -import { createLinkedState } from '../../src/linked-state'; - -describe('linked-state', () => { - class TestComponent extends Component { } - let testComponent, linkFunction; - - before( () => { - testComponent = new TestComponent(); - sinon.spy(TestComponent.prototype, 'setState'); - }); - - describe('createLinkedState without eventPath argument', () => { - - before( () => { - linkFunction = createLinkedState(testComponent,'testStateKey'); - expect(linkFunction).to.be.a('function'); - }); - - beforeEach( () => { - TestComponent.prototype['setState'].reset(); - }); - - it('should use value attribute on text input when no eventPath is supplied', () => { - let element = document.createElement('input'); - element.type= 'text'; - element.value = 'newValue'; - - linkFunction({ - currentTarget: element, - target: element - }); - - expect(TestComponent.prototype.setState).to.have.been.calledOnce; - expect(TestComponent.prototype.setState).to.have.been.calledWith({'testStateKey': 'newValue'}); - - linkFunction.call(element); - - expect(TestComponent.prototype.setState).to.have.been.calledTwice; - expect(TestComponent.prototype.setState.secondCall).to.have.been.calledWith({'testStateKey': 'newValue'}); - }); - - it('should use checked attribute on checkbox input when no eventPath is supplied', () => { - let checkboxElement = document.createElement('input'); - checkboxElement.type= 'checkbox'; - checkboxElement.checked = true; - - linkFunction({ - currentTarget: checkboxElement, - target: checkboxElement - }); - - expect(TestComponent.prototype.setState).to.have.been.calledOnce; - expect(TestComponent.prototype.setState).to.have.been.calledWith({'testStateKey': true}); - }); - - it('should use checked attribute on radio input when no eventPath is supplied', () => { - let radioElement = document.createElement('input'); - radioElement.type= 'radio'; - radioElement.checked = true; - - linkFunction({ - currentTarget: radioElement, - target: radioElement - }); - - expect(TestComponent.prototype.setState).to.have.been.calledOnce; - expect(TestComponent.prototype.setState).to.have.been.calledWith({'testStateKey': true}); - }); - - - it('should set dot notated state key appropriately', () => { - linkFunction = createLinkedState(testComponent,'nested.state.key'); - let element = document.createElement('input'); - element.type= 'text'; - element.value = 'newValue'; - - linkFunction({ - currentTarget: element, - target: element - }); - - expect(TestComponent.prototype.setState).to.have.been.calledOnce; - expect(TestComponent.prototype.setState).to.have.been.calledWith({nested: {state: {key: 'newValue'}}}); - }); - - }); - - describe('createLinkedState with eventPath argument', () => { - - before( () => { - linkFunction = createLinkedState(testComponent,'testStateKey', 'nested.path'); - expect(linkFunction).to.be.a('function'); - }); - - beforeEach( () => { - TestComponent.prototype['setState'].reset(); - }); - - it('should give precedence to nested.path on event over nested.path on component', () => { - let event = {nested: {path: 'nestedPathValueFromEvent'}}; - let component = {_component: {nested: {path: 'nestedPathValueFromComponent'}}}; - - linkFunction.call(component, event); - - expect(TestComponent.prototype.setState).to.have.been.calledOnce; - expect(TestComponent.prototype.setState).to.have.been.calledWith({'testStateKey': 'nestedPathValueFromEvent'}); - }); - }); -}); diff --git a/thirdparty/preact/test/browser/performance.js b/thirdparty/preact/test/browser/performance.js deleted file mode 100644 index e1f7d7956..000000000 --- a/thirdparty/preact/test/browser/performance.js +++ /dev/null @@ -1,245 +0,0 @@ -/*global coverage, ENABLE_PERFORMANCE, NODE_ENV*/ -/*eslint no-console:0*/ -/** @jsx h */ - -let { h, Component, render } = require(NODE_ENV==='production' ? '../../dist/preact.min.js' : '../../src/preact'); - -const MULTIPLIER = ENABLE_PERFORMANCE ? (coverage ? 5 : 1) : 999999; - - -let now = typeof performance!=='undefined' && performance.now ? () => performance.now() : () => +new Date(); - -function loop(iter, time) { - let start = now(), - count = 0; - while ( now()-start < time ) { - count++; - iter(); - } - return count; -} - - -function benchmark(iter, callback) { - let a = 0; - function noop() { - try { a++; } finally { a += Math.random(); } - } - - // warm - for (let i=3; i--; ) noop(), iter(); - - let count = 5, - time = 200, - passes = 0, - noops = loop(noop, time), - iterations = 0; - - function next() { - iterations += loop(iter, time); - setTimeout(++passes===count ? done : next, 10); - } - - function done() { - let ticks = Math.round(noops / iterations * count), - hz = iterations / count / time * 1000, - message = `${hz|0}/s (${ticks} ticks)`; - callback({ iterations, noops, count, time, ticks, hz, message }); - } - - next(); -} - - -describe('performance', function() { - let scratch; - - this.timeout(10000); - - before( () => { - if (coverage) { - console.warn('WARNING: Code coverage is enabled, which dramatically reduces performance. Do not pay attention to these numbers.'); - } - scratch = document.createElement('div'); - (document.body || document.documentElement).appendChild(scratch); - }); - - beforeEach( () => { - scratch.innerHTML = ''; - }); - - after( () => { - scratch.parentNode.removeChild(scratch); - scratch = null; - }); - - it('should rerender without changes fast', done => { - let jsx = ( -
    -
    -

    a {'b'} c {0} d

    - -
    -
    -
    {}}> - - -
    - - -
    - - - - - - -
    -
    -
    - ); - - let root; - benchmark( () => { - root = render(jsx, scratch, root); - }, ({ ticks, message }) => { - console.log(`PERF: empty diff: ${message}`); - expect(ticks).to.be.below(350 * MULTIPLIER); - done(); - }); - }); - - it('should rerender repeated trees fast', done => { - class Header extends Component { - render() { - return ( -
    -

    a {'b'} c {0} d

    - -
    - ); - } - } - class Form extends Component { - render() { - return ( -
    {}}> - - -
    - - -
    - - - ); - } - } - class ButtonBar extends Component { - render() { - return ( - - - - - - - ); - } - } - class Button extends Component { - render(props) { - return - - - - - - -
    - ); - }, ({ ticks, message }) => { - console.log(`PERF: large VTree: ${message}`); - expect(ticks).to.be.below(2000 * MULTIPLIER); - done(); - }); - }); -}); diff --git a/thirdparty/preact/test/browser/refs.js b/thirdparty/preact/test/browser/refs.js deleted file mode 100644 index 337a9717b..000000000 --- a/thirdparty/preact/test/browser/refs.js +++ /dev/null @@ -1,305 +0,0 @@ -import { h, render, Component } from '../../src/preact'; -/** @jsx h */ - -// gives call count and argument errors names (otherwise sinon just uses "spy"): -let spy = (name, ...args) => { - let spy = sinon.spy(...args); - spy.displayName = `spy('${name}')`; - return spy; -}; - -describe('refs', () => { - let scratch; - - before( () => { - scratch = document.createElement('div'); - (document.body || document.documentElement).appendChild(scratch); - }); - - beforeEach( () => { - scratch.innerHTML = ''; - }); - - after( () => { - scratch.parentNode.removeChild(scratch); - scratch = null; - }); - - it('should invoke refs in render()', () => { - let ref = spy('ref'); - render(
    , scratch); - expect(ref).to.have.been.calledOnce.and.calledWith(scratch.firstChild); - }); - - it('should invoke refs in Component.render()', () => { - let outer = spy('outer'), - inner = spy('inner'); - class Foo extends Component { - render() { - return ( -
    - -
    - ); - } - } - render(, scratch); - - expect(outer).to.have.been.calledWith(scratch.firstChild); - expect(inner).to.have.been.calledWith(scratch.firstChild.firstChild); - }); - - it('should pass components to ref functions', () => { - let ref = spy('ref'), - instance; - class Foo extends Component { - constructor() { - super(); - instance = this; - } - render() { - return
    ; - } - } - render(, scratch); - - expect(ref).to.have.been.calledOnce.and.calledWith(instance); - }); - - it('should pass rendered DOM from functional components to ref functions', () => { - let ref = spy('ref'); - - const Foo = () =>
    ; - - let root = render(, scratch); - expect(ref).to.have.been.calledOnce.and.calledWith(scratch.firstChild); - - ref.reset(); - render(, scratch, root); - expect(ref).to.have.been.calledOnce.and.calledWith(scratch.firstChild); - - ref.reset(); - render(, scratch, root); - expect(ref).to.have.been.calledOnce.and.calledWith(null); - }); - - it('should pass children to ref functions', () => { - let outer = spy('outer'), - inner = spy('inner'), - rerender, inst; - class Outer extends Component { - constructor() { - super(); - rerender = () => this.forceUpdate(); - } - render() { - return ( -
    - -
    - ); - } - } - class Inner extends Component { - constructor() { - super(); - inst = this; - } - render() { - return ; - } - } - - let root = render(, scratch); - - expect(outer).to.have.been.calledOnce.and.calledWith(inst); - expect(inner).to.have.been.calledOnce.and.calledWith(inst.base); - - outer.reset(); - inner.reset(); - - rerender(); - - expect(outer).to.have.been.calledOnce.and.calledWith(inst); - expect(inner).to.have.been.calledOnce.and.calledWith(inst.base); - - outer.reset(); - inner.reset(); - - render(
    , scratch, root); - - expect(outer).to.have.been.calledOnce.and.calledWith(null); - expect(inner).to.have.been.calledOnce.and.calledWith(null); - }); - - it('should pass high-order children to ref functions', () => { - let outer = spy('outer'), - inner = spy('inner'), - innermost = spy('innermost'), - outerInst, - innerInst; - class Outer extends Component { - constructor() { - super(); - outerInst = this; - } - render() { - return ; - } - } - class Inner extends Component { - constructor() { - super(); - innerInst = this; - } - render() { - return ; - } - } - - let root = render(, scratch); - - expect(outer, 'outer initial').to.have.been.calledOnce.and.calledWith(outerInst); - expect(inner, 'inner initial').to.have.been.calledOnce.and.calledWith(innerInst); - expect(innermost, 'innerMost initial').to.have.been.calledOnce.and.calledWith(innerInst.base); - - outer.reset(); - inner.reset(); - innermost.reset(); - root = render(, scratch, root); - - expect(outer, 'outer update').to.have.been.calledOnce.and.calledWith(outerInst); - expect(inner, 'inner update').to.have.been.calledOnce.and.calledWith(innerInst); - expect(innermost, 'innerMost update').to.have.been.calledOnce.and.calledWith(innerInst.base); - - outer.reset(); - inner.reset(); - innermost.reset(); - root = render(
    , scratch, root); - - expect(outer, 'outer unmount').to.have.been.calledOnce.and.calledWith(null); - expect(inner, 'inner unmount').to.have.been.calledOnce.and.calledWith(null); - expect(innermost, 'innerMost unmount').to.have.been.calledOnce.and.calledWith(null); - }); - - it('should not pass ref into component as a prop', () => { - let foo = spy('foo'), - bar = spy('bar'); - - class Foo extends Component { - render(){ return
    ; } - } - const Bar = spy('Bar', () =>
    ); - - sinon.spy(Foo.prototype, 'render'); - - render(( -
    - - -
    - ), scratch); - - expect(Foo.prototype.render).to.have.been.calledWithMatch({ ref:sinon.match.falsy, a:'a' }, { }, { }); - expect(Bar).to.have.been.calledWithMatch({ b:'b', ref:bar }, { }); - }); - - // Test for #232 - it('should only null refs after unmount', () => { - let root, outer, inner; - - class TestUnmount extends Component { - componentWillUnmount() { - expect(this).to.have.property('outer', outer); - expect(this).to.have.property('inner', inner); - } - - componentDidUnmount() { - expect(this).to.have.property('outer', null); - expect(this).to.have.property('inner', null); - } - - render() { - return ( -
    this.outer=c }> -
    this.inner=c } /> -
    - ); - } - } - - sinon.spy(TestUnmount.prototype, 'componentWillUnmount'); - sinon.spy(TestUnmount.prototype, 'componentDidUnmount'); - - root = render(
    , scratch, root); - outer = scratch.querySelector('#outer'); - inner = scratch.querySelector('#inner'); - - expect(TestUnmount.prototype.componentWillUnmount).not.to.have.been.called; - expect(TestUnmount.prototype.componentDidUnmount).not.to.have.been.called; - - root = render(
    , scratch, root); - - expect(TestUnmount.prototype.componentWillUnmount).to.have.been.calledOnce; - expect(TestUnmount.prototype.componentDidUnmount).to.have.been.calledOnce; - }); - - it('should null and re-invoke refs when swapping component root element type', () => { - let inst; - - class App extends Component { - render() { - return
    ; - } - } - - class Child extends Component { - constructor(props, context) { - super(props, context); - this.state = { show:false }; - inst = this; - } - handleMount(){} - render(_, { show }) { - if (!show) return
    ; - return some test content; - } - } - sinon.spy(Child.prototype, 'handleMount'); - - render(, scratch); - expect(inst.handleMount).to.have.been.calledOnce.and.calledWith(scratch.querySelector('#div')); - inst.handleMount.reset(); - - inst.setState({ show:true }); - inst.forceUpdate(); - expect(inst.handleMount).to.have.been.calledTwice; - expect(inst.handleMount.firstCall).to.have.been.calledWith(null); - expect(inst.handleMount.secondCall).to.have.been.calledWith(scratch.querySelector('#span')); - inst.handleMount.reset(); - - inst.setState({ show:false }); - inst.forceUpdate(); - expect(inst.handleMount).to.have.been.calledTwice; - expect(inst.handleMount.firstCall).to.have.been.calledWith(null); - expect(inst.handleMount.secondCall).to.have.been.calledWith(scratch.querySelector('#div')); - }); - - - it('should add refs to components representing DOM nodes with no attributes if they have been pre-rendered', () => { - // Simulate pre-render - let parent = document.createElement('div'); - let child = document.createElement('div'); - parent.appendChild(child); - scratch.appendChild(parent); // scratch contains:
    - - let ref = spy('ref'); - - function Wrapper() { - return
    ; - } - - render(
    , scratch, scratch.firstChild); - expect(ref).to.have.been.calledOnce.and.calledWith(scratch.firstChild.firstChild); - }); -}); diff --git a/thirdparty/preact/test/browser/render.js b/thirdparty/preact/test/browser/render.js deleted file mode 100644 index 5d18fb282..000000000 --- a/thirdparty/preact/test/browser/render.js +++ /dev/null @@ -1,439 +0,0 @@ -/* global DISABLE_FLAKEY */ - -import { h, render } from '../../src/preact'; -/** @jsx h */ - -function getAttributes(node) { - let attrs = {}; - for (let i=node.attributes.length; i--; ) { - attrs[node.attributes[i].name] = node.attributes[i].value; - } - return attrs; -} - -// hacky normalization of attribute order across browsers. -function sortAttributes(html) { - return html.replace(/<([a-z0-9-]+)((?:\s[a-z0-9:_.-]+=".*?")+)((?:\s*\/)?>)/gi, (s, pre, attrs, after) => { - let list = attrs.match(/\s[a-z0-9:_.-]+=".*?"/gi).sort( (a, b) => a>b ? 1 : -1 ); - if (~after.indexOf('/')) after = '>'; - return '<' + pre + list.join('') + after; - }); -} - -describe('render()', () => { - let scratch; - - before( () => { - scratch = document.createElement('div'); - (document.body || document.documentElement).appendChild(scratch); - }); - - beforeEach( () => { - scratch.innerHTML = ''; - }); - - after( () => { - scratch.parentNode.removeChild(scratch); - scratch = null; - }); - - it('should create empty nodes (<* />)', () => { - render(
    , scratch); - expect(scratch.childNodes) - .to.have.length(1) - .and.to.have.deep.property('0.nodeName', 'DIV'); - - scratch.innerHTML = ''; - - render(, scratch); - expect(scratch.childNodes) - .to.have.length(1) - .and.to.have.deep.property('0.nodeName', 'SPAN'); - - scratch.innerHTML = ''; - - render(, scratch); - render(, scratch); - expect(scratch.childNodes).to.have.length(2); - expect(scratch.childNodes[0]).to.have.property('nodeName', 'FOO'); - expect(scratch.childNodes[1]).to.have.property('nodeName', 'X-BAR'); - }); - - it('should nest empty nodes', () => { - render(( -
    - - - -
    - ), scratch); - - expect(scratch.childNodes) - .to.have.length(1) - .and.to.have.deep.property('0.nodeName', 'DIV'); - - let c = scratch.childNodes[0].childNodes; - expect(c).to.have.length(3); - expect(c).to.have.deep.property('0.nodeName', 'SPAN'); - expect(c).to.have.deep.property('1.nodeName', 'FOO'); - expect(c).to.have.deep.property('2.nodeName', 'X-BAR'); - }); - - it('should not render falsey values', () => { - render(( -
    - {null},{undefined},{false},{0},{NaN} -
    - ), scratch); - - expect(scratch.firstChild).to.have.property('innerHTML', ',,,0,NaN'); - }); - - it('should clear falsey attributes', () => { - let root = render(( -
    - ), scratch); - - root = render(( -
    - ), scratch, root); - - expect(getAttributes(scratch.firstChild), 'from previous truthy values').to.eql({ - a0: '0', - anan: 'NaN' - }); - - scratch.innerHTML = ''; - - root = render(( -
    - ), scratch); - - expect(getAttributes(scratch.firstChild), 'initial render').to.eql({ - a0: '0', - anan: 'NaN' - }); - }); - - it('should clear falsey input values', () => { - let root = render(( -
    - - - - -
    - ), scratch); - - expect(root.children[0]).to.have.property('value', '0'); - expect(root.children[1]).to.have.property('value', 'false'); - expect(root.children[2]).to.have.property('value', ''); - expect(root.children[3]).to.have.property('value', ''); - }); - - it('should clear falsey DOM properties', () => { - let root; - function test(val) { - root = render(( -
    - - - - ), scratch, root); - } - - test('2'); - test(false); - expect(scratch).to.have.property('innerHTML', '
    ', 'for false'); - - test('3'); - test(null); - expect(scratch).to.have.property('innerHTML', '
    ', 'for null'); - - test('4'); - test(undefined); - expect(scratch).to.have.property('innerHTML', '
    ', 'for undefined'); - }); - - it('should apply string attributes', () => { - render(
    , scratch); - - let div = scratch.childNodes[0]; - expect(div).to.have.deep.property('attributes.length', 2); - - expect(div).to.have.deep.property('attributes[0].name', 'foo'); - expect(div).to.have.deep.property('attributes[0].value', 'bar'); - - expect(div).to.have.deep.property('attributes[1].name', 'data-foo'); - expect(div).to.have.deep.property('attributes[1].value', 'databar'); - }); - - it('should apply class as String', () => { - render(
    , scratch); - expect(scratch.childNodes[0]).to.have.property('className', 'foo'); - }); - - it('should alias className to class', () => { - render(
    , scratch); - expect(scratch.childNodes[0]).to.have.property('className', 'bar'); - }); - - it('should apply style as String', () => { - render(
    , scratch); - expect(scratch.childNodes[0]).to.have.deep.property('style.cssText') - .that.matches(/top\s*:\s*5px\s*/) - .and.matches(/position\s*:\s*relative\s*/); - }); - - it('should only register on* functions as handlers', () => { - let click = () => {}, - onclick = () => {}; - - let proto = document.createElement('div').constructor.prototype; - - sinon.spy(proto, 'addEventListener'); - - render(
    , scratch); - - expect(scratch.childNodes[0]).to.have.deep.property('attributes.length', 0); - - expect(proto.addEventListener).to.have.been.calledOnce - .and.to.have.been.calledWithExactly('click', sinon.match.func, false); - - proto.addEventListener.restore(); - }); - - it('should add and remove event handlers', () => { - let click = sinon.spy(), - mousedown = sinon.spy(); - - let proto = document.createElement('div').constructor.prototype; - sinon.spy(proto, 'addEventListener'); - sinon.spy(proto, 'removeEventListener'); - - function fireEvent(on, type) { - let e = document.createEvent('Event'); - e.initEvent(type, true, true); - on.dispatchEvent(e); - } - - render(
    click(1) } onMouseDown={ mousedown } />, scratch); - - expect(proto.addEventListener).to.have.been.calledTwice - .and.to.have.been.calledWith('click') - .and.calledWith('mousedown'); - - fireEvent(scratch.childNodes[0], 'click'); - expect(click).to.have.been.calledOnce - .and.calledWith(1); - - proto.addEventListener.reset(); - click.reset(); - - render(
    click(2) } />, scratch, scratch.firstChild); - - expect(proto.addEventListener).not.to.have.been.called; - - expect(proto.removeEventListener) - .to.have.been.calledOnce - .and.calledWith('mousedown'); - - fireEvent(scratch.childNodes[0], 'click'); - expect(click).to.have.been.calledOnce - .and.to.have.been.calledWith(2); - - fireEvent(scratch.childNodes[0], 'mousedown'); - expect(mousedown).not.to.have.been.called; - - proto.removeEventListener.reset(); - click.reset(); - mousedown.reset(); - - render(
    , scratch, scratch.firstChild); - - expect(proto.removeEventListener) - .to.have.been.calledOnce - .and.calledWith('click'); - - fireEvent(scratch.childNodes[0], 'click'); - expect(click).not.to.have.been.called; - - proto.addEventListener.restore(); - proto.removeEventListener.restore(); - }); - - it('should use capturing for events that do not bubble', () => { - let click = sinon.spy(), - focus = sinon.spy(); - - let root = render(( -
    -
    - ), scratch); - - root.firstElementChild.click(); - root.firstElementChild.focus(); - - expect(click, 'click').to.have.been.calledOnce; - - if (DISABLE_FLAKEY!==true) { - // Focus delegation requires a 50b hack I'm not sure we want to incur - expect(focus, 'focus').to.have.been.calledOnce; - - // IE doesn't set it - expect(click).to.have.been.calledWithMatch({ eventPhase: 0 }); // capturing - expect(focus).to.have.been.calledWithMatch({ eventPhase: 0 }); // capturing - } - }); - - it('should serialize style objects', () => { - let root = render(( -
    - test -
    - ), scratch); - - let { style } = scratch.childNodes[0]; - expect(style).to.have.property('color').that.equals('rgb(255, 255, 255)'); - expect(style).to.have.property('background').that.contains('rgb(255, 100, 0)'); - expect(style).to.have.property('backgroundPosition').that.equals('10px 10px'); - expect(style).to.have.property('backgroundSize', 'cover'); - expect(style).to.have.property('padding', '5px'); - expect(style).to.have.property('top', '100px'); - expect(style).to.have.property('left', '100%'); - - root = render(( -
    test
    - ), scratch, root); - - expect(root).to.have.deep.property('style.cssText').that.equals('color: rgb(0, 255, 255);'); - - root = render(( -
    test
    - ), scratch, root); - - expect(root).to.have.deep.property('style.cssText').that.equals('display: inline;'); - - root = render(( -
    test
    - ), scratch, root); - - expect(root).to.have.deep.property('style.cssText').that.equals('background-color: rgb(0, 255, 255);'); - }); - - it('should serialize class/className', () => { - render(
    , scratch); - - let { className } = scratch.childNodes[0]; - expect(className).to.be.a.string; - expect(className.split(' ')) - .to.include.members(['yes1', 'yes2', 'yes3', 'yes4', 'yes5']) - .and.not.include.members(['no1', 'no2', 'no3', 'no4', 'no5']); - }); - - it('should support dangerouslySetInnerHTML', () => { - let html = 'foo & bar'; - let root = render(
    , scratch); - - expect(scratch.firstChild).to.have.property('innerHTML', html); - expect(scratch.innerHTML).to.equal('
    '+html+'
    '); - - root = render(
    ab
    , scratch, root); - - expect(scratch).to.have.property('innerHTML', `
    ab
    `); - - root = render(
    , scratch, root); - - expect(scratch.innerHTML).to.equal('
    '+html+'
    '); - }); - - it('should reconcile mutated DOM attributes', () => { - let check = p => render(, scratch, scratch.lastChild), - value = () => scratch.lastChild.checked, - setValue = p => scratch.lastChild.checked = p; - check(true); - expect(value()).to.equal(true); - check(false); - expect(value()).to.equal(false); - check(true); - expect(value()).to.equal(true); - setValue(true); - check(false); - expect(value()).to.equal(false); - setValue(false); - check(true); - expect(value()).to.equal(true); - }); - - it('should ignore props.children if children are manually specified', () => { - expect( -
    c
    - ).to.eql( -
    c
    - ); - }); - - it('should reorder child pairs', () => { - let root = render(( -
    - a - b -
    - ), scratch, root); - - let a = scratch.firstChild.firstChild; - let b = scratch.firstChild.lastChild; - - expect(a).to.have.property('nodeName', 'A'); - expect(b).to.have.property('nodeName', 'B'); - - root = render(( -
    - b - a -
    - ), scratch, root); - - expect(scratch.firstChild.firstChild).to.have.property('nodeName', 'B'); - expect(scratch.firstChild.lastChild).to.have.property('nodeName', 'A'); - expect(scratch.firstChild.firstChild).to.equal(b); - expect(scratch.firstChild.lastChild).to.equal(a); - }); - - // Discussion: https://github.com/developit/preact/issues/287 - ('HTMLDataListElement' in window ? it : xit)('should allow to pass through as an attribute', () => { - render(( -
    - - - - - - -
    - ), scratch); - - let html = scratch.firstElementChild.firstElementChild.outerHTML; - expect(sortAttributes(html)).to.equal(sortAttributes('')); - }); -}); diff --git a/thirdparty/preact/test/browser/spec.js b/thirdparty/preact/test/browser/spec.js deleted file mode 100644 index d33cdb93f..000000000 --- a/thirdparty/preact/test/browser/spec.js +++ /dev/null @@ -1,127 +0,0 @@ -import { h, render, rerender, Component } from '../../src/preact'; -/** @jsx h */ - -const EMPTY_CHILDREN = []; - -describe('Component spec', () => { - let scratch; - - before( () => { - scratch = document.createElement('div'); - (document.body || document.documentElement).appendChild(scratch); - }); - - beforeEach( () => { - scratch.innerHTML = ''; - }); - - after( () => { - scratch.parentNode.removeChild(scratch); - scratch = null; - }); - - describe('defaultProps', () => { - it('should apply default props on initial render', () => { - class WithDefaultProps extends Component { - constructor(props, context) { - super(props, context); - expect(props).to.be.deep.equal({ - children: EMPTY_CHILDREN, - fieldA: 1, fieldB: 2, - fieldC: 1, fieldD: 2 - }); - } - render() { - return
    ; - } - } - WithDefaultProps.defaultProps = { fieldC: 1, fieldD: 1 }; - render(, scratch); - }); - - it('should apply default props on rerender', () => { - let doRender; - class Outer extends Component { - constructor() { - super(); - this.state = { i:1 }; - } - componentDidMount() { - doRender = () => this.setState({ i: 2 }); - } - render(props, { i }) { - return ; - } - } - class WithDefaultProps extends Component { - constructor(props, context) { - super(props, context); - this.ctor(props, context); - } - ctor(){} - componentWillReceiveProps() {} - render() { - return
    ; - } - } - WithDefaultProps.defaultProps = { fieldC: 1, fieldD: 1 }; - - let proto = WithDefaultProps.prototype; - sinon.spy(proto, 'ctor'); - sinon.spy(proto, 'componentWillReceiveProps'); - sinon.spy(proto, 'render'); - - render(, scratch); - doRender(); - - const PROPS1 = { - fieldA: 1, fieldB: 1, - fieldC: 1, fieldD: 1 - }; - - const PROPS2 = { - fieldA: 1, fieldB: 2, - fieldC: 1, fieldD: 2 - }; - - expect(proto.ctor).to.have.been.calledWithMatch(PROPS1); - expect(proto.render).to.have.been.calledWithMatch(PROPS1); - - rerender(); - - // expect(proto.ctor).to.have.been.calledWith(PROPS2); - expect(proto.componentWillReceiveProps).to.have.been.calledWithMatch(PROPS2); - expect(proto.render).to.have.been.calledWithMatch(PROPS2); - }); - - // @TODO: migrate this to preact-compat - xit('should cache default props', () => { - class WithDefaultProps extends Component { - constructor(props, context) { - super(props, context); - expect(props).to.be.deep.equal({ - fieldA: 1, fieldB: 2, - fieldC: 1, fieldD: 2, - fieldX: 10 - }); - } - getDefaultProps() { - return { fieldA: 1, fieldB: 1 }; - } - render() { - return
    ; - } - } - WithDefaultProps.defaultProps = { fieldC: 1, fieldD: 1 }; - sinon.spy(WithDefaultProps.prototype, 'getDefaultProps'); - render(( -
    - - - -
    - ), scratch); - expect(WithDefaultProps.prototype.getDefaultProps).to.be.calledOnce; - }); - }); -}); diff --git a/thirdparty/preact/test/browser/svg.js b/thirdparty/preact/test/browser/svg.js deleted file mode 100644 index 684f4dd96..000000000 --- a/thirdparty/preact/test/browser/svg.js +++ /dev/null @@ -1,112 +0,0 @@ -import { h, render } from '../../src/preact'; -/** @jsx h */ - - -// hacky normalization of attribute order across browsers. -function sortAttributes(html) { - return html.replace(/<([a-z0-9-]+)((?:\s[a-z0-9:_.-]+=".*?")+)((?:\s*\/)?>)/gi, (s, pre, attrs, after) => { - let list = attrs.match(/\s[a-z0-9:_.-]+=".*?"/gi).sort( (a, b) => a>b ? 1 : -1 ); - if (~after.indexOf('/')) after = '>'; - return '<' + pre + list.join('') + after; - }); -} - - -describe('svg', () => { - let scratch; - - before( () => { - scratch = document.createElement('div'); - (document.body || document.documentElement).appendChild(scratch); - }); - - beforeEach( () => { - scratch.innerHTML = ''; - }); - - after( () => { - scratch.parentNode.removeChild(scratch); - scratch = null; - }); - - it('should render SVG to string', () => { - render(( - - - - ), scratch); - - let html = sortAttributes(String(scratch.innerHTML).replace(' xmlns="http://www.w3.org/2000/svg"', '')); - expect(html).to.equal(sortAttributes(` - - - - `.replace(/[\n\t]+/g,''))); - }); - - it('should render SVG to DOM', () => { - const Demo = () => ( - - - - ); - render(, scratch); - - let html = sortAttributes(String(scratch.innerHTML).replace(' xmlns="http://www.w3.org/2000/svg"', '')); - expect(html).to.equal(sortAttributes('')); - }); - - it('should use attributes for className', () => { - const Demo = ({ c }) => ( - - - - ); - let root = render(, scratch, root); - sinon.spy(root, 'removeAttribute'); - root = render(, scratch, root); - expect(root.removeAttribute).to.have.been.calledOnce.and.calledWith('class'); - root.removeAttribute.restore(); - - root = render(
    , scratch, root); - root = render(, scratch, root); - sinon.spy(root, 'setAttribute'); - root = render(, scratch, root); - expect(root.setAttribute).to.have.been.calledOnce.and.calledWith('class', 'foo_2'); - root.setAttribute.restore(); - root = render(, scratch, root); - root = render(, scratch, root); - }); - - it('should still support class attribute', () => { - render(( - - ), scratch); - - expect(scratch.innerHTML).to.contain(` class="foo bar"`); - }); - - it('should serialize class', () => { - render(( - - ), scratch); - - expect(scratch.innerHTML).to.contain(` class="foo other"`); - }); - - it('should switch back to HTML for ', () => { - render(( - - - - test - - - - ), scratch); - - expect(scratch.getElementsByTagName('a')) - .to.have.property('0') - .that.is.a('HTMLAnchorElement'); - }); -}); -- cgit v1.2.3