Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more tests - useSharedValue, useAnimatedStyle , useDerivedValue #5981

Merged
merged 12 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ComparisonMode, TestValue } from './types';
import { ComparisonMode, TestValue, ValidPropNames } from './types';

const DISTANCE_TOLERANCE = 0.5;

Expand Down Expand Up @@ -54,6 +54,13 @@ const COMPARATORS: {
},

[ComparisonMode.OBJECT]: (expected, value) => {
if (expected === null || value === null) {
return expected === null && value === null;
}
if (expected === undefined || value === undefined) {
return expected === undefined && value === undefined;
}

if (typeof expected !== 'object' || typeof value !== 'object') {
return false;
}
Expand Down Expand Up @@ -90,3 +97,16 @@ const COMPARATORS: {
export function getComparator(mode: ComparisonMode) {
return COMPARATORS[mode];
}

export function getComparisonModeForProp(prop: ValidPropNames): ComparisonMode {
const propToComparisonModeDict = {
zIndex: ComparisonMode.NUMBER,
opacity: ComparisonMode.NUMBER,
width: ComparisonMode.DISTANCE,
height: ComparisonMode.DISTANCE,
top: ComparisonMode.DISTANCE,
left: ComparisonMode.DISTANCE,
backgroundColor: ComparisonMode.COLOR,
};
return propToComparisonModeDict[prop];
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class Matchers {
constructor(private _currentValue: TestValue, private _testCase: TestCase) {}

private static _assertValueIsCallTracker(value: TrackerCallCount | TestValue): asserts value is TrackerCallCount {
if (typeof value !== 'object' || !('name' in value && 'onJS' in value && 'onUI' in value)) {
if (typeof value !== 'object' || !(value !== null && 'name' in value && 'onJS' in value && 'onUI' in value)) {
throw Error('Invalid value');
}
}
Expand Down Expand Up @@ -145,13 +145,15 @@ export class Matchers {
public toMatchNativeSnapshots(nativeSnapshots: Array<OperationUpdate>, expectNegativeMismatch = false) {
let errorString = '';
const jsUpdates = this._currentValue as Array<OperationUpdate>;
for (let i = 0; i < jsUpdates.length; i++) {
errorString += this.compareJsAndNativeSnapshot(jsUpdates, nativeSnapshots, i, expectNegativeMismatch);
}

if (jsUpdates.length !== nativeSnapshots.length - 1) {
errorString += `Expected ${jsUpdates.length} snapshots, but received ${nativeSnapshots.length - 1} snapshots\n`;
} else {
for (let i = 0; i < jsUpdates.length; i++) {
errorString += this.compareJsAndNativeSnapshot(jsUpdates, nativeSnapshots, i, expectNegativeMismatch);
}
}

if (errorString !== '') {
this._testCase.errors.push('Native snapshot mismatch: \n' + errorString);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// #region numbers
const INTEGERS = [
-1000000000, -1234567, -1000000, -1000, -10, -5, -3, -2, -1, -0, 0, +0, 1, 2, 3, 5, 10, 1000, 1000000, -1234567,
1000000000,
Expand All @@ -21,7 +22,18 @@ const BINARY_NOTATION = [0b1111111, 0b101010, 0b0001, 0b11001, 0b111111111111111

const OCTADECIMAL_NOTATION = [0o123456, 0o111111112];

const BIG_INTS = [BigInt(123456789123456789), BigInt(Number.MAX_VALUE)];
const BIG_INTS = [
BigInt(123456789123456789),
BigInt(Number.MAX_VALUE),
BigInt('0'),
BigInt('1'),
BigInt(-1),
BigInt(-123456789),
BigInt('9007199254740991'),
BigInt('0x1fffffffffffff'),
BigInt('0o377777777777777777'),
BigInt('0b11111111111111111111111111111111111111111111111111111'),
];

const UNDERSCORE_SEPARATED_NUMBES = [
0b00_000_000_000_000_000_000_000_000_000_001, -1.07808734473_36499e-3_9, 1_0_00000000.1234567,
Expand All @@ -36,13 +48,15 @@ const EXTREME_NUMBERS = [
Number.EPSILON,
];

const TYPICAL_STRINGS = [
'Aaaaaaa\n \t\t \v aaaaaa',
'Super long'.repeat(10000000),
const NOT_NUMBERS = [Infinity, -Infinity, NaN];
// #endregion

// #region strings
const TYPICAL_STRINGS = ['Aaaaaaa\n \t\t \v aaaaaa', 'Super long'.repeat(10000000), '', 'A string primitive'];

const STRING_OBJECTS = [
// eslint-disable-next-line no-new-wrappers
new String('A String object'),
'',
'A string primitive',
];

const EMOJI_STRINGS = ['Emoji consisting of multiple sub-emojis 👨‍👨‍👧‍👦', '👨‍👨‍👧‍👦', '😎', '👩🏽‍🏫'];
Expand Down Expand Up @@ -72,30 +86,9 @@ const MISC_CHARACTERS = [
'🅷🅴🅻🅻🅾 🆆🅾🆁🅳',
'🅗🅔🅛🅛🅞 🅦🅞🅡🅓',
];
const NOT_NUMBERS = [Infinity, -Infinity, NaN];

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

const FANCY_OBJECTS = [globalThis];

const SYMBOLS = [Symbol('Hello!'), Symbol(123), Symbol()];

const DATES = [
new Date('2012-05-24'),
Intl.DateTimeFormat(navigator.language),
new Date('December 17, 1995 03:24:00'),
new Date(),
new Date(1999, 11),
new Date(1999, 11, 24),
new Date(1999, 11, 17),
new Date(1999, 11, 17, 33),
new Date(1999, 11, 17, 33, 54),
new Date(1999, 11, 17, 33, 54, 12),
new Date(1999, 120, 17, 33, 54, 12),
];

const REGEXPS = [/ab+c/i, new RegExp('ab+c', 'i'), new RegExp(/ab+c/, 'i'), /\d/y];
// #endregion

// #region bufferArrays
const iterable = (function* () {
yield* [1, 2, 3];
})();
Expand Down Expand Up @@ -142,14 +135,44 @@ const FLOAT_ARRAYS = [
new Float64Array(iterable),
];

const BUFFER_ARRAYS = [new ArrayBuffer(8), new ArrayBuffer(0)];
// #endregion

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

const SYMBOLS = [Symbol('Hello!'), Symbol(123), Symbol()];

const DATES = [
new Date('2012-05-24'),
Intl.DateTimeFormat(navigator.language),
new Date('December 17, 1995 03:24:00'),
new Date(),
new Date(1999, 11),
new Date(1999, 11, 24),
new Date(1999, 11, 17),
new Date(1999, 11, 17, 33),
new Date(1999, 11, 17, 33, 54),
new Date(1999, 11, 17, 33, 54, 12),
new Date(1999, 120, 17, 33, 54, 12),
];

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;
const MAX_SIZE_OF_ARRAY = 1000;

const ARRAYS = [
const NUMERICAL_ARRAYS = [
Array.from(Array(MAX_SIZE_OF_ARRAY).keys()),
[[[[[[[[[[[[[[[[[[1], 2], 3], 4], 5], 6], 7], 8], 9], [[[[], 10]]]]]]]]]]]],

new ArrayBuffer(8),
new ArrayBuffer(0),
];
const VARIOUS_TYPE_ARRAYS = [
['a', 123],
[1, 2, 3, ['A', 'B', 'C', 'D']],
[1, 2, 3, [{ A: 'A' }, 'B', 'C', 'D']],
[1, 2, 3, [{ A: ['A'] }, 'B', 'C', 'D']],
[null, 2, 3, ['A', [[[null]]], 'B', 'C', 'D']],
[null, undefined, [undefined, [[[null]]], undefined], [[], []]],
[null, undefined, [{}, [[[null]]], undefined], [[], []]],
];

const OBJECTS = [
Expand Down Expand Up @@ -181,19 +204,22 @@ export const Presets = {
...HEXADECIMAL_NOTATION,
...BINARY_NOTATION,
...OCTADECIMAL_NOTATION,
...BIG_INTS,
...UNDERSCORE_SEPARATED_NUMBES,
],
bigInts: BIG_INTS,
strings: [
...TYPICAL_STRINGS,
...EMOJI_STRINGS,
...COMMON_CHARS_AND_LIGATURES,
...NON_DEFAULT_ALPHABETS,
...MISC_CHARACTERS,
],
stringObjects: [...STRING_OBJECTS],
symbols: SYMBOLS,
regexps: REGEXPS,
dates: DATES,
objects: [...MAPS, ...SETS, ...OBJECTS, ...EMPTIES, ...FANCY_OBJECTS],
arrays: [...INT_ARRAYS, ...UINT_ARRAYS, ...FLOAT_ARRAYS, ...ARRAYS],
serializableObjects: [...OBJECTS, ...EMPTIES, ...REGEXPS],
unserializableObjects: [...MAPS, ...SETS],
serializableArrays: [...NUMERICAL_ARRAYS, ...VARIOUS_TYPE_ARRAYS],
arrays: [...INT_ARRAYS, ...UINT_ARRAYS, ...FLOAT_ARRAYS, ...NUMERICAL_ARRAYS, ...BUFFER_ARRAYS],
};
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const describe: {
testRunner.describe(name, buildSuite, DescribeDecorator.SKIP);
},
only: (name: string, buildSuite: () => void) => {
testRunner.describe(name, buildSuite, DescribeDecorator.SKIP);
testRunner.describe(name, buildSuite, DescribeDecorator.ONLY);
},
},
);
Expand Down Expand Up @@ -65,13 +65,13 @@ export const test: {
},
{
each: <T>(examples: Array<T>) => {
return testRunner.testEach(examples, null);
return testRunner.testEach(examples, TestDecorator.ONLY);
},
},
),
failing: Object.assign(
(name: string, warningMessage: string, testCase: () => void) => {
testRunner.test(name, testCase, TestDecorator.FAILING, warningMessage);
(name: string, expectedWarning: string, testCase: () => void) => {
testRunner.test(name, testCase, TestDecorator.FAILING, expectedWarning);
},
{
each: <T>(examples: Array<T>) => {
Expand All @@ -81,7 +81,7 @@ export const test: {
),
warn: Object.assign(
(name: string, expectedWarning: string, testCase: () => void) => {
testRunner.test(name, testCase, TestDecorator.WARN);
testRunner.test(name, testCase, TestDecorator.WARN, expectedWarning);
},
{
each: <T>(examples: Array<T>) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { Component } from 'react';
import { findNodeHandle } from 'react-native';
import { getViewProp } from 'react-native-reanimated';
import { ComponentRef } from './types';

export type ValidPropNames = 'zIndex' | 'opacity' | 'width' | 'height' | 'top' | 'left' | 'backgroundColor';
import { ComponentRef, ValidPropNames } from './types';

export class TestComponent {
constructor(private ref: ComponentRef) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ export class TestRunner {
errors: [],
decorator,
warningMessage: warningMessage,
skip: false,
}
: {
name: applyMarkdown(name),
Expand All @@ -154,6 +155,7 @@ export class TestRunner {
callsRegistry: {},
errors: [],
decorator,
skip: decorator === TestDecorator.SKIP,
},
);
}
Expand Down Expand Up @@ -217,7 +219,7 @@ export class TestRunner {
await this.runOnUIBlocking(() => {
'worklet';
valueContainer.value = sharedValue.value;
});
}, 1000);
const uiValue = valueContainer.value;
return {
name,
Expand Down Expand Up @@ -407,26 +409,34 @@ export class TestRunner {
this._currentTestSuite.afterEach = job;
}

private waitForPropertyValueChange(targetObject: LockObject, targetProperty: 'lock', initialValue = true) {
private waitForPropertyValueChange(
targetObject: LockObject,
targetProperty: 'lock',
initialValue = true,
maxWaitTime?: number,
) {
return new Promise(resolve => {
const startTime = performance.now();
const interval = setInterval(() => {
if (targetObject[targetProperty] !== initialValue) {
const currentTime = performance.now();
const waitTimeExceeded = maxWaitTime && maxWaitTime < currentTime - startTime;
if (targetObject[targetProperty] !== initialValue || waitTimeExceeded) {
clearInterval(interval);
resolve(targetObject[targetProperty]);
}
}, 10);
});
}

public async runOnUIBlocking(worklet: () => void) {
public async runOnUIBlocking(worklet: () => void, maxWaitTime?: number) {
const unlock = () => (this._threadLock.lock = false);
this._threadLock.lock = true;
runOnUI(() => {
'worklet';
worklet();
runOnJS(unlock)();
})();
await this.waitForPropertyValueChange(this._threadLock, 'lock', true);
await this.waitForPropertyValueChange(this._threadLock, 'lock', true, maxWaitTime);
}

public async recordAnimationUpdates() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export function color(value: NullableTestValue, color: 'yellow' | 'cyan' | 'gree
orange: '\x1b[38;5;208m',
reset: '\x1b[0m',
};

return `${COLOR_CODES[color]}${value}${COLOR_CODES.reset}`;
const stringValue = typeof value === 'object' ? JSON.stringify(value) : value?.toString();
return `${COLOR_CODES[color]}${stringValue}${COLOR_CODES.reset}`;
}

export function applyMarkdown(template: string) {
Expand All @@ -51,12 +51,16 @@ export function applyMarkdown(template: string) {

export function formatString(template: string, variableObject: unknown, index: number) {
const valueToString: (arg0: unknown) => string = (value: unknown) => {
if (value instanceof Error) {
return `**${value.name}** "${value.message}"`;
}
if (typeof value === 'object') {
return JSON.stringify(value);
}
if (typeof value === 'function') {
return value.name;
}

return value?.toString() || '';
};
let testName = template;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ export type TestSuite = {
decorator?: DescribeDecorator | null;
};

export type ValidPropNames = 'zIndex' | 'opacity' | 'width' | 'height' | 'top' | 'left' | 'backgroundColor';

export enum ComparisonMode {
STRING = 'STRING',
DISTANCE = 'DISTANCE',
Expand All @@ -87,7 +89,15 @@ export interface Operation {
updates: OperationUpdate;
}

export type TestValue = TrackerCallCount | string | Array<unknown> | number | bigint | Record<string, unknown>;
export type TestValue =
| TrackerCallCount
| string
| Array<unknown>
| number
| bigint
| Record<string, unknown>
| null
| undefined;
export type NullableTestValue = TestValue | null | undefined;

export type TestConfiguration = {
Expand Down
5 changes: 5 additions & 0 deletions app/src/examples/RuntimeTests/RuntimeTestsExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ import './tests/layoutAnimations/entering/enteringColors.test';

import './tests/utilities/relativeCoords.test';

import './tests/core/useSharedValue.test';
import './tests/core/useAnimatedStyle/reuseAnimatedStyle.test';
import './tests/core/useDerivedValue/basic.test';
import './tests/core/useDerivedValue/chain.test';

export default function RuntimeTestsExample() {
return <RuntimeTestsRunner />;
}
Loading