From b4dd2488a4492eeb80e5775d084d79af45282a25 Mon Sep 17 00:00:00 2001 From: Paul Armstrong Date: Mon, 30 Jan 2017 13:24:04 -0800 Subject: [PATCH] Refactor denormalize/unvisit. Fixes gh-225 --- src/schemas/Array.js | 8 +++-- src/schemas/Entity.js | 18 +++++++---- src/schemas/__tests__/Array.test.js | 31 +++++++++++++++++++ .../__snapshots__/Array.test.js.snap | 14 +++++++++ 4 files changed, 63 insertions(+), 8 deletions(-) diff --git a/src/schemas/Array.js b/src/schemas/Array.js index 52a090f1..2dcff402 100644 --- a/src/schemas/Array.js +++ b/src/schemas/Array.js @@ -23,7 +23,9 @@ export const normalize = (schema, input, parent, key, visit, addEntity) => { export const denormalize = (schema, input, unvisit, getDenormalizedEntity) => { schema = validateSchema(schema); - return input.map((entityOrId) => unvisit(entityOrId, schema, getDenormalizedEntity)); + return Array.isArray(input) ? + input.map((entityOrId) => unvisit(entityOrId, schema, getDenormalizedEntity)) : + input; }; export default class ArraySchema extends PolymorphicSchema { @@ -35,6 +37,8 @@ export default class ArraySchema extends PolymorphicSchema { } denormalize(input, unvisit, getDenormalizedEntity) { - return input.map((value) => this.denormalizeValue(value, unvisit, getDenormalizedEntity)); + return Array.isArray(input) ? + input.map((value) => this.denormalizeValue(value, unvisit, getDenormalizedEntity)) : + input; } } diff --git a/src/schemas/Entity.js b/src/schemas/Entity.js index c67718da..68ac6728 100644 --- a/src/schemas/Entity.js +++ b/src/schemas/Entity.js @@ -1,5 +1,3 @@ -import { denormalize } from './Object'; - export default class EntitySchema { constructor(key, definition = {}, options = {}) { if (!key || typeof key !== 'string') { @@ -16,7 +14,7 @@ export default class EntitySchema { this._key = key; this._getId = typeof idAttribute === 'function' ? idAttribute : (input) => input[idAttribute]; - this._idAttribute = idAttribute + this._idAttribute = idAttribute; this._mergeStrategy = mergeStrategy; this._processStrategy = processStrategy; this.define(definition); @@ -25,9 +23,9 @@ export default class EntitySchema { get key() { return this._key; } - + get idAttribute() { - return this._idAttribute + return this._idAttribute; } define(definition) { @@ -63,6 +61,14 @@ export default class EntitySchema { if (typeof entity !== 'object') { return entity; } - return denormalize(this.schema, entity, unvisit, getDenormalizedEntity); + + const processedEntity = { ...entity }; + Object.keys(this.schema).forEach((key) => { + if (processedEntity.hasOwnProperty(key)) { + const schema = this.schema[key]; + processedEntity[key] = unvisit(processedEntity[key], schema, getDenormalizedEntity); + } + }); + return processedEntity; } } diff --git a/src/schemas/__tests__/Array.test.js b/src/schemas/__tests__/Array.test.js index cd856dc8..8b520cc6 100644 --- a/src/schemas/__tests__/Array.test.js +++ b/src/schemas/__tests__/Array.test.js @@ -85,6 +85,21 @@ describe(`${schema.Array.name} denormalization`, () => { }; expect(denormalize([ 1, 2 ], [ cats ], entities)).toMatchSnapshot(); }); + + it('returns the input value if is not an array', () => { + const filling = new schema.Entity('fillings'); + const taco = new schema.Entity('tacos', { fillings: [ filling ] }); + const entities = { + tacos: { + '123': { + id: '123', + fillings: null + } + } + }; + + expect(denormalize('123', taco, entities)).toMatchSnapshot(); + }); }); describe('Class', () => { @@ -137,5 +152,21 @@ describe(`${schema.Array.name} denormalization`, () => { expect(denormalize(input, listSchema, entities)).toMatchSnapshot(); }); + + it('returns the input value if is not an array', () => { + const filling = new schema.Entity('fillings'); + const fillings = new schema.Array(filling); + const taco = new schema.Entity('tacos', { fillings }); + const entities = { + tacos: { + '123': { + id: '123', + fillings: null + } + } + }; + + expect(denormalize('123', taco, entities)).toMatchSnapshot(); + }); }); }); diff --git a/src/schemas/__tests__/__snapshots__/Array.test.js.snap b/src/schemas/__tests__/__snapshots__/Array.test.js.snap index 045e51af..c150b845 100644 --- a/src/schemas/__tests__/__snapshots__/Array.test.js.snap +++ b/src/schemas/__tests__/__snapshots__/Array.test.js.snap @@ -31,6 +31,13 @@ Array [ ] `; +exports[`ArraySchema denormalization Class returns the input value if is not an array 1`] = ` +Object { + "fillings": null, + "id": "123", +} +`; + exports[`ArraySchema denormalization Object denormalizes a single entity 1`] = ` Array [ Object { @@ -44,6 +51,13 @@ Array [ ] `; +exports[`ArraySchema denormalization Object returns the input value if is not an array 1`] = ` +Object { + "fillings": null, + "id": "123", +} +`; + exports[`ArraySchema normalization Class filters out undefined and null normalized values 1`] = ` Object { "entities": Object {