From 9363c380bdc7983b4d57f53bdcd0d8a0debed756 Mon Sep 17 00:00:00 2001 From: Travis Prescott Date: Tue, 4 Jun 2024 11:36:49 -0700 Subject: [PATCH] Add test case. --- packages/versioning/src/versioning.ts | 32 +++++++++++++++++---- packages/versioning/test/versioning.test.ts | 31 +++++++++++++++++++- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/packages/versioning/src/versioning.ts b/packages/versioning/src/versioning.ts index 78755ff279..892d85586f 100644 --- a/packages/versioning/src/versioning.ts +++ b/packages/versioning/src/versioning.ts @@ -212,7 +212,7 @@ function getParentAddedVersion( return versions.find((x) => x.name === key); } } - return undefined; + return versions[0]; } function getParentAddedVersionInTimeline( @@ -232,7 +232,16 @@ function getParentAddedVersionInTimeline( return moment.versions().next().value; } } - return undefined; + return timeline.first().versions().next().value; +} + +/** + * Returns true if the first version modifier was @added, false if @removed. + */ +function resolveAddedFirst(added: Version[], removed: Version[]): boolean { + if (added.length === 0) return false; + if (removed.length === 0) return true; + return added[0].index < removed[0].index; } export function getAvailabilityMap( @@ -261,9 +270,15 @@ export function getAvailabilityMap( ) return undefined; + const wasAddedFirst = resolveAddedFirst(added, removed); + // implicitly, all versioned things are assumed to have been added at // v1 if not specified, or inherited from their parent. - if (!added.length && !parentAdded) { + if (!wasAddedFirst && !parentAdded) { + // if the first version modifier was @removed, and the parent is implicitly available, + // then assume the type was available. + added = [allVersions[0], ...added]; + } else if (!added.length && !parentAdded) { // no version information on the item or its parent implicitly means it has always been available added.push(allVersions[0]); } else if (!added.length && parentAdded) { @@ -317,11 +332,18 @@ export function getAvailabilityMapInTimeline( ) return undefined; + const wasAddedFirst = resolveAddedFirst(added, removed); + // implicitly, all versioned things are assumed to have been added at // v1 if not specified, or inherited from their parent. - if (!added.length && !parentAdded) { + const firstVersion = timeline.first().versions().next().value; + if (!wasAddedFirst && !parentAdded) { + // if the first version modifier was @removed, and the parent is implicitly available, + // then assume the type was available. + added = [firstVersion, ...added]; + } else if (!added.length && !parentAdded) { // no version information on the item or its parent implicitly means it has always been available - added.push(timeline.first().versions().next().value); + added.push(firstVersion); } else if (!added.length && parentAdded) { // if no version info on type but is on parent, inherit that parent's "added" version added.push(parentAdded); diff --git a/packages/versioning/test/versioning.test.ts b/packages/versioning/test/versioning.test.ts index 17cefbe3eb..e2635e891f 100644 --- a/packages/versioning/test/versioning.test.ts +++ b/packages/versioning/test/versioning.test.ts @@ -281,7 +281,7 @@ describe("versioning: logic", () => { ); }); - it("can be removed respecting model versioning", async () => { + it("can be removed respecting model versioning with explicit versions", async () => { const { source, projections: [v2, v3, v4], @@ -311,6 +311,35 @@ describe("versioning: logic", () => { ); }); + it("can be removed respecting model versioning with implicit versions", async () => { + const { + source, + projections: [v1, v2, v3], + } = await versionedModel( + ["v1", "v2", "v3"], + `model Test { + a: int32; + @removed(Versions.v2) + @added(Versions.v3) + b: int32; + } + ` + ); + + assertHasProperties(v1, ["a", "b"]); + assertHasProperties(v2, ["a"]); + assertHasProperties(v3, ["a", "b"]); + + assertModelProjectsTo( + [ + [v1, "v1"], + [v2, "v2"], + [v3, "v3"], + ], + source + ); + }); + it("can be renamed", async () => { const { source,