Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
"ignoreComments": true
}
],
"no-multiple-empty-lines": [2, {"max": 3}]
"no-multiple-empty-lines": [2, {"max": 3}],
"import/no-extraneous-dependencies": 0,
"react/jsx-filename-extension": 0,
"import/no-dynamic-require": 0,
"no-multi-assign": 0,
"o-undef": 0,
}
}
15 changes: 5 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
language: node_js
node_js:
- "4.0.0"
- "6.0.0"
- "4"
- "6"
- "8.9.1"
- "8"


# values taken from react-native's package.json
env:
- REACT_NATIVE_VERSION=0.38 REACT_VERSION=15.4.0
- REACT_NATIVE_VERSION=0.39 REACT_VERSION=15.4.0-rc.4
- REACT_NATIVE_VERSION=0.40 REACT_VERSION=15.4.1
- REACT_NATIVE_VERSION=0.41 REACT_VERSION=15.4.0
- REACT_NATIVE_VERSION=0.42 REACT_VERSION=15.4.1
- REACT_NATIVE_VERSION=0.43 REACT_VERSION=16.0.0-alpha.6
- REACT_NATIVE_VERSION=0.50 REACT_VERSION=16.0.0

before_install:
- npm install react@~$REACT_VERSION react-dom@~$REACT_VERSION react-native@~$REACT_NATIVE_VERSION

before_script:
- npm uninstall react-native react react-dom react-addons-test-utils
- npm install react@~$REACT_VERSION react-dom@~$REACT_VERSION react-addons-test-utils@~$REACT_VERSION react-native@~$REACT_NATIVE_VERSION
- npm run build-haste
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
A fully mocked and test-friendly version of react native

## Requirements
- Node.js 4+
- Node.js 6+ (dropping support for Node 4 as some dev dependencies don't support it)
- The latest version of react-native

__Note__: This library is designed to work with the most recent version of react-native. If you aren't using the most recent version, you will probably need to download an older version of this library, as the API is likely to be different, and the dependencies are likely to break.
Expand Down
46 changes: 24 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,36 +33,38 @@
},
"homepage": "https://github.com/RealOrangeOne/react-native-mock#readme",
"dependencies": {
"glob": "7.1.1",
"mockery": "2.0.0",
"glob": "7.1.2",
"mockery": "2.1.0",
"perfy": "1.1.2",
"promise": "7.1.1",
"regenerator-runtime": "0.10.1",
"sinon": "1.17.7",
"promise": "8.0.1",
"regenerator-runtime": "0.11.0",
"sinon": "4.1.1",
"underscore": "1.8.3"
},
"devDependencies": {
"babel-cli": "6.9.0",
"chai": "3.5.0",
"chai-as-promised": "6.0.0",
"enzyme": "2.8.0",
"eslint": "2.10.2",
"eslint-config-airbnb": "9.0.1",
"eslint-plugin-import": "1.8.0",
"eslint-plugin-jsx-a11y": "1.2.2",
"eslint-plugin-react": "5.1.1",
"eslint-plugin-react-native": "1.0.2",
"jsdom": "9.9.1",
"mocha": "3.2.0",
"babel-cli": "6.26.0",
"chai": "4.1.2",
"chai-as-promised": "7.1.1",
"enzyme": "3.1.1",
"enzyme-adapter-react-16": "1.0.4",
"eslint": "4.10.0",
"eslint-config-airbnb": "16.1.0",
"eslint-plugin-import": "2.8.0",
"eslint-plugin-jsx-a11y": "6.0.2",
"eslint-plugin-react": "7.4.0",
"eslint-plugin-react-native": "3.1.0",
"jsdom": "11.3.0",
"mocha": "4.0.1",
"mocha-assume": "1.0.0",
"nyc": "10.0.0",
"semver": "5.3.0",
"sinon-chai": "2.8.0"
"nyc": "11.3.0",
"semver": "5.4.1",
"sinon-chai": "2.14.0"
},
"peerDependencies": {
"babel-core": "*",
"babel-preset-react-native": "*",
"react": ">=15.4.0",
"react-native": ">=0.38.0"
"react": ">=16.0.0",
"react-dom": ">=16.0.0",
"react-native": ">=0.50.0"
}
}
15 changes: 10 additions & 5 deletions scripts/test-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,28 @@ const chai = require('chai');
const sinonChai = require('sinon-chai');
const chaiAsPromised = require('chai-as-promised');
const jsdom = require('jsdom');
const Enzyme = require('enzyme');
const React16Adapter = require('enzyme-adapter-react-16');

Enzyme.configure({ adapter: new React16Adapter() });

chai.expect();
chai.use(sinonChai);
chai.use(chaiAsPromised);

// Jsdom document & window
const doc = jsdom.jsdom('<!doctype html><html><body></body></html>');
const win = doc.defaultView;
const { JSDOM } = jsdom;
const dom = new JSDOM('<!doctype html><html><body></body></html>');
const win = dom.window;

// Add to global
global.document = doc;
global.document = win.document;
global.window = win;

// Add window keys to global window
Object.keys(window).forEach((key) => {
Object.keys(window).forEach((key) => { // eslint-disable-line no-undef
if (!(key in global)) {
global[key] = window[key];
global[key] = window[key]; // eslint-disable-line no-undef
}
});

Expand Down
19 changes: 16 additions & 3 deletions src/NativeModules.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import sinon from 'sinon';

const ReactNativeVersion = require('react-native/Libraries/Core/ReactNativeVersion');

module.exports = {
AlertManager: {
alertWithArgs: sinon.spy()
Expand Down Expand Up @@ -63,11 +65,11 @@ module.exports = {
},
IntentAndroid: {
openURL: sinon.spy(),
canOpenURL: sinon.spy(url => new Promise((resolve) => resolve(true)))
canOpenURL: sinon.spy(url => new Promise(resolve => resolve(true)))
},
LinkingManager: {
openURL: sinon.spy(),
canOpenURL: sinon.spy(url => new Promise((resolve) => resolve(true)))
canOpenURL: sinon.spy(url => new Promise(resolve => resolve(true)))
},
ModalFullscreenViewManager: {},
Networking: {
Expand Down Expand Up @@ -145,7 +147,8 @@ module.exports = {
osVersion: '10',
interfaceIdiom: 'pad',
isTesting: true,
version: '7'
version: '7',
reactNativeVersion: ReactNativeVersion.version
},
AndroidConstants: {
Version: '7',
Expand All @@ -155,5 +158,15 @@ module.exports = {
osVersion: '10',
interfaceIdiom: 'pad',
isTesting: true
},
DeviceInfo: {
Dimensions: {
windowPhysicalPixels: {
fontScale: 2,
height: 1334,
scale: 2,
width: 750
}
}
}
};
4 changes: 2 additions & 2 deletions src/createMockComponent.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';

export default name => {
export default (name) => {
const RealComponent = require(name);
const realComponentName = RealComponent.name === 'Component' ? name : RealComponent.name;
const componentName = (RealComponent.displayName || realComponentName || name).replace(/^(RCT|RK)/, '');

const Component = class extends RealComponent { // eslint-disable-line react/prefer-stateless-function
const Component = class extends RealComponent { // eslint-disable-line react/prefer-stateless-function
render() {
return React.createElement(
componentName,
Expand Down
8 changes: 4 additions & 4 deletions src/haste.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ var PROJECT_NODE_MODULES = path.join(PROJECT_ROOT, 'node_modules');
var TIMER = 'time';

if (!fs.existsSync(PROJECT_NODE_MODULES)) {
PROJECT_NODE_MODULES = path.join(CWD, 'node_modules'); // For tests
PROJECT_NODE_MODULES = path.join(CWD, 'node_modules'); // For tests
}

perfy.start(TIMER);
Expand All @@ -32,10 +32,10 @@ _.forEach(files, function (file) {
var matches = providesRegex.exec(fs.readFileSync(file).toString());
if (matches && validName.test(matches[1])) {
var component = matches[1];
if (component.match(iosTest) && file.endsWith('.android.js')) { // Dont add IOS components if they end in android.js
if (component.match(iosTest) && file.endsWith('.android.js')) { // Dont add IOS components if they end in android.js
return;
}
if (component.match(androidTest) && file.endsWith('.ios.js')) { // Dont add Android components if they end in ios.js
if (component.match(androidTest) && file.endsWith('.ios.js')) { // Dont add Android components if they end in ios.js
return;
}
data.hasteMap[component] = file.replace(PROJECT_NODE_MODULES + '/', '');
Expand All @@ -47,5 +47,5 @@ fs.writeFileSync(path.join(CWD, 'haste-map.json'), JSON.stringify(data, null, 2)
var results = perfy.end(TIMER);

if (process.env.NODE_ENV !== 'test') {
console.log(results.summary); // eslint-disable-line no-console
console.log(results.summary); // eslint-disable-line no-console
}
1 change: 1 addition & 0 deletions src/image-compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

const m = require('module');

const originalLoader = m._load;

m._load = function hookedLoader(request, parent, isMain) {
Expand Down
2 changes: 1 addition & 1 deletion src/mocks/AsyncStorage.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const AsyncStorage = require('AsyncStorage'); // eslint-disable-line import/no-unresolved
const AsyncStorage = require('AsyncStorage'); // eslint-disable-line import/no-unresolved

let _data = {};

Expand Down
20 changes: 9 additions & 11 deletions src/mocks/ListView.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/* eslint-disable react/prop-types */

const React = require('react');
const ScrollView = require('ScrollView'); // eslint-disable-line import/no-unresolved
const ScrollView = require('ScrollView'); // eslint-disable-line import/no-unresolved
const StaticRenderer = require('StaticRenderer'); // eslint-disable-line import/no-unresolved
const View = require('View'); // eslint-disable-line import/no-unresolved

Expand All @@ -24,23 +24,21 @@ class ListViewMock extends React.Component {
const { dataSource, renderFooter, renderHeader } = this.props;
const rows = [renderHeader && renderHeader()];
const allRowIDs = dataSource.rowIdentities;
for (let sectionIdx = 0; sectionIdx < allRowIDs.length; sectionIdx++) {
for (let sectionIdx = 0; sectionIdx < allRowIDs.length; sectionIdx += 1) {
const sectionID = dataSource.sectionIdentities[sectionIdx];
const rowIDs = allRowIDs[sectionIdx];
for (let rowIdx = 0; rowIdx < rowIDs.length; rowIdx++) {
for (let rowIdx = 0; rowIdx < rowIDs.length; rowIdx += 1) {
const rowID = rowIDs[rowIdx];
rows.push(
<StaticRenderer
shouldUpdate
key={rowID}
render={this.props.renderRow.bind(
rows.push(<StaticRenderer
shouldUpdate
key={rowID}
render={this.props.renderRow.bind(
null,
dataSource.getRowData(sectionIdx, rowIdx),
sectionID,
rowID
)}
/>
);
/>);
}
}

Expand All @@ -55,7 +53,7 @@ class ListViewMock extends React.Component {
}

ListViewMock.defaultProps = {
renderScrollComponent: (props) => <ScrollView {...props} />
renderScrollComponent: props => <ScrollView {...props} />
};

ListViewMock.DataSource = require('ListViewDataSource'); // eslint-disable-line import/no-unresolved
Expand Down
4 changes: 2 additions & 2 deletions src/mocks/ListViewDataSource.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const DataSource = require('ListViewDataSource'); // eslint-disable-line import/no-unresolved
const DataSource = require('ListViewDataSource'); // eslint-disable-line import/no-unresolved

DataSource.prototype.toJSON = function () {
function ListViewDataSource(dataBlob) {
this.items = 0;
// Ensure this doesn't throw.
try {
Object.keys(dataBlob).forEach(key => {
Object.keys(dataBlob).forEach((key) => {
this.items += dataBlob[key] && (
dataBlob[key].length || dataBlob[key].size || 0
);
Expand Down
7 changes: 4 additions & 3 deletions src/react-native-mock.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import mockery from 'mockery';
import _ from 'underscore';
import React from 'react';
import sinon from 'sinon';

import defineGlobalProperty from './defineGlobalProperty';
import createMockComponent, { MOCK_COMPONENTS } from './createMockComponent';
import mockNativeModules from './NativeModules';
import React from 'react';
import sinon from 'sinon';


// Setup babel to build react-native source
Expand Down Expand Up @@ -33,7 +34,7 @@ mockery.registerMock('ensureComponentIsNative', () => true);
mockery.registerMock('requireNativeComponent', sinon.spy(viewName => props => React.createElement(
viewName,
props,
props.children // eslint-disable-line react/prop-types
props.children // eslint-disable-line react/prop-types
)));
mockery.registerMock('ErrorUtils', require('./mocks/ErrorUtils'));

Expand Down
2 changes: 1 addition & 1 deletion tests/image-compiler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { expect } from 'chai';

describe('Image Compiler', function () {
it('should require a jpg image', function () {
expect(require('foo.jpg')).to.deep.equal({ uri: 'foo.jpg' }); // eslint-disable-line import/no-unresolved
expect(require('foo.jpg')).to.deep.equal({ uri: 'foo.jpg' }); // eslint-disable-line import/no-unresolved
});

it('should require a jpeg image', function () {
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/apis/AlertIOS.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('AlertIOS', () => {
},
{
text: 'OK',
onPress: password => {}
onPress: (password) => {}
}
],
'secure-text'
Expand Down
9 changes: 0 additions & 9 deletions tests/integration/apis/BackAndroid.test.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import { expect } from 'chai';
import sinon from 'sinon';

describe('BackAndroid', () => {
const { BackAndroid } = require('react-native');

it('should bind events', function () {
expect(BackAndroid.addEventListener).to.be.a('function');
expect(BackAndroid.addEventListener().remove).to.be.a('function');
expect(BackAndroid.removeEventListener).to.be.a('function');
expect(BackAndroid.exitApp).to.be.a('function');
});

it('should remove', function () {
sinon.stub(BackAndroid, 'removeEventListener');
BackAndroid.addEventListener().remove();
expect(BackAndroid.removeEventListener).to.have.been.calledOnce;
BackAndroid.removeEventListener.restore();
});
});
11 changes: 11 additions & 0 deletions tests/integration/apis/BackHandler.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { expect } from 'chai';

describe('BackHandler', () => {
const { BackHandler } = require('react-native');

it('should bind events', function () {
expect(BackHandler.addEventListener).to.be.a('function');
expect(BackHandler.removeEventListener).to.be.a('function');
expect(BackHandler.exitApp).to.be.a('function');
});
});
4 changes: 2 additions & 2 deletions tests/integration/apis/Dimensions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ describe('Dimensions', () => {
it('should get dimensions', function () {
expect(Dimensions.get('window')).to.deep.equal({
fontScale: 2,
height: 1334,
height: 667,
scale: 2,
width: 750
width: 375
});
});

Expand Down
Loading