Skip to content
Closed
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
@@ -0,0 +1,49 @@
/**
* 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 AnimatedImplementation from '../AnimatedImplementation';
import AnimatedMock from '../AnimatedMock';

describe('Animated Mock', () => {
it('matches implementation keys', () => {
expect(Object.keys(AnimatedMock)).toEqual(
Object.keys(AnimatedImplementation),
);
});
it('matches implementation params', () => {
Object.keys(AnimatedImplementation).forEach(key => {
if (AnimatedImplementation[key].length !== AnimatedMock[key].length) {
throw new Error(
'key ' +
key +
' had different lengths: ' +
JSON.stringify(
{
impl: {
len: AnimatedImplementation[key].length,
type: typeof AnimatedImplementation[key],
val: AnimatedImplementation[key].toString(),
},
mock: {
len: AnimatedMock[key].length,
type: typeof AnimatedMock[key],
val: AnimatedMock[key].toString(),
},
},
null,
2,
),
);
}
});
});
});

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,13 @@
* @format
*/

import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';

import Animated from '../Animated';
import AnimatedObject from '../nodes/AnimatedObject';
import nullthrows from 'nullthrows';

describe('AnimatedObject', () => {
let Animated;
let AnimatedObject;

beforeEach(() => {
jest.resetModules();

Animated = require('../Animated').default;
AnimatedObject = require('../nodes/AnimatedObject').default;
});

it('should get the proper value', () => {
const anim = new Animated.Value(0);
const translateAnim = anim.interpolate({
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,33 @@
* @format
*/

import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';

import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper';
import AnimatedValue from '../nodes/AnimatedValue';

describe('AnimatedValue', () => {
let NativeAnimatedHelper;
let AnimatedValue;
// Fantom uses the real native animated module and does not support
// `jest.spyOn`, so we wrap the relevant `NativeAnimatedHelper.API` methods
// with call-through mocks that count invocations and restore them afterwards.
const restoreAPI: Array<() => void> = [];

function spyOnAPI(name: string) {
// $FlowFixMe[invalid-computed-prop]
const original = NativeAnimatedHelper.API[name];
const spy = jest.fn((...args: Array<unknown>) =>
original.apply(NativeAnimatedHelper.API, args),
);
// $FlowFixMe[prop-missing]
// $FlowFixMe[cannot-write]
NativeAnimatedHelper.API[name] = spy;
restoreAPI.push(() => {
// $FlowFixMe[prop-missing]
// $FlowFixMe[cannot-write]
NativeAnimatedHelper.API[name] = original;
});
return spy;
}

function createNativeAnimatedValue(): AnimatedValue {
return new AnimatedValue(0, {useNativeDriver: true});
Expand All @@ -32,31 +56,17 @@ describe('AnimatedValue', () => {
}

beforeEach(() => {
jest.resetModules();

jest.mock('../NativeAnimatedTurboModule', () => ({
__esModule: true,
default: {
addListener: jest.fn(),
createAnimatedNode: jest.fn(),
dropAnimatedNode: jest.fn(),
removeListeners: jest.fn(),
startListeningToAnimatedNodeValue: jest.fn(),
stopListeningToAnimatedNodeValue: jest.fn(),
extractAnimatedNodeOffset: jest.fn(),
// ...
},
}));

NativeAnimatedHelper =
require('../../../src/private/animated/NativeAnimatedHelper').default;
AnimatedValue = require('../nodes/AnimatedValue').default;

jest.spyOn(NativeAnimatedHelper.API, 'createAnimatedNode');
jest.spyOn(NativeAnimatedHelper.API, 'dropAnimatedNode');
jest.spyOn(NativeAnimatedHelper.API, 'startListeningToAnimatedNodeValue');
jest.spyOn(NativeAnimatedHelper.API, 'setWaitingForIdentifier');
jest.spyOn(NativeAnimatedHelper.API, 'unsetWaitingForIdentifier');
spyOnAPI('createAnimatedNode');
spyOnAPI('dropAnimatedNode');
spyOnAPI('startListeningToAnimatedNodeValue');
spyOnAPI('setWaitingForIdentifier');
spyOnAPI('unsetWaitingForIdentifier');
});

afterEach(() => {
while (restoreAPI.length > 0) {
restoreAPI.pop()?.();
}
});

it('emits update events for listeners added', () => {
Expand Down Expand Up @@ -217,15 +227,22 @@ describe('AnimatedValue', () => {

emitMockUpdate(node, 123, 50);

const spy = jest.spyOn(node, '__onAnimatedValueUpdateReceived');
// $FlowFixMe[method-unbinding]
const original = node.__onAnimatedValueUpdateReceived;
const spy = jest.fn((...args: Array<unknown>) =>
original.apply(node, args),
);
// $FlowFixMe[cannot-write]
node.__onAnimatedValueUpdateReceived = spy;

const mockValue = 100;
const mockOffset = 50;

emitMockUpdate(node, mockValue, mockOffset);

expect(spy).toHaveBeenCalledWith(mockValue, mockOffset);
spy.mockRestore();
// $FlowFixMe[cannot-write]
node.__onAnimatedValueUpdateReceived = original;
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* @format
*/

'use strict';
import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';

import Easing from '../Easing';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
* @format
*/

import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';

import type {
InterpolationConfigSupportedOutputType,
InterpolationConfigType,
Expand All @@ -33,6 +35,13 @@ function createInterpolation<T extends InterpolationConfigSupportedOutputType>(
}

describe('Interpolation', () => {
const originalConsoleWarn = console.warn;

afterEach(() => {
// $FlowFixMe[cannot-write]
console.warn = originalConsoleWarn;
});

it('should work with defaults', () => {
const interpolation = createInterpolation({
inputRange: [0, 1],
Expand Down Expand Up @@ -365,7 +374,10 @@ describe('Interpolation', () => {
});

it('should work with PlatformColor', () => {
jest.spyOn(console, 'warn').mockImplementationOnce(() => {});
const mockWarn = jest.fn();
// $FlowFixMe[cannot-write]
console.warn = mockWarn;

const interpolation = createInterpolation({
inputRange: [0, 1],
outputRange: [
Expand All @@ -381,28 +393,28 @@ describe('Interpolation', () => {
expect(interpolation(2 / 3)).toStrictEqual(
PlatformColor('@android:color/white'),
);
expect(console.warn).toBeCalledWith(
expect(mockWarn).toBeCalledWith(
'PlatformColor interpolation should happen natively, here we fallback to the closest color',
);
expect(interpolation(1)).toStrictEqual(
PlatformColor('@android:color/darker_gray'),
);
});

it.each([
for (const [label, outputRange, expected] of [
['radians', ['1rad', '2rad'], [1, 2]],
['degrees', ['90deg', '180deg'], [Math.PI / 2, Math.PI]],
['numbers', [1024, Math.PI], [1024, Math.PI]],
['unknown', ['5foo', '10foo'], ['5foo', '10foo']],
])(
'should convert %s to numbers in the native config',
(_, outputRange, expected) => {
]) {
it(`should convert ${label} to numbers in the native config`, () => {
const config = new AnimatedInterpolation(
// $FlowFixMe[incompatible-type]
{},
// $FlowFixMe[incompatible-call]
{inputRange: [0, 1], outputRange},
).__getNativeConfig();
expect(config.outputRange).toEqual(expected);
},
);
});
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* @format
*/

'use strict';
import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';

import TimingAnimation from '../animations/TimingAnimation';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* @copyright 2014-2015 Gaetan Renaudeau. MIT License.
*/

'use strict';
import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';

import bezier from '../bezier';

Expand Down
Loading
Loading