mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Add feature flag around React.createFactory (#17873)
This commit is contained in:
+7
-3
@@ -13,6 +13,8 @@ let React;
|
||||
let ReactDOM;
|
||||
let ReactIs;
|
||||
|
||||
const ReactFeatureFlags = require('shared/ReactFeatureFlags');
|
||||
|
||||
describe('ReactIs', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
@@ -54,9 +56,11 @@ describe('ReactIs', () => {
|
||||
expect(ReactIs.isValidElementType(MemoComponent)).toEqual(true);
|
||||
expect(ReactIs.isValidElementType(Context.Provider)).toEqual(true);
|
||||
expect(ReactIs.isValidElementType(Context.Consumer)).toEqual(true);
|
||||
expect(ReactIs.isValidElementType(React.createFactory('div'))).toEqual(
|
||||
true,
|
||||
);
|
||||
if (!ReactFeatureFlags.disableCreateFactory) {
|
||||
expect(ReactIs.isValidElementType(React.createFactory('div'))).toEqual(
|
||||
true,
|
||||
);
|
||||
}
|
||||
expect(ReactIs.isValidElementType(React.Fragment)).toEqual(true);
|
||||
expect(ReactIs.isValidElementType(React.StrictMode)).toEqual(true);
|
||||
expect(ReactIs.isValidElementType(React.Suspense)).toEqual(true);
|
||||
|
||||
@@ -64,6 +64,7 @@ import {
|
||||
enableScopeAPI,
|
||||
exposeConcurrentModeAPIs,
|
||||
enableChunksAPI,
|
||||
disableCreateFactory,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
const React = {
|
||||
Children: {
|
||||
@@ -101,7 +102,6 @@ const React = {
|
||||
|
||||
createElement: __DEV__ ? createElementWithValidation : createElement,
|
||||
cloneElement: __DEV__ ? cloneElementWithValidation : cloneElement,
|
||||
createFactory: __DEV__ ? createFactoryWithValidation : createFactory,
|
||||
isValidElement: isValidElement,
|
||||
|
||||
version: ReactVersion,
|
||||
@@ -109,6 +109,10 @@ const React = {
|
||||
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: ReactSharedInternals,
|
||||
};
|
||||
|
||||
if (!disableCreateFactory) {
|
||||
React.createFactory = __DEV__ ? createFactoryWithValidation : createFactory;
|
||||
}
|
||||
|
||||
if (exposeConcurrentModeAPIs) {
|
||||
React.useTransition = useTransition;
|
||||
React.useDeferredValue = useDeferredValue;
|
||||
|
||||
@@ -10,10 +10,8 @@ ReactDOM = null
|
||||
PropTypes = null
|
||||
|
||||
describe 'ReactCoffeeScriptClass', ->
|
||||
div = null
|
||||
span = null
|
||||
container = null
|
||||
Inner = null
|
||||
InnerComponent = null
|
||||
attachedListener = null;
|
||||
renderedName = null;
|
||||
|
||||
@@ -24,15 +22,12 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
container = document.createElement 'div'
|
||||
attachedListener = null
|
||||
renderedName = null
|
||||
div = React.createFactory 'div'
|
||||
span = React.createFactory 'span'
|
||||
class InnerComponent extends React.Component
|
||||
InnerComponent = class extends React.Component
|
||||
getName: -> this.props.name
|
||||
render: ->
|
||||
attachedListener = this.props.onClick
|
||||
renderedName = this.props.name
|
||||
return div className: this.props.name
|
||||
Inner = React.createFactory InnerComponent
|
||||
return React.createElement('div', className: this.props.name)
|
||||
|
||||
test = (element, expectedTag, expectedClassName) ->
|
||||
instance = ReactDOM.render(element, container)
|
||||
@@ -61,8 +56,9 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
it 'renders a simple stateless component with prop', ->
|
||||
class Foo extends React.Component
|
||||
render: ->
|
||||
Inner
|
||||
React.createElement(InnerComponent,
|
||||
name: @props.bar
|
||||
)
|
||||
|
||||
test React.createElement(Foo, bar: 'foo'), 'DIV', 'foo'
|
||||
test React.createElement(Foo, bar: 'bar'), 'DIV', 'bar'
|
||||
@@ -75,8 +71,9 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
@state = bar: @props.initialValue
|
||||
|
||||
render: ->
|
||||
span
|
||||
React.createElement('span',
|
||||
className: @state.bar
|
||||
)
|
||||
|
||||
test React.createElement(Foo, initialValue: 'foo'), 'SPAN', 'foo'
|
||||
undefined
|
||||
@@ -91,11 +88,12 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
|
||||
render: ->
|
||||
if @state.bar is 'foo'
|
||||
return div(
|
||||
return React.createElement('div',
|
||||
className: 'foo'
|
||||
)
|
||||
span
|
||||
React.createElement('span',
|
||||
className: @state.bar
|
||||
)
|
||||
|
||||
instance = test React.createElement(Foo, initialValue: 'foo'), 'DIV', 'foo'
|
||||
instance.changeState()
|
||||
@@ -108,8 +106,9 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
super props
|
||||
@state = foo: null
|
||||
render: ->
|
||||
div
|
||||
React.createElement('div',
|
||||
className: "#{@state.foo} #{@state.bar}"
|
||||
)
|
||||
Foo.getDerivedStateFromProps = (nextProps, prevState) ->
|
||||
{
|
||||
foo: nextProps.foo
|
||||
@@ -121,7 +120,7 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
it 'warns if getDerivedStateFromProps is not static', ->
|
||||
class Foo extends React.Component
|
||||
render: ->
|
||||
div()
|
||||
React.createElement('div')
|
||||
getDerivedStateFromProps: ->
|
||||
{}
|
||||
expect(->
|
||||
@@ -132,7 +131,7 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
it 'warns if getDerivedStateFromError is not static', ->
|
||||
class Foo extends React.Component
|
||||
render: ->
|
||||
div()
|
||||
React.createElement('div')
|
||||
getDerivedStateFromError: ->
|
||||
{}
|
||||
expect(->
|
||||
@@ -143,7 +142,7 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
it 'warns if getSnapshotBeforeUpdate is static', ->
|
||||
class Foo extends React.Component
|
||||
render: ->
|
||||
div()
|
||||
React.createElement('div')
|
||||
Foo.getSnapshotBeforeUpdate = () ->
|
||||
{}
|
||||
expect(->
|
||||
@@ -154,8 +153,9 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
it 'warns if state not initialized before static getDerivedStateFromProps', ->
|
||||
class Foo extends React.Component
|
||||
render: ->
|
||||
div
|
||||
React.createElement('div',
|
||||
className: "#{@state.foo} #{@state.bar}"
|
||||
)
|
||||
Foo.getDerivedStateFromProps = (nextProps, prevState) ->
|
||||
{
|
||||
foo: nextProps.foo
|
||||
@@ -179,8 +179,9 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
foo: 'foo'
|
||||
bar: 'bar'
|
||||
render: ->
|
||||
div
|
||||
React.createElement('div',
|
||||
className: "#{@state.foo} #{@state.bar}"
|
||||
)
|
||||
Foo.getDerivedStateFromProps = (nextProps, prevState) ->
|
||||
{
|
||||
foo: "not-#{prevState.foo}"
|
||||
@@ -195,8 +196,9 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
@state =
|
||||
value: 'initial'
|
||||
render: ->
|
||||
div
|
||||
React.createElement('div',
|
||||
className: @state.value
|
||||
)
|
||||
Foo.getDerivedStateFromProps = (nextProps, prevState) ->
|
||||
if nextProps.update
|
||||
return {
|
||||
@@ -250,7 +252,7 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
|
||||
render: ->
|
||||
renderCount++
|
||||
span className: @state.bar
|
||||
React.createElement('span', className: @state.bar)
|
||||
|
||||
test React.createElement(Foo, initialValue: 'foo'), 'SPAN', 'bar'
|
||||
expect(renderCount).toBe 1
|
||||
@@ -263,7 +265,7 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
@state = state
|
||||
|
||||
render: ->
|
||||
span()
|
||||
React.createElement('span')
|
||||
|
||||
expect(->
|
||||
test React.createElement(Foo), 'SPAN', ''
|
||||
@@ -276,7 +278,7 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
@state = null
|
||||
|
||||
render: ->
|
||||
span()
|
||||
React.createElement('span')
|
||||
|
||||
test React.createElement(Foo), 'SPAN', ''
|
||||
undefined
|
||||
@@ -290,9 +292,10 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
@setState bar: 'bar'
|
||||
|
||||
render: ->
|
||||
Inner
|
||||
React.createElement(InnerComponent,
|
||||
name: @state.bar
|
||||
onClick: @handleClick
|
||||
)
|
||||
|
||||
test React.createElement(Foo, initialValue: 'foo'), 'DIV', 'foo'
|
||||
attachedListener()
|
||||
@@ -308,9 +311,10 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
@setState bar: 'bar'
|
||||
|
||||
render: ->
|
||||
Inner
|
||||
React.createElement(InnerComponent,
|
||||
name: @state.bar
|
||||
onClick: @handleClick
|
||||
)
|
||||
|
||||
test React.createElement(Foo, initialValue: 'foo'), 'DIV', 'foo'
|
||||
expect(attachedListener).toThrow()
|
||||
@@ -326,9 +330,10 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
@forceUpdate()
|
||||
|
||||
render: ->
|
||||
Inner
|
||||
React.createElement(InnerComponent,
|
||||
name: @mutativeValue
|
||||
onClick: @handleClick
|
||||
)
|
||||
|
||||
test React.createElement(Foo, initialValue: 'foo'), 'DIV', 'foo'
|
||||
attachedListener()
|
||||
@@ -364,8 +369,9 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
lifeCycles.push 'will-unmount'
|
||||
|
||||
render: ->
|
||||
span
|
||||
React.createElement('span',
|
||||
className: @props.value
|
||||
)
|
||||
|
||||
test React.createElement(Foo, value: 'foo'), 'SPAN', 'foo'
|
||||
expect(lifeCycles).toEqual [
|
||||
@@ -404,8 +410,9 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
{}
|
||||
|
||||
render: ->
|
||||
span
|
||||
React.createElement('span',
|
||||
className: 'foo'
|
||||
)
|
||||
|
||||
expect(->
|
||||
test React.createElement(Foo), 'SPAN', 'foo'
|
||||
@@ -431,8 +438,9 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
{}
|
||||
|
||||
render: ->
|
||||
span
|
||||
React.createElement('span',
|
||||
className: 'foo'
|
||||
)
|
||||
|
||||
test React.createElement(Foo), 'SPAN', 'foo'
|
||||
undefined
|
||||
@@ -443,8 +451,9 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
false
|
||||
|
||||
render: ->
|
||||
span
|
||||
React.createElement('span',
|
||||
className: 'foo'
|
||||
)
|
||||
|
||||
expect(->
|
||||
test React.createElement(NamedComponent), 'SPAN', 'foo'
|
||||
@@ -461,8 +470,9 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
false
|
||||
|
||||
render: ->
|
||||
span
|
||||
React.createElement('span',
|
||||
className: 'foo'
|
||||
)
|
||||
|
||||
expect(->
|
||||
test React.createElement(NamedComponent), 'SPAN', 'foo'
|
||||
@@ -478,8 +488,9 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
false
|
||||
|
||||
render: ->
|
||||
span
|
||||
React.createElement('span',
|
||||
className: 'foo'
|
||||
)
|
||||
|
||||
expect(->
|
||||
test React.createElement(NamedComponent), 'SPAN', 'foo'
|
||||
@@ -491,7 +502,7 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
|
||||
it 'should throw AND warn when trying to access classic APIs', ->
|
||||
instance =
|
||||
test Inner(name: 'foo'), 'DIV', 'foo'
|
||||
test React.createElement(InnerComponent, name: 'foo'), 'DIV', 'foo'
|
||||
expect(->
|
||||
expect(-> instance.replaceState {}).toThrow()
|
||||
).toWarnDev(
|
||||
@@ -511,7 +522,7 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
@contextTypes:
|
||||
bar: PropTypes.string
|
||||
render: ->
|
||||
div className: @context.bar
|
||||
React.createElement('div', className: @context.bar)
|
||||
|
||||
class Foo extends React.Component
|
||||
@childContextTypes:
|
||||
@@ -527,16 +538,17 @@ describe 'ReactCoffeeScriptClass', ->
|
||||
it 'supports classic refs', ->
|
||||
class Foo extends React.Component
|
||||
render: ->
|
||||
Inner
|
||||
React.createElement(InnerComponent,
|
||||
name: 'foo'
|
||||
ref: 'inner'
|
||||
)
|
||||
|
||||
instance = test(React.createElement(Foo), 'DIV', 'foo')
|
||||
expect(instance.refs.inner.getName()).toBe 'foo'
|
||||
undefined
|
||||
|
||||
it 'supports drilling through to the DOM using findDOMNode', ->
|
||||
instance = test Inner(name: 'foo'), 'DIV', 'foo'
|
||||
instance = test React.createElement(InnerComponent, name: 'foo'), 'DIV', 'foo'
|
||||
node = ReactDOM.findDOMNode(instance)
|
||||
expect(node).toBe container.firstChild
|
||||
undefined
|
||||
|
||||
@@ -13,6 +13,8 @@ let React;
|
||||
let ReactDOM;
|
||||
let ReactTestUtils;
|
||||
|
||||
const ReactFeatureFlags = require('shared/ReactFeatureFlags');
|
||||
|
||||
describe('ReactElement', () => {
|
||||
let ComponentClass;
|
||||
let originalSymbol;
|
||||
@@ -46,7 +48,7 @@ describe('ReactElement', () => {
|
||||
});
|
||||
|
||||
it('returns a complete element according to spec', () => {
|
||||
const element = React.createFactory(ComponentClass)();
|
||||
const element = React.createElement(ComponentClass);
|
||||
expect(element.type).toBe(ComponentClass);
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
@@ -121,7 +123,7 @@ describe('ReactElement', () => {
|
||||
});
|
||||
|
||||
it('allows a string to be passed as the type', () => {
|
||||
const element = React.createFactory('div')();
|
||||
const element = React.createElement('div');
|
||||
expect(element.type).toBe('div');
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
@@ -133,7 +135,7 @@ describe('ReactElement', () => {
|
||||
});
|
||||
|
||||
it('returns an immutable element', () => {
|
||||
const element = React.createFactory(ComponentClass)();
|
||||
const element = React.createElement(ComponentClass);
|
||||
if (__DEV__) {
|
||||
expect(() => (element.type = 'div')).toThrow();
|
||||
} else {
|
||||
@@ -143,7 +145,7 @@ describe('ReactElement', () => {
|
||||
|
||||
it('does not reuse the original config object', () => {
|
||||
const config = {foo: 1};
|
||||
const element = React.createFactory(ComponentClass)(config);
|
||||
const element = React.createElement(ComponentClass, config);
|
||||
expect(element.props.foo).toBe(1);
|
||||
config.foo = 2;
|
||||
expect(element.props.foo).toBe(1);
|
||||
@@ -151,12 +153,12 @@ describe('ReactElement', () => {
|
||||
|
||||
it('does not fail if config has no prototype', () => {
|
||||
const config = Object.create(null, {foo: {value: 1, enumerable: true}});
|
||||
const element = React.createFactory(ComponentClass)(config);
|
||||
const element = React.createElement(ComponentClass, config);
|
||||
expect(element.props.foo).toBe(1);
|
||||
});
|
||||
|
||||
it('extracts key and ref from the config', () => {
|
||||
const element = React.createFactory(ComponentClass)({
|
||||
const element = React.createElement(ComponentClass, {
|
||||
key: '12',
|
||||
ref: '34',
|
||||
foo: '56',
|
||||
@@ -172,7 +174,7 @@ describe('ReactElement', () => {
|
||||
});
|
||||
|
||||
it('extracts null key and ref', () => {
|
||||
const element = React.createFactory(ComponentClass)({
|
||||
const element = React.createElement(ComponentClass, {
|
||||
key: null,
|
||||
ref: null,
|
||||
foo: '12',
|
||||
@@ -193,7 +195,7 @@ describe('ReactElement', () => {
|
||||
key: undefined,
|
||||
ref: undefined,
|
||||
};
|
||||
const element = React.createFactory(ComponentClass)(props);
|
||||
const element = React.createElement(ComponentClass, props);
|
||||
expect(element.type).toBe(ComponentClass);
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
@@ -212,7 +214,7 @@ describe('ReactElement', () => {
|
||||
});
|
||||
|
||||
it('coerces the key to a string', () => {
|
||||
const element = React.createFactory(ComponentClass)({
|
||||
const element = React.createElement(ComponentClass, {
|
||||
key: 12,
|
||||
foo: '56',
|
||||
});
|
||||
@@ -227,12 +229,11 @@ describe('ReactElement', () => {
|
||||
});
|
||||
|
||||
it('preserves the owner on the element', () => {
|
||||
const Component = React.createFactory(ComponentClass);
|
||||
let element;
|
||||
|
||||
class Wrapper extends React.Component {
|
||||
render() {
|
||||
element = Component();
|
||||
element = React.createElement(ComponentClass);
|
||||
return element;
|
||||
}
|
||||
}
|
||||
@@ -245,7 +246,8 @@ describe('ReactElement', () => {
|
||||
|
||||
it('merges an additional argument onto the children prop', () => {
|
||||
const a = 1;
|
||||
const element = React.createFactory(ComponentClass)(
|
||||
const element = React.createElement(
|
||||
ComponentClass,
|
||||
{
|
||||
children: 'text',
|
||||
},
|
||||
@@ -255,14 +257,15 @@ describe('ReactElement', () => {
|
||||
});
|
||||
|
||||
it('does not override children if no rest args are provided', () => {
|
||||
const element = React.createFactory(ComponentClass)({
|
||||
const element = React.createElement(ComponentClass, {
|
||||
children: 'text',
|
||||
});
|
||||
expect(element.props.children).toBe('text');
|
||||
});
|
||||
|
||||
it('overrides children if null is provided as an argument', () => {
|
||||
const element = React.createFactory(ComponentClass)(
|
||||
const element = React.createElement(
|
||||
ComponentClass,
|
||||
{
|
||||
children: 'text',
|
||||
},
|
||||
@@ -275,7 +278,7 @@ describe('ReactElement', () => {
|
||||
const a = 1;
|
||||
const b = 2;
|
||||
const c = 3;
|
||||
const element = React.createFactory(ComponentClass)(null, a, b, c);
|
||||
const element = React.createElement(ComponentClass, null, a, b, c);
|
||||
expect(element.props.children).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
@@ -309,7 +312,9 @@ describe('ReactElement', () => {
|
||||
expect(React.isValidElement(true)).toEqual(false);
|
||||
expect(React.isValidElement({})).toEqual(false);
|
||||
expect(React.isValidElement('string')).toEqual(false);
|
||||
expect(React.isValidElement(React.createFactory('div'))).toEqual(false);
|
||||
if (!ReactFeatureFlags.disableCreateFactory) {
|
||||
expect(React.isValidElement(React.createFactory('div'))).toEqual(false);
|
||||
}
|
||||
expect(React.isValidElement(Component)).toEqual(false);
|
||||
expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
|
||||
|
||||
@@ -467,7 +472,9 @@ describe('ReactElement', () => {
|
||||
expect(React.isValidElement(true)).toEqual(false);
|
||||
expect(React.isValidElement({})).toEqual(false);
|
||||
expect(React.isValidElement('string')).toEqual(false);
|
||||
expect(React.isValidElement(React.createFactory('div'))).toEqual(false);
|
||||
if (!ReactFeatureFlags.disableCreateFactory) {
|
||||
expect(React.isValidElement(React.createFactory('div'))).toEqual(false);
|
||||
}
|
||||
expect(React.isValidElement(Component)).toEqual(false);
|
||||
expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
|
||||
|
||||
|
||||
@@ -315,7 +315,7 @@ describe('ReactElementClone', () => {
|
||||
});
|
||||
|
||||
it('should ignore undefined key and ref', () => {
|
||||
const element = React.createFactory(ComponentClass)({
|
||||
const element = React.createElement(ComponentClass, {
|
||||
key: '12',
|
||||
ref: '34',
|
||||
foo: '56',
|
||||
@@ -337,7 +337,7 @@ describe('ReactElementClone', () => {
|
||||
});
|
||||
|
||||
it('should extract null key and ref', () => {
|
||||
const element = React.createFactory(ComponentClass)({
|
||||
const element = React.createElement(ComponentClass, {
|
||||
key: '12',
|
||||
ref: '34',
|
||||
foo: '56',
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
|
||||
let React;
|
||||
let ReactDOM;
|
||||
let ReactFeatureFlags;
|
||||
let ReactTestUtils;
|
||||
|
||||
let ReactFeatureFlags = require('shared/ReactFeatureFlags');
|
||||
|
||||
// NOTE: We're explicitly not using JSX here. This is intended to test
|
||||
// a new React.jsx api which does not have a JSX transformer yet.
|
||||
// A lot of these tests are pulled from ReactElement-test because
|
||||
@@ -67,7 +68,9 @@ describe('ReactElement.jsx', () => {
|
||||
expect(React.isValidElement(true)).toEqual(false);
|
||||
expect(React.isValidElement({})).toEqual(false);
|
||||
expect(React.isValidElement('string')).toEqual(false);
|
||||
expect(React.isValidElement(React.createFactory('div'))).toEqual(false);
|
||||
if (!ReactFeatureFlags.disableCreateFactory) {
|
||||
expect(React.isValidElement(React.createFactory('div'))).toEqual(false);
|
||||
}
|
||||
expect(React.isValidElement(Component)).toEqual(false);
|
||||
expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
|
||||
|
||||
@@ -297,7 +300,9 @@ describe('ReactElement.jsx', () => {
|
||||
expect(React.isValidElement(true)).toEqual(false);
|
||||
expect(React.isValidElement({})).toEqual(false);
|
||||
expect(React.isValidElement('string')).toEqual(false);
|
||||
expect(React.isValidElement(React.createFactory('div'))).toEqual(false);
|
||||
if (!ReactFeatureFlags.disableCreateFactory) {
|
||||
expect(React.isValidElement(React.createFactory('div'))).toEqual(false);
|
||||
}
|
||||
expect(React.isValidElement(Component)).toEqual(false);
|
||||
expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
|
||||
|
||||
|
||||
@@ -13,11 +13,12 @@
|
||||
// classic JS without JSX.
|
||||
|
||||
let PropTypes;
|
||||
let ReactFeatureFlags;
|
||||
let React;
|
||||
let ReactDOM;
|
||||
let ReactTestUtils;
|
||||
|
||||
let ReactFeatureFlags = require('shared/ReactFeatureFlags');
|
||||
|
||||
describe('ReactElementValidator', () => {
|
||||
let ComponentClass;
|
||||
|
||||
@@ -38,27 +39,29 @@ describe('ReactElementValidator', () => {
|
||||
});
|
||||
|
||||
it('warns for keys for arrays of elements in rest args', () => {
|
||||
const Component = React.createFactory(ComponentClass);
|
||||
|
||||
expect(() => {
|
||||
Component(null, [Component(), Component()]);
|
||||
React.createElement(ComponentClass, null, [
|
||||
React.createElement(ComponentClass),
|
||||
React.createElement(ComponentClass),
|
||||
]);
|
||||
}).toErrorDev('Each child in a list should have a unique "key" prop.');
|
||||
});
|
||||
|
||||
it('warns for keys for arrays of elements with owner info', () => {
|
||||
const Component = React.createFactory(ComponentClass);
|
||||
|
||||
class InnerClass extends React.Component {
|
||||
render() {
|
||||
return Component(null, this.props.childSet);
|
||||
return React.createElement(ComponentClass, null, this.props.childSet);
|
||||
}
|
||||
}
|
||||
|
||||
const InnerComponent = React.createFactory(InnerClass);
|
||||
|
||||
class ComponentWrapper extends React.Component {
|
||||
render() {
|
||||
return InnerComponent({childSet: [Component(), Component()]});
|
||||
return React.createElement(InnerClass, {
|
||||
childSet: [
|
||||
React.createElement(ComponentClass),
|
||||
React.createElement(ComponentClass),
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,34 +147,6 @@ describe('ReactElementValidator', () => {
|
||||
});
|
||||
|
||||
it('warns for keys for iterables of elements in rest args', () => {
|
||||
const Component = React.createFactory(ComponentClass);
|
||||
|
||||
const iterable = {
|
||||
'@@iterator': function() {
|
||||
let i = 0;
|
||||
return {
|
||||
next: function() {
|
||||
const done = ++i > 2;
|
||||
return {value: done ? undefined : Component(), done: done};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
expect(() => Component(null, iterable)).toErrorDev(
|
||||
'Each child in a list should have a unique "key" prop.',
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warns for arrays of elements with keys', () => {
|
||||
const Component = React.createFactory(ComponentClass);
|
||||
|
||||
Component(null, [Component({key: '#1'}), Component({key: '#2'})]);
|
||||
});
|
||||
|
||||
it('does not warns for iterable elements with keys', () => {
|
||||
const Component = React.createFactory(ComponentClass);
|
||||
|
||||
const iterable = {
|
||||
'@@iterator': function() {
|
||||
let i = 0;
|
||||
@@ -179,7 +154,7 @@ describe('ReactElementValidator', () => {
|
||||
next: function() {
|
||||
const done = ++i > 2;
|
||||
return {
|
||||
value: done ? undefined : Component({key: '#' + i}),
|
||||
value: done ? undefined : React.createElement(ComponentClass),
|
||||
done: done,
|
||||
};
|
||||
},
|
||||
@@ -187,19 +162,50 @@ describe('ReactElementValidator', () => {
|
||||
},
|
||||
};
|
||||
|
||||
Component(null, iterable);
|
||||
expect(() =>
|
||||
React.createElement(ComponentClass, null, iterable),
|
||||
).toErrorDev('Each child in a list should have a unique "key" prop.');
|
||||
});
|
||||
|
||||
it('does not warns for arrays of elements with keys', () => {
|
||||
React.createElement(ComponentClass, null, [
|
||||
React.createElement(ComponentClass, {key: '#1'}),
|
||||
React.createElement(ComponentClass, {key: '#2'}),
|
||||
]);
|
||||
});
|
||||
|
||||
it('does not warns for iterable elements with keys', () => {
|
||||
const iterable = {
|
||||
'@@iterator': function() {
|
||||
let i = 0;
|
||||
return {
|
||||
next: function() {
|
||||
const done = ++i > 2;
|
||||
return {
|
||||
value: done
|
||||
? undefined
|
||||
: React.createElement(ComponentClass, {key: '#' + i}),
|
||||
done: done,
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
React.createElement(ComponentClass, null, iterable);
|
||||
});
|
||||
|
||||
it('does not warn when the element is directly in rest args', () => {
|
||||
const Component = React.createFactory(ComponentClass);
|
||||
|
||||
Component(null, Component(), Component());
|
||||
React.createElement(
|
||||
ComponentClass,
|
||||
null,
|
||||
React.createElement(ComponentClass),
|
||||
React.createElement(ComponentClass),
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn when the array contains a non-element', () => {
|
||||
const Component = React.createFactory(ComponentClass);
|
||||
|
||||
Component(null, [{}, {}]);
|
||||
React.createElement(ComponentClass, null, [{}, {}]);
|
||||
});
|
||||
|
||||
it('should give context for PropType errors in nested components.', () => {
|
||||
@@ -433,23 +439,25 @@ describe('ReactElementValidator', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn when accessing .type on an element factory', () => {
|
||||
function TestComponent() {
|
||||
return <div />;
|
||||
}
|
||||
if (!ReactFeatureFlags.disableCreateFactory) {
|
||||
it('should warn when accessing .type on an element factory', () => {
|
||||
function TestComponent() {
|
||||
return <div />;
|
||||
}
|
||||
|
||||
let TestFactory = React.createFactory(TestComponent);
|
||||
expect(
|
||||
() => TestFactory.type,
|
||||
).toWarnDev(
|
||||
'Warning: Factory.type is deprecated. Access the class directly before ' +
|
||||
'passing it to createFactory.',
|
||||
{withoutStack: true},
|
||||
);
|
||||
let TestFactory = React.createFactory(TestComponent);
|
||||
expect(
|
||||
() => TestFactory.type,
|
||||
).toWarnDev(
|
||||
'Warning: Factory.type is deprecated. Access the class directly before ' +
|
||||
'passing it to createFactory.',
|
||||
{withoutStack: true},
|
||||
);
|
||||
|
||||
// Warn once, not again
|
||||
expect(TestFactory.type).toBe(TestComponent);
|
||||
});
|
||||
// Warn once, not again
|
||||
expect(TestFactory.type).toBe(TestComponent);
|
||||
});
|
||||
}
|
||||
|
||||
it('does not warn when using DOM node as children', () => {
|
||||
class DOMContainer extends React.Component {
|
||||
|
||||
@@ -44,10 +44,6 @@ export function addUserTimingListener() {
|
||||
// Disable javascript: URL strings in href for XSS protection.
|
||||
export const disableJavaScriptURLs = false;
|
||||
|
||||
// React Fire: prevent the value and checked attributes from syncing
|
||||
// with their related DOM properties
|
||||
export const disableInputAttributeSyncing = false;
|
||||
|
||||
// These APIs will no longer be "unstable" in the upcoming 16.7 release,
|
||||
// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
|
||||
export const exposeConcurrentModeAPIs = __EXPERIMENTAL__;
|
||||
@@ -85,9 +81,6 @@ export const enableSuspenseCallback = false;
|
||||
// from React.createElement to React.jsx
|
||||
// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
|
||||
export const warnAboutDefaultPropsOnFunctionComponents = false;
|
||||
export const warnAboutStringRefs = false;
|
||||
|
||||
export const disableLegacyContext = false;
|
||||
|
||||
export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
|
||||
|
||||
@@ -97,3 +90,18 @@ export const enableTrustedTypesIntegration = false;
|
||||
|
||||
// Flag to turn event.target and event.currentTarget in ReactNative from a reactTag to a component instance
|
||||
export const enableNativeTargetAsInstance = false;
|
||||
|
||||
// --------------------------
|
||||
// Future APIs to be deprecated
|
||||
// --------------------------
|
||||
|
||||
// Prevent the value and checked attributes from syncing
|
||||
// with their related DOM properties
|
||||
export const disableInputAttributeSyncing = false;
|
||||
|
||||
export const warnAboutStringRefs = false;
|
||||
|
||||
export const disableLegacyContext = false;
|
||||
|
||||
// Disables React.createFactory
|
||||
export const disableCreateFactory = false;
|
||||
|
||||
@@ -45,6 +45,7 @@ export const disableLegacyContext = false;
|
||||
export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
|
||||
export const enableTrainModelFix = false;
|
||||
export const enableTrustedTypesIntegration = false;
|
||||
export const disableCreateFactory = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
||||
@@ -40,6 +40,7 @@ export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
|
||||
export const enableTrainModelFix = false;
|
||||
export const enableTrustedTypesIntegration = false;
|
||||
export const enableNativeTargetAsInstance = false;
|
||||
export const disableCreateFactory = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
||||
@@ -40,6 +40,7 @@ export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
|
||||
export const enableTrainModelFix = false;
|
||||
export const enableTrustedTypesIntegration = false;
|
||||
export const enableNativeTargetAsInstance = false;
|
||||
export const disableCreateFactory = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
||||
@@ -40,6 +40,7 @@ export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
|
||||
export const enableTrainModelFix = false;
|
||||
export const enableTrustedTypesIntegration = false;
|
||||
export const enableNativeTargetAsInstance = false;
|
||||
export const disableCreateFactory = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
||||
@@ -38,6 +38,7 @@ export const disableSchedulerTimeoutBasedOnReactExpirationTime = false;
|
||||
export const enableTrainModelFix = false;
|
||||
export const enableTrustedTypesIntegration = false;
|
||||
export const enableNativeTargetAsInstance = false;
|
||||
export const disableCreateFactory = false;
|
||||
|
||||
// Only used in www builds.
|
||||
export function addUserTimingListener() {
|
||||
|
||||
@@ -90,6 +90,8 @@ export const flushSuspenseFallbacksInTests = true;
|
||||
|
||||
export const enableNativeTargetAsInstance = false;
|
||||
|
||||
export const disableCreateFactory = false;
|
||||
|
||||
// Flow magic to verify the exports of this file match the original version.
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
type Check<_X, Y: _X, X: Y = _X> = null;
|
||||
|
||||
Reference in New Issue
Block a user