2018-09-20 02:56:13 +02:00
/ * * @ l i c e n s e R e a c t v 1 6 . 5 . 2
2017-10-14 18:40:54 +02:00
* react - dom - test - utils . development . js
*
2018-09-20 02:56:13 +02:00
* Copyright ( c ) Facebook , Inc . and its affiliates .
2017-10-14 18:40:54 +02:00
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree .
* /
2017-12-10 21:51:33 +01:00
2017-10-14 18:40:54 +02:00
'use strict' ;
2017-12-10 21:51:33 +01:00
if ( process . env . NODE _ENV !== "production" ) {
( function ( ) {
2017-10-14 18:40:54 +02:00
'use strict' ;
var _assign = require ( 'object-assign' ) ;
2017-12-10 21:51:33 +01:00
var React = require ( 'react' ) ;
var ReactDOM = require ( 'react-dom' ) ;
2017-10-14 18:40:54 +02:00
/ * *
2018-09-20 02:56:13 +02:00
* Use invariant ( ) to assert state which your program assumes to be true .
*
* Provide sprintf - style format ( only % s is supported ) and arguments
* to provide information about what broke and what you were
* expecting .
*
* The invariant message will be stripped in production , but the invariant
* will remain to ensure logic does not differ in production .
* /
var validateFormat = function ( ) { } ;
{
validateFormat = function ( format ) {
if ( format === undefined ) {
throw new Error ( 'invariant requires an error message argument' ) ;
}
} ;
}
function invariant ( condition , format , a , b , c , d , e , f ) {
validateFormat ( format ) ;
if ( ! condition ) {
var error = void 0 ;
if ( format === undefined ) {
error = new Error ( 'Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.' ) ;
} else {
var args = [ a , b , c , d , e , f ] ;
var argIndex = 0 ;
error = new Error ( format . replace ( /%s/g , function ( ) {
return args [ argIndex ++ ] ;
} ) ) ;
error . name = 'Invariant Violation' ;
}
error . framesToPop = 1 ; // we don't care about invariant's own frame
throw error ;
}
}
// Relying on the `invariant()` implementation lets us
// preserve the format and params in the www builds.
/ * *
* Similar to invariant but only logs a warning if the condition is not met .
* This can be used to log issues in development environments in critical
* paths . Removing the logging code for production environments will keep the
* same logic and follow the same code paths .
2017-10-14 18:40:54 +02:00
* /
2018-09-20 02:56:13 +02:00
var warningWithoutStack = function ( ) { } ;
{
warningWithoutStack = function ( condition , format ) {
for ( var _len = arguments . length , args = Array ( _len > 2 ? _len - 2 : 0 ) , _key = 2 ; _key < _len ; _key ++ ) {
args [ _key - 2 ] = arguments [ _key ] ;
}
if ( format === undefined ) {
throw new Error ( '`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument' ) ;
}
if ( args . length > 8 ) {
// Check before the condition to catch violations early.
throw new Error ( 'warningWithoutStack() currently supports at most 8 arguments.' ) ;
}
if ( condition ) {
return ;
}
if ( typeof console !== 'undefined' ) {
var _args$map = args . map ( function ( item ) {
return '' + item ;
} ) ,
a = _args$map [ 0 ] ,
b = _args$map [ 1 ] ,
c = _args$map [ 2 ] ,
d = _args$map [ 3 ] ,
e = _args$map [ 4 ] ,
f = _args$map [ 5 ] ,
g = _args$map [ 6 ] ,
h = _args$map [ 7 ] ;
var message = 'Warning: ' + format ;
// We intentionally don't use spread (or .apply) because it breaks IE9:
// https://github.com/facebook/react/issues/13610
switch ( args . length ) {
case 0 :
console . error ( message ) ;
break ;
case 1 :
console . error ( message , a ) ;
break ;
case 2 :
console . error ( message , a , b ) ;
break ;
case 3 :
console . error ( message , a , b , c ) ;
break ;
case 4 :
console . error ( message , a , b , c , d ) ;
break ;
case 5 :
console . error ( message , a , b , c , d , e ) ;
break ;
case 6 :
console . error ( message , a , b , c , d , e , f ) ;
break ;
case 7 :
console . error ( message , a , b , c , d , e , f , g ) ;
break ;
case 8 :
console . error ( message , a , b , c , d , e , f , g , h ) ;
break ;
default :
throw new Error ( 'warningWithoutStack() currently supports at most 8 arguments.' ) ;
}
}
try {
// --- Welcome to debugging React ---
// This error was thrown as a convenience so that you can use this stack
// to find the callsite that caused this warning to fire.
var argIndex = 0 ;
var _message = 'Warning: ' + format . replace ( /%s/g , function ( ) {
return args [ argIndex ++ ] ;
} ) ;
throw new Error ( _message ) ;
} catch ( x ) { }
} ;
}
var warningWithoutStack$1 = warningWithoutStack ;
2017-10-14 18:40:54 +02:00
/ * *
* ` ReactInstanceMap ` maintains a mapping from a public facing stateful
* instance ( key ) and the internal representation ( value ) . This allows public
* methods to accept the user facing instance as an argument and map them back
* to internal methods .
*
2017-12-10 21:51:33 +01:00
* Note that this module is currently shared and assumed to be stateless .
* If this becomes an actual Map , that will break .
2017-10-14 18:40:54 +02:00
* /
/ * *
2017-12-10 21:51:33 +01:00
* This API should be called ` delete ` but we ' d have to make sure to always
* transform these to strings for IE support . When this transform is fully
* supported we can rename it .
2017-10-14 18:40:54 +02:00
* /
2017-12-10 21:51:33 +01:00
function get ( key ) {
return key . _reactInternalFiber ;
2017-10-14 18:40:54 +02:00
}
2018-09-20 02:56:13 +02:00
var ReactSharedInternals = React . _ _SECRET _INTERNALS _DO _NOT _USE _OR _YOU _WILL _BE _FIRED ;
2017-12-10 21:51:33 +01:00
2018-09-20 02:56:13 +02:00
// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
// nor polyfill, then a plain number is used for performance.
2017-12-10 21:51:33 +01:00
2018-09-20 02:56:13 +02:00
var FunctionalComponent = 0 ;
var FunctionalComponentLazy = 1 ;
2017-12-10 21:51:33 +01:00
var ClassComponent = 2 ;
2018-09-20 02:56:13 +02:00
var ClassComponentLazy = 3 ;
// Before we know whether it is functional or class
var HostRoot = 5 ; // Root of a host tree. Could be nested inside another node.
2017-12-10 21:51:33 +01:00
// A subtree. Could be an entry point to a different renderer.
2018-09-20 02:56:13 +02:00
var HostComponent = 7 ;
var HostText = 8 ;
// Don't change these two values. They're used by React Dev Tools.
var NoEffect = /* */ 0 ;
2017-12-10 21:51:33 +01:00
// You can change the rest (and add more).
2018-09-20 02:56:13 +02:00
var Placement = /* */ 2 ;
// Update & Callback & Ref & Snapshot
// Union of all host effects
var ReactCurrentOwner = ReactSharedInternals . ReactCurrentOwner ;
2017-10-14 18:40:54 +02:00
var MOUNTING = 1 ;
var MOUNTED = 2 ;
var UNMOUNTED = 3 ;
function isFiberMountedImpl ( fiber ) {
var node = fiber ;
if ( ! fiber . alternate ) {
// If there is no alternate, this might be a new tree that isn't inserted
// yet. If it is, then it will have a pending insertion effect on it.
if ( ( node . effectTag & Placement ) !== NoEffect ) {
return MOUNTING ;
}
2018-09-20 02:56:13 +02:00
while ( node . return ) {
node = node . return ;
2017-10-14 18:40:54 +02:00
if ( ( node . effectTag & Placement ) !== NoEffect ) {
return MOUNTING ;
}
}
} else {
2018-09-20 02:56:13 +02:00
while ( node . return ) {
node = node . return ;
2017-10-14 18:40:54 +02:00
}
}
if ( node . tag === HostRoot ) {
// TODO: Check if this was a nested HostRoot when used with
// renderContainerIntoSubtree.
return MOUNTED ;
}
// If we didn't hit the root, that means that we're in an disconnected tree
// that has been unmounted.
return UNMOUNTED ;
}
2017-12-10 21:51:33 +01:00
2017-10-14 18:40:54 +02:00
function assertIsMounted ( fiber ) {
! ( isFiberMountedImpl ( fiber ) === MOUNTED ) ? invariant ( false , 'Unable to find node on an unmounted component.' ) : void 0 ;
}
function findCurrentFiberUsingSlowPath ( fiber ) {
var alternate = fiber . alternate ;
if ( ! alternate ) {
// If there is no alternate, then we only need to check if it is mounted.
var state = isFiberMountedImpl ( fiber ) ;
! ( state !== UNMOUNTED ) ? invariant ( false , 'Unable to find node on an unmounted component.' ) : void 0 ;
if ( state === MOUNTING ) {
return null ;
}
return fiber ;
}
// If we have two possible branches, we'll walk backwards up to the root
// to see what path the root points to. On the way we may hit one of the
// special cases and we'll deal with them.
var a = fiber ;
var b = alternate ;
while ( true ) {
2018-09-20 02:56:13 +02:00
var parentA = a . return ;
2017-10-14 18:40:54 +02:00
var parentB = parentA ? parentA . alternate : null ;
if ( ! parentA || ! parentB ) {
// We're at the root.
break ;
}
// If both copies of the parent fiber point to the same child, we can
// assume that the child is current. This happens when we bailout on low
// priority: the bailed out fiber's child reuses the current child.
if ( parentA . child === parentB . child ) {
var child = parentA . child ;
while ( child ) {
if ( child === a ) {
// We've determined that A is the current branch.
assertIsMounted ( parentA ) ;
return fiber ;
}
if ( child === b ) {
// We've determined that B is the current branch.
assertIsMounted ( parentA ) ;
return alternate ;
}
child = child . sibling ;
}
// We should never have an alternate for any mounting node. So the only
// way this could possibly happen is if this was unmounted, if at all.
invariant ( false , 'Unable to find node on an unmounted component.' ) ;
}
2018-09-20 02:56:13 +02:00
if ( a . return !== b . return ) {
2017-10-14 18:40:54 +02:00
// The return pointer of A and the return pointer of B point to different
// fibers. We assume that return pointers never criss-cross, so A must
// belong to the child set of A.return, and B must belong to the child
// set of B.return.
a = parentA ;
b = parentB ;
} else {
// The return pointers point to the same fiber. We'll have to use the
// default, slow path: scan the child sets of each parent alternate to see
// which child belongs to which set.
//
// Search parent A's child set
var didFindChild = false ;
var _child = parentA . child ;
while ( _child ) {
if ( _child === a ) {
didFindChild = true ;
a = parentA ;
b = parentB ;
break ;
}
if ( _child === b ) {
didFindChild = true ;
b = parentA ;
a = parentB ;
break ;
}
_child = _child . sibling ;
}
if ( ! didFindChild ) {
// Search parent B's child set
_child = parentB . child ;
while ( _child ) {
if ( _child === a ) {
didFindChild = true ;
a = parentB ;
b = parentA ;
break ;
}
if ( _child === b ) {
didFindChild = true ;
b = parentB ;
a = parentA ;
break ;
}
_child = _child . sibling ;
}
! didFindChild ? invariant ( false , 'Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.' ) : void 0 ;
}
}
! ( a . alternate === b ) ? invariant ( false , 'Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.' ) : void 0 ;
}
// If the root is not a host container, we're in a disconnected tree. I.e.
// unmounted.
! ( a . tag === HostRoot ) ? invariant ( false , 'Unable to find node on an unmounted component.' ) : void 0 ;
if ( a . stateNode . current === a ) {
// We've determined that A is the current branch.
return fiber ;
}
// Otherwise B has to be current branch.
return alternate ;
}
2017-12-10 21:51:33 +01:00
/* eslint valid-typeof: 0 */
2017-10-14 18:40:54 +02:00
var EVENT _POOL _SIZE = 10 ;
/ * *
* @ interface Event
* @ see http : //www.w3.org/TR/DOM-Level-3-Events/
* /
var EventInterface = {
type : null ,
target : null ,
// currentTarget is set when dispatching; no use in copying it here
2018-09-20 02:56:13 +02:00
currentTarget : function ( ) {
return null ;
} ,
2017-10-14 18:40:54 +02:00
eventPhase : null ,
bubbles : null ,
cancelable : null ,
timeStamp : function ( event ) {
return event . timeStamp || Date . now ( ) ;
} ,
defaultPrevented : null ,
isTrusted : null
} ;
2018-09-20 02:56:13 +02:00
function functionThatReturnsTrue ( ) {
return true ;
}
function functionThatReturnsFalse ( ) {
return false ;
}
2017-10-14 18:40:54 +02:00
/ * *
* Synthetic events are dispatched by event plugins , typically in response to a
* top - level event delegation handler .
*
* These systems should generally use pooling to reduce the frequency of garbage
* collection . The system should check ` isPersistent ` to determine whether the
* event should be released into the pool after being dispatched . Users that
* need a persisted event should invoke ` persist ` .
*
* Synthetic events ( and subclasses ) implement the DOM Level 3 Events API by
* normalizing browser quirks . Subclasses do not necessarily have to implement a
* DOM interface ; custom application - specific events can also subclass this .
*
* @ param { object } dispatchConfig Configuration used to dispatch this event .
* @ param { * } targetInst Marker identifying the event target .
* @ param { object } nativeEvent Native browser event .
* @ param { DOMEventTarget } nativeEventTarget Target node .
* /
function SyntheticEvent ( dispatchConfig , targetInst , nativeEvent , nativeEventTarget ) {
{
// these have a getter/setter for warnings
delete this . nativeEvent ;
delete this . preventDefault ;
delete this . stopPropagation ;
2018-09-20 02:56:13 +02:00
delete this . isDefaultPrevented ;
delete this . isPropagationStopped ;
2017-10-14 18:40:54 +02:00
}
this . dispatchConfig = dispatchConfig ;
this . _targetInst = targetInst ;
this . nativeEvent = nativeEvent ;
var Interface = this . constructor . Interface ;
for ( var propName in Interface ) {
if ( ! Interface . hasOwnProperty ( propName ) ) {
continue ;
}
{
delete this [ propName ] ; // this has a getter/setter for warnings
}
var normalize = Interface [ propName ] ;
if ( normalize ) {
this [ propName ] = normalize ( nativeEvent ) ;
} else {
if ( propName === 'target' ) {
this . target = nativeEventTarget ;
} else {
this [ propName ] = nativeEvent [ propName ] ;
}
}
}
var defaultPrevented = nativeEvent . defaultPrevented != null ? nativeEvent . defaultPrevented : nativeEvent . returnValue === false ;
if ( defaultPrevented ) {
2018-09-20 02:56:13 +02:00
this . isDefaultPrevented = functionThatReturnsTrue ;
2017-10-14 18:40:54 +02:00
} else {
2018-09-20 02:56:13 +02:00
this . isDefaultPrevented = functionThatReturnsFalse ;
2017-10-14 18:40:54 +02:00
}
2018-09-20 02:56:13 +02:00
this . isPropagationStopped = functionThatReturnsFalse ;
2017-10-14 18:40:54 +02:00
return this ;
}
_assign ( SyntheticEvent . prototype , {
preventDefault : function ( ) {
this . defaultPrevented = true ;
var event = this . nativeEvent ;
if ( ! event ) {
return ;
}
if ( event . preventDefault ) {
event . preventDefault ( ) ;
} else if ( typeof event . returnValue !== 'unknown' ) {
event . returnValue = false ;
}
2018-09-20 02:56:13 +02:00
this . isDefaultPrevented = functionThatReturnsTrue ;
2017-10-14 18:40:54 +02:00
} ,
stopPropagation : function ( ) {
var event = this . nativeEvent ;
if ( ! event ) {
return ;
}
if ( event . stopPropagation ) {
event . stopPropagation ( ) ;
} else if ( typeof event . cancelBubble !== 'unknown' ) {
// The ChangeEventPlugin registers a "propertychange" event for
// IE. This event does not support bubbling or cancelling, and
// any references to cancelBubble throw "Member not found". A
// typeof check of "unknown" circumvents this issue (and is also
// IE specific).
event . cancelBubble = true ;
}
2018-09-20 02:56:13 +02:00
this . isPropagationStopped = functionThatReturnsTrue ;
2017-10-14 18:40:54 +02:00
} ,
/ * *
* We release all dispatched ` SyntheticEvent ` s after each event loop , adding
* them back into the pool . This allows a way to hold onto a reference that
* won ' t be added back into the pool .
* /
persist : function ( ) {
2018-09-20 02:56:13 +02:00
this . isPersistent = functionThatReturnsTrue ;
2017-10-14 18:40:54 +02:00
} ,
/ * *
* Checks if this event should be released back into the pool .
*
* @ return { boolean } True if this should not be released , false otherwise .
* /
2018-09-20 02:56:13 +02:00
isPersistent : functionThatReturnsFalse ,
2017-10-14 18:40:54 +02:00
/ * *
* ` PooledClass ` looks for ` destructor ` on each instance it releases .
* /
destructor : function ( ) {
var Interface = this . constructor . Interface ;
for ( var propName in Interface ) {
{
Object . defineProperty ( this , propName , getPooledWarningPropertyDefinition ( propName , Interface [ propName ] ) ) ;
}
}
2018-09-20 02:56:13 +02:00
this . dispatchConfig = null ;
this . _targetInst = null ;
this . nativeEvent = null ;
this . isDefaultPrevented = functionThatReturnsFalse ;
this . isPropagationStopped = functionThatReturnsFalse ;
this . _dispatchListeners = null ;
this . _dispatchInstances = null ;
2017-10-14 18:40:54 +02:00
{
Object . defineProperty ( this , 'nativeEvent' , getPooledWarningPropertyDefinition ( 'nativeEvent' , null ) ) ;
2018-09-20 02:56:13 +02:00
Object . defineProperty ( this , 'isDefaultPrevented' , getPooledWarningPropertyDefinition ( 'isDefaultPrevented' , functionThatReturnsFalse ) ) ;
Object . defineProperty ( this , 'isPropagationStopped' , getPooledWarningPropertyDefinition ( 'isPropagationStopped' , functionThatReturnsFalse ) ) ;
Object . defineProperty ( this , 'preventDefault' , getPooledWarningPropertyDefinition ( 'preventDefault' , function ( ) { } ) ) ;
Object . defineProperty ( this , 'stopPropagation' , getPooledWarningPropertyDefinition ( 'stopPropagation' , function ( ) { } ) ) ;
2017-10-14 18:40:54 +02:00
}
}
} ) ;
SyntheticEvent . Interface = EventInterface ;
/ * *
* Helper to reduce boilerplate when creating subclasses .
* /
2018-09-20 02:56:13 +02:00
SyntheticEvent . extend = function ( Interface ) {
2017-10-14 18:40:54 +02:00
var Super = this ;
var E = function ( ) { } ;
E . prototype = Super . prototype ;
var prototype = new E ( ) ;
2018-09-20 02:56:13 +02:00
function Class ( ) {
return Super . apply ( this , arguments ) ;
}
2017-10-14 18:40:54 +02:00
_assign ( prototype , Class . prototype ) ;
Class . prototype = prototype ;
Class . prototype . constructor = Class ;
Class . Interface = _assign ( { } , Super . Interface , Interface ) ;
2018-09-20 02:56:13 +02:00
Class . extend = Super . extend ;
2017-10-14 18:40:54 +02:00
addEventPoolingTo ( Class ) ;
2018-09-20 02:56:13 +02:00
return Class ;
} ;
2017-10-14 18:40:54 +02:00
addEventPoolingTo ( SyntheticEvent ) ;
/ * *
2017-12-10 21:51:33 +01:00
* Helper to nullify syntheticEvent instance properties when destructing
*
* @ param { String } propName
* @ param { ? object } getVal
* @ return { object } defineProperty object
* /
2017-10-14 18:40:54 +02:00
function getPooledWarningPropertyDefinition ( propName , getVal ) {
var isFunction = typeof getVal === 'function' ;
return {
configurable : true ,
set : set ,
get : get
} ;
function set ( val ) {
var action = isFunction ? 'setting the method' : 'setting the property' ;
warn ( action , 'This is effectively a no-op' ) ;
return val ;
}
function get ( ) {
var action = isFunction ? 'accessing the method' : 'accessing the property' ;
var result = isFunction ? 'This is a no-op function' : 'This is set to null' ;
warn ( action , result ) ;
return getVal ;
}
function warn ( action , result ) {
var warningCondition = false ;
2018-09-20 02:56:13 +02:00
! warningCondition ? warningWithoutStack$1 ( false , "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.' , action , propName , result ) : void 0 ;
2017-10-14 18:40:54 +02:00
}
}
function getPooledEvent ( dispatchConfig , targetInst , nativeEvent , nativeInst ) {
var EventConstructor = this ;
if ( EventConstructor . eventPool . length ) {
var instance = EventConstructor . eventPool . pop ( ) ;
EventConstructor . call ( instance , dispatchConfig , targetInst , nativeEvent , nativeInst ) ;
return instance ;
}
return new EventConstructor ( dispatchConfig , targetInst , nativeEvent , nativeInst ) ;
}
function releasePooledEvent ( event ) {
var EventConstructor = this ;
2018-09-20 02:56:13 +02:00
! ( event instanceof EventConstructor ) ? invariant ( false , 'Trying to release an event instance into a pool of a different type.' ) : void 0 ;
2017-10-14 18:40:54 +02:00
event . destructor ( ) ;
if ( EventConstructor . eventPool . length < EVENT _POOL _SIZE ) {
EventConstructor . eventPool . push ( event ) ;
}
}
function addEventPoolingTo ( EventConstructor ) {
EventConstructor . eventPool = [ ] ;
EventConstructor . getPooled = getPooledEvent ;
EventConstructor . release = releasePooledEvent ;
}
2018-09-20 02:56:13 +02:00
/ * *
* Forked from fbjs / warning :
* https : //github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
*
* Only change is we use console . warn instead of console . error ,
* and do nothing when 'console' is not supported .
* This really simplifies the code .
* -- -
* Similar to invariant but only logs a warning if the condition is not met .
* This can be used to log issues in development environments in critical
* paths . Removing the logging code for production environments will keep the
* same logic and follow the same code paths .
* /
var lowPriorityWarning = function ( ) { } ;
{
var printWarning = function ( format ) {
for ( var _len = arguments . length , args = Array ( _len > 1 ? _len - 1 : 0 ) , _key = 1 ; _key < _len ; _key ++ ) {
args [ _key - 1 ] = arguments [ _key ] ;
}
var argIndex = 0 ;
var message = 'Warning: ' + format . replace ( /%s/g , function ( ) {
return args [ argIndex ++ ] ;
} ) ;
if ( typeof console !== 'undefined' ) {
console . warn ( message ) ;
}
try {
// --- Welcome to debugging React ---
// This error was thrown as a convenience so that you can use this stack
// to find the callsite that caused this warning to fire.
throw new Error ( message ) ;
} catch ( x ) { }
} ;
lowPriorityWarning = function ( condition , format ) {
if ( format === undefined ) {
throw new Error ( '`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument' ) ;
}
if ( ! condition ) {
for ( var _len2 = arguments . length , args = Array ( _len2 > 2 ? _len2 - 2 : 0 ) , _key2 = 2 ; _key2 < _len2 ; _key2 ++ ) {
args [ _key2 - 2 ] = arguments [ _key2 ] ;
}
printWarning . apply ( undefined , [ format ] . concat ( args ) ) ;
}
} ;
}
var lowPriorityWarning$1 = lowPriorityWarning ;
/ * *
* HTML nodeType values that represent the type of the node
* /
var ELEMENT _NODE = 1 ;
// Do not uses the below two methods directly!
// Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.
// (It is the only module that is allowed to access these methods.)
function unsafeCastStringToDOMTopLevelType ( topLevelType ) {
return topLevelType ;
}
var canUseDOM = ! ! ( typeof window !== 'undefined' && window . document && window . document . createElement ) ;
2017-12-10 21:51:33 +01:00
/ * *
* Generate a mapping of standard vendor prefixes using the defined style property and event name .
*
* @ param { string } styleProp
* @ param { string } eventName
* @ returns { object }
* /
function makePrefixMap ( styleProp , eventName ) {
var prefixes = { } ;
prefixes [ styleProp . toLowerCase ( ) ] = eventName . toLowerCase ( ) ;
prefixes [ 'Webkit' + styleProp ] = 'webkit' + eventName ;
prefixes [ 'Moz' + styleProp ] = 'moz' + eventName ;
return prefixes ;
}
/ * *
* A list of event names to a configurable list of vendor prefixes .
* /
var vendorPrefixes = {
animationend : makePrefixMap ( 'Animation' , 'AnimationEnd' ) ,
animationiteration : makePrefixMap ( 'Animation' , 'AnimationIteration' ) ,
animationstart : makePrefixMap ( 'Animation' , 'AnimationStart' ) ,
transitionend : makePrefixMap ( 'Transition' , 'TransitionEnd' )
} ;
/ * *
* Event names that have already been detected and prefixed ( if applicable ) .
* /
var prefixedEventNames = { } ;
/ * *
* Element to check for prefixes on .
* /
var style = { } ;
/ * *
* Bootstrap if a DOM exists .
* /
2018-09-20 02:56:13 +02:00
if ( canUseDOM ) {
2017-12-10 21:51:33 +01:00
style = document . createElement ( 'div' ) . style ;
// On some platforms, in particular some releases of Android 4.x,
// the un-prefixed "animation" and "transition" properties are defined on the
// style object but the events that fire will still be prefixed, so we need
// to check if the un-prefixed events are usable, and if not remove them from the map.
if ( ! ( 'AnimationEvent' in window ) ) {
delete vendorPrefixes . animationend . animation ;
delete vendorPrefixes . animationiteration . animation ;
delete vendorPrefixes . animationstart . animation ;
}
// Same as above
if ( ! ( 'TransitionEvent' in window ) ) {
delete vendorPrefixes . transitionend . transition ;
}
}
/ * *
* Attempts to determine the correct vendor prefixed event name .
*
* @ param { string } eventName
* @ returns { string }
* /
function getVendorPrefixedEventName ( eventName ) {
if ( prefixedEventNames [ eventName ] ) {
return prefixedEventNames [ eventName ] ;
} else if ( ! vendorPrefixes [ eventName ] ) {
return eventName ;
}
var prefixMap = vendorPrefixes [ eventName ] ;
for ( var styleProp in prefixMap ) {
if ( prefixMap . hasOwnProperty ( styleProp ) && styleProp in style ) {
return prefixedEventNames [ eventName ] = prefixMap [ styleProp ] ;
}
}
2018-09-20 02:56:13 +02:00
return eventName ;
2017-12-10 21:51:33 +01:00
}
/ * *
2018-09-20 02:56:13 +02:00
* To identify top level events in ReactDOM , we use constants defined by this
* module . This is the only module that uses the unsafe * methods to express
* that the constants actually correspond to the browser event names . This lets
* us save some bundle size by avoiding a top level type - > event name map .
* The rest of ReactDOM code should import top level types from this file .
2017-12-10 21:51:33 +01:00
* /
2018-09-20 02:56:13 +02:00
var TOP _ABORT = unsafeCastStringToDOMTopLevelType ( 'abort' ) ;
var TOP _ANIMATION _END = unsafeCastStringToDOMTopLevelType ( getVendorPrefixedEventName ( 'animationend' ) ) ;
var TOP _ANIMATION _ITERATION = unsafeCastStringToDOMTopLevelType ( getVendorPrefixedEventName ( 'animationiteration' ) ) ;
var TOP _ANIMATION _START = unsafeCastStringToDOMTopLevelType ( getVendorPrefixedEventName ( 'animationstart' ) ) ;
var TOP _BLUR = unsafeCastStringToDOMTopLevelType ( 'blur' ) ;
var TOP _CAN _PLAY = unsafeCastStringToDOMTopLevelType ( 'canplay' ) ;
var TOP _CAN _PLAY _THROUGH = unsafeCastStringToDOMTopLevelType ( 'canplaythrough' ) ;
var TOP _CANCEL = unsafeCastStringToDOMTopLevelType ( 'cancel' ) ;
var TOP _CHANGE = unsafeCastStringToDOMTopLevelType ( 'change' ) ;
var TOP _CLICK = unsafeCastStringToDOMTopLevelType ( 'click' ) ;
var TOP _CLOSE = unsafeCastStringToDOMTopLevelType ( 'close' ) ;
var TOP _COMPOSITION _END = unsafeCastStringToDOMTopLevelType ( 'compositionend' ) ;
var TOP _COMPOSITION _START = unsafeCastStringToDOMTopLevelType ( 'compositionstart' ) ;
var TOP _COMPOSITION _UPDATE = unsafeCastStringToDOMTopLevelType ( 'compositionupdate' ) ;
var TOP _CONTEXT _MENU = unsafeCastStringToDOMTopLevelType ( 'contextmenu' ) ;
var TOP _COPY = unsafeCastStringToDOMTopLevelType ( 'copy' ) ;
var TOP _CUT = unsafeCastStringToDOMTopLevelType ( 'cut' ) ;
var TOP _DOUBLE _CLICK = unsafeCastStringToDOMTopLevelType ( 'dblclick' ) ;
var TOP _DRAG = unsafeCastStringToDOMTopLevelType ( 'drag' ) ;
var TOP _DRAG _END = unsafeCastStringToDOMTopLevelType ( 'dragend' ) ;
var TOP _DRAG _ENTER = unsafeCastStringToDOMTopLevelType ( 'dragenter' ) ;
var TOP _DRAG _EXIT = unsafeCastStringToDOMTopLevelType ( 'dragexit' ) ;
var TOP _DRAG _LEAVE = unsafeCastStringToDOMTopLevelType ( 'dragleave' ) ;
var TOP _DRAG _OVER = unsafeCastStringToDOMTopLevelType ( 'dragover' ) ;
var TOP _DRAG _START = unsafeCastStringToDOMTopLevelType ( 'dragstart' ) ;
var TOP _DROP = unsafeCastStringToDOMTopLevelType ( 'drop' ) ;
var TOP _DURATION _CHANGE = unsafeCastStringToDOMTopLevelType ( 'durationchange' ) ;
var TOP _EMPTIED = unsafeCastStringToDOMTopLevelType ( 'emptied' ) ;
var TOP _ENCRYPTED = unsafeCastStringToDOMTopLevelType ( 'encrypted' ) ;
var TOP _ENDED = unsafeCastStringToDOMTopLevelType ( 'ended' ) ;
var TOP _ERROR = unsafeCastStringToDOMTopLevelType ( 'error' ) ;
var TOP _FOCUS = unsafeCastStringToDOMTopLevelType ( 'focus' ) ;
var TOP _INPUT = unsafeCastStringToDOMTopLevelType ( 'input' ) ;
var TOP _KEY _DOWN = unsafeCastStringToDOMTopLevelType ( 'keydown' ) ;
var TOP _KEY _PRESS = unsafeCastStringToDOMTopLevelType ( 'keypress' ) ;
var TOP _KEY _UP = unsafeCastStringToDOMTopLevelType ( 'keyup' ) ;
var TOP _LOAD = unsafeCastStringToDOMTopLevelType ( 'load' ) ;
var TOP _LOAD _START = unsafeCastStringToDOMTopLevelType ( 'loadstart' ) ;
var TOP _LOADED _DATA = unsafeCastStringToDOMTopLevelType ( 'loadeddata' ) ;
var TOP _LOADED _METADATA = unsafeCastStringToDOMTopLevelType ( 'loadedmetadata' ) ;
var TOP _MOUSE _DOWN = unsafeCastStringToDOMTopLevelType ( 'mousedown' ) ;
var TOP _MOUSE _MOVE = unsafeCastStringToDOMTopLevelType ( 'mousemove' ) ;
var TOP _MOUSE _OUT = unsafeCastStringToDOMTopLevelType ( 'mouseout' ) ;
var TOP _MOUSE _OVER = unsafeCastStringToDOMTopLevelType ( 'mouseover' ) ;
var TOP _MOUSE _UP = unsafeCastStringToDOMTopLevelType ( 'mouseup' ) ;
var TOP _PASTE = unsafeCastStringToDOMTopLevelType ( 'paste' ) ;
var TOP _PAUSE = unsafeCastStringToDOMTopLevelType ( 'pause' ) ;
var TOP _PLAY = unsafeCastStringToDOMTopLevelType ( 'play' ) ;
var TOP _PLAYING = unsafeCastStringToDOMTopLevelType ( 'playing' ) ;
var TOP _PROGRESS = unsafeCastStringToDOMTopLevelType ( 'progress' ) ;
var TOP _RATE _CHANGE = unsafeCastStringToDOMTopLevelType ( 'ratechange' ) ;
var TOP _SCROLL = unsafeCastStringToDOMTopLevelType ( 'scroll' ) ;
var TOP _SEEKED = unsafeCastStringToDOMTopLevelType ( 'seeked' ) ;
var TOP _SEEKING = unsafeCastStringToDOMTopLevelType ( 'seeking' ) ;
var TOP _SELECTION _CHANGE = unsafeCastStringToDOMTopLevelType ( 'selectionchange' ) ;
var TOP _STALLED = unsafeCastStringToDOMTopLevelType ( 'stalled' ) ;
var TOP _SUSPEND = unsafeCastStringToDOMTopLevelType ( 'suspend' ) ;
var TOP _TEXT _INPUT = unsafeCastStringToDOMTopLevelType ( 'textInput' ) ;
var TOP _TIME _UPDATE = unsafeCastStringToDOMTopLevelType ( 'timeupdate' ) ;
var TOP _TOGGLE = unsafeCastStringToDOMTopLevelType ( 'toggle' ) ;
var TOP _TOUCH _CANCEL = unsafeCastStringToDOMTopLevelType ( 'touchcancel' ) ;
var TOP _TOUCH _END = unsafeCastStringToDOMTopLevelType ( 'touchend' ) ;
var TOP _TOUCH _MOVE = unsafeCastStringToDOMTopLevelType ( 'touchmove' ) ;
var TOP _TOUCH _START = unsafeCastStringToDOMTopLevelType ( 'touchstart' ) ;
var TOP _TRANSITION _END = unsafeCastStringToDOMTopLevelType ( getVendorPrefixedEventName ( 'transitionend' ) ) ;
var TOP _VOLUME _CHANGE = unsafeCastStringToDOMTopLevelType ( 'volumechange' ) ;
var TOP _WAITING = unsafeCastStringToDOMTopLevelType ( 'waiting' ) ;
var TOP _WHEEL = unsafeCastStringToDOMTopLevelType ( 'wheel' ) ;
// List of events that need to be individually attached to media elements.
// Note that events in this list will *not* be listened to at the top level
// unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.
2017-12-10 21:51:33 +01:00
var findDOMNode = ReactDOM . findDOMNode ;
2018-09-20 02:56:13 +02:00
// Keep in sync with ReactDOMUnstableNativeDependencies.js
// and ReactDOM.js:
var _ReactDOM$ _ _SECRET _IN = ReactDOM . _ _SECRET _INTERNALS _DO _NOT _USE _OR _YOU _WILL _BE _FIRED . Events ;
var getInstanceFromNode = _ReactDOM$ _ _SECRET _IN [ 0 ] ;
var getNodeFromInstance = _ReactDOM$ _ _SECRET _IN [ 1 ] ;
var getFiberCurrentPropsFromNode = _ReactDOM$ _ _SECRET _IN [ 2 ] ;
var injectEventPluginsByName = _ReactDOM$ _ _SECRET _IN [ 3 ] ;
var eventNameDispatchConfigs = _ReactDOM$ _ _SECRET _IN [ 4 ] ;
var accumulateTwoPhaseDispatches = _ReactDOM$ _ _SECRET _IN [ 5 ] ;
var accumulateDirectDispatches = _ReactDOM$ _ _SECRET _IN [ 6 ] ;
var enqueueStateRestore = _ReactDOM$ _ _SECRET _IN [ 7 ] ;
var restoreStateIfNeeded = _ReactDOM$ _ _SECRET _IN [ 8 ] ;
var dispatchEvent = _ReactDOM$ _ _SECRET _IN [ 9 ] ;
var runEventsInBatch = _ReactDOM$ _ _SECRET _IN [ 10 ] ;
2017-10-14 18:40:54 +02:00
function Event ( suffix ) { }
2018-09-20 02:56:13 +02:00
var hasWarnedAboutDeprecatedMockComponent = false ;
2017-10-14 18:40:54 +02:00
/ * *
* @ class ReactTestUtils
* /
2018-09-20 02:56:13 +02:00
/ * *
* Simulates a top level event being dispatched from a raw event that occurred
* on an ` Element ` node .
* @ param { number } topLevelType A number from ` TopLevelEventTypes `
* @ param { ! Element } node The dom to simulate an event occurring on .
* @ param { ? Event } fakeNativeEvent Fake native event to use in SyntheticEvent .
* /
function simulateNativeEventOnNode ( topLevelType , node , fakeNativeEvent ) {
fakeNativeEvent . target = node ;
dispatchEvent ( topLevelType , fakeNativeEvent ) ;
}
/ * *
* Simulates a top level event being dispatched from a raw event that occurred
* on the ` ReactDOMComponent ` ` comp ` .
* @ param { Object } topLevelType A type from ` BrowserEventConstants.topLevelTypes ` .
* @ param { ! ReactDOMComponent } comp
* @ param { ? Event } fakeNativeEvent Fake native event to use in SyntheticEvent .
* /
function simulateNativeEventOnDOMComponent ( topLevelType , comp , fakeNativeEvent ) {
simulateNativeEventOnNode ( topLevelType , findDOMNode ( comp ) , fakeNativeEvent ) ;
}
2017-10-14 18:40:54 +02:00
function findAllInRenderedFiberTreeInternal ( fiber , test ) {
if ( ! fiber ) {
return [ ] ;
}
2017-12-10 21:51:33 +01:00
var currentParent = findCurrentFiberUsingSlowPath ( fiber ) ;
2017-10-14 18:40:54 +02:00
if ( ! currentParent ) {
return [ ] ;
}
var node = currentParent ;
var ret = [ ] ;
while ( true ) {
2018-09-20 02:56:13 +02:00
if ( node . tag === HostComponent || node . tag === HostText || node . tag === ClassComponent || node . tag === ClassComponentLazy || node . tag === FunctionalComponent || node . tag === FunctionalComponentLazy ) {
2017-10-14 18:40:54 +02:00
var publicInst = node . stateNode ;
if ( test ( publicInst ) ) {
ret . push ( publicInst ) ;
}
}
if ( node . child ) {
2018-09-20 02:56:13 +02:00
node . child . return = node ;
2017-10-14 18:40:54 +02:00
node = node . child ;
continue ;
}
if ( node === currentParent ) {
return ret ;
}
while ( ! node . sibling ) {
2018-09-20 02:56:13 +02:00
if ( ! node . return || node . return === currentParent ) {
2017-10-14 18:40:54 +02:00
return ret ;
}
2018-09-20 02:56:13 +02:00
node = node . return ;
2017-10-14 18:40:54 +02:00
}
2018-09-20 02:56:13 +02:00
node . sibling . return = node . return ;
2017-10-14 18:40:54 +02:00
node = node . sibling ;
}
}
2018-09-20 02:56:13 +02:00
function validateClassInstance ( inst , methodName ) {
if ( ! inst ) {
// This is probably too relaxed but it's existing behavior.
return ;
}
if ( get ( inst ) ) {
// This is a public instance indeed.
return ;
}
var received = void 0 ;
var stringified = '' + inst ;
if ( Array . isArray ( inst ) ) {
received = 'an array' ;
} else if ( inst && inst . nodeType === ELEMENT _NODE && inst . tagName ) {
received = 'a DOM node' ;
} else if ( stringified === '[object Object]' ) {
received = 'object with keys {' + Object . keys ( inst ) . join ( ', ' ) + '}' ;
} else {
received = stringified ;
}
invariant ( false , '%s(...): the first argument must be a React class instance. Instead received: %s.' , methodName , received ) ;
}
2017-10-14 18:40:54 +02:00
/ * *
* Utilities for making it easy to test React components .
*
2017-12-10 21:51:33 +01:00
* See https : //reactjs.org/docs/test-utils.html
2017-10-14 18:40:54 +02:00
*
* Todo : Support the entire DOM . scry query syntax . For now , these simple
* utilities will suffice for testing purposes .
* @ lends ReactTestUtils
* /
var ReactTestUtils = {
renderIntoDocument : function ( element ) {
var div = document . createElement ( 'div' ) ;
// None of our tests actually require attaching the container to the
// DOM, and doing so creates a mess that we rely on test isolation to
// clean up, so we're going to stop honoring the name of this method
// (and probably rename it eventually) if no problems arise.
// document.documentElement.appendChild(div);
2017-12-10 21:51:33 +01:00
return ReactDOM . render ( element , div ) ;
2017-10-14 18:40:54 +02:00
} ,
isElement : function ( element ) {
2017-12-10 21:51:33 +01:00
return React . isValidElement ( element ) ;
2017-10-14 18:40:54 +02:00
} ,
isElementOfType : function ( inst , convenienceConstructor ) {
2017-12-10 21:51:33 +01:00
return React . isValidElement ( inst ) && inst . type === convenienceConstructor ;
2017-10-14 18:40:54 +02:00
} ,
isDOMComponent : function ( inst ) {
2018-09-20 02:56:13 +02:00
return ! ! ( inst && inst . nodeType === ELEMENT _NODE && inst . tagName ) ;
2017-10-14 18:40:54 +02:00
} ,
isDOMComponentElement : function ( inst ) {
2017-12-10 21:51:33 +01:00
return ! ! ( inst && React . isValidElement ( inst ) && ! ! inst . tagName ) ;
2017-10-14 18:40:54 +02:00
} ,
isCompositeComponent : function ( inst ) {
if ( ReactTestUtils . isDOMComponent ( inst ) ) {
// Accessing inst.setState warns; just return false as that'll be what
// this returns when we have DOM nodes as refs directly
return false ;
}
return inst != null && typeof inst . render === 'function' && typeof inst . setState === 'function' ;
} ,
isCompositeComponentWithType : function ( inst , type ) {
if ( ! ReactTestUtils . isCompositeComponent ( inst ) ) {
return false ;
}
2017-12-10 21:51:33 +01:00
var internalInstance = get ( inst ) ;
var constructor = internalInstance . type ;
2017-10-14 18:40:54 +02:00
return constructor === type ;
} ,
findAllInRenderedTree : function ( inst , test ) {
2018-09-20 02:56:13 +02:00
validateClassInstance ( inst , 'findAllInRenderedTree' ) ;
2017-10-14 18:40:54 +02:00
if ( ! inst ) {
return [ ] ;
}
2017-12-10 21:51:33 +01:00
var internalInstance = get ( inst ) ;
return findAllInRenderedFiberTreeInternal ( internalInstance , test ) ;
2017-10-14 18:40:54 +02:00
} ,
/ * *
* Finds all instance of components in the rendered tree that are DOM
* components with the class name matching ` className ` .
* @ return { array } an array of all the matches .
* /
scryRenderedDOMComponentsWithClass : function ( root , classNames ) {
2018-09-20 02:56:13 +02:00
validateClassInstance ( root , 'scryRenderedDOMComponentsWithClass' ) ;
2017-10-14 18:40:54 +02:00
return ReactTestUtils . findAllInRenderedTree ( root , function ( inst ) {
if ( ReactTestUtils . isDOMComponent ( inst ) ) {
var className = inst . className ;
if ( typeof className !== 'string' ) {
// SVG, probably.
className = inst . getAttribute ( 'class' ) || '' ;
}
var classList = className . split ( /\s+/ ) ;
if ( ! Array . isArray ( classNames ) ) {
! ( classNames !== undefined ) ? invariant ( false , 'TestUtils.scryRenderedDOMComponentsWithClass expects a className as a second argument.' ) : void 0 ;
classNames = classNames . split ( /\s+/ ) ;
}
return classNames . every ( function ( name ) {
return classList . indexOf ( name ) !== - 1 ;
} ) ;
}
return false ;
} ) ;
} ,
/ * *
* Like scryRenderedDOMComponentsWithClass but expects there to be one result ,
* and returns that one result , or throws exception if there is any other
* number of matches besides one .
* @ return { ! ReactDOMComponent } The one match .
* /
findRenderedDOMComponentWithClass : function ( root , className ) {
2018-09-20 02:56:13 +02:00
validateClassInstance ( root , 'findRenderedDOMComponentWithClass' ) ;
2017-10-14 18:40:54 +02:00
var all = ReactTestUtils . scryRenderedDOMComponentsWithClass ( root , className ) ;
if ( all . length !== 1 ) {
throw new Error ( 'Did not find exactly one match (found: ' + all . length + ') ' + 'for class:' + className ) ;
}
return all [ 0 ] ;
} ,
/ * *
* Finds all instance of components in the rendered tree that are DOM
* components with the tag name matching ` tagName ` .
* @ return { array } an array of all the matches .
* /
scryRenderedDOMComponentsWithTag : function ( root , tagName ) {
2018-09-20 02:56:13 +02:00
validateClassInstance ( root , 'scryRenderedDOMComponentsWithTag' ) ;
2017-10-14 18:40:54 +02:00
return ReactTestUtils . findAllInRenderedTree ( root , function ( inst ) {
return ReactTestUtils . isDOMComponent ( inst ) && inst . tagName . toUpperCase ( ) === tagName . toUpperCase ( ) ;
} ) ;
} ,
/ * *
* Like scryRenderedDOMComponentsWithTag but expects there to be one result ,
* and returns that one result , or throws exception if there is any other
* number of matches besides one .
* @ return { ! ReactDOMComponent } The one match .
* /
findRenderedDOMComponentWithTag : function ( root , tagName ) {
2018-09-20 02:56:13 +02:00
validateClassInstance ( root , 'findRenderedDOMComponentWithTag' ) ;
2017-10-14 18:40:54 +02:00
var all = ReactTestUtils . scryRenderedDOMComponentsWithTag ( root , tagName ) ;
if ( all . length !== 1 ) {
throw new Error ( 'Did not find exactly one match (found: ' + all . length + ') ' + 'for tag:' + tagName ) ;
}
return all [ 0 ] ;
} ,
/ * *
* Finds all instances of components with type equal to ` componentType ` .
* @ return { array } an array of all the matches .
* /
scryRenderedComponentsWithType : function ( root , componentType ) {
2018-09-20 02:56:13 +02:00
validateClassInstance ( root , 'scryRenderedComponentsWithType' ) ;
2017-10-14 18:40:54 +02:00
return ReactTestUtils . findAllInRenderedTree ( root , function ( inst ) {
return ReactTestUtils . isCompositeComponentWithType ( inst , componentType ) ;
} ) ;
} ,
/ * *
* Same as ` scryRenderedComponentsWithType ` but expects there to be one result
* and returns that one result , or throws exception if there is any other
* number of matches besides one .
* @ return { ! ReactComponent } The one match .
* /
findRenderedComponentWithType : function ( root , componentType ) {
2018-09-20 02:56:13 +02:00
validateClassInstance ( root , 'findRenderedComponentWithType' ) ;
2017-10-14 18:40:54 +02:00
var all = ReactTestUtils . scryRenderedComponentsWithType ( root , componentType ) ;
if ( all . length !== 1 ) {
throw new Error ( 'Did not find exactly one match (found: ' + all . length + ') ' + 'for componentType:' + componentType ) ;
}
return all [ 0 ] ;
} ,
/ * *
* Pass a mocked component module to this method to augment it with
* useful methods that allow it to be used as a dummy React component .
* Instead of rendering as usual , the component will become a simple
* < div > containing any provided children .
*
* @ param { object } module the mock function object exported from a
* module that defines the component to be mocked
* @ param { ? string } mockTagName optional dummy root tag name to return
* from render method ( overrides
* module . mockTagName if provided )
* @ return { object } the ReactTestUtils object ( for chaining )
* /
mockComponent : function ( module , mockTagName ) {
2018-09-20 02:56:13 +02:00
if ( ! hasWarnedAboutDeprecatedMockComponent ) {
hasWarnedAboutDeprecatedMockComponent = true ;
lowPriorityWarning$1 ( false , 'ReactTestUtils.mockComponent() is deprecated. ' + 'Use shallow rendering or jest.mock() instead.\n\n' + 'See https://fb.me/test-utils-mock-component for more information.' ) ;
}
2017-10-14 18:40:54 +02:00
mockTagName = mockTagName || module . mockTagName || 'div' ;
module . prototype . render . mockImplementation ( function ( ) {
2017-12-10 21:51:33 +01:00
return React . createElement ( mockTagName , null , this . props . children ) ;
2017-10-14 18:40:54 +02:00
} ) ;
return this ;
} ,
nativeTouchData : function ( x , y ) {
return {
touches : [ { pageX : x , pageY : y } ]
} ;
} ,
Simulate : null ,
SimulateNative : { }
} ;
/ * *
* Exports :
*
* - ` ReactTestUtils.Simulate.click(Element) `
* - ` ReactTestUtils.Simulate.mouseMove(Element) `
* - ` ReactTestUtils.Simulate.change(Element) `
* - ... ( All keys from event plugin ` eventTypes ` objects )
* /
function makeSimulator ( eventType ) {
return function ( domNode , eventData ) {
2017-12-10 21:51:33 +01:00
! ! React . isValidElement ( domNode ) ? invariant ( false , 'TestUtils.Simulate expected a DOM node as the first argument but received a React element. Pass the DOM node you wish to simulate the event on instead. Note that TestUtils.Simulate will not work if you are using shallow rendering.' ) : void 0 ;
2017-10-14 18:40:54 +02:00
! ! ReactTestUtils . isCompositeComponent ( domNode ) ? invariant ( false , 'TestUtils.Simulate expected a DOM node as the first argument but received a component instance. Pass the DOM node you wish to simulate the event on instead.' ) : void 0 ;
2018-09-20 02:56:13 +02:00
var dispatchConfig = eventNameDispatchConfigs [ eventType ] ;
2017-10-14 18:40:54 +02:00
var fakeNativeEvent = new Event ( ) ;
fakeNativeEvent . target = domNode ;
fakeNativeEvent . type = eventType . toLowerCase ( ) ;
// We don't use SyntheticEvent.getPooled in order to not have to worry about
// properly destroying any properties assigned from `eventData` upon release
2018-09-20 02:56:13 +02:00
var targetInst = getInstanceFromNode ( domNode ) ;
var event = new SyntheticEvent ( dispatchConfig , targetInst , fakeNativeEvent , domNode ) ;
2017-10-14 18:40:54 +02:00
// Since we aren't using pooling, always persist the event. This will make
// sure it's marked and won't warn when setting additional properties.
event . persist ( ) ;
_assign ( event , eventData ) ;
if ( dispatchConfig . phasedRegistrationNames ) {
2018-09-20 02:56:13 +02:00
accumulateTwoPhaseDispatches ( event ) ;
2017-10-14 18:40:54 +02:00
} else {
2018-09-20 02:56:13 +02:00
accumulateDirectDispatches ( event ) ;
2017-10-14 18:40:54 +02:00
}
2017-12-10 21:51:33 +01:00
ReactDOM . unstable _batchedUpdates ( function ( ) {
2017-10-14 18:40:54 +02:00
// Normally extractEvent enqueues a state restore, but we'll just always
// do that since we we're by-passing it here.
2018-09-20 02:56:13 +02:00
enqueueStateRestore ( domNode ) ;
runEventsInBatch ( event , true ) ;
2017-10-14 18:40:54 +02:00
} ) ;
2018-09-20 02:56:13 +02:00
restoreStateIfNeeded ( ) ;
2017-10-14 18:40:54 +02:00
} ;
}
function buildSimulators ( ) {
ReactTestUtils . Simulate = { } ;
2018-09-20 02:56:13 +02:00
var eventType = void 0 ;
for ( eventType in eventNameDispatchConfigs ) {
2017-10-14 18:40:54 +02:00
/ * *
* @ param { ! Element | ReactDOMComponent } domComponentOrNode
* @ param { ? object } eventData Fake event data to use in SyntheticEvent .
* /
ReactTestUtils . Simulate [ eventType ] = makeSimulator ( eventType ) ;
}
}
buildSimulators ( ) ;
/ * *
* Exports :
*
* - ` ReactTestUtils.SimulateNative.click(Element/ReactDOMComponent) `
* - ` ReactTestUtils.SimulateNative.mouseMove(Element/ReactDOMComponent) `
* - ` ReactTestUtils.SimulateNative.mouseIn/ReactDOMComponent) `
* - ` ReactTestUtils.SimulateNative.mouseOut(Element/ReactDOMComponent) `
* - ... ( All keys from ` BrowserEventConstants.topLevelTypes ` )
*
* Note : Top level event types are a subset of the entire set of handler types
* ( which include a broader set of "synthetic" events ) . For example , onDragDone
* is a synthetic event . Except when testing an event plugin or React ' s event
* handling code specifically , you probably want to use ReactTestUtils . Simulate
* to dispatch synthetic events .
* /
2018-09-20 02:56:13 +02:00
function makeNativeSimulator ( eventType , topLevelType ) {
2017-10-14 18:40:54 +02:00
return function ( domComponentOrNode , nativeEventData ) {
var fakeNativeEvent = new Event ( eventType ) ;
_assign ( fakeNativeEvent , nativeEventData ) ;
if ( ReactTestUtils . isDOMComponent ( domComponentOrNode ) ) {
2018-09-20 02:56:13 +02:00
simulateNativeEventOnDOMComponent ( topLevelType , domComponentOrNode , fakeNativeEvent ) ;
2017-10-14 18:40:54 +02:00
} else if ( domComponentOrNode . tagName ) {
// Will allow on actual dom nodes.
2018-09-20 02:56:13 +02:00
simulateNativeEventOnNode ( topLevelType , domComponentOrNode , fakeNativeEvent ) ;
2017-10-14 18:40:54 +02:00
}
} ;
}
2018-09-20 02:56:13 +02:00
[ [ TOP _ABORT , 'abort' ] , [ TOP _ANIMATION _END , 'animationEnd' ] , [ TOP _ANIMATION _ITERATION , 'animationIteration' ] , [ TOP _ANIMATION _START , 'animationStart' ] , [ TOP _BLUR , 'blur' ] , [ TOP _CAN _PLAY _THROUGH , 'canPlayThrough' ] , [ TOP _CAN _PLAY , 'canPlay' ] , [ TOP _CANCEL , 'cancel' ] , [ TOP _CHANGE , 'change' ] , [ TOP _CLICK , 'click' ] , [ TOP _CLOSE , 'close' ] , [ TOP _COMPOSITION _END , 'compositionEnd' ] , [ TOP _COMPOSITION _START , 'compositionStart' ] , [ TOP _COMPOSITION _UPDATE , 'compositionUpdate' ] , [ TOP _CONTEXT _MENU , 'contextMenu' ] , [ TOP _COPY , 'copy' ] , [ TOP _CUT , 'cut' ] , [ TOP _DOUBLE _CLICK , 'doubleClick' ] , [ TOP _DRAG _END , 'dragEnd' ] , [ TOP _DRAG _ENTER , 'dragEnter' ] , [ TOP _DRAG _EXIT , 'dragExit' ] , [ TOP _DRAG _LEAVE , 'dragLeave' ] , [ TOP _DRAG _OVER , 'dragOver' ] , [ TOP _DRAG _START , 'dragStart' ] , [ TOP _DRAG , 'drag' ] , [ TOP _DROP , 'drop' ] , [ TOP _DURATION _CHANGE , 'durationChange' ] , [ TOP _EMPTIED , 'emptied' ] , [ TOP _ENCRYPTED , 'encrypted' ] , [ TOP _ENDED , 'ended' ] , [ TOP _ERROR , 'error' ] , [ TOP _FOCUS , 'focus' ] , [ TOP _INPUT , 'input' ] , [ TOP _KEY _DOWN , 'keyDown' ] , [ TOP _KEY _PRESS , 'keyPress' ] , [ TOP _KEY _UP , 'keyUp' ] , [ TOP _LOAD _START , 'loadStart' ] , [ TOP _LOAD _START , 'loadStart' ] , [ TOP _LOAD , 'load' ] , [ TOP _LOADED _DATA , 'loadedData' ] , [ TOP _LOADED _METADATA , 'loadedMetadata' ] , [ TOP _MOUSE _DOWN , 'mouseDown' ] , [ TOP _MOUSE _MOVE , 'mouseMove' ] , [ TOP _MOUSE _OUT , 'mouseOut' ] , [ TOP _MOUSE _OVER , 'mouseOver' ] , [ TOP _MOUSE _UP , 'mouseUp' ] , [ TOP _PASTE , 'paste' ] , [ TOP _PAUSE , 'pause' ] , [ TOP _PLAY , 'play' ] , [ TOP _PLAYING , 'playing' ] , [ TOP _PROGRESS , 'progress' ] , [ TOP _RATE _CHANGE , 'rateChange' ] , [ TOP _SCROLL , 'scroll' ] , [ TOP _SEEKED , 'seeked' ] , [ TOP _SEEKING , 'seeking' ] , [ TOP _SELECTION _CHANGE , 'selectionChange' ] , [ TOP _STALLED , 'stalled' ] , [ TOP _SUSPEND , 'suspend' ] , [ TOP _TEXT _INPUT , 'textInput' ] , [ TOP _TIME _UPDATE , 'timeUpdate' ] , [ TOP _TOGGLE , 'toggle' ] , [ TOP _TOUCH _CANCEL , 'touchCancel' ] , [ TOP _TOUCH _END , 'touchEnd' ] , [ TOP _TOUCH _MOVE , 'touchMove' ] , [ TOP _TOUCH _START , 'touchStart' ] , [ TOP _TRANSITION _END , 'transitionEnd' ] , [ TOP _VOLUME _CHANGE , 'volumeChange' ] , [ TOP _WAITING , 'waiting' ] , [ TOP _WHEEL , 'wheel' ] ] . forEach ( function ( _ref ) {
var topLevelType = _ref [ 0 ] ,
eventType = _ref [ 1 ] ;
2017-10-14 18:40:54 +02:00
/ * *
* @ param { ! Element | ReactDOMComponent } domComponentOrNode
* @ param { ? Event } nativeEventData Fake native event to use in SyntheticEvent .
* /
2018-09-20 02:56:13 +02:00
ReactTestUtils . SimulateNative [ eventType ] = makeNativeSimulator ( eventType , topLevelType ) ;
2017-10-14 18:40:54 +02:00
} ) ;
2017-12-10 21:51:33 +01:00
var ReactTestUtils$2 = Object . freeze ( {
default : ReactTestUtils
} ) ;
var ReactTestUtils$3 = ( ReactTestUtils$2 && ReactTestUtils ) || ReactTestUtils$2 ;
// TODO: decide on the top-level export form.
// This is hacky but makes it work with both Rollup and Jest.
2018-09-20 02:56:13 +02:00
var testUtils = ReactTestUtils$3 . default || ReactTestUtils$3 ;
2017-12-10 21:51:33 +01:00
module . exports = testUtils ;
} ) ( ) ;
2017-10-14 18:40:54 +02:00
}