Skip to content

Commit 44a8ebd

Browse files
committed
add RangeList tests
1 parent 622763d commit 44a8ebd

File tree

2 files changed

+100
-12
lines changed

2 files changed

+100
-12
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { describe, it, expect } from "vitest";
2+
import { RangeList } from "./RangeList";
3+
4+
describe("RangeList", () => {
5+
it("should add a single range", () => {
6+
const rangeList = new RangeList();
7+
rangeList.add(1, 100);
8+
9+
const ranges = rangeList.getAllRanges();
10+
expect(ranges).toHaveLength(1);
11+
expect(ranges[0]).toEqual({
12+
start: 1,
13+
end: 100,
14+
refCount: 1,
15+
data: null,
16+
});
17+
});
18+
19+
it("should handle overlapping ranges", () => {
20+
const rangeList = new RangeList();
21+
rangeList.add(1, 100);
22+
rangeList.add(30, 50);
23+
24+
const ranges = rangeList.getAllRanges();
25+
expect(ranges).toHaveLength(3);
26+
expect(ranges).toEqual([
27+
{ start: 1, end: 30, refCount: 1, data: null },
28+
{ start: 30, end: 50, refCount: 2, data: null },
29+
{ start: 50, end: 100, refCount: 1, data: null },
30+
]);
31+
});
32+
33+
it("should remove a range at existing boundaries", () => {
34+
const rangeList = new RangeList();
35+
rangeList.add(1, 100);
36+
rangeList.add(30, 50);
37+
rangeList.remove(30, 50);
38+
39+
const ranges = rangeList.getAllRanges();
40+
expect(ranges).toHaveLength(3);
41+
expect(ranges).toEqual([
42+
{ start: 1, end: 30, refCount: 1, data: null },
43+
{ start: 30, end: 50, refCount: 1, data: null },
44+
{ start: 50, end: 100, refCount: 1, data: null },
45+
]);
46+
});
47+
48+
it("should throw error when removing range at non-existing boundaries", () => {
49+
const rangeList = new RangeList();
50+
rangeList.add(1, 100);
51+
rangeList.add(30, 50);
52+
53+
expect(() => rangeList.remove(2, 50)).toThrow("Range boundaries must match existing boundaries");
54+
});
55+
56+
it("should get ranges within boundaries", () => {
57+
const rangeList = new RangeList();
58+
rangeList.add(1, 100);
59+
rangeList.add(30, 50);
60+
61+
const ranges = rangeList.getRanges(30, 100);
62+
expect(ranges).toHaveLength(2);
63+
expect(ranges).toEqual([
64+
{ start: 30, end: 50, refCount: 2, data: null },
65+
{ start: 50, end: 100, refCount: 1, data: null },
66+
]);
67+
});
68+
69+
it("should throw error when end is less than or equal to start", () => {
70+
const rangeList = new RangeList();
71+
72+
expect(() => rangeList.add(100, 1)).toThrow("End must be greater than start");
73+
expect(() => rangeList.add(1, 1)).toThrow("End must be greater than start");
74+
expect(() => rangeList.remove(100, 1)).toThrow("End must be greater than start");
75+
expect(() => rangeList.remove(1, 1)).toThrow("End must be greater than start");
76+
expect(() => rangeList.getRanges(100, 1)).toThrow("End must be greater than start");
77+
expect(() => rangeList.getRanges(1, 1)).toThrow("End must be greater than start");
78+
});
79+
80+
it("should handle multiple overlapping ranges", () => {
81+
const rangeList = new RangeList();
82+
rangeList.add(1, 100);
83+
rangeList.add(30, 50);
84+
rangeList.add(40, 60);
85+
86+
const ranges = rangeList.getAllRanges();
87+
expect(ranges).toHaveLength(5);
88+
expect(ranges).toEqual([
89+
{ start: 1, end: 30, refCount: 1, data: null },
90+
{ start: 30, end: 40, refCount: 2, data: null },
91+
{ start: 40, end: 50, refCount: 3, data: null },
92+
{ start: 50, end: 60, refCount: 2, data: null },
93+
{ start: 60, end: 100, refCount: 1, data: null },
94+
]);
95+
});
96+
});

packages/hub/src/utils/RangeList.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* I want to be able to associate data to each range. And I want to be able to get the ranges inside boundaries. For example , with [1, 30], [30, 50] * 2, [50, 100] configuration
1717
*
1818
* - getting [30, 100] => I receive [30, 50] * 2, [50, 100], and I can get / modify the data assocaited to each range by accessing their data prop. Note the "*2" is just the ref counter, there is onlly one range object for the interval returned
19-
* - getting [2, 50] => error because "2" is not a boundary
19+
* - getting [2, 50] => I get [30, 50] * 2
2020
*
2121
* ----
2222
*
@@ -45,7 +45,7 @@ export class RangeList<T> {
4545
const overlappingRanges: { index: number; range: Range<T> }[] = [];
4646
for (let i = 0; i < this.ranges.length; i++) {
4747
const range = this.ranges[i];
48-
if (start <= range.end && end >= range.start) {
48+
if (start < range.end && end > range.start) {
4949
overlappingRanges.push({ index: i, range });
5050
}
5151
if (range.data !== null) {
@@ -134,7 +134,7 @@ export class RangeList<T> {
134134
const affectedRanges: { index: number; range: Range<T> }[] = [];
135135
for (let i = 0; i < this.ranges.length; i++) {
136136
const range = this.ranges[i];
137-
if (start <= range.end && end >= range.start) {
137+
if (start < range.end && end > range.start) {
138138
affectedRanges.push({ index: i, range });
139139
}
140140
}
@@ -167,15 +167,7 @@ export class RangeList<T> {
167167
throw new TypeError("End must be greater than start");
168168
}
169169

170-
// Find ranges that overlap with the requested boundaries
171-
const result: Range<T>[] = [];
172-
for (const range of this.ranges) {
173-
if (start <= range.end && end >= range.start) {
174-
result.push(range);
175-
}
176-
}
177-
178-
return result;
170+
return this.ranges.filter((range) => start < range.end && end > range.start);
179171
}
180172

181173
/**

0 commit comments

Comments
 (0)