fix: a chapter's first mile-marker post no longer arrives late
This commit is contained in:
@@ -9,6 +9,8 @@ import {
|
||||
MILESTONE_ASSIGN_Z,
|
||||
MILESTONE_FAR_Z,
|
||||
MILESTONE_FLASH_MAX_RATE,
|
||||
MILESTONE_LATE_ASSIGN_Z,
|
||||
|
||||
MILESTONE_NEAR_Z,
|
||||
MILESTONE_PASS_Z,
|
||||
MILESTONE_SIDE,
|
||||
@@ -200,7 +202,53 @@ describe('mile markers on the road', () => {
|
||||
expect(seen.filter((pass) => pass.reverse).map((pass) => pass.entry)).toEqual([2, 1, 0]);
|
||||
});
|
||||
|
||||
it('only hands an entry to a post still far up the road, in the haze', () => {
|
||||
it('does not keep the first entry waiting when the reader starts scrolling at the heading', () => {
|
||||
for (const [section, rate, speed] of [
|
||||
['profile', 0.03, 18],
|
||||
['profile', 0.05, 18],
|
||||
['experience', 0.03, 18],
|
||||
['experience', 0.05, 25],
|
||||
] as const) {
|
||||
const count = MILESTONE_COUNTS[section];
|
||||
for (const lead of [0, 0.4, 1.7, 2.9]) {
|
||||
const road = createMilestoneRoad(true);
|
||||
// Cruising through the chapter before, then straight into reading from the heading.
|
||||
const state = drive(road, 3 + lead, () => ({ section: 'start', p: null, speed }));
|
||||
const seen: Array<{ entry: number; p: number }> = [];
|
||||
let last: readonly number[] = road.posts().map((post) => post.z);
|
||||
drive(road, 1 / rate, (t) => ({ section, p: Math.min(1, t * rate), speed }), state, (posts, _t, p) => {
|
||||
posts.forEach((post, k) => {
|
||||
if (post.entry >= 0 && post.presence > 0 && last[k]! < MILESTONE_PASS_Z && post.z >= MILESTONE_PASS_Z) {
|
||||
seen.push({ entry: post.entry, p: p! });
|
||||
}
|
||||
});
|
||||
last = posts.map((post) => post.z);
|
||||
});
|
||||
expect(seen[0]?.entry).toBe(0);
|
||||
// Within a post's spacing of the line (the road brings one every 60 m); it used to be up to two entries late.
|
||||
expect(Math.abs(seen[0]!.p - passPoint(0, count))).toBeLessThan(0.4 / count);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('sends the opening entry by soon when the reader stays at the heading', () => {
|
||||
for (const lead of [0, 0.4, 1.7, 2.9]) {
|
||||
const road = createMilestoneRoad(true);
|
||||
const state = drive(road, 3 + lead, () => ({ section: 'start', p: null, speed: 18 }));
|
||||
let first = Number.POSITIVE_INFINITY;
|
||||
let last: readonly number[] = road.posts().map((post) => post.z);
|
||||
drive(road, 12, () => ({ section: 'profile', p: 0, speed: 18 }), state, (posts, t) => {
|
||||
posts.forEach((post, k) => {
|
||||
if (post.entry === 0 && post.presence > 0 && last[k]! < MILESTONE_PASS_Z && post.z >= MILESTONE_PASS_Z) first = Math.min(first, t);
|
||||
});
|
||||
last = posts.map((post) => post.z);
|
||||
});
|
||||
// A post already on the road, not one from the haze (~8.5 s at this speed).
|
||||
expect(first).toBeLessThan(6.5);
|
||||
}
|
||||
});
|
||||
|
||||
it('only hands an entry to a post still far up the road, or to a dark one as a chapter begins', () => {
|
||||
const road = createMilestoneRoad(true);
|
||||
const born = new Map<number, number>();
|
||||
drive(road, 30, (t) => ({ section: 'experience', p: Math.min(1, t * 0.03), speed: 30 }), { distance: 0 }, (posts) => {
|
||||
@@ -209,7 +257,10 @@ describe('mile markers on the road', () => {
|
||||
});
|
||||
});
|
||||
expect(born.size).toBeGreaterThan(0);
|
||||
for (const z of born.values()) expect(z).toBeLessThan(MILESTONE_ASSIGN_Z);
|
||||
// The opening entry may go to a nearer post that was still dark; every later one comes from the haze.
|
||||
const zs = [...born.values()];
|
||||
expect(zs[0]!).toBeLessThan(MILESTONE_LATE_ASSIGN_Z);
|
||||
for (const z of zs.slice(1)) expect(z).toBeLessThan(MILESTONE_ASSIGN_Z);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user