diff --git a/.eslintrc b/.eslintrc
index 06dc1920..33105a65 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -3,16 +3,26 @@
"es6": true,
"browser": true
},
- "extends": "airbnb",
+ "parser": "babel-eslint",
"parserOptions": {
"ecmaVersion": 7,
"ecmaFeatures": {
- "experimentalObjectRestSpread": true,
"jsx": true
},
"sourceType": "module"
},
- "parser": "babel-eslint",
+ "settings": {
+ "react": {
+ "createClass": "createReactClass",
+ "pragma": "React",
+ "version": "15.0"
+ },
+ "propWrapperFunctions": [ "forbidExtraProps" ]
+ },
+ "extends": ["eslint:recommended", "plugin:react/recommended"],
+ "globals": {
+ "process": true
+ },
"rules": {
"quotes": [0],
"comma-dangle": [2, "only-multiline"],
@@ -23,12 +33,9 @@
"func-names": [0],
"arrow-parens": [0],
"space-before-function-paren": [0],
- "import/no-extraneous-dependencies": [2, {"devDependencies": true}],
"jsx-a11y/no-static-element-interactions": [0],
"react/no-find-dom-node": [0],
"react/jsx-closing-bracket-location": [0],
- "react/jsx-filename-extension": ["error", {"extensions": [".js"]}],
- "react/forbid-prop-types": [1, {"forbid": ["any"]}],
"react/require-default-props": 0
}
}
diff --git a/karma.conf.js b/karma.conf.js
index 023f7cab..b9e1cd14 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -1,34 +1,33 @@
-const browsers = [process.env.CONTINUOUS_INTEGRATION ? 'Firefox' : 'Chrome'];
+let browsers = ['Chrome'];
+let coverageType = 'text';
+
+if (process.env.CONTINUOUS_INTEGRATION) {
+ browsers = ['Firefox'];
+ coverageType = 'lcovonly';
+}
module.exports = function(config) {
config.set({
-
- basePath: '',
-
frameworks: ['mocha'],
- files: [
- 'specs/spec_index.js'
- ],
-
preprocessors: {
- 'specs/spec_index.js': ['webpack', 'sourcemap']
+ './src/*.js': ['coverage'],
+ './src/**/*.js': ['coverage'],
+ './specs/index.js': ['webpack', 'sourcemap']
},
+ files: ['./specs/index.js'],
+
webpack: require('./webpack.test.config'),
- webpackMiddleware: {
- stats: 'errors-only'
- },
+ webpackMiddleware: { stats: 'errors-only' },
reporters: ['mocha', 'coverage'],
- mochaReporter: {
- showDiff: true
- },
+ mochaReporter: { showDiff: true },
coverageReporter: {
- type : 'lcov',
+ type : coverageType,
dir : 'coverage/',
subdir: '.'
},
diff --git a/package.json b/package.json
index 13b04ac0..eeef8456 100644
--- a/package.json
+++ b/package.json
@@ -15,51 +15,44 @@
"scripts": {
"start": "./node_modules/.bin/webpack-dev-server --inline --host 127.0.0.1 --content-base examples/",
"test": "cross-env NODE_ENV=test karma start",
- "lint": "eslint src/"
+ "lint": "eslint src/ spec/"
},
"authors": [
"Ryan Florence"
],
"license": "MIT",
"devDependencies": {
- "babel-cli": "^6.24.1",
"babel-core": "^6.25.0",
- "babel-eslint": "^7.1.1",
- "babel-loader": "^6.2.4",
+ "babel-eslint": "^8.0.0",
+ "babel-loader": "^7.1.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
- "codeclimate-test-reporter": "^0.4.0",
"coveralls": "^2.13.1",
"cross-env": "^5.0.1",
- "envify": "^3.4.1",
- "eslint": "^3.19.0",
- "eslint-config-airbnb": "^15.0.1",
- "eslint-plugin-import": "^2.3.0",
- "eslint-plugin-jsx-a11y": "^5.0.3",
+ "eslint": "^4.7.1",
+ "eslint-plugin-jsx-a11y": "^6.0.2",
"eslint-plugin-react": "^7.1.0",
- "expect": "^1.20.2",
"gitbook-cli": "^2.3.0",
- "istanbul-instrumenter-loader": "0.2.0",
+ "istanbul-instrumenter-loader": "^3.0.0",
"karma": "^1.3.0",
- "karma-chrome-launcher": "2.0.0",
- "karma-cli": "1.0.1",
+ "karma-chrome-launcher": "2.2.0",
"karma-coverage": "^1.1.1",
- "karma-firefox-launcher": "1.0.0",
+ "karma-firefox-launcher": "1.0.1",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.1",
"karma-sourcemap-loader": "^0.3.7",
- "karma-webpack": "^1.8.1",
- "mocha": "3.2.0",
- "npm-run-all": "^3.1.2",
+ "karma-webpack": "^2.0.4",
+ "mocha": "3.5.3",
+ "npm-run-all": "^4.1.1",
"react": "^15.6.1",
"react-dom": "^15.6.1",
- "rf-release": "0.4.0",
+ "should": "^13.1.0",
"sinon": "next",
- "uglify-js": "2.4.24",
- "webpack": "^1.12.14",
- "webpack-dev-server": "1.11.0"
+ "uglify-js": "3.1.1",
+ "webpack": "^3.6.0",
+ "webpack-dev-server": "2.8.2"
},
"dependencies": {
"exenv": "^1.2.0",
diff --git a/specs/Modal.events.spec.js b/specs/Modal.events.spec.js
index cf353a9b..7d31aa66 100644
--- a/specs/Modal.events.spec.js
+++ b/specs/Modal.events.spec.js
@@ -1,41 +1,41 @@
/* eslint-env mocha */
+import 'should';
import sinon from 'sinon';
-import expect from 'expect';
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-dom/test-utils';
-import Modal from '../src/components/Modal';
+import Modal from '../src/components/Modal.js';
import {
moverlay, mcontent,
clickAt, mouseDownAt, mouseUpAt, escKeyDown, tabKeyDown,
renderModal, emptyDOM
} from './helper';
-describe('Events', () => {
+export default () => {
afterEach('Unmount modal', emptyDOM);
it('should trigger the onAfterOpen callback', () => {
const afterOpenCallback = sinon.spy();
renderModal({ isOpen: true, onAfterOpen: afterOpenCallback });
- expect(afterOpenCallback.called).toBeTruthy();
+ afterOpenCallback.called.should.be.ok();
});
it('keeps focus inside the modal when child has no tabbable elements', () => {
let tabPrevented = false;
const modal = renderModal({ isOpen: true }, 'hello');
const content = mcontent(modal);
- expect(document.activeElement).toEqual(content);
+ document.activeElement.should.be.eql(content);
tabKeyDown(content, {
preventDefault() { tabPrevented = true; }
});
- expect(tabPrevented).toEqual(true);
+ tabPrevented.should.be.eql(true);
});
it('handles case when child has no tabbable elements', () => {
const modal = renderModal({ isOpen: true }, 'hello');
const content = mcontent(modal);
tabKeyDown(content);
- expect(document.activeElement).toEqual(content);
+ document.activeElement.should.be.eql(content);
});
it('should close on Esc key event', () => {
@@ -46,10 +46,10 @@ describe('Events', () => {
onRequestClose: requestCloseCallback
});
escKeyDown(mcontent(modal));
- expect(requestCloseCallback.called).toBeTruthy();
+ requestCloseCallback.called.should.be.ok();
// Check if event is passed to onRequestClose callback.
- const event = requestCloseCallback.getCall(0).args[0];
- expect(event).toExist();
+ const ev = requestCloseCallback.getCall(0).args[0];
+ ev.should.be.ok();
});
describe('shouldCloseOnoverlayClick', () => {
@@ -61,7 +61,7 @@ describe('Events', () => {
});
const overlay = moverlay(modal);
clickAt(overlay);
- expect(!requestCloseCallback.called).toBeTruthy();
+ requestCloseCallback.called.should.not.be.ok();
});
it('when true, click on overlay must close', () => {
@@ -72,7 +72,7 @@ describe('Events', () => {
onRequestClose: requestCloseCallback
});
clickAt(moverlay(modal));
- expect(requestCloseCallback.called).toBeTruthy();
+ requestCloseCallback.called.should.be.ok();
});
it('overlay mouse down and content mouse up, should not close', () => {
@@ -84,7 +84,7 @@ describe('Events', () => {
});
mouseDownAt(moverlay(modal));
mouseUpAt(mcontent(modal));
- expect(!requestCloseCallback.called).toBeTruthy();
+ requestCloseCallback.called.should.not.be.ok();
});
it('content mouse down and overlay mouse up, should not close', () => {
@@ -96,7 +96,7 @@ describe('Events', () => {
});
mouseDownAt(mcontent(modal));
mouseUpAt(moverlay(modal));
- expect(!requestCloseCallback.called).toBeTruthy();
+ requestCloseCallback.called.should.not.be.ok();
});
});
@@ -110,7 +110,7 @@ describe('Events', () => {
hasPropagated = true;
});
moverlay(modal).dispatchEvent(new MouseEvent('click', { bubbles: true }));
- expect(hasPropagated).toBeTruthy();
+ hasPropagated.should.be.ok();
});
it('verify event passing on overlay click', () => {
@@ -125,9 +125,9 @@ describe('Events', () => {
// Used to test that this was the event received
fakeData: 'ABC'
});
- expect(requestCloseCallback.called).toBeTruthy();
+ requestCloseCallback.called.should.be.ok();
// Check if event is passed to onRequestClose callback.
const event = requestCloseCallback.getCall(0).args[0];
- expect(event).toExist();
+ event.should.be.ok();
});
-});
+};
diff --git a/specs/Modal.spec.js b/specs/Modal.spec.js
index 38248c82..f9861b45 100644
--- a/specs/Modal.spec.js
+++ b/specs/Modal.spec.js
@@ -1,10 +1,11 @@
/* eslint-env mocha */
-import expect from 'expect';
+import 'should';
+import should from 'should';
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-dom/test-utils';
-import Modal from '../src/components/Modal';
-import * as ariaAppHider from '../src/helpers/ariaAppHider';
+import Modal from 'react-modal';
+import * as ariaAppHider from 'react-modal/helpers/ariaAppHider';
import {
isBodyWithReactModalOpenClass,
contentAttribute,
@@ -13,7 +14,7 @@ import {
renderModal, unmountModal, emptyDOM
} from './helper';
-describe('State', () => {
+export default () => {
afterEach('check if test cleaned up rendered modals', emptyDOM);
it('scopes tab navigation to the modal');
@@ -22,29 +23,29 @@ describe('State', () => {
it('can be open initially', () => {
const modal = renderModal({ isOpen: true }, 'hello');
- expect(mcontent(modal)).toExist();
+ mcontent(modal).should.be.ok();
});
it('can be closed initially', () => {
const modal = renderModal({}, 'hello');
- expect(ReactDOM.findDOMNode(mcontent(modal))).toNotExist();
+ should(ReactDOM.findDOMNode(mcontent(modal))).not.be.ok();
});
it('doesn\'t render the portal if modal is closed', () => {
const modal = renderModal({}, 'hello');
- expect(ReactDOM.findDOMNode(modal.portal)).toNotExist();
- })
+ should(ReactDOM.findDOMNode(modal.portal)).not.be.ok();
+ });
it('has default props', () => {
const node = document.createElement('div');
Modal.setAppElement(document.createElement('div'));
const modal = ReactDOM.render(, node);
const props = modal.props;
- expect(props.isOpen).toBe(false);
- expect(props.ariaHideApp).toBe(true);
- expect(props.closeTimeoutMS).toBe(0);
- expect(props.shouldFocusAfterRender).toBe(true);
- expect(props.shouldCloseOnOverlayClick).toBe(true);
+ props.isOpen.should.not.be.ok();
+ props.ariaHideApp.should.be.ok();
+ props.closeTimeoutMS.should.be.eql(0);
+ props.shouldFocusAfterRender.should.be.ok();
+ props.shouldCloseOnOverlayClick.should.be.ok();
ReactDOM.unmountComponentAtNode(node);
ariaAppHider.resetForTesting();
Modal.setAppElement(document.body); // restore default
@@ -56,7 +57,7 @@ describe('State', () => {
ReactDOM.render((
), node);
- expect(el.getAttribute('aria-hidden')).toEqual('true');
+ el.getAttribute('aria-hidden').should.be.eql('true');
ReactDOM.unmountComponentAtNode(node);
});
@@ -75,9 +76,9 @@ describe('State', () => {
}
Modal.setAppElement(node);
ReactDOM.render(, node);
- expect(
- document.body.querySelector('.ReactModalPortal').parentNode
- ).toEqual(
+ document.body.querySelector(
+ '.ReactModalPortal'
+ ).parentNode.should.be.eql(
document.body
);
ReactDOM.unmountComponentAtNode(node);
@@ -85,13 +86,13 @@ describe('State', () => {
it ('default parentSelector should be document.body.', () => {
const modal = renderModal({ isOpen: true });
- expect(modal.props.parentSelector()).toEqual(document.body);
+ modal.props.parentSelector().should.be.eql(document.body);
});
it('renders the modal content with a dialog aria role when provided ', () => {
const child = 'I am a child of Modal, and he has sent me here...';
const modal = renderModal({ isOpen: true, role: 'dialog' }, child);
- expect(contentAttribute(modal, 'role')).toEqual('dialog');
+ contentAttribute(modal, 'role').should.be.eql('dialog');
});
it('sets aria-label based on the contentLabel prop', () => {
@@ -100,15 +101,14 @@ describe('State', () => {
isOpen: true,
contentLabel: 'Special Modal'
}, child);
- expect(
- contentAttribute(modal, 'aria-label')
- ).toEqual('Special Modal');
+
+ contentAttribute(modal, 'aria-label').should.be.eql('Special Modal');
});
it('removes the portal node', () => {
const modal = renderModal({ isOpen: true }, 'hello');
unmountModal();
- expect(document.querySelector('.ReactModalPortal')).toNotExist();
+ should(document.querySelector('.ReactModalPortal')).not.be.ok();
});
it('removes the portal node after closeTimeoutMS', done => {
@@ -117,7 +117,7 @@ describe('State', () => {
function checkDOM(count) {
const portal = document.querySelectorAll('.ReactModalPortal');
- expect(portal.length).toBe(count);
+ portal.length.should.be.eql(count);
}
unmountModal();
@@ -134,12 +134,12 @@ describe('State', () => {
it('focuses the modal content by default', () => {
const modal = renderModal({ isOpen: true }, null);
- expect(document.activeElement).toBe(mcontent(modal));
+ document.activeElement.should.be.eql(mcontent(modal));
});
it('does not focus the modal content when shouldFocusAfterRender is false', () => {
const modal = renderModal({ isOpen: true, shouldFocusAfterRender: false }, null);
- expect(document.activeElement).toNotBe(mcontent(modal));
+ document.activeElement.should.not.be.eql(mcontent(modal));
});
it('give back focus to previous element or modal.', done => {
@@ -154,16 +154,16 @@ describe('State', () => {
}, null);
const modalContent = mcontent(modalA);
- expect(document.activeElement).toEqual(modalContent);
+ document.activeElement.should.be.eql(modalContent);
const modalB = renderModal({
isOpen: true,
className: 'modal-b',
onRequestClose() {
const modalContent = mcontent(modalB);
- expect(document.activeElement).toEqual(mcontent(modalA));
+ document.activeElement.should.be.eql(mcontent(modalA));
escKeyDown(modalContent);
- expect(document.activeElement).toEqual(modalContent);
+ document.activeElement.should.be.eql(modalContent);
}
}, null);
@@ -176,7 +176,7 @@ describe('State', () => {
{ el && el.focus(); content = el; }} />
);
renderModal({ isOpen: true }, input, () => {
- expect(document.activeElement).toEqual(content);
+ document.activeElement.should.be.eql(content);
});
});
@@ -185,14 +185,12 @@ describe('State', () => {
isOpen: true,
portalClassName: 'myPortalClass'
});
- expect(modal.node.className.includes('myPortalClass')).toBeTruthy();
+ modal.node.className.includes('myPortalClass').should.be.ok();
});
it('supports custom className', () => {
const modal = renderModal({ isOpen: true, className: 'myClass' });
- expect(
- mcontent(modal).className.includes('myClass')
- ).toBeTruthy();
+ mcontent(modal).className.includes('myClass').should.be.ok();
});
it('supports overlayClassName', () => {
@@ -200,9 +198,7 @@ describe('State', () => {
isOpen: true,
overlayClassName: 'myOverlayClass'
});
- expect(
- moverlay(modal).className.includes('myOverlayClass')
- ).toBeTruthy();
+ moverlay(modal).className.includes('myOverlayClass').should.be.ok();
});
it('overrides content classes with custom object className', () => {
@@ -214,9 +210,7 @@ describe('State', () => {
beforeClose: 'myClass_before-close'
}
});
- expect(
- mcontent(modal).className
- ).toEqual(
+ mcontent(modal).className.should.be.eql(
'myClass myClass_after-open'
);
unmountModal();
@@ -231,9 +225,7 @@ describe('State', () => {
beforeClose: 'myOverlayClass_before-close'
}
});
- expect(
- moverlay(modal).className
- ).toEqual(
+ moverlay(modal).className.should.be.eql(
'myOverlayClass myOverlayClass_after-open'
);
unmountModal();
@@ -244,37 +236,35 @@ describe('State', () => {
isOpen: true,
bodyOpenClassName: 'custom-modal-open'
});
- expect(
- document.body.className.indexOf('custom-modal-open') > -1
- ).toBeTruthy();
+ (document.body.className.indexOf('custom-modal-open') > -1).should.be.ok();
});
it('don\'t append class to document.body if modal is not open', () => {
renderModal({ isOpen: false });
- expect(!isBodyWithReactModalOpenClass()).toBeTruthy();
+ isBodyWithReactModalOpenClass().should.not.be.ok();
unmountModal();
});
it('append class to document.body if modal is open', () => {
renderModal({ isOpen: true });
- expect(isBodyWithReactModalOpenClass()).toBeTruthy();
+ isBodyWithReactModalOpenClass().should.be.ok();
unmountModal();
});
it('removes class from document.body when unmounted without closing', () => {
renderModal({ isOpen: true });
unmountModal();
- expect(!isBodyWithReactModalOpenClass()).toBeTruthy();
+ isBodyWithReactModalOpenClass().should.not.be.ok();
});
it('remove class from document.body when no modals opened', () => {
renderModal({ isOpen: true });
renderModal({ isOpen: true });
- expect(isBodyWithReactModalOpenClass()).toBeTruthy();
+ isBodyWithReactModalOpenClass().should.be.ok();
unmountModal();
- expect(isBodyWithReactModalOpenClass()).toBeTruthy();
+ isBodyWithReactModalOpenClass().should.be.ok();
unmountModal();
- expect(!isBodyWithReactModalOpenClass()).toBeTruthy();
+ isBodyWithReactModalOpenClass().should.not.be.ok();
});
it('supports adding/removing multiple document.body classes', () => {
@@ -282,9 +272,9 @@ describe('State', () => {
isOpen: true,
bodyOpenClassName: 'A B C'
});
- expect(document.body.classList.contains('A', 'B', 'C')).toBeTruthy();
+ document.body.classList.contains('A', 'B', 'C').should.be.ok();
unmountModal();
- expect(!document.body.classList.contains('A', 'B', 'C')).toBeTruthy();
+ document.body.classList.contains('A', 'B', 'C').should.not.be.ok();
});
it('does not remove shared classes if more than one modal is open', () => {
@@ -297,38 +287,36 @@ describe('State', () => {
bodyOpenClassName: 'A B'
});
- expect(isBodyWithReactModalOpenClass('A B')).toBeTruthy();
+ isBodyWithReactModalOpenClass('A B').should.be.ok();
unmountModal();
- expect(!isBodyWithReactModalOpenClass('A B')).toBeTruthy();
- expect(isBodyWithReactModalOpenClass('A')).toBeTruthy();
+ isBodyWithReactModalOpenClass('A B').should.not.be.ok();
+ isBodyWithReactModalOpenClass('A').should.be.ok();
unmountModal();
- expect(!isBodyWithReactModalOpenClass('A')).toBeTruthy();
+ isBodyWithReactModalOpenClass('A').should.not.be.ok();
});
it('should not add classes to document.body for unopened modals', () => {
renderModal({ isOpen: true });
- expect(isBodyWithReactModalOpenClass()).toBeTruthy();
+ isBodyWithReactModalOpenClass().should.be.ok();
renderModal({ isOpen: false, bodyOpenClassName: 'testBodyClass' });
- expect(!isBodyWithReactModalOpenClass('testBodyClass')).toBeTruthy()
+ isBodyWithReactModalOpenClass('testBodyClass').should.not.be.ok();
});
it('should not remove classes from document.body when rendering unopened modal', () => {
renderModal({ isOpen: true });
- expect(isBodyWithReactModalOpenClass()).toBeTruthy();
+ isBodyWithReactModalOpenClass().should.be.ok();
renderModal({ isOpen: false, bodyOpenClassName: 'testBodyClass' });
renderModal({ isOpen: false });
- expect(!isBodyWithReactModalOpenClass('testBodyClass')).toBeTruthy()
- expect(isBodyWithReactModalOpenClass()).toBeTruthy();
+ isBodyWithReactModalOpenClass('testBodyClass').should.not.be.ok();
+ isBodyWithReactModalOpenClass().should.be.ok();
renderModal({ isOpen: false });
renderModal({ isOpen: false });
- expect(isBodyWithReactModalOpenClass()).toBeTruthy();
+ isBodyWithReactModalOpenClass().should.be.ok();
});
it('additional aria attributes', () => {
const modal = renderModal({ isOpen: true, aria: { labelledby: "a" }}, 'hello');
- expect(
- mcontent(modal).getAttribute('aria-labelledby')
- ).toEqual("a");
+ mcontent(modal).getAttribute('aria-labelledby').should.be.eql("a");
unmountModal();
});
@@ -338,13 +326,13 @@ describe('State', () => {
ReactDOM.render((
), node);
- expect(document.body.getAttribute('aria-hidden')).toEqual('true');
+ document.body.getAttribute('aria-hidden').should.be.eql('true');
ReactDOM.unmountComponentAtNode(node);
- expect(document.body.getAttribute('aria-hidden')).toEqual(null);
+ should(document.body.getAttribute('aria-hidden')).not.be.ok();
});
it('raise an exception if appElement is a selector and no elements were found.', () => {
- expect(() => ariaAppHider.setElement('.test')).toThrow();
+ should(() => ariaAppHider.setElement('.test')).throw();
});
it('removes aria-hidden from appElement when unmounted w/o closing', () => {
@@ -353,16 +341,16 @@ describe('State', () => {
ReactDOM.render((
), node);
- expect(el.getAttribute('aria-hidden')).toEqual('true');
+ el.getAttribute('aria-hidden').should.be.eql('true');
ReactDOM.unmountComponentAtNode(node);
- expect(el.getAttribute('aria-hidden')).toEqual(null);
+ should(el.getAttribute('aria-hidden')).not.be.ok();
});
it('adds --after-open for animations', () => {
const modal = renderModal({ isOpen: true });
const rg = /--after-open/i;
- expect(rg.test(mcontent(modal).className)).toBeTruthy();
- expect(rg.test(moverlay(modal).className)).toBeTruthy();
+ rg.test(mcontent(modal).className).should.be.ok();
+ rg.test(moverlay(modal).className).should.be.ok();
});
it('adds --before-close for animations', () => {
@@ -374,8 +362,8 @@ describe('State', () => {
modal.portal.closeWithTimeout();
const rg = /--before-close/i;
- expect(rg.test(moverlay(modal).className)).toBeTruthy();
- expect(rg.test(mcontent(modal).className)).toBeTruthy();
+ rg.test(moverlay(modal).className).should.be.ok();
+ rg.test(mcontent(modal).className).should.be.ok();
modal.portal.closeWithoutTimeout();
});
@@ -389,18 +377,18 @@ describe('State', () => {
modal.portal.closeWithTimeout();
modal.portal.open();
modal.portal.closeWithoutTimeout();
- expect(!modal.portal.state.isOpen).toBeTruthy();
+ modal.portal.state.isOpen.should.not.be.ok();
});
it('verify default prop of shouldCloseOnOverlayClick', () => {
const modal = renderModal({ isOpen: true });
- expect(modal.props.shouldCloseOnOverlayClick).toBeTruthy();
+ modal.props.shouldCloseOnOverlayClick.should.be.ok();
});
it('verify prop of shouldCloseOnOverlayClick', () => {
const modalOpts = { isOpen: true, shouldCloseOnOverlayClick: false };
const modal = renderModal(modalOpts);
- expect(!modal.props.shouldCloseOnOverlayClick).toBeTruthy();
+ modal.props.shouldCloseOnOverlayClick.should.not.be.ok();
});
it('keeps the modal in the DOM until closeTimeoutMS elapses', done => {
@@ -412,8 +400,8 @@ describe('State', () => {
function checkDOM(count) {
const overlay = document.querySelectorAll('.ReactModal__Overlay');
const content = document.querySelectorAll('.ReactModal__Content');
- expect(overlay.length).toBe(count);
- expect(content.length).toBe(count);
+ overlay.length.should.be.eql(count);
+ content.length.should.be.eql(count);
}
// content is still mounted after modal is gone
@@ -454,7 +442,7 @@ describe('State', () => {
document.body.appendChild(currentDiv);
const mount = () => ReactDOM.render(, currentDiv);
- expect(mount).toNotThrow();
+ mount.should.not.throw();
document.body.removeChild(currentDiv);
});
@@ -470,7 +458,7 @@ describe('State', () => {
}
componentDidMount() {
- expect(modal.node.className).toEqual('myPortalClass');
+ modal.node.className.should.be.eql('myPortalClass');
this.setState({
testHasChanged: true
@@ -478,7 +466,7 @@ describe('State', () => {
}
componentDidUpdate() {
- expect(modal.node.className).toEqual('myPortalClass-modifier');
+ modal.node.className.should.be.eql('myPortalClass-modifier');
}
render() {
@@ -501,4 +489,4 @@ describe('State', () => {
Modal.setAppElement(node);
ReactDOM.render(, node);
});
-});
+};
diff --git a/specs/Modal.style.spec.js b/specs/Modal.style.spec.js
index 68302338..59a8ddf5 100644
--- a/specs/Modal.style.spec.js
+++ b/specs/Modal.style.spec.js
@@ -1,21 +1,21 @@
/* eslint-env mocha */
-import expect from 'expect';
+import 'should';
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-dom/test-utils';
-import Modal from '../src/components/Modal';
-import * as ariaAppHider from '../src/helpers/ariaAppHider';
+import Modal from 'react-modal';
+import * as ariaAppHider from 'react-modal/helpers/ariaAppHider';
import {
mcontent, moverlay,
renderModal, emptyDOM
} from './helper';
-describe('Style', () => {
+export default () => {
afterEach('Unmount modal', emptyDOM);
it('overrides the default styles when a custom classname is used', () => {
const modal = renderModal({ isOpen: true, className: 'myClass' });
- expect(mcontent(modal).style.top).toEqual('');
+ mcontent(modal).style.top.should.be.eql('');
});
it('overrides the default styles when a custom overlayClassName is used',
@@ -24,32 +24,32 @@ describe('Style', () => {
isOpen: true,
overlayClassName: 'myOverlayClass'
});
- expect(moverlay(modal).style.backgroundColor).toEqual('');
+ moverlay(modal).style.backgroundColor.should.be.eql('');
}
);
it('supports adding style to the modal contents', () => {
const style = { content: { width: '20px' } };
const modal = renderModal({ isOpen: true, style });
- expect(mcontent(modal).style.width).toEqual('20px');
+ mcontent(modal).style.width.should.be.eql('20px');
});
it('supports overriding style on the modal contents', () => {
const style = { content: { position: 'static' } };
const modal = renderModal({ isOpen: true, style });
- expect(mcontent(modal).style.position).toEqual('static');
+ mcontent(modal).style.position.should.be.eql('static');
});
it('supports adding style on the modal overlay', () => {
const style = { overlay: { width: '75px' } };
const modal = renderModal({ isOpen: true, style });
- expect(moverlay(modal).style.width).toEqual('75px');
+ moverlay(modal).style.width.should.be.eql('75px');
});
it('supports overriding style on the modal overlay', () => {
const style = { overlay: { position: 'static' } };
const modal = renderModal({ isOpen: true, style });
- expect(moverlay(modal).style.position).toEqual('static');
+ moverlay(modal).style.position.should.be.eql('static');
});
it('supports overriding the default styles', () => {
@@ -59,7 +59,7 @@ describe('Style', () => {
const newStyle = previousStyle === 'relative' ? 'static' : 'relative';
Modal.defaultStyles.content.position = newStyle;
const modal = renderModal({ isOpen: true });
- expect(modal.portal.content.style.position).toEqual(newStyle);
+ modal.portal.content.style.position.should.be.eql(newStyle);
Modal.defaultStyles.content.position = previousStyle;
});
-});
+};
diff --git a/specs/index.js b/specs/index.js
new file mode 100644
index 00000000..9fdd1f47
--- /dev/null
+++ b/specs/index.js
@@ -0,0 +1,9 @@
+/* eslint-env mocha */
+
+import ModalState from './Modal.spec';
+import ModalEvents from './Modal.events.spec';
+import ModalStyle from './Modal.style.spec';
+
+describe('State', ModalState);
+describe('Style', ModalStyle);
+describe('Events', ModalEvents);
diff --git a/specs/spec_index.js b/specs/spec_index.js
deleted file mode 100644
index 2d24be84..00000000
--- a/specs/spec_index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-const testsContext = require.context('.', true, /spec$/);
-testsContext.keys().forEach((path) => {
- try {
- testsContext(path);
- } catch (err) {
- console.error(`[ERROR] WITH SPEC FILE: ${path}`);
- console.error(err);
- }
-});
-
-const componentsContext = require.context('../src', true, /\.js$/);
-componentsContext.keys().forEach((path) => {
- try {
- componentsContext(path);
- } catch (err) {
- console.error(`[ERROR] WITH LIB FILE: ${path}`);
- console.error(err);
- }
-});
diff --git a/webpack.config.js b/webpack.config.js
index 28c1fb08..9faa5d97 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -34,8 +34,8 @@ module.exports = {
},
module: {
- loaders: [
- { test: /\.js$/, exclude: /node_modules/, loader: 'babel' }
+ rules: [
+ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }
]
},
@@ -46,7 +46,8 @@ module.exports = {
},
plugins: [
- new webpack.optimize.CommonsChunkPlugin('shared.js')
+ new webpack.optimize.CommonsChunkPlugin('shared.js'),
+ new webpack.LoaderOptionsPlugin({ debug: true })
]
};
diff --git a/webpack.test.config.js b/webpack.test.config.js
index 85302c6a..b5652f6e 100644
--- a/webpack.test.config.js
+++ b/webpack.test.config.js
@@ -2,17 +2,14 @@ const path = require('path');
const commonConfig = require('./webpack.config');
commonConfig.plugins = [];
-commonConfig.entry = undefined;
-commonConfig.debug = true;
+commonConfig.entry = './specs/index.js';
commonConfig.devtool = 'inline-source-map';
-if (process.env.CONTINUOUS_INTEGRATION || process.env.COVERAGE) {
- commonConfig.module.postLoaders = commonConfig.module.postLoaders || [];
- commonConfig.module.postLoaders.push({
- test: /\.js$/,
- include: path.resolve('src'),
- loader: 'istanbul-instrumenter'
- });
-}
+commonConfig.module.rules.unshift({
+ test: /\.js$/,
+ use: { loader: 'istanbul-instrumenter-loader' },
+ enforce: 'post',
+ include: path.resolve(__dirname, './src')
+});
module.exports = commonConfig;