Skip to content

Commit

Permalink
Add expectNullable and expectNotNullable to runtime tests (#5935)
Browse files Browse the repository at this point in the history
## Summary

As in description, added nullcheck methods `expectNullable` and
`expectNotNullable` to runtime tests API.

## Test plan

Use either of the methods in any of existing runtime tests and run their
example.
  • Loading branch information
szydlovsky committed Apr 24, 2024
1 parent 9ab071e commit f5dfead
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 5 deletions.
@@ -1,6 +1,6 @@
import { getComparator } from './Comparators';
import { appendWhiteSpaceToMatchLength, color } from './stringFormatUtils';
import { ComparisonMode, OperationUpdate, TestCase, TestValue, TrackerCallCount } from './types';
import { ComparisonMode, OperationUpdate, TestCase, TestValue, NullableTestValue, TrackerCallCount } from './types';

type MatcherFunction = (
currentValue: TestValue,
Expand Down Expand Up @@ -210,3 +210,15 @@ export class Matchers {
return `Expected ${expected} snapshots, but received ${received} snapshots\n`;
}
}

export function nullableMatch(currentValue: NullableTestValue, testCase: TestCase, negation: boolean = false) {
const pass = currentValue === null || currentValue === undefined;

const coloredExpected = color('nullable', 'green');
const coloredReceived = color(currentValue, 'red');
const message = `Expected${negation ? ' NOT' : ''} ${coloredExpected} received ${coloredReceived}`;

if ((!pass && !negation) || (pass && negation)) {
testCase.errors.push(message);
}
}
Expand Up @@ -2,7 +2,7 @@ import { Component, ReactElement } from 'react';
import { TestRunner } from './TestRunner';
import { TestComponent } from './TestComponent';
import type { SharedValue } from 'react-native-reanimated';
import { TestConfiguration, TestValue } from './types';
import { TestConfiguration, TestValue, NullableTestValue } from './types';

export { Presets } from './Presets';

Expand Down Expand Up @@ -100,6 +100,14 @@ export function expect(value: TestValue) {
return testRunner.expect(value);
}

export function expectNullable(currentValue: NullableTestValue) {
return testRunner.expectNullable(currentValue);
}

export function expectNotNullable(currentValue: NullableTestValue) {
return testRunner.expectNotNullable(currentValue);
}

export function configure(config: TestConfiguration) {
return testRunner.configure(config);
}
Expand Down
@@ -1,5 +1,6 @@
import { Component, MutableRefObject, ReactElement, useRef } from 'react';
import type {
NullableTestValue,
LockObject,
Operation,
SharedValueSnapshot,
Expand All @@ -15,7 +16,7 @@ import { render, stopRecordingAnimationUpdates, unmockAnimationTimer } from './R
import { makeMutable, runOnUI, runOnJS, SharedValue } from 'react-native-reanimated';
import { color, formatString, indentNestingLevel } from './stringFormatUtils';
import { createUpdatesContainer } from './UpdatesContainer';
import { Matchers } from './Matchers';
import { Matchers, nullableMatch } from './Matchers';
import { assertMockedAnimationTimestamp, assertTestCase, assertTestSuite } from './Asserts';

let callTrackerRegistryJS: Record<string, number> = {};
Expand Down Expand Up @@ -258,6 +259,16 @@ export class TestRunner {
return new Matchers(currentValue, this._currentTestCase);
}

public expectNullable(currentValue: NullableTestValue) {
assertTestCase(this._currentTestCase);
nullableMatch(currentValue, this._currentTestCase);
}

public expectNotNullable(currentValue: NullableTestValue) {
assertTestCase(this._currentTestCase);
nullableMatch(currentValue, this._currentTestCase, true);
}

public beforeAll(job: () => void) {
assertTestSuite(this._currentTestSuite);
this._currentTestSuite.beforeAll = job;
Expand Down
@@ -1,4 +1,4 @@
import { TestValue } from './types';
import { NullableTestValue } from './types';

export const RUNTIME_TEST_ERRORS = {
UNDEFINED_TEST_SUITE: 'Undefined test suite context',
Expand All @@ -16,7 +16,7 @@ export function appendWhiteSpaceToMatchLength(message: string | number, length:
return `${messageStr}${' '.repeat(length - messageLen)}`;
}

export function color(value: TestValue, color: 'yellow' | 'cyan' | 'green' | 'red' | 'gray') {
export function color(value: NullableTestValue, color: 'yellow' | 'cyan' | 'green' | 'red' | 'gray') {
const COLOR_CODES = {
red: '\x1b[31m',
green: '\x1b[32m',
Expand Down
Expand Up @@ -65,6 +65,7 @@ export interface Operation {
}

export type TestValue = TrackerCallCount | string | Array<unknown> | number | bigint | Record<string, unknown>;
export type NullableTestValue = TestValue | null | undefined;

export type TestConfiguration = {
render: Dispatch<SetStateAction<ReactNode | null>>;
Expand Down

0 comments on commit f5dfead

Please sign in to comment.