when-am-i / files / src / utils / lanes.test.ts
lanes.test.ts
| 1 | import { describe, it, expect } from 'vitest'; |
| 2 | import { assignLanes } from './lanes'; |
| 3 | |
| 4 | interface Span { start: number; end: number; } |
| 5 | const lane = (spans: Span[]) => |
| 6 | assignLanes(spans, (s) => s.start, (s) => s.end); |
| 7 | |
| 8 | describe('assignLanes', () => { |
| 9 | it('puts non-overlapping, adjacent intervals in the same lane', () => { |
| 10 | const { lanes, count } = lane([ |
| 11 | { start: 1630, end: 1752 }, |
| 12 | { start: 1752, end: Infinity }, // half-open: shares the lane |
| 13 | ]); |
| 14 | expect(count).toBe(1); |
| 15 | expect(lanes.map((l) => l.lane)).toEqual([0, 0]); |
| 16 | }); |
| 17 | |
| 18 | it('puts overlapping intervals in separate lanes', () => { |
| 19 | const { lanes, count } = lane([ |
| 20 | { start: -Infinity, end: Infinity }, // spans everything |
| 21 | { start: 1630, end: 1752 }, |
| 22 | { start: 1752, end: Infinity }, |
| 23 | ]); |
| 24 | expect(count).toBe(2); |
| 25 | // The all-spanning interval gets its own lane; the two adjacent ones share the other. |
| 26 | const byOrder = lanes.sort((a, b) => a.item.start - b.item.start).map((l) => l.lane); |
| 27 | expect(byOrder[0]).not.toBe(byOrder[1]); // spanning vs 1630 |
| 28 | expect(byOrder[1]).toBe(byOrder[2]); // 1630 and 1752 share |
| 29 | }); |
| 30 | |
| 31 | it('opens a third lane when three intervals overlap at once', () => { |
| 32 | const { count } = lane([ |
| 33 | { start: 0, end: 10 }, |
| 34 | { start: 5, end: 15 }, |
| 35 | { start: 8, end: 20 }, |
| 36 | ]); |
| 37 | expect(count).toBe(3); |
| 38 | }); |
| 39 | }); |