-
-
Notifications
You must be signed in to change notification settings - Fork 214
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add rawCheck and rawTransform action #597
- Loading branch information
1 parent
a0ea365
commit ec79160
Showing
22 changed files
with
729 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './rawCheck.ts'; | ||
export * from './rawCheckAsync.ts'; | ||
export { RawCheckIssue } from './types.ts'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { describe, expectTypeOf, test } from 'vitest'; | ||
import type { InferInput, InferIssue, InferOutput } from '../../types/index.ts'; | ||
import { rawCheck, type RawCheckAction } from './rawCheck.ts'; | ||
import type { RawCheckIssue } from './types.ts'; | ||
|
||
describe('rawCheck', () => { | ||
test('should return action object', () => { | ||
expectTypeOf(rawCheck<string>(() => {})).toEqualTypeOf< | ||
RawCheckAction<string> | ||
>(); | ||
}); | ||
|
||
describe('should infer correct types', () => { | ||
type Input = ['foo', 123, true]; | ||
type Action = RawCheckAction<Input>; | ||
|
||
test('of input', () => { | ||
expectTypeOf<InferInput<Action>>().toEqualTypeOf<Input>(); | ||
}); | ||
|
||
test('of output', () => { | ||
expectTypeOf<InferOutput<Action>>().toEqualTypeOf<Input>(); | ||
}); | ||
|
||
test('of issue', () => { | ||
expectTypeOf<InferIssue<Action>>().toEqualTypeOf<RawCheckIssue<Input>>(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { describe, expect, test } from 'vitest'; | ||
import { expectActionIssue, expectNoActionIssue } from '../../vitest/index.ts'; | ||
import { rawCheck, type RawCheckAction } from './rawCheck.ts'; | ||
import type { RawCheckIssue } from './types.ts'; | ||
|
||
describe('rawCheck', () => { | ||
const action = rawCheck<number>(({ dataset, addIssue }) => { | ||
if (dataset.typed && dataset.value <= 0) { | ||
addIssue({ message: 'message' }); | ||
} | ||
}); | ||
|
||
test('should return action object', () => { | ||
expect(action).toStrictEqual({ | ||
kind: 'validation', | ||
type: 'raw_check', | ||
reference: rawCheck, | ||
expects: null, | ||
async: false, | ||
_run: expect.any(Function), | ||
} satisfies RawCheckAction<number>); | ||
}); | ||
|
||
describe('should return dataset without issues', () => { | ||
test('for untyped inputs', () => { | ||
expect(action._run({ typed: false, value: null }, {})).toStrictEqual({ | ||
typed: false, | ||
value: null, | ||
}); | ||
}); | ||
|
||
test('for valid inputs', () => { | ||
expectNoActionIssue(action, [1, 12345, Infinity]); | ||
}); | ||
}); | ||
|
||
describe('should return dataset with issues', () => { | ||
const baseIssue: Omit<RawCheckIssue<number>, 'input' | 'received'> = { | ||
kind: 'validation', | ||
type: 'raw_check', | ||
expected: null, | ||
message: 'message', | ||
}; | ||
|
||
test('for invalid inputs', () => { | ||
expectActionIssue(action, baseIssue, [0, -1, -12345, -Infinity]); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import type { BaseValidation } from '../../types/index.ts'; | ||
import { _addIssue } from '../../utils/index.ts'; | ||
import type { Context, RawCheckIssue } from './types.ts'; | ||
|
||
/** | ||
* Raw check action type. | ||
*/ | ||
export interface RawCheckAction<TInput> | ||
extends BaseValidation<TInput, TInput, RawCheckIssue<TInput>> { | ||
/** | ||
* The action type. | ||
*/ | ||
readonly type: 'raw_check'; | ||
/** | ||
* The action reference. | ||
*/ | ||
readonly reference: typeof rawCheck; | ||
/** | ||
* The expected property. | ||
*/ | ||
readonly expects: null; | ||
} | ||
|
||
/** | ||
* Creates a raw check validation action. | ||
* | ||
* @param action The validation action. | ||
* | ||
* @returns A raw check action. | ||
*/ | ||
export function rawCheck<TInput>( | ||
action: (context: Context<TInput>) => void | ||
): RawCheckAction<TInput> { | ||
return { | ||
kind: 'validation', | ||
type: 'raw_check', | ||
reference: rawCheck, | ||
async: false, | ||
expects: null, | ||
_run(dataset, config) { | ||
action({ | ||
dataset, | ||
config, | ||
addIssue: (info) => | ||
_addIssue(this, info?.label ?? 'input', dataset, config, info), | ||
}); | ||
return dataset; | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { describe, expectTypeOf, test } from 'vitest'; | ||
import type { InferInput, InferIssue, InferOutput } from '../../types/index.ts'; | ||
import { type RawCheckActionAsync, rawCheckAsync } from './rawCheckAsync.ts'; | ||
import type { RawCheckIssue } from './types.ts'; | ||
|
||
describe('rawCheckAsync', () => { | ||
test('should return action object', () => { | ||
expectTypeOf(rawCheckAsync<string>(async () => {})).toEqualTypeOf< | ||
RawCheckActionAsync<string> | ||
>(); | ||
}); | ||
|
||
describe('should infer correct types', () => { | ||
type Input = ['foo', 123, true]; | ||
type Action = RawCheckActionAsync<Input>; | ||
|
||
test('of input', () => { | ||
expectTypeOf<InferInput<Action>>().toEqualTypeOf<Input>(); | ||
}); | ||
|
||
test('of output', () => { | ||
expectTypeOf<InferOutput<Action>>().toEqualTypeOf<Input>(); | ||
}); | ||
|
||
test('of issue', () => { | ||
expectTypeOf<InferIssue<Action>>().toEqualTypeOf<RawCheckIssue<Input>>(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { describe, expect, test } from 'vitest'; | ||
import { | ||
expectActionIssueAsync, | ||
expectNoActionIssueAsync, | ||
} from '../../vitest/index.ts'; | ||
import { type RawCheckActionAsync, rawCheckAsync } from './rawCheckAsync.ts'; | ||
import type { RawCheckIssue } from './types.ts'; | ||
|
||
describe('rawCheckAsync', () => { | ||
const action = rawCheckAsync<number>(async ({ dataset, addIssue }) => { | ||
if (dataset.typed && dataset.value <= 0) { | ||
addIssue({ message: 'message' }); | ||
} | ||
}); | ||
|
||
test('should return action object', () => { | ||
expect(action).toStrictEqual({ | ||
kind: 'validation', | ||
type: 'raw_check', | ||
reference: rawCheckAsync, | ||
expects: null, | ||
async: true, | ||
_run: expect.any(Function), | ||
} satisfies RawCheckActionAsync<number>); | ||
}); | ||
|
||
describe('should return dataset without issues', () => { | ||
test('for untyped inputs', async () => { | ||
expect( | ||
await action._run({ typed: false, value: null }, {}) | ||
).toStrictEqual({ | ||
typed: false, | ||
value: null, | ||
}); | ||
}); | ||
|
||
test('for valid inputs', async () => { | ||
await expectNoActionIssueAsync(action, [1, 12345, Infinity]); | ||
}); | ||
}); | ||
|
||
describe('should return dataset with issues', () => { | ||
const baseIssue: Omit<RawCheckIssue<number>, 'input' | 'received'> = { | ||
kind: 'validation', | ||
type: 'raw_check', | ||
expected: null, | ||
message: 'message', | ||
}; | ||
|
||
test('for invalid inputs', async () => { | ||
await expectActionIssueAsync(action, baseIssue, [ | ||
0, | ||
-1, | ||
-12345, | ||
-Infinity, | ||
]); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import type { BaseValidationAsync, MaybePromise } from '../../types/index.ts'; | ||
import { _addIssue } from '../../utils/index.ts'; | ||
import type { Context, RawCheckIssue } from './types.ts'; | ||
|
||
/** | ||
* Raw check action async type. | ||
*/ | ||
export interface RawCheckActionAsync<TInput> | ||
extends BaseValidationAsync<TInput, TInput, RawCheckIssue<TInput>> { | ||
/** | ||
* The action type. | ||
*/ | ||
readonly type: 'raw_check'; | ||
/** | ||
* The action reference. | ||
*/ | ||
readonly reference: typeof rawCheckAsync; | ||
/** | ||
* The expected property. | ||
*/ | ||
readonly expects: null; | ||
} | ||
|
||
/** | ||
* Creates a raw check validation action. | ||
* | ||
* @param action The validation action. | ||
* | ||
* @returns A raw check action. | ||
*/ | ||
export function rawCheckAsync<TInput>( | ||
action: (context: Context<TInput>) => MaybePromise<void> | ||
): RawCheckActionAsync<TInput> { | ||
return { | ||
kind: 'validation', | ||
type: 'raw_check', | ||
reference: rawCheckAsync, | ||
async: true, | ||
expects: null, | ||
async _run(dataset, config) { | ||
await action({ | ||
dataset, | ||
config, | ||
addIssue: (info) => | ||
_addIssue(this, info?.label ?? 'input', dataset, config, info), | ||
}); | ||
return dataset; | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import type { | ||
BaseIssue, | ||
Config, | ||
Dataset, | ||
ErrorMessage, | ||
IssuePathItem, | ||
} from '../../types/index.ts'; | ||
|
||
/** | ||
* Raw check issue type. | ||
*/ | ||
export interface RawCheckIssue<TInput> extends BaseIssue<TInput> { | ||
/** | ||
* The issue kind. | ||
*/ | ||
readonly kind: 'validation'; | ||
/** | ||
* The issue type. | ||
*/ | ||
readonly type: 'raw_check'; | ||
} | ||
|
||
/** | ||
* Issue info type. | ||
*/ | ||
interface IssueInfo<TInput> { | ||
label?: string; | ||
input?: unknown; | ||
expected?: string; | ||
received?: string; | ||
message?: ErrorMessage<RawCheckIssue<TInput>>; | ||
path?: [IssuePathItem, ...IssuePathItem[]]; | ||
} | ||
|
||
/** | ||
* Add issue type. | ||
*/ | ||
type AddIssue<TInput> = (info?: IssueInfo<TInput>) => void; | ||
|
||
/** | ||
* Context type. | ||
*/ | ||
export interface Context<TInput> { | ||
readonly dataset: Dataset<TInput, BaseIssue<unknown>>; | ||
readonly config: Config<RawCheckIssue<TInput>>; | ||
readonly addIssue: AddIssue<TInput>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from './rawTransform.ts'; | ||
export * from './rawTransformAsync.ts'; | ||
export { RawTransformIssue } from './types.ts'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { describe, expectTypeOf, test } from 'vitest'; | ||
import type { InferInput, InferIssue, InferOutput } from '../../types/index.ts'; | ||
import { rawTransform, type RawTransformAction } from './rawTransform.ts'; | ||
import type { RawTransformIssue } from './types.ts'; | ||
|
||
describe('rawTransform', () => { | ||
test('should return action object', () => { | ||
expectTypeOf( | ||
rawTransform<string, number>(({ dataset }) => dataset.value.length) | ||
).toEqualTypeOf<RawTransformAction<string, number>>(); | ||
}); | ||
|
||
describe('should infer correct types', () => { | ||
type Action = RawTransformAction<string, number>; | ||
|
||
test('of input', () => { | ||
expectTypeOf<InferInput<Action>>().toEqualTypeOf<string>(); | ||
}); | ||
|
||
test('of output', () => { | ||
expectTypeOf<InferOutput<Action>>().toEqualTypeOf<number>(); | ||
}); | ||
|
||
test('of issue', () => { | ||
expectTypeOf<InferIssue<Action>>().toEqualTypeOf< | ||
RawTransformIssue<string> | ||
>(); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.