UNPKG

treehouse-react

Version:

Binding for using treehouse in React applications

147 lines (116 loc) 3.68 kB
const JSDOM = require("jsdom").JSDOM; const App = require('treehouse/lib/App') const React = require('react') const ReactDOM = require('react-dom') const wrap = require('../lib').wrap describe("Component", () => { const html = id => global.document.getElementById(id).innerHTML const render = (component) => { let element = global.window.document.getElementById('test') return ReactDOM.render(component, element) } let app beforeEach(() => { global.window = (new JSDOM('<!doctype html><html><body><div id="test"></div></body></html>')).window global.document = global.window.document app = new App() }) describe("rendering", () => { let Widget, widgetRenderCount, WrappedWidget beforeEach(() => { widgetRenderCount = 0 Widget = wrap( ({theFruit}) => { widgetRenderCount++ return <div id="widget">{theFruit}</div> }, app.pick(t => { return { theFruit: t.at(['fruit']) } }) ) }) it("renders from the tree", () => { app.trunk().set({fruit: 'orange', animal: 'sheep'}) app.commit() render(<Widget />) expect(html('widget')).toEqual('orange') }) describe("using props", () => { beforeEach(() => { Widget = wrap( ({a, b, c}) => (<div id="alphabet">{[a,b,c].join(',')}</div>), app.pick(t => { return { a: t.at('a'), b: t.at('b') } }) ) }) it("merges props, giving priority to passed in ones", () => { app.trunk().set({a: 'AYE', b: 'BEE'}) render(<Widget b="beta" c="gamma" />) expect(html('alphabet')).toEqual('AYE,beta,gamma') }) }) describe("updating", () => { beforeEach(() => { app.trunk().set({fruit: 'orange', animal: 'sheep'}) app.commit() render(<Widget/>) widgetRenderCount = 0 }) it("updates when the relevant branch has been touched", () => { app.at(['fruit']).set('apple') app.commit() expect(html('widget')).toEqual('apple') expect(widgetRenderCount).toEqual(1) }) it("doesn't update when the relevant branch hasn't been touched", () => { app.at(['animal']).set('sloth') app.commit() expect(html('widget')).toEqual('orange') expect(widgetRenderCount).toEqual(0) }) it("doesn't call render if the state from tree is the same", () => { spyOn(app, 'log') // Suppress log warning app.at(['fruit']).set('orange') app.commit() expect(html('widget')).toEqual('orange') expect(widgetRenderCount).toEqual(0) }) }) describe("parent-child relationships", () => { let Container, containerRenderCount beforeEach(() => { Container = wrap( () => { containerRenderCount++ return <div id="container"><Widget/></div> }, app.pick(t => { return { fruit: t.at(['fruit']) } }) ) app.trunk().set({fruit: 'orange'}) app.commit() render(<Container/>) containerRenderCount = 0 widgetRenderCount = 0 }) it("only updates once even though its parent wants to update it as well as itself", () => { app.at(['fruit']).set('apple') app.commit() expect(html('container')).toEqual('<div id="widget">apple</div>') expect(containerRenderCount).toEqual(1) expect(widgetRenderCount).toEqual(1) }) }) }) })