git-history-ui 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/build/frontend/index.html +13 -0
- package/build/frontend/main-44CFNHDH.js +8 -0
- package/build/frontend/polyfills-5CFQRCPP.js +2 -0
- package/build/frontend/styles-26JPPBSI.css +1 -0
- package/dist/backend/server.d.ts.map +1 -1
- package/dist/backend/server.js +19 -5
- package/dist/backend/server.js.map +1 -1
- package/package.json +8 -2
- package/.dockerignore +0 -19
- package/.eslintrc.js +0 -21
- package/Dockerfile +0 -29
- package/demo.js +0 -45
- package/frontend/.editorconfig +0 -17
- package/frontend/.vscode/extensions.json +0 -4
- package/frontend/.vscode/launch.json +0 -20
- package/frontend/.vscode/tasks.json +0 -42
- package/frontend/README.md +0 -59
- package/frontend/angular.json +0 -99
- package/frontend/package-lock.json +0 -11272
- package/frontend/package.json +0 -58
- package/frontend/postcss.config.js +0 -6
- package/frontend/proxy.conf.json +0 -7
- package/frontend/src/app/app.component.ts +0 -598
- package/frontend/src/app/app.config.ts +0 -12
- package/frontend/src/app/app.css +0 -0
- package/frontend/src/app/app.html +0 -342
- package/frontend/src/app/app.routes.ts +0 -3
- package/frontend/src/app/app.spec.ts +0 -23
- package/frontend/src/app/app.ts +0 -12
- package/frontend/src/app/components/color-palette-selector/color-palette-selector.component.ts +0 -137
- package/frontend/src/app/components/commit-detail/commit-detail.component.ts +0 -327
- package/frontend/src/app/components/commit-graph/commit-graph.component.ts +0 -294
- package/frontend/src/app/components/commit-list/commit-list.component.ts +0 -199
- package/frontend/src/app/components/diff-viewer/diff-viewer.component.ts +0 -311
- package/frontend/src/app/models/color-palette.models.ts +0 -229
- package/frontend/src/app/models/git.models.ts +0 -39
- package/frontend/src/app/services/git.service.ts +0 -43
- package/frontend/src/index.html +0 -13
- package/frontend/src/main.ts +0 -6
- package/frontend/src/styles.css +0 -401
- package/frontend/tailwind.config.js +0 -11
- package/frontend/tsconfig.app.json +0 -15
- package/frontend/tsconfig.json +0 -34
- package/frontend/tsconfig.spec.json +0 -14
- package/jest.config.js +0 -26
- package/src/__tests__/gitService.test.ts +0 -533
- package/src/__tests__/setup.ts +0 -25
- package/src/backend/dev-server.ts +0 -14
- package/src/backend/gitService.ts +0 -277
- package/src/backend/server.ts +0 -140
- package/src/cli.ts +0 -56
- package/tsconfig.json +0 -25
- /package/{frontend/public → build/frontend}/favicon.ico +0 -0
|
@@ -1,533 +0,0 @@
|
|
|
1
|
-
import { GitService } from '../backend/gitService';
|
|
2
|
-
|
|
3
|
-
// Mock simple-git
|
|
4
|
-
const mockGit = {
|
|
5
|
-
log: jest.fn(),
|
|
6
|
-
tags: jest.fn(),
|
|
7
|
-
branch: jest.fn(),
|
|
8
|
-
diff: jest.fn(),
|
|
9
|
-
raw: jest.fn(),
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
jest.mock('simple-git', () => {
|
|
13
|
-
return jest.fn(() => mockGit);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
describe('GitService', () => {
|
|
17
|
-
let gitService: GitService;
|
|
18
|
-
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
gitService = new GitService();
|
|
21
|
-
jest.clearAllMocks();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
describe('getCommits', () => {
|
|
25
|
-
it('should return an array of commits', async () => {
|
|
26
|
-
const mockCommits = [
|
|
27
|
-
{
|
|
28
|
-
hash: 'abc123',
|
|
29
|
-
date: '2024-01-01',
|
|
30
|
-
message: 'Test commit',
|
|
31
|
-
author_name: 'Test Author',
|
|
32
|
-
author_email: 'test@example.com',
|
|
33
|
-
refs: 'HEAD -> main',
|
|
34
|
-
body: '',
|
|
35
|
-
hash_abbrev: 'abc123',
|
|
36
|
-
tree: 'def456',
|
|
37
|
-
tree_abbrev: 'def456',
|
|
38
|
-
parent: 'ghi789',
|
|
39
|
-
parent_abbrev: 'ghi789'
|
|
40
|
-
}
|
|
41
|
-
];
|
|
42
|
-
|
|
43
|
-
mockGit.log.mockResolvedValue({ all: mockCommits });
|
|
44
|
-
mockGit.diff.mockResolvedValue('');
|
|
45
|
-
mockGit.branch.mockResolvedValue({ all: ['main'] });
|
|
46
|
-
mockGit.raw.mockResolvedValue('');
|
|
47
|
-
|
|
48
|
-
const commits = await gitService.getCommits();
|
|
49
|
-
|
|
50
|
-
expect(Array.isArray(commits)).toBe(true);
|
|
51
|
-
expect(commits.length).toBeGreaterThan(0);
|
|
52
|
-
expect(commits[0]).toHaveProperty('hash');
|
|
53
|
-
expect(commits[0]).toHaveProperty('author');
|
|
54
|
-
expect(commits[0]).toHaveProperty('date');
|
|
55
|
-
expect(commits[0]).toHaveProperty('message');
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it('should respect the limit parameter', async () => {
|
|
59
|
-
const mockCommits = Array(3).fill(null).map((_, i) => ({
|
|
60
|
-
hash: `hash${i}`,
|
|
61
|
-
date: '2024-01-01',
|
|
62
|
-
message: `Commit ${i}`,
|
|
63
|
-
author_name: 'Test Author',
|
|
64
|
-
author_email: 'test@example.com',
|
|
65
|
-
refs: 'HEAD -> main',
|
|
66
|
-
body: '',
|
|
67
|
-
hash_abbrev: `hash${i}`,
|
|
68
|
-
tree: 'def456',
|
|
69
|
-
tree_abbrev: 'def456',
|
|
70
|
-
parent: 'ghi789',
|
|
71
|
-
parent_abbrev: 'ghi789'
|
|
72
|
-
}));
|
|
73
|
-
|
|
74
|
-
mockGit.log.mockResolvedValue({ all: mockCommits });
|
|
75
|
-
|
|
76
|
-
const commits = await gitService.getCommits({ limit: 3 });
|
|
77
|
-
|
|
78
|
-
// The GitService should respect the limit parameter
|
|
79
|
-
expect(commits.length).toBe(3);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('should handle git log errors', async () => {
|
|
83
|
-
mockGit.log.mockRejectedValue(new Error('Git error'));
|
|
84
|
-
|
|
85
|
-
await expect(gitService.getCommits()).rejects.toThrow('Git error');
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('should handle empty commit list', async () => {
|
|
89
|
-
mockGit.log.mockResolvedValue({ all: [] });
|
|
90
|
-
|
|
91
|
-
const commits = await gitService.getCommits();
|
|
92
|
-
|
|
93
|
-
expect(Array.isArray(commits)).toBe(true);
|
|
94
|
-
expect(commits.length).toBe(0);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('should handle file filter option', async () => {
|
|
98
|
-
const mockCommits = [
|
|
99
|
-
{
|
|
100
|
-
hash: 'abc123',
|
|
101
|
-
date: '2024-01-01',
|
|
102
|
-
message: 'Test commit',
|
|
103
|
-
author_name: 'Test Author',
|
|
104
|
-
author_email: 'test@example.com',
|
|
105
|
-
refs: 'HEAD -> main',
|
|
106
|
-
body: '',
|
|
107
|
-
hash_abbrev: 'abc123',
|
|
108
|
-
tree: 'def456',
|
|
109
|
-
tree_abbrev: 'def456',
|
|
110
|
-
parent: 'ghi789',
|
|
111
|
-
parent_abbrev: 'ghi789'
|
|
112
|
-
}
|
|
113
|
-
];
|
|
114
|
-
|
|
115
|
-
mockGit.log.mockResolvedValue({ all: mockCommits });
|
|
116
|
-
|
|
117
|
-
const commits = await gitService.getCommits({ file: 'src/app.js' });
|
|
118
|
-
|
|
119
|
-
expect(Array.isArray(commits)).toBe(true);
|
|
120
|
-
expect(commits.length).toBeGreaterThan(0);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('should handle since filter option', async () => {
|
|
124
|
-
const mockCommits = [
|
|
125
|
-
{
|
|
126
|
-
hash: 'abc123',
|
|
127
|
-
date: '2024-01-01',
|
|
128
|
-
message: 'Test commit',
|
|
129
|
-
author_name: 'Test Author',
|
|
130
|
-
author_email: 'test@example.com',
|
|
131
|
-
refs: 'HEAD -> main',
|
|
132
|
-
body: '',
|
|
133
|
-
hash_abbrev: 'abc123',
|
|
134
|
-
tree: 'def456',
|
|
135
|
-
tree_abbrev: 'def456',
|
|
136
|
-
parent: 'ghi789',
|
|
137
|
-
parent_abbrev: 'ghi789'
|
|
138
|
-
}
|
|
139
|
-
];
|
|
140
|
-
|
|
141
|
-
mockGit.log.mockResolvedValue({ all: mockCommits });
|
|
142
|
-
|
|
143
|
-
const commits = await gitService.getCommits({ since: 'v1.0.0' });
|
|
144
|
-
|
|
145
|
-
expect(Array.isArray(commits)).toBe(true);
|
|
146
|
-
expect(commits.length).toBeGreaterThan(0);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it('should handle author filter option', async () => {
|
|
150
|
-
const mockCommits = [
|
|
151
|
-
{
|
|
152
|
-
hash: 'abc123',
|
|
153
|
-
date: '2024-01-01',
|
|
154
|
-
message: 'Test commit',
|
|
155
|
-
author_name: 'Test Author',
|
|
156
|
-
author_email: 'test@example.com',
|
|
157
|
-
refs: 'HEAD -> main',
|
|
158
|
-
body: '',
|
|
159
|
-
hash_abbrev: 'abc123',
|
|
160
|
-
tree: 'def456',
|
|
161
|
-
tree_abbrev: 'def456',
|
|
162
|
-
parent: 'ghi789',
|
|
163
|
-
parent_abbrev: 'ghi789'
|
|
164
|
-
}
|
|
165
|
-
];
|
|
166
|
-
|
|
167
|
-
mockGit.log.mockResolvedValue({ all: mockCommits });
|
|
168
|
-
mockGit.diff.mockResolvedValue('');
|
|
169
|
-
mockGit.branch.mockResolvedValue({ all: ['main'] });
|
|
170
|
-
mockGit.raw.mockResolvedValue('');
|
|
171
|
-
|
|
172
|
-
const commits = await gitService.getCommits({ author: 'Test Author' });
|
|
173
|
-
|
|
174
|
-
expect(Array.isArray(commits)).toBe(true);
|
|
175
|
-
expect(commits.length).toBeGreaterThan(0);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
it('should handle private method errors gracefully', async () => {
|
|
179
|
-
const mockCommits = [
|
|
180
|
-
{
|
|
181
|
-
hash: 'abc123',
|
|
182
|
-
date: '2024-01-01',
|
|
183
|
-
message: 'Test commit',
|
|
184
|
-
author_name: 'Test Author',
|
|
185
|
-
author_email: 'test@example.com',
|
|
186
|
-
refs: 'HEAD -> main',
|
|
187
|
-
body: '',
|
|
188
|
-
hash_abbrev: 'abc123',
|
|
189
|
-
tree: 'def456',
|
|
190
|
-
tree_abbrev: 'def456',
|
|
191
|
-
parent: 'ghi789',
|
|
192
|
-
parent_abbrev: 'ghi789'
|
|
193
|
-
}
|
|
194
|
-
];
|
|
195
|
-
|
|
196
|
-
mockGit.log.mockResolvedValue({ all: mockCommits });
|
|
197
|
-
mockGit.diff.mockRejectedValue(new Error('Diff error'));
|
|
198
|
-
mockGit.branch.mockRejectedValue(new Error('Branch error'));
|
|
199
|
-
mockGit.raw.mockRejectedValue(new Error('Tag error'));
|
|
200
|
-
|
|
201
|
-
const commits = await gitService.getCommits();
|
|
202
|
-
|
|
203
|
-
expect(Array.isArray(commits)).toBe(true);
|
|
204
|
-
expect(commits.length).toBeGreaterThan(0);
|
|
205
|
-
expect(commits[0].files).toEqual([]);
|
|
206
|
-
expect(commits[0].branches).toEqual([]);
|
|
207
|
-
expect(commits[0].tags).toEqual([]);
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
it('should handle non-Error exceptions', async () => {
|
|
211
|
-
mockGit.log.mockRejectedValue('String error');
|
|
212
|
-
|
|
213
|
-
await expect(gitService.getCommits()).rejects.toThrow('Failed to get commits: Unknown error');
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
describe('getTags', () => {
|
|
218
|
-
it('should return an array of tags', async () => {
|
|
219
|
-
const mockTags = ['v1.0.0', 'v1.1.0', 'v2.0.0'];
|
|
220
|
-
mockGit.tags.mockResolvedValue({ all: mockTags });
|
|
221
|
-
|
|
222
|
-
const tags = await gitService.getTags();
|
|
223
|
-
|
|
224
|
-
expect(Array.isArray(tags)).toBe(true);
|
|
225
|
-
expect(tags).toEqual(mockTags);
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
it('should handle git tags errors', async () => {
|
|
229
|
-
mockGit.tags.mockRejectedValue(new Error('Git tags error'));
|
|
230
|
-
|
|
231
|
-
await expect(gitService.getTags()).rejects.toThrow('Git tags error');
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
it('should handle empty tags list', async () => {
|
|
235
|
-
mockGit.tags.mockResolvedValue({ all: [] });
|
|
236
|
-
|
|
237
|
-
const tags = await gitService.getTags();
|
|
238
|
-
|
|
239
|
-
expect(Array.isArray(tags)).toBe(true);
|
|
240
|
-
expect(tags.length).toBe(0);
|
|
241
|
-
});
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
describe('getBranches', () => {
|
|
245
|
-
it('should return an array of branches', async () => {
|
|
246
|
-
const mockBranches = ['main', 'develop', 'feature/test'];
|
|
247
|
-
mockGit.branch.mockResolvedValue({ all: mockBranches });
|
|
248
|
-
|
|
249
|
-
const branches = await gitService.getBranches();
|
|
250
|
-
|
|
251
|
-
expect(Array.isArray(branches)).toBe(true);
|
|
252
|
-
expect(branches).toEqual(mockBranches);
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
it('should handle git branch errors', async () => {
|
|
256
|
-
mockGit.branch.mockRejectedValue(new Error('Git branch error'));
|
|
257
|
-
|
|
258
|
-
await expect(gitService.getBranches()).rejects.toThrow('Git branch error');
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
it('should handle empty branches list', async () => {
|
|
262
|
-
mockGit.branch.mockResolvedValue({ all: [] });
|
|
263
|
-
|
|
264
|
-
const branches = await gitService.getBranches();
|
|
265
|
-
|
|
266
|
-
expect(Array.isArray(branches)).toBe(true);
|
|
267
|
-
expect(branches.length).toBe(0);
|
|
268
|
-
});
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
describe('getDiff', () => {
|
|
272
|
-
it('should return diff for a commit', async () => {
|
|
273
|
-
const mockDiff = 'diff --git a/file.js b/file.js\nindex 123..456 100644\n--- a/file.js\n+++ b/file.js\n@@ -1,3 +1,4 @@\n line1\n+line2\n line3';
|
|
274
|
-
mockGit.diff.mockResolvedValue(mockDiff);
|
|
275
|
-
|
|
276
|
-
const diff = await gitService.getDiff('abc123');
|
|
277
|
-
|
|
278
|
-
expect(Array.isArray(diff)).toBe(true);
|
|
279
|
-
expect(diff.length).toBeGreaterThan(0);
|
|
280
|
-
expect(diff[0]).toHaveProperty('file');
|
|
281
|
-
expect(diff[0]).toHaveProperty('additions');
|
|
282
|
-
expect(diff[0]).toHaveProperty('deletions');
|
|
283
|
-
expect(diff[0]).toHaveProperty('changes');
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
it('should handle git diff errors', async () => {
|
|
287
|
-
mockGit.diff.mockRejectedValue(new Error('Git diff error'));
|
|
288
|
-
|
|
289
|
-
await expect(gitService.getDiff('abc123')).rejects.toThrow('Git diff error');
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
it('should handle empty diff', async () => {
|
|
293
|
-
mockGit.diff.mockResolvedValue('');
|
|
294
|
-
|
|
295
|
-
const diff = await gitService.getDiff('abc123');
|
|
296
|
-
|
|
297
|
-
expect(Array.isArray(diff)).toBe(true);
|
|
298
|
-
expect(diff.length).toBe(0);
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
it('should parse complex diff with multiple files', async () => {
|
|
302
|
-
const mockDiff = `diff --git a/file1.js b/file1.js
|
|
303
|
-
index 123..456 100644
|
|
304
|
-
--- a/file1.js
|
|
305
|
-
+++ b/file1.js
|
|
306
|
-
@@ -1,3 +1,4 @@
|
|
307
|
-
line1
|
|
308
|
-
+line2
|
|
309
|
-
line3
|
|
310
|
-
diff --git a/file2.js b/file2.js
|
|
311
|
-
index 789..012 100644
|
|
312
|
-
--- a/file2.js
|
|
313
|
-
+++ b/file2.js
|
|
314
|
-
@@ -1,2 +1,3 @@
|
|
315
|
-
old1
|
|
316
|
-
+new1
|
|
317
|
-
old2`;
|
|
318
|
-
mockGit.diff.mockResolvedValue(mockDiff);
|
|
319
|
-
|
|
320
|
-
const diff = await gitService.getDiff('abc123');
|
|
321
|
-
|
|
322
|
-
expect(Array.isArray(diff)).toBe(true);
|
|
323
|
-
expect(diff.length).toBe(2);
|
|
324
|
-
expect(diff[0].file).toBe('file1.js');
|
|
325
|
-
expect(diff[1].file).toBe('file2.js');
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
it('should handle diff with no file match', async () => {
|
|
329
|
-
const mockDiff = 'diff --git a/ b/\nindex 123..456 100644\n--- a/\n+++ b/';
|
|
330
|
-
mockGit.diff.mockResolvedValue(mockDiff);
|
|
331
|
-
|
|
332
|
-
const diff = await gitService.getDiff('abc123');
|
|
333
|
-
|
|
334
|
-
expect(Array.isArray(diff)).toBe(true);
|
|
335
|
-
expect(diff.length).toBeGreaterThan(0);
|
|
336
|
-
expect(diff[0].file).toBe('');
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
it('should handle diff with context lines and headers', async () => {
|
|
340
|
-
const mockDiff = `diff --git a/file.js b/file.js
|
|
341
|
-
index 123..456 100644
|
|
342
|
-
--- a/file.js
|
|
343
|
-
+++ b/file.js
|
|
344
|
-
@@ -1,3 +1,4 @@
|
|
345
|
-
line1
|
|
346
|
-
+line2
|
|
347
|
-
line3
|
|
348
|
-
unchanged line`;
|
|
349
|
-
mockGit.diff.mockResolvedValue(mockDiff);
|
|
350
|
-
|
|
351
|
-
const diff = await gitService.getDiff('abc123');
|
|
352
|
-
|
|
353
|
-
expect(Array.isArray(diff)).toBe(true);
|
|
354
|
-
expect(diff.length).toBeGreaterThan(0);
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
it('should handle diff with only deletions', async () => {
|
|
358
|
-
const mockDiff = `diff --git a/file.js b/file.js
|
|
359
|
-
index 123..456 100644
|
|
360
|
-
--- a/file.js
|
|
361
|
-
+++ b/file.js
|
|
362
|
-
@@ -1,3 +1,2 @@
|
|
363
|
-
line1
|
|
364
|
-
-line2
|
|
365
|
-
line3`;
|
|
366
|
-
mockGit.diff.mockResolvedValue(mockDiff);
|
|
367
|
-
|
|
368
|
-
const diff = await gitService.getDiff('abc123');
|
|
369
|
-
|
|
370
|
-
expect(Array.isArray(diff)).toBe(true);
|
|
371
|
-
expect(diff.length).toBeGreaterThan(0);
|
|
372
|
-
expect(diff[0].deletions).toBeGreaterThan(0);
|
|
373
|
-
});
|
|
374
|
-
});
|
|
375
|
-
|
|
376
|
-
describe('getCommit', () => {
|
|
377
|
-
it('should return a single commit', async () => {
|
|
378
|
-
const mockCommit = {
|
|
379
|
-
hash: 'abc123',
|
|
380
|
-
date: '2024-01-01',
|
|
381
|
-
message: 'Test commit',
|
|
382
|
-
author_name: 'Test Author',
|
|
383
|
-
author_email: 'test@example.com',
|
|
384
|
-
refs: 'HEAD -> main',
|
|
385
|
-
body: '',
|
|
386
|
-
hash_abbrev: 'abc123',
|
|
387
|
-
tree: 'def456',
|
|
388
|
-
tree_abbrev: 'def456',
|
|
389
|
-
parent: 'ghi789',
|
|
390
|
-
parent_abbrev: 'ghi789'
|
|
391
|
-
};
|
|
392
|
-
|
|
393
|
-
mockGit.log.mockResolvedValue({ all: [mockCommit] });
|
|
394
|
-
|
|
395
|
-
const commit = await gitService.getCommit('abc123');
|
|
396
|
-
|
|
397
|
-
expect(commit).toHaveProperty('hash', 'abc123');
|
|
398
|
-
expect(commit).toHaveProperty('author', 'Test Author');
|
|
399
|
-
expect(commit).toHaveProperty('date', '2024-01-01');
|
|
400
|
-
expect(commit).toHaveProperty('message', 'Test commit');
|
|
401
|
-
});
|
|
402
|
-
|
|
403
|
-
it('should handle commit not found', async () => {
|
|
404
|
-
mockGit.log.mockResolvedValue({ all: [] });
|
|
405
|
-
|
|
406
|
-
await expect(gitService.getCommit('nonexistent')).rejects.toThrow('Commit not found');
|
|
407
|
-
});
|
|
408
|
-
|
|
409
|
-
it('should handle git log errors', async () => {
|
|
410
|
-
mockGit.log.mockRejectedValue(new Error('Git error'));
|
|
411
|
-
|
|
412
|
-
await expect(gitService.getCommit('abc123')).rejects.toThrow('Git error');
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
it('should handle non-Error exceptions', async () => {
|
|
416
|
-
mockGit.log.mockRejectedValue('String error');
|
|
417
|
-
|
|
418
|
-
await expect(gitService.getCommit('abc123')).rejects.toThrow('Failed to get commit: Unknown error');
|
|
419
|
-
});
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
describe('getBlame', () => {
|
|
423
|
-
it('should return blame information for a file', async () => {
|
|
424
|
-
const mockBlame = 'abc123 1 1 1\nauthor Test Author\n\tline1';
|
|
425
|
-
mockGit.raw.mockResolvedValue(mockBlame);
|
|
426
|
-
|
|
427
|
-
const blame = await gitService.getBlame('test.js');
|
|
428
|
-
|
|
429
|
-
expect(Array.isArray(blame)).toBe(true);
|
|
430
|
-
expect(blame.length).toBeGreaterThan(0);
|
|
431
|
-
expect(blame[0]).toHaveProperty('hash');
|
|
432
|
-
expect(blame[0]).toHaveProperty('author');
|
|
433
|
-
expect(blame[0]).toHaveProperty('line');
|
|
434
|
-
expect(blame[0]).toHaveProperty('content');
|
|
435
|
-
});
|
|
436
|
-
|
|
437
|
-
it('should handle git blame errors', async () => {
|
|
438
|
-
mockGit.raw.mockRejectedValue(new Error('Git blame error'));
|
|
439
|
-
|
|
440
|
-
await expect(gitService.getBlame('test.js')).rejects.toThrow('Git blame error');
|
|
441
|
-
});
|
|
442
|
-
|
|
443
|
-
it('should handle empty blame', async () => {
|
|
444
|
-
mockGit.raw.mockResolvedValue('');
|
|
445
|
-
|
|
446
|
-
const blame = await gitService.getBlame('test.js');
|
|
447
|
-
|
|
448
|
-
expect(Array.isArray(blame)).toBe(true);
|
|
449
|
-
expect(blame.length).toBe(0);
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
it('should handle non-Error exceptions', async () => {
|
|
453
|
-
mockGit.raw.mockRejectedValue('String error');
|
|
454
|
-
|
|
455
|
-
await expect(gitService.getBlame('test.js')).rejects.toThrow('Failed to get blame: Unknown error');
|
|
456
|
-
});
|
|
457
|
-
|
|
458
|
-
it('should parse blame with author-time', async () => {
|
|
459
|
-
const mockBlame = `abc123 1 1 1
|
|
460
|
-
author Test Author
|
|
461
|
-
author-time 1640995200
|
|
462
|
-
\tline1`;
|
|
463
|
-
mockGit.raw.mockResolvedValue(mockBlame);
|
|
464
|
-
|
|
465
|
-
const blame = await gitService.getBlame('test.js');
|
|
466
|
-
|
|
467
|
-
expect(Array.isArray(blame)).toBe(true);
|
|
468
|
-
expect(blame.length).toBeGreaterThan(0);
|
|
469
|
-
expect(blame[0]).toHaveProperty('date');
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
it('should parse blame without author-time', async () => {
|
|
473
|
-
const mockBlame = `abc123 1 1 1
|
|
474
|
-
author Test Author
|
|
475
|
-
\tline1`;
|
|
476
|
-
mockGit.raw.mockResolvedValue(mockBlame);
|
|
477
|
-
|
|
478
|
-
const blame = await gitService.getBlame('test.js');
|
|
479
|
-
|
|
480
|
-
expect(Array.isArray(blame)).toBe(true);
|
|
481
|
-
expect(blame.length).toBeGreaterThan(0);
|
|
482
|
-
expect(blame[0]).toHaveProperty('date');
|
|
483
|
-
});
|
|
484
|
-
|
|
485
|
-
it('should handle malformed blame data', async () => {
|
|
486
|
-
const mockBlame = 'invalid blame data without proper format';
|
|
487
|
-
mockGit.raw.mockResolvedValue(mockBlame);
|
|
488
|
-
|
|
489
|
-
const blame = await gitService.getBlame('test.js');
|
|
490
|
-
|
|
491
|
-
expect(Array.isArray(blame)).toBe(true);
|
|
492
|
-
expect(blame.length).toBe(0);
|
|
493
|
-
});
|
|
494
|
-
|
|
495
|
-
it('should parse blame with multiple lines and complete properly', async () => {
|
|
496
|
-
const mockBlame = `abc123 1 1 1
|
|
497
|
-
author Test Author
|
|
498
|
-
author-time 1640995200
|
|
499
|
-
\tline1
|
|
500
|
-
def456 2 2 1
|
|
501
|
-
author Another Author
|
|
502
|
-
\tline2`;
|
|
503
|
-
mockGit.raw.mockResolvedValue(mockBlame);
|
|
504
|
-
|
|
505
|
-
const blame = await gitService.getBlame('test.js');
|
|
506
|
-
|
|
507
|
-
expect(Array.isArray(blame)).toBe(true);
|
|
508
|
-
expect(blame.length).toBe(2);
|
|
509
|
-
expect(blame[0].hash).toBe('abc123');
|
|
510
|
-
expect(blame[1].hash).toBe('def456');
|
|
511
|
-
});
|
|
512
|
-
});
|
|
513
|
-
|
|
514
|
-
describe('Error handling', () => {
|
|
515
|
-
it('should handle non-Error exceptions in getTags', async () => {
|
|
516
|
-
mockGit.tags.mockRejectedValue('String error');
|
|
517
|
-
|
|
518
|
-
await expect(gitService.getTags()).rejects.toThrow('Failed to get tags: Unknown error');
|
|
519
|
-
});
|
|
520
|
-
|
|
521
|
-
it('should handle non-Error exceptions in getBranches', async () => {
|
|
522
|
-
mockGit.branch.mockRejectedValue('String error');
|
|
523
|
-
|
|
524
|
-
await expect(gitService.getBranches()).rejects.toThrow('Failed to get branches: Unknown error');
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
it('should handle non-Error exceptions in getDiff', async () => {
|
|
528
|
-
mockGit.diff.mockRejectedValue('String error');
|
|
529
|
-
|
|
530
|
-
await expect(gitService.getDiff('abc123')).rejects.toThrow('Failed to get diff: Unknown error');
|
|
531
|
-
});
|
|
532
|
-
});
|
|
533
|
-
});
|
package/src/__tests__/setup.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
// Test setup file
|
|
2
|
-
import { jest } from '@jest/globals';
|
|
3
|
-
|
|
4
|
-
// Mock console methods to reduce noise in tests
|
|
5
|
-
global.console = {
|
|
6
|
-
...console,
|
|
7
|
-
log: jest.fn(),
|
|
8
|
-
debug: jest.fn(),
|
|
9
|
-
info: jest.fn(),
|
|
10
|
-
warn: jest.fn(),
|
|
11
|
-
error: jest.fn(),
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
// Mock process.exit to prevent tests from exiting
|
|
15
|
-
process.exit = jest.fn() as any;
|
|
16
|
-
|
|
17
|
-
// Set test timeout
|
|
18
|
-
jest.setTimeout(10000);
|
|
19
|
-
|
|
20
|
-
// Add a simple test to satisfy Jest requirements
|
|
21
|
-
describe('Setup', () => {
|
|
22
|
-
it('should be configured correctly', () => {
|
|
23
|
-
expect(true).toBe(true);
|
|
24
|
-
});
|
|
25
|
-
});
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { startServer } from './server';
|
|
2
|
-
|
|
3
|
-
async function main() {
|
|
4
|
-
try {
|
|
5
|
-
console.log('🚀 Starting Git History UI Development Server...');
|
|
6
|
-
await startServer(3000, 'localhost');
|
|
7
|
-
console.log('✅ Development server running at http://localhost:3000');
|
|
8
|
-
} catch (error) {
|
|
9
|
-
console.error('❌ Error starting development server:', error);
|
|
10
|
-
process.exit(1);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
main();
|