diff --git a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap index 08ce35433..ac686d63e 100644 --- a/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap +++ b/Libraries/Components/Touchable/__tests__/__snapshots__/TouchableHighlight-test.js.snap @@ -21,7 +21,10 @@ exports[`TouchableHighlight renders correctly 1`] = ` ] } testID={undefined}> - + Touchable diff --git a/Libraries/Components/View/__mocks__/View.js b/Libraries/Components/View/__mocks__/View.js deleted file mode 100644 index fa3eca60c..000000000 --- a/Libraries/Components/View/__mocks__/View.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * 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 React = require('React'); -const StyleSheetPropType = require('StyleSheetPropType'); -const ViewStylePropTypes = require('ViewStylePropTypes'); - -class View extends React.Component { - render() { - const {children, ...props} = this.props; - return React.createElement('View', props, children); - } -} - -View.propTypes = { - style: StyleSheetPropType(ViewStylePropTypes), -}; - -module.exports = View; diff --git a/Libraries/Image/__mocks__/Image.js b/Libraries/Image/__mocks__/Image.js deleted file mode 100644 index 03a8c0e93..000000000 --- a/Libraries/Image/__mocks__/Image.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * 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 ImageResizeMode = require('ImageResizeMode'); -const React = require('React'); -const {Component} = React; - -class Image extends Component { - static get resizeMode() { - return ImageResizeMode; - } - render() { - const {children, ...props} = this.props; - return React.createElement('Image', props, children); - } -} - -module.exports = Image; diff --git a/Libraries/Network/__tests__/XMLHttpRequest-test.js b/Libraries/Network/__tests__/XMLHttpRequest-test.js index 7b3d7a5e0..aca4b6b7d 100644 --- a/Libraries/Network/__tests__/XMLHttpRequest-test.js +++ b/Libraries/Network/__tests__/XMLHttpRequest-test.js @@ -8,6 +8,16 @@ */ 'use strict'; +jest.unmock('Platform'); +const Platform = require('Platform'); +let requestId = 1; + +function setRequestId(id){ + if (Platform.OS === 'ios') { + return; + } + requestId = id; +} jest .disableAutomock() @@ -18,11 +28,11 @@ jest removeListeners: function() {}, sendRequest(options, callback) { if (typeof callback === 'function') { // android does not pass a callback - callback(1); + callback(requestId); } }, abortRequest: function() {}, - } + }, }); const XMLHttpRequest = require('XMLHttpRequest'); @@ -112,15 +122,17 @@ describe('XMLHttpRequest', function() { xhr.open('GET', 'blabla'); xhr.send(); - xhr.__didReceiveData(1, 'Some data'); + setRequestId(2); + xhr.__didReceiveData(requestId, 'Some data'); expect(xhr.responseText).toBe('Some data'); }); it('should call ontimeout function when the request times out', function() { xhr.open('GET', 'blabla'); xhr.send(); - xhr.__didCompleteResponse(1, 'Timeout', true); - xhr.__didCompleteResponse(1, 'Timeout', true); + setRequestId(3); + xhr.__didCompleteResponse(requestId, 'Timeout', true); + xhr.__didCompleteResponse(requestId, 'Timeout', true); expect(xhr.readyState).toBe(xhr.DONE); @@ -138,7 +150,8 @@ describe('XMLHttpRequest', function() { it('should call onerror function when the request times out', function() { xhr.open('GET', 'blabla'); xhr.send(); - xhr.__didCompleteResponse(1, 'Generic error'); + setRequestId(4); + xhr.__didCompleteResponse(requestId, 'Generic error'); expect(xhr.readyState).toBe(xhr.DONE); @@ -158,7 +171,8 @@ describe('XMLHttpRequest', function() { it('should call onload function when there is no error', function() { xhr.open('GET', 'blabla'); xhr.send(); - xhr.__didCompleteResponse(1, null); + setRequestId(5); + xhr.__didCompleteResponse(requestId, null); expect(xhr.readyState).toBe(xhr.DONE); @@ -182,8 +196,8 @@ describe('XMLHttpRequest', function() { xhr.upload.onprogress = jest.fn(); var handleProgress = jest.fn(); xhr.upload.addEventListener('progress', handleProgress); - - xhr.__didUploadProgress(1, 42, 100); + setRequestId(6); + xhr.__didUploadProgress(requestId, 42, 100); expect(xhr.upload.onprogress.mock.calls.length).toBe(1); expect(handleProgress.mock.calls.length).toBe(1); @@ -197,7 +211,8 @@ describe('XMLHttpRequest', function() { it('should combine response headers with CRLF', function() { xhr.open('GET', 'blabla'); xhr.send(); - xhr.__didReceiveResponse(1, 200, { + setRequestId(7); + xhr.__didReceiveResponse(requestId, 200, { 'Content-Type': 'text/plain; charset=utf-8', 'Content-Length': '32', }); diff --git a/Libraries/Text/__mocks__/Text.js b/Libraries/Text/__mocks__/Text.js deleted file mode 100644 index 7cd9332c3..000000000 --- a/Libraries/Text/__mocks__/Text.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * 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 React = require('React'); -const {Component} = React; - -const RealText = require.requireActual('Text'); - -class Text extends Component { - render() { - const {children, ...props} = this.props; - return React.createElement('Text', props, children); - } -} -Text.propTypes = RealText.propTypes; - -module.exports = Text; diff --git a/jest/mockComponent.js b/jest/mockComponent.js new file mode 100644 index 000000000..3b2f3abf4 --- /dev/null +++ b/jest/mockComponent.js @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2013-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. + */ + +module.exports = moduleName => { + const RealComponent = require.requireActual(moduleName); + const React = require('react'); + + const Component = class extends RealComponent { + render() { + return React.createElement( + RealComponent.displayName || RealComponent.name, + this.props, + this.props.children, + ); + } + }; + return Component; +}; diff --git a/jestSupport/preprocessor.js b/jest/preprocessor.js similarity index 100% rename from jestSupport/preprocessor.js rename to jest/preprocessor.js diff --git a/jest/setup.js b/jest/setup.js new file mode 100644 index 000000000..3ebdebcf7 --- /dev/null +++ b/jest/setup.js @@ -0,0 +1,160 @@ +/** + * 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('../packager/react-packager/src/Resolver/polyfills/babelHelpers.js'); +require.requireActual('../packager/react-packager/src/Resolver/polyfills/Object.es7.js'); +require.requireActual('../packager/react-packager/src/Resolver/polyfills/error-guard'); + +global.__DEV__ = true; + +global.Promise = require.requireActual('promise'); +global.regeneratorRuntime = require.requireActual('regenerator-runtime/runtime'); + +jest + .mock('npmlog'); + +// there's a __mock__ for it. +jest.setMock('ErrorUtils', require('ErrorUtils')); + +jest + .mock('ReactNativeDefaultInjection') + .mock('Image', () => mockComponent('Image')) + .mock('Text', () => mockComponent('Text')) + .mock('TextInput', () => mockComponent('TextInput')) + .mock('Modal', () => mockComponent('Modal')) + .mock('View', () => mockComponent('View')) + .mock('ScrollView', () => mockComponent('ScrollView')) + .mock( + 'ActivityIndicator', + () => mockComponent('ActivityIndicator'), + ) + .mock('ListView', () => { + const RealListView = require.requireActual('ListView'); + const ListView = mockComponent('ListView'); + ListView.prototype.render = RealListView.prototype.render; + return ListView; + }) + .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; + }); + } catch (e) { + this.items = 'unknown'; + } + } + + return new ListViewDataSource(this._dataBlob); + }; + return DataSource; + }) + .mock('ensureComponentIsNative', () => () => true); + +const mockEmptyObject = {}; +const mockNativeModules = { + AlertManager: { + alertWithArgs: jest.fn(), + }, + AsyncLocalStorage: { + clear: jest.fn(), + getItem: jest.fn(), + removeItem: jest.fn(), + setItem: jest.fn(), + }, + BuildInfo: { + appVersion: '0', + buildVersion: '0', + }, + Clipboard: { + setString: jest.fn(), + }, + DataManager: { + queryData: jest.fn(), + }, + 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( + (uri, success) => process.nextTick(() => success(320, 240)) + ), + prefetchImage: jest.fn(), + }, + ImageViewManager: { + getSize: jest.fn( + (uri, success) => process.nextTick(() => success(320, 240)) + ), + prefetchImage: jest.fn(), + }, + ModalFullscreenViewManager: {}, + SourceCode: { + scriptURL: null, + }, + Timing: { + createTimer: jest.fn(), + deleteTimer: jest.fn(), + }, + UIManager: { + customBubblingEventTypes: {}, + customDirectEventTypes: {}, + Dimensions: { + window: { + fontScale: 2, + height: 1334, + scale: 2, + width: 750, + }, + }, + RCTModalFullscreenView: { + Constants: {}, + }, + RCTScrollView: { + Constants: {}, + }, + RCTView: { + Constants: {}, + }, + }, +}; + +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, + })); diff --git a/jestSupport/env.js b/jestSupport/env.js index 186f3e247..ba63dfcb2 100644 --- a/jestSupport/env.js +++ b/jestSupport/env.js @@ -1,37 +1,13 @@ /** - * Copyright (c) 2015-present, Facebook, Inc. + * Copyright (c) 2013-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'; -require.requireActual('../packager/react-packager/src/Resolver/polyfills/babelHelpers.js'); -require.requireActual('../packager/react-packager/src/Resolver/polyfills/Object.es7.js'); - -global.__DEV__ = true; -global.__fbBatchedBridgeConfig = { - remoteModuleConfig: [], - localModulesConfig: [], -}; - -global.Promise = require('promise'); -global.regeneratorRuntime = require.requireActual('regenerator-runtime/runtime'); - -jest - .mock('ensureComponentIsNative') - .mock('Image') - .mock('npmlog') - .mock('NativeModules') - .mock('Text') - .mock('View'); - -const mockEmptyObject = {}; -jest.mock('ReactNativePropRegistry', () => ({ - register: id => id, - getByID: () => mockEmptyObject, -})); - -jest.setMock('ErrorUtils', require('ErrorUtils')); +throw new Error( + 'React-Native and Jest should be tested together with the jest-react-native preset:' + + 'http://facebook.github.io/jest/docs/tutorial-react-native.html' +); diff --git a/package.json b/package.json index 4619f1677..324725860 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,9 @@ }, "jest": { "automock": true, - "scriptPreprocessor": "jestSupport/preprocessor.js", + "scriptPreprocessor": "jest/preprocessor.js", "setupFiles": [ - "jestSupport/env.js" + "jest/setup.js" ], "timers": "fake", "moduleNameMapper": { @@ -117,7 +117,7 @@ "LICENSE", "PATENTS", "README.md", - "jestSupport", + "jest", ".flowconfig", "flow" ], diff --git a/packager/package.json b/packager/package.json index f18fc259b..700d9715c 100644 --- a/packager/package.json +++ b/packager/package.json @@ -10,7 +10,7 @@ "node": ">=4" }, "jest": { - "setupEnvScriptFile": "jestSupport/env.js", + "setupEnvScriptFile": "jest/setup.js", "testPathIgnorePatterns": [ "/node_modules/" ], diff --git a/website/jsdocs/__tests__/jsdocs-test.js b/website/jsdocs/__tests__/jsdocs-test.js index 778482526..3e69f93f5 100644 --- a/website/jsdocs/__tests__/jsdocs-test.js +++ b/website/jsdocs/__tests__/jsdocs-test.js @@ -8,15 +8,18 @@ * */ 'use strict'; +jest.disableAutomock(); const fs = require('fs'); +const path = require('path'); + const jsDocs = require('../jsdocs'); -const libs = __dirname + '/../../../Libraries/'; +const libs = path.join(__dirname, '/../../../Libraries/'); function checkWeCanParse(library) { - let path = libs + library; - let code = fs.readFileSync(path).toString(); - let json = jsDocs(code); + const pathToCode = path.join(libs, library); + const code = fs.readFileSync(pathToCode).toString(); + const json = jsDocs(code); expect(json).toBeTruthy(); } @@ -30,7 +33,7 @@ describe('parseSource', () => { }); it('should not parse invalid code', () => { - let code = ` + const code = ` for x in range(10): print 'oops this isnt python' `;