diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000..626c4f3
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,2 @@
+/lib
+/node_modules
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..c199225
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,215 @@
+{
+ "parser": "babel-eslint",
+ "plugins": [
+ "babel",
+ "flow-vars",
+ "react"
+ ],
+ "env": {
+ "browser": true,
+ "node": true
+ },
+ "globals": {
+ "Map": false
+ },
+ "rules": {
+ "no-cond-assign": 1, // disallow assignment in conditional expressions
+ "no-console": 0, // disallow use of console: should use nuclide-logging instead
+ "no-constant-condition": 1, // disallow use of constant expressions in conditions
+ "no-control-regex": 1, // disallow control characters in regular expressions
+ "no-debugger": 1, // disallow use of debugger
+ "no-dupe-keys": 1, // disallow duplicate keys when creating object literals
+ "no-dupe-args": 1, // disallow duplicate arguments in functions
+ "no-duplicate-case": 1, // disallow a duplicate case label
+ "no-empty": 0, // disallow empty statements
+ "no-empty-character-class": 1, // disallow the use of empty character classes in regular expressions
+ "no-ex-assign": 1, // disallow assigning to the exception in a catch block
+ "no-extra-boolean-cast": 1, // disallow double-negation boolean casts in a boolean context
+ "no-extra-semi": 1, // disallow unnecessary semicolons
+ "no-func-assign": 1, // disallow overwriting functions written as function declarations
+ "no-inner-declarations": 0, // disallow function or variable declarations in nested blocks
+ "no-invalid-regexp": 1, // disallow invalid regular expression strings in the RegExp constructor
+ "no-negated-in-lhs": 1, // disallow negation of the left operand of an in expression
+ "no-obj-calls": 1, // disallow the use of object properties of the global object (Math and JSON) as functions
+ "no-regex-spaces": 1, // disallow multiple spaces in a regular expression literal
+ "no-reserved-keys": 0, // disallow reserved words being used as object literal keys
+ "no-sparse-arrays": 1, // disallow sparse arrays
+ "no-unreachable": 1, // disallow unreachable statements after a return, throw, continue, or break statement
+ "use-isnan": 1, // disallow comparisons with the value NaN
+ "valid-jsdoc": 0, // Ensure JSDoc comments are valid
+ "valid-typeof": 1, // Ensure that the results of typeof are compared against a valid string
+
+ // Best Practices (designed to prevent you from making mistakes)
+
+ "block-scoped-var": 0, // treat var statements as if they were block scoped
+ "complexity": 0, // specify the maximum cyclomatic complexity allowed in a program
+ "consistent-return": 0, // require return statements to either always or never specify values
+ "curly": 1, // specify curly brace conventions for all control statements
+ "default-case": 0, // require default case in switch statements
+ "dot-notation": 0, // dot notation encouraged except for foreign properties that cannot be renamed (i.e., Closure Compiler rules)
+ "eqeqeq": [1, "allow-null"], // require the use of === and !==
+ "guard-for-in": 1, // make sure for-in loops have an if statement
+ "no-alert": 1, // disallow the use of alert, confirm, and prompt
+ "no-caller": 1, // disallow use of arguments.caller or arguments.callee
+ "no-div-regex": 1, // disallow division operators explicitly at beginning of regular expression
+ "no-else-return": 0, // disallow else after a return in an if
+ "no-eq-null": 0, // disallow comparisons to null without a type-checking operator
+ "no-eval": 1, // disallow use of eval()
+ "no-extend-native": 1, // disallow adding to native types
+ "no-extra-bind": 1, // disallow unnecessary function binding
+ "no-fallthrough": 1, // disallow fallthrough of case statements
+ "no-floating-decimal": 1, // disallow the use of leading or trailing decimal points in numeric literals
+ "no-implied-eval": 1, // disallow use of eval()-like methods
+ "no-labels": 1, // disallow use of labeled statements
+ "no-iterator": 1, // disallow usage of __iterator__ property
+ "no-lone-blocks": 1, // disallow unnecessary nested blocks
+ "no-loop-func": 0, // disallow creation of functions within loops
+ "no-multi-str": 0, // disallow use of multiline strings
+ "no-native-reassign": 0, // disallow reassignments of native objects
+ "no-new": 1, // disallow use of new operator when not part of the assignment or comparison
+ "no-new-func": 1, // disallow use of new operator for Function object
+ "no-new-wrappers": 1, // disallows creating new instances of String,Number, and Boolean
+ "no-octal": 1, // disallow use of octal literals
+ "no-octal-escape": 1, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251";
+ "no-proto": 1, // disallow usage of __proto__ property
+ "no-redeclare": 1, // disallow declaring the same variable more then once
+ "no-return-assign": 1, // disallow use of assignment in return statement
+ "no-script-url": 1, // disallow use of javascript: urls.
+ "no-self-compare": 1, // disallow comparisons where both sides are exactly the same
+ "no-sequences": 1, // disallow use of comma operator
+ "no-unused-expressions": 0, // disallow usage of expressions in statement position
+ "no-void": 1, // disallow use of void operator
+ "no-warning-comments": 0, // disallow usage of configurable warning terms in comments e.g. TODO or FIXME
+ "no-with": 1, // disallow use of the with statement
+ "radix": 1, // require use of the second argument for parseInt()
+ "vars-on-top": 0, // requires to declare all vars on top of their containing scope
+ "wrap-iife": 0, // require immediate function invocation to be wrapped in parentheses
+ "yoda": 1, // require or disallow Yoda conditions
+ "strict": 0, // this rule conflicts with 'use-babel' so we'll just disable it
+
+ // Variables
+
+ "no-catch-shadow": 1, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment)
+ "no-delete-var": 1, // disallow deletion of variables
+ "no-label-var": 1, // disallow labels that share a name with a variable
+ "no-shadow": 0, // disallow declaration of variables already declared in the outer scope
+ "no-shadow-restricted-names": 1, // disallow shadowing of names such as arguments
+ "no-undef": 1, // disallow undeclared variables
+ "no-undefined": 0, // disallow use of undefined variable
+ "no-undef-init": 0, // disallow use of undefined when initializing variables
+ "no-unused-vars": 1, // disallow declaration of variables that are not used in the code
+ "no-use-before-define": 0, // disallow use of variables before they are defined
+
+ // Node.js
+
+ "handle-callback-err": 1, // enforces error handling in callbacks
+ "no-mixed-requires": 1, // disallow mixing regular variable and require declarations
+ "no-new-require": 1, // disallow use of new operator with the require function
+ "no-path-concat": 1, // disallow string concatenation with __dirname and __filename
+ "no-process-exit": 0, // disallow process.exit()
+ "no-restricted-modules": 1, // restrict usage of specified node modules
+ "no-sync": 0, // disallow use of synchronous methods
+
+ // React (eslint-plugin-react)
+
+ "jsx-quotes": [1, "prefer-double"], // not
+ "react/jsx-curly-spacing": [ // Enforce or disallow spaces inside of curly braces in JSX attributes
+ 1, "never"
+ ],
+ "react/jsx-no-undef": 1, // Disallow undeclared variables in JSX
+ "react/jsx-uses-react": 1, // Prevent React to be incorrectly marked as unused
+ "react/jsx-uses-vars": 1, // Prevent variables used in JSX to be incorrectly marked as unused
+ "react/no-unknown-property": 1, // Prevent usage of unknown DOM property
+ "react/prop-types": 1, // Prevent missing props validation in a React component definition
+ "react/react-in-jsx-scope": 2, // Prevent missing React when using JSX
+
+ // Stylistic (these rules are purely matters of style and are quite subjective)
+
+ "key-spacing": 1, // require space after colon `{a: 1}`
+ "comma-spacing": 1, // require space after comma `var a, b;`
+ "no-multi-spaces": 1, // don't allow more spaces than necessary
+ "brace-style": [ // enforce one true brace style
+ 1, "1tbs", {
+ "allowSingleLine": false
+ }
+ ],
+ "camelcase": [ // require camel case names
+ 1, {"properties": "never"}
+ ],
+ "consistent-this": [1, "self"], // enforces consistent naming when capturing the current execution context
+ "eol-last": 1, // enforce newline at the end of file, with no multiple empty lines
+ "func-names": 0, // require function expressions to have a name
+ "func-style": 0, // enforces use of function declarations or expressions
+ "new-cap": 0, // require a capital letter for constructors
+ "new-parens": 1, // disallow the omission of parentheses when invoking a constructor with no arguments
+ "no-nested-ternary": 0, // disallow nested ternary expressions
+ "no-array-constructor": 1, // disallow use of the Array constructor
+ "no-lonely-if": 0, // disallow if as the only statement in an else block
+ "no-new-object": 1, // disallow use of the Object constructor
+ "no-spaced-func": 1, // disallow space between function identifier and application
+ "semi-spacing": 1, // disallow space before semicolon
+ "no-ternary": 0, // disallow the use of ternary operators
+ "no-trailing-spaces": 1, // disallow trailing whitespace at the end of lines
+ "no-underscore-dangle": 0, // disallow dangling underscores in identifiers
+ "no-extra-parens": [1, "functions"], // disallow wrapping of non-IIFE statements in parens
+ "no-mixed-spaces-and-tabs": 1, // disallow mixed spaces and tabs for indentation
+ "indent": [1, 4, {"SwitchCase": 1}], // indentation should be four spaces
+ "quotes": [ // enforce single quotes, allow double to avoid escaping ("don't escape" instead of 'don\'t escape')
+ 1, "single", "avoid-escape"
+ ],
+ "quote-props": [1, "as-needed"], // require quotes around object literal property names
+ "semi": 1, // require or disallow use of semicolons instead of ASI
+ "sort-vars": 0, // sort variables within the same declaration block
+ "keyword-spacing": 1, // require a space around certain keywords
+ "space-before-blocks": 1, // require a space before blocks
+ "space-before-function-paren": [ // disallow a space before function parenthesis
+ 1, "never"
+ ],
+ "object-curly-spacing": [ // disallow spaces inside of curly braces in object literals
+ 1, "never"
+ ],
+ "array-bracket-spacing": [ // disallow spaces inside of curly braces in array literals
+ 1, "never"
+ ],
+ "space-in-parens": 1, // require or disallow spaces inside parentheses
+ "space-infix-ops": 1, // require spaces around operators
+ "space-unary-ops": 1, // require a space around word operators such as typeof
+ "max-nested-callbacks": 0, // specify the maximum depth callbacks can be nested
+ // "one-var": [1, "never"], // allow just one var statement per function
+ "wrap-regex": 0, // require regex literals to be wrapped in parentheses
+
+ // ECMAScript 6/7 (2015 and above)
+ "arrow-parens": 1, // require parens in arrow function arguments
+ "arrow-spacing": 1, // require space before/after arrow function's arrow (fixable)
+ "constructor-super": 1, // verify calls of super() in constructors
+ "generator-star-spacing": 0, // enforce spacing around the * in generator functions (fixable)
+ "no-class-assign": 1, // disallow modifying variables of class declarations
+ "no-const-assign": 1, // disallow modifying variables that are declared using const
+ "no-dupe-class-members": 1, // disallow duplicate name in class members
+ "no-this-before-super": 1, // disallow use of this/super before calling super() in constructors.
+ "no-var": 0, // require let or const instead of var
+ "object-shorthand": 0, // require method and property shorthand syntax for object literals
+ "prefer-arrow-callback": 1, // suggest using arrow functions as callbacks
+ "prefer-const": 0, // suggest using const declaration for variables that are never modified after declared
+ "prefer-reflect": 0, // suggest using Reflect methods where applicable
+ "prefer-spread": 0, // suggest using the spread operator instead of .apply().
+ "prefer-template": 0, // suggest using template literals instead of strings concatenation
+ "require-yield": 0, // disallow generator functions that do not have yield
+ "babel/no-await-in-loop": 1, // async inside a loop will run operations in serial, when often the desired behavior is to do do in parallel
+
+ // Legacy (included for compatibility with JSHint and JSLint. While the names of the rules may not match up with the JSHint/JSLint counterpart, the functionality is the same)
+
+ "max-depth": 0, // specify the maximum depth that blocks can be nested
+ //"max-len": [ // specify the maximum length of a line in your program [warning level, max line length, number of characters to treat a tab as]
+ // 1, 100, 2, {
+ // "ignoreUrls": true,
+ // "ignorePattern": "^\\s*(import\\s[^{]+from|(var|const|let)\\s[^{]+=\\s*require\\s*\\()"
+ // }
+ //],
+ "max-params": 0, // limits the number of parameters that can be used in the function declaration.
+ "max-statements": 0, // specify the maximum number of statement allowed in a function
+ "no-bitwise": 0, // disallow use of bitwise operators
+ "no-plusplus": 0 // disallow use of unary operators, ++ and --
+
+ }
+}
diff --git a/.gitignore b/.gitignore
index cf9c7f9..41ac350 100755
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+lib
node_modules
coverage
dist
@@ -7,4 +8,6 @@ dist
!.gitignore
!.npmignore
!.babelrc
+!.eslintrc
+!.eslintignore
!.travis.yml
diff --git a/package.json b/package.json
index 6a40041..3b01790 100644
--- a/package.json
+++ b/package.json
@@ -22,17 +22,20 @@
"dependencies": {
"es6-map": "^0.1.3",
"hoist-non-react-statics": "^1.0.5",
- "lodash": "^4.6.1",
- "object-unfreeze": "^1.0.2"
+ "lodash": "^4.6.1"
},
"devDependencies": {
"chai": "^3.5.0",
+ "eslint": "^2.12.0",
+ "eslint-plugin-babel": "^3.2.0",
+ "eslint-plugin-flow-vars": "^0.4.0",
+ "eslint-plugin-react": "^5.1.1",
"jsdom": "^8.1.0",
"pragmatist": "^3.0.21",
- "react": "^15.0.0-rc.1",
- "react-addons-shallow-compare": "^15.0.0-rc.1",
- "react-addons-test-utils": "^15.0.0-rc.1",
- "react-dom": "^15.0.0-rc.1"
+ "react": "^15.1.0",
+ "react-addons-shallow-compare": "^15.1.0",
+ "react-addons-test-utils": "^15.1.0",
+ "react-dom": "^15.1.0"
},
"scripts": {
"pragmatist": "node ./node_modules/.bin/pragmatist --es5",
diff --git a/src/extendReactClass.js b/src/extendReactClass.js
deleted file mode 100644
index fd00abd..0000000
--- a/src/extendReactClass.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* eslint-disable react/prop-types */
-
-import linkClass from './linkClass';
-import React from 'react';
-import _ from 'lodash';
-import hoistNonReactStatics from 'hoist-non-react-statics';
-
-/**
- * @param {ReactClass} Component
- * @param {Object} defaultStyles
- * @param {Object} options
- * @returns {ReactClass}
- */
-export default (Component: Object, defaultStyles: Object, options: Object) => {
- const WrappedComponent = class extends Component {
- render () {
- let propsChanged,
- styles;
-
- propsChanged = false;
-
- if (this.props.styles) {
- styles = this.props.styles;
- } else if (_.isObject(defaultStyles)) {
- this.props = _.assign({}, this.props, {
- styles: defaultStyles
- });
-
- propsChanged = true;
- styles = defaultStyles;
- } else {
- styles = {};
- }
-
- const renderResult = super.render();
-
- if (propsChanged) {
- delete this.props.styles;
- }
-
- if (renderResult) {
- return linkClass(renderResult, styles, options);
- }
-
- return React.createElement('noscript');
- }
- };
-
- return hoistNonReactStatics(WrappedComponent, Component);
-};
diff --git a/src/index.js b/src/index.js
index 6c1a78c..41cf94d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,38 +1,24 @@
import _ from 'lodash';
-import extendReactClass from './extendReactClass';
-import wrapStatelessFunction from './wrapStatelessFunction';
+import wrapComponent from './wrapComponent';
/**
* @see https://github.com/gajus/react-css-modules#options
*/
type OptionsType = {};
-/**
- * Determines if the given object has the signature of a class that inherits React.Component.
- */
-const isReactComponent = (maybeReactComponent: any): boolean => {
- return 'prototype' in maybeReactComponent && _.isFunction(maybeReactComponent.prototype.render);
-};
-
/**
* When used as a function.
*/
const functionConstructor = (Component: Function, defaultStyles: Object, options: OptionsType): Function => {
- let decoratedClass;
-
- if (isReactComponent(Component)) {
- decoratedClass = extendReactClass(Component, defaultStyles, options);
- } else {
- decoratedClass = wrapStatelessFunction(Component, defaultStyles, options);
- }
+ let WrappedComponent = wrapComponent(Component, defaultStyles, options);
if (Component.displayName) {
- decoratedClass.displayName = Component.displayName;
+ WrappedComponent.displayName = Component.displayName;
} else {
- decoratedClass.displayName = Component.name;
+ WrappedComponent.displayName = Component.name;
}
- return decoratedClass;
+ return WrappedComponent;
};
/**
diff --git a/src/isIterable.js b/src/isIterable.js
deleted file mode 100644
index ac6dc72..0000000
--- a/src/isIterable.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import _ from 'lodash';
-
-const ITERATOR_SYMBOL = _.isFunction(Symbol) && Symbol.iterator;
-const OLD_ITERATOR_SYMBOL = '@@iterator';
-
-/**
- * @see https://github.com/lodash/lodash/issues/1668
- * @see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols
- */
-export default (maybeIterable: any): boolean => {
- let iterator;
-
- if (!_.isObject(maybeIterable)) {
- return false;
- }
-
- if (ITERATOR_SYMBOL) {
- iterator = maybeIterable[ITERATOR_SYMBOL];
- } else {
- iterator = maybeIterable[OLD_ITERATOR_SYMBOL];
- }
-
- return _.isFunction(iterator);
-};
diff --git a/src/linkClass.js b/src/linkClass.js
deleted file mode 100644
index 2c3c930..0000000
--- a/src/linkClass.js
+++ /dev/null
@@ -1,75 +0,0 @@
-import _ from 'lodash';
-import React, {
- ReactElement
-} from 'react';
-import makeConfiguration from './makeConfiguration';
-import isIterable from './isIterable';
-import parseStyleName from './parseStyleName';
-import generateAppendClassName from './generateAppendClassName';
-import objectUnfreeze from 'object-unfreeze';
-
-const linkElement = (element: ReactElement, styles: Object, configuration: Object): ReactElement => {
- let appendClassName,
- elementIsFrozen,
- elementShallowCopy;
-
- elementShallowCopy = element;
-
- if (Object.isFrozen && Object.isFrozen(elementShallowCopy)) {
- elementIsFrozen = true;
-
- // https://github.com/facebook/react/blob/v0.13.3/src/classic/element/ReactElement.js#L131
- elementShallowCopy = objectUnfreeze(elementShallowCopy);
- elementShallowCopy.props = objectUnfreeze(elementShallowCopy.props);
- }
-
- const styleNames = parseStyleName(elementShallowCopy.props.styleName || '', configuration.allowMultiple);
-
- if (React.isValidElement(elementShallowCopy.props.children)) {
- elementShallowCopy.props.children = linkElement(React.Children.only(elementShallowCopy.props.children), styles, configuration);
- } else if (_.isArray(elementShallowCopy.props.children) || isIterable(elementShallowCopy.props.children)) {
- elementShallowCopy.props.children = React.Children.map(elementShallowCopy.props.children, (node) => {
- if (React.isValidElement(node)) {
- return linkElement(node, styles, configuration);
- } else {
- return node;
- }
- });
- }
-
- if (styleNames.length) {
- appendClassName = generateAppendClassName(styles, styleNames, configuration.errorWhenNotFound);
-
- if (appendClassName) {
- if (elementShallowCopy.props.className) {
- appendClassName = elementShallowCopy.props.className + ' ' + appendClassName;
- }
-
- elementShallowCopy.props.className = appendClassName;
- elementShallowCopy.props.styleName = null;
- }
- }
-
- if (elementIsFrozen) {
- Object.freeze(elementShallowCopy.props);
- Object.freeze(elementShallowCopy);
- }
-
- return elementShallowCopy;
-};
-
-/**
- * @param {ReactElement} element
- * @param {Object} styles CSS modules class map.
- * @param {CSSModules~Options} userConfiguration
- */
-export default (element: ReactElement, styles = {}, userConfiguration): ReactElement => {
- // @see https://github.com/gajus/react-css-modules/pull/30
- if (!_.isObject(element)) {
- return element;
- }
-
- const configuration = makeConfiguration(userConfiguration);
-
- return linkElement(element, styles, configuration);
-};
diff --git a/src/wrapComponent.js b/src/wrapComponent.js
new file mode 100644
index 0000000..c5d71d8
--- /dev/null
+++ b/src/wrapComponent.js
@@ -0,0 +1,70 @@
+/* eslint-disable react/prop-types */
+
+import generateAppendClassName from './generateAppendClassName';
+import hoistNonReactStatics from 'hoist-non-react-statics';
+import makeConfiguration from './makeConfiguration';
+import parseStyleName from './parseStyleName';
+import React, {Children} from 'react';
+
+/**
+ * @param {ReactElement} element
+ * @param {Object} styles
+ * @param {Object} options
+ * @returns {ReactElement}
+ */
+function updateProps(element: Object, styles: Object, options: Object) {
+ if (element == null || typeof element !== 'object') {
+ return element;
+ }
+ let {styleName, className, children} = element.props;
+ let didUpdate = false;
+ if (styleName != null) {
+ let styleNames = parseStyleName(styleName, options.allowMultiple);
+ let appendClassName = generateAppendClassName(styles, styleNames, options.errorWhenNotFound);
+ className = className ? className + ' ' + appendClassName : appendClassName;
+ didUpdate = true;
+ }
+ if (children != null) {
+ let newChildren = [];
+ let didUpdateChildren = true;
+ Children.forEach(children, (child) => {
+ let newChild = updateProps(child, styles, options);
+ newChildren.push(newChild);
+ if (newChild !== child) {
+ didUpdateChildren = true;
+ }
+ });
+ if (didUpdateChildren) {
+ children = newChildren;
+ didUpdate = true;
+ }
+ }
+ if (didUpdate) {
+ let props = {...element.props, className, children};
+ return {...element, props};
+ } else {
+ return element;
+ }
+}
+
+/**
+ * @param {Function} Component
+ * @param {Object} defaultStyles
+ * @param {Object} options
+ * @returns {ReactClass}
+ */
+export default function wrapComponent(Component: Function, defaultStyles: Object = {}, options: Object = {}) {
+ class WrappedComponent extends React.Component {
+ render() {
+ let {props} = this;
+ let {styles} = props;
+ if (styles == null) {
+ styles = defaultStyles;
+ props = {...props, styles};
+ }
+ let element = React.createElement(Component, props);
+ return updateProps(element, styles, makeConfiguration(options));
+ }
+ }
+ return hoistNonReactStatics(WrappedComponent, Component);
+}
diff --git a/src/wrapStatelessFunction.js b/src/wrapStatelessFunction.js
deleted file mode 100644
index 878119a..0000000
--- a/src/wrapStatelessFunction.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* eslint-disable react/prop-types */
-
-import _ from 'lodash';
-import React from 'react';
-import linkClass from './linkClass';
-
-/**
- * @see https://facebook.github.io/react/blog/2015/09/10/react-v0.14-rc1.html#stateless-function-components
- */
-export default (Component: Function, defaultStyles: Object, options: Object): Function => {
- const WrappedComponent = (props = {}, ...args) => {
- let styles,
- useProps;
-
- if (props.styles) {
- useProps = props;
- styles = props.styles;
- } else if (_.isObject(defaultStyles)) {
- useProps = _.assign({}, props, {
- styles: defaultStyles
- });
-
- styles = defaultStyles;
- } else {
- useProps = props;
- styles = {};
- }
-
- const renderResult = Component(useProps, ...args);
-
- if (renderResult) {
- return linkClass(renderResult, styles, options);
- }
-
- return React.createElement('noscript');
- };
-
- _.assign(WrappedComponent, Component);
-
- return WrappedComponent;
-};
diff --git a/tests/.eslintrc b/tests/.eslintrc
new file mode 100644
index 0000000..7eeefc3
--- /dev/null
+++ b/tests/.eslintrc
@@ -0,0 +1,5 @@
+{
+ "env": {
+ "mocha": true
+ }
+}
diff --git a/tests/extendReactClass.js b/tests/extendReactClass.js
index 16aed7f..5fc22a7 100644
--- a/tests/extendReactClass.js
+++ b/tests/extendReactClass.js
@@ -1,150 +1,150 @@
/* eslint-disable max-nested-callbacks, react/prefer-stateless-function, react/prop-types, react/no-multi-comp */
-import {
- expect
-} from 'chai';
-
-import React from 'react';
-import TestUtils from 'react-addons-test-utils';
-import shallowCompare from 'react-addons-shallow-compare';
-import jsdom from 'jsdom';
-import extendReactClass from './../src/extendReactClass';
-
-describe('extendReactClass', () => {
- beforeEach(() => {
- global.document = jsdom.jsdom('
');
-
- global.window = document.defaultView;
- });
- context('using default styles', () => {
- it('exposes styles through this.props.styles property', (done) => {
- let Component;
-
- const styles = {
- foo: 'foo-1'
- };
-
- Component = class extends React.Component {
- render () {
- expect(this.props.styles).to.equal(styles);
- done();
- }
- };
-
- Component = extendReactClass(Component, styles);
-
- TestUtils.renderIntoDocument();
- });
- it('does not affect the other instance properties', (done) => {
- let Component;
-
- Component = class extends React.Component {
- render () {
- expect(this.props.bar).to.equal('baz');
- done();
- }
- };
-
- const styles = {
- foo: 'foo-1'
- };
-
- Component = extendReactClass(Component, styles);
-
- TestUtils.renderIntoDocument();
- });
- it('does not affect pure-render logic', (done) => {
- let Component,
- rendered;
-
- rendered = false;
-
- const styles = {
- foo: 'foo-1'
- };
-
- Component = class extends React.Component {
- shouldComponentUpdate (newProps) {
- if (rendered) {
- expect(shallowCompare(this.props, newProps)).to.equal(true);
-
- done();
- }
-
- return true;
- }
-
- render () {
- rendered = true;
- }
- };
-
- Component = extendReactClass(Component, styles);
-
- const instance = TestUtils.renderIntoDocument();
-
- // trigger shouldComponentUpdate
- instance.setState({});
- });
- });
- context('overwriting default styles using "styles" property of the extended component', () => {
- it('overwrites default styles', (done) => {
- let Component;
-
- const styles = {
- foo: 'foo-1'
- };
-
- Component = class extends React.Component {
- render () {
- expect(this.props.styles).to.equal(styles);
- done();
- }
- };
-
- Component = extendReactClass(Component, {
- bar: 'bar-0',
- foo: 'foo-0'
- });
-
- TestUtils.renderIntoDocument();
- });
- });
- context('rendering Component that returns null', () => {
- it('generates