Skip to content

Commit c4bdce7

Browse files
author
Elias Mulhall
committed
Update tests
1 parent c34f12a commit c4bdce7

File tree

3 files changed

+61
-38
lines changed

3 files changed

+61
-38
lines changed

test/json-decode.test.ts

Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ describe('constant', () => {
124124
interface TrueValue {
125125
x: true;
126126
}
127-
const decoder: Decoder<TrueValue> = object({x: constant(true)});
127+
const decoder: Decoder<TrueValue> = object<TrueValue>({x: constant(true)});
128128

129129
expect(decoder.run({x: true})).toEqual({ok: true, result: {x: true}});
130130
});
@@ -133,7 +133,7 @@ describe('constant', () => {
133133
interface FalseValue {
134134
x: false;
135135
}
136-
const decoder: Decoder<FalseValue> = object({x: constant(false)});
136+
const decoder = object<FalseValue>({x: constant(false)});
137137

138138
expect(decoder.run({x: false})).toEqual({ok: true, result: {x: false}});
139139
});
@@ -142,7 +142,7 @@ describe('constant', () => {
142142
interface NullValue {
143143
x: null;
144144
}
145-
const decoder: Decoder<NullValue> = object({x: constant(null)});
145+
const decoder = object<NullValue>({x: constant(null)});
146146

147147
expect(decoder.run({x: null})).toEqual({ok: true, result: {x: null}});
148148
});
@@ -253,14 +253,53 @@ describe('object', () => {
253253
});
254254
});
255255

256-
it('ignores optional fields that decode to undefined', () => {
257-
const decoder = object({
258-
a: number(),
259-
b: optional(string())
256+
describe('optional and undefined fields', () => {
257+
it('ignores optional fields that decode to undefined', () => {
258+
interface AB {
259+
a: number;
260+
b?: string;
261+
}
262+
263+
const decoder: Decoder<AB> = object<AB>({
264+
a: number(),
265+
b: optional(string())
266+
});
267+
268+
expect(decoder.run({a: 12, b: 'hats'})).toEqual({ok: true, result: {a: 12, b: 'hats'}});
269+
expect(decoder.run({a: 12})).toEqual({ok: true, result: {a: 12}});
260270
});
261271

262-
expect(decoder.run({a: 12, b: 'hats'})).toEqual({ok: true, result: {a: 12, b: 'hats'}});
263-
expect(decoder.run({a: 12})).toEqual({ok: true, result: {a: 12}});
272+
it('includes fields that are mapped to a value when not found', () => {
273+
interface AB {
274+
a: number;
275+
b: string;
276+
}
277+
278+
const decoder: Decoder<AB> = object<AB>({
279+
a: number(),
280+
b: oneOf(string(), constant(undefined)).map(
281+
(b: string | undefined) => (b === undefined ? 'b not found' : b)
282+
)
283+
});
284+
285+
expect(decoder.run({a: 12, b: 'hats'})).toEqual({ok: true, result: {a: 12, b: 'hats'}});
286+
expect(decoder.run({a: 12})).toEqual({ok: true, result: {a: 12, b: 'b not found'}});
287+
});
288+
289+
it('includes fields that are mapped to a undefined when not found', () => {
290+
interface AB {
291+
a: number;
292+
b: string | undefined;
293+
}
294+
295+
const decoder: Decoder<AB> = object<AB>({
296+
a: number(),
297+
b: oneOf(string(), constant(undefined))
298+
});
299+
300+
expect(decoder.run({a: 12, b: 'hats'})).toEqual({ok: true, result: {a: 12, b: 'hats'}});
301+
expect(decoder.run({a: 12})).toEqual({ok: true, result: {a: 12, b: undefined}});
302+
});
264303
});
265304
});
266305

@@ -344,32 +383,13 @@ describe('dict', () => {
344383
});
345384

346385
describe('optional', () => {
347-
describe('decoding a non-object type', () => {
348-
const decoder = optional(number());
349-
350-
it('can decode the given type', () => {
351-
expect(decoder.run(5)).toEqual({ok: true, result: 5});
352-
});
353-
354-
it('can decode undefined', () => {
355-
expect(decoder.run(undefined)).toEqual({ok: true, result: undefined});
356-
});
357-
358-
it('fails when the value is invalid', () => {
359-
expect(decoder.run(false)).toMatchObject({
360-
ok: false,
361-
error: {at: 'input', message: 'expected a number, got a boolean'}
362-
});
363-
});
364-
});
365-
366386
describe('decoding an interface with optional fields', () => {
367387
interface User {
368388
id: number;
369389
isDog?: boolean;
370390
}
371391

372-
const decoder: Decoder<User> = object({
392+
const decoder = object<User>({
373393
id: number(),
374394
isDog: optional(boolean())
375395
});
@@ -459,8 +479,8 @@ describe('union', () => {
459479
type C = A | B;
460480

461481
const decoder: Decoder<C> = union(
462-
object({kind: constant<'a'>('a'), value: number()}),
463-
object({kind: constant<'b'>('b'), value: boolean()})
482+
object<A>({kind: constant<'a'>('a'), value: number()}),
483+
object<B>({kind: constant<'b'>('b'), value: boolean()})
464484
);
465485

466486
it('can decode a value that matches one of the union types', () => {
@@ -537,7 +557,7 @@ describe('valueAt', () => {
537557
});
538558

539559
describe('decode an optional field', () => {
540-
const decoder = valueAt(['a', 'b', 'c'], optional(string()));
560+
const decoder = valueAt(['a', 'b', 'c'], oneOf(string(), constant(undefined)));
541561

542562
it('fails when the path does not exist', () => {
543563
const error = decoder.run({a: {x: 'cats'}});
@@ -638,7 +658,7 @@ describe('lazy', () => {
638658
replies: Comment[];
639659
}
640660

641-
const decoder: Decoder<Comment> = object({
661+
const decoder: Decoder<Comment> = object<Comment>({
642662
msg: string(),
643663
replies: lazy(() => array(decoder))
644664
});

test/phone-example.test.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ describe('decode phone number objects', () => {
4242
constant(PhoneUse.Work)
4343
);
4444

45-
const internationalPhoneDecoder: Decoder<InternationalPhone> = object({
45+
const internationalPhoneDecoder = object<InternationalPhone>({
4646
id: number(),
4747
use: optional(phoneUseDecoder),
4848
international: constant(true),
4949
rawNumber: string()
5050
});
5151

52-
const domesticPhoneDecoder: Decoder<DomesticPhone> = object({
52+
const domesticPhoneDecoder = object<DomesticPhone>({
5353
id: number(),
5454
use: optional(phoneUseDecoder),
5555
international: constant(false),
@@ -58,7 +58,10 @@ describe('decode phone number objects', () => {
5858
lineNumber: string()
5959
});
6060

61-
const phoneDecoder: Decoder<Phone> = union(domesticPhoneDecoder, internationalPhoneDecoder);
61+
const phoneDecoder: Decoder<Phone> = union<DomesticPhone, InternationalPhone>(
62+
domesticPhoneDecoder,
63+
internationalPhoneDecoder
64+
);
6265

6366
const phonesDecoder: Decoder<Phone[]> = array(phoneDecoder);
6467

test/user-example.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Decoder, string, number, boolean, object} from '../src/index';
1+
import {string, number, boolean, object} from '../src/index';
22

33
describe('decode json as User interface', () => {
44
interface User {
@@ -22,7 +22,7 @@ describe('decode json as User interface', () => {
2222
active: false
2323
};
2424

25-
const userDecoder: Decoder<User> = object({
25+
const userDecoder = object<User>({
2626
firstname: string(),
2727
lastname: string(),
2828
age: number(),

0 commit comments

Comments
 (0)