Skip to content

Commit

Permalink
Expose less internals for TestUtils (facebook#13539)
Browse files Browse the repository at this point in the history
* Expose less internals for TestUtils

* Keep EventPluginHub for www

* Reorder to simplify
  • Loading branch information
gaearon authored Sep 3, 2018
1 parent 0b74e95 commit 3c1dcd3
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -393,11 +393,8 @@ describe('ResponderEventPlugin', () => {
beforeEach(() => {
jest.resetModules();

const ReactDOM = require('react-dom');
const ReactDOMUnstableNativeDependencies = require('react-dom/unstable-native-dependencies');
EventPluginHub =
ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
.EventPluginHub;
EventPluginHub = require('events/EventPluginHub');
const injectComponentTree =
ReactDOMUnstableNativeDependencies.injectComponentTree;
ResponderEventPlugin =
Expand Down
22 changes: 14 additions & 8 deletions packages/react-dom/src/client/ReactDOM.js
Original file line number Diff line number Diff line change
Expand Up @@ -739,14 +739,20 @@ const ReactDOM: Object = {
unstable_flushControlled: DOMRenderer.flushControlled,

__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
// For TapEventPlugin which is popular in open source
EventPluginHub,
// Used by test-utils
EventPluginRegistry,
EventPropagators,
ReactControlledComponent,
ReactDOMComponentTree,
ReactDOMEventListener,
// Keep in sync with ReactDOMUnstableNativeDependencies.js
// and ReactTestUtils.js. This is an array for better minification.
Events: [
ReactDOMComponentTree.getInstanceFromNode,
ReactDOMComponentTree.getNodeFromInstance,
ReactDOMComponentTree.getFiberCurrentPropsFromNode,
EventPluginRegistry.eventNameDispatchConfigs,
EventPropagators.accumulateTwoPhaseDispatches,
EventPropagators.accumulateDirectDispatches,
ReactControlledComponent.enqueueStateRestore,
ReactControlledComponent.restoreStateIfNeeded,
ReactDOMEventListener.dispatchEvent,
EventPluginHub.runEventsInBatch,
],
},
};

Expand Down
2 changes: 2 additions & 0 deletions packages/react-dom/src/client/ReactDOMFB.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* @flow
*/

import * as EventPluginHub from 'events/EventPluginHub';
import * as ReactFiberTreeReflection from 'react-reconciler/reflection';
import * as ReactInstanceMap from 'shared/ReactInstanceMap';
import {addUserTimingListener} from 'shared/ReactFeatureFlags';
Expand All @@ -25,6 +26,7 @@ Object.assign(
ReactDOMComponentTree,
ReactInstanceMap,
// Used by www msite:
EventPluginHub,
TapEventPlugin,
// Perf experiment
addUserTimingListener,
Expand Down
56 changes: 25 additions & 31 deletions packages/react-dom/src/test-utils/ReactTestUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,22 @@ import {ELEMENT_NODE} from '../shared/HTMLNodeType';
import * as DOMTopLevelEventTypes from '../events/DOMTopLevelEventTypes';

const {findDOMNode} = ReactDOM;
const {
EventPluginHub,
EventPluginRegistry,
EventPropagators,
ReactControlledComponent,
ReactDOMComponentTree,
ReactDOMEventListener,
} = ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
// Keep in sync with ReactDOMUnstableNativeDependencies.js
// and ReactDOM.js:
const [
getInstanceFromNode,
/* eslint-disable no-unused-vars */
getNodeFromInstance,
getFiberCurrentPropsFromNode,
/* eslint-enable no-unused-vars */
eventNameDispatchConfigs,
accumulateTwoPhaseDispatches,
accumulateDirectDispatches,
enqueueStateRestore,
restoreStateIfNeeded,
dispatchEvent,
runEventsInBatch,
] = ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Events;

function Event(suffix) {}

Expand All @@ -50,7 +58,7 @@ let hasWarnedAboutDeprecatedMockComponent = false;
*/
function simulateNativeEventOnNode(topLevelType, node, fakeNativeEvent) {
fakeNativeEvent.target = node;
ReactDOMEventListener.dispatchEvent(topLevelType, fakeNativeEvent);
dispatchEvent(topLevelType, fakeNativeEvent);
}

/**
Expand Down Expand Up @@ -399,16 +407,15 @@ function makeSimulator(eventType) {
'a component instance. Pass the DOM node you wish to simulate the event on instead.',
);

const dispatchConfig =
EventPluginRegistry.eventNameDispatchConfigs[eventType];
const dispatchConfig = eventNameDispatchConfigs[eventType];

const 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
const targetInst = ReactDOMComponentTree.getInstanceFromNode(domNode);
const targetInst = getInstanceFromNode(domNode);
const event = new SyntheticEvent(
dispatchConfig,
targetInst,
Expand All @@ -422,26 +429,26 @@ function makeSimulator(eventType) {
Object.assign(event, eventData);

if (dispatchConfig.phasedRegistrationNames) {
EventPropagators.accumulateTwoPhaseDispatches(event);
accumulateTwoPhaseDispatches(event);
} else {
EventPropagators.accumulateDirectDispatches(event);
accumulateDirectDispatches(event);
}

ReactDOM.unstable_batchedUpdates(function() {
// Normally extractEvent enqueues a state restore, but we'll just always
// do that since we we're by-passing it here.
ReactControlledComponent.enqueueStateRestore(domNode);
EventPluginHub.runEventsInBatch(event, true);
enqueueStateRestore(domNode);
runEventsInBatch(event, true);
});
ReactControlledComponent.restoreStateIfNeeded();
restoreStateIfNeeded();
};
}

function buildSimulators() {
ReactTestUtils.Simulate = {};

let eventType;
for (eventType in EventPluginRegistry.eventNameDispatchConfigs) {
for (eventType in eventNameDispatchConfigs) {
/**
* @param {!Element|ReactDOMComponent} domComponentOrNode
* @param {?object} eventData Fake event data to use in SyntheticEvent.
Expand All @@ -450,19 +457,6 @@ function buildSimulators() {
}
}

// Rebuild ReactTestUtils.Simulate whenever event plugins are injected
const oldInjectEventPluginOrder =
EventPluginHub.injection.injectEventPluginOrder;
EventPluginHub.injection.injectEventPluginOrder = function() {
oldInjectEventPluginOrder.apply(this, arguments);
buildSimulators();
};
const oldInjectEventPlugins = EventPluginHub.injection.injectEventPluginsByName;
EventPluginHub.injection.injectEventPluginsByName = function() {
oldInjectEventPlugins.apply(this, arguments);
buildSimulators();
};

buildSimulators();

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ export function injectComponentTree(ComponentTree) {
export {ResponderEventPlugin, ResponderTouchHistoryStore};

// Inject react-dom's ComponentTree into this module.
const {
ReactDOMComponentTree,
} = ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
// Keep in sync with ReactDOM.js and ReactTestUtils.js:
const [
getInstanceFromNode,
getNodeFromInstance,
getFiberCurrentPropsFromNode,
] = ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Events;
EventPluginUtils.setComponentTree(
ReactDOMComponentTree.getFiberCurrentPropsFromNode,
ReactDOMComponentTree.getInstanceFromNode,
ReactDOMComponentTree.getNodeFromInstance,
getFiberCurrentPropsFromNode,
getInstanceFromNode,
getNodeFromInstance,
);

0 comments on commit 3c1dcd3

Please sign in to comment.