Skip to content

Commit

Permalink
Merge branch 'main' into @tomekzaw/react-native-0.76
Browse files Browse the repository at this point in the history
  • Loading branch information
tomekzaw committed Sep 17, 2024
2 parents 4b53a1e + abdf821 commit 869696c
Show file tree
Hide file tree
Showing 42 changed files with 1,174 additions and 271 deletions.
64 changes: 64 additions & 0 deletions apps/common-app/src/examples/LayoutAnimations/ViewFlattening.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { StyleSheet, View, Button } from 'react-native';
import Animated, { FadeOut } from 'react-native-reanimated';

import React from 'react';

export default function ViewFlatteningExample() {
const [visible, setVisible] = React.useState(true);

return (
<View style={styles.container}>
<Button title="Toggle" onPress={() => setVisible(!visible)} />
<View style={styles.purpleBox} collapsable={!visible}>
<View style={styles.redBox} collapsable={visible}>
<View style={styles.greenBox} collapsable={false}>
{visible && (
<Animated.View
style={styles.blueBox}
exiting={FadeOut.duration(2000)}
/>
)}
</View>
</View>
<View style={styles.redBox} collapsable={!visible}>
<View style={styles.greenBox} collapsable={false}>
{visible && (
<Animated.View
style={styles.blueBox}
exiting={FadeOut.duration(2000)}
/>
)}
</View>
</View>
</View>
</View>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
purpleBox: {
width: 200,
height: 200,
backgroundColor: 'purple',
},
redBox: {
width: 100,
height: 100,
backgroundColor: 'red',
},
greenBox: {
width: 50,
height: 50,
backgroundColor: 'green',
},
blueBox: {
width: 25,
height: 25,
backgroundColor: 'blue',
},
});
47 changes: 24 additions & 23 deletions apps/common-app/src/examples/RuntimeTests/ReJest/RuntimeTestsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Component, ReactElement } from 'react';
import { TestRunner } from './TestRunner/TestRunner';
import type { TestComponent } from './TestComponent';
import type { SharedValue } from 'react-native-reanimated';
import type { TestConfiguration, TestValue, BuildFunction } from './types';
import type { TestConfiguration, TestValue, MaybeAsync } from './types';
import { DescribeDecorator, TestDecorator } from './types';

export { Presets } from './Presets';
Expand All @@ -11,45 +11,46 @@ const testRunner = new TestRunner();
const windowDimensionsMocker = testRunner.getWindowDimensionsMocker();
const animationRecorder = testRunner.getAnimationUpdatesRecorder();
const valueRegistry = testRunner.getValueRegistry();
const testSuiteBuilder = testRunner.getTestSuiteBuilder();
const callTrackerRegistry = testRunner.getCallTrackerRegistry();
const notificationRegistry = testRunner.getNotificationRegistry();

type DescribeFunction = (name: string, buildSuite: BuildFunction) => void;
type TestFunction = (name: string, buildTest: BuildFunction) => void;
type DescribeFunction = (name: string, buildSuite: MaybeAsync<void>) => void;
type TestFunction = (name: string, buildTest: MaybeAsync<void>) => void;
type TestEachFunction = <T>(
examples: Array<T>,
) => (name: string, testCase: (example: T, index: number) => void | Promise<void>) => void;
type DecoratedTestFunction = TestFunction & { each: TestEachFunction };

const describeBasic = (name: string, buildSuite: BuildFunction) => {
testRunner.describe(name, buildSuite, null);
const describeBasic = (name: string, buildSuite: MaybeAsync<void>) => {
testSuiteBuilder.describe(name, buildSuite, null);
};

export const describe = <DescribeFunction & Record<DescribeDecorator, DescribeFunction>>describeBasic;
describe.skip = (name, buildSuite) => {
testRunner.describe(name, buildSuite, DescribeDecorator.SKIP);
testSuiteBuilder.describe(name, buildSuite, DescribeDecorator.SKIP);
};
describe.only = (name, buildSuite) => {
testRunner.describe(name, buildSuite, DescribeDecorator.ONLY);
testSuiteBuilder.describe(name, buildSuite, DescribeDecorator.ONLY);
};

const testBasic: DecoratedTestFunction = (name: string, testCase: BuildFunction) => {
testRunner.test(name, testCase, null);
const testBasic: DecoratedTestFunction = (name: string, testCase: MaybeAsync<void>) => {
testSuiteBuilder.test(name, testCase, null);
};
testBasic.each = <T>(examples: Array<T>) => {
return testRunner.testEach(examples, null);
return testSuiteBuilder.testEach(examples, null);
};
const testSkip: DecoratedTestFunction = (name: string, testCase: BuildFunction) => {
testRunner.test(name, testCase, TestDecorator.SKIP);
const testSkip: DecoratedTestFunction = (name: string, testCase: MaybeAsync<void>) => {
testSuiteBuilder.test(name, testCase, TestDecorator.SKIP);
};
testSkip.each = <T>(examples: Array<T>) => {
return testRunner.testEach(examples, TestDecorator.SKIP);
return testSuiteBuilder.testEach(examples, TestDecorator.SKIP);
};
const testOnly: DecoratedTestFunction = (name: string, testCase: BuildFunction) => {
testRunner.test(name, testCase, TestDecorator.ONLY);
const testOnly: DecoratedTestFunction = (name: string, testCase: MaybeAsync<void>) => {
testSuiteBuilder.test(name, testCase, TestDecorator.ONLY);
};
testOnly.each = <T>(examples: Array<T>) => {
return testRunner.testEach(examples, TestDecorator.ONLY);
return testSuiteBuilder.testEach(examples, TestDecorator.ONLY);
};

type TestType = DecoratedTestFunction & Record<TestDecorator.SKIP | TestDecorator.ONLY, DecoratedTestFunction>;
Expand All @@ -58,20 +59,20 @@ export const test = <TestType>testBasic;
test.skip = testSkip;
test.only = testOnly;

export function beforeAll(job: () => void) {
export function beforeAll(job: MaybeAsync<void>) {
testRunner.beforeAll(job);
}

export function beforeEach(job: () => void) {
testRunner.beforeEach(job);
export function afterAll(job: MaybeAsync<void>) {
testRunner.afterAll(job);
}

export function afterEach(job: () => void) {
testRunner.afterEach(job);
export function beforeEach(job: MaybeAsync<void>) {
testRunner.beforeEach(job);
}

export function afterAll(job: () => void) {
testRunner.afterAll(job);
export function afterEach(job: MaybeAsync<void>) {
testRunner.afterEach(job);
}

export async function render(component: ReactElement<Component> | null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import type { Component, MutableRefObject, ReactElement } from 'react';
import { useRef } from 'react';
import type { BuildFunction, TestCase, TestConfiguration, TestSuite, TestValue } from '../types';
import { DescribeDecorator, TestDecorator } from '../types';
import type { MaybeAsync, TestCase, TestConfiguration, TestSuite, TestValue } from '../types';
import { TestComponent } from '../TestComponent';
import { applyMarkdown, formatTestName } from '../utils/stringFormatUtils';
import { Matchers } from '../matchers/Matchers';
import { assertTestCase, assertTestSuite } from './Asserts';
import { RenderLock } from '../utils/SyncUIRunner';
Expand All @@ -13,21 +11,21 @@ import { WindowDimensionsMocker } from './WindowDimensionsMocker';
import { AnimationUpdatesRecorder } from './AnimationUpdatesRecorder';
import { CallTrackerRegistry } from './CallTrackerRegistry';
import { NotificationRegistry } from './NotificationRegistry';
import { TestSuiteBuilder } from './TestSuiteBuilder';
export { Presets } from '../Presets';

export class TestRunner {
private _testSuites: TestSuite[] = [];
private _currentTestSuite: TestSuite | null = null;
private _currentTestCase: TestCase | null = null;
private _renderHook: (component: ReactElement<Component> | null) => void = () => {};
private _includesOnly: boolean = false;
private _renderLock: RenderLock = new RenderLock();
private _testSummary: TestSummaryLogger = new TestSummaryLogger();
private _windowDimensionsMocker: WindowDimensionsMocker = new WindowDimensionsMocker();
private _animationRecorder = new AnimationUpdatesRecorder();
private _valueRegistry = new ValueRegistry();
private _callTrackerRegistry = new CallTrackerRegistry();
private _notificationRegistry = new NotificationRegistry();
private _testSuiteBuilder = new TestSuiteBuilder();

public getWindowDimensionsMocker() {
return this._windowDimensionsMocker;
Expand All @@ -49,6 +47,10 @@ export class TestRunner {
return this._notificationRegistry;
}

public getTestSuiteBuilder() {
return this._testSuiteBuilder;
}

public configure(config: TestConfiguration) {
this._renderHook = config.render;
return this._renderLock;
Expand All @@ -74,65 +76,6 @@ export class TestRunner {
return await this.render(null);
}

public describe(name: string, buildSuite: BuildFunction, decorator: DescribeDecorator | null) {
if (decorator === DescribeDecorator.ONLY) {
this._includesOnly = true;
}

let index: number; // We have to manage the order of the nested describes
if (this._currentTestSuite === null) {
index = this._testSuites.length; // If we have no parent describe, we append at the end
} else {
const parentIndex = this._testSuites.findIndex(testSuite => {
return testSuite === this._currentTestSuite;
});
const parentNesting = this._currentTestSuite.nestingLevel;
index = parentIndex + 1;
while (index < this._testSuites.length && this._testSuites[index].nestingLevel > parentNesting) {
// Append after last child of the parent describe
// The children have bigger nesting level
index += 1;
}
}

const testDecorator = decorator || this._currentTestSuite?.decorator;

this._testSuites.splice(index, 0, {
name: applyMarkdown(name),
buildSuite,
testCases: [],
nestingLevel: (this._currentTestSuite?.nestingLevel || 0) + 1,
decorator: testDecorator || null,
});
}

public test(name: string, run: BuildFunction, decorator: TestDecorator | null) {
assertTestSuite(this._currentTestSuite);
if (decorator === TestDecorator.ONLY) {
this._includesOnly = true;
}
this._currentTestSuite.testCases.push({
name: applyMarkdown(name),
run,
componentsRefs: {},
callsRegistry: {},
errors: [],
skip: decorator === TestDecorator.SKIP || this._currentTestSuite.decorator === DescribeDecorator.SKIP,
decorator,
});
}

public testEach<T>(examples: Array<T>, decorator: TestDecorator | null) {
return (name: string, testCase: (example: T, index: number) => void | Promise<void>) => {
examples.forEach((example, index) => {
const currentTestCase = async () => {
await testCase(example, index);
};
this.test(formatTestName(name, example, index), currentTestCase, decorator);
});
};
}

public useTestRef(name: string): MutableRefObject<Component | null> {
// eslint-disable-next-line react-hooks/rules-of-hooks
const ref = useRef(null);
Expand All @@ -149,35 +92,10 @@ export class TestRunner {

public async runTests() {
console.log('\n');

for (const testSuite of this._testSuites) {
this._currentTestSuite = testSuite;
await testSuite.buildSuite();
this._currentTestSuite = null;
}

for (const testSuite of this._testSuites) {
let skipTestSuite = testSuite.skip;

if (this._includesOnly) {
skipTestSuite = skipTestSuite || !(testSuite.decorator === DescribeDecorator.ONLY);

for (const testCase of testSuite.testCases) {
if (testCase.decorator === TestDecorator.ONLY) {
skipTestSuite = false;
} else {
testCase.skip = testCase.skip || !(testSuite.decorator === DescribeDecorator.ONLY);
}
}
}
testSuite.skip = skipTestSuite;
}

for (const testSuite of this._testSuites) {
await this._testSuiteBuilder.buildTests();
for (const testSuite of this._testSuiteBuilder.getTestSuites()) {
await this.runTestSuite(testSuite);
}

this._testSuites = [];
this._testSummary.printSummary();
}

Expand Down Expand Up @@ -233,22 +151,22 @@ export class TestRunner {
return new Matchers(currentValue, this._currentTestCase);
}

public beforeAll(job: () => void) {
public beforeAll(job: MaybeAsync<void>) {
assertTestSuite(this._currentTestSuite);
this._currentTestSuite.beforeAll = job;
}

public afterAll(job: () => void) {
public afterAll(job: MaybeAsync<void>) {
assertTestSuite(this._currentTestSuite);
this._currentTestSuite.afterAll = job;
}

public beforeEach(job: () => void) {
public beforeEach(job: MaybeAsync<void>) {
assertTestSuite(this._currentTestSuite);
this._currentTestSuite.beforeEach = job;
}

public afterEach(job: () => void) {
public afterEach(job: MaybeAsync<void>) {
assertTestSuite(this._currentTestSuite);
this._currentTestSuite.afterEach = job;
}
Expand Down
Loading

0 comments on commit 869696c

Please sign in to comment.