Skip to content

Commit

Permalink
Merge pull request #58 from MaskingTechnology/57-add-support-for-dese…
Browse files Browse the repository at this point in the history
…rializing-dates

#57 Added the date serializer
  • Loading branch information
basmasking authored Nov 14, 2022
2 parents 0c115e1 + 8f5d893 commit 38b90da
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 0 deletions.
39 changes: 39 additions & 0 deletions jitar/src/runtime/serialization/DateSerializer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

import Serializer from './interfaces/Serializer.js';

import SerializedDate from './types/SerializedDate.js';
import InvalidPropertyType from './errors/InvalidPropertyType.js';

class DateSerializer implements Serializer
{
serialize(date: Date): SerializedDate
{
return { serialized: true, name: 'Date', value: date.toISOString() };
}

async deserialize(serializedDate: SerializedDate): Promise<Date>
{
this.#validateDate(serializedDate);

return new Date(serializedDate.value);
}

#validateDate(serializedDate: SerializedDate): void
{
if (typeof serializedDate.value !== 'string')
{
throw new InvalidPropertyType('date', 'value', 'string');
}

const date = Date.parse(serializedDate.value);

if (Number.isNaN(date))
{
throw new InvalidPropertyType('date', 'value', 'date');
}
}
}

const instance = new DateSerializer();

export default instance;
7 changes: 7 additions & 0 deletions jitar/src/runtime/serialization/ValueSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Serializer from './interfaces/Serializer.js';
import MapSerializer from './MapSerializer.js';
import ObjectSerializer from './ObjectSerializer.js';
import SetSerializer from './SetSerializer.js';
import DateSerializer from './DateSerializer.js';

import SerializableObject from './types/SerializableObject.js';
import Serialized from './types/Serialized.js';
Expand All @@ -16,6 +17,7 @@ import SerializedClass from './types/SerializedClass.js';
import SerializedMap from './types/SerializedMap.js';
import SerializedObject from './types/SerializedObject.js';
import SerializedSet from './types/SerializedSet.js';
import SerializedDate from './types/SerializedDate.js';
import TypedArray from './types/TypedArray.js';

class ValueSerializer implements Serializer
Expand All @@ -38,6 +40,10 @@ class ValueSerializer implements Serializer
{
return SetSerializer.serialize(value);
}
if (value instanceof Date)
{
return DateSerializer.serialize(value);
}
else if (value instanceof Error)
{
// The error class is like Array, Map and Set in that it's a native class.
Expand Down Expand Up @@ -78,6 +84,7 @@ class ValueSerializer implements Serializer
{
case 'Map': return await MapSerializer.deserialize(value as SerializedMap);
case 'Set': return await SetSerializer.deserialize(value as SerializedSet);
case 'Date': return await DateSerializer.deserialize(value as SerializedDate);
case 'ArrayBuffer': return await ArrayBufferSerializer.deserialize(value as SerializedArrayBuffer);
default: return await ClassSerializer.deserialize(value as SerializedClass);
}
Expand Down
9 changes: 9 additions & 0 deletions jitar/src/runtime/serialization/types/SerializedDate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

import Serialized from './Serialized.js';

type SerializedDate = Serialized &
{
value: string
};

export default SerializedDate;
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ const emptyObject: unknown = {};
const mixedObject: unknown = { a: 1, b: true, c: 'hello' };
const nestedObject: unknown = { a: 1, b: true, c: { d: false, e: true } };

const fixedDate = new Date('2021-01-01T00:00:00.000Z');
const serializedFixedDate = { serialized: true, name: 'Date', value: '2021-01-01T00:00:00.000Z' };
const serializedInvalidDateValue = { serialized: true, name: 'Date', value: true };
const serializedInvalidDateString = { serialized: true, name: 'Date', value: 'hello' };

const emptyMap: Map<unknown, unknown> = new Map();
const mixedMap: Map<unknown, unknown> = new Map().set('a', 1).set('b', true);
const nestedMap: Map<unknown, unknown> = new Map().set('b', 'hello').set('c', new Map().set('d', false));
Expand Down Expand Up @@ -174,6 +179,7 @@ export
numberValue, boolValue, stringValue, nullValue, undefinedValue,
emptyArray, mixedArray, nestedArray,
emptyObject, mixedObject, nestedObject,
fixedDate, serializedFixedDate, serializedInvalidDateValue, serializedInvalidDateString,
emptyMap, mixedMap, nestedMap, serializedEmptyMap, serializedMixedMap, serializedNestedMap,
emptySet, mixedSet, nestedSet, serializedEmptySet, serializedMixedSet, serializedNestedSet,
dataClass, constructedClass, nestedClass, serializedDataClass, serializedConstructedClass, serializedNestedClass,
Expand Down
22 changes: 22 additions & 0 deletions jitar/test/runtime/serialization/ValueSerializer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import
numberValue, boolValue, stringValue, nullValue, undefinedValue,
emptyArray, mixedArray, nestedArray,
emptyObject, mixedObject, nestedObject,
fixedDate, serializedFixedDate, serializedInvalidDateValue, serializedInvalidDateString,
emptyMap, mixedMap, nestedMap, serializedEmptyMap, serializedMixedMap, serializedNestedMap,
emptySet, mixedSet, nestedSet, serializedEmptySet, serializedMixedSet, serializedNestedSet,
dataClass, constructedClass, nestedClass, serializedDataClass, serializedConstructedClass, serializedNestedClass,
Expand Down Expand Up @@ -38,6 +39,13 @@ describe('serialization/ValueSerializer', () =>
expect(notset).toBe(undefinedValue);
});

it('should serialize date values', () =>
{
const date = ValueSerializer.serialize(fixedDate);

expect(date).toEqual(serializedFixedDate);
});

it('should serialize arrays', () =>
{
const empty = ValueSerializer.serialize(emptyArray);
Expand Down Expand Up @@ -138,6 +146,13 @@ describe('serialization/ValueSerializer', () =>
expect(notset).toBe(undefinedValue);
});

it('should deserialize date values', async () =>
{
const date = await ValueSerializer.deserialize(serializedFixedDate);

expect(date).toEqual(fixedDate);
});

it('should deserialize arrays', async () =>
{
const empty = await ValueSerializer.deserialize(emptyArray);
Expand Down Expand Up @@ -214,6 +229,13 @@ describe('serialization/ValueSerializer', () =>
expect(deserialize).rejects.toEqual(new InvalidClass('Infinity'));
});

it('should not deserialize invalid date objects', async () =>
{
const invalidDateValue = async () => await ValueSerializer.deserialize(serializedInvalidDateValue);
const invalidDateString = async () => await ValueSerializer.deserialize(serializedInvalidDateString);

expect(invalidDateValue).rejects.toEqual(new InvalidPropertyType('date', 'value', 'string'));
expect(invalidDateString).rejects.toEqual(new InvalidPropertyType('date', 'value', 'date'));
it('should deserialize array buffer', async () =>
{
const viewUint16 = await ValueSerializer.deserialize(serializedJitarViewUint16);
Expand Down

0 comments on commit 38b90da

Please sign in to comment.