it ('overrides missing prefixed properties', () => { middleware.register ('foo:', (id, prop) => prop + '/' + id); expect (middleware.link ({'x': 1, 'foo:x': 'bar'}, 'i')).to.deep.equal ({'foo:x': 'bar/i'}); expect (middleware.link ({'x': 1, 'foo:x': 'bar'}, 'i', {'foo:x': 'foo'})).to.deep.equal ({'foo:x': 'foo/i'}); expect (middleware.link ({'x': 1, 'foo:x': 'bar'}, 'i', {'foo:y': 'foo'})) .to.deep.equal ({'foo:x': 'bar/i', 'foo:y': 'foo/i'}); });
it ('applies custom middleware logic to prefixed properties', () => { middleware.register ('foo:', (id, prop) => prop + '/' + id); expect (middleware.link ({'x': 1, 'foo:x': 'bar'}, 'i')).to.deep.equal ({'foo:x': 'bar/i'}); expect (middleware.link ({'x': 1, 'foo:x': 'bar'}, 'i', {x: 2})).to.deep.equal ({'foo:x': 'bar/i'}); expect (middleware.link ({'x': 1, 'foo:x': 'bar'}, 'i', {'foo:x': 'BAR'})).to.deep.equal ({'foo:x': 'BAR/i'}); expect (middleware.link ({'x': 1, 'foo:x': 'X', 'foo:y': 'Y'}, 'i', {'foo:x': 'BAR'})) .to.deep.equal ({'foo:x': 'BAR/i', 'foo:y': 'Y/i'}); });
it ('applies default middleware logic to prefixed properties', () => { middleware.register ('foo:'); expect (middleware.link ({'x': 1, 'foo:x': 'bar'}, 'i')).to.deep.equal ({'foo:x': 'bar'}); expect (middleware.link ({'x': 1, 'foo:x': 'bar'}, 'i', {x: 2})).to.deep.equal ({'foo:x': 'bar'}); expect (middleware.link ({'x': 1, 'foo:x': 'bar'}, 'i', {'foo:x': 'BAR'})).to.deep.equal ({'foo:x': 'BAR'}); expect (middleware.link ({'x': 1, 'foo:x': 'X', 'foo:y': 'Y'}, 'i', {'foo:x': 'BAR'})) .to.deep.equal ({'foo:x': 'BAR', 'foo:y': 'Y'}); });
render () { styleGetCounter = 0; expect (styleGetCounter).to.equal (0); const styles1 = this.getStyles ('style1'); expect (styleGetCounter).to.equal (expectedCounter); const styles2 = this.getStyles ('style1'); // no theme to style recompilation expect (styleGetCounter).to.equal (expectedCounter); expect (styles1 === styles2).to.be.false (); return <div></div>; }
it ('produces <input> element with value taken from state', () => { const store = Store.create (); const state = store.select ('root').set ('value', 'hello'); const theme = Theme.create ('default'); const html = ReactDOMServer.renderToStaticMarkup (<TextField state={state} theme={theme} />); expect (html).to.startWith ('<span'); expect (html).to.endWith ('/></span>'); expect (html).to.contain ('<input type="text"'); expect (html).to.contain (' value="hello"'); });
it ('injects styles based on theme, with kind=bar', () => { class _Test extends React.Component { render () { const {state} = this.props; expect (this.theme).to.exist (); expect (this.getStyles ('style1')).to.exist (); expect (this.getStyles ('style1')).to.have.property ('with'); expect (this.getStyles ('style1')).to.have.length (1); expect (this.getStyles ('style1')[0]).to.have.property ('x', 1); expect (this.getStyles ('style1')[0]).to.have.property ('font', 'Lato, sans-serif'); expect (this.getStyles ('style1')[0]).to.have.property ('y', 20); expect (this.getStyles ('style1')[0]).to.have.property ('z', 30); expect (this.getStyles ('style2')[0]).to.have.property ('x', 2); const styles = this.getStyles ('style1').with ('foo'); expect (styles).to.have.property ('with'); expect (styles).to.have.length (1); expect (styles[0]).to.have.property ('x', 2); expect (styles[0]).to.have.property ('font', 'Lato, sans-serif'); expect (styles[0]).to.have.property ('y', 2); expect (styles[0]).to.have.property ('z', 30); return <div style={styles}>{state.get ('text')}</div>; } } const Test = Electrum.wrap ('Test', _Test, {styles: {style1: _Test$styles1, style2: _Test$styles2}}); const html = ReactDOMServer.renderToStaticMarkup (<Test state={store.select ('x')} theme={theme} kind='bar'/>); const expectedHtml = '<div style="x:2px;font:Lato, sans-serif;y:2px;z:30px;" data-radium="true">Hello</div>'; expect (html).to.equal (expectedHtml); });
it ('produces expected HTML code', () => { const post = <Post state={store.select ('blog.post-1')} />; const html = ReactDOMServer.renderToStaticMarkup (post); expect (html).to.equal ( '<div data-radium="true">' + '<div id="text">Hello, world...</div>' + '<div data-radium="true"><img src="http://ima.ge/"/><span>John</span></div>' + '</div>'); });
it ('produces <input> element with id taken from props', () => { const store = Store.create (); const state = store.select ('root').set ('value', 'hello'); const theme = Theme.create ('default'); const html = ReactDOMServer.renderToStaticMarkup (<TextField state={state} theme={theme} id="foobar" />); expect (html).to.contain (' id="foobar"'); });
it ('re-renders only when store changes', () => { const mountNode = document.getElementById ('root'); let spy; Electrum.configureLog ('shouldComponentUpdate', (o, p, s, dirty) => { spy += `/${o.constructor.displayName}: ${dirty}`; }); spy = ''; log = ''; ReactDOM.render (<Post state={store.select ('blog.post-1')} />, mountNode); expect (log).to.equal ('/Post/Author'); expect (spy).to.equal (''); spy = ''; log = ''; ReactDOM.render (<Post state={store.select ('blog.post-1')} />, mountNode); expect (log).to.equal (''); expect (spy).to.equal ('/Post: false'); // Mutate the store; this will re-render <Content>, but not <Author> store.select ('blog.post-1.content').set ('text', 'Bye'); spy = ''; log = ''; ReactDOM.render (<Post state={store.select ('blog.post-1')} />, mountNode); expect (log).to.equal ('/Post'); expect (spy).to.equal ('/Post: true/Content: true/Author: false'); Electrum.configureLog ('shouldComponentUpdate'); });
it ('accepts working with no wrapper', () => { expect (() => new Electrum ({})).to.not.throw (Error); });
it ('uses arguments in correct order', () => { var a = {wrap: c => c}; var b = {wrap: c => c}; var e = new Electrum (a, b); expect (e.connectors).to.deep.equal ([b, a]); });
it ('does nothing for an unregistered middleware', () => { expect (middleware.unregister ('foo')).to.be.undefined (); expect (middleware.list ()).to.deep.equal ([]); });
it ('unregisters a registered middleware', () => { const m = {}; middleware.register ('foo', m); expect (middleware.unregister ('foo')).to.equal (m); expect (middleware.list ()).to.deep.equal ([]); });
it ('throws if a middleware is registered twice', () => { middleware.register ('foo'); expect (() => middleware.register ('foo')).to.throw (Error); });
render () { const {state} = this.props; expect (this.theme).to.exist (); expect (this.getStyles ('style1')).to.exist (); expect (this.getStyles ('style1')).to.have.property ('with'); expect (this.getStyles ('style1')).to.have.length (1); expect (this.getStyles ('style1')[0]).to.have.property ('x', 1); expect (this.getStyles ('style1')[0]).to.have.property ('font', 'Lato, sans-serif'); expect (this.getStyles ('style2')[0]).to.have.property ('x', 2); expect (this.mergeStyles ('style1')).to.deep.equal ({}); expect (this.mergeStyles ('style1', 'foo')).to.deep.equal ({x: 2, y: 2}); expect (this.mergeStyles ('style1', 'foo', 'bar')).to.deep.equal ({x: 2, y: 40, z: 30}); const styles = this.getStyles ('style1').with ('foo'); expect (styles).to.have.property ('with'); expect (styles).to.have.length (1); expect (styles[0]).to.have.property ('x', 2); expect (styles[0]).to.have.property ('font', 'Lato, sans-serif'); expect (styles[0]).to.have.property ('y', 2); return <div style={styles}>{state.get ('text')}</div>; }
it ('overrides missing properties', () => { middleware.register ('foo', (id, prop) => prop + '/' + id); expect (middleware.link ({x: 1, foo: 'bar'}, 'i')).to.deep.equal ({foo: 'bar/i'}); expect (middleware.link ({x: 1, foo: 'bar'}, 'i', {foo: 'foo'})).to.deep.equal ({foo: 'foo/i'}); expect (middleware.link ({x: 1, bar: 'bar'}, 'i', {foo: 'foo'})).to.deep.equal ({foo: 'foo/i'}); });
render () { const {state} = this.props; expect (this.theme).to.exist (); expect (this.getStyles ('style1')).to.exist (); expect (this.getStyles ('style1')).to.have.property ('with'); expect (this.getStyles ('style1')).to.have.length (1); expect (this.getStyles ('style1')[0]).to.have.property ('x', 1); expect (this.getStyles ('style1')[0]).to.have.property ('font', 'Lato, sans-serif'); expect (this.getStyles ('style1')[0]).to.have.property ('y', 20); expect (this.getStyles ('style1')[0]).to.have.property ('z', 30); expect (this.getStyles ('style2')[0]).to.have.property ('x', 2); const styles = this.getStyles ('style1').with ('foo'); expect (styles).to.have.property ('with'); expect (styles).to.have.length (1); expect (styles[0]).to.have.property ('x', 2); expect (styles[0]).to.have.property ('font', 'Lato, sans-serif'); expect (styles[0]).to.have.property ('y', 2); expect (styles[0]).to.have.property ('z', 30); return <div style={styles}>{state.get ('text')}</div>; }
it ('applies custom middleware logic to properties', () => { middleware.register ('foo', (id, prop) => prop + '/' + id); expect (middleware.link ({x: 1, foo: 'bar'}, 'i')).to.deep.equal ({foo: 'bar/i'}); expect (middleware.link ({x: 1, foo: 'bar'}, 'i', {x: 2})).to.deep.equal ({foo: 'bar/i'}); expect (middleware.link ({x: 1, foo: 'bar'}, 'i', {foo: 'BAR'})).to.deep.equal ({foo: 'BAR/i'}); });
it ('applies default middleware logic to properties', () => { middleware.register ('foo'); expect (middleware.link ({x: 1, foo: 'bar'}, 'i')).to.deep.equal ({foo: 'bar'}); expect (middleware.link ({x: 1, foo: 'bar'}, 'i', {x: 2})).to.deep.equal ({foo: 'bar'}); expect (middleware.link ({x: 1, foo: 'bar'}, 'i', {foo: 'BAR'})).to.deep.equal ({foo: 'BAR'}); });
it ('throws if wrap is not the expected wrapper function', () => { expect (() => new Electrum ({wrap: () => null})).to.throw (Error); expect (() => new Electrum ({wrap: (a, b) => a || b})).to.throw (Error); });
it ('produces empty instance', () => { const e = new Electrum (); expect (e.connectors).to.deep.equal ([]); expect (e.bus).to.exist (); });
it ('removes property when overrides specify an undefined value', () => { middleware.register ('foo', (id, prop) => prop + '/' + id); expect (middleware.link ({x: 1, foo: 'bar'}, 'i')).to.deep.equal ({foo: 'bar/i'}); expect (middleware.link ({x: 1, foo: 'bar'}, 'i', {foo: undefined})).to.deep.equal ({}); });
it ('registers a named middleware', () => { middleware.register ('foo'); expect (middleware.list ()).to.deep.equal ([ 'foo' ]); });
it ('produces named components', () => { expect (Content.displayName).to.equal ('Content'); expect (Author.displayName).to.equal ('Author'); expect (Post.displayName).to.equal ('Post'); });