Skip to content

Commit 2f99bc6

Browse files
committed
refactor: migrate to bun test, add integration tests, reorganize sources
- Replace jest with bun test - Remove meaningless mock tests (main.test.ts, __fixtures__/) - Add full pipeline integration test (physics + font + SVG) - Move source files from src/server/ to src/ root - Move font to public/ directory - Remove rollup-plugin-copy dependency - Update rollup config and jest config - Update dist bundle
1 parent 6566bc2 commit 2f99bc6

16 files changed

Lines changed: 148 additions & 245 deletions

‎__fixtures__/core.ts‎

Lines changed: 0 additions & 10 deletions
This file was deleted.

‎__tests__/integration.test.ts‎

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/**
2+
* Integration test: full pipeline from gensvg → physics → font loading → SVG output.
3+
*/
4+
import { afterEach, beforeEach, describe, expect, it, mock } from 'bun:test'
5+
6+
function mockContributionsResponse() {
7+
return {
8+
total: 7,
9+
contributions: [
10+
[
11+
{ date: '2026-07-19', intensity: 1, count: 1 },
12+
{ date: '2026-07-20', intensity: 2, count: 5 },
13+
{ date: '2026-07-21', intensity: 3, count: 10 },
14+
{ date: '2026-07-22', intensity: 0, count: 0 },
15+
{ date: '2026-07-23', intensity: 4, count: 20 },
16+
{ date: '2026-07-24', intensity: 1, count: 3 },
17+
{ date: '2026-07-25', intensity: 2, count: 7 }
18+
]
19+
]
20+
}
21+
}
22+
23+
const mockFetchContributions = mock(async () => mockContributionsResponse())
24+
mock.module('../src/github-contributions.ts', () => ({
25+
fetchContributions: mockFetchContributions,
26+
INTENSITY_COLORS: ['#ebedf0', '#9be9a8', '#40c463', '#30a14e', '#216e39']
27+
}))
28+
29+
const { gensvg } = await import('../src/gensvg.js')
30+
31+
describe('full pipeline integration', () => {
32+
beforeEach(() => {
33+
mockFetchContributions.mockImplementation(async () =>
34+
mockContributionsResponse()
35+
)
36+
})
37+
38+
afterEach(() => {
39+
mockFetchContributions.mockReset()
40+
})
41+
42+
it('generates a valid SVG with contributions and text paths', async () => {
43+
const svg = await gensvg({
44+
username: 'testuser',
45+
text: 'Hi',
46+
fontSize: 40,
47+
sampleRate: 4,
48+
shape: 'circle'
49+
})
50+
51+
expect(typeof svg).toBe('string')
52+
expect(svg).toContain('<svg')
53+
expect(svg).toContain('xmlns="http://www.w3.org/2000/svg"')
54+
expect(svg).toContain('</svg>')
55+
expect(svg).toContain('<circle')
56+
expect(svg).toContain('animateTransform')
57+
expect(svg).toContain('<path d="')
58+
})
59+
60+
it('generates square-shaped contributions when shape is square', async () => {
61+
const svg = await gensvg({
62+
username: 'testuser',
63+
text: 'Hi',
64+
fontSize: 40,
65+
shape: 'square'
66+
})
67+
68+
expect(svg).toContain('<rect')
69+
expect(svg).not.toContain('<circle')
70+
})
71+
72+
it('handles empty text gracefully', async () => {
73+
const svg = await gensvg({
74+
username: 'testuser',
75+
text: '',
76+
fontSize: 40
77+
})
78+
79+
expect(svg).toContain('<svg')
80+
expect(svg).toContain('</svg')
81+
})
82+
83+
it('throws on invalid username (API error)', async () => {
84+
mockFetchContributions.mockImplementation(async () => {
85+
throw new Error(
86+
'Failed to fetch contributions for "nonexistent": 404 Not Found'
87+
)
88+
})
89+
90+
await expect(
91+
gensvg({ username: 'nonexistent', text: 'Test' })
92+
).rejects.toThrow('Failed to fetch contributions')
93+
})
94+
95+
it('produces deterministic SVG for same inputs', async () => {
96+
const svg1 = await gensvg({
97+
username: 'testuser',
98+
text: 'OK',
99+
fontSize: 30,
100+
shape: 'circle'
101+
})
102+
103+
mockFetchContributions.mockImplementation(async () =>
104+
mockContributionsResponse()
105+
)
106+
107+
const svg2 = await gensvg({
108+
username: 'testuser',
109+
text: 'OK',
110+
fontSize: 30,
111+
shape: 'circle'
112+
})
113+
114+
expect(svg1).toBe(svg2)
115+
})
116+
})

‎__tests__/main.test.ts‎

Lines changed: 0 additions & 126 deletions
This file was deleted.

0 commit comments

Comments
 (0)