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
Prev Previous commit
Next Next commit
Add tests for useAnimatedStyle
  • Loading branch information
Latropos committed May 7, 2024
commit 1db6e7444b6943d54612393e4ed7e334e57bb49a
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 @@ -97,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
@@ -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 @@ -47,6 +47,8 @@ export type TestSuite = {
only?: boolean;
};

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

export enum ComparisonMode {
STRING = 'STRING',
DISTANCE = 'DISTANCE',
Expand Down
1 change: 1 addition & 0 deletions app/src/examples/RuntimeTests/RuntimeTestsExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import './tests/layoutAnimations/entering/enteringColors.test';
import './tests/utilities/relativeCoords.test';

import './tests/core/useSharedValue.test';
import './tests/core/useAnimatedStyle/reuseAnimatedStyle.test';

export default function RuntimeTestsExample() {
return <RuntimeTestsRunner />;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { useEffect } from 'react';
import { View, StyleSheet } from 'react-native';
import Animated, { useSharedValue, useAnimatedStyle, withTiming, AnimatableValueObject } from 'react-native-reanimated';
import React from 'react';
import { ComparisonMode } from '../../../ReanimatedRuntimeTestsRunner/types';
import {
describe,
test,
expect,
render,
useTestRef,
getTestComponent,
wait,
} from '../../../ReanimatedRuntimeTestsRunner/RuntimeTestsApi';
import { getComparisonModeForProp } from '../../../ReanimatedRuntimeTestsRunner/Comparators';

describe.only('Test reusing animatedStyles', () => {
const COMPONENT_REF = {
ONE: 'ONE',
TWO: 'TWO',
THREE: 'THREE',
};

const TripleComponent = ({
startStyle,
finalStyle,
animate = false,
}: {
startStyle: AnimatableValueObject;
finalStyle: AnimatableValueObject;
animate: boolean;
}) => {
const toggle = useSharedValue(true);

const svStyle = useSharedValue(startStyle);

const refOne = useTestRef(COMPONENT_REF.ONE);
const refTwo = useTestRef(COMPONENT_REF.TWO);
const refThree = useTestRef(COMPONENT_REF.THREE);

const animatedStyle = useAnimatedStyle(() => {
if (!animate) {
return toggle.value ? startStyle : finalStyle;
} else {
return svStyle.value;
}
});

useEffect(() => {
if (!animate) {
toggle.value = false;
} else {
svStyle.value = withTiming(finalStyle, { duration: 900 });
Latropos marked this conversation as resolved.
Show resolved Hide resolved
}
});

return (
<View style={styles.container}>
<Animated.View ref={refOne} style={[styles.animatedBox, { backgroundColor: 'palevioletred' }, animatedStyle]} />
<Animated.View ref={refTwo} style={[styles.animatedBox, { backgroundColor: 'teal' }, animatedStyle]} />
<Animated.View ref={refThree} style={[styles.animatedBox, { backgroundColor: 'darkorange' }, animatedStyle]} />
</View>
);
};

const TEST_CASES: Array<{ startStyle: AnimatableValueObject; finalStyle: AnimatableValueObject; animate: boolean }> =
[
{ startStyle: { width: 100 }, finalStyle: { width: 300 }, animate: true },
{ startStyle: { left: 10 }, finalStyle: { left: 30 }, animate: true },
{ startStyle: { top: 10 }, finalStyle: { top: 30 }, animate: true },
{ startStyle: { opacity: 0 }, finalStyle: { opacity: 1 }, animate: true },
{ startStyle: { height: 20 }, finalStyle: { height: 100 }, animate: true },
{ startStyle: { margin: 0 }, finalStyle: { margin: 100 }, animate: true },
{ startStyle: { margin: -100 }, finalStyle: { margin: 0 }, animate: true },
{ startStyle: { opacity: 0 }, finalStyle: { opacity: 1 }, animate: false },
{ startStyle: { height: 20 }, finalStyle: { height: 100 }, animate: false },
{ startStyle: { margin: 0 }, finalStyle: { margin: 100 }, animate: false },
{ startStyle: { margin: -100 }, finalStyle: { margin: 0 }, animate: false },
{ startStyle: { margin: -50, height: 20 }, finalStyle: { margin: 40, height: 200 }, animate: true },
{ startStyle: { margin: 50, height: 20 }, finalStyle: { margin: -40, height: 200 }, animate: true },
{ startStyle: { margin: -50, top: 20 }, finalStyle: { margin: 40, top: 200 }, animate: true },
{
startStyle: { margin: -50, top: 20, height: 20 },
finalStyle: { margin: 40, top: 200, height: 200 },
animate: true,
},
{ startStyle: { height: 20, width: 100 }, finalStyle: { height: 100, width: 300 }, animate: true },
{
startStyle: { height: 20, width: 100, backgroundColor: 'white' },
finalStyle: { height: 100, width: 300, backgroundColor: 'royalblue' },
animate: true,
},
{
startStyle: { height: 20, width: 100, margin: 0, backgroundColor: 'white' },
finalStyle: { height: 100, width: 300, margin: 20, backgroundColor: 'royalblue' },
animate: true,
},
];

test.each(TEST_CASES)(
'Animate 3 components from ${startStyle} to ${finalStyle}, animate=${animate}',
async ({ startStyle, finalStyle, animate }) => {
await render(<TripleComponent startStyle={startStyle} finalStyle={finalStyle} animate={animate} />);
const componentOne = getTestComponent(COMPONENT_REF.ONE);
const componentTwo = getTestComponent(COMPONENT_REF.TWO);
const componentThree = getTestComponent(COMPONENT_REF.THREE);

await wait(1000);

// Check the distance from the top
const componentHeight = 'height' in finalStyle ? (finalStyle.height as number) : 80;
const componentMargin = 'margin' in finalStyle ? (finalStyle.margin as number) : 0;
const componentTop = 'top' in finalStyle ? (finalStyle.top as number) : 0;
Latropos marked this conversation as resolved.
Show resolved Hide resolved

expect(await componentOne.getAnimatedStyle('top')).toBe(componentTop + componentMargin, ComparisonMode.DISTANCE);
expect(await componentTwo.getAnimatedStyle('top')).toBe(
componentTop + 3 * componentMargin + componentHeight,
ComparisonMode.DISTANCE,
);
expect(await componentThree.getAnimatedStyle('top')).toBe(
componentTop + 5 * componentMargin + 2 * componentHeight,
ComparisonMode.DISTANCE,
);

// Check the remaining props
for (let key of ['width', 'height', 'left', 'opacity', 'backgroundColor'] as const) {
if (key in Object.keys(finalStyle)) {
const currentVal = await componentOne.getAnimatedStyle(key);
expect(currentVal).toBe(finalStyle[key], getComparisonModeForProp(key));
}
}
},
);
});

const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
},
animatedBox: {
height: 80,
},
});
Loading