diff options
Diffstat (limited to 'preact/test/shared')
-rw-r--r-- | preact/test/shared/createContext.test.js | 24 | ||||
-rw-r--r-- | preact/test/shared/createElement.test.js | 299 | ||||
-rw-r--r-- | preact/test/shared/exports.test.js | 32 | ||||
-rw-r--r-- | preact/test/shared/isValidElement.test.js | 5 | ||||
-rw-r--r-- | preact/test/shared/isValidElementTests.js | 37 |
5 files changed, 397 insertions, 0 deletions
diff --git a/preact/test/shared/createContext.test.js b/preact/test/shared/createContext.test.js new file mode 100644 index 0000000..1c64c3c --- /dev/null +++ b/preact/test/shared/createContext.test.js @@ -0,0 +1,24 @@ +import { createElement, createContext } from '../../'; +import { expect } from 'chai'; + +/** @jsx createElement */ +/* eslint-env browser, mocha */ + +describe('createContext', () => { + it('should return a Provider and a Consumer', () => { + const context = createContext(); + expect(context).to.have.property('Provider'); + expect(context).to.have.property('Consumer'); + }); + + it('should return a valid Provider Component', () => { + const { Provider } = createContext(); + const contextValue = { value: 'test' }; + const children = [<div>child1</div>, <div>child2</div>]; + + const providerComponent = <Provider {...contextValue}>{children}</Provider>; + //expect(providerComponent).to.have.property('tag', 'Provider'); + expect(providerComponent.props.value).to.equal(contextValue.value); + expect(providerComponent.props.children).to.equal(children); + }); +}); diff --git a/preact/test/shared/createElement.test.js b/preact/test/shared/createElement.test.js new file mode 100644 index 0000000..a7231b6 --- /dev/null +++ b/preact/test/shared/createElement.test.js @@ -0,0 +1,299 @@ +import { createElement } from '../../'; +import { expect } from 'chai'; + +const h = createElement; +/** @jsx createElement */ +/*eslint-env browser, mocha */ + +// const buildVNode = (nodeName, attributes, children=[]) => ({ +// nodeName, +// children, +// attributes, +// key: attributes && attributes.key +// }); + +describe('createElement(jsx)', () => { + it('should return a VNode', () => { + let r; + expect(() => (r = h('foo'))).not.to.throw(); + expect(r).to.be.an('object'); + // expect(r).to.be.an.instanceof(VNode); + expect(r).to.have.property('type', 'foo'); + expect(r) + .to.have.property('props') + .that.eql({}); + // expect(r).to.have.deep.property('props.children').that.eql(null); + }); + + it('should set VNode#type property', () => { + expect(<div />).to.have.property('type', 'div'); + function Test() { + return <div />; + } + expect(<Test />).to.have.property('type', Test); + }); + + it('should set VNode.constructor property to prevent json injection', () => { + const vnode = <span />; + expect(vnode.constructor).to.equal(undefined); + }); + + it('should set VNode#props property', () => { + const props = {}; + expect(h('div', props).props).to.deep.equal(props); + }); + + it('should set VNode#key property', () => { + expect(<div />).to.have.property('key').that.does.not.exist; + expect(<div a="a" />).to.have.property('key').that.does.not.exist; + expect(<div key="1" />).to.have.property('key', '1'); + }); + + it('should not set VNode#props.key property', () => { + expect(<div />).to.not.have.nested.property('props.key'); + expect(<div key="1" />).to.not.have.nested.property('props.key'); + expect(<div key={0} />).to.not.have.nested.property('props.key'); + expect(<div key={''} />).to.not.have.nested.property('props.key'); + }); + + it('should set VNode#ref property', () => { + expect(<div />).to.have.property('ref').that.does.not.exist; + expect(<div a="a" />).to.have.property('ref').that.does.not.exist; + const emptyFunction = () => {}; + expect(<div ref={emptyFunction} />).to.have.property('ref', emptyFunction); + }); + + it('should not set VNode#props.ref property', () => { + expect(<div />).to.not.have.nested.property('props.ref'); + expect(<div ref={() => {}} />).to.not.have.nested.property('props.ref'); + }); + + it('should have ordered VNode properties', () => { + expect(Object.keys(<div />).filter(key => !/^_/.test(key))).to.deep.equal([ + 'type', + 'props', + 'key', + 'ref', + 'constructor' + ]); + }); + + it('should preserve raw props', () => { + let props = { foo: 'bar', baz: 10, func: () => {} }, + r = h('foo', props); + expect(r) + .to.be.an('object') + .with.property('props') + .that.deep.equals(props); + }); + + it('should support element children', () => { + let kid1 = h('bar'); + let kid2 = h('baz'); + let r = h('foo', null, kid1, kid2); + + expect(r) + .to.be.an('object') + .with.nested.deep.property('props.children', [kid1, kid2]); + }); + + it('should support multiple element children, given as arg list', () => { + let kid1 = h('bar'); + let kid3 = h('test'); + let kid2 = h('baz', null, kid3); + + let r = h('foo', null, kid1, kid2); + + expect(r) + .to.be.an('object') + .with.nested.deep.property('props.children', [kid1, kid2]); + }); + + it('should handle multiple element children, given as an array', () => { + let kid1 = h('bar'); + let kid3 = h('test'); + let kid2 = h('baz', null, kid3); + + let r = h('foo', null, [kid1, kid2]); + + expect(r) + .to.be.an('object') + .with.nested.deep.property('props.children', [kid1, kid2]); + }); + + it('should support nested children', () => { + const m = x => { + const result = h(x); + delete result._original; + return result; + }; + expect(h('foo', null, m('a'), [m('b'), m('c')], m('d'))) + .to.have.nested.property('props.children') + .that.eql([m('a'), [m('b'), m('c')], m('d')]); + + expect(h('foo', null, [m('a'), [m('b'), m('c')], m('d')])) + .to.have.nested.property('props.children') + .that.eql([m('a'), [m('b'), m('c')], m('d')]); + + expect(h('foo', { children: [m('a'), [m('b'), m('c')], m('d')] })) + .to.have.nested.property('props.children') + .that.eql([m('a'), [m('b'), m('c')], m('d')]); + + expect(h('foo', { children: [[m('a'), [m('b'), m('c')], m('d')]] })) + .to.have.nested.property('props.children') + .that.eql([[m('a'), [m('b'), m('c')], m('d')]]); + + expect(h('foo', { children: m('a') })) + .to.have.nested.property('props.children') + .that.eql(m('a')); + + expect(h('foo', { children: 'a' })) + .to.have.nested.property('props.children') + .that.eql('a'); + }); + + it('should support text children', () => { + let r = h('foo', null, 'textstuff'); + + expect(r) + .to.be.an('object') + .with.nested.property('props.children') + .that.equals('textstuff'); + }); + + it('should override children if null is provided as an argument', () => { + let r = h('foo', { foo: 'bar', children: 'baz' }, null); + + expect(r) + .to.be.an('object') + .to.deep.nested.include({ + 'props.foo': 'bar', + 'props.children': null + }); + }); + + it('should NOT set children prop when unspecified', () => { + let r = h('foo', { foo: 'bar' }); + + expect(r) + .to.be.an('object') + .to.have.nested.property('props.foo') + .not.to.have.nested.property('props.children'); + }); + + it('should NOT merge adjacent text children', () => { + const bar = h('bar'); + const barClone = h('bar'); + const baz = h('baz'); + const bazClone = h('baz'); + const baz2 = h('baz'); + const baz2Clone = h('baz'); + + delete bar._original; + delete barClone._original; + delete baz._original; + delete bazClone._original; + delete baz2._original; + delete baz2Clone._original; + + let r = h( + 'foo', + null, + 'one', + 'two', + bar, + 'three', + baz, + baz2, + 'four', + null, + 'five', + 'six' + ); + + expect(r) + .to.be.an('object') + .with.nested.property('props.children') + .that.deep.equals([ + 'one', + 'two', + barClone, + 'three', + bazClone, + baz2Clone, + 'four', + null, + 'five', + 'six' + ]); + }); + + it('should not merge nested adjacent text children', () => { + let r = h( + 'foo', + null, + 'one', + ['two', null, 'three'], + null, + ['four', null, 'five', null], + 'six', + null + ); + + expect(r) + .to.be.an('object') + .with.nested.property('props.children') + .that.deep.equals([ + 'one', + ['two', null, 'three'], + null, + ['four', null, 'five', null], + 'six', + null + ]); + }); + + it('should not merge children that are boolean values', () => { + let r = h('foo', null, 'one', true, 'two', false, 'three'); + + expect(r) + .to.be.an('object') + .with.nested.property('props.children') + .that.deep.equals(['one', true, 'two', false, 'three']); + }); + + it('should not merge children of components', () => { + let Component = ({ children }) => children; + let r = h(Component, null, 'x', 'y'); + + expect(r) + .to.be.an('object') + .with.nested.property('props.children') + .that.deep.equals(['x', 'y']); + }); + + it('should respect defaultProps', () => { + const Component = ({ children }) => children; + Component.defaultProps = { foo: 'bar' }; + expect(h(Component).props).to.deep.equal({ foo: 'bar' }); + }); + + it('should override defaultProps', () => { + const Component = ({ children }) => children; + Component.defaultProps = { foo: 'default' }; + expect(h(Component, { foo: 'bar' }).props).to.deep.equal({ foo: 'bar' }); + }); + + it('should ignore props.children if children are manually specified', () => { + const element = ( + <div a children={['a', 'b']}> + c + </div> + ); + const childrenless = <div a>c</div>; + delete element._original; + delete childrenless._original; + + expect(element).to.eql(childrenless); + }); +}); diff --git a/preact/test/shared/exports.test.js b/preact/test/shared/exports.test.js new file mode 100644 index 0000000..b075af5 --- /dev/null +++ b/preact/test/shared/exports.test.js @@ -0,0 +1,32 @@ +import { + createElement, + h, + createContext, + Component, + Fragment, + render, + hydrate, + cloneElement, + options, + createRef, + toChildArray, + isValidElement +} from '../../'; +import { expect } from 'chai'; + +describe('preact', () => { + it('should be available as named exports', () => { + expect(h).to.be.a('function'); + expect(createElement).to.be.a('function'); + expect(Component).to.be.a('function'); + expect(Fragment).to.exist; + expect(render).to.be.a('function'); + expect(hydrate).to.be.a('function'); + expect(cloneElement).to.be.a('function'); + expect(createContext).to.be.a('function'); + expect(options).to.exist.and.be.an('object'); + expect(createRef).to.be.a('function'); + expect(isValidElement).to.be.a('function'); + expect(toChildArray).to.be.a('function'); + }); +}); diff --git a/preact/test/shared/isValidElement.test.js b/preact/test/shared/isValidElement.test.js new file mode 100644 index 0000000..66c49b6 --- /dev/null +++ b/preact/test/shared/isValidElement.test.js @@ -0,0 +1,5 @@ +import { createElement, isValidElement, Component } from '../../'; +import { expect } from 'chai'; +import { isValidElementTests } from './isValidElementTests'; + +isValidElementTests(expect, isValidElement, createElement, Component); diff --git a/preact/test/shared/isValidElementTests.js b/preact/test/shared/isValidElementTests.js new file mode 100644 index 0000000..d0e86b5 --- /dev/null +++ b/preact/test/shared/isValidElementTests.js @@ -0,0 +1,37 @@ +/** @jsx createElement */ + +export function isValidElementTests( + expect, + isValidElement, + createElement, + Component +) { + describe('isValidElement', () => { + it('should check if the argument is a valid vnode', () => { + // Failure cases + expect(isValidElement(123)).to.equal(false); + expect(isValidElement(0)).to.equal(false); + expect(isValidElement('')).to.equal(false); + expect(isValidElement('abc')).to.equal(false); + expect(isValidElement(null)).to.equal(false); + expect(isValidElement(undefined)).to.equal(false); + expect(isValidElement(true)).to.equal(false); + expect(isValidElement(false)).to.equal(false); + expect(isValidElement([])).to.equal(false); + expect(isValidElement([123])).to.equal(false); + expect(isValidElement([null])).to.equal(false); + + // Success cases + expect(isValidElement(<div />)).to.equal(true); + + const Foo = () => 123; + expect(isValidElement(<Foo />)).to.equal(true); + class Bar extends Component { + render() { + return <div />; + } + } + expect(isValidElement(<Bar />)).to.equal(true); + }); + }); +} |