This commit is contained in:
Salakar 2018-03-24 05:53:49 +00:00
parent 9eeddcab6e
commit 1aa2e032f9
14 changed files with 789 additions and 166 deletions

View File

@ -81,3 +81,15 @@ CPU/ABI: null (null)
Path: /Users/mike/.android/avd/Actually_THIS_one.avd
Error: Failed to parse properties from /Users/mike/.android/avd/Actually_THIS_one.avd/config.ini
#### Running specific tests
Add a `--grep` to e2e/mocha.opts file, e.g. `--grep auth` for all tests that have auth in the file path or tests descriptions.
#### Running Node debugger
Add `--inspect` to e2e/mocha.opts file
To open node debugger tools on chrome navigate to chrome://inspect/#devices and click the `Open dedicated DevTools for Node` link.
Add the default connection of `localhost:9229` if you haven't already - then the debugger will automatically connect everytime you start tests with inspect flag.

View File

@ -1,38 +1,43 @@
{
"project_info": {
"project_number": "17067372085",
"firebase_url": "https://rnfirebase-5579a.firebaseio.com",
"project_id": "rnfirebase",
"storage_bucket": "rnfirebase.appspot.com"
"project_number": "305229645282",
"firebase_url": "https://rnfirebase-b9ad4.firebaseio.com",
"project_id": "rnfirebase-b9ad4",
"storage_bucket": "rnfirebase-b9ad4.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:17067372085:android:efe37851d57e1d05",
"mobilesdk_app_id": "1:305229645282:android:efe37851d57e1d05",
"android_client_info": {
"package_name": "com.reactnativefirebasedemo"
}
},
"oauth_client": [
{
"client_id": "17067372085-ltes2e70ehnlp4s5bl7uljuqvjul2l9s.apps.googleusercontent.com",
"client_id": "305229645282-5fgq5kq024eqpvji5o0i7jq7q7bnnpl9.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.reactnativefirebasedemo",
"certificate_hash": "34d770365973b7580e04dab50692506aff7bd32f"
"certificate_hash": "1f92c8aab0a091a3aaccfa144bf402bb97273494"
}
},
{
"client_id": "17067372085-n572o9802h9jbv9oo60h53117pk9333k.apps.googleusercontent.com",
"client_id": "305229645282-cvp6v0iogjjuuvi5g2dcb3lrr9n884a3.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.reactnativefirebasedemo",
"certificate_hash": "859f2afac694e21d26ca67e750c9875107c2e755"
}
},
{
"client_id": "305229645282-j8ij0jev9ut24odmlk9i215pas808ugn.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyB-z0ytgXRRiClvslJl0tp-KbhDub9o6AM"
},
{
"current_key": "AIzaSyAJw8mR1fPcEYC9ouZbkCStJufcCQrhmjQ"
"current_key": "AIzaSyCzbBYFyX8d6VdSu7T4s10IWYbPc-dguwM"
}
],
"services": {
@ -43,15 +48,15 @@
"status": 2,
"other_platform_oauth_client": [
{
"client_id": "17067372085-n572o9802h9jbv9oo60h53117pk9333k.apps.googleusercontent.com",
"client_type": 3
},
{
"client_id": "17067372085-siujfe334vool17t2mtrmjrsgl81nhd9.apps.googleusercontent.com",
"client_id": "305229645282-t29pn6o2t7se1f7rvrfsll4r0pvd6fb6.apps.googleusercontent.com",
"client_type": 2,
"ios_info": {
"bundle_id": "com.invertase.RNFirebaseTests"
}
},
{
"client_id": "305229645282-j8ij0jev9ut24odmlk9i215pas808ugn.apps.googleusercontent.com",
"client_type": 3
}
]
},
@ -62,31 +67,28 @@
},
{
"client_info": {
"mobilesdk_app_id": "1:17067372085:android:af36d4d29a83e04c",
"mobilesdk_app_id": "1:305229645282:android:c9de0f8cb930daf5",
"android_client_info": {
"package_name": "com.testing"
"package_name": "com.reactnativefirebaseexamples"
}
},
"oauth_client": [
{
"client_id": "17067372085-066pi4ln798odtdrifoktb3mea9dtipt.apps.googleusercontent.com",
"client_id": "305229645282-hu7tr12kgn5lfhq82l51b1sh66aaue5f.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "com.testing",
"certificate_hash": "34d770365973b7580e04dab50692506aff7bd32f"
"package_name": "com.reactnativefirebaseexamples",
"certificate_hash": "1f92c8aab0a091a3aaccfa144bf402bb97273494"
}
},
{
"client_id": "17067372085-n572o9802h9jbv9oo60h53117pk9333k.apps.googleusercontent.com",
"client_id": "305229645282-j8ij0jev9ut24odmlk9i215pas808ugn.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyB-z0ytgXRRiClvslJl0tp-KbhDub9o6AM"
},
{
"current_key": "AIzaSyAJw8mR1fPcEYC9ouZbkCStJufcCQrhmjQ"
"current_key": "AIzaSyCzbBYFyX8d6VdSu7T4s10IWYbPc-dguwM"
}
],
"services": {
@ -97,15 +99,15 @@
"status": 2,
"other_platform_oauth_client": [
{
"client_id": "17067372085-n572o9802h9jbv9oo60h53117pk9333k.apps.googleusercontent.com",
"client_type": 3
},
{
"client_id": "17067372085-siujfe334vool17t2mtrmjrsgl81nhd9.apps.googleusercontent.com",
"client_id": "305229645282-t29pn6o2t7se1f7rvrfsll4r0pvd6fb6.apps.googleusercontent.com",
"client_type": 2,
"ios_info": {
"bundle_id": "com.invertase.RNFirebaseTests"
}
},
{
"client_id": "305229645282-j8ij0jev9ut24odmlk9i215pas808ugn.apps.googleusercontent.com",
"client_type": 3
}
]
},
@ -113,6 +115,37 @@
"status": 2
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:305229645282:android:af36d4d29a83e04c",
"android_client_info": {
"package_name": "com.testing"
}
},
"oauth_client": [
{
"client_id": "305229645282-j8ij0jev9ut24odmlk9i215pas808ugn.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyCzbBYFyX8d6VdSu7T4s10IWYbPc-dguwM"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"

View File

@ -23,7 +23,7 @@ class Root extends Component {
render() {
return (
<View>
<Text>React Native Firebase Test App</Text>
<Text testID="tap">React Native Firebase Test App</Text>
</View>
);
}

View File

@ -2,13 +2,13 @@ const detox = require('detox');
const vm = require('./vm');
const ws = require('./ws');
// TODO each reload/relaunch should capture __coverage__
const detoxOriginalInit = detox.init.bind(detox);
const detoxOriginalCleanup = detox.cleanup.bind(detox);
let detoxOriginalReloadReactNative = null;
let bridgeReady = false;
process.on('rn-ready', () => {
// console.log('READY', true);
bridgeReady = true;
});
@ -19,37 +19,38 @@ function onceBridgeReady() {
});
}
detox.init = async (...args) => {
bridgeReady = false;
console.log('detox.init.start');
return detoxOriginalInit(...args).then(() => {
console.log('detox.init.complete');
detoxOriginalReloadReactNative = device.reloadReactNative.bind(device);
function shimDevice() {
// reloadReactNative
const detoxOriginalReloadReactNative = device.reloadReactNative.bind(device);
device.reloadReactNative = async () => {
console.log('reloadReactNative.start');
bridgeReady = false;
// return device.launchApp({ newInstance: true }).then(() => {
global.bridge.reload();
return onceBridgeReady();
};
// launchApp
const detoxOriginalLaunchApp = device.launchApp.bind(device);
device.launchApp = async (...args) => {
bridgeReady = false;
await detoxOriginalLaunchApp(...args);
return onceBridgeReady();
};
// todo other device methods
}
detox.init = async (...args) => {
bridgeReady = false;
return detoxOriginalInit(...args).then(() => {
shimDevice();
return onceBridgeReady();
});
};
detox.cleanup = async (...args) => {
console.log('detox.cleanup');
return detoxOriginalCleanup(...args).then(() => {
console.log('detox.cleanup.end');
detox.cleanup = async (...args) =>
detoxOriginalCleanup(...args).then(() => {
ws.close();
process.exit();
});
};
global.bridge = {
_ws: null,

View File

@ -25,11 +25,12 @@ function sendResult(replyID, result) {
}
/**
*
* TODO
* @param message
*/
function sendError(message) {
console.error(message);
function sendError(error) {
console.log('error');
throw error;
}
/**
@ -67,13 +68,80 @@ function getScript(src, callback) {
});
}
function consoleShim() {
return {
...console,
log(...args) {
if (
args[0] &&
typeof args[0] === 'string' &&
args[0].startsWith('Running application "')
) {
return;
}
if (
args[0] &&
typeof args[0] === 'string' &&
args[0].startsWith('Deprecated')
) {
return;
}
console.log(...args);
},
warn(...args) {
if (
args[0] &&
typeof args[0] === 'string' &&
args[0].startsWith('Running application "')
) {
return;
}
if (
args[0] &&
typeof args[0] === 'string' &&
args[0].startsWith('Deprecated')
) {
return;
}
console.log(...args);
},
};
}
process.on('ws-message', request => {
// console.log(request.method);
switch (request.method) {
case 'prepareJSRuntime':
if (currentContext) {
try {
for (const name in currentContext.__fbBatchedBridge) {
currentContext.__fbBatchedBridge[name] = undefined;
delete currentContext.__fbBatchedBridge[name];
}
for (const name in currentContext.__fbGenNativeModule) {
currentContext.__fbGenNativeModule[name] = undefined;
delete currentContext.__fbGenNativeModule[name];
}
for (const name in currentContext.__fbBatchedBridgeConfig) {
currentContext.__fbBatchedBridgeConfig[name] = undefined;
delete currentContext.__fbBatchedBridgeConfig[name];
}
for (const name in currentContext) {
currentContext[name] = undefined;
delete currentContext[name];
}
} catch (e) {
console.error(e);
}
}
currentContext = undefined;
currentContext = createContext({
console,
console: consoleShim(),
__bridgeNode: {
ready() {
process.emit('rn-ready');
@ -128,7 +196,7 @@ process.on('ws-message', request => {
try {
script.runInContext(currentContext, TEMP_BUNDLE_PATH);
} catch (e) {
sendError(`Failed to exec script: ${e.message}`);
sendError(e);
}
sendResult(request.id);
});
@ -148,9 +216,11 @@ process.on('ws-message', request => {
);
}
} catch (e) {
if (request.method !== '$disconnected') {
sendError(
`Failed while making a call ${request.method}:::${e.message}`
);
}
} finally {
sendResult(request.id, JSON.stringify(returnValue));
}

View File

@ -6,7 +6,7 @@ const ws = new WebSocket(
);
ws.onmessage = message => process.emit('ws-message', JSON.parse(message.data));
ws.onopen = () => console.log('WS open');
// ws.onopen = () => console.log('WS open');
ws.onclose = event => (!event.wasClean ? console.log('WS close', event) : '');
module.exports = ws;

View File

@ -1,6 +1,10 @@
import reactNative, { Platform, NativeModules } from 'react-native';
import RNRestart from 'react-native-restart'; // Import package from node modules
require('sinon');
require('should-sinon');
require('should');
const bridgeNode = global.__bridgeNode;
// https://github.com/ptmt/react-native-macos/blob/master/React/Modules/RCTDevSettings.mm
@ -26,3 +30,9 @@ export default {
}
},
};
// keep alive
setInterval(() => {
// I don't do anything lol
// BUT i am needed - otherwise RN's batch bridge starts to hang in detox... ???
}, 50);

241
tests-new/e2e/auth/auth.js Normal file
View File

@ -0,0 +1,241 @@
const sinon = require('sinon');
require('should-sinon');
const should = require('should');
const randomString = (length, chars) => {
let mask = '';
if (chars.indexOf('a') > -1) mask += 'abcdefghijklmnopqrstuvwxyz';
if (chars.indexOf('A') > -1) mask += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (chars.indexOf('#') > -1) mask += '0123456789';
if (chars.indexOf('!') > -1) mask += '~`!@#$%^&*()_+-={}[]:";\'<>?,./|\\';
let result = '';
for (let i = length; i > 0; --i) {
result += mask[Math.round(Math.random() * (mask.length - 1))];
}
return result;
};
describe('.auth()', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
describe('.signInAnonymously()', () => {
it('it should sign in anonymously', () => {
const successCb = currentUser => {
debugger;
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
should.equal(currentUser.toJSON().email, null);
currentUser.isAnonymous.should.equal(true);
currentUser.providerId.should.equal('firebase');
currentUser.should.equal(bridge.module.auth().currentUser);
return bridge.module.auth().signOut();
};
return bridge.module
.auth()
.signInAnonymously()
.then(successCb);
});
});
describe('.signInAnonymouslyAndRetrieveData()', () => {
it('it should sign in anonymously', () => {
const successCb = currentUserCredential => {
const currentUser = currentUserCredential.user;
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
should.equal(currentUser.toJSON().email, null);
currentUser.isAnonymous.should.equal(true);
currentUser.providerId.should.equal('firebase');
currentUser.should.equal(bridge.module.auth().currentUser);
const { additionalUserInfo } = currentUserCredential;
additionalUserInfo.should.be.an.Object();
return bridge.module.auth().signOut();
};
return bridge.module
.auth()
.signInAnonymouslyAndRetrieveData()
.then(successCb);
});
});
describe('.signInWithEmailAndPassword()', () => {
it('it should login with email and password', () => {
const email = 'test@test.com';
const pass = 'test1234';
const successCb = currentUser => {
currentUser.should.be.an.Object();
currentUser.uid.should.be.a.String();
currentUser.toJSON().should.be.an.Object();
currentUser.toJSON().email.should.eql('test@test.com');
currentUser.isAnonymous.should.equal(false);
currentUser.providerId.should.equal('firebase');
currentUser.should.equal(bridge.module.auth().currentUser);
return bridge.module.auth().signOut();
};
return bridge.module
.auth()
.signInWithEmailAndPassword(email, pass)
.then(successCb);
});
it('it should error on login if user is disabled', () => {
const email = 'disabled@account.com';
const pass = 'test1234';
const successCb = () => Promise.reject(new Error('Did not error.'));
const failureCb = error => {
error.code.should.equal('auth/user-disabled');
error.message.should.equal(
'The user account has been disabled by an administrator.'
);
return Promise.resolve();
};
return bridge.module
.auth()
.signInWithEmailAndPassword(email, pass)
.then(successCb)
.catch(failureCb);
});
it('it should error on login if password incorrect', () => {
const email = 'test@test.com';
const pass = 'test1234666';
const successCb = () => Promise.reject(new Error('Did not error.'));
const failureCb = error => {
error.code.should.equal('auth/wrong-password');
error.message.should.equal(
'The password is invalid or the user does not have a password.'
);
return Promise.resolve();
};
return bridge.module
.auth()
.signInWithEmailAndPassword(email, pass)
.then(successCb)
.catch(failureCb);
});
it('it should error on login if user not found', () => {
const email = 'randomSomeone@fourOhFour.com';
const pass = 'test1234';
const successCb = () => Promise.reject(new Error('Did not error.'));
const failureCb = error => {
error.code.should.equal('auth/user-not-found');
error.message.should.equal(
'There is no user record corresponding to this identifier. The user may have been deleted.'
);
return Promise.resolve();
};
return bridge.module
.auth()
.signInWithEmailAndPassword(email, pass)
.then(successCb)
.catch(failureCb);
});
});
describe('.onAuthStateChanged()', () => {
it('calls callback with the current user and when auth state changes', async () => {
await bridge.module.auth().signInAnonymouslyAndRetrieveData();
// Test
const callback = sinon.spy();
let unsubscribe;
await new Promise(resolve => {
unsubscribe = bridge.module.auth().onAuthStateChanged(user => {
callback(user);
resolve();
});
});
callback.should.be.calledWith(bridge.module.auth().currentUser);
callback.should.be.calledOnce();
// Sign out
await bridge.module.auth().signOut();
await new Promise(resolve => {
setTimeout(() => resolve(), 100);
});
// Assertions
callback.should.be.calledWith(null);
callback.should.be.calledTwice();
// Tear down
unsubscribe();
});
it('stops listening when unsubscribe called', async () => {
await bridge.module.auth().signInAnonymouslyAndRetrieveData();
// Test
const callback = sinon.spy();
let unsubscribe;
await new Promise(resolve => {
unsubscribe = bridge.module.auth().onAuthStateChanged(user => {
callback(user);
resolve();
});
});
callback.should.be.calledWith(bridge.module.auth().currentUser);
callback.should.be.calledOnce();
// Sign out
await bridge.module.auth().signOut();
await new Promise(resolve => {
setTimeout(() => resolve(), 100);
});
// Assertions
// callback.should.be.calledWith(null);
callback.should.be.calledTwice();
// Unsubscribe
unsubscribe();
// Sign back in
await bridge.module.auth().signInAnonymouslyAndRetrieveData();
// Assertions
callback.should.be.calledTwice();
// Tear down
await bridge.module.auth().signOut();
});
});
});

View File

@ -1,60 +1,42 @@
// describe('Example', () => {
// beforeEach(async () => {
// await device.reloadReactNative();
// });
//
// it('should have welcome screen', async () => {
// await expect(element(by.id('welcome'))).toBeVisible();
// });
//
// it('should show hello screen after tap', async () => {
// await element(by.id('hello_button')).tap();
// await expect(element(by.text('Hello!!!'))).toBeVisible();
// });
//
// it('should show world screen after tap', async () => {
// await element(by.id('world_button')).tap();
// await expect(element(by.text('World!!!'))).toBeVisible();
// });
// });
const should = require('should');
describe('should work inside node', () => {
describe('bridge', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should provide bridge global', () => {
const firebase = bridge.module;
it('should provide -> global.bridge', () => {
should(bridge).not.be.undefined();
return Promise.resolve();
});
it('should require 2', () => {
const firebase = bridge.module;
// const { Platform } = bridge.rnModule;
// should.equal(firebase.auth.nativeModuleExists, true);
it('should provide -> global.bridge.module', () => {
should(bridge.module).not.be.undefined();
return Promise.resolve();
});
it('should require 3', () => {
const firebase = bridge.module;
// const { Platform } = bridge.rnModule;
// should.equal(firebase.auth.nativeModuleExists, true);
it('should provide -> global.bridge.rn', () => {
should(bridge.rn).not.be.undefined();
should(bridge.rn.Platform.OS).be.a.String();
should(bridge.rn.Platform.OS).equal(device.getPlatform());
return Promise.resolve();
});
it('should require 4', () => {
const firebase = bridge.module;
// const { Platform } = bridge.rnModule;
// should.equal(firebase.auth.nativeModuleExists, true);
it('should provide -> global.reload and allow reloadReactNative usage', async () => {
should(bridge.reload).be.a.Function();
// and check it works without breaking anything
await device.reloadReactNative();
should(bridge.reload).be.a.Function();
return Promise.resolve();
});
it('should require 5', () => {
const firebase = bridge.module;
// const { Platform } = bridge.rnModule;
// should.equal(firebase.auth.nativeModuleExists, true);
it('should allow detox to launchApp without breaking remote debug', async () => {
await device.launchApp({ newInstance: true });
should(bridge.module).not.be.undefined();
should(bridge.reload).be.a.Function();
should(bridge.rn).not.be.undefined();
should(bridge.rn.Platform.OS).be.a.String();
should(bridge.rn.Platform.OS).equal(device.getPlatform());
return Promise.resolve();
});
});

View File

@ -1,60 +0,0 @@
// describe('Example', () => {
// beforeEach(async () => {
// await device.reloadReactNative();
// });
//
// it('should have welcome screen', async () => {
// await expect(element(by.id('welcome'))).toBeVisible();
// });
//
// it('should show hello screen after tap', async () => {
// await element(by.id('hello_button')).tap();
// await expect(element(by.text('Hello!!!'))).toBeVisible();
// });
//
// it('should show world screen after tap', async () => {
// await element(by.id('world_button')).tap();
// await expect(element(by.text('World!!!'))).toBeVisible();
// });
// });
describe('should work inside node', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should require', () => {
const firebase = bridge.module;
return Promise.resolve();
});
it('should require 2', () => {
const firebase = bridge.module;
// const { Platform } = bridge.rnModule;
// should.equal(firebase.auth.nativeModuleExists, true);
return Promise.resolve();
});
it('should require 3', () => {
const firebase = bridge.module;
// const { Platform } = bridge.rnModule;
// should.equal(firebase.auth.nativeModuleExists, true);
return Promise.resolve();
});
it('should require 4', () => {
const firebase = bridge.module;
// const { Platform } = bridge.rnModule;
// should.equal(firebase.auth.nativeModuleExists, true);
return Promise.resolve();
});
it('should require 5', () => {
const firebase = bridge.module;
// const { Platform } = bridge.rnModule;
// should.equal(firebase.auth.nativeModuleExists, true);
return Promise.resolve();
});
});

View File

@ -0,0 +1,78 @@
const should = require('should');
describe('firestore.runTransaction', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should set, update and delete transactionally and allow a return value', async () => {
const firebase = bridge.module;
let deleteMe = false;
const firestore = firebase.firestore();
const docRef = firestore
.collection('transactions')
.doc(Date.now().toString());
const updateFunction = async transaction => {
const doc = await transaction.get(docRef);
if (doc.exists && deleteMe) {
transaction.delete(docRef);
return 'bye';
}
if (!doc.exists) {
transaction.set(docRef, { value: 1 });
return 1;
}
const newValue = doc.data().value + 1;
if (newValue > 2) {
return Promise.reject(new Error('Value should not be greater than 2!'));
}
transaction.update(docRef, {
value: newValue,
somethingElse: 'update',
});
return newValue;
};
// set tests
const val1 = await firestore.runTransaction(updateFunction);
should.equal(val1, 1);
const doc1 = await docRef.get();
doc1.data().value.should.equal(1);
should.equal(doc1.data().somethingElse, undefined);
// update
const val2 = await firestore.runTransaction(updateFunction);
should.equal(val2, 2);
const doc2 = await docRef.get();
doc2.data().value.should.equal(2);
doc2.data().somethingElse.should.equal('update');
// rejecting / cancelling transaction
let didReject = false;
try {
await firestore.runTransaction(updateFunction);
} catch (e) {
didReject = true;
}
should.equal(didReject, true);
const doc3 = await docRef.get();
doc3.data().value.should.equal(2);
doc3.data().somethingElse.should.equal('update');
// delete
deleteMe = true;
const val4 = await firestore.runTransaction(updateFunction);
should.equal(val4, 'bye');
const doc4 = await docRef.get();
should.equal(doc4.exists, false);
return Promise.resolve('Test Completed');
});
});

View File

@ -1,4 +1,5 @@
--recursive
--timeout 120000
--slow 1200
--bail
--require ./bridge/env/node

View File

@ -4,6 +4,14 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@sinonjs/formatio": {
"version": "2.0.0",
"resolved": "http://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz",
"integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==",
"requires": {
"samsam": "1.3.0"
}
},
"absolute-path": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/absolute-path/-/absolute-path-0.0.0.tgz",
@ -960,6 +968,15 @@
"babel-runtime": "6.26.0"
}
},
"babel-plugin-transform-es2015-duplicate-keys": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
"integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
"requires": {
"babel-runtime": "6.26.0",
"babel-types": "6.26.0"
}
},
"babel-plugin-transform-es2015-for-of": {
"version": "6.23.0",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
@ -1054,6 +1071,14 @@
"babel-runtime": "6.26.0"
}
},
"babel-plugin-transform-es2015-typeof-symbol": {
"version": "6.23.0",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
"integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
"requires": {
"babel-runtime": "6.26.0"
}
},
"babel-plugin-transform-es2015-unicode-regex": {
"version": "6.24.1",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
@ -1185,6 +1210,82 @@
}
}
},
"babel-preset-es2015": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.6.0.tgz",
"integrity": "sha1-iLM+WP7JTG695Y3GXs5dFODsJWg=",
"requires": {
"babel-plugin-check-es2015-constants": "6.22.0",
"babel-plugin-transform-es2015-arrow-functions": "6.22.0",
"babel-plugin-transform-es2015-block-scoped-functions": "6.22.0",
"babel-plugin-transform-es2015-block-scoping": "6.26.0",
"babel-plugin-transform-es2015-classes": "6.24.1",
"babel-plugin-transform-es2015-computed-properties": "6.24.1",
"babel-plugin-transform-es2015-destructuring": "6.23.0",
"babel-plugin-transform-es2015-duplicate-keys": "6.24.1",
"babel-plugin-transform-es2015-for-of": "6.23.0",
"babel-plugin-transform-es2015-function-name": "6.24.1",
"babel-plugin-transform-es2015-literals": "6.22.0",
"babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
"babel-plugin-transform-es2015-object-super": "6.24.1",
"babel-plugin-transform-es2015-parameters": "6.24.1",
"babel-plugin-transform-es2015-shorthand-properties": "6.24.1",
"babel-plugin-transform-es2015-spread": "6.22.0",
"babel-plugin-transform-es2015-sticky-regex": "6.24.1",
"babel-plugin-transform-es2015-template-literals": "6.22.0",
"babel-plugin-transform-es2015-typeof-symbol": "6.23.0",
"babel-plugin-transform-es2015-unicode-regex": "6.24.1",
"babel-plugin-transform-regenerator": "6.26.0"
}
},
"babel-preset-es2015-mod": {
"version": "6.6.0",
"resolved": "https://registry.npmjs.org/babel-preset-es2015-mod/-/babel-preset-es2015-mod-6.6.0.tgz",
"integrity": "sha1-4QW2LrfBABCQq4YiUpiQTPkMHo4=",
"requires": {
"babel-plugin-transform-es2015-modules-commonjs": "6.7.7",
"babel-plugin-transform-regenerator": "6.6.5",
"babel-preset-es2015": "6.6.0",
"modify-babel-preset": "2.0.2"
},
"dependencies": {
"babel-plugin-transform-es2015-modules-commonjs": {
"version": "6.7.7",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.7.7.tgz",
"integrity": "sha1-+lyiAWYXxNcSEj2M/BV4f8qoPzM=",
"requires": {
"babel-plugin-transform-strict-mode": "6.24.1",
"babel-runtime": "5.8.38",
"babel-template": "6.26.0",
"babel-types": "6.26.0"
}
},
"babel-plugin-transform-regenerator": {
"version": "6.6.5",
"resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.6.5.tgz",
"integrity": "sha1-B5qYK9VuIjXjHuOxetVK66iY1Oc=",
"requires": {
"babel-core": "6.26.0",
"babel-plugin-syntax-async-functions": "6.13.0",
"babel-plugin-transform-es2015-block-scoping": "6.26.0",
"babel-plugin-transform-es2015-for-of": "6.23.0",
"babel-runtime": "5.8.38",
"babel-traverse": "6.26.0",
"babel-types": "6.26.0",
"babylon": "6.18.0",
"private": "0.1.8"
}
},
"babel-runtime": {
"version": "5.8.38",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.38.tgz",
"integrity": "sha1-HAsC62MxL18If/IEUIJ7QlydTBk=",
"requires": {
"core-js": "1.2.7"
}
}
}
},
"babel-preset-es2015-node": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/babel-preset-es2015-node/-/babel-preset-es2015-node-6.1.1.tgz",
@ -1201,6 +1302,15 @@
"semver": "5.5.0"
}
},
"babel-preset-es3": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/babel-preset-es3/-/babel-preset-es3-1.0.1.tgz",
"integrity": "sha1-4I3ZUKFnDauLUKvOqpuT09mszR4=",
"requires": {
"babel-plugin-transform-es3-member-expression-literals": "6.22.0",
"babel-plugin-transform-es3-property-literals": "6.22.0"
}
},
"babel-preset-fbjs": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-2.1.4.tgz",
@ -5099,6 +5209,11 @@
"integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=",
"dev": true
},
"just-extend": {
"version": "1.1.27",
"resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz",
"integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g=="
},
"kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
@ -5216,6 +5331,11 @@
"lodash._root": "3.0.1"
}
},
"lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
},
"lodash.isarguments": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
@ -5286,6 +5406,11 @@
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
"integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
},
"lolex": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.2.tgz",
"integrity": "sha512-A5pN2tkFj7H0dGIAM6MFvHKMJcPnjZsOMvR7ujCjfgW5TbV6H9vb1PgxLtHvjqNZTHsUolz+6/WEO0N1xNx2ng=="
},
"loose-envify": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
@ -5725,6 +5850,14 @@
}
}
},
"modify-babel-preset": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/modify-babel-preset/-/modify-babel-preset-2.0.2.tgz",
"integrity": "sha1-v6UJZp/kn0IiwM4XG6RO0OgVUec=",
"requires": {
"require-relative": "0.8.7"
}
},
"morgan": {
"version": "1.6.1",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.6.1.tgz",
@ -5838,6 +5971,18 @@
"integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
"dev": true
},
"nise": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/nise/-/nise-1.3.2.tgz",
"integrity": "sha512-KPKb+wvETBiwb4eTwtR/OsA2+iijXP+VnlSFYJo3EHjm2yjek1NWxHOUQat3i7xNLm1Bm18UA5j5Wor0yO2GtA==",
"requires": {
"@sinonjs/formatio": "2.0.0",
"just-extend": "1.1.27",
"lolex": "2.3.2",
"path-to-regexp": "1.7.0",
"text-encoding": "0.6.4"
}
},
"node-fetch": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
@ -6245,6 +6390,14 @@
"integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
"dev": true
},
"path-to-regexp": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
"integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
"requires": {
"isarray": "0.0.1"
}
},
"path-type": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
@ -6901,6 +7054,11 @@
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
},
"require-relative": {
"version": "0.8.7",
"resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz",
"integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4="
},
"require-uncached": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
@ -7008,6 +7166,11 @@
"ret": "0.1.15"
}
},
"samsam": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz",
"integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg=="
},
"sane": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/sane/-/sane-2.5.0.tgz",
@ -7464,6 +7627,59 @@
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww=="
},
"should": {
"version": "13.2.1",
"resolved": "https://registry.npmjs.org/should/-/should-13.2.1.tgz",
"integrity": "sha512-l+/NwEMO+DcstsHEwPHRHzC9j4UOE3VQwJGcMWSsD/vqpqHbnQ+1iSHy64Ihmmjx1uiRPD9pFadTSc3MJtXAgw==",
"requires": {
"should-equal": "2.0.0",
"should-format": "3.0.3",
"should-type": "1.4.0",
"should-type-adaptors": "1.1.0",
"should-util": "1.0.0"
}
},
"should-equal": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz",
"integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==",
"requires": {
"should-type": "1.4.0"
}
},
"should-format": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz",
"integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=",
"requires": {
"should-type": "1.4.0",
"should-type-adaptors": "1.1.0"
}
},
"should-sinon": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/should-sinon/-/should-sinon-0.0.6.tgz",
"integrity": "sha512-ScBOH5uW5QVFaONmUnIXANSR6z5B8IKzEmBP3HE5sPOCDuZ88oTMdUdnKoCVQdLcCIrRrhRLPS5YT+7H40a04g=="
},
"should-type": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz",
"integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM="
},
"should-type-adaptors": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz",
"integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==",
"requires": {
"should-type": "1.4.0",
"should-util": "1.0.0"
}
},
"should-util": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.0.tgz",
"integrity": "sha1-yYzaN0qmsZDfi6h8mInCtNtiAGM="
},
"signal-exit": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
@ -7501,6 +7717,30 @@
}
}
},
"sinon": {
"version": "4.4.8",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-4.4.8.tgz",
"integrity": "sha512-EWZf/D5BN/BbDFPmwY2abw6wgELVmk361self+lcwEmVw0WWUxURp2S/YoDB2WG/xurFVzKQglMARweYRWM6Hw==",
"requires": {
"@sinonjs/formatio": "2.0.0",
"diff": "3.3.1",
"lodash.get": "4.4.2",
"lolex": "2.3.2",
"nise": "1.3.2",
"supports-color": "5.3.0",
"type-detect": "4.0.8"
},
"dependencies": {
"supports-color": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz",
"integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==",
"requires": {
"has-flag": "3.0.0"
}
}
}
},
"slash": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
@ -8289,6 +8529,11 @@
}
}
},
"text-encoding": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz",
"integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk="
},
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@ -8445,6 +8690,11 @@
"prelude-ls": "1.1.2"
}
},
"type-detect": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="
},
"type-is": {
"version": "1.6.16",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",

View File

@ -13,11 +13,16 @@
"ios:pod:install": "cd ios && rm -rf ReactNativeFirebaseDemo.xcworkspace && pod install && cd .."
},
"dependencies": {
"babel-preset-es2015-mod": "^6.6.0",
"babel-preset-es3": "^1.0.1",
"detox": "^7.2.0",
"mocha": "^4.0.1",
"react": "^16.2.0",
"react-native": "^0.52.3",
"react-native-restart": "0.0.6",
"should": "^13.2.1",
"should-sinon": "0.0.6",
"sinon": "^4.4.8",
"ws": "^5.1.0"
},
"devDependencies": {