From 5537055bf87c8b19e9fa8413486eef6a7ac5017f Mon Sep 17 00:00:00 2001 From: Spencer Ahrens Date: Tue, 20 Dec 2016 15:44:54 -0800 Subject: [PATCH] Add some `Fake`s for easier interaction snapshot testing Summary: `Fake` components are simplified so snapshots are stable and reliable, and references are exported so that interactions like `onRefresh` and `onScroll` can be called manually. Currently there is just one global export for each class, but we may change this in the future if we need to manage multiple `Fake`s of the same type in one render tree. Right now these must be installed explicitly, but I might move them into `__mocks__` folders if it seems reasonable to make them defaults. Reviewed By: cpojer Differential Revision: D4318207 fbshipit-source-id: 62802353a98b09ca1c80804ef7201ea63091f94a --- .../RefreshControl/RefreshControl.js | 2 +- .../__mocks__/RefreshControlMock.js | 29 +++++++++ .../ScrollView/__mocks__/ScrollViewMock.js | 33 ++++++++++ .../ListView/__mocks__/ListViewMock.js | 60 +++++++++++++++++++ jest/setup.js | 10 +--- 5 files changed, 126 insertions(+), 8 deletions(-) create mode 100644 Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js create mode 100644 Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js create mode 100644 Libraries/CustomComponents/ListView/__mocks__/ListViewMock.js diff --git a/Libraries/Components/RefreshControl/RefreshControl.js b/Libraries/Components/RefreshControl/RefreshControl.js index c80520fad..662246770 100644 --- a/Libraries/Components/RefreshControl/RefreshControl.js +++ b/Libraries/Components/RefreshControl/RefreshControl.js @@ -152,7 +152,7 @@ const RefreshControl = React.createClass({ return ( this._nativeRef = ref} + ref={ref => {this._nativeRef = ref;}} onRefresh={this._onRefresh} /> ); diff --git a/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js b/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js new file mode 100644 index 000000000..e5cd5b83a --- /dev/null +++ b/Libraries/Components/RefreshControl/__mocks__/RefreshControlMock.js @@ -0,0 +1,29 @@ +/** + * 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. + * + * @flow + */ +'use strict'; + +const React = require('React'); + +const requireNativeComponent = require('requireNativeComponent'); + +const RCTRefreshControl = requireNativeComponent('RCTRefreshControl'); + +class RefreshControlMock extends React.Component { + static latestRef: ?RefreshControlMock; + componentDidMount() { + RefreshControlMock.latestRef = this; + } + render() { + return ; + } +} + +module.exports = RefreshControlMock; diff --git a/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js b/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js new file mode 100644 index 000000000..16a62ee39 --- /dev/null +++ b/Libraries/Components/ScrollView/__mocks__/ScrollViewMock.js @@ -0,0 +1,33 @@ +/** + * 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. + * + * @flow + */ +'use strict'; + +const React = require('React'); +const View = require('View'); + +const requireNativeComponent = require('requireNativeComponent'); + +const RCTScrollView = requireNativeComponent('RCTScrollView'); + +class ScrollViewMock extends React.Component { + render() { + return ( + + {this.props.refreshControl} + + {this.props.children} + + + ); + } +} + +module.exports = ScrollViewMock; diff --git a/Libraries/CustomComponents/ListView/__mocks__/ListViewMock.js b/Libraries/CustomComponents/ListView/__mocks__/ListViewMock.js new file mode 100644 index 000000000..dd34d6a68 --- /dev/null +++ b/Libraries/CustomComponents/ListView/__mocks__/ListViewMock.js @@ -0,0 +1,60 @@ +/** + * 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. + * + * @flow + */ +'use strict'; + +const ListViewDataSource = require('ListViewDataSource'); +const React = require('React'); +const ScrollView = require('ScrollView'); +const StaticRenderer = require('StaticRenderer'); +const View = require('View'); + +class ListViewMock extends React.Component { + static latestRef: ?ListViewMock; + static defaultProps = { + renderScrollComponent: (props) => , + } + componentDidMount() { + ListViewMock.latestRef = this; + } + render() { + const {dataSource, renderFooter, renderHeader} = this.props; + const rows = [renderHeader && renderHeader()]; + const allRowIDs = dataSource.rowIdentities; + for (let sectionIdx = 0; sectionIdx < allRowIDs.length; sectionIdx++) { + const sectionID = dataSource.sectionIdentities[sectionIdx]; + const rowIDs = allRowIDs[sectionIdx]; + for (let rowIdx = 0; rowIdx < rowIDs.length; rowIdx++) { + const rowID = rowIDs[rowIdx]; + rows.push( + + ); + } + } + renderFooter && rows.push(renderFooter()); + return ( + + {this.props.renderScrollComponent({children: rows})} + + ); + } + static DataSource = ListViewDataSource; +} + +module.exports = ListViewMock; diff --git a/jest/setup.js b/jest/setup.js index cab0eb220..e55970205 100644 --- a/jest/setup.js +++ b/jest/setup.js @@ -33,17 +33,13 @@ jest .mock('TextInput', () => mockComponent('TextInput')) .mock('Modal', () => mockComponent('Modal')) .mock('View', () => mockComponent('View')) - .mock('ScrollView', () => mockComponent('ScrollView')) + .mock('RefreshControl', () => require.requireMock('RefreshControlMock')) + .mock('ScrollView', () => require.requireMock('ScrollViewMock')) .mock( 'ActivityIndicator', () => mockComponent('ActivityIndicator'), ) - .mock('ListView', () => { - const RealListView = require.requireActual('ListView'); - const ListView = mockComponent('ListView'); - ListView.prototype.render = RealListView.prototype.render; - return ListView; - }) + .mock('ListView', () => require.requireMock('ListViewMock')) .mock('ListViewDataSource', () => { const DataSource = require.requireActual('ListViewDataSource'); DataSource.prototype.toJSON = function() {