From c339d741843c65d3de1792f67ddf41540b46706e Mon Sep 17 00:00:00 2001 From: Felipe Lalanne <1822826+pipex@users.noreply.github.com> Date: Wed, 3 Jan 2024 16:01:14 -0300 Subject: [PATCH] Do not recurse into arrays when constructing Target The `Distance` module does not compare array elements, so the `Target` constructor should not replace removed elements with `UNDEFINED` Change-type: patch --- lib/distance.ts | 5 ++--- lib/target.spec.ts | 11 +++++++++++ lib/target.ts | 4 ++++ tests/orchestrator/planning.spec.ts | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/distance.ts b/lib/distance.ts index 697ac64..ed241e1 100644 --- a/lib/distance.ts +++ b/lib/distance.ts @@ -138,9 +138,8 @@ function* getOperations( * Calculates the list of changes between the current state and the target */ export function diff(s: S, t: Target): Array> { - return [...getOperations(s, t)] - .filter(({ isLeaf }) => isLeaf) - .map(({ isLeaf, ...op }) => op); + const ops = [...getOperations(s, t)]; + return ops.filter(({ isLeaf }) => isLeaf).map(({ isLeaf, ...op }) => op); } function from(src: S, tgt: Target): Distance { diff --git a/lib/target.spec.ts b/lib/target.spec.ts index 3b6cf50..88ac5d5 100644 --- a/lib/target.spec.ts +++ b/lib/target.spec.ts @@ -66,5 +66,16 @@ describe('Target', () => { g: { h: 'hello' }, }); }); + + it('does not iterate into arrays', () => { + type S = { + a?: string[]; + }; + + const state: S = { a: ['foo', 'bar'] }; + expect(Target.from(state, {})).to.deep.equal({ a: UNDEFINED }); + expect(Target.from(state, { a: ['foo'] })).to.deep.equal({ a: ['foo'] }); + expect(Target.from(state, { a: ['bar'] })).to.deep.equal({ a: ['bar'] }); + }); }); }); diff --git a/lib/target.ts b/lib/target.ts index 5ab85e1..28a0d52 100644 --- a/lib/target.ts +++ b/lib/target.ts @@ -55,6 +55,10 @@ function from( while (queue.length > 0) { const { s, t, p } = queue.shift()!; + // Don't recurse into arrays + if (Array.isArray(s) || Array.isArray(t)) { + continue; + } for (const key of Object.keys(s)) { if (key in t && t[key] === undefined && s[key] !== undefined) { t[key] = UNDEFINED; diff --git a/tests/orchestrator/planning.spec.ts b/tests/orchestrator/planning.spec.ts index 744265f..e3c99ac 100644 --- a/tests/orchestrator/planning.spec.ts +++ b/tests/orchestrator/planning.spec.ts @@ -120,7 +120,7 @@ describe('orchestrator/planning', () => { }, }, keys: {}, - images: [{ name: 'a0_main:r0' }], + images: { 'a0_main:r0': { name: 'alpine:latest' } }, }; const result = planner.findPlan(device, {