Skip to content

Commit

Permalink
fix: Add tests and fix some
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Aug 7, 2024
1 parent f383d69 commit 872e77c
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 41 deletions.
1 change: 0 additions & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
},
"dependencies": {
"deep-equal": "^2.2.3",
"fast-safe-stringify": "^2.1.1",
"react": "^18.3.1",
"react-native": "^0.74.5",
"react-native-safe-area-context": "^4.10.8"
Expand Down
13 changes: 7 additions & 6 deletions example/src/Testers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import deepEqual from 'deep-equal'
import { stringify } from './utils'

export type Must = 'equals' | 'throws'

Expand All @@ -23,7 +24,7 @@ export class State<T> {
didThrow(): State<T> {
if (this.errorThrown == null) {
this.onFailed(
`Expected test to throw an error, but no error was thrown! Instead it returned a result: ${this.result}`
`Expected test to throw an error, but no error was thrown! Instead it returned a result: ${stringify(this.result)}`
)
} else {
this.onPassed()
Expand All @@ -34,7 +35,7 @@ export class State<T> {
didNotThrow(): State<T> {
if (this.errorThrown != null) {
this.onFailed(
`Expected test to not throw any errors, but an error was thrown! Error: ${this.errorThrown}`
`Expected test to not throw any errors, but an error was thrown! Error: ${stringify(this.errorThrown)}`
)
} else {
this.onPassed()
Expand All @@ -45,7 +46,7 @@ export class State<T> {
equals(other: T): State<T> {
if (!deepEqual(this.result, other)) {
this.onFailed(
`Expected "${this.result}" (${typeof this.result}) to equal "${other}" (${typeof other}), but they are not equal!`
`Expected "${stringify(this.result)}" (${typeof this.result}) to equal "${stringify(other)}" (${typeof other}), but they are not equal!`
)
} else {
this.onPassed()
Expand All @@ -56,7 +57,7 @@ export class State<T> {
didReturn(type: JSType): State<T> {
if (typeof this.result !== type) {
this.onFailed(
`Expected ${this.result}'s type (${typeof this.result}) to be ${type}!`
`Expected ${stringify(this.result)}'s type (${typeof this.result}) to be ${type}!`
)
} else {
this.onPassed()
Expand All @@ -67,7 +68,7 @@ export class State<T> {
toContain(key: keyof T): State<T> {
if (!Object.keys(this.result as any).includes(key as any)) {
this.onFailed(
`Expected "${this.result}" to contain ${String(key)}, but it didn't! Keys: ${Object.keys(this.result as any)}`
`Expected "${stringify(this.result)}" to contain ${String(key)}, but it didn't! Keys: ${Object.keys(this.result as any)}`
)
} else {
this.onPassed()
Expand All @@ -78,7 +79,7 @@ export class State<T> {
toBeArray(): State<T> {
if (!Array.isArray(this.result)) {
this.onFailed(
`Expected "${this.result}" (${typeof this.result}) to be an array, but it isn't!`
`Expected "${stringify(this.result)}" (${typeof this.result}) to be an array, but it isn't!`
)
} else {
this.onPassed()
Expand Down
137 changes: 109 additions & 28 deletions example/src/getTests.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { HybridTestObject } from 'react-native-nitro-image'
import {
HybridTestObject,
OldEnum,
type Car,
type Person,
} from 'react-native-nitro-image'
import type { State } from './Testers'
import { it } from './Testers'
import { stringify } from './utils'

type TestResult =
| {
Expand All @@ -17,33 +23,17 @@ export interface TestRunner {
run: () => Promise<TestResult>
}

function stringify(value: unknown): string {
if (value == null) {
return 'null'
}

switch (typeof value) {
case 'string':
return value
case 'bigint':
case 'boolean':
case 'number':
case 'symbol':
return String(value)
case 'function':
return value.toString()
case 'object':
if (value instanceof Error) {
return `${value.name}: ${value.message}`
}
if ('toString' in value) {
const string = value.toString()
if (string !== '[object Object]') return string
}
return `{ ${value} ${Object.keys(value).join(', ')} }`
default:
return `${value}`
}
const TEST_PERSON: Person = {
age: 24,
name: 'Marc',
}
const TEST_CAR: Car = {
year: 2018,
make: 'Lamborghini',
model: 'Huracan Performante',
power: 640,
powertrain: 'gas',
driver: undefined, // <-- value needs to be explicitly set, to equal it with native's std::optional<..>
}

function createTest<T>(
Expand Down Expand Up @@ -278,6 +268,97 @@ export function getTests(): TestRunner[] {
).didThrow()
),

// Complex variants tests
createTest('getVariantEnum(...) converts enum', () =>
it(() => HybridTestObject.getVariantEnum(OldEnum.THIRD))
.didNotThrow()
.equals(OldEnum.THIRD)
),
createTest('getVariantEnum(...) converts boolean', () =>
it(() => HybridTestObject.getVariantEnum(true))
.didNotThrow()
.equals(true)
),
createTest('getVariantEnum(...) throws at wrong type (string)', () =>
// @ts-expect-error
it(() => HybridTestObject.getVariantEnum('string')).didThrow()
),
createTest('getVariantObjects(...) converts Person', () =>
it(() => HybridTestObject.getVariantObjects(TEST_PERSON))
.didNotThrow()
.equals(TEST_PERSON)
),
createTest('getVariantObjects(...) converts Car', () =>
it(() => HybridTestObject.getVariantObjects(TEST_CAR))
.didNotThrow()
.equals(TEST_CAR)
),
createTest('getVariantObjects(...) converts Car (+ person)', () =>
it(() =>
HybridTestObject.getVariantObjects({ ...TEST_CAR, driver: TEST_PERSON })
)
.didNotThrow()
.equals({ ...TEST_CAR, driver: TEST_PERSON })
),
createTest('getVariantObjects(...) throws at wrong type (string)', () =>
// @ts-expect-error
it(() => HybridTestObject.getVariantObjects('some-string')).didThrow()
),
createTest(
'getVariantObjects(...) throws at wrong type (wrong object)',
() =>
it(() =>
// @ts-expect-error
HybridTestObject.getVariantObjects({ someValue: 55 })
).didThrow()
),
createTest('getVariantHybrid(...) converts Hybrid', () =>
it(() => HybridTestObject.getVariantHybrid(HybridTestObject))
.didNotThrow()
// @ts-expect-error
.toContain('getVariantHybrid')
),
createTest('getVariantHybrid(...) converts Person', () =>
it(() => HybridTestObject.getVariantHybrid(TEST_PERSON))
.didNotThrow()
.equals(TEST_PERSON)
),
createTest('getVariantHybrid(...) throws at wrong type (string)', () =>
// @ts-expect-error
it(() => HybridTestObject.getVariantHybrid('some-string')).didThrow()
),
createTest(
'getVariantHybrid(...) throws at wrong type (wrong object)',
() =>
it(() =>
// @ts-expect-error
HybridTestObject.getVariantHybrid({ someValue: 55 })
).didThrow()
),
createTest('getVariantTuple(...) converts TestTuple', () =>
it(() => HybridTestObject.getVariantTuple([532, 'hello', false]))
.didNotThrow()
.equals([532, 'hello', false])
),
createTest('getVariantTuple(...) converts Float3', () =>
it(() => HybridTestObject.getVariantTuple([10, 20, 30]))
.didNotThrow()
.equals([10, 20, 30])
),
createTest('getVariantTuple(...) converts number[]', () =>
it(() => HybridTestObject.getVariantTuple([10, 20, 30, 40, 50]))
.didNotThrow()
.equals([10, 20, 30, 40, 50])
),
createTest('getVariantTuple(...) throws at wrong type (string)', () =>
// @ts-expect-error
it(() => HybridTestObject.getVariantTuple('hello')).didThrow()
),
createTest('getVariantTuple(...) throws at wrong type (string[])', () =>
// @ts-expect-error
it(() => HybridTestObject.getVariantTuple(['hello', 'world'])).didThrow()
),

// Tuples Tests
createTest("set someTuple to [55, 'hello']", () =>
it(() => (HybridTestObject.someTuple = [55, 'hello'])).didNotThrow()
Expand Down
28 changes: 28 additions & 0 deletions example/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export function stringify(value: unknown): string {
if (value == null) {
return 'null'
}

switch (typeof value) {
case 'string':
return value
case 'bigint':
case 'boolean':
case 'number':
case 'symbol':
return String(value)
case 'function':
return value.toString()
case 'object':
if (value instanceof Error) {
return `${value.name}: ${value.message}`
}
if ('toString' in value) {
const string = value.toString()
if (string !== '[object Object]') return string
}
return `{ ${value} ${Object.keys(value).join(', ')} }`
default:
return `${value}`
}
}
1 change: 1 addition & 0 deletions packages/react-native-nitro-image/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { NitroModules } from 'react-native-nitro-modules'
import type { ImageFactory } from './specs/ImageFactory.nitro'
import type { TestObject } from './specs/TestObject.nitro'

export * from './specs/TestObject.nitro'
export * from './specs/Image.nitro'
export * from './specs/ImageFactory.nitro'

Expand Down
12 changes: 6 additions & 6 deletions packages/react-native-nitro-image/src/specs/TestObject.nitro.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { type HybridObject, type AnyMap } from 'react-native-nitro-modules'

type Float3 = [number, number, number]
type TestTuple = [number, string, boolean]
export type Float3 = [number, number, number]
export type TestTuple = [number, string, boolean]

type Powertrain = 'electric' | 'gas' | 'hybrid'
export type Powertrain = 'electric' | 'gas' | 'hybrid'

enum OldEnum {
export enum OldEnum {
FIRST,
SECOND,
THIRD,
}

interface Car {
export interface Car {
year: number
make: string
model: string
Expand All @@ -20,7 +20,7 @@ interface Car {
driver?: Person
}

interface Person {
export interface Person {
name: string
age: number
}
Expand Down

0 comments on commit 872e77c

Please sign in to comment.