Lint and test addons on CI (#9936)

* Lint addons

* Run prettier on addons

* Fix all lint issues

* Remove unused variable

* Test addons on CI
This commit is contained in:
Dan Abramov
2017-06-12 21:26:56 +01:00
committed by GitHub
parent 61e8ee71b6
commit beb370c102
22 changed files with 442 additions and 239 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
# We can probably lint these later but not important at this point
addons/
addons/**/node_modules/
src/renderers/art
src/shared/vendor
# But not in docs/_js/examples/*
+195 -50
View File
@@ -43,7 +43,6 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
* Policies that describe methods in `ReactClassInterface`.
*/
var injectedMixins = [];
/**
@@ -69,7 +68,6 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
* @internal
*/
var ReactClassInterface = {
/**
* An array of Mixin objects to include when defining your component.
*
@@ -286,8 +284,7 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
* @internal
* @overridable
*/
updateComponent: 'OVERRIDE_BASE'
updateComponent: 'OVERRIDE_BASE',
};
/**
@@ -300,71 +297,106 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
* which all other static methods are defined.
*/
var RESERVED_SPEC_KEYS = {
displayName: function (Constructor, displayName) {
displayName: function(Constructor, displayName) {
Constructor.displayName = displayName;
},
mixins: function (Constructor, mixins) {
mixins: function(Constructor, mixins) {
if (mixins) {
for (var i = 0; i < mixins.length; i++) {
mixSpecIntoComponent(Constructor, mixins[i]);
}
}
},
childContextTypes: function (Constructor, childContextTypes) {
childContextTypes: function(Constructor, childContextTypes) {
if (process.env.NODE_ENV !== 'production') {
validateTypeDef(Constructor, childContextTypes, 'childContext');
}
Constructor.childContextTypes = _assign({}, Constructor.childContextTypes, childContextTypes);
Constructor.childContextTypes = _assign(
{},
Constructor.childContextTypes,
childContextTypes,
);
},
contextTypes: function (Constructor, contextTypes) {
contextTypes: function(Constructor, contextTypes) {
if (process.env.NODE_ENV !== 'production') {
validateTypeDef(Constructor, contextTypes, 'context');
}
Constructor.contextTypes = _assign({}, Constructor.contextTypes, contextTypes);
Constructor.contextTypes = _assign(
{},
Constructor.contextTypes,
contextTypes,
);
},
/**
* Special case getDefaultProps which should move into statics but requires
* automatic merging.
*/
getDefaultProps: function (Constructor, getDefaultProps) {
getDefaultProps: function(Constructor, getDefaultProps) {
if (Constructor.getDefaultProps) {
Constructor.getDefaultProps = createMergedResultFunction(Constructor.getDefaultProps, getDefaultProps);
Constructor.getDefaultProps = createMergedResultFunction(
Constructor.getDefaultProps,
getDefaultProps,
);
} else {
Constructor.getDefaultProps = getDefaultProps;
}
},
propTypes: function (Constructor, propTypes) {
propTypes: function(Constructor, propTypes) {
if (process.env.NODE_ENV !== 'production') {
validateTypeDef(Constructor, propTypes, 'prop');
}
Constructor.propTypes = _assign({}, Constructor.propTypes, propTypes);
},
statics: function (Constructor, statics) {
statics: function(Constructor, statics) {
mixStaticSpecIntoComponent(Constructor, statics);
},
autobind: function () {} };
autobind: function() {},
};
function validateTypeDef(Constructor, typeDef, location) {
for (var propName in typeDef) {
if (typeDef.hasOwnProperty(propName)) {
// use a warning instead of an _invariant so components
// don't show up in prod but only in __DEV__
process.env.NODE_ENV !== 'production' ? warning(typeof typeDef[propName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', Constructor.displayName || 'ReactClass', ReactPropTypeLocationNames[location], propName) : void 0;
if (process.env.NODE_ENV !== 'production') {
warning(
typeof typeDef[propName] === 'function',
'%s: %s type `%s` is invalid; it must be a function, usually from ' +
'React.PropTypes.',
Constructor.displayName || 'ReactClass',
ReactPropTypeLocationNames[location],
propName,
);
}
}
}
}
function validateMethodOverride(isAlreadyDefined, name) {
var specPolicy = ReactClassInterface.hasOwnProperty(name) ? ReactClassInterface[name] : null;
var specPolicy = ReactClassInterface.hasOwnProperty(name)
? ReactClassInterface[name]
: null;
// Disallow overriding of base class methods unless explicitly allowed.
if (ReactClassMixin.hasOwnProperty(name)) {
_invariant(specPolicy === 'OVERRIDE_BASE', 'ReactClassInterface: You are attempting to override ' + '`%s` from your class specification. Ensure that your method names ' + 'do not overlap with React methods.', name);
_invariant(
specPolicy === 'OVERRIDE_BASE',
'ReactClassInterface: You are attempting to override ' +
'`%s` from your class specification. Ensure that your method names ' +
'do not overlap with React methods.',
name,
);
}
// Disallow defining methods more than once unless explicitly allowed.
if (isAlreadyDefined) {
_invariant(specPolicy === 'DEFINE_MANY' || specPolicy === 'DEFINE_MANY_MERGED', 'ReactClassInterface: You are attempting to define ' + '`%s` on your component more than once. This conflict may be due ' + 'to a mixin.', name);
_invariant(
specPolicy === 'DEFINE_MANY' || specPolicy === 'DEFINE_MANY_MERGED',
'ReactClassInterface: You are attempting to define ' +
'`%s` on your component more than once. This conflict may be due ' +
'to a mixin.',
name,
);
}
}
@@ -378,14 +410,33 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
var typeofSpec = typeof spec;
var isMixinValid = typeofSpec === 'object' && spec !== null;
process.env.NODE_ENV !== 'production' ? warning(isMixinValid, '%s: You\'re attempting to include a mixin that is either null ' + 'or not an object. Check the mixins included by the component, ' + 'as well as any mixins they include themselves. ' + 'Expected object but got %s.', Constructor.displayName || 'ReactClass', spec === null ? null : typeofSpec) : void 0;
if (process.env.NODE_ENV !== 'production') {
warning(
isMixinValid,
"%s: You're attempting to include a mixin that is either null " +
'or not an object. Check the mixins included by the component, ' +
'as well as any mixins they include themselves. ' +
'Expected object but got %s.',
Constructor.displayName || 'ReactClass',
spec === null ? null : typeofSpec,
);
}
}
return;
}
_invariant(typeof spec !== 'function', 'ReactClass: You\'re attempting to ' + 'use a component class or function as a mixin. Instead, just use a ' + 'regular object.');
_invariant(!isValidElement(spec), 'ReactClass: You\'re attempting to ' + 'use a component as a mixin. Instead, just use a regular object.');
_invariant(
typeof spec !== 'function',
"ReactClass: You're attempting to " +
'use a component class or function as a mixin. Instead, just use a ' +
'regular object.',
);
_invariant(
!isValidElement(spec),
"ReactClass: You're attempting to " +
'use a component as a mixin. Instead, just use a regular object.',
);
var proto = Constructor.prototype;
var autoBindPairs = proto.__reactAutoBindPairs;
@@ -420,7 +471,11 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
// 2. Overridden methods (that were mixed in).
var isReactClassMethod = ReactClassInterface.hasOwnProperty(name);
var isFunction = typeof property === 'function';
var shouldAutoBind = isFunction && !isReactClassMethod && !isAlreadyDefined && spec.autobind !== false;
var shouldAutoBind =
isFunction &&
!isReactClassMethod &&
!isAlreadyDefined &&
spec.autobind !== false;
if (shouldAutoBind) {
autoBindPairs.push(name, property);
@@ -430,7 +485,15 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
var specPolicy = ReactClassInterface[name];
// These cases should already be caught by validateMethodOverride.
_invariant(isReactClassMethod && (specPolicy === 'DEFINE_MANY_MERGED' || specPolicy === 'DEFINE_MANY'), 'ReactClass: Unexpected spec policy %s for key %s ' + 'when mixing in component specs.', specPolicy, name);
_invariant(
isReactClassMethod &&
(specPolicy === 'DEFINE_MANY_MERGED' ||
specPolicy === 'DEFINE_MANY'),
'ReactClass: Unexpected spec policy %s for key %s ' +
'when mixing in component specs.',
specPolicy,
name,
);
// For methods which are defined more than once, call the existing
// methods before calling the new property, merging if appropriate.
@@ -465,10 +528,23 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
}
var isReserved = name in RESERVED_SPEC_KEYS;
_invariant(!isReserved, 'ReactClass: You are attempting to define a reserved ' + 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' + 'as an instance property instead; it will still be accessible on the ' + 'constructor.', name);
_invariant(
!isReserved,
'ReactClass: You are attempting to define a reserved ' +
'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' +
'as an instance property instead; it will still be accessible on the ' +
'constructor.',
name,
);
var isInherited = name in Constructor;
_invariant(!isInherited, 'ReactClass: You are attempting to define ' + '`%s` on your component more than once. This conflict may be ' + 'due to a mixin.', name);
_invariant(
!isInherited,
'ReactClass: You are attempting to define ' +
'`%s` on your component more than once. This conflict may be ' +
'due to a mixin.',
name,
);
Constructor[name] = property;
}
}
@@ -481,11 +557,22 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
* @return {object} one after it has been mutated to contain everything in two.
*/
function mergeIntoWithNoDuplicateKeys(one, two) {
_invariant(one && two && typeof one === 'object' && typeof two === 'object', 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.');
_invariant(
one && two && typeof one === 'object' && typeof two === 'object',
'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.',
);
for (var key in two) {
if (two.hasOwnProperty(key)) {
_invariant(one[key] === undefined, 'mergeIntoWithNoDuplicateKeys(): ' + 'Tried to merge two objects with the same key: `%s`. This conflict ' + 'may be due to a mixin; in particular, this may be caused by two ' + 'getInitialState() or getDefaultProps() methods returning objects ' + 'with clashing keys.', key);
_invariant(
one[key] === undefined,
'mergeIntoWithNoDuplicateKeys(): ' +
'Tried to merge two objects with the same key: `%s`. This conflict ' +
'may be due to a mixin; in particular, this may be caused by two ' +
'getInitialState() or getDefaultProps() methods returning objects ' +
'with clashing keys.',
key,
);
one[key] = two[key];
}
}
@@ -546,8 +633,14 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
boundMethod.__reactBoundArguments = null;
var componentName = component.constructor.displayName;
var _bind = boundMethod.bind;
boundMethod.bind = function (newThis) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
boundMethod.bind = function(newThis) {
for (
var _len = arguments.length,
args = Array(_len > 1 ? _len - 1 : 0),
_key = 1;
_key < _len;
_key++
) {
args[_key - 1] = arguments[_key];
}
@@ -555,9 +648,24 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
// ignore the value of "this" that the user is trying to use, so
// let's warn.
if (newThis !== component && newThis !== null) {
process.env.NODE_ENV !== 'production' ? warning(false, 'bind(): React component methods may only be bound to the ' + 'component instance. See %s', componentName) : void 0;
if (process.env.NODE_ENV !== 'production') {
warning(
false,
'bind(): React component methods may only be bound to the ' +
'component instance. See %s',
componentName,
);
}
} else if (!args.length) {
process.env.NODE_ENV !== 'production' ? warning(false, 'bind(): You are binding a component method to the component. ' + 'React does this for you automatically in a high-performance ' + 'way, so you can safely remove this call. See %s', componentName) : void 0;
if (process.env.NODE_ENV !== 'production') {
warning(
false,
'bind(): You are binding a component method to the component. ' +
'React does this for you automatically in a high-performance ' +
'way, so you can safely remove this call. See %s',
componentName,
);
}
return boundMethod;
}
var reboundMethod = _bind.apply(boundMethod, arguments);
@@ -585,15 +693,15 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
}
var IsMountedPreMixin = {
componentDidMount: function () {
componentDidMount: function() {
this.__isMounted = true;
}
},
};
var IsMountedPostMixin = {
componentWillUnmount: function () {
componentWillUnmount: function() {
this.__isMounted = false;
}
},
};
/**
@@ -601,12 +709,11 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
* therefore not already part of the modern ReactComponent.
*/
var ReactClassMixin = {
/**
* TODO: This will be deprecated because state should always keep a consistent
* type signature and the only use case for this, is to avoid that.
*/
replaceState: function (newState, callback) {
replaceState: function(newState, callback) {
this.updater.enqueueReplaceState(this, newState, callback);
},
@@ -616,17 +723,29 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
* @protected
* @final
*/
isMounted: function () {
isMounted: function() {
if (process.env.NODE_ENV !== 'production') {
process.env.NODE_ENV !== 'production' ? warning(this.__didWarnIsMounted, '%s: isMounted is deprecated. Instead, make sure to clean up ' + 'subscriptions and pending requests in componentWillUnmount to ' + 'prevent memory leaks.', this.constructor && this.constructor.displayName || this.name || 'Component') : void 0;
warning(
this.__didWarnIsMounted,
'%s: isMounted is deprecated. Instead, make sure to clean up ' +
'subscriptions and pending requests in componentWillUnmount to ' +
'prevent memory leaks.',
(this.constructor && this.constructor.displayName) ||
this.name ||
'Component',
);
this.__didWarnIsMounted = true;
}
return !!this.__isMounted;
}
},
};
var ReactClassComponent = function () {};
_assign(ReactClassComponent.prototype, ReactComponent.prototype, ReactClassMixin);
var ReactClassComponent = function() {};
_assign(
ReactClassComponent.prototype,
ReactComponent.prototype,
ReactClassMixin,
);
/**
* Creates a composite component class given a class specification.
@@ -640,12 +759,16 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
// To keep our warnings more understandable, we'll use a little hack here to
// ensure that Constructor.name !== 'Constructor'. This makes sure we don't
// unnecessarily identify a class without displayName as 'Constructor'.
var Constructor = identity(function (props, context, updater) {
var Constructor = identity(function(props, context, updater) {
// This constructor gets overridden by mocks. The argument is used
// by mocks to assert on what gets mounted.
if (process.env.NODE_ENV !== 'production') {
process.env.NODE_ENV !== 'production' ? warning(this instanceof Constructor, 'Something is calling a React component directly. Use a factory or ' + 'JSX instead. See: https://fb.me/react-legacyfactory') : void 0;
warning(
this instanceof Constructor,
'Something is calling a React component directly. Use a factory or ' +
'JSX instead. See: https://fb.me/react-legacyfactory',
);
}
// Wire up auto-binding
@@ -666,13 +789,20 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
var initialState = this.getInitialState ? this.getInitialState() : null;
if (process.env.NODE_ENV !== 'production') {
// We allow auto-mocks to proceed as if they're returning null.
if (initialState === undefined && this.getInitialState._isMockFunction) {
if (
initialState === undefined &&
this.getInitialState._isMockFunction
) {
// This is probably bad practice. Consider warning here and
// deprecating this convenience.
initialState = null;
}
}
_invariant(typeof initialState === 'object' && !Array.isArray(initialState), '%s.getInitialState(): must return an object or null', Constructor.displayName || 'ReactCompositeComponent');
_invariant(
typeof initialState === 'object' && !Array.isArray(initialState),
'%s.getInitialState(): must return an object or null',
Constructor.displayName || 'ReactCompositeComponent',
);
this.state = initialState;
});
@@ -704,11 +834,26 @@ function factory(ReactComponent, isValidElement, ReactNoopUpdateQueue) {
}
}
_invariant(Constructor.prototype.render, 'createClass(...): Class specification must implement a `render` method.');
_invariant(
Constructor.prototype.render,
'createClass(...): Class specification must implement a `render` method.',
);
if (process.env.NODE_ENV !== 'production') {
process.env.NODE_ENV !== 'production' ? warning(!Constructor.prototype.componentShouldUpdate, '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', spec.displayName || 'A component') : void 0;
process.env.NODE_ENV !== 'production' ? warning(!Constructor.prototype.componentWillRecieveProps, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', spec.displayName || 'A component') : void 0;
warning(
!Constructor.prototype.componentShouldUpdate,
'%s has a method called ' +
'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
'The name is phrased as a question because the function is ' +
'expected to return a value.',
spec.displayName || 'A component',
);
warning(
!Constructor.prototype.componentWillRecieveProps,
'%s has a method called ' +
'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?',
spec.displayName || 'A component',
);
}
// Reduce time spent doing lookups by setting these on the prototype.
+1 -1
View File
@@ -19,5 +19,5 @@ var ReactNoopUpdateQueue = new React.Component().updater;
module.exports = factory(
React.Component,
React.isValidElement,
ReactNoopUpdateQueue
ReactNoopUpdateQueue,
);
+34 -36
View File
@@ -23,7 +23,11 @@ global.requestAnimationFrame = function(callback) {
global.requestIdleCallback = function(callback) {
setTimeout(() => {
callback({ timeRemaining() { return Infinity; } });
callback({
timeRemaining() {
return Infinity;
},
});
});
};
@@ -39,7 +43,7 @@ describe('ReactClass-spec', () => {
expect(function() {
createReactClass({});
}).toThrowError(
'createClass(...): Class specification must implement a `render` method.'
'createClass(...): Class specification must implement a `render` method.',
);
});
@@ -51,8 +55,7 @@ describe('ReactClass-spec', () => {
},
});
expect(TestComponent.displayName)
.toBe('TestComponent');
expect(TestComponent.displayName).toBe('TestComponent');
});
it('should copy prop types onto the Constructor', () => {
@@ -67,8 +70,7 @@ describe('ReactClass-spec', () => {
});
expect(TestComponent.propTypes).toBeDefined();
expect(TestComponent.propTypes.value)
.toBe(propValidator);
expect(TestComponent.propTypes.value).toBe(propValidator);
});
it('should warn on invalid prop types', () => {
@@ -85,7 +87,7 @@ describe('ReactClass-spec', () => {
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toBe(
'Warning: Component: prop type `prop` is invalid; ' +
'it must be a function, usually from React.PropTypes.'
'it must be a function, usually from React.PropTypes.',
);
});
@@ -103,7 +105,7 @@ describe('ReactClass-spec', () => {
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toBe(
'Warning: Component: context type `prop` is invalid; ' +
'it must be a function, usually from React.PropTypes.'
'it must be a function, usually from React.PropTypes.',
);
});
@@ -121,7 +123,7 @@ describe('ReactClass-spec', () => {
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toBe(
'Warning: Component: child context type `prop` is invalid; ' +
'it must be a function, usually from React.PropTypes.'
'it must be a function, usually from React.PropTypes.',
);
});
@@ -139,8 +141,8 @@ describe('ReactClass-spec', () => {
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toBe(
'Warning: A component has a method called componentShouldUpdate(). Did you ' +
'mean shouldComponentUpdate()? The name is phrased as a question ' +
'because the function is expected to return a value.'
'mean shouldComponentUpdate()? The name is phrased as a question ' +
'because the function is expected to return a value.',
);
createReactClass({
@@ -155,8 +157,8 @@ describe('ReactClass-spec', () => {
expect(console.error.calls.count()).toBe(2);
expect(console.error.calls.argsFor(1)[0]).toBe(
'Warning: NamedComponent has a method called componentShouldUpdate(). Did you ' +
'mean shouldComponentUpdate()? The name is phrased as a question ' +
'because the function is expected to return a value.'
'mean shouldComponentUpdate()? The name is phrased as a question ' +
'because the function is expected to return a value.',
);
});
@@ -173,7 +175,7 @@ describe('ReactClass-spec', () => {
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toBe(
'Warning: A component has a method called componentWillRecieveProps(). Did you ' +
'mean componentWillReceiveProps()?'
'mean componentWillReceiveProps()?',
);
});
@@ -194,9 +196,9 @@ describe('ReactClass-spec', () => {
});
}).toThrowError(
'ReactClass: You are attempting to define a reserved property, ' +
'`getDefaultProps`, that shouldn\'t be on the "statics" key. Define ' +
'it as an instance property instead; it will still be accessible on ' +
'the constructor.'
'`getDefaultProps`, that shouldn\'t be on the "statics" key. Define ' +
'it as an instance property instead; it will still be accessible on ' +
'the constructor.',
);
});
@@ -221,19 +223,19 @@ describe('ReactClass-spec', () => {
expect(console.error.calls.count()).toBe(4);
expect(console.error.calls.argsFor(0)[0]).toBe(
'createClass(...): `mixins` is now a static property and should ' +
'be defined inside "statics".'
'be defined inside "statics".',
);
expect(console.error.calls.argsFor(1)[0]).toBe(
'createClass(...): `propTypes` is now a static property and should ' +
'be defined inside "statics".'
'be defined inside "statics".',
);
expect(console.error.calls.argsFor(2)[0]).toBe(
'createClass(...): `contextTypes` is now a static property and ' +
'should be defined inside "statics".'
'should be defined inside "statics".',
);
expect(console.error.calls.argsFor(3)[0]).toBe(
'createClass(...): `childContextTypes` is now a static property and ' +
'should be defined inside "statics".'
'should be defined inside "statics".',
);
});
@@ -329,7 +331,7 @@ describe('ReactClass-spec', () => {
expect(function() {
instance = ReactTestUtils.renderIntoDocument(instance);
}).toThrowError(
'Component.getInitialState(): must return an object or null'
'Component.getInitialState(): must return an object or null',
);
});
});
@@ -343,8 +345,8 @@ describe('ReactClass-spec', () => {
return <span />;
},
});
expect(
() => ReactTestUtils.renderIntoDocument(<Component />)
expect(() =>
ReactTestUtils.renderIntoDocument(<Component />),
).not.toThrow();
});
@@ -360,7 +362,7 @@ describe('ReactClass-spec', () => {
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toBe(
'Warning: Something is calling a React component directly. Use a ' +
'factory or JSX instead. See: https://fb.me/react-legacyfactory'
'factory or JSX instead. See: https://fb.me/react-legacyfactory',
);
});
@@ -368,23 +370,19 @@ describe('ReactClass-spec', () => {
var ops = [];
var Component = createReactClass({
getInitialState() {
return { step: 0 };
return {step: 0};
},
render() {
ops.push('Render: ' + this.state.step);
return <div />;
}
},
});
var instance = ReactTestUtils.renderIntoDocument(<Component />);
instance.replaceState({ step: 1 }, () => {
instance.replaceState({step: 1}, () => {
ops.push('Callback: ' + instance.state.step);
});
expect(ops).toEqual([
'Render: 0',
'Render: 1',
'Callback: 1',
]);
expect(ops).toEqual(['Render: 0', 'Render: 1', 'Callback: 1']);
});
it('isMounted works', () => {
@@ -439,7 +437,7 @@ describe('ReactClass-spec', () => {
instance = this;
this.log('render');
return <div />;
}
},
});
var container = document.createElement('div');
@@ -467,8 +465,8 @@ describe('ReactClass-spec', () => {
expect(console.error.calls.count()).toBe(1);
expect(console.error.calls.argsFor(0)[0]).toEqual(
'Warning: MyComponent: isMounted is deprecated. Instead, make sure to ' +
'clean up subscriptions and pending requests in componentWillUnmount ' +
'to prevent memory leaks.'
'clean up subscriptions and pending requests in componentWillUnmount ' +
'to prevent memory leaks.',
);
});
});
+31 -33
View File
@@ -11,9 +11,8 @@
var React = require('react');
var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' &&
Symbol.for &&
Symbol.for('react.element')) ||
var REACT_ELEMENT_TYPE =
(typeof Symbol === 'function' && Symbol.for && Symbol.for('react.element')) ||
0xeac7;
var emptyFunction = require('fbjs/lib/emptyFunction');
@@ -29,7 +28,10 @@ var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.
function getIteratorFn(maybeIterable) {
var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);
var iteratorFn =
maybeIterable &&
((ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL]) ||
maybeIterable[FAUX_ITERATOR_SYMBOL]);
if (typeof iteratorFn === 'function') {
return iteratorFn;
}
@@ -39,7 +41,7 @@ function escape(key) {
var escapeRegex = /[=:]/g;
var escaperLookup = {
'=': '=0',
':': '=2'
':': '=2',
};
var escapedString = ('' + key).replace(escapeRegex, function(match) {
return escaperLookup[match];
@@ -63,7 +65,7 @@ function traverseAllChildrenImpl(
children,
nameSoFar,
callback,
traverseContext
traverseContext,
) {
var type = typeof children;
@@ -85,7 +87,7 @@ function traverseAllChildrenImpl(
children,
// If it's the only child, treat the name as if it was wrapped in an array
// so that it's consistent if the number of children grows.
nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar
nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar,
);
return 1;
}
@@ -103,20 +105,20 @@ function traverseAllChildrenImpl(
child,
nextName,
callback,
traverseContext
traverseContext,
);
}
} else {
var iteratorFn = getIteratorFn(children);
if (iteratorFn) {
if (process.env.NODE_ENV !== "production") {
if (process.env.NODE_ENV !== 'production') {
// Warn about using Maps as children
if (iteratorFn === children.entries) {
warning(
didWarnAboutMaps,
'Using Maps as children is unsupported and will likely yield ' +
'unexpected results. Convert it to a sequence/iterable of keyed ' +
'ReactElements instead.'
'ReactElements instead.',
);
didWarnAboutMaps = true;
}
@@ -132,13 +134,14 @@ function traverseAllChildrenImpl(
child,
nextName,
callback,
traverseContext
traverseContext,
);
}
} else if (type === 'object') {
var addendum = '';
if (process.env.NODE_ENV !== "production") {
addendum = ' If you meant to render a collection of children, use an array ' +
if (process.env.NODE_ENV !== 'production') {
addendum =
' If you meant to render a collection of children, use an array ' +
'instead or wrap the object using createFragment(object) from the ' +
'React add-ons.';
}
@@ -149,7 +152,7 @@ function traverseAllChildrenImpl(
childrenString === '[object Object]'
? 'object with keys {' + Object.keys(children).join(', ') + '}'
: childrenString,
addendum
addendum,
);
}
}
@@ -173,12 +176,10 @@ function escapeUserProvidedKey(text) {
function cloneAndReplaceKey(oldElement, newKey) {
return React.cloneElement(
oldElement,
{ key: newKey },
oldElement.props !== undefined
? oldElement.props.children
: undefined
{key: newKey},
oldElement.props !== undefined ? oldElement.props.children : undefined,
);
};
}
var DEFAULT_POOL_SIZE = 10;
var DEFAULT_POOLER = oneArgumentPooler;
@@ -194,10 +195,7 @@ var oneArgumentPooler = function(copyFieldsFrom) {
}
};
var addPoolingTo = function addPoolingTo(
CopyConstructor,
pooler
) {
var addPoolingTo = function addPoolingTo(CopyConstructor, pooler) {
// Casting as any so that flow ignores the actual implementation and trusts
// it to match the type we declared
var NewKlass = CopyConstructor;
@@ -214,7 +212,7 @@ var standardReleaser = function standardReleaser(instance) {
var Klass = this;
invariant(
instance instanceof Klass,
'Trying to release an instance into a pool of a different type.'
'Trying to release an instance into a pool of a different type.',
);
instance.destructor();
if (Klass.instancePool.length < Klass.poolSize) {
@@ -261,7 +259,7 @@ function mapSingleChildIntoContext(bookKeeping, child, childKey) {
mappedChild,
result,
childKey,
emptyFunction.thatReturnsArgument
emptyFunction.thatReturnsArgument,
);
} else if (mappedChild != null) {
if (React.isValidElement(mappedChild)) {
@@ -273,7 +271,7 @@ function mapSingleChildIntoContext(bookKeeping, child, childKey) {
(mappedChild.key && (!child || child.key !== mappedChild.key)
? escapeUserProvidedKey(mappedChild.key) + '/'
: '') +
childKey
childKey,
);
}
result.push(mappedChild);
@@ -289,7 +287,7 @@ function mapIntoWithKeyPrefixInternal(children, array, prefix, func, context) {
array,
escapedPrefix,
func,
context
context,
);
traverseAllChildren(children, mapSingleChildIntoContext, traverseContext);
MapBookKeeping.release(traverseContext);
@@ -304,7 +302,7 @@ function createReactFragment(object) {
warning(
false,
'React.addons.createFragment only accepts a single object. Got: %s',
object
object,
);
return object;
}
@@ -312,7 +310,7 @@ function createReactFragment(object) {
warning(
false,
'React.addons.createFragment does not accept a ReactElement ' +
'without a wrapper object.'
'without a wrapper object.',
);
return object;
}
@@ -320,18 +318,18 @@ function createReactFragment(object) {
invariant(
object.nodeType !== 1,
'React.addons.createFragment(...): Encountered an invalid child; DOM ' +
'elements are not valid children of React components.'
'elements are not valid children of React components.',
);
var result = [];
for (var key in object) {
if (process.env.NODE_ENV !== "production") {
if (process.env.NODE_ENV !== 'production') {
if (!warnedAboutNumeric && numericPropertyRegex.test(key)) {
warning(
false,
'React.addons.createFragment(...): Child objects should have ' +
'non-numeric keys so ordering is preserved.'
'non-numeric keys so ordering is preserved.',
);
warnedAboutNumeric = true;
}
@@ -340,7 +338,7 @@ function createReactFragment(object) {
object[key],
result,
key,
emptyFunction.thatReturnsArgument
emptyFunction.thatReturnsArgument,
);
}
+10 -11
View File
@@ -12,7 +12,6 @@
'use strict';
var React;
var ReactDOM;
var createReactFragment;
// For testing DOM Fiber.
@@ -22,34 +21,34 @@ global.requestAnimationFrame = function(callback) {
global.requestIdleCallback = function(callback) {
setTimeout(() => {
callback({ timeRemaining() { return Infinity; } });
callback({
timeRemaining() {
return Infinity;
},
});
});
};
const expectDev = function expectDev(actual) {
const expectation = expect(actual);
if (global.__suppressDevFailures) {
Object.keys(expectation).forEach((name) => {
wrapDevMatcher(expectation, name);
wrapDevMatcher(expectation.not, name);
});
}
return expectation;
};
describe('createReactFragment', () => {
beforeEach(() => {
jest.resetModules()
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
createReactFragment = require('./index');
});
it('warns for numeric keys on objects as children', () => {
spyOn(console, 'error');
createReactFragment({1: React.createElement('span'), 2: React.createElement('span')});
createReactFragment({
1: React.createElement('span'),
2: React.createElement('span'),
});
expectDev(console.error.calls.count()).toBe(1);
expectDev(console.error.calls.argsFor(0)[0]).toContain(
+1 -1
View File
@@ -1 +1 @@
module.exports = require('react/lib/ReactCSSTransitionGroup');
module.exports = require('react/lib/ReactCSSTransitionGroup');
+1 -1
View File
@@ -150,7 +150,7 @@ var LinkedStateMixin = {
linkState: function(key) {
return new ReactLink(
this.state[key],
ReactStateSetters.createStateKeySetter(this, key)
ReactStateSetters.createStateKeySetter(this, key),
);
},
};
+13 -7
View File
@@ -23,13 +23,17 @@ global.requestAnimationFrame = function(callback) {
global.requestIdleCallback = function(callback) {
setTimeout(() => {
callback({ timeRemaining() { return Infinity; } });
callback({
timeRemaining() {
return Infinity;
},
});
});
};
describe('LinkedStateMixin', () => {
beforeEach(() => {
jest.resetModules()
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
@@ -48,11 +52,11 @@ describe('LinkedStateMixin', () => {
},
render: function() {
return <input type="text" valueLink={this.linkState('message')} />;
}
},
});
const instance = ReactTestUtils.renderIntoDocument(
React.createElement(WithLink)
React.createElement(WithLink),
);
expect(instance.state.message).toBe('Hello!');
@@ -76,12 +80,14 @@ describe('LinkedStateMixin', () => {
var handleChange = function(e) {
valueLink.requestChange(e.target.value);
};
return <input type="text" value={valueLink.value} onChange={handleChange} />;
}
return (
<input type="text" value={valueLink.value} onChange={handleChange} />
);
},
});
const instance = ReactTestUtils.renderIntoDocument(
React.createElement(WithoutLink)
React.createElement(WithoutLink),
);
expect(instance.state.message).toBe('Hello!');
+12 -22
View File
@@ -22,26 +22,18 @@ global.requestAnimationFrame = function(callback) {
global.requestIdleCallback = function(callback) {
setTimeout(() => {
callback({ timeRemaining() { return Infinity; } });
});
};
const expectDev = function expectDev(actual) {
const expectation = expect(actual);
if (global.__suppressDevFailures) {
Object.keys(expectation).forEach((name) => {
wrapDevMatcher(expectation, name);
wrapDevMatcher(expectation.not, name);
callback({
timeRemaining() {
return Infinity;
},
});
}
return expectation;
});
};
describe('createReactFragment', () => {
beforeEach(() => {
React = require('react');
ReactComponentWithPureRenderMixin =
require('./index');
ReactComponentWithPureRenderMixin = require('./index');
ReactTestUtils = require('react-addons-test-utils');
});
@@ -56,12 +48,10 @@ describe('createReactFragment', () => {
}
render() {
return (
React.createElement(Apple, {
color: this.state.color,
ref: "apple"
})
);
return React.createElement(Apple, {
color: this.state.color,
ref: 'apple',
});
}
}
@@ -95,7 +85,7 @@ describe('createReactFragment', () => {
});
var instance = ReactTestUtils.renderIntoDocument(
React.createElement(PlasticWrap)
React.createElement(PlasticWrap),
);
expect(renderCalls).toBe(1);
@@ -145,7 +135,7 @@ describe('createReactFragment', () => {
});
var instance = ReactTestUtils.renderIntoDocument(
React.createElement(Component)
React.createElement(Component),
);
expect(renderCalls).toBe(1);
+24 -7
View File
@@ -23,7 +23,11 @@ global.requestAnimationFrame = function(callback) {
global.requestIdleCallback = function(callback) {
setTimeout(() => {
callback({ timeRemaining() { return Infinity; } });
callback({
timeRemaining() {
return Infinity;
},
});
});
};
@@ -57,17 +61,26 @@ describe('shallowCompare', () => {
var component;
text = ['porcini'];
component = ReactDOM.render(React.createElement(Component, { text }), container);
component = ReactDOM.render(
React.createElement(Component, {text}),
container,
);
expect(container.textContent).toBe('porcini');
expect(renders).toBe(1);
text = ['morel'];
component = ReactDOM.render(React.createElement(Component, { text }), container);
component = ReactDOM.render(
React.createElement(Component, {text}),
container,
);
expect(container.textContent).toBe('morel');
expect(renders).toBe(2);
text[0] = 'portobello';
component = ReactDOM.render(React.createElement(Component, { text }), container);
component = ReactDOM.render(
React.createElement(Component, {text}),
container,
);
expect(container.textContent).toBe('morel');
expect(renders).toBe(2);
@@ -116,7 +129,7 @@ describe('shallowCompare', () => {
render() {
return React.createElement(Apple, {
color: this.state.color,
ref: 'apple'
ref: 'apple',
});
}
}
@@ -152,7 +165,9 @@ describe('shallowCompare', () => {
},
});
var instance = ReactTestUtils.renderIntoDocument(React.createElement(PlasticWrap));
var instance = ReactTestUtils.renderIntoDocument(
React.createElement(PlasticWrap),
);
expect(renderCalls).toBe(1);
// Do not re-render based on props
@@ -202,7 +217,9 @@ describe('shallowCompare', () => {
},
});
var instance = ReactTestUtils.renderIntoDocument(React.createElement(Component));
var instance = ReactTestUtils.renderIntoDocument(
React.createElement(Component),
);
expect(renderCalls).toBe(1);
// Do not re-render if state is equal
+1 -1
View File
@@ -17,7 +17,7 @@ var warning = require('fbjs/lib/warning');
warning(
false,
'ReactTestUtils has been moved to react-dom/test-utils. ' +
'Update references to remove this warning.'
'Update references to remove this warning.',
);
module.exports = require('react-dom/lib/ReactTestUtils');
+3 -6
View File
@@ -12,20 +12,17 @@
'use strict';
describe('ReactTestUtils', function() {
let ReactTestUtils;
let React;
beforeEach(function() {
spyOn(console, 'error');
React = require('react');
ReactTestUtils = require('./index');
});
it('should warn on include', function() {
expect(console.error).toHaveBeenCalledWith(
'Warning: ReactTestUtils has been moved to react-dom/test-utils. ' +
'Update references to remove this warning.'
'Update references to remove this warning.',
);
});
@@ -36,7 +33,7 @@ describe('ReactTestUtils', function() {
class MyComponent extends React.Component {
constructor(props, context) {
super(props, context);
this.state = { bar: 123 };
this.state = {bar: 123};
}
render() {
return <div onClick={onClick}>{this.props.baz}</div>;
@@ -44,7 +41,7 @@ describe('ReactTestUtils', function() {
}
const instance = ReactTestUtils.renderIntoDocument(
<MyComponent baz='abc' />
<MyComponent baz="abc" />,
);
expect(instance.state.bar).toBe(123);
+1 -1
View File
@@ -1 +1 @@
module.exports = require('react/lib/ReactTransitionGroup');
module.exports = require('react/lib/ReactTransitionGroup');
+16 -16
View File
@@ -50,15 +50,15 @@ function invariantArrayCase(value, spec, command) {
Array.isArray(value),
'update(): expected target of %s to be an array; got %s.',
command,
value
value,
);
var specValue = spec[command];
invariant(
Array.isArray(specValue),
'update(): expected spec of %s to be an array; got %s. ' +
'Did you forget to wrap your parameter in an array?',
'Did you forget to wrap your parameter in an array?',
command,
specValue
specValue,
);
}
@@ -70,16 +70,16 @@ function update(value, spec) {
invariant(
typeof spec === 'object',
'update(): You provided a key path to update() that did not contain one ' +
'of %s. Did you forget to include {%s: ...}?',
'of %s. Did you forget to include {%s: ...}?',
ALL_COMMANDS_LIST.join(', '),
COMMAND_SET
COMMAND_SET,
);
if (hasOwnProperty.call(spec, COMMAND_SET)) {
invariant(
Object.keys(spec).length === 1,
'Cannot have more than one key in an object with %s',
COMMAND_SET
COMMAND_SET,
);
return spec[COMMAND_SET];
@@ -91,15 +91,15 @@ function update(value, spec) {
var mergeObj = spec[COMMAND_MERGE];
invariant(
mergeObj && typeof mergeObj === 'object',
'update(): %s expects a spec of type \'object\'; got %s',
"update(): %s expects a spec of type 'object'; got %s",
COMMAND_MERGE,
mergeObj
mergeObj,
);
invariant(
nextValue && typeof nextValue === 'object',
'update(): %s expects a target of type \'object\'; got %s',
"update(): %s expects a target of type 'object'; got %s",
COMMAND_MERGE,
nextValue
nextValue,
);
_assign(nextValue, spec[COMMAND_MERGE]);
}
@@ -123,22 +123,22 @@ function update(value, spec) {
Array.isArray(value),
'Expected %s target to be an array; got %s',
COMMAND_SPLICE,
value
value,
);
invariant(
Array.isArray(spec[COMMAND_SPLICE]),
'update(): expected spec of %s to be an array of arrays; got %s. ' +
'Did you forget to wrap your parameters in an array?',
'Did you forget to wrap your parameters in an array?',
COMMAND_SPLICE,
spec[COMMAND_SPLICE]
spec[COMMAND_SPLICE],
);
spec[COMMAND_SPLICE].forEach(function(args) {
invariant(
Array.isArray(args),
'update(): expected spec of %s to be an array of arrays; got %s. ' +
'Did you forget to wrap your parameters in an array?',
'Did you forget to wrap your parameters in an array?',
COMMAND_SPLICE,
spec[COMMAND_SPLICE]
spec[COMMAND_SPLICE],
);
nextValue.splice.apply(nextValue, args);
});
@@ -149,7 +149,7 @@ function update(value, spec) {
typeof spec[COMMAND_APPLY] === 'function',
'update(): expected spec of %s to be a function; got %s.',
COMMAND_APPLY,
spec[COMMAND_APPLY]
spec[COMMAND_APPLY],
);
nextValue = spec[COMMAND_APPLY](nextValue);
}
+10 -2
View File
@@ -28,7 +28,9 @@ describe('update', () => {
it('should support nested collections', () => {
const collection = [1, 2, {a: [12, 17, 15]}];
const newCollection = update(collection, {2: {a: {$splice: [[1, 1, 13, 14]]}}});
const newCollection = update(collection, {
2: {a: {$splice: [[1, 1, 13, 14]]}},
});
expect(collection).toEqual([1, 2, {a: [12, 17, 15]}]);
expect(newCollection).toEqual([1, 2, {a: [12, 13, 14, 15]}]);
@@ -38,7 +40,13 @@ describe('update', () => {
it('should support updating a value based on its current one', () => {
const obj = {a: 5, b: 3};
const newObj = update(obj, {b: {$apply: function(x) {return x * 2;}}});
const newObj = update(obj, {
b: {
$apply: function(x) {
return x * 2;
},
},
});
expect(newObj).toEqual({a: 5, b: 6});
const newObj2 = update(obj, {b: {$set: obj.b * 2}});
+46 -33
View File
@@ -11,25 +11,13 @@
var React = require('react');
var emptyFunction = require('fbjs/lib/emptyFunction');
var invariant = require('fbjs/lib/invariant');
var warning = require('fbjs/lib/warning');
var hasReadOnlyValue = {
'button': true,
'checkbox': true,
'image': true,
'hidden': true,
'radio': true,
'reset': true,
'submit': true,
};
function _assertSingleLink(inputProps) {
invariant(
inputProps.checkedLink == null || inputProps.valueLink == null,
'Cannot provide a checkedLink and a valueLink. If you want to use ' +
'checkedLink, you probably don\'t want to use valueLink and vice versa.'
"checkedLink, you probably don't want to use valueLink and vice versa.",
);
}
function _assertValueLink(inputProps) {
@@ -37,7 +25,7 @@ function _assertValueLink(inputProps) {
invariant(
inputProps.value == null && inputProps.onChange == null,
'Cannot provide a valueLink and a value or onChange event. If you want ' +
'to use value or onChange, you probably don\'t want to use valueLink.'
"to use value or onChange, you probably don't want to use valueLink.",
);
}
@@ -46,22 +34,11 @@ function _assertCheckedLink(inputProps) {
invariant(
inputProps.checked == null && inputProps.onChange == null,
'Cannot provide a checkedLink and a checked property or onChange event. ' +
'If you want to use checked or onChange, you probably don\'t want to ' +
'use checkedLink'
"If you want to use checked or onChange, you probably don't want to " +
'use checkedLink',
);
}
var loggedTypeFailures = {};
function getDeclarationErrorAddendum(owner) {
if (owner) {
var name = owner.getName();
if (name) {
return ' Check the render method of `' + name + '`.';
}
}
return '';
}
/**
* Provide a linked `value` attribute for controlled forms. You should not use
* this outside of the ReactDOM controlled form components.
@@ -109,13 +86,49 @@ var LinkedValueUtils = {
},
};
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError('Cannot call a class as a function');
}
}
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _possibleConstructorReturn(self, call) {
if (!self) {
throw new ReferenceError(
"this hasn't been initialised - super() hasn't been called",
);
}
return call && (typeof call === 'object' || typeof call === 'function')
? call
: self;
}
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _inherits(subClass, superClass) {
if (typeof superClass !== 'function' && superClass !== null) {
throw new TypeError(
'Super expression must either be null or a function, not ' +
typeof superClass,
);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true,
},
});
if (superClass) {
if (Object.setPrototypeOf) {
Object.setPrototypeOf(subClass, superClass);
} else {
// eslint-disable-next-line no-proto
subClass.__proto__ = superClass;
}
}
}
var LinkedInput = function (_React$Component) {
var LI = (function(_React$Component) {
_inherits(LinkedInput, _React$Component);
function LinkedInput() {
@@ -142,6 +155,6 @@ var LinkedInput = function (_React$Component) {
};
return LinkedInput;
}(React.Component);
})(React.Component);
module.exports = LinkedInput;
module.exports = LI;
+12 -8
View File
@@ -18,7 +18,11 @@ global.requestAnimationFrame = function(callback) {
global.requestIdleCallback = function(callback) {
setTimeout(() => {
callback({ timeRemaining() { return Infinity; } });
callback({
timeRemaining() {
return Infinity;
},
});
});
};
@@ -42,19 +46,19 @@ describe('LinkedStateMixin', function() {
const container = document.createElement('div');
const component = ReactDOM.render(
React.createElement(LinkedInput, {
value: "foo",
onChange: noop
value: 'foo',
onChange: noop,
}),
container
container,
);
const input = ReactDOM.findDOMNode(component);
expect(input.value).toBe('foo');
ReactDOM.render(
React.createElement(LinkedInput, {
valueLink: {value: 'boo'},
requestChange: noop
requestChange: noop,
}),
container
container,
);
expect(input.value).toBe('boo');
});
@@ -65,8 +69,8 @@ describe('LinkedStateMixin', function() {
value: 'foo',
valueLink: {
value: 'boo',
requestChange: noop
}
requestChange: noop,
},
});
expect(function() {
ReactDOM.render(element, container);
+23
View File
@@ -0,0 +1,23 @@
var fs = require('fs');
var path = require('path');
var spawnSync = require('child_process').spawnSync;
fs
.readdirSync(__dirname)
.filter(file => {
return fs.statSync(path.join(__dirname, file)).isDirectory();
})
.forEach(dir => {
spawnSync('npm', ['install'], {
cwd: path.join(__dirname, dir),
stdio: 'inherit',
});
const result = spawnSync('npm', ['test'], {
cwd: path.join(__dirname, dir),
stdio: 'inherit',
});
if (result.status !== 0) {
process.exit('npm test exited with non-zero code.');
}
// TODO: also test that build succeeds
});
+1
View File
@@ -28,6 +28,7 @@ if [ $((0 % CIRCLE_NODE_TOTAL)) -eq "$CIRCLE_NODE_INDEX" ]; then
COMMANDS_TO_RUN+=('./node_modules/.bin/grunt build')
COMMANDS_TO_RUN+=('./scripts/circleci/test_extract_errors.sh')
COMMANDS_TO_RUN+=('./scripts/circleci/track_stats.sh')
COMMANDS_TO_RUN+=('node ./addons/test')
fi
RETURN_CODES=()
+6
View File
@@ -34,6 +34,12 @@ const config = {
'**/node_modules/**',
],
},
addons: {
patterns: ['addons/**/*.js'],
ignore: [
'**/node_modules/**',
],
},
};
function exec(command, args) {
-2
View File
@@ -34,8 +34,6 @@
* consumption of ReactLink easier; see LinkedValueUtils and LinkedStateMixin.
*/
var React = require('React');
/**
* Deprecated: An an easy way to express two-way binding with React.
* See https://facebook.github.io/react/docs/two-way-binding-helpers.html