Skip to content

Commit 6cfb647

Browse files
CopilotoBusk
andcommitted
Add comparison generation logic with tests
Co-authored-by: oBusk <13413409+oBusk@users.noreply.github.com>
1 parent 5db77bf commit 6cfb647

2 files changed

Lines changed: 407 additions & 0 deletions

File tree

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
import { generateComparisons } from "./generateComparisons";
2+
3+
describe("generateComparisons", () => {
4+
it("returns empty array for package with 0 versions", () => {
5+
const result = generateComparisons([], {});
6+
expect(result).toEqual([]);
7+
});
8+
9+
it("returns empty array for package with 1 version", () => {
10+
const versions = ["1.0.0"];
11+
const versionMap = { "1.0.0": { time: "2020-01-01" } };
12+
const result = generateComparisons(versions, versionMap);
13+
expect(result).toEqual([]);
14+
});
15+
16+
it("generates exactly 10 comparisons for a package with many versions", () => {
17+
const versions = [
18+
"1.0.0",
19+
"1.0.1",
20+
"1.1.0",
21+
"1.1.1",
22+
"2.0.0",
23+
"2.0.1",
24+
"2.1.0",
25+
"2.1.1",
26+
"3.0.0",
27+
"3.0.1",
28+
"3.1.0",
29+
"3.1.1",
30+
"3.1.2",
31+
"3.1.3",
32+
"3.1.4",
33+
"3.1.5",
34+
];
35+
const versionMap: Record<string, { time: string }> = {};
36+
versions.forEach((v, i) => {
37+
versionMap[v] = { time: `2020-01-${String(i + 1).padStart(2, "0")}` };
38+
});
39+
40+
const result = generateComparisons(versions, versionMap);
41+
expect(result).toHaveLength(10);
42+
});
43+
44+
it("identifies major bumps correctly", () => {
45+
const versions = [
46+
"1.0.0",
47+
"1.9.4",
48+
"2.0.0",
49+
"2.5.0",
50+
"3.0.0",
51+
"3.1.0",
52+
];
53+
const versionMap: Record<string, { time: string }> = {
54+
"1.0.0": { time: "2020-01-01" },
55+
"1.9.4": { time: "2020-06-01" },
56+
"2.0.0": { time: "2020-07-01" },
57+
"2.5.0": { time: "2020-12-01" },
58+
"3.0.0": { time: "2021-01-01" },
59+
"3.1.0": { time: "2021-02-01" },
60+
};
61+
62+
const result = generateComparisons(versions, versionMap);
63+
64+
// Should include major bumps: 3.0.0 vs 2.5.0, 2.0.0 vs 1.9.4
65+
const majorBumps = result.filter((c) => c.type === "major");
66+
expect(majorBumps.length).toBeGreaterThan(0);
67+
expect(majorBumps).toContainEqual({
68+
from: "2.5.0",
69+
to: "3.0.0",
70+
type: "major",
71+
});
72+
expect(majorBumps).toContainEqual({
73+
from: "1.9.4",
74+
to: "2.0.0",
75+
type: "major",
76+
});
77+
});
78+
79+
it("identifies minor bumps correctly", () => {
80+
const versions = ["2.0.0", "2.0.12", "2.1.0", "2.1.3", "2.2.0"];
81+
const versionMap: Record<string, { time: string }> = {
82+
"2.0.0": { time: "2020-01-01" },
83+
"2.0.12": { time: "2020-06-01" },
84+
"2.1.0": { time: "2020-07-01" },
85+
"2.1.3": { time: "2020-12-01" },
86+
"2.2.0": { time: "2021-01-01" },
87+
};
88+
89+
const result = generateComparisons(versions, versionMap);
90+
91+
const minorBumps = result.filter((c) => c.type === "minor");
92+
expect(minorBumps.length).toBeGreaterThan(0);
93+
expect(minorBumps).toContainEqual({
94+
from: "2.1.3",
95+
to: "2.2.0",
96+
type: "minor",
97+
});
98+
expect(minorBumps).toContainEqual({
99+
from: "2.0.12",
100+
to: "2.1.0",
101+
type: "minor",
102+
});
103+
});
104+
105+
it("identifies patch bumps correctly", () => {
106+
const versions = ["2.1.3", "2.1.4", "2.1.5", "2.1.6"];
107+
const versionMap: Record<string, { time: string }> = {
108+
"2.1.3": { time: "2020-01-01" },
109+
"2.1.4": { time: "2020-02-01" },
110+
"2.1.5": { time: "2020-03-01" },
111+
"2.1.6": { time: "2020-04-01" },
112+
};
113+
114+
const result = generateComparisons(versions, versionMap);
115+
116+
const patchBumps = result.filter((c) => c.type === "patch");
117+
expect(patchBumps.length).toBeGreaterThan(0);
118+
expect(patchBumps).toContainEqual({
119+
from: "2.1.5",
120+
to: "2.1.6",
121+
type: "patch",
122+
});
123+
});
124+
125+
it("returns fewer than 10 comparisons for packages with few versions", () => {
126+
const versions = ["1.0.0", "1.0.1", "1.0.2"];
127+
const versionMap: Record<string, { time: string }> = {
128+
"1.0.0": { time: "2020-01-01" },
129+
"1.0.1": { time: "2020-02-01" },
130+
"1.0.2": { time: "2020-03-01" },
131+
};
132+
133+
const result = generateComparisons(versions, versionMap);
134+
expect(result.length).toBeLessThanOrEqual(2);
135+
});
136+
137+
it("backfills from majors when not enough minor/patch bumps", () => {
138+
const versions = [
139+
"1.0.0",
140+
"2.0.0",
141+
"3.0.0",
142+
"4.0.0",
143+
"5.0.0",
144+
"6.0.0",
145+
"7.0.0",
146+
"8.0.0",
147+
"9.0.0",
148+
"10.0.0",
149+
"11.0.0",
150+
];
151+
const versionMap: Record<string, { time: string }> = {};
152+
versions.forEach((v, i) => {
153+
versionMap[v] = { time: `2020-${String(i + 1).padStart(2, "0")}-01` };
154+
});
155+
156+
const result = generateComparisons(versions, versionMap);
157+
158+
// Should have 10 major bumps (since there are no minor/patch bumps)
159+
expect(result).toHaveLength(10);
160+
const majorBumps = result.filter((c) => c.type === "major");
161+
expect(majorBumps.length).toBe(10);
162+
});
163+
164+
it("sorts comparisons by publish date (newest first)", () => {
165+
const versions = ["1.0.0", "1.0.1", "2.0.0", "2.0.1"];
166+
const versionMap: Record<string, { time: string }> = {
167+
"1.0.0": { time: "2020-01-01" },
168+
"1.0.1": { time: "2020-02-01" },
169+
"2.0.0": { time: "2020-03-01" },
170+
"2.0.1": { time: "2020-04-01" },
171+
};
172+
173+
const result = generateComparisons(versions, versionMap);
174+
175+
// Should be sorted by the "to" version's publish date, newest first
176+
for (let i = 0; i < result.length - 1; i++) {
177+
const timeA = versionMap[result[i].to].time;
178+
const timeB = versionMap[result[i + 1].to].time;
179+
expect(timeA >= timeB).toBe(true);
180+
}
181+
});
182+
183+
it("handles versions with prerelease tags", () => {
184+
const versions = [
185+
"1.0.0",
186+
"1.0.1",
187+
"2.0.0-beta.1",
188+
"2.0.0",
189+
"2.0.1",
190+
];
191+
const versionMap: Record<string, { time: string }> = {};
192+
versions.forEach((v, i) => {
193+
versionMap[v] = { time: `2020-01-${String(i + 1).padStart(2, "0")}` };
194+
});
195+
196+
const result = generateComparisons(versions, versionMap);
197+
198+
// Should include all valid semver versions, including prereleases
199+
expect(result.length).toBeGreaterThan(0);
200+
result.forEach((comparison) => {
201+
expect(comparison.from).toBeTruthy();
202+
expect(comparison.to).toBeTruthy();
203+
});
204+
});
205+
});

0 commit comments

Comments
 (0)