Skip to content

Commit e734a29

Browse files
author
Elias Mulhall
committed
Update tests
1 parent b02d03c commit e734a29

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
});
@@ -243,14 +243,53 @@ describe('object', () => {
243243
});
244244
});
245245

246-
it('ignores optional fields that decode to undefined', () => {
247-
const decoder = object({
248-
a: number(),
249-
b: optional(string())
246+
describe('optional and undefined fields', () => {
247+
it('ignores optional fields that decode to undefined', () => {
248+
interface AB {
249+
a: number;
250+
b?: string;
251+
}
252+
253+
const decoder: Decoder<AB> = object<AB>({
254+
a: number(),
255+
b: optional(string())
256+
});
257+
258+
expect(decoder.run({a: 12, b: 'hats'})).toEqual({ok: true, result: {a: 12, b: 'hats'}});
259+
expect(decoder.run({a: 12})).toEqual({ok: true, result: {a: 12}});
250260
});
251261

252-
expect(decoder.run({a: 12, b: 'hats'})).toEqual({ok: true, result: {a: 12, b: 'hats'}});
253-
expect(decoder.run({a: 12})).toEqual({ok: true, result: {a: 12}});
262+
it('includes fields that are mapped to a value when not found', () => {
263+
interface AB {
264+
a: number;
265+
b: string;
266+
}
267+
268+
const decoder: Decoder<AB> = object<AB>({
269+
a: number(),
270+
b: oneOf(string(), constant(undefined)).map(
271+
(b: string | undefined) => (b === undefined ? 'b not found' : b)
272+
)
273+
});
274+
275+
expect(decoder.run({a: 12, b: 'hats'})).toEqual({ok: true, result: {a: 12, b: 'hats'}});
276+
expect(decoder.run({a: 12})).toEqual({ok: true, result: {a: 12, b: 'b not found'}});
277+
});
278+
279+
it('includes fields that are mapped to a undefined when not found', () => {
280+
interface AB {
281+
a: number;
282+
b: string | undefined;
283+
}
284+
285+
const decoder: Decoder<AB> = object<AB>({
286+
a: number(),
287+
b: oneOf(string(), constant(undefined))
288+
});
289+
290+
expect(decoder.run({a: 12, b: 'hats'})).toEqual({ok: true, result: {a: 12, b: 'hats'}});
291+
expect(decoder.run({a: 12})).toEqual({ok: true, result: {a: 12, b: undefined}});
292+
});
254293
});
255294
});
256295

@@ -334,32 +373,13 @@ describe('dict', () => {
334373
});
335374

336375
describe('optional', () => {
337-
describe('decoding a non-object type', () => {
338-
const decoder = optional(number());
339-
340-
it('can decode the given type', () => {
341-
expect(decoder.run(5)).toEqual({ok: true, result: 5});
342-
});
343-
344-
it('can decode undefined', () => {
345-
expect(decoder.run(undefined)).toEqual({ok: true, result: undefined});
346-
});
347-
348-
it('fails when the value is invalid', () => {
349-
expect(decoder.run(false)).toMatchObject({
350-
ok: false,
351-
error: {at: 'input', message: 'expected a number, got a boolean'}
352-
});
353-
});
354-
});
355-
356376
describe('decoding an interface with optional fields', () => {
357377
interface User {
358378
id: number;
359379
isDog?: boolean;
360380
}
361381

362-
const decoder: Decoder<User> = object({
382+
const decoder = object<User>({
363383
id: number(),
364384
isDog: optional(boolean())
365385
});
@@ -449,8 +469,8 @@ describe('union', () => {
449469
type C = A | B;
450470

451471
const decoder: Decoder<C> = union(
452-
object({kind: constant<'a'>('a'), value: number()}),
453-
object({kind: constant<'b'>('b'), value: boolean()})
472+
object<A>({kind: constant<'a'>('a'), value: number()}),
473+
object<B>({kind: constant<'b'>('b'), value: boolean()})
454474
);
455475

456476
it('can decode a value that matches one of the union types', () => {
@@ -527,7 +547,7 @@ describe('valueAt', () => {
527547
});
528548

529549
describe('decode an optional field', () => {
530-
const decoder = valueAt(['a', 'b', 'c'], optional(string()));
550+
const decoder = valueAt(['a', 'b', 'c'], oneOf(string(), constant(undefined)));
531551

532552
it('fails when the path does not exist', () => {
533553
const error = decoder.run({a: {x: 'cats'}});
@@ -628,7 +648,7 @@ describe('lazy', () => {
628648
replies: Comment[];
629649
}
630650

631-
const decoder: Decoder<Comment> = object({
651+
const decoder: Decoder<Comment> = object<Comment>({
632652
msg: string(),
633653
replies: lazy(() => array(decoder))
634654
});

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)