mirror of
https://github.com/status-im/react-native.git
synced 2025-02-03 21:24:31 +00:00
bbceb48dbb
Summary: When Jest is mocking native components that are assigned a ref with an arrow function, a warning is generated about stateless components which can not have a ref. This does not happen when the ref is assigned directly. Fixes #16045. <!-- Thank you for sending the PR! We appreciate you spending the time to work on these changes. Help us understand your motivation by explaining why you decided to make this change. You can learn more about contributing to React Native here: http://facebook.github.io/react-native/docs/contributing.html Happy contributing! --> The test provided in the related issue is used to validate the fix. I don't know how to detect console warnings in a Jest test. Closes https://github.com/facebook/react-native/pull/16046 Differential Revision: D6017903 Pulled By: ericnakagawa fbshipit-source-id: a7ed61c39f141a4094f08fc875289a7a79ebe9e8
326 lines
9.1 KiB
JavaScript
326 lines
9.1 KiB
JavaScript
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
'use strict';
|
|
|
|
const mockComponent = require.requireActual('./mockComponent');
|
|
|
|
require.requireActual('../Libraries/polyfills/babelHelpers.js');
|
|
require.requireActual('../Libraries/polyfills/Object.es7.js');
|
|
require.requireActual('../Libraries/polyfills/error-guard');
|
|
|
|
global.__DEV__ = true;
|
|
|
|
global.Promise = require.requireActual('promise');
|
|
global.regeneratorRuntime = require.requireActual('regenerator-runtime/runtime');
|
|
|
|
global.requestAnimationFrame = function(callback) {
|
|
setTimeout(callback, 0);
|
|
};
|
|
global.cancelAnimationFrame = function(id) {
|
|
clearTimeout(id);
|
|
};
|
|
|
|
jest
|
|
.mock('setupDevtools')
|
|
.mock('npmlog');
|
|
|
|
// there's a __mock__ for it.
|
|
jest.setMock('ErrorUtils', require('ErrorUtils'));
|
|
|
|
jest
|
|
.mock('InitializeCore', () => {})
|
|
.mock('Image', () => mockComponent('Image'))
|
|
.mock('Text', () => mockComponent('Text'))
|
|
.mock('TextInput', () => mockComponent('TextInput'))
|
|
.mock('Modal', () => mockComponent('Modal'))
|
|
.mock('View', () => mockComponent('View'))
|
|
.mock('RefreshControl', () => require.requireMock('RefreshControlMock'))
|
|
.mock('ScrollView', () => require.requireMock('ScrollViewMock'))
|
|
.mock(
|
|
'ActivityIndicator',
|
|
() => mockComponent('ActivityIndicator'),
|
|
)
|
|
.mock('ListView', () => require.requireMock('ListViewMock'))
|
|
.mock('ListViewDataSource', () => {
|
|
const DataSource = require.requireActual('ListViewDataSource');
|
|
DataSource.prototype.toJSON = function() {
|
|
function ListViewDataSource(dataBlob) {
|
|
this.items = 0;
|
|
// Ensure this doesn't throw.
|
|
try {
|
|
Object.keys(dataBlob).forEach(key => {
|
|
this.items += dataBlob[key] && (
|
|
dataBlob[key].length || dataBlob[key].size || 0
|
|
);
|
|
});
|
|
} catch (e) {
|
|
this.items = 'unknown';
|
|
}
|
|
}
|
|
|
|
return new ListViewDataSource(this._dataBlob);
|
|
};
|
|
return DataSource;
|
|
})
|
|
.mock('AnimatedImplementation', () => {
|
|
const AnimatedImplementation = require.requireActual('AnimatedImplementation');
|
|
const oldCreate = AnimatedImplementation.createAnimatedComponent;
|
|
AnimatedImplementation.createAnimatedComponent = function(Component) {
|
|
const Wrapped = oldCreate(Component);
|
|
Wrapped.__skipSetNativeProps_FOR_TESTS_ONLY = true;
|
|
return Wrapped;
|
|
};
|
|
return AnimatedImplementation;
|
|
})
|
|
.mock('ReactNative', () => {
|
|
const ReactNative = require.requireActual('ReactNative');
|
|
const NativeMethodsMixin =
|
|
ReactNative.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.NativeMethodsMixin;
|
|
[
|
|
'measure',
|
|
'measureInWindow',
|
|
'measureLayout',
|
|
'setNativeProps',
|
|
'focus',
|
|
'blur',
|
|
].forEach((key) => {
|
|
let warned = false;
|
|
NativeMethodsMixin[key] = function() {
|
|
if (warned) {
|
|
return;
|
|
}
|
|
warned = true;
|
|
console.warn(
|
|
'Calling .' + key + '() in the test renderer environment is not ' +
|
|
'supported. Instead, mock out your components that use ' +
|
|
'findNodeHandle with replacements that don\'t rely on the ' +
|
|
'native environment.',
|
|
);
|
|
};
|
|
});
|
|
return ReactNative;
|
|
})
|
|
.mock('ensureComponentIsNative', () => () => true);
|
|
|
|
const mockEmptyObject = {};
|
|
const mockNativeModules = {
|
|
AlertManager: {
|
|
alertWithArgs: jest.fn(),
|
|
},
|
|
AppState: {
|
|
addEventListener: jest.fn(),
|
|
},
|
|
AsyncLocalStorage: {
|
|
multiGet: jest.fn((keys, callback) => process.nextTick(() => callback(null, []))),
|
|
multiSet: jest.fn((entries, callback) => process.nextTick(() => callback(null))),
|
|
multiRemove: jest.fn((keys, callback) => process.nextTick(() => callback(null))),
|
|
multiMerge: jest.fn((entries, callback) => process.nextTick(() => callback(null))),
|
|
clear: jest.fn(callback => process.nextTick(() => callback(null))),
|
|
getAllKeys: jest.fn(callback => process.nextTick(() => callback(null, []))),
|
|
},
|
|
BuildInfo: {
|
|
appVersion: '0',
|
|
buildVersion: '0',
|
|
},
|
|
Clipboard: {
|
|
setString: jest.fn(),
|
|
},
|
|
DataManager: {
|
|
queryData: jest.fn(),
|
|
},
|
|
DeviceInfo: {
|
|
Dimensions: {
|
|
window: {
|
|
fontScale: 2,
|
|
height: 1334,
|
|
scale: 2,
|
|
width: 750,
|
|
},
|
|
},
|
|
},
|
|
FacebookSDK: {
|
|
login: jest.fn(),
|
|
logout: jest.fn(),
|
|
queryGraphPath: jest.fn((path, method, params, callback) => callback()),
|
|
},
|
|
FbRelayNativeAdapter: {
|
|
updateCLC: jest.fn(),
|
|
},
|
|
GraphPhotoUpload: {
|
|
upload: jest.fn(),
|
|
},
|
|
I18n: {
|
|
translationsDictionary: JSON.stringify({
|
|
'Good bye, {name}!|Bye message': '\u{00A1}Adi\u{00F3}s {name}!',
|
|
}),
|
|
},
|
|
ImageLoader: {
|
|
getSize: jest.fn(
|
|
(url) => new Promise(() => ({width: 320, height: 240}))
|
|
),
|
|
prefetchImage: jest.fn(),
|
|
},
|
|
ImageViewManager: {
|
|
getSize: jest.fn(
|
|
(uri, success) => process.nextTick(() => success(320, 240))
|
|
),
|
|
prefetchImage: jest.fn(),
|
|
},
|
|
KeyboardObserver: {
|
|
addListener: jest.fn(),
|
|
removeListeners: jest.fn(),
|
|
},
|
|
Linking: {
|
|
openURL: jest.fn(),
|
|
canOpenURL: jest.fn(
|
|
() => new Promise((resolve) => resolve(true))
|
|
),
|
|
addEventListener: jest.fn(),
|
|
getInitialURL: jest.fn(
|
|
() => new Promise((resolve) => resolve())
|
|
),
|
|
removeEventListener: jest.fn(),
|
|
},
|
|
LocationObserver: {
|
|
getCurrentPosition: jest.fn(),
|
|
startObserving: jest.fn(),
|
|
stopObserving: jest.fn(),
|
|
},
|
|
ModalFullscreenViewManager: {},
|
|
NetInfo: {
|
|
fetch: jest.fn(
|
|
() => new Promise((resolve) => resolve())
|
|
),
|
|
addEventListener: jest.fn(),
|
|
isConnected: {
|
|
fetch: jest.fn(
|
|
() => new Promise((resolve) => resolve())
|
|
),
|
|
addEventListener: jest.fn(),
|
|
},
|
|
},
|
|
Networking: {
|
|
sendRequest: jest.fn(),
|
|
abortRequest: jest.fn(),
|
|
addListener: jest.fn(),
|
|
removeListeners: jest.fn(),
|
|
},
|
|
PushNotificationManager: {
|
|
presentLocalNotification: jest.fn(),
|
|
scheduleLocalNotification: jest.fn(),
|
|
cancelAllLocalNotifications: jest.fn(),
|
|
removeAllDeliveredNotifications: jest.fn(),
|
|
getDeliveredNotifications: jest.fn(callback => process.nextTick(() => [])),
|
|
removeDeliveredNotifications: jest.fn(),
|
|
setApplicationIconBadgeNumber: jest.fn(),
|
|
getApplicationIconBadgeNumber: jest.fn(callback => process.nextTick(() => callback(0))),
|
|
cancelLocalNotifications: jest.fn(),
|
|
getScheduledLocalNotifications: jest.fn(callback => process.nextTick(() => callback())),
|
|
requestPermissions: jest.fn(() => Promise.resolve({alert: true, badge: true, sound: true})),
|
|
abandonPermissions: jest.fn(),
|
|
checkPermissions: jest.fn(callback => process.nextTick(() => callback({alert: true, badge: true, sound: true}))),
|
|
getInitialNotification: jest.fn(() => Promise.resolve(null)),
|
|
addListener: jest.fn(),
|
|
removeListeners: jest.fn(),
|
|
},
|
|
SourceCode: {
|
|
scriptURL: null,
|
|
},
|
|
StatusBarManager: {
|
|
setColor: jest.fn(),
|
|
setStyle: jest.fn(),
|
|
setHidden: jest.fn(),
|
|
setNetworkActivityIndicatorVisible: jest.fn(),
|
|
setBackgroundColor: jest.fn(),
|
|
setTranslucent: jest.fn(),
|
|
},
|
|
Timing: {
|
|
createTimer: jest.fn(),
|
|
deleteTimer: jest.fn(),
|
|
},
|
|
UIManager: {
|
|
AndroidViewPager: {
|
|
Commands: {
|
|
setPage: jest.fn(),
|
|
setPageWithoutAnimation: jest.fn(),
|
|
},
|
|
},
|
|
blur: jest.fn(),
|
|
createView: jest.fn(),
|
|
dispatchViewManagerCommand: jest.fn(),
|
|
focus: jest.fn(),
|
|
setChildren: jest.fn(),
|
|
manageChildren: jest.fn(),
|
|
updateView: jest.fn(),
|
|
removeSubviewsFromContainerWithID: jest.fn(),
|
|
replaceExistingNonRootView: jest.fn(),
|
|
customBubblingEventTypes: {},
|
|
customDirectEventTypes: {},
|
|
AndroidTextInput: {
|
|
Commands: {},
|
|
},
|
|
ModalFullscreenView: {
|
|
Constants: {},
|
|
},
|
|
ScrollView: {
|
|
Constants: {},
|
|
},
|
|
View: {
|
|
Constants: {},
|
|
},
|
|
},
|
|
BlobModule: {
|
|
BLOB_URI_SCHEME: 'content',
|
|
BLOB_URI_HOST: null,
|
|
enableBlobSupport: jest.fn(),
|
|
disableBlobSupport: jest.fn(),
|
|
createFromParts: jest.fn(),
|
|
sendBlob: jest.fn(),
|
|
release: jest.fn(),
|
|
},
|
|
WebSocketModule: {
|
|
connect: jest.fn(),
|
|
send: jest.fn(),
|
|
sendBinary: jest.fn(),
|
|
ping: jest.fn(),
|
|
close: jest.fn(),
|
|
addListener: jest.fn(),
|
|
removeListeners: jest.fn(),
|
|
},
|
|
};
|
|
|
|
Object.keys(mockNativeModules).forEach(module => {
|
|
try {
|
|
jest.doMock(module, () => mockNativeModules[module]); // needed by FacebookSDK-test
|
|
} catch (e) {
|
|
jest.doMock(module, () => mockNativeModules[module], {virtual: true});
|
|
}
|
|
});
|
|
|
|
jest
|
|
.doMock('NativeModules', () => mockNativeModules)
|
|
.doMock('ReactNativePropRegistry', () => ({
|
|
register: id => id,
|
|
getByID: () => mockEmptyObject,
|
|
}));
|
|
|
|
jest.doMock('requireNativeComponent', () => {
|
|
const React = require('react');
|
|
|
|
return viewName => class extends React.Component {
|
|
render() {
|
|
return React.createElement(
|
|
viewName,
|
|
this.props,
|
|
this.props.children,
|
|
);
|
|
}
|
|
};
|
|
});
|