Skip to content

Commit 446a601

Browse files
committed
add tests
1 parent cffaba0 commit 446a601

File tree

2 files changed

+158
-2
lines changed

2 files changed

+158
-2
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import type { LineData, UTCTimestamp } from "lightweight-charts";
2+
3+
import { mergeData, startOfResolution } from "./chart";
4+
5+
describe("mergeData", () => {
6+
it("merges two arrays with no overlap", () => {
7+
const a: LineData[] = [
8+
{ time: 1000 as UTCTimestamp, value: 10 },
9+
{ time: 2000 as UTCTimestamp, value: 20 },
10+
];
11+
const b: LineData[] = [
12+
{ time: 3000 as UTCTimestamp, value: 30 },
13+
{ time: 4000 as UTCTimestamp, value: 40 },
14+
];
15+
16+
const result = mergeData(a, b);
17+
18+
expect(result).toEqual([
19+
{ time: 1000, value: 10 },
20+
{ time: 2000, value: 20 },
21+
{ time: 3000, value: 30 },
22+
{ time: 4000, value: 40 },
23+
]);
24+
});
25+
26+
it("deduplicates by time, keeping the second value", () => {
27+
const a: LineData[] = [
28+
{ time: 1000 as UTCTimestamp, value: 10 },
29+
{ time: 2000 as UTCTimestamp, value: 20 },
30+
];
31+
const b: LineData[] = [
32+
{ time: 2000 as UTCTimestamp, value: 99 },
33+
{ time: 3000 as UTCTimestamp, value: 30 },
34+
];
35+
36+
const result = mergeData(a, b);
37+
38+
expect(result).toEqual([
39+
{ time: 1000, value: 10 },
40+
{ time: 2000, value: 99 }, // second value overwrites first
41+
{ time: 3000, value: 30 },
42+
]);
43+
});
44+
45+
it("sorts the merged array by time", () => {
46+
const a: LineData[] = [
47+
{ time: 3000 as UTCTimestamp, value: 30 },
48+
{ time: 1000 as UTCTimestamp, value: 10 },
49+
];
50+
const b: LineData[] = [
51+
{ time: 4000 as UTCTimestamp, value: 40 },
52+
{ time: 2000 as UTCTimestamp, value: 20 },
53+
];
54+
55+
const result = mergeData(a, b);
56+
57+
expect(result).toEqual([
58+
{ time: 1000, value: 10 },
59+
{ time: 2000, value: 20 },
60+
{ time: 3000, value: 30 },
61+
{ time: 4000, value: 40 },
62+
]);
63+
});
64+
65+
it("handles empty first array", () => {
66+
const a: LineData[] = [];
67+
const b: LineData[] = [
68+
{ time: 1000 as UTCTimestamp, value: 10 },
69+
{ time: 2000 as UTCTimestamp, value: 20 },
70+
];
71+
72+
const result = mergeData(a, b);
73+
74+
expect(result).toEqual([
75+
{ time: 1000, value: 10 },
76+
{ time: 2000, value: 20 },
77+
]);
78+
});
79+
80+
it("handles empty second array", () => {
81+
const a: LineData[] = [
82+
{ time: 1000 as UTCTimestamp, value: 10 },
83+
{ time: 2000 as UTCTimestamp, value: 20 },
84+
];
85+
const b: LineData[] = [];
86+
87+
const result = mergeData(a, b);
88+
89+
expect(result).toEqual([
90+
{ time: 1000, value: 10 },
91+
{ time: 2000, value: 20 },
92+
]);
93+
});
94+
95+
it("handles both arrays empty", () => {
96+
const a: LineData[] = [];
97+
const b: LineData[] = [];
98+
99+
const result = mergeData(a, b);
100+
101+
expect(result).toEqual([]);
102+
});
103+
});
104+
105+
describe("startOfResolution", () => {
106+
it("returns start of second for 1s resolution", () => {
107+
const date = new Date("2024-01-15T10:30:45.678Z");
108+
const result = startOfResolution(date, "1s");
109+
110+
expect(result).toBe(new Date("2024-01-15T10:30:45.000Z").getTime());
111+
});
112+
113+
it("returns start of minute for 1m resolution", () => {
114+
const date = new Date("2024-01-15T10:30:45.678Z");
115+
const result = startOfResolution(date, "1m");
116+
117+
expect(result).toBe(new Date("2024-01-15T10:30:00.000Z").getTime());
118+
});
119+
120+
it("returns start of minute for 5m resolution", () => {
121+
const date = new Date("2024-01-15T10:30:45.678Z");
122+
const result = startOfResolution(date, "5m");
123+
124+
expect(result).toBe(new Date("2024-01-15T10:30:00.000Z").getTime());
125+
});
126+
127+
it("returns start of hour for 1H resolution", () => {
128+
const date = new Date("2024-01-15T10:30:45.678Z");
129+
const result = startOfResolution(date, "1H");
130+
131+
expect(result).toBe(new Date("2024-01-15T10:00:00.000Z").getTime());
132+
});
133+
134+
it("returns start of day for 1D resolution", () => {
135+
const date = new Date("2024-01-15T10:30:45.678Z");
136+
const result = startOfResolution(date, "1D");
137+
138+
expect(result).toBe(new Date("2024-01-15T00:00:00.000Z").getTime());
139+
});
140+
141+
it("throws error for unknown resolution", () => {
142+
const date = new Date("2024-01-15T10:30:45.678Z");
143+
144+
expect(() => startOfResolution(date, "15m")).toThrow(
145+
"Unknown resolution: 15m",
146+
);
147+
});
148+
149+
it("throws error for invalid resolution", () => {
150+
const date = new Date("2024-01-15T10:30:45.678Z");
151+
152+
expect(() => startOfResolution(date, "invalid")).toThrow(
153+
"Unknown resolution: invalid",
154+
);
155+
});
156+
});

apps/insights/src/components/PriceFeed/Chart/chart.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ function isLineData(data: LineData | WhitespaceData): data is LineData {
450450
/**
451451
* Merge (and sort) two arrays of line data, deduplicating by time
452452
*/
453-
function mergeData(as: LineData[], bs: LineData[]) {
453+
export function mergeData(as: LineData[], bs: LineData[]) {
454454
const unique = new Map<number, LineData>();
455455

456456
// TODO fhqvst Can optimize with while's
@@ -468,7 +468,7 @@ function mergeData(as: LineData[], bs: LineData[]) {
468468
/**
469469
* Convert a date to the start of the given resolution, i.e. 1s = startOfSecond, 1m = startOfMinute, etc.
470470
*/
471-
function startOfResolution(date: Date, resolution: string) {
471+
export function startOfResolution(date: Date, resolution: string) {
472472
switch (resolution) {
473473
case "1s": {
474474
return startOfSecond(date).getTime();

0 commit comments

Comments
 (0)