From e706d48066a96b8085630bf823aaa6e518ce568f Mon Sep 17 00:00:00 2001 From: echenley Date: Mon, 23 Nov 2015 18:03:21 -0600 Subject: [PATCH] reorganize tests, use chrome until phantomjs works --- package.json | 52 +++++----- src/js/components/LoginLinks.jsx | 16 ++-- src/js/components/Modal.jsx | 9 +- src/js/components/__tests__/Login-test.jsx | 81 ++++++++++++++++ .../components/__tests__/LoginLinks-test.jsx | 25 +++++ src/js/components/__tests__/Modal-test.jsx | 86 +++++++++++++++++ .../components/__tests__/ProfileLink-test.jsx | 31 ++++++ src/js/components/__tests__/Register-test.jsx | 81 ++++++++++++++++ .../util/__tests__/abbreviateNumber-test.js | 31 +++--- src/js/util/__tests__/hostNameFromUrl-test.js | 10 +- src/js/util/__tests__/pluralize-test.js | 14 ++- test/components/Login-test.jsx | 78 --------------- test/components/LoginLinks-test.jsx | 36 ------- test/components/Modal-test.jsx | 94 ------------------- test/components/ProfileLink-test.jsx | 33 ------- test/components/Register-test.jsx | 77 --------------- test/karma.conf.js | 16 ++-- test/test.bundle.js | 6 +- test/util/clearCache.js | 8 -- 19 files changed, 384 insertions(+), 400 deletions(-) create mode 100644 src/js/components/__tests__/Login-test.jsx create mode 100644 src/js/components/__tests__/LoginLinks-test.jsx create mode 100644 src/js/components/__tests__/Modal-test.jsx create mode 100644 src/js/components/__tests__/ProfileLink-test.jsx create mode 100644 src/js/components/__tests__/Register-test.jsx delete mode 100644 test/components/Login-test.jsx delete mode 100644 test/components/LoginLinks-test.jsx delete mode 100644 test/components/Modal-test.jsx delete mode 100644 test/components/ProfileLink-test.jsx delete mode 100644 test/components/Register-test.jsx delete mode 100644 test/util/clearCache.js diff --git a/package.json b/package.json index 30f1064..5d6cc5a 100644 --- a/package.json +++ b/package.json @@ -1,38 +1,34 @@ { "name": "react-news", "version": "0.1.0", + "license": "MIT", "repository": { "type": "git", "url": "https://github.com/echenley/react-news.git" }, - "dependencies": { - "babel-preset-es2015": "^6.1.2", - "babel-preset-react": "^6.1.2", - "babel-preset-stage-2": "^6.1.2", - "babel-runtime": "^6.0.14", - "classnames": "^2.2.0", - "firebase": "^2.3.1", - "md5": "^2.0.0", - "moment": "^2.10.6", - "react": "^0.14.2", - "react-addons-update": "^0.14.2", - "react-dom": "^0.14.2", - "react-router": "1.0.0-rc4", - "reflux": "^0.3.0" - }, "devDependencies": { "autoprefixer": "^6.1.0", - "babel": "^6.0.15", + "babel-core": "^6.1.2", "babel-eslint": "^4.1.4", "babel-loader": "^6.0.1", "babel-plugin-transform-runtime": "^6.1.18", + "babel-polyfill": "^6.2.0", + "babel-preset-es2015": "^6.1.2", + "babel-preset-react": "^6.1.2", + "babel-preset-stage-2": "^6.1.2", + "babel-runtime": "^6.2.0", "chai": "^3.4.0", - "css-loader": "^0.22.0", + "chai-equal-jsx": "^1.0.8", + "classnames": "^2.2.0", + "css-loader": "^0.23.0", "eslint": "^1.8.0", "eslint-friendly-formatter": "^1.2.2", "eslint-loader": "^1.1.1", "eslint-plugin-react": "^3.7.1", - "history": "^1.13.1", + "expect": "^1.12.2", + "expect-jsx": "^2.1.0", + "firebase": "^2.3.1", + "history": "^1.13.0", "html-webpack-plugin": "^1.6.2", "istanbul-instrumenter-loader": "^0.1.3", "jsdom": "^7.0.2", @@ -48,31 +44,37 @@ "karma-sinon-chai": "^1.1.0", "karma-sourcemap-loader": "^0.3.6", "karma-webpack": "^1.7.0", - "lodash": "^3.10.1", + "md5": "^2.0.0", "mocha": "^2.3.3", - "node-sass": "^3.4.2", + "moment": "^2.10.6", + "node-sass": "^3.4.1", "null-loader": "^0.1.1", "phantomjs": "^1.9.18", - "postcss-loader": "^0.7.0", + "postcss-loader": "^0.8.0", + "react": "^0.14.2", "react-addons-test-utils": "^0.14.2", + "react-addons-update": "^0.14.2", + "react-dom": "^0.14.2", "react-hot-loader": "^1.3.0", + "react-router": "^1.0.0-rc3", + "reflux": "^0.3.0", "sass-loader": "^3.1.1", "sinon": "^1.17.2", "sinon-chai": "^2.8.0", "style-loader": "^0.13.0", - "svg-inline-loader": "^0.3.0", + "svg-inline-loader": "^0.4.0", "webpack": "^1.12.3", "webpack-dev-server": "^1.12.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=4.0.0" }, "scripts": { "start": "rm -rf build/* && node server.js", "build": "rm -rf build/* && ./node_modules/.bin/webpack", "dist": "rm -rf dist/* && ./node_modules/.bin/webpack -p --config webpack.production.config.js", "lint": "./node_modules/.bin/eslint src/", - "test": "./node_modules/.bin/karma start ./test/karma.conf.js", - "test-dev": "./node_modules/.bin/karma start ./test/karma.conf.js --no-single-run" + "test": "./node_modules/.bin/karma start ./test/karma.conf.js --reporters mocha,coverage", + "test:watch": "./node_modules/.bin/karma start ./test/karma.conf.js --no-single-run --reporters mocha" } } diff --git a/src/js/components/LoginLinks.jsx b/src/js/components/LoginLinks.jsx index 2f9b50f..7e62fab 100644 --- a/src/js/components/LoginLinks.jsx +++ b/src/js/components/LoginLinks.jsx @@ -3,15 +3,11 @@ import React from 'react'; import Actions from '../actions/Actions'; -const LoginLinks = React.createClass({ - render() { - return ( - - Actions.showModal('login') }>Sign In - Actions.showModal('register') } className="register-link">Register - - ); - } -}); +const LoginLinks = () => ( + + Actions.showModal('login') }>Sign In + Actions.showModal('register') } className="register-link">Register + +); export default LoginLinks; diff --git a/src/js/components/Modal.jsx b/src/js/components/Modal.jsx index b3a850e..0715406 100644 --- a/src/js/components/Modal.jsx +++ b/src/js/components/Modal.jsx @@ -6,13 +6,20 @@ import Icon from './Icon'; const Modal = React.createClass({ propTypes: { - hideModal: PropTypes.func, + hideModal: PropTypes.func.isRequired, children: PropTypes.oneOfType([ PropTypes.array, PropTypes.element ]).isRequired }, + getDefaultProps() { + return { + hideModal: () => {}, + children: null + }; + }, + componentDidMount() { // allow esc to close modal document.addEventListener('keyup', this.onKeyUp); diff --git a/src/js/components/__tests__/Login-test.jsx b/src/js/components/__tests__/Login-test.jsx new file mode 100644 index 0000000..ca53d92 --- /dev/null +++ b/src/js/components/__tests__/Login-test.jsx @@ -0,0 +1,81 @@ +'use strict'; + +import React from 'react'; +import { findDOMNode } from 'react-dom'; +import createParent from '../../../../test/util/createParent'; +import Login from '../Login'; + +import { + createRenderer, + renderIntoDocument, + findRenderedDOMComponentWithTag +} from 'react-addons-test-utils'; + +const userData = { + username: 'echenley', + md5hash: '7da6a19ef0b1a9b9794cf5c7cc7439f1' +}; + +const errorMessage = 'uh oh'; + +const renderer = createRenderer(); + +describe('', () => { + describe('DOM', () => { + it('should render correctly WITH errorMessage prop', () => { + // login with errorMessage prop + renderer.render(); + const actualElement = renderer.getRenderOutput(); + + const expectedErrorMessage = ( +
{ errorMessage }
+ ); + + expect(actualElement).to.includeJSX(expectedErrorMessage); + }); + + it('should render correctly WITHOUT errorMessage prop', () => { + // login without errorMessage prop + renderer.render(); + const actualElement = renderer.getRenderOutput(); + const actualErrorMessage = actualElement.props.children[2]; + + expect(actualErrorMessage).to.not.exist; + }); + }); + + describe('Behavior', () => { + let parent; + let login; + + beforeEach(() => { + let LoginParent = createParent(Login, 'login', { + errorMessage: '', + user: { isLoggedIn: false } + }); + + parent = renderIntoDocument(); + login = parent.refs.login; + }); + + it('should disable submit button until props update', () => { + let submitButton = findDOMNode(findRenderedDOMComponentWithTag(login, 'button')); + + login.setState({ submitted: true }); + expect(submitButton.disabled).to.equal(true); + + parent.setState({ errorMessage: 'invalid user' }); + + expect(login.state.submitted).to.equal(false); + expect(submitButton.disabled).to.equal(false); + }); + + it('should clear form when user prop updates', () => { + login.clearForm = sinon.spy(); + expect(login.clearForm).to.have.not.been.called; + + parent.setState({ user: { isLoggedIn: true } }); + expect(login.clearForm).to.have.been.called; + }); + }); +}); \ No newline at end of file diff --git a/src/js/components/__tests__/LoginLinks-test.jsx b/src/js/components/__tests__/LoginLinks-test.jsx new file mode 100644 index 0000000..ecf584f --- /dev/null +++ b/src/js/components/__tests__/LoginLinks-test.jsx @@ -0,0 +1,25 @@ +'use strict'; + +import React from 'react'; +import { createRenderer } from 'react-addons-test-utils'; + +import LoginLinks from '../LoginLinks'; + +describe('', () => { + describe('DOM', function() { + it('should render correctly', () => { + const renderer = createRenderer(); + renderer.render(); + const actualElement = renderer.getRenderOutput(); + + const expectedElement = ( + + {} }>Sign In + {} } className="register-link">Register + + ); + + expect(actualElement).to.equalJSX(expectedElement); + }); + }); +}); \ No newline at end of file diff --git a/src/js/components/__tests__/Modal-test.jsx b/src/js/components/__tests__/Modal-test.jsx new file mode 100644 index 0000000..1ff7928 --- /dev/null +++ b/src/js/components/__tests__/Modal-test.jsx @@ -0,0 +1,86 @@ +'use strict'; + +import React from 'react'; +import { findDOMNode } from 'react-dom'; +import createParent from '../../../../test/util/createParent'; +import Modal from '../Modal'; +import Icon from '../Icon'; + +import { + createRenderer, + renderIntoDocument, + findRenderedDOMComponentWithClass, + Simulate +} from 'react-addons-test-utils'; + + +describe('', () => { + describe('DOM', () => { + it('should render properly', () => { + const childJSX = ( +
hey
+ ); + + const shallowRenderer = createRenderer(); + shallowRenderer.render({ childJSX }); + const actualElement = shallowRenderer.getRenderOutput(); + + expect(actualElement).to.equalJSX(( +
{} }> + +
+ )); + }); + }); + + describe('Behavior', () => { + let parent; + let modal; + let hideModalSpy; + + beforeEach(() => { + hideModalSpy = sinon.spy(); + + let ModalParent = createParent(Modal, 'modal', { + hideModal: hideModalSpy, + children:
+ }); + + parent = renderIntoDocument(); + modal = parent.refs.modal; + }); + + it('should call props.hideModal when .modal-overlay is clicked', () => { + expect(hideModalSpy).to.have.not.been.called; + Simulate.click(findDOMNode(modal)); + expect(hideModalSpy).to.have.been.called; + }); + + it('should call props.hideModal when .modal-close is clicked', () => { + const modalClose = findRenderedDOMComponentWithClass(modal, 'modal-close'); + expect(hideModalSpy).to.have.not.been.called; + Simulate.click(findDOMNode(modalClose)); + expect(hideModalSpy).to.have.been.called; + }); + + // TODO: figure out how to test this + // it('should call props.hideModal when escape key is pressed', () => { + // expect(hideModalSpy).to.have.not.been.called; + // Simulate.keyPress(document, { keyCode: 27 }); + // expect(hideModalSpy).to.have.been.called; + // }); + + it('should not be removed when .modal-inner is clicked', () => { + const modalInner = findRenderedDOMComponentWithClass(modal, 'modal-inner'); + expect(hideModalSpy).to.have.not.been.called; + Simulate.click(findDOMNode(modalInner)); + expect(hideModalSpy).to.have.not.been.called; + }); + }); +}); \ No newline at end of file diff --git a/src/js/components/__tests__/ProfileLink-test.jsx b/src/js/components/__tests__/ProfileLink-test.jsx new file mode 100644 index 0000000..97dc819 --- /dev/null +++ b/src/js/components/__tests__/ProfileLink-test.jsx @@ -0,0 +1,31 @@ +'use strict'; + +import React from 'react'; +import { createRenderer } from 'react-addons-test-utils'; + +import { Link } from 'react-router'; +import ProfileLink from '../ProfileLink'; + +const userData = { + username: 'echenley', + md5hash: '7da6a19ef0b1a9b9794cf5c7cc7439f1' +}; + +const renderer = createRenderer(); +renderer.render(); +const actualElement = renderer.getRenderOutput(); + +const expectedElement = ( + + { userData.username } + + +); + +describe('', () => { + describe('DOM', function() { + it('should render correctly', () => { + expect(actualElement).to.equalJSX(expectedElement); + }); + }); +}); \ No newline at end of file diff --git a/src/js/components/__tests__/Register-test.jsx b/src/js/components/__tests__/Register-test.jsx new file mode 100644 index 0000000..a7d0dd0 --- /dev/null +++ b/src/js/components/__tests__/Register-test.jsx @@ -0,0 +1,81 @@ +'use strict'; + +import React from 'react'; +import { findDOMNode } from 'react-dom'; +import createParent from '../../../../test/util/createParent'; +import Register from '../Register'; + +import { + createRenderer, + renderIntoDocument, + findRenderedDOMComponentWithTag +} from 'react-addons-test-utils'; + +const userData = { + username: 'echenley', + md5hash: '7da6a19ef0b1a9b9794cf5c7cc7439f1' +}; + +const errorMessage = 'uh oh'; + +const renderer = createRenderer(); + +describe('', () => { + describe('DOM', () => { + it('should render correctly WITH errorMessage prop', () => { + // login with errorMessage prop + renderer.render(); + const actualElement = renderer.getRenderOutput(); + + const expectedErrorMessage = ( +
{ errorMessage }
+ ); + + expect(actualElement).to.includeJSX(expectedErrorMessage); + }); + + it('should render correctly WITHOUT errorMessage prop', () => { + // login without errorMessage prop + renderer.render(); + const actualElement = renderer.getRenderOutput(); + const actualErrorMessage = actualElement.props.children[2]; + + expect(actualErrorMessage).to.not.exist; + }); + }); + + describe('Behavior', () => { + let parent; + let register; + + beforeEach(() => { + let LoginParent = createParent(Register, 'register', { + errorMessage: '', + user: { isLoggedIn: false } + }); + + parent = renderIntoDocument(); + register = parent.refs.register; + }); + + it('should disable submit button until props update', () => { + let submitButton = findDOMNode(findRenderedDOMComponentWithTag(register, 'button')); + + register.setState({ submitted: true }); + expect(submitButton.disabled).to.equal(true); + + parent.setState({ errorMessage: 'invalid user' }); + + expect(register.state.submitted).to.equal(false); + expect(submitButton.disabled).to.equal(false); + }); + + it('should clear form when user prop updates', () => { + register.clearForm = sinon.spy(); + expect(register.clearForm).to.have.not.been.called; + + parent.setState({ user: { isLoggedIn: true } }); + expect(register.clearForm).to.have.been.called; + }); + }); +}); \ No newline at end of file diff --git a/src/js/util/__tests__/abbreviateNumber-test.js b/src/js/util/__tests__/abbreviateNumber-test.js index 87adbb3..e249bf1 100644 --- a/src/js/util/__tests__/abbreviateNumber-test.js +++ b/src/js/util/__tests__/abbreviateNumber-test.js @@ -1,24 +1,21 @@ 'use strict'; -jest.dontMock('../abbreviateNumber'); +import abbreviateNumber from '../abbreviateNumber'; -describe('abbreviateNumber', function() { - let abbreviateNumber = require('../abbreviateNumber'); - - it('always returns a string', function() { - expect(abbreviateNumber(1, 0)).toBe('1'); - expect(abbreviateNumber(999, 1)).toBe('999'); +describe('abbreviateNumber', () => { + it('always returns a string', () => { + expect(abbreviateNumber(1, 0)).to.equal('1'); + expect(abbreviateNumber(999, 1)).to.equal('999'); }); - it('abbreviates numbers correctly', function() { - expect(abbreviateNumber(0, 2)).toBe('0'); - expect(abbreviateNumber(12, 1)).toBe('12'); - expect(abbreviateNumber(1000, 1)).toBe('1k'); - expect(abbreviateNumber(1234, 0)).toBe('1k'); - expect(abbreviateNumber(34567, 2)).toBe('34.57k'); - expect(abbreviateNumber(918395, 1)).toBe('918.4k'); - expect(abbreviateNumber(2134124, 2)).toBe('2.13m'); - expect(abbreviateNumber(47475782130, 2)).toBe('47.48b'); - expect(abbreviateNumber(47475782130000, 2)).toBe('47.48t'); + it('abbreviates numbers correctly', () => { + expect(abbreviateNumber(0, 2)).to.equal('0'); + expect(abbreviateNumber(12, 1)).to.equal('12'); + expect(abbreviateNumber(1000, 1)).to.equal('1k'); + expect(abbreviateNumber(1234, 0)).to.equal('1k'); + expect(abbreviateNumber(34567, 2)).to.equal('34.57k'); + expect(abbreviateNumber(918395, 1)).to.equal('918.4k'); + expect(abbreviateNumber(2134124, 2)).to.equal('2.13m'); + expect(abbreviateNumber(47475782130, 2)).to.equal('47.48b'); }); }); diff --git a/src/js/util/__tests__/hostNameFromUrl-test.js b/src/js/util/__tests__/hostNameFromUrl-test.js index 6f99e58..882afe5 100644 --- a/src/js/util/__tests__/hostNameFromUrl-test.js +++ b/src/js/util/__tests__/hostNameFromUrl-test.js @@ -1,10 +1,8 @@ 'use strict'; -jest.dontMock('../hostNameFromUrl'); - -describe('hostNameFromUrl', function() { - let hostNameFromUrl = require('../hostNameFromUrl'); +import hostNameFromUrl from '../hostNameFromUrl'; +describe('hostNameFromUrl', () => { let urls = [ { url: 'https://www.youtube.com/watch?v=_OVg8uov78I', @@ -16,9 +14,9 @@ describe('hostNameFromUrl', function() { } ]; - it('returns hostname correctly', function() { + it('returns hostname correctly', () => { for (let { url, hostname } of urls) { - expect(hostNameFromUrl(url)).toBe(hostname); + expect(hostNameFromUrl(url)).to.equal(hostname); } }); }); diff --git a/src/js/util/__tests__/pluralize-test.js b/src/js/util/__tests__/pluralize-test.js index 10684c6..03a007c 100644 --- a/src/js/util/__tests__/pluralize-test.js +++ b/src/js/util/__tests__/pluralize-test.js @@ -1,13 +1,11 @@ 'use strict'; -jest.dontMock('../pluralize'); +import pluralize from '../pluralize'; -describe('hostNameFromUrl', function() { - let pluralize = require('../pluralize'); - - it('pluralize correctly', function() { - expect(pluralize(1, 'comment')).toBe('1 comment'); - expect(pluralize(21, 'comment')).toBe('21 comments'); - expect(pluralize(10, 'turkey')).toBe('10 turkeys'); +describe('pluralize', function() { + it('pluralizes correctly', function() { + expect(pluralize(1, 'comment')).to.equal('1 comment'); + expect(pluralize(21, 'comment')).to.equal('21 comments'); + expect(pluralize(10, 'turkey')).to.equal('10 turkeys'); }); }); diff --git a/test/components/Login-test.jsx b/test/components/Login-test.jsx deleted file mode 100644 index 34edf29..0000000 --- a/test/components/Login-test.jsx +++ /dev/null @@ -1,78 +0,0 @@ -'use strict'; - -import createParent from '../util/createParent'; -import { findDOMNode } from 'react-dom'; - -var React; -var Login; -var TestUtils; - -describe('Login Component', () => { - let login; - - beforeEach(() => { - React = require('react'); - Login = require('../../src/js/components/Login'); - TestUtils = require('react-addons-test-utils'); - }); - - describe('DOM', () => { - - beforeEach(() => { - login = TestUtils.renderIntoDocument(); - }); - - it('should render a div with className "login"', () => { - expect(findDOMNode(login).className).to.equal('login'); - }); - - it('should render an error message only when passed as prop', () => { - let error; - error = TestUtils.scryRenderedDOMComponentsWithClass(login, 'error'); - - expect(error.length).to.equal(0); - - // rerender with errorMessage prop - login = TestUtils.renderIntoDocument(); - error = TestUtils.findRenderedDOMComponentWithClass(login, 'error'); - - expect(findDOMNode(error).textContent).to.equal('uh oh'); - }); - }); - - describe('Props', () => { - let parent; - let login; - - beforeEach(() => { - let LoginParent = createParent(Login, 'login', { - errorMessage: '', - user: { isLoggedIn: false } - }); - - parent = TestUtils.renderIntoDocument(); - login = parent.refs.login; - }); - - it('should disable submit button until props update', () => { - let submitButton = findDOMNode(TestUtils.findRenderedDOMComponentWithTag(login, 'button')); - - login.setState({ submitted: true }); - expect(submitButton.disabled).to.equal(true); - - parent.setState({ errorMessage: 'invalid user' }); - - expect(login.state.submitted).to.equal(false); - expect(submitButton.disabled).to.equal(false); - }); - - it('should clear form when user prop updates', () => { - login.clearForm = sinon.spy(); - expect(login.clearForm).to.have.not.been.called; - - parent.setState({ user: { isLoggedIn: true } }); - expect(login.clearForm).to.have.been.called; - }); - - }); -}); \ No newline at end of file diff --git a/test/components/LoginLinks-test.jsx b/test/components/LoginLinks-test.jsx deleted file mode 100644 index bf70912..0000000 --- a/test/components/LoginLinks-test.jsx +++ /dev/null @@ -1,36 +0,0 @@ -'use strict'; - -import { findDOMNode } from 'react-dom'; - -var React; -var LoginLinks; -var TestUtils; - -describe('LoginLinks Component', () => { - let loginLinks; - - beforeEach(() => { - React = require('react'); - LoginLinks = require('../../src/js/components/LoginLinks'); - TestUtils = require('react-addons-test-utils'); - }); - - describe('DOM', function() { - beforeEach(() => { - loginLinks = TestUtils.renderIntoDocument(); - }); - - it('should render a span with className "login-links"', () => { - expect(findDOMNode(loginLinks).className).to.equal('login-links'); - }); - - it('should render "Sign In" and "Register" links', () => { - let links = TestUtils.scryRenderedDOMComponentsWithTag(loginLinks, 'a'); - let linkText = links.map((link) => findDOMNode(link).textContent); - - expect(links.length).to.equal(2); - expect(linkText[0]).to.equal('Sign In'); - expect(linkText[1]).to.equal('Register'); - }); - }); -}); \ No newline at end of file diff --git a/test/components/Modal-test.jsx b/test/components/Modal-test.jsx deleted file mode 100644 index 4377de9..0000000 --- a/test/components/Modal-test.jsx +++ /dev/null @@ -1,94 +0,0 @@ -'use strict'; - -import createParent from '../util/createParent'; -import { findDOMNode } from 'react-dom'; - -var React; -var Modal; -var TestUtils; - -describe('Modal Component', () => { - - beforeEach(() => { - React = require('react'); - Modal = require('../../src/js/components/Modal'); - TestUtils = require('react-addons-test-utils'); - }); - - describe('DOM', () => { - let modal; - let modalChild; - - beforeEach(() => { - modalChild =
; - const shallowRenderer = TestUtils.createRenderer(); - shallowRenderer.render({ modalChild }); - modal = shallowRenderer.getRenderOutput(); - }); - - it('should render
', () => { - expect(modal.props.className).to.equal('modal-overlay'); - }); - - it('should render a child ', () => { - const modalInner = modal.props.children; - expect(modalInner.props.className).to.equal('modal-inner'); - }); - - it('should render a child ', () => { - const modalClose = modal.props.children.props.children[0]; - expect(modalClose.props.className).to.equal('modal-close'); - }); - - it('should render additional children after .modal-close', () => { - const modalChildren = modal.props.children.props.children; - expect(modalChildren.length).to.equal(2); - expect(modalChildren[1]).to.equal(modalChild); - }); - }); - - describe('Behavior', () => { - let parent; - let modal; - let hideModalSpy; - - beforeEach(() => { - hideModalSpy = sinon.spy(); - - let ModalParent = createParent(Modal, 'modal', { - hideModal: hideModalSpy, - children:
- }); - - parent = TestUtils.renderIntoDocument(); - modal = parent.refs.modal; - }); - - it('should call props.hideModal when .modal-overlay is clicked', () => { - expect(hideModalSpy).to.have.not.been.called; - TestUtils.Simulate.click(findDOMNode(modal)); - expect(hideModalSpy).to.have.been.called; - }); - - it('should call props.hideModal when .modal-close is clicked', () => { - const modalClose = TestUtils.findRenderedDOMComponentWithClass(modal, 'modal-close'); - expect(hideModalSpy).to.have.not.been.called; - TestUtils.Simulate.click(findDOMNode(modalClose)); - expect(hideModalSpy).to.have.been.called; - }); - - // TODO: figure out how to test this - // it('should call props.hideModal when escape key is pressed', () => { - // expect(hideModalSpy).to.have.not.been.called; - // TestUtils.Simulate.keyPress(document, { keyCode: 27 }); - // expect(hideModalSpy).to.have.been.called; - // }); - - it('should not be removed when .modal-inner is clicked', () => { - const modalInner = TestUtils.findRenderedDOMComponentWithClass(modal, 'modal-inner'); - expect(hideModalSpy).to.have.not.been.called; - TestUtils.Simulate.click(findDOMNode(modalInner)); - expect(hideModalSpy).to.have.not.been.called; - }); - }); -}); \ No newline at end of file diff --git a/test/components/ProfileLink-test.jsx b/test/components/ProfileLink-test.jsx deleted file mode 100644 index 37e535b..0000000 --- a/test/components/ProfileLink-test.jsx +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; - -import React from 'react'; -import { Link } from 'react-router'; -import ProfileLink from '../../src/js/components/ProfileLink'; - -import TestUtils from 'react-addons-test-utils'; - -const userData = { - username: 'echenley', - md5hash: '7da6a19ef0b1a9b9794cf5c7cc7439f1' -}; - -const shallowRenderer = TestUtils.createRenderer(); -shallowRenderer.render(); -const profileLink = shallowRenderer.getRenderOutput(); - -describe('ProfileLink Component', () => { - describe('DOM', function() { - it('should render a link with className "login-links"', () => { - expect(profileLink.type).to.equal(Link); - expect(profileLink.props.className).to.equal('profile-link'); - }); - - it('should render username and gravatar', () => { - const children = profileLink.props.children; - - expect(children.length).to.equal(2); - expect(children[0].props.children).to.equal('echenley'); - expect(children[1].props.src).to.contain('7da6a19ef0b1a9b9794cf5c7cc7439f1'); - }); - }); -}); \ No newline at end of file diff --git a/test/components/Register-test.jsx b/test/components/Register-test.jsx deleted file mode 100644 index 5f92f56..0000000 --- a/test/components/Register-test.jsx +++ /dev/null @@ -1,77 +0,0 @@ -'use strict'; - -import createParent from '../util/createParent'; -import { findDOMNode } from 'react-dom'; - -var React; -var Register; -var TestUtils; - -describe('Register Component', () => { - - beforeEach(() => { - React = require('react'); - Register = require('../../src/js/components/Register'); - TestUtils = require('react-addons-test-utils'); - }); - - describe('DOM', () => { - let register; - let error; - - beforeEach(() => { - register = TestUtils.renderIntoDocument(); - }); - - it('should render a div with className "register"', () => { - expect(findDOMNode(register).className).to.equal('register'); - }); - - it('should not render an error message when not passed one', () => { - error = TestUtils.scryRenderedDOMComponentsWithClass(register, 'error'); - expect(error.length).to.equal(0); - }); - - it('should render an error message when passed as prop', () => { - register = TestUtils.renderIntoDocument(); - error = TestUtils.findRenderedDOMComponentWithClass(register, 'error'); - expect(findDOMNode(error).textContent).to.equal('uh oh'); - }); - }); - - describe('Props', () => { - let parent; - let register; - - beforeEach(() => { - let RegisterParent = createParent(Register, 'register', { - errorMessage: '', - user: { isLoggedIn: false } - }); - - parent = TestUtils.renderIntoDocument(); - register = parent.refs.register; - }); - - it('should disable submit button until props update', () => { - let submitButton = findDOMNode(TestUtils.findRenderedDOMComponentWithTag(register, 'button')); - - register.setState({ submitted: true }); - expect(submitButton.disabled).to.equal(true); - - parent.setState({ errorMessage: 'invalid user' }); - - expect(register.state.submitted).to.equal(false); - expect(submitButton.disabled).to.equal(false); - }); - - it('should clear form when user prop updates', () => { - register.clearForm = sinon.spy(); - expect(register.clearForm).to.have.not.been.called; - - parent.setState({ user: { isLoggedIn: true } }); - expect(register.clearForm).to.have.been.called; - }); - - }); -}); \ No newline at end of file diff --git a/test/karma.conf.js b/test/karma.conf.js index 2c9244d..4be3017 100644 --- a/test/karma.conf.js +++ b/test/karma.conf.js @@ -4,13 +4,17 @@ var webpackTestConfig = require('../webpack.tests.config.js'); module.exports = function(config) { config.set({ - browsers: ['PhantomJS'], + browsers: ['Chrome'], // karma only needs to know about the test bundle - files: [ - './test.bundle.js' - ], + files: ['./test.bundle.js'], singleRun: true, - frameworks: ['chai', 'mocha', 'sinon', 'sinon-chai', 'phantomjs-shim'], + frameworks: [ + 'chai', + 'mocha', + 'sinon', + 'sinon-chai', + 'phantomjs-shim' + ], plugins: [ 'karma-chrome-launcher', 'karma-chai', @@ -42,6 +46,6 @@ module.exports = function(config) { webpackMiddleware: { noInfo: true, }, - port: 3002 + port: 3300 }); }; diff --git a/test/test.bundle.js b/test/test.bundle.js index 36575e2..987a624 100644 --- a/test/test.bundle.js +++ b/test/test.bundle.js @@ -1,4 +1,8 @@ 'use strict'; -var context = require.context('./components/', true, /-test\.(js|jsx)$/); +import equalJSX from 'chai-equal-jsx'; + +chai.use(equalJSX); + +var context = require.context('../src/js/', true, /-test\.(js|jsx)$/); context.keys().forEach(context); diff --git a/test/util/clearCache.js b/test/util/clearCache.js deleted file mode 100644 index 41948fc..0000000 --- a/test/util/clearCache.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -export default () => { - // React caches required modules - for (var i in require.cache) { - delete require.cache[i]; - } -};