Add 'testWithArg' to Fantom benchmarking API (#52831)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/52831

# Changelog
[Internal] -

The corresponding `testWithArg` API is similar to the existing `test` one for the Fantom benchmarks, except it would allow to run the same test several times in a parametrized manner, with the set of parameters specified as an array (for now, of numbers).

This allows to easily implement testing patterns such as we have in a View benchmark test, whereas we have a mostly duplicated test body doing a similar thing with 100, 1000, 1500 view component instances etc.

Reviewed By: rubennorte

Differential Revision: D78970312

fbshipit-source-id: 504b7aada648c7213ce698f088ac71d9fde8884b
This commit is contained in:
Ruslan Shestopalyuk
2025-07-25 08:53:45 -07:00
committed by Facebook GitHub Bot
parent 3271e57c75
commit c5bb31c46e
+69 -5
View File
@@ -35,9 +35,32 @@ type TestOptions = $ReadOnly<{
type SuiteResults = Array<$ReadOnly<TaskResult>>;
type TestWithArgName<TestArgType> = string | ((testArg: TestArgType) => string);
type TestWithArgOptions<TestArgType> =
| FnOptions
| ((testArg: TestArgType) => FnOptions);
interface ParameterizedTestFunction {
<TestArgType>(
testArgs: $ReadOnlyArray<TestArgType>,
name: TestWithArgName<TestArgType>,
fn: (testArg: TestArgType) => void,
options?: TestWithArgOptions<TestArgType>,
): SuiteAPI;
only: <TestArgType>(
testArgs: $ReadOnlyArray<TestArgType>,
name: TestWithArgName<TestArgType>,
fn: (testArg: TestArgType) => void,
options?: TestWithArgOptions<TestArgType>,
) => SuiteAPI;
}
interface TestFunction {
(name: string, fn: () => void, options?: FnOptions): SuiteAPI;
only: (name: string, fn: () => void, options?: FnOptions) => SuiteAPI;
// `each` allows to run the same test multiple times with different arguments, provided as an array of values:
each: ParameterizedTestFunction;
}
interface SuiteAPI {
@@ -45,15 +68,17 @@ interface SuiteAPI {
verify(fn: (results: SuiteResults) => void): SuiteAPI;
}
interface TestTask {
name: string;
fn: () => void;
options: TestOptions | void;
}
export function suite(
suiteName: string,
suiteOptions?: SuiteOptions = {},
): SuiteAPI {
const tasks: Array<{
name: string,
fn: () => void,
options: TestOptions | void,
}> = [];
const tasks: Array<TestTask> = [];
const verifyFns = [];
global.it(suiteName, () => {
@@ -165,6 +190,45 @@ export function suite(
return suiteAPI;
};
const testWithArg = <TestArgType>(
testArg: TestArgType,
name: TestWithArgName<TestArgType>,
fn: (testArg: TestArgType) => void,
options?: TestWithArgOptions<TestArgType>,
only?: boolean = false,
): TestTask => {
const taskName =
typeof name === 'function'
? name(testArg)
: `${name} [arg=${String(testArg)}]`;
const taskOptions =
typeof options === 'function' ? options(testArg) : options;
const taskFn = () => fn(testArg);
return {name: taskName, fn: taskFn, options: {...taskOptions, only}};
};
// $FlowIssue[incompatible-type]
const testEach: ParameterizedTestFunction = <TestArgType>(
testArgs: $ReadOnlyArray<TestArgType>,
name: TestWithArgName<TestArgType>,
fn: (testArg: TestArgType) => void,
options?: TestWithArgOptions<TestArgType>,
): SuiteAPI => {
for (const testArg of testArgs) {
tasks.push(testWithArg(testArg, name, fn, options));
}
return suiteAPI;
};
testEach.only = (testArgs, name, fn, options) => {
for (const testArg of testArgs) {
tasks.push(testWithArg(testArg, name, fn, options, true));
}
return suiteAPI;
};
test.each = testEach;
const suiteAPI = {
test,
verify(fn: (results: SuiteResults) => void): SuiteAPI {