Skip to content

Commit

Permalink
Support snapshots of many views (#6047)
Browse files Browse the repository at this point in the history
## Summary
Previously recording snapshots of component containing multiple views
were generating array of all the updates in random order.

The new API is as follows:
```
const component = getTestComponent('ComponentRed');
expect(updatesContainer.getUpdates(component)).toMatchSnapshots(Snapshots.component);
```
If you don't specify any component, but snapshot recorded more than one
an error is thrown. Same if you specify a component, but there is only
one recording.

Other changes in this PR include:
* Organise logic of matcher functions:
  * Move rawMatchers into separate file
  * Move snapshot matchers into separate file
* Clean up error log of snapshot mismatch and format as an array:
<img width="625" alt="Screenshot 2024-06-06 at 16 23 20"
src="https://github.com/software-mansion/react-native-reanimated/assets/56199675/c239e65c-d71a-44af-83cd-c3256da1d51f">

 
## Test plan
File `Animations.test.tsx` was renamed into
`TestsOfTestingFramework.test.tsx`, include some tests of snapshot
mismatch (and mismatch of callback functions)
Tested on Paper, on IOS and Android. Some of the fixes, created to make
tests work well on Android, were extracted into separate PR
#6084
  • Loading branch information
Latropos committed Jun 17, 2024
1 parent 6947a3c commit c41eee5
Show file tree
Hide file tree
Showing 25 changed files with 741 additions and 524 deletions.
8 changes: 8 additions & 0 deletions apps/common-app/src/examples/RuntimeTests/.prettierrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,12 @@ module.exports = {
singleQuote: true,
trailingComma: 'all',
printWidth: 120, // Increase line width to make test cases more compact
overrides: [
{
files: '*.snapshot.ts',
options: {
printWidth: 1000,
},
},
],
};
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { RUNTIME_TEST_ERRORS } from './stringFormatUtils';
import { TestCase, TestSuite } from './types';
import type { TestCase, TestSuite } from './types';

export function assertMockedAnimationTimestamp(timestamp: number | undefined): asserts timestamp is number {
'worklet';
if (timestamp === undefined) {
throw new Error(RUNTIME_TEST_ERRORS.NO_MOCKED_TIMESTAMP);
throw new Error("Seems that you've forgot to call `mockAnimationTimer()`");
}
}

export function assertTestSuite(test: TestSuite | null): asserts test is TestSuite {
if (!test) {
throw new Error(RUNTIME_TEST_ERRORS.UNDEFINED_TEST_SUITE);
throw new Error('Undefined test suite context');
}
}

export function assertTestCase(test: TestCase | null): asserts test is TestCase {
if (!test) {
throw new Error(RUNTIME_TEST_ERRORS.UNDEFINED_TEST_CASE);
throw new Error('Undefined test case context');
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ const ENGINEERING_NOTATION = [
1000000000e-7, 9.275686287246587e38,
];

const HEXADECIMAL_NOTATION = [0xff, 0xab1234, 0x123456, 0xffbbdd, 0x8989aaaa, 0x1234567890abcdef];
const HEXADECIMAL_NOTATION = [0xff, 0xab1234, 0x123456, 0xffbbdd, 0x8989aaaa, 0x1234567890abcd];

const BINARY_NOTATION = [0b1111111, 0b101010, 0b0001, 0b11001, 0b1111111111111111111111111111111111111111111111111111];

const OCTADECIMAL_NOTATION = [0o123456, 0o111111112];

const BIG_INTS = [
BigInt(123456789123456789),
BigInt(1234567891234567),
BigInt(Number.MAX_VALUE),
BigInt('0'),
BigInt('1'),
Expand Down Expand Up @@ -140,6 +140,7 @@ const BUFFER_ARRAYS = [new ArrayBuffer(8), new ArrayBuffer(0)];

const EMPTIES = [[], null, undefined, {}, [[]], [{}], [null]];

// eslint-disable-next-line symbol-description
const SYMBOLS = [Symbol('Hello!'), Symbol(123), Symbol()];

const DATES = [
Expand All @@ -156,6 +157,7 @@ const DATES = [
new Date(1999, 120, 17, 33, 54, 12),
];

// eslint-disable-next-line prefer-regex-literals
const REGEXPS = [/ab+c/i, new RegExp('ab+c', 'i'), new RegExp(/ab+c/, 'i'), /\d/y];

// const MAX_SIZE_OF_ARRAY = Math.pow(2, 31) - 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ type TestFunction = (name: string, buildTest: BuildFunction) => void;
type TestFunctionWithWarning = (name: string, warningMessage: string, buildTest: BuildFunction) => void;
type TestEachFunction = <T>(
examples: Array<T>,
) => (name: string, testCase: (example: T, index?: number) => void | Promise<void>) => void;
) => (name: string, testCase: (example: T, index: number) => void | Promise<void>) => void;
type TestEachFunctionWithWarning = <T>(
examples: Array<T>,
) => (name: string, expectedWarning: string, testCase: (example: T, index?: number) => void | Promise<void>) => void;
) => (name: string, expectedWarning: string, testCase: (example: T, index: number) => void | Promise<void>) => void;
type DecoratedTestFunction = TestFunction & { each: TestEachFunction };
type DecoratedTestFunctionWithWarning = TestFunctionWithWarning & { each: TestEachFunctionWithWarning };

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { View, Button, StyleSheet, Text } from 'react-native';
import React, { ReactNode, useEffect, useState } from 'react';
import type { ReactNode } from 'react';
import React, { useEffect, useState } from 'react';
import { runTests, configure } from './RuntimeTestsApi';
import { LockObject } from './types';
import type { LockObject } from './types';

let renderLock: LockObject = { lock: false };
export class ErrorBoundary extends React.Component<
Expand Down Expand Up @@ -38,6 +39,7 @@ export default function RuntimeTestsRunner() {
<View style={styles.container}>
<Button
title="Run tests"
// eslint-disable-next-line @typescript-eslint/no-misused-promises
onPress={async () => {
renderLock = configure({ render: setComponent });
await runTests();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Component } from 'react';
import type { Component } from 'react';
import { findNodeHandle } from 'react-native';
import { getViewProp } from 'react-native-reanimated';
import { ComponentRef, ValidPropNames } from './types';
import type { ComponentRef, ValidPropNames } from './types';

export class TestComponent {
constructor(private ref: ComponentRef) {}
constructor(private ref: ComponentRef) {
this.ref = ref;
}

public getStyle(propName: string) {
return this.ref.current?.props.style[propName];
Expand Down
Loading

0 comments on commit c41eee5

Please sign in to comment.