From 54179dc8ef902cf901191914257af13ad1a51a48 Mon Sep 17 00:00:00 2001 From: Jan Molak Date: Wed, 29 Aug 2018 16:14:22 +0100 Subject: [PATCH] fix(toJSON): Corrected serialisation of falsey primitives Thanks for spotting the issue, @baasie! --- spec/serialisation.spec.ts | 26 ++++++++++++++++++++++++++ src/TinyType.ts | 6 ++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/spec/serialisation.spec.ts b/spec/serialisation.spec.ts index e8818078..a3eee3d3 100644 --- a/spec/serialisation.spec.ts +++ b/spec/serialisation.spec.ts @@ -1,9 +1,35 @@ import 'mocha'; +import { given } from 'mocha-testdata'; + import { Serialised, TinyType, TinyTypeOf } from '../src'; import { expect } from './expect'; describe('Serialisation', () => { + describe('of single-value TinyTypes', () => { + + class Amount extends TinyTypeOf() {} + class Name extends TinyTypeOf() {} + class Vote extends TinyTypeOf() {} + class Maybe extends TinyType { + constructor(public readonly value: any) { + super(); + } + } + + given([ + { obj: new Amount(0), expectedType: 'number' }, + { obj: new Amount(10/3), expectedType: 'number' }, + { obj: new Name('Jan'), expectedType: 'string' }, + { obj: new Vote(true), expectedType: 'boolean' }, + { obj: new Vote(false), expectedType: 'boolean' }, + { obj: new Maybe(undefined), expectedType: 'undefined' }, + ]). + it('preserves the type of the wrapped value', ({ obj, expectedType: expectedType }) => { + expect(obj.toJSON()).to.be.an(expectedType); + }); + }); + describe('of TinyTypes wrapping several primitive values', () => { class Person extends TinyType { diff --git a/src/TinyType.ts b/src/TinyType.ts index 47848ee1..63b939f5 100644 --- a/src/TinyType.ts +++ b/src/TinyType.ts @@ -124,7 +124,9 @@ export abstract class TinyType implements Serialisable { toJSON(): JSONObject | NonNullJSONPrimitive { const isObject = (value: any) => Object(value) === value, - isPrimitive = (value: any) => Object(value) !== value; + isSerialisablePrimitive = (value: any) => + !! ~ ['string', 'boolean', 'null', 'undefined'].indexOf(typeof value) || + (typeof value === 'number' && ! isNaN(value) && ! ~ [ Infinity, -Infinity ].indexOf(value)); function toJSON(value: any): JSONObject | NonNullJSONPrimitive { switch (true) { @@ -134,7 +136,7 @@ export abstract class TinyType implements Serialisable { return value.map(v => toJSON(v)); case value && isObject(value): return JSON.parse(JSON.stringify(value)); - case value && isPrimitive(value): + case isSerialisablePrimitive(value): return value; default: return JSON.stringify(value);