diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/Examples-UIExplorer-UIExplorerIntegrationTests-js-IntegrationTestsApp/testSimpleSnapshotTest_1@2x.png b/Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/Examples-UIExplorer-UIExplorerIntegrationTests-js-IntegrationTestsApp/testSimpleSnapshotTest_1@2x.png deleted file mode 100644 index fd91abf42..000000000 Binary files a/Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/Examples-UIExplorer-UIExplorerIntegrationTests-js-IntegrationTestsApp/testSimpleSnapshotTest_1@2x.png and /dev/null differ diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/Examples-UIExplorer-UIExplorerIntegrationTests-js-IntegrationTestsApp/testImageSnapshotTest_1@2x.png b/Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/IntegrationTests-IntegrationTestsApp/testImageSnapshotTest_1@2x.png similarity index 100% rename from Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/Examples-UIExplorer-UIExplorerIntegrationTests-js-IntegrationTestsApp/testImageSnapshotTest_1@2x.png rename to Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/IntegrationTests-IntegrationTestsApp/testImageSnapshotTest_1@2x.png diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/IntegrationTests-IntegrationTestsApp/testSimpleSnapshotTest_1@2x.png b/Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/IntegrationTests-IntegrationTestsApp/testSimpleSnapshotTest_1@2x.png new file mode 100644 index 000000000..ea37dc900 Binary files /dev/null and b/Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/IntegrationTests-IntegrationTestsApp/testSimpleSnapshotTest_1@2x.png differ diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/UIExplorerIntegrationTests.m b/Examples/UIExplorer/UIExplorerIntegrationTests/UIExplorerIntegrationTests.m index 834f60901..54efba917 100644 --- a/Examples/UIExplorer/UIExplorerIntegrationTests/UIExplorerIntegrationTests.m +++ b/Examples/UIExplorer/UIExplorerIntegrationTests/UIExplorerIntegrationTests.m @@ -37,10 +37,10 @@ NSOperatingSystemVersion version = [NSProcessInfo processInfo].operatingSystemVersion; RCTAssert((version.majorVersion == 8 && version.minorVersion >= 3) || version.majorVersion >= 9, @"Tests should be run on iOS 8.3+, found %zd.%zd.%zd", version.majorVersion, version.minorVersion, version.patchVersion); - _runner = RCTInitRunnerForApp(@"Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestsApp", nil); + _runner = RCTInitRunnerForApp(@"IntegrationTests/IntegrationTestsApp", nil); } -#pragma mark Logic Tests +#pragma mark - Test harness - (void)testTheTester_waitOneFrame { @@ -59,16 +59,17 @@ configurationBlock:nil expectErrorRegex:@"because shouldThrow"]; } +#pragma mark - JS tests + // This list should be kept in sync with IntegrationTestsApp.js RCT_TEST(IntegrationTestHarnessTest) RCT_TEST(TimersTest) RCT_TEST(AsyncStorageTest) RCT_TEST(AppEventsTest) //RCT_TEST(ImageSnapshotTest) // Disabled: #8985988 +//RCT_TEST(LayoutEventsTest) // Disabled due to flakiness: #8686784 RCT_TEST(SimpleSnapshotTest) +RCT_TEST(PromiseTest) -// Disable due to flakiness: #8686784 -//RCT_TEST(LayoutEventsTest) -//RCT_TEST(PromiseTest) @end diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/js/AppEventsTest.js b/IntegrationTests/AppEventsTest.js similarity index 96% rename from Examples/UIExplorer/UIExplorerIntegrationTests/js/AppEventsTest.js rename to IntegrationTests/AppEventsTest.js index 95370771b..7362072ff 100644 --- a/Examples/UIExplorer/UIExplorerIntegrationTests/js/AppEventsTest.js +++ b/IntegrationTests/AppEventsTest.js @@ -14,12 +14,11 @@ var React = require('react-native'); var { NativeAppEventEmitter, - NativeModules, StyleSheet, Text, View, } = React; -var TestModule = NativeModules.TestModule; +var { TestModule } = React.NativeModules; var deepDiffer = require('deepDiffer'); diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/js/AsyncStorageTest.js b/IntegrationTests/AsyncStorageTest.js similarity index 93% rename from Examples/UIExplorer/UIExplorerIntegrationTests/js/AsyncStorageTest.js rename to IntegrationTests/AsyncStorageTest.js index 43df4df18..3bd313a7f 100644 --- a/Examples/UIExplorer/UIExplorerIntegrationTests/js/AsyncStorageTest.js +++ b/IntegrationTests/AsyncStorageTest.js @@ -5,16 +5,18 @@ * 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'; -var RCTTestModule = require('NativeModules').TestModule; var React = require('react-native'); var { AsyncStorage, Text, View, } = React; +var { TestModule } = React.NativeModules; var deepDiffer = require('deepDiffer'); @@ -31,21 +33,21 @@ var VAL_MERGE_EXPECT = {'foo': 1, 'bar': {'hoo': 2, 'boo': 1}, 'baz': 2, 'moo': {'a': 3}}; // setup in componentDidMount -var done; -var updateMessage; +var done = (result : ?boolean) => {}; +var updateMessage = (message : string ) => {}; -function runTestCase(description, fn) { +function runTestCase(description : string, fn) { updateMessage(description); fn(); } -function expectTrue(condition, message) { +function expectTrue(condition : boolean, message : string) { if (!condition) { throw new Error(message); } } -function expectEqual(lhs, rhs, testname) { +function expectEqual(lhs, rhs, testname : string) { expectTrue( !deepDiffer(lhs, rhs), 'Error in test ' + testname + ': expected\n' + JSON.stringify(rhs) + @@ -155,7 +157,7 @@ var AsyncStorageTest = React.createClass({ }, componentDidMount() { - done = () => this.setState({done: true}, RCTTestModule.markTestCompleted); + done = () => this.setState({done: true}, TestModule.markTestCompleted); updateMessage = (msg) => { this.setState({messages: this.state.messages.concat('\n' + msg)}); DEBUG && console.log(msg); diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/js/ImageSnapshotTest.js b/IntegrationTests/ImageSnapshotTest.js similarity index 91% rename from Examples/UIExplorer/UIExplorerIntegrationTests/js/ImageSnapshotTest.js rename to IntegrationTests/ImageSnapshotTest.js index 13689742e..7724ab5d3 100644 --- a/Examples/UIExplorer/UIExplorerIntegrationTests/js/ImageSnapshotTest.js +++ b/IntegrationTests/ImageSnapshotTest.js @@ -5,6 +5,8 @@ * 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'; @@ -13,8 +15,7 @@ var { Image, View, } = React; - -var { TestModule } = React.addons; +var { TestModule } = React.NativeModules; var ImageSnapshotTest = React.createClass({ componentDidMount() { @@ -23,7 +24,7 @@ var ImageSnapshotTest = React.createClass({ } }, - done(success) { + done(success : boolean) { TestModule.markTestPassed(success); }, diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestHarnessTest.js b/IntegrationTests/IntegrationTestHarnessTest.js similarity index 84% rename from Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestHarnessTest.js rename to IntegrationTests/IntegrationTestHarnessTest.js index 12243a0fe..27ef7428d 100644 --- a/Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestHarnessTest.js +++ b/IntegrationTests/IntegrationTestHarnessTest.js @@ -5,15 +5,18 @@ * 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'; -var RCTTestModule = require('NativeModules').TestModule; +var requestAnimationFrame = require('requestAnimationFrame'); var React = require('react-native'); var { Text, View, } = React; +var { TestModule } = React.NativeModules; var IntegrationTestHarnessTest = React.createClass({ propTypes: { @@ -39,12 +42,12 @@ var IntegrationTestHarnessTest = React.createClass({ if (this.props.shouldThrow) { throw new Error('Throwing error because shouldThrow'); } - if (!RCTTestModule) { + if (!TestModule) { throw new Error('RCTTestModule is not registered.'); - } else if (!RCTTestModule.markTestCompleted) { + } else if (!TestModule.markTestCompleted) { throw new Error('RCTTestModule.markTestCompleted not defined.'); } - this.setState({done: true}, RCTTestModule.markTestCompleted); + this.setState({done: true}, TestModule.markTestCompleted); }, render() { diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestsApp.js b/IntegrationTests/IntegrationTestsApp.js similarity index 94% rename from Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestsApp.js rename to IntegrationTests/IntegrationTestsApp.js index 5ab306386..95c2697c1 100644 --- a/Examples/UIExplorer/UIExplorerIntegrationTests/js/IntegrationTestsApp.js +++ b/IntegrationTests/IntegrationTestsApp.js @@ -6,14 +6,11 @@ * 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. * - * @providesModule IntegrationTestsApp + * @flow */ 'use strict'; -require('regenerator/runtime'); - var React = require('react-native'); - var { AppRegistry, ScrollView, @@ -23,7 +20,7 @@ var { View, } = React; -/* Keep this list in sync with UIExplorerIntegrationTests.m */ +// Keep this list in sync with UIExplorerIntegrationTests.m var TESTS = [ require('./IntegrationTestHarnessTest'), require('./TimersTest'), diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/js/LayoutEventsTest.js b/IntegrationTests/LayoutEventsTest.js similarity index 98% rename from Examples/UIExplorer/UIExplorerIntegrationTests/js/LayoutEventsTest.js rename to IntegrationTests/LayoutEventsTest.js index 6719585fc..9f7eb7d54 100644 --- a/Examples/UIExplorer/UIExplorerIntegrationTests/js/LayoutEventsTest.js +++ b/IntegrationTests/LayoutEventsTest.js @@ -15,12 +15,11 @@ var React = require('react-native'); var { Image, LayoutAnimation, - NativeModules, StyleSheet, Text, View, } = React; -var TestModule = NativeModules.TestModule; +var { TestModule } = React.NativeModules; var deepDiffer = require('deepDiffer'); diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/js/PromiseTest.js b/IntegrationTests/PromiseTest.js similarity index 80% rename from Examples/UIExplorer/UIExplorerIntegrationTests/js/PromiseTest.js rename to IntegrationTests/PromiseTest.js index c28f4670a..563655c3d 100644 --- a/Examples/UIExplorer/UIExplorerIntegrationTests/js/PromiseTest.js +++ b/IntegrationTests/PromiseTest.js @@ -6,15 +6,14 @@ * 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. * - * @providesModule PromiseTest + * @flow */ 'use strict'; -var RCTTestModule = require('NativeModules').TestModule; var React = require('react-native'); +var { TestModule } = React.NativeModules; var PromiseTest = React.createClass({ - shouldResolve: false, shouldReject: false, shouldSucceedAsync: false, @@ -26,45 +25,45 @@ var PromiseTest = React.createClass({ this.testShouldReject(), this.testShouldSucceedAsync(), this.testShouldThrowAsync(), - ]).then(() => RCTTestModule.markTestPassed( + ]).then(() => TestModule.markTestPassed( this.shouldResolve && this.shouldReject && this.shouldSucceedAsync && this.shouldThrowAsync )); }, testShouldResolve() { - return RCTTestModule + return TestModule .shouldResolve() .then(() => this.shouldResolve = true) .catch(() => this.shouldResolve = false); }, testShouldReject() { - return RCTTestModule + return TestModule .shouldReject() .then(() => this.shouldReject = false) .catch(() => this.shouldReject = true); }, - async testShouldSucceedAsync() { + async testShouldSucceedAsync() : Promise { try { - await RCTTestModule.shouldResolve(); + await TestModule.shouldResolve(); this.shouldSucceedAsync = true; } catch (e) { this.shouldSucceedAsync = false; } }, - async testShouldThrowAsync() { + async testShouldThrowAsync() : Promise { try { - await RCTTestModule.shouldReject(); + await TestModule.shouldReject(); this.shouldThrowAsync = false; } catch (e) { this.shouldThrowAsync = true; } }, - render() { + render() : ReactElement { return ; } diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/js/SimpleSnapshotTest.js b/IntegrationTests/SimpleSnapshotTest.js similarity index 89% rename from Examples/UIExplorer/UIExplorerIntegrationTests/js/SimpleSnapshotTest.js rename to IntegrationTests/SimpleSnapshotTest.js index 20eacec48..2f0e93358 100644 --- a/Examples/UIExplorer/UIExplorerIntegrationTests/js/SimpleSnapshotTest.js +++ b/IntegrationTests/SimpleSnapshotTest.js @@ -5,16 +5,19 @@ * 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'; var React = require('react-native'); +var requestAnimationFrame = require('requestAnimationFrame'); + var { StyleSheet, View, } = React; - -var { TestModule } = React.addons; +var { TestModule } = React.NativeModules; var SimpleSnapshotTest = React.createClass({ componentDidMount() { @@ -24,7 +27,7 @@ var SimpleSnapshotTest = React.createClass({ requestAnimationFrame(() => TestModule.verifySnapshot(this.done)); }, - done(success) { + done(success : boolean) { TestModule.markTestPassed(success); }, diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/js/TimersTest.js b/IntegrationTests/TimersTest.js similarity index 95% rename from Examples/UIExplorer/UIExplorerIntegrationTests/js/TimersTest.js rename to IntegrationTests/TimersTest.js index c84dc3192..56fa9235c 100644 --- a/Examples/UIExplorer/UIExplorerIntegrationTests/js/TimersTest.js +++ b/IntegrationTests/TimersTest.js @@ -5,21 +5,27 @@ * 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'; -var RCTTestModule = require('NativeModules').TestModule; var React = require('react-native'); +var TimerMixin = require('react-timer-mixin'); + var { StyleSheet, Text, View, } = React; -var TimerMixin = require('react-timer-mixin'); +var { TestModule } = React.NativeModules; var TimersTest = React.createClass({ mixins: [TimerMixin], + _nextTest: () => {}, + _interval: -1, + getInitialState() { return { count: 0, @@ -113,7 +119,7 @@ var TimersTest = React.createClass({ }, done() { - this.setState({done: true}, RCTTestModule.markTestCompleted); + this.setState({done: true}, TestModule.markTestCompleted); }, render() { @@ -140,7 +146,7 @@ var TimersTest = React.createClass({ this.setState({count: this.state.count + 1}); }, - _fail(caller) { + _fail(caller : string) : void { throw new Error('_fail called by ' + caller); }, }); diff --git a/Libraries/RCTTest/RCTTestRunner.h b/Libraries/RCTTest/RCTTestRunner.h index aee9d412b..b5e8430cd 100644 --- a/Libraries/RCTTest/RCTTestRunner.h +++ b/Libraries/RCTTest/RCTTestRunner.h @@ -23,13 +23,19 @@ moduleProvider:(moduleProvider__)] @protocol RCTBridgeModule; +@class RCTBridge; @class RCTRootView; @interface RCTTestRunner : NSObject +/** + * Controls the mode snapshots are run in. If set to true, new snapshots are written to disk, + * otherwise, the UI will be compared to the existing snapshot. + */ @property (nonatomic, assign) BOOL recordMode; -@property (nonatomic, strong) NSURL *scriptURL; + +@property (nonatomic, readonly) NSURL *scriptURL; /** * Initialize a runner. It's recommended that you use the RCTInitRunnerForApp