From 7e0e132084a9cbc2a03f0d5b327f7e0dc23f0879 Mon Sep 17 00:00:00 2001 From: Alex Komoroske Date: Sat, 8 Jul 2023 10:10:11 -0700 Subject: [PATCH] Fix a condition in array/object auto-rolling. If the sub-object only had seed-references, it wouldn't notice it should unroll (it would only unroll if it was a nested seed). Added a test to catch this behavior and ensure it works right. Part of #42. Noticed while working on #37. --- src/seed.ts | 20 ++++++++++---------- test/base/test.ts | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/seed.ts b/src/seed.ts index d342f51..be921a4 100644 --- a/src/seed.ts +++ b/src/seed.ts @@ -116,11 +116,11 @@ changes were made in it or any sub-keeys, changesMade will be true. If changesMade is false, then the return result will === the argument. */ -const expandSeedComputedObjects = (data : D, comingFrom : ComingFrom = '') : [result : D | SeedData, changesMade : boolean, isSeedData : boolean] => { if (!data || typeof data != 'object') return [data, false, false]; +const expandSeedComputedObjects = (data : D, comingFrom : ComingFrom = '') : [result : D | SeedData, changesMade : boolean, isComputedObject : boolean] => { if (!data || typeof data != 'object') return [data, false, false]; //It's a seed reference, which is a leaf and fine. //TODO: shouldn't I use a more explicit test? - if ('seed' in data) return [data, false, false]; + if ('seed' in data) return [data, false, true]; //We check for type in data, and not seedData.parse, because if there are //nested arrays and objects with seedData in they will fail the seedData @@ -153,14 +153,14 @@ const expandSeedComputedObjects = (data : D, co if (Array.isArray(data)) { const clone = [...data] as InputValueArray; let changesMade = false; - let containsSeedData = false; + let containsComputed = false; for (const [i, value] of data.entries()) { - const [modifiedValue, localChangesMade, localContainsSeedData] = expandSeedComputedObjects(value); + const [modifiedValue, localChangesMade, localContainsComputed] = expandSeedComputedObjects(value); if (localChangesMade) changesMade = true; - if (localContainsSeedData) containsSeedData = true; + if (localContainsComputed) containsComputed = true; clone[i] = modifiedValue as InputValue; } - if (changesMade || containsSeedData) { + if (changesMade || containsComputed) { //TODO: why do I have to do this unncessary and incorrect cast to //SeedDataArray to get typescript to be satisfied? //eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -179,15 +179,15 @@ const expandSeedComputedObjects = (data : D, co //it's a generic object. const clone = {...data} as InputValueObject; let changesMade = false; - let containsSeedData = false; + let containsComputed = false; for (const [key, value] of TypedObject.entries(data)) { - const [modifiedValue, localChangesMade, localContainsSeedData] = expandSeedComputedObjects(value); + const [modifiedValue, localChangesMade, localContainsComputed] = expandSeedComputedObjects(value); if (localChangesMade) changesMade = true; - if (localContainsSeedData) containsSeedData = true; + if (localContainsComputed) containsComputed = true; //eslint-disable-next-line @typescript-eslint/no-explicit-any (clone as any)[key] = modifiedValue; } - if (changesMade || containsSeedData) { + if (changesMade || containsComputed) { //TODO: why do I have to do this unncessary and incorrect cast to //SeedDataObject to get typescript to be satisfied? if (comingFrom == 'object') return [clone as SeedDataObject, true, true]; diff --git a/test/base/test.ts b/test/base/test.ts index fe797e9..96fed24 100644 --- a/test/base/test.ts +++ b/test/base/test.ts @@ -1168,6 +1168,49 @@ describe('expandSeedPacket tests', () => { assert.deepStrictEqual(result, golden); }); + it('seed with auto-object single layer nested with seed ref', async () => { + const packet : SeedPacket = { + version: 0, + environment: {}, + seeds: { + '': { + type: 'render', + template: '{{name}} is {{age}}', + vars: { + name: { + seed: 'other' + }, + age: 3 + } + } + } + }; + const result = expandSeedPacket(packet); + const golden : ExpandedSeedPacket = { + version: 0, + environment: {}, + seeds: { + '': { + type: 'render', + template: '{{name}} is {{age}}', + vars: { + seed: '-vars', + } + }, + '-vars': { + type: 'object', + properties: { + name: { + seed: 'other' + }, + age: 3 + } + } + } + }; + assert.deepStrictEqual(result, golden); + }); + it('seed with auto-object with auto-array inside layer nested', async () => { const packet : SeedPacket = { version: 0,