Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add and export makeSuccessResult and makeErrorResult helpers #138

Merged
merged 3 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 39 additions & 53 deletions src/all.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import {
} from './test-prelude.ts'
import { z } from './test-prelude.ts'

import { mdf } from './constructor.ts'
import { makeSuccessResult, mdf } from './constructor.ts'
import { all } from './domain-functions.ts'
import type { DomainFunction } from './types.ts'
import type { Equal, Expect } from './types.test.ts'
import { makeErrorResult } from './errors.ts'

describe('all', () => {
it('should combine two domain functions into one', async () => {
Expand All @@ -19,13 +20,10 @@ describe('all', () => {
const c = all(a, b)
type _R = Expect<Equal<typeof c, DomainFunction<[number, number]>>>

assertEquals(await c({ id: 1 }), {
success: true,
data: [2, 0],
errors: [],
inputErrors: [],
environmentErrors: [],
})
assertEquals(
await c({ id: 1 }),
makeSuccessResult<[number, number]>([2, 0]),
)
})

it('should combine many domain functions into one', async () => {
Expand All @@ -36,13 +34,10 @@ describe('all', () => {
type _R = Expect<Equal<typeof d, DomainFunction<[string, number, boolean]>>>

const results = await d({ id: 1 })
assertEquals(results, {
success: true,
data: ['1', 2, true],
errors: [],
inputErrors: [],
environmentErrors: [],
})
assertEquals(
results,
makeSuccessResult<[string, number, boolean]>(['1', 2, true]),
)
})

it('should return error when one of the domain functions has input errors', async () => {
Expand All @@ -52,17 +47,14 @@ describe('all', () => {
const c = all(a, b)
type _R = Expect<Equal<typeof c, DomainFunction<[number, string]>>>

assertEquals(await c({ id: 1 }), {
success: false,
inputErrors: [
{
message: 'Expected string, received number',
path: ['id'],
},
],
errors: [],
environmentErrors: [],
})
assertEquals(
await c({ id: 1 }),
makeErrorResult({
inputErrors: [
{ message: 'Expected string, received number', path: ['id'] },
],
}),
)
})

it('should return error when one of the domain functions fails', async () => {
Expand All @@ -74,12 +66,12 @@ describe('all', () => {
const c = all(a, b)
type _R = Expect<Equal<typeof c, DomainFunction<[number, never]>>>

assertEquals(await c({ id: 1 }), {
success: false,
errors: [{ message: 'Error', exception: 'Error' }],
inputErrors: [],
environmentErrors: [],
})
assertEquals(
await c({ id: 1 }),
makeErrorResult({
errors: [{ message: 'Error', exception: 'Error' }],
}),
)
})

it('should combine the inputError messages of both functions', async () => {
Expand All @@ -89,21 +81,15 @@ describe('all', () => {
const c = all(a, b)
type _R = Expect<Equal<typeof c, DomainFunction<[string, string]>>>

assertEquals(await c({ id: 1 }), {
success: false,
inputErrors: [
{
message: 'Expected string, received number',
path: ['id'],
},
{
message: 'Expected string, received number',
path: ['id'],
},
],
environmentErrors: [],
errors: [],
})
assertEquals(
await c({ id: 1 }),
makeErrorResult({
inputErrors: [
{ message: 'Expected string, received number', path: ['id'] },
{ message: 'Expected string, received number', path: ['id'] },
],
}),
)
})

it('should combine the error messages when both functions fail', async () => {
Expand All @@ -117,11 +103,11 @@ describe('all', () => {
const c = all(a, b)
type _R = Expect<Equal<typeof c, DomainFunction<[never, never]>>>

assertObjectMatch(await c({ id: 1 }), {
success: false,
errors: [{ message: 'Error A' }, { message: 'Error B' }],
inputErrors: [],
environmentErrors: [],
})
assertObjectMatch(
await c({ id: 1 }),
makeErrorResult({
errors: [{ message: 'Error A' }, { message: 'Error B' }],
}),
)
})
})
34 changes: 14 additions & 20 deletions src/apply-environment.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { assertEquals, describe, it } from './test-prelude.ts'
import { z } from './test-prelude.ts'

import { mdf } from './constructor.ts'
import { makeSuccessResult, mdf } from './constructor.ts'
import { applyEnvironment } from './domain-functions.ts'
import { makeErrorResult } from './errors.ts'

describe('applyEnvironment', () => {
it('fails when environment fails parser', async () => {
Expand All @@ -13,17 +14,14 @@ describe('applyEnvironment', () => {
'invalid environment',
)

assertEquals(await getEnvWithEnvironment('some input'), {
success: false,
errors: [],
inputErrors: [],
environmentErrors: [
{
message: 'Expected number, received string',
path: [],
},
],
})
assertEquals(
await getEnvWithEnvironment('some input'),
makeErrorResult({
environmentErrors: [
{ message: 'Expected number, received string', path: [] },
],
}),
)
})

it('should apply environment', async () => {
Expand All @@ -34,13 +32,9 @@ describe('applyEnvironment', () => {
'constant environment',
)

assertEquals(await getEnvWithEnvironment('some input'), {
success: true,
data: 'constant environment',
errors: [],
inputErrors: [],
environmentErrors: [],
})
assertEquals(
await getEnvWithEnvironment('some input'),
makeSuccessResult('constant environment'),
)
})
})

99 changes: 35 additions & 64 deletions src/branch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import {
} from './test-prelude.ts'
import { z } from './test-prelude.ts'

import { mdf } from './constructor.ts'
import { makeSuccessResult, mdf } from './constructor.ts'
import { branch, pipe, all } from './domain-functions.ts'
import type { DomainFunction } from './types.ts'
import type { Equal, Expect } from './types.test.ts'
import { makeErrorResult } from './errors.ts'

describe('branch', () => {
it('should pipe a domain function with a function that returns a DF', async () => {
Expand All @@ -21,13 +22,7 @@ describe('branch', () => {
const c = branch(a, () => Promise.resolve(b))
type _R = Expect<Equal<typeof c, DomainFunction<number>>>

assertEquals(await c({ id: 1 }), {
success: true,
data: 2,
errors: [],
inputErrors: [],
environmentErrors: [],
})
assertEquals(await c({ id: 1 }), makeSuccessResult(2))
})

it('should enable conditionally choosing the next DF with the output of first one', async () => {
Expand All @@ -40,13 +35,7 @@ describe('branch', () => {
const d = branch(a, (output) => (output.next === 'multiply' ? c : b))
type _R = Expect<Equal<typeof d, DomainFunction<number | string>>>

assertEquals(await d({ id: 1 }), {
success: true,
data: 6,
errors: [],
inputErrors: [],
environmentErrors: [],
})
assertEquals(await d({ id: 1 }), makeSuccessResult(6))
})

it('should not pipe if the predicate returns null', async () => {
Expand All @@ -60,13 +49,10 @@ describe('branch', () => {
Equal<typeof d, DomainFunction<string | { id: number; next: string }>>
>

assertEquals(await d({ id: 1 }), {
success: true,
data: { id: 3, next: 'multiply' },
errors: [],
inputErrors: [],
environmentErrors: [],
})
assertEquals(
await d({ id: 1 }),
makeSuccessResult({ id: 3, next: 'multiply' }),
)
})

it('should use the same environment in all composed functions', async () => {
Expand All @@ -84,13 +70,7 @@ describe('branch', () => {
const c = branch(a, () => b)
type _R = Expect<Equal<typeof c, DomainFunction<number>>>

assertEquals(await c(undefined, { env: 1 }), {
success: true,
data: 4,
errors: [],
inputErrors: [],
environmentErrors: [],
})
assertEquals(await c(undefined, { env: 1 }), makeSuccessResult(4))
})

it('should gracefully fail if the first function fails', async () => {
Expand All @@ -101,17 +81,14 @@ describe('branch', () => {
const c = branch(a, () => b)
type _R = Expect<Equal<typeof c, DomainFunction<number>>>

assertEquals(await c({ id: '1' }), {
success: false,
errors: [],
inputErrors: [
{
path: ['id'],
message: 'Expected number, received string',
},
],
environmentErrors: [],
})
assertEquals(
await c({ id: '1' }),
makeErrorResult({
inputErrors: [
{ path: ['id'], message: 'Expected number, received string' },
],
}),
)
})

it('should gracefully fail if the second function fails', async () => {
Expand All @@ -122,17 +99,14 @@ describe('branch', () => {
const c = branch(a, () => b)
type _R = Expect<Equal<typeof c, DomainFunction<number>>>

assertEquals(await c({ id: 1 }), {
success: false,
errors: [],
inputErrors: [
{
path: ['id'],
message: 'Expected number, received string',
},
],
environmentErrors: [],
})
assertEquals(
await c({ id: 1 }),
makeErrorResult({
inputErrors: [
{ path: ['id'], message: 'Expected number, received string' },
],
}),
)
})

it('should gracefully fail if the condition function fails', async () => {
Expand All @@ -147,12 +121,12 @@ describe('branch', () => {
})
type _R = Expect<Equal<typeof c, DomainFunction<number>>>

assertObjectMatch(await c({ id: 1 }), {
success: false,
errors: [{ message: 'condition function failed' }],
inputErrors: [],
environmentErrors: [],
})
assertObjectMatch(
await c({ id: 1 }),
makeErrorResult({
errors: [{ message: 'condition function failed' }],
}),
)
})

it('should not break composition with other combinators', async () => {
Expand All @@ -170,12 +144,9 @@ describe('branch', () => {
)
type _R = Expect<Equal<typeof d, DomainFunction<[number, { id: number }]>>>

assertEquals(await d({ id: 1 }), {
data: [4, { id: 3 }],
success: true,
errors: [],
inputErrors: [],
environmentErrors: [],
})
assertEquals(
await d({ id: 1 }),
makeSuccessResult<[number, { id: number }]>([4, { id: 3 }]),
)
})
})
Loading
Loading