From e30793b5be3646c31b68484593fa847e82d60fe9 Mon Sep 17 00:00:00 2001 From: Chris Wegrzyn Date: Thu, 23 May 2024 08:48:23 -0400 Subject: [PATCH] ProgressTrack: enforce upper/lower bound when using advancement methods (#77) Fixes #64 --- src/tracks/progress.test.ts | 4 ++++ src/tracks/progress.ts | 16 +++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/tracks/progress.test.ts b/src/tracks/progress.test.ts index c0b1c312..bcdb674a 100644 --- a/src/tracks/progress.test.ts +++ b/src/tracks/progress.test.ts @@ -74,6 +74,10 @@ describe("ProgressTrack", () => { expect(track.advancedByTicks(10)).toBe(track); }); + it("won't advance negatively below 0 ticks", () => { + expect(make({ progress: 1 }).advancedByTicks(-2).progress).toBe(0); + }); + it("won't advance past 40 ticks", () => { expect(make({ progress: 39 }).advancedByTicks(2).progress).toBe(40); }); diff --git a/src/tracks/progress.ts b/src/tracks/progress.ts index b33ceb6d..add23550 100644 --- a/src/tracks/progress.ts +++ b/src/tracks/progress.ts @@ -164,26 +164,24 @@ export class ProgressTrack { return Math.ceil(this.ticksRemaining / this.ticksPerStep); } + /** Set the meter directly to a specific number of ticks, ensuring legal range for this meter. */ withTicks(ticks: number): ProgressTrack { - const newProgress = Math.min( - this.unbounded ? Number.MAX_SAFE_INTEGER : MAX_TICKS, - ticks, + const newProgress = Math.max( + 0, + Math.min(this.unbounded ? Number.MAX_SAFE_INTEGER : MAX_TICKS, ticks), ); if (this.complete || newProgress === this.progress) return this; return new ProgressTrack({ ...this, progress: newProgress }); } + /** Advance the meter by `steps`, ensuring legal range for this meter. */ advanced(steps: number): ProgressTrack { return this.advancedByTicks(steps * this.ticksPerStep); } + /** Advance the meter by `ticks`, ensuring legal range for this meter. */ advancedByTicks(ticks: number): ProgressTrack { - const newProgress = Math.min( - this.unbounded ? Number.MAX_SAFE_INTEGER : MAX_TICKS, - this.progress + ticks, - ); - if (this.complete || newProgress === this.progress) return this; - return new ProgressTrack({ ...this, progress: newProgress }); + return this.withTicks(this.progress + ticks); } completed(): ProgressTrack {