/** * Copyright (c) 2015-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format * @flow */ 'use strict'; const React = require('react'); const createReactClass = require('create-react-class'); const ReactNative = require('react-native'); /* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error * found when Flow v0.54 was deployed. To see the error delete this comment and * run Flow. */ const TimerMixin = require('react-timer-mixin'); const {StyleSheet, Text, View} = ReactNative; const {TestModule} = ReactNative.NativeModules; const TimersTest = createReactClass({ displayName: 'TimersTest', mixins: [TimerMixin], _nextTest: () => {}, _interval: -1, getInitialState() { return { count: 0, done: false, }; }, componentDidMount() { this.setTimeout(this.testSetTimeout0, 1000); }, testSetTimeout0() { this.setTimeout(this.testSetTimeout1, 0); }, testSetTimeout1() { this.setTimeout(this.testSetTimeout50, 1); }, testSetTimeout50() { this.setTimeout(this.testRequestAnimationFrame, 50); }, testRequestAnimationFrame() { this.requestAnimationFrame(this.testSetInterval0); }, testSetInterval0() { this._nextTest = this.testSetInterval20; this._interval = this.setInterval(this._incrementInterval, 0); }, testSetInterval20() { this._nextTest = this.testSetImmediate; this._interval = this.setInterval(this._incrementInterval, 20); }, testSetImmediate() { this.setImmediate(this.testClearTimeout0); }, testClearTimeout0() { const timeout = this.setTimeout(() => this._fail('testClearTimeout0'), 0); this.clearTimeout(timeout); this.testClearTimeout30(); }, testClearTimeout30() { const timeout = this.setTimeout(() => this._fail('testClearTimeout30'), 30); this.clearTimeout(timeout); this.setTimeout(this.testClearMulti, 50); }, testClearMulti() { const fails = []; fails.push(this.setTimeout(() => this._fail('testClearMulti-1'), 20)); fails.push(this.setTimeout(() => this._fail('testClearMulti-2'), 50)); const delayClear = this.setTimeout( () => this._fail('testClearMulti-3'), 50, ); fails.push(this.setTimeout(() => this._fail('testClearMulti-4'), 0)); fails.push(this.setTimeout(() => this._fail('testClearMulti-5'), 10)); fails.forEach(timeout => this.clearTimeout(timeout)); this.setTimeout(() => this.clearTimeout(delayClear), 20); this.setTimeout(this.testOrdering, 50); }, testOrdering() { // Clear timers are set first because it's more likely to uncover bugs. let fail0; this.setImmediate(() => this.clearTimeout(fail0)); fail0 = this.setTimeout( () => this._fail( 'testOrdering-t0, setImmediate should happen before ' + 'setTimeout 0', ), 0, ); let failAnim; // This should fail without the t=0 fastpath feature. this.setTimeout(() => this.cancelAnimationFrame(failAnim), 0); failAnim = this.requestAnimationFrame(() => this._fail( 'testOrdering-Anim, setTimeout 0 should happen before ' + 'requestAnimationFrame', ), ); let fail25; this.setTimeout(() => { this.clearTimeout(fail25); }, 20); fail25 = this.setTimeout( () => this._fail( 'testOrdering-t25, setTimeout 20 should happen before ' + 'setTimeout 25', ), 25, ); this.setTimeout(this.done, 50); }, done() { this.setState({done: true}, () => { TestModule.markTestCompleted(); }); }, render() { return ( {this.constructor.displayName + ': \n'} Intervals: {this.state.count + '\n'} {this.state.done ? 'Done' : 'Testing...'} ); }, _incrementInterval() { if (this.state.count > 3) { throw new Error('interval incremented past end.'); } if (this.state.count === 3) { this.clearInterval(this._interval); this.setState({count: 0}, this._nextTest); return; } this.setState({count: this.state.count + 1}); }, _fail(caller: string): void { throw new Error('_fail called by ' + caller); }, }); const styles = StyleSheet.create({ container: { backgroundColor: 'white', padding: 40, }, }); TimersTest.displayName = 'TimersTest'; module.exports = TimersTest;