Skip to content

Commit

Permalink
Merge 4e05c1f into eccc73d
Browse files Browse the repository at this point in the history
  • Loading branch information
Felixfranzen committed Nov 4, 2020
2 parents eccc73d + 4e05c1f commit e197895
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 18 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 29 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,20 +301,35 @@ export class Decoder<T> {
]);

/**
* A decoder that accepts undefined and null. Useful in conjunction with other
* decoders.
* A decoder that accepts undefined.
*
* Example:
* ```
* Decoder.empty.run(null) // OK, value is undefined
* Decoder.empty.run(undefined) // OK, value is undefined
* Decoder.empty.run(5) // FAIL, value is not null or undefined
* Decoder.undefined.run(null) // FAIL
* Decoder.undefined.run(5) // FAIL
* Decoder.undefined.run(undefined) // OK
*```
*/
public static empty: Decoder<undefined> = new Decoder((data) =>
data === null || data === undefined
? Result.ok(undefined)
: Result.fail(makeSingleError('Not null or undefined', data))
public static undefined: Decoder<undefined> = new Decoder((data) =>
data === undefined
? Result.ok(data)
: Result.fail(makeSingleError('Not undefined', data))
);

/**
* A decoder that accepts undefined.
*
* Example:
* ```
* Decoder.null.run(undefined) // FAIL
* Decoder.null.run(5) // FAIL
* Decoder.null.run(null) // OK
*```
*/
public static null: Decoder<null> = new Decoder((data) =>
data === null
? Result.ok(data)
: Result.fail(makeSingleError('Not null', data))
);

/**
Expand Down Expand Up @@ -364,7 +379,11 @@ export class Decoder<T> {
* ```
*/
public static optional = <T>(decoder: Decoder<T>): Decoder<T | undefined> =>
Decoder.oneOf([Decoder.empty, decoder]);
Decoder.oneOf([
Decoder.undefined,
Decoder.null.map((_) => undefined),
decoder,
]);

/**
* Create a decoder that always fails with a message.
Expand Down
29 changes: 22 additions & 7 deletions test/decoder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,18 +197,33 @@ describe('Array decoder', () => {
});

describe('Null decoder', () => {
it('decodes null and undefined', () => {
const res2 = Decoder.empty.run(undefined);
const res3 = Decoder.empty.run(null);
expect(res2).toEqual({ type: 'OK', value: undefined });
expect(res3).toEqual({ type: 'OK', value: undefined });
it('decodes null', () => {
const result = Decoder.null.run(null);
expect(result).toEqual({ type: 'OK', value: null });
});

it('does not decode invalid data', () => {
fc.assert(
fc.property(fc.anything(), (anything: any) => {
fc.pre(anything !== null && anything !== undefined);
const res = Decoder.empty.run(anything);
fc.pre(anything !== null);
const res = Decoder.null.run(anything);
expect(res).toHaveProperty('type', 'FAIL');
})
);
});
});

describe('Undefined decoder', () => {
it('decodes undefined', () => {
const result = Decoder.undefined.run(undefined);
expect(result).toEqual({ type: 'OK', value: undefined });
});

it('does not decode invalid data', () => {
fc.assert(
fc.property(fc.anything(), (anything: any) => {
fc.pre(anything !== undefined);
const res = Decoder.undefined.run(anything);
expect(res).toHaveProperty('type', 'FAIL');
})
);
Expand Down

0 comments on commit e197895

Please sign in to comment.