diff --git a/packages/react-native/Libraries/Components/ProgressBarAndroid/__tests__/ProgressBarAndroid-itest.js b/packages/react-native/Libraries/Components/ProgressBarAndroid/__tests__/ProgressBarAndroid-itest.js new file mode 100644 index 000000000000..e9ac0dc193ae --- /dev/null +++ b/packages/react-native/Libraries/Components/ProgressBarAndroid/__tests__/ProgressBarAndroid-itest.js @@ -0,0 +1,136 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; + +import * as Fantom from '@react-native/fantom'; +import * as React from 'react'; +// $FlowFixMe[missing-platform-support] +import ProgressBarAndroid from '../ProgressBarAndroid.android'; + +describe('', () => { + describe('props', () => { + describe('styleAttr and indeterminate', () => { + it('renders with styleAttr="Horizontal" and indeterminate={true}', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + , + ); + }); + + expect(root.getRenderedOutput().toJSX()).toEqual( + , + ); + }); + + it('renders with default props', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + , + ); + }); + + expect(root.getRenderedOutput().toJSX()).toEqual( + , + ); + }); + + it('renders with styleAttr="Normal"', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + , + ); + }); + + expect(root.getRenderedOutput().toJSX()).toEqual( + , + ); + }); + + it('renders with styleAttr="Horizontal" and determinate progress', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + , + ); + }); + + expect(root.getRenderedOutput().toJSX()).toEqual( + , + ); + }); + }); + + describe('animating', () => { + it('defaults to true', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + , + ); + }); + + expect(root.getRenderedOutput().toJSX()).toEqual( + , + ); + }); + + it('renders when animating is false', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + , + ); + }); + + expect(root.getRenderedOutput().toJSX()).toEqual( + , + ); + }); + }); + + describe('testID', () => { + it('is propagated to the native component', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + , + ); + }); + + expect(root.getRenderedOutput({props: ['testID']}).toJSX()).toEqual( + , + ); + }); + }); + }); +}); diff --git a/packages/react-native/Libraries/Components/ProgressBarAndroid/__tests__/ProgressBarAndroid-test.js b/packages/react-native/Libraries/Components/ProgressBarAndroid/__tests__/ProgressBarAndroid-test.js deleted file mode 100644 index e187637eec70..000000000000 --- a/packages/react-native/Libraries/Components/ProgressBarAndroid/__tests__/ProgressBarAndroid-test.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict-local - * @format - */ - -'use strict'; - -const ReactNativeTestTools = require('../../../Utilities/ReactNativeTestTools'); -/* $FlowFixMe[cannot-resolve-module] (>=0.99.0 site=react_native_ios_fb) This - * comment suppresses an error found when Flow v0.99 was deployed. To see the - * error, delete this comment and run Flow. */ -// $FlowFixMe[missing-platform-support] -const ProgressBarAndroid = require('../ProgressBarAndroid.android').default; -const React = require('react'); - -describe('', () => { - it('should render as expected', async () => { - await ReactNativeTestTools.expectRendersMatchingSnapshot( - 'ProgressBarAndroid', - () => , - () => { - jest.dontMock('../ProgressBarAndroid'); - }, - ); - }); -}); diff --git a/packages/react-native/Libraries/Components/SafeAreaView/__tests__/SafeAreaView-itest.js b/packages/react-native/Libraries/Components/SafeAreaView/__tests__/SafeAreaView-itest.js new file mode 100644 index 000000000000..fc826b67b17f --- /dev/null +++ b/packages/react-native/Libraries/Components/SafeAreaView/__tests__/SafeAreaView-itest.js @@ -0,0 +1,39 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; + +import * as Fantom from '@react-native/fantom'; +import * as React from 'react'; +import {SafeAreaView, Text, View} from 'react-native'; + +describe('', () => { + it('renders with children', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + Hello World! + + , + ); + }); + + expect(root.getRenderedOutput({props: []}).toJSX()).toEqual( + + + Hello World! + + , + ); + }); +}); diff --git a/packages/react-native/Libraries/Components/SafeAreaView/__tests__/SafeAreaView-test.js b/packages/react-native/Libraries/Components/SafeAreaView/__tests__/SafeAreaView-test.js deleted file mode 100644 index e5387b169017..000000000000 --- a/packages/react-native/Libraries/Components/SafeAreaView/__tests__/SafeAreaView-test.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import SafeAreaView from '../SafeAreaView'; - -const Text = require('../../../Text/Text').default; -const ReactNativeTestTools = require('../../../Utilities/ReactNativeTestTools'); -const View = require('../../View/View').default; -const React = require('react'); - -describe('', () => { - it('should render as expected', async () => { - await ReactNativeTestTools.expectRendersMatchingSnapshot( - 'SafeAreaView', - () => ( - - - Hello World! - - - ), - () => { - jest.dontMock('../SafeAreaView'); - }, - ); - }); -}); diff --git a/packages/react-native/Libraries/Components/Touchable/__tests__/TouchableHighlight-itest.js b/packages/react-native/Libraries/Components/Touchable/__tests__/TouchableHighlight-itest.js new file mode 100644 index 000000000000..01eb0ceea852 --- /dev/null +++ b/packages/react-native/Libraries/Components/Touchable/__tests__/TouchableHighlight-itest.js @@ -0,0 +1,162 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + * @oncall react_native + */ + +import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; + +import * as Fantom from '@react-native/fantom'; +import * as React from 'react'; +import {Text, TouchableHighlight, View} from 'react-native'; + +describe('', () => { + describe('rendering', () => { + it('renders as a view with accessible="true"', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + , + ); + }); + + expect(root.getRenderedOutput({props: ['accessible']}).toJSX()).toEqual( + + + , + ); + }); + + it('renders children inside the touchable', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + Touchable + , + ); + }); + + expect(root.getRenderedOutput({props: ['accessible']}).toJSX()).toEqual( + + Touchable + , + ); + }); + }); + + describe('disabled', () => { + it('sets accessibilityState disabled to true when disabled={true}', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + , + ); + }); + + expect( + root.getRenderedOutput({props: ['accessibilityState']}).toJSX(), + ).toEqual( + + + , + ); + }); + + it('sets accessibilityState disabled to true when disabled={true} and accessibilityState is empty', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + , + ); + }); + + expect( + root.getRenderedOutput({props: ['accessibilityState']}).toJSX(), + ).toEqual( + + + , + ); + }); + + it('keeps other accessibilityState fields when disabled={true}', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + , + ); + }); + + expect( + root.getRenderedOutput({props: ['accessibilityState']}).toJSX(), + ).toEqual( + + + , + ); + }); + + it('overrides accessibilityState disabled=false with disabled prop', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + , + ); + }); + + expect( + root.getRenderedOutput({props: ['accessibilityState']}).toJSX(), + ).toEqual( + + + , + ); + }); + + it('sets accessibilityState disabled when only accessibilityState has disabled=true', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + , + ); + }); + + expect( + root.getRenderedOutput({props: ['accessibilityState']}).toJSX(), + ).toEqual( + + + , + ); + }); + }); +}); diff --git a/packages/react-native/Libraries/Components/Touchable/__tests__/TouchableHighlight-test.js b/packages/react-native/Libraries/Components/Touchable/__tests__/TouchableHighlight-test.js deleted file mode 100644 index 338e22cdd3a2..000000000000 --- a/packages/react-native/Libraries/Components/Touchable/__tests__/TouchableHighlight-test.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import Text from '../../../Text/Text'; -import View from '../../View/View'; -import TouchableHighlight from '../TouchableHighlight'; -import * as React from 'react'; - -const render = require('@react-native/jest-preset/jest/renderer'); - -describe('TouchableHighlight', () => { - it('renders correctly', async () => { - const instance = await render.create( - - Touchable - , - ); - - expect(instance.toJSON()).toMatchSnapshot(); - }); - - it('has displayName', () => { - expect(TouchableHighlight.displayName).toEqual('TouchableHighlight'); - }); -}); - -describe('TouchableHighlight with disabled state', () => { - it('should be disabled when disabled is true', async () => { - expect( - await render.create( - - - , - ), - ).toMatchSnapshot(); - }); - - it('should be disabled when disabled is true and accessibilityState is empty', async () => { - expect( - await render.create( - - - , - ), - ).toMatchSnapshot(); - }); - - it('should keep accessibilityState when disabled is true', async () => { - expect( - await render.create( - - - , - ), - ).toMatchSnapshot(); - }); - - it('should overwrite accessibilityState with value of disabled prop', async () => { - expect( - await render.create( - - - , - ), - ).toMatchSnapshot(); - }); - - it('should disable button when accessibilityState is disabled', async () => { - expect( - await render.create( - - - , - ), - ).toMatchSnapshot(); - }); -}); diff --git a/packages/react-native/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-itest.js b/packages/react-native/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-itest.js new file mode 100644 index 000000000000..df50684e0b0f --- /dev/null +++ b/packages/react-native/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-itest.js @@ -0,0 +1,162 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + * @oncall react_native + */ + +import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; + +import * as Fantom from '@react-native/fantom'; +import * as React from 'react'; +import {Text, TouchableNativeFeedback, View} from 'react-native'; + +describe('', () => { + describe('displayName', () => { + it('has displayName set to TouchableNativeFeedback', () => { + expect(TouchableNativeFeedback.displayName).toEqual( + 'TouchableNativeFeedback', + ); + }); + }); + + describe('rendering', () => { + it('renders as a view with accessible="true"', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + , + ); + }); + + expect(root.getRenderedOutput({props: ['accessible']}).toJSX()).toEqual( + , + ); + }); + + it('renders with children', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + Touchable + + , + ); + }); + + expect(root.getRenderedOutput({props: ['accessible']}).toJSX()).toEqual( + + Touchable + , + ); + }); + }); + + describe('disabled prop', () => { + it('sets accessibilityState disabled to true when disabled={true}', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + , + ); + }); + + expect( + root.getRenderedOutput({props: ['accessibilityState']}).toJSX(), + ).toEqual( + , + ); + }); + + it('sets accessibilityState disabled to true even when accessibilityState is empty', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + , + ); + }); + + expect( + root.getRenderedOutput({props: ['accessibilityState']}).toJSX(), + ).toEqual( + , + ); + }); + + it('keeps other accessibilityState values when disabled={true}', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + , + ); + }); + + expect( + root.getRenderedOutput({props: ['accessibilityState']}).toJSX(), + ).toEqual( + , + ); + }); + + it('overwrites accessibilityState disabled=false when disabled={true}', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + , + ); + }); + + expect( + root.getRenderedOutput({props: ['accessibilityState']}).toJSX(), + ).toEqual( + , + ); + }); + + it('overwrites accessibilityState disabled=true when disabled={false}', () => { + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render( + + + , + ); + }); + + expect( + root.getRenderedOutput({props: ['accessibilityState']}).toJSX(), + ).toEqual( + , + ); + }); + }); +}); diff --git a/packages/react-native/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-test.js b/packages/react-native/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-test.js deleted file mode 100644 index 1b8a29e73c4b..000000000000 --- a/packages/react-native/Libraries/Components/Touchable/__tests__/TouchableNativeFeedback-test.js +++ /dev/null @@ -1,114 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict-local - * @format - */ - -'use strict'; - -import Text from '../../../Text/Text'; -import View from '../../View/View'; -import TouchableNativeFeedback from '../TouchableNativeFeedback'; -import * as React from 'react'; - -const render = require('@react-native/jest-preset/jest/renderer'); - -describe('TouchableWithoutFeedback', () => { - it('renders correctly', async () => { - const instance = await render.create( - - Touchable - , - ); - - expect(instance.toJSON()).toMatchSnapshot(); - }); - - it('has displayName', () => { - expect(TouchableNativeFeedback.displayName).toEqual( - 'TouchableNativeFeedback', - ); - }); -}); - -describe('', () => { - it('should render as expected', async () => { - const instance = await render.create( - - - , - ); - - expect(instance.toJSON()).toMatchSnapshot(); - }); -}); - -describe('', () => { - it('should be disabled when disabled is true', async () => { - expect( - await render.create( - - - , - ), - ).toMatchSnapshot(); - }); -}); - -describe('', () => { - it('should be disabled when disabled is true and accessibilityState is empty', async () => { - expect( - await render.create( - - - , - ), - ).toMatchSnapshot(); - }); -}); - -describe('', () => { - it('should keep accessibilityState when disabled is true', async () => { - expect( - await render.create( - - - , - ), - ).toMatchSnapshot(); - }); -}); - -describe('', () => { - it('should overwrite accessibilityState with value of disabled prop', async () => { - expect( - await render.create( - - - , - ), - ).toMatchSnapshot(); - }); -}); - -describe('', () => { - it('should overwrite accessibilityState with value of disabled prop', async () => { - expect( - await render.create( - - - , - ), - ).toMatchSnapshot(); - }); -}); diff --git a/packages/react-native/src/private/animated/__tests__/createAnimatedPropsHook-itest.js b/packages/react-native/src/private/animated/__tests__/createAnimatedPropsHook-itest.js new file mode 100644 index 000000000000..e506fd9eddfe --- /dev/null +++ b/packages/react-native/src/private/animated/__tests__/createAnimatedPropsHook-itest.js @@ -0,0 +1,122 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; + +import {AnimatedEvent} from '../../../../Libraries/Animated/AnimatedEvent'; +import createAnimatedPropsHook from '../createAnimatedPropsHook'; +import * as Fantom from '@react-native/fantom'; +import * as React from 'react'; +import {useLayoutEffect} from 'react'; + +describe('useAnimatedProps', () => { + it('returns the same ref callback when `props` changes', () => { + const useAnimatedProps = createAnimatedPropsHook(null); + + const refs: Array = []; + function Sentinel(props: {[string]: mixed}): React.Node { + // $FlowFixMe[underconstrained-implicit-instantiation] + const [, ref] = useAnimatedProps(props); + useLayoutEffect(() => { + refs.push(ref); + }, [ref]); + return null; + } + + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render(); + }); + expect(refs.length).toBe(1); + expect(typeof refs[0]).toBe('function'); + + Fantom.runTask(() => { + root.render(); + }); + expect(refs.length).toBe(1); + + Fantom.runTask(() => { + root.destroy(); + }); + Fantom.runWorkLoop(); + }); + + it('returns the same ref callback when `AnimatedEvent` is the same', () => { + const useAnimatedProps = createAnimatedPropsHook(null); + + const refs: Array = []; + function Sentinel(props: {[string]: mixed}): React.Node { + // $FlowFixMe[underconstrained-implicit-instantiation] + const [, ref] = useAnimatedProps(props); + useLayoutEffect(() => { + refs.push(ref); + }, [ref]); + return null; + } + + const event = new AnimatedEvent([{}], {useNativeDriver: true}); + + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render(); + }); + expect(refs.length).toBe(1); + expect(typeof refs[0]).toBe('function'); + + Fantom.runTask(() => { + root.render(); + }); + expect(refs.length).toBe(1); + + Fantom.runTask(() => { + root.destroy(); + }); + Fantom.runWorkLoop(); + }); + + it('returns a new ref callback when `AnimatedEvent` changes', () => { + const useAnimatedProps = createAnimatedPropsHook(null); + + const refs: Array = []; + function Sentinel(props: {[string]: mixed}): React.Node { + // $FlowFixMe[underconstrained-implicit-instantiation] + const [, ref] = useAnimatedProps(props); + useLayoutEffect(() => { + refs.push(ref); + }, [ref]); + return null; + } + + const eventA = new AnimatedEvent([{}], {useNativeDriver: true}); + const eventB = new AnimatedEvent([{}], {useNativeDriver: true}); + + const root = Fantom.createRoot(); + + Fantom.runTask(() => { + root.render(); + }); + expect(refs.length).toBe(1); + expect(typeof refs[0]).toBe('function'); + + Fantom.runTask(() => { + root.render(); + }); + expect(refs.length).toBe(2); + expect(typeof refs[1]).toBe('function'); + expect(refs[0]).not.toBe(refs[1]); + + Fantom.runTask(() => { + root.destroy(); + }); + Fantom.runWorkLoop(); + }); +}); diff --git a/packages/react-native/src/private/animated/__tests__/createAnimatedPropsHook-test.js b/packages/react-native/src/private/animated/__tests__/createAnimatedPropsHook-test.js deleted file mode 100644 index 1d15c9e038d2..000000000000 --- a/packages/react-native/src/private/animated/__tests__/createAnimatedPropsHook-test.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict-local - * @format - */ - -import {AnimatedEvent} from '../../../../Libraries/Animated/AnimatedEvent'; -import createAnimatedPropsHook from '../createAnimatedPropsHook'; -import {create, update} from '@react-native/jest-preset/jest/renderer'; -import {useLayoutEffect} from 'react'; - -describe('useAnimatedProps', () => { - it('returns the same ref callback when `props` changes', async () => { - const useAnimatedProps = createAnimatedPropsHook(null); - - const refs = []; - function Sentinel(props: {[string]: unknown}): React.Node { - const [, ref] = useAnimatedProps<{[string]: unknown}, unknown>(props); - useLayoutEffect(() => { - refs.push(ref); - }, [ref]); - return null; - } - - const root = await create(); - expect(refs.length).toBe(1); - expect(refs[0]).toBeInstanceOf(Function); - - await update(root, ); - expect(refs.length).toBe(1); - }); - - it('returns the same ref callback when `AnimatedEvent` is the same', async () => { - const useAnimatedProps = createAnimatedPropsHook(null); - - const refs = []; - function Sentinel(props: {[string]: unknown}): React.Node { - const [, ref] = useAnimatedProps<{[string]: unknown}, unknown>(props); - useLayoutEffect(() => { - refs.push(ref); - }, [ref]); - return null; - } - - const event = new AnimatedEvent([{}], {useNativeDriver: true}); - - const root = await create(); - expect(refs.length).toBe(1); - expect(refs[0]).toBeInstanceOf(Function); - - await update(root, ); - expect(refs.length).toBe(1); - }); - - it('returns a new ref callback when `AnimatedEvent` changes', async () => { - const useAnimatedProps = createAnimatedPropsHook(null); - - const refs = []; - function Sentinel(props: {[string]: unknown}): React.Node { - const [, ref] = useAnimatedProps<{[string]: unknown}, unknown>(props); - useLayoutEffect(() => { - refs.push(ref); - }, [ref]); - return null; - } - - const eventA = new AnimatedEvent([{}], {useNativeDriver: true}); - const eventB = new AnimatedEvent([{}], {useNativeDriver: true}); - - const root = await create(); - expect(refs.length).toBe(1); - expect(refs[0]).toBeInstanceOf(Function); - - await update(root, ); - expect(refs.length).toBe(2); - expect(refs[1]).toBeInstanceOf(Function); - - expect(refs[0]).not.toBe(refs[1]); - }); -}); diff --git a/packages/react-native/src/private/webapis/dom/oldstylecollections/__tests__/HTMLCollection-test.js b/packages/react-native/src/private/webapis/dom/oldstylecollections/__tests__/HTMLCollection-itest.js similarity index 95% rename from packages/react-native/src/private/webapis/dom/oldstylecollections/__tests__/HTMLCollection-test.js rename to packages/react-native/src/private/webapis/dom/oldstylecollections/__tests__/HTMLCollection-itest.js index cc281e40a521..0c3b61eae393 100644 --- a/packages/react-native/src/private/webapis/dom/oldstylecollections/__tests__/HTMLCollection-test.js +++ b/packages/react-native/src/private/webapis/dom/oldstylecollections/__tests__/HTMLCollection-itest.js @@ -8,6 +8,8 @@ * @format */ +import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment'; + import {createHTMLCollection} from '../HTMLCollection'; describe('HTMLCollection', () => { @@ -39,13 +41,13 @@ describe('HTMLCollection', () => { expect(() => { collection[0] = 'replacement'; - }).toThrow(TypeError); + }).toThrow(); expect(collection[0]).toBe('a'); expect(() => { // $FlowExpectedError[cannot-write] collection.length = 100; - }).toThrow(TypeError); + }).toThrow(); expect(collection.length).toBe(3); });