* Copyright (c) 2024 Huawei Technologies Co., Ltd.
*
* This source code is licensed under the MIT license found in the
* LICENSE-MIT file in the root directory of this source tree.
*/
import { TestCase, TestSuite } from '@rnoh/testerino';
import React, { useEffect } from 'react';
import { AppState, AppStateStatus, Text } from 'react-native';
import { Button } from '../components';
async function wait(ms: number) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
const PRECISION_IN_MS = 100;
export function TimerTest() {
return (
<TestSuite name="Timer">
<TestCase
itShould="take three seconds to finish this test (setTimeout)"
initialState={0}
arrange={({ setState }) => {
return (
<Button
label="Start Timeout"
onPress={() => {
setState(prev => prev + 1);
}}
/>
);
}}
assert={async ({ expect }) => {
const waitTimeInMs = 3000;
const time1 = new Date().getTime();
await wait(waitTimeInMs);
const time2 = new Date().getTime();
expect(time1).to.be.greaterThan(0);
expect(time2).to.be.greaterThan(0);
expect(Math.abs(time2 - time1 - waitTimeInMs)).to.be.lessThan(
PRECISION_IN_MS,
);
}}
/>
<TestCase
itShould="take three seconds to finish this test (setInterval)"
initialState={0}
arrange={({ setState }) => {
return (
<Button
label="Start Interval"
onPress={() => {
setState(prev => prev + 1);
}}
/>
);
}}
assert={async ({ expect }) => {
await wait(3000);
let i = 0;
const time1 = new Date().getTime();
await new Promise(resolve => {
setInterval(() => {
if (i === 1) {
resolve(null);
}
i++;
}, 1000);
});
const time2 = new Date().getTime();
expect(Math.abs(time2 - time1 - 2000)).to.be.lessThan(
PRECISION_IN_MS,
);
}}
/>
<TestCase<{ date: Date; appStateStatus: AppStateStatus }[]>
modal
itShould="not trigger updates when the application is in background"
initialState={[]}
arrange={({ state, setState }) => {
return (
<Effect
onEffect={() => {
const interval = setInterval(() => {
setState(prev => [
...prev,
{
date: new Date(),
appStateStatus: AppState.currentState,
},
]);
}, 1000);
return () => clearInterval(interval);
}}>
<Text>
{JSON.stringify(
state.reduce(
(acc, tick) => {
return {
...acc,
[tick.appStateStatus]: acc[tick.appStateStatus] + 1,
};
},
{
active: 0,
background: 0,
extension: 0,
inactive: 0,
unknown: 0,
} as Record<AppStateStatus, number>,
),
)}
</Text>
</Effect>
);
}}
assert={({ expect, state }) => {
expect(
state.filter(tick => tick.appStateStatus !== 'active').length,
).to.be.eq(0);
}}
/>
</TestSuite>
);
}
function Effect({
onEffect,
children,
}: {
onEffect: () => void | (() => void);
children: any;
}) {
useEffect(onEffect, []);
return children;
}