* Copyright (c) 2025 Huawei Technologies Co., Ltd.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {expect as expect_} from 'chai';
import {useContext, useEffect, useLayoutEffect} from 'react';
import {
TestCaseContext,
TestSuiteContext,
TestingContext,
} from './TestingContext';
import {ExampleTestCase, ExampleTestCaseProps} from './ExampleTestCase';
import {LogicalTestCase} from './LogicalTestCase';
import {ManualTestCase, SmartManualTestCaseProps} from './ManualTestCase';
import {
AutomatedTestCase,
SmartAutomatedTestCaseProps,
} from './AutomatedTestCase';
import {TestCaseType} from './TestingContext';
export function getTestCaseTypeFromProps(
props: Record<string, any>,
): TestCaseType | null {
if ('fn' in props) {
return 'logical';
}
if ('act' in props) {
return 'automated';
}
if ('arrange' in props) {
return 'manual';
}
if ('itShould' in props) {
return 'example';
}
return null;
}
export function TestCase<TState = undefined>(
props: {itShould: string; skip?: boolean | string; tags?: string[]} & (
| ExampleTestCaseProps
| {fn: (utils: {expect: typeof expect_}) => Promise<void> | void}
| SmartManualTestCaseProps<TState>
| SmartAutomatedTestCaseProps<TState>
),
) {
const {itShould, tags, ...otherProps} = props;
const {registerTestCase, reportTestCaseResult, filter, isSequential} =
useContext(TestingContext)!;
const shouldRenderExample = 'children' in otherProps;
const shouldRenderManualTestCase = 'arrange' in otherProps;
const shouldRenderAutomatedTestCase = 'act' in otherProps;
const {testSuiteId, onTestCaseIgnored} = useContext(TestSuiteContext)!;
const testCaseId = `${testSuiteId ?? ''}::${itShould}`;
const testCaseType = getTestCaseTypeFromProps(props);
const shouldBeIgnored =
testCaseType === null
? true
: !filter({
tags: tags ?? [],
testCaseType: testCaseType,
});
useLayoutEffect(() => {
if (isSequential) {
return;
}
if (shouldBeIgnored) {
onTestCaseIgnored(testCaseId);
return;
}
return registerTestCase(testCaseId);
}, []);
useEffect(() => {
if (!isSequential) {
return;
}
if (shouldBeIgnored) {
onTestCaseIgnored(testCaseId);
return;
}
return registerTestCase(testCaseId);
}, []);
if (shouldBeIgnored) {
return null;
}
return (
<TestCaseContext.Provider
value={{
reportTestCaseResult: result => {
reportTestCaseResult(testCaseId, result);
},
}}>
{shouldRenderExample ? (
<ExampleTestCase itShould={itShould} {...otherProps}>
{otherProps.children}
</ExampleTestCase>
) : shouldRenderAutomatedTestCase ? (
<AutomatedTestCase itShould={itShould} {...otherProps} />
) : shouldRenderManualTestCase ? (
<ManualTestCase itShould={itShould} {...otherProps} />
) : (
<LogicalTestCase name={itShould} {...otherProps} />
)}
</TestCaseContext.Provider>
);
}