Skip to content

Commit 666eeb5

Browse files
committed
feat(structured): improve patch parsing flexibility and type safety
Enhanced the patch parsing logic to provide more flexible configuration options. This includes adjustments to how dates and diff structures are processed based on user-defined settings. Corresponding test suites have been expanded to cover these new option variations, ensuring robustness. Type definitions related to parsed commit data have also been updated to accurately represent the structured diff output when that option is enabled.
1 parent d3a6d95 commit 666eeb5

File tree

3 files changed

+82
-9
lines changed

3 files changed

+82
-9
lines changed

src/logics/parse/patch.test.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,79 @@ index 4328ba4..63af774 100644
187187
expect(commits[0].diff).toBe(expectedDiff);
188188
});
189189
});
190+
191+
describe("parseGitPatch with options", () => {
192+
const mockCommit = mockSingleCommit; // Use a simple mock for option testing
193+
194+
it("parses with parseDates: true", () => {
195+
const commits = parseGitPatch(mockCommit, { parseDates: true });
196+
expect(commits).toHaveLength(1);
197+
const commit = commits[0];
198+
expect(commit.date).toBeInstanceOf(Date);
199+
expect((commit.date as Date).toISOString()).toBe(
200+
new Date("Wed, 12 Oct 2022 14:38:15 +0200").toISOString()
201+
);
202+
expect(typeof commit.diff).toBe("string"); // structuredDiff is false by default or explicitly
203+
});
204+
205+
it("parses with structuredDiff: true", () => {
206+
const commits = parseGitPatch(mockCommit, { structuredDiff: true });
207+
expect(commits).toHaveLength(1);
208+
const commit = commits[0];
209+
expect(typeof commit.date).toBe("string"); // parseDates is false
210+
expect(Array.isArray(commit.diff)).toBe(true);
211+
expect(commit.diff.length).toBeGreaterThan(0);
212+
const firstDiff = commit.diff[0];
213+
expect(firstDiff).toHaveProperty("oldPath");
214+
expect(firstDiff).toHaveProperty("newPath");
215+
expect(firstDiff).toHaveProperty("hunks");
216+
expect(firstDiff.oldPath).toBe("file1.txt");
217+
expect(firstDiff.newPath).toBe("file1.txt");
218+
expect(firstDiff.hunks).toBeArray();
219+
expect(firstDiff.hunks[0].lines).toBeArray();
220+
});
221+
222+
it("parses with parseDates: true and structuredDiff: true", () => {
223+
const commits = parseGitPatch(mockCommit, {
224+
parseDates: true,
225+
structuredDiff: true,
226+
});
227+
expect(commits).toHaveLength(1);
228+
const commit = commits[0];
229+
expect(commit.date).toBeInstanceOf(Date);
230+
expect((commit.date as Date).toISOString()).toBe(
231+
new Date("Wed, 12 Oct 2022 14:38:15 +0200").toISOString()
232+
);
233+
expect(Array.isArray(commit.diff)).toBe(true);
234+
expect(commit.diff.length).toBeGreaterThan(0);
235+
const firstDiff = commit.diff[0];
236+
expect(firstDiff).toHaveProperty("oldPath");
237+
expect(firstDiff).toHaveProperty("newPath");
238+
expect(firstDiff).toHaveProperty("hunks");
239+
expect(firstDiff.oldPath).toBe("file1.txt");
240+
expect(firstDiff.newPath).toBe("file1.txt");
241+
});
242+
243+
it("parses with default options (equivalent to parseDates: false, structuredDiff: false)", () => {
244+
const commits = parseGitPatch(mockCommit, {}); // Empty options object
245+
expect(commits).toHaveLength(1);
246+
const commit = commits[0];
247+
expect(typeof commit.date).toBe("string");
248+
expect(commit.date).toBe("Wed, 12 Oct 2022 14:38:15 +0200");
249+
expect(typeof commit.diff).toBe("string");
250+
expect(commit.diff).toContain("diff --git a/file1.txt b/file1.txt");
251+
});
252+
253+
it("parses with explicit false options", () => {
254+
const commits = parseGitPatch(mockCommit, {
255+
parseDates: false,
256+
structuredDiff: false,
257+
});
258+
expect(commits).toHaveLength(1);
259+
const commit = commits[0];
260+
expect(typeof commit.date).toBe("string");
261+
expect(commit.date).toBe("Wed, 12 Oct 2022 14:38:15 +0200");
262+
expect(typeof commit.diff).toBe("string");
263+
expect(commit.diff).toContain("diff --git a/file1.txt b/file1.txt");
264+
});
265+
});

src/logics/parse/patch.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,8 @@ import { parseDiffToStructured } from "./diffToStructured";
33
import { HEADERS, REGEX } from "../../consts";
44

55
export function parseGitPatch<
6-
O extends ParseOptions<any, any> = ParseOptions<false, false>
7-
>(
8-
patch: string,
9-
options: O = { parseDates: false, structuredDiff: false } as O
10-
): ParsedCommit<O>[] {
6+
O extends ParseOptions<boolean, boolean> = ParseOptions<false, false>
7+
>(patch: string, options?: O): ParsedCommit<O>[] {
118
type DateType = ParsedCommit<O>["date"];
129
type DiffType = ParsedCommit<O>["diff"];
1310
const lines = patch.split("\n");
@@ -33,11 +30,11 @@ export function parseGitPatch<
3330
}
3431

3532
const date = (
36-
options.parseDates && currentDate ? new Date(currentDate) : currentDate
33+
options?.parseDates && currentDate ? new Date(currentDate) : currentDate
3734
) as DateType;
3835

3936
const shouldStructurizeDiff =
40-
options.structuredDiff && diffString.trim().length > 0;
37+
options?.structuredDiff && diffString.trim().length > 0;
4138
const diff = (
4239
shouldStructurizeDiff ? parseDiffToStructured(diffString) : diffString
4340
) as DiffType;

src/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface DiffHunk {
1919
lines: DiffLine[];
2020
}
2121

22-
export interface DiffLine {
22+
interface DiffLine {
2323
type: "addition" | "deletion" | "context";
2424
content: string;
2525
}
@@ -34,5 +34,5 @@ export interface ParsedCommit<
3434
authorEmail: string;
3535
date: SelectIfTrue<O["parseDates"], Date, string>;
3636
message: string;
37-
diff: SelectIfTrue<O["structuredDiff"], FileChange, string>;
37+
diff: SelectIfTrue<O["structuredDiff"], FileChange[], string>;
3838
}

0 commit comments

Comments
 (0)