1import asyncRetry from 'async-retry'; 2import { isMatch } from 'lodash'; 3import React from 'react'; 4import { Alert } from 'react-native'; 5 6export const waitFor = (millis) => new Promise((resolve) => setTimeout(resolve, millis)); 7 8export const alertAndWaitForResponse = async (message) => { 9 return new Promise((resolve) => Alert.alert(message, null, [{ text: 'OK', onPress: resolve }])); 10}; 11 12export const retryForStatus = (object, status) => 13 asyncRetry( 14 async (bail, retriesCount) => { 15 const readStatus = await object.getStatusAsync(); 16 if (isMatch(readStatus, status)) { 17 return true; 18 } else { 19 const stringifiedStatus = JSON.stringify(status); 20 const desiredError = `The A/V instance has not entered desired state (${stringifiedStatus}) after ${retriesCount} retries.`; 21 const lastKnownError = `Last known state: ${JSON.stringify(readStatus)}.`; 22 throw new Error(`${desiredError} ${lastKnownError}`); 23 } 24 }, 25 { retries: 5, minTimeout: 100 } 26 ); 27 28export const mountAndWaitFor = (child, propName = 'ref', setPortalChild) => 29 new Promise((resolve) => { 30 // `ref` prop is set directly in the child, not in the `props` object. 31 // https://github.com/facebook/react/issues/8873#issuecomment-275423780 32 const previousPropFunc = propName === 'ref' ? child.ref : child.props[propName]; 33 const newPropFunc = (val) => { 34 previousPropFunc && previousPropFunc(val); 35 resolve(val); 36 }; 37 const clonedChild = React.cloneElement(child, { [propName]: newPropFunc }); 38 setPortalChild(clonedChild); 39 }); 40 41export class TimeoutError extends Error { 42 constructor(...args) { 43 super(...args); 44 this.name = 'TimeoutError'; 45 } 46} 47 48export const mountAndWaitForWithTimeout = (child, propName = 'ref', setPortalChild, timeout) => 49 Promise.race([ 50 mountAndWaitFor(child, propName, setPortalChild), 51 new Promise((resolve, reject) => { 52 setTimeout(() => { 53 reject(new TimeoutError(`mountAndWaitFor did not resolve after ${timeout} ms.`)); 54 }, timeout); 55 }), 56 ]); 57 58export default { 59 waitFor, 60 TimeoutError, 61 retryForStatus, 62 mountAndWaitFor, 63 mountAndWaitForWithTimeout, 64}; 65