diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 3a252026103..de9b683c1c4 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -2,7 +2,7 @@ "name": "instantsearch.js", "version": "1.4.1", "npm-shrinkwrap-version": "200.4.0", - "node-version": "v5.5.0", + "node-version": "v5.9.0", "dependencies": { "algoliasearch": { "version": "3.13.0", @@ -6372,6 +6372,100 @@ } } }, + "enzyme": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-2.2.0.tgz", + "dependencies": { + "is-subset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz" + }, + "lodash": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.6.1.tgz" + }, + "object.assign": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.3.tgz", + "dependencies": { + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "dependencies": { + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz" + } + } + }, + "function-bind": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz" + }, + "object-keys": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.9.tgz" + } + } + }, + "object.values": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.0.3.tgz", + "dependencies": { + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "dependencies": { + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz" + }, + "object-keys": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.9.tgz" + } + } + }, + "es-abstract": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.5.0.tgz", + "dependencies": { + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "dependencies": { + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz" + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz" + } + } + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz" + }, + "is-regex": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.3.tgz" + } + } + }, + "function-bind": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz" + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz" + } + } + } + } + }, "eslint": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/eslint/-/eslint-1.10.3.tgz", diff --git a/package.json b/package.json index 706efcfb412..37c24360a23 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "conventional-changelog": "^0.5.3", "dmd": "^1.3.8", "doctoc": "^1.0.0", + "enzyme": "2.2.0", "eslint": "^1.10.3", "eslint-config-airbnb": "^0.1.0", "eslint-config-algolia": "^4.5.0", diff --git a/scripts/karma.conf.babel.js b/scripts/karma.conf.babel.js index 5ad8dd36e28..d7c0e5f30ea 100644 --- a/scripts/karma.conf.babel.js +++ b/scripts/karma.conf.babel.js @@ -11,6 +11,15 @@ let baseConfig = { loaders: [{ test: /\.js$/, exclude: /node_modules/, loader: 'babel' }] + }, + // enzyme does not work well with webpack: + // https://github.com/airbnb/enzyme/issues/47#issuecomment-165430136 + externals: { + jsdom: 'window', + cheerio: 'window', + 'react/lib/ExecutionEnvironment': true, + 'react/lib/ReactContext': 'window', + 'text-encoding': 'window' } }, webpackMiddleware: {noInfo: true} diff --git a/src/components/RefinementList/__tests__/RefinementList-test.js b/src/components/RefinementList/__tests__/RefinementList-test.js index 46f76dbbae6..2179e04d5fd 100644 --- a/src/components/RefinementList/__tests__/RefinementList-test.js +++ b/src/components/RefinementList/__tests__/RefinementList-test.js @@ -1,8 +1,8 @@ /* eslint-env mocha */ import React from 'react'; +import {shallow} from 'enzyme'; import expect from 'expect'; -import TestUtils from 'react-addons-test-utils'; import RefinementList from '../RefinementList'; import RefinementListItem from '../RefinementListItem'; @@ -10,171 +10,318 @@ import expectJSX from 'expect-jsx'; expect.extend(expectJSX); describe('RefinementList', () => { - let renderer; - let parentListProps; - let itemProps; - - beforeEach(() => { - let {createRenderer} = TestUtils; - let cssClasses = { - list: 'list', - item: 'item', - active: 'active' - }; - let templateData = {cssClasses}; - let commonItemProps = { - handleClick: () => {}, - itemClassName: 'item', - subItems: undefined, - templateKey: 'item', - templateProps: {} + function shallowRender(extraProps: {}) { + let props = { + createURL: () => 'url', + facetValues: [], + ...extraProps }; + return shallow(React.createElement(RefinementList, props)); + } + + describe('cssClasses', () => { + it('should add the `list` class to the root element', () => { + // Given + let props = { + cssClasses: { + list: 'list' + } + }; + + // When + let actual = shallowRender(props); - parentListProps = {className: 'list'}; - itemProps = [{ - ...commonItemProps, - itemClassName: 'item active', - facetValueToRefine: 'facet1', - isRefined: true, - templateData: { - ...templateData, - name: 'facet1', - isRefined: true - } - }, { - ...commonItemProps, - facetValueToRefine: 'facet2', - isRefined: false, - templateData: { - ...templateData, - name: 'facet2', - isRefined: false - } - }]; - renderer = createRenderer(); + // Then + expect(actual.hasClass('list')).toEqual(true); + }); + + it('should set item classes to the refinements', () => { + // Given + let props = { + cssClasses: { + item: 'item' + }, + facetValues: [ + {name: 'foo', isRefined: true} + ] + }; + + // When + let actual = shallowRender(props).find(RefinementListItem); + + // Then + expect(actual.props().itemClassName).toContain('item'); + }); + + it('should set active classes to the active refinements', () => { + // Given + let props = { + cssClasses: { + active: 'active' + }, + facetValues: [ + {name: 'foo', isRefined: true}, + {name: 'bar', isRefined: false} + ] + }; + + // When + let activeItem = shallowRender(props).find({isRefined: true}); + let inactiveItem = shallowRender(props).find({isRefined: false}); + + // Then + expect(activeItem.props().itemClassName).toContain('active'); + expect(inactiveItem.props().itemClassName).toNotContain('active'); + }); }); + describe('items', () => { + it('should have the correct names', () => { + // Given + let props = { + facetValues: [ + {name: 'foo', isRefined: false}, + {name: 'bar', isRefined: false} + ] + }; + + // When + let items = shallowRender(props).find(RefinementListItem); + let firstItem = items.at(0); + let secondItem = items.at(1); + + // Then + expect(firstItem.props().facetValueToRefine).toEqual('foo'); + expect(secondItem.props().facetValueToRefine).toEqual('bar'); + }); + + it('should correctly set if refined or not', () => { + // Given + let props = { + facetValues: [ + {name: 'foo', isRefined: false}, + {name: 'bar', isRefined: true} + ] + }; + + // When + let items = shallowRender(props).find(RefinementListItem); + let firstItem = items.at(0); + let secondItem = items.at(1); - it('should render default list', () => { - let out = render(); - - expect(out).toEqualJSX( -