From 56af5e35533c43291c3fb6410786f15f4e48adc6 Mon Sep 17 00:00:00 2001 From: Senrokai Date: Tue, 29 Sep 2026 19:30:38 +0200 Subject: [PATCH] Test the clock where CI could not see it: the date field's time zone, a backwards date, a reopened panel Three behaviours of the clock had no test that would fail without them: - "jumps the clock to the date submitted, read as UTC" only told UTC from local time on a machine outside UTC. CI runs on ubuntu-latest, in UTC, where both readings are the same instant, so a field read as local time passed all 805 tests there. The test now sets TZ to Asia/Kolkata (UTC +5:30) itself, and afterEach unstubs it. - Nothing checked that a negative rate moves the date backwards; the dock's test read only the rate's sign. The store now checks that at -86 400 s/s a second of wall clock is a day earlier. - Nothing checked that reopening the Display panel fills the date field with the clock's date, rather than the one it held when the dock was built. Controls, the suite run under TZ=UTC: the field read as local time fails "jumps the clock to the date submitted, read as UTC"; the rate's size taken without its sign fails "runs the date backwards at a negative rate"; toggleTab not refilling the field fails "fills the date field again with the clock's date when the panel is opened again". Co-Authored-By: Claude Opus 5.5 (1M context) --- src/app/features/hud/hud-dock.component.spec.ts | 17 ++++++++++++++++- src/app/shared/state/time.store.spec.ts | 8 ++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/app/features/hud/hud-dock.component.spec.ts b/src/app/features/hud/hud-dock.component.spec.ts index 7b3f361..cd29fda 100644 --- a/src/app/features/hud/hud-dock.component.spec.ts +++ b/src/app/features/hud/hud-dock.component.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Router } from '@angular/router'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { DataLoaderService } from '../../core/data/data-loader.service'; import { BookmarksStore } from '../../shared/state/bookmarks.store'; @@ -378,6 +378,8 @@ describe('HudDockComponent', () => { fixture.detectChanges(); }); + afterEach(() => vi.unstubAllEnvs()); + function button(name: string): HTMLButtonElement { return [...host().querySelectorAll('#dock-panel-display button')].find((b) => b.textContent?.trim() === name)!; } @@ -417,6 +419,9 @@ describe('HudDockComponent', () => { }); it('jumps the clock to the date submitted, read as UTC', () => { + // Five and a half hours from UTC, so a field read as local time lands elsewhere: in UTC itself, + // where CI runs, the two readings are the same instant and this could not tell them apart. + vi.stubEnv('TZ', 'Asia/Kolkata'); const field = host().querySelector('#clock-date')!; field.value = '2020-12-21T18:00'; button('Go').click(); @@ -431,5 +436,15 @@ describe('HudDockComponent', () => { expect(time.atNow()).toBe(true); expect(host().querySelector('#clock-date')!.value).toBe(time.date().toISOString().slice(0, 16)); }); + + it('fills the date field again with the clock’s date when the panel is opened again', () => { + time.setDate(new Date('2020-12-21T18:00Z')); + fixture.componentInstance.toggleTab('display'); + fixture.detectChanges(); + fixture.componentInstance.toggleTab('display'); + fixture.detectChanges(); + + expect(host().querySelector('#clock-date')!.value).toBe('2020-12-21T18:00'); + }); }); }); diff --git a/src/app/shared/state/time.store.spec.ts b/src/app/shared/state/time.store.spec.ts index 9895c92..88bb121 100644 --- a/src/app/shared/state/time.store.spec.ts +++ b/src/app/shared/state/time.store.spec.ts @@ -48,6 +48,14 @@ describe('TimeStore', () => { expect(time.julianDate() - afterTwoDays).toBeLessThan(1 / 24); }); + it('runs the date backwards at a negative rate', () => { + time.setRate(-86_400); + const before = time.julianDate(); + vi.advanceTimersByTime(1000); + + expect(time.julianDate() - before).toBeCloseTo(-1, 9); + }); + it('knows the map is away from now even once it is back at real time', () => { expect(time.atNow()).toBe(true); time.setRate(2_629_800);