Skip to content

Commit

Permalink
Merge pull request #138 from seasonedcc/make-error-and-success
Browse files Browse the repository at this point in the history
feat: Add and export makeSuccessResult and makeErrorResult helpers
  • Loading branch information
diogob authored Apr 8, 2024
2 parents dafc5cf + 8df5bd3 commit c81b27b
Show file tree
Hide file tree
Showing 16 changed files with 488 additions and 603 deletions.
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

0 comments on commit c81b27b

Please sign in to comment.