Skip to content

Commit 6ef43e7

Browse files
committed
Fix tests and refactor
1 parent f2192de commit 6ef43e7

File tree

5 files changed

+56
-60
lines changed

5 files changed

+56
-60
lines changed

src/__fixtures__/diff.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,6 @@ b/dirty.js
5151
`;
5252

5353
export const filenamesA = `a/dirty.js
54-
`
54+
`
55+
56+
export const diffFileList = "file1\nfile2\nfile3\n"

src/__fixtures__/postprocessArguments.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Linter } from "eslint";
1+
import type { Linter } from "eslint";
22

33
const postprocessArguments = [
44
[

src/git.test.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import * as child_process from "child_process";
22
import { mocked } from "ts-jest/utils";
33
import { getDiffFileList, getDiffForFile, getRangesForDiff } from "./git";
4-
import { hunks, includingOnlyRemovals, filenamesAB } from "./__fixtures__/diff";
4+
import {
5+
hunks,
6+
includingOnlyRemovals,
7+
diffFileList,
8+
} from "./__fixtures__/diff";
59
import path from "path";
610

711
jest.mock("child_process");
@@ -29,25 +33,27 @@ describe("git", () => {
2933

3034
it("should hit the cached diff of a file", () => {
3135
jest.mock("child_process").resetAllMocks();
32-
mockedChildProcess.execSync.mockReturnValue(Buffer.from(hunks));
36+
mockedChildProcess.execSync.mockReturnValueOnce(Buffer.from(hunks));
3337

3438
const diffFromFileA = getDiffForFile("./mockfileCache.js");
3539
const diffFromFileB = getDiffForFile("./mockfileCache.js");
3640
expect(mockedChildProcess.execSync).toHaveBeenCalledTimes(1);
3741
expect(diffFromFileA).toEqual(diffFromFileB);
3842

43+
mockedChildProcess.execSync.mockReturnValueOnce(Buffer.from(hunks));
3944
getDiffForFile("./mockfileMiss.js");
4045
expect(mockedChildProcess.execSync).toHaveBeenCalledTimes(2);
4146
});
4247

4348
it("should get the list of staged files", () => {
44-
mockedChildProcess.execSync.mockReturnValue(Buffer.from(filenamesAB));
49+
jest.mock("child_process").resetAllMocks();
50+
mockedChildProcess.execSync.mockReturnValue(Buffer.from(diffFileList));
4551

4652
const fileList = getDiffFileList();
4753

4854
expect(mockedChildProcess.execSync).toHaveBeenCalled();
4955
expect(fileList).toEqual(
50-
["a/dirty.js", "b/dirty.js"].map((p) => path.resolve(p))
56+
["file1", "file2", "file3"].map((p) => path.resolve(p))
5157
);
5258
});
5359
});

src/git.ts

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,45 @@ const sanitizeFilePath = (filePath: string) =>
88
const diffCacheKey = (filePath: string, staged: boolean): string =>
99
JSON.stringify([path.resolve(filePath), staged]);
1010

11-
const diffCache = new Map<string, string>();
11+
const setCachedDiff = (filePath: string, staged: boolean, diff: string): void =>
12+
void diffCache.set(diffCacheKey(filePath, staged), diff);
13+
14+
const getCachedDiff = (filePath: string, staged: boolean) =>
15+
diffCache.get(diffCacheKey(filePath, staged));
1216

17+
const diffCache = new Map<string, string>();
1318
const getDiffForFile = (filePath: string, staged = false): string => {
14-
// Get diff entry from cache
15-
const cachedDiff = diffCache.get(diffCacheKey(filePath, staged));
16-
if (cachedDiff) {
17-
// If entry is not falsy return it
18-
return cachedDiff;
19-
} else {
20-
// Otherwise spawn child_process set it in cache and return it
21-
const diff = child_process
19+
let diff = getCachedDiff(filePath, staged);
20+
if (diff === undefined) {
21+
const result = child_process
2222
.execSync(
2323
`git diff --diff-filter=ACM --unified=0 HEAD ${
24-
staged ? "--staged" : ""
24+
staged ? " --staged" : ""
2525
} -- ${sanitizeFilePath(filePath)}`
2626
)
2727
.toString();
28-
diffCache.set(diffCacheKey(filePath, staged), diff);
29-
return diff;
28+
setCachedDiff(filePath, staged, result);
29+
diff = result;
3030
}
31+
32+
return diff;
3133
};
3234

35+
let diffFileListCache: string[];
3336
const getDiffFileList = (staged = false): string[] => {
34-
return child_process
35-
.execSync(
36-
`git diff --diff-filter=ACM HEAD ${staged ? "--staged" : ""} --name-only`
37-
)
38-
.toString()
39-
.split("\n")
40-
.filter((filePath) => filePath.length)
41-
.map((filePath) => path.resolve(filePath));
37+
if (diffFileListCache === undefined) {
38+
diffFileListCache = child_process
39+
.execSync(
40+
`git diff --diff-filter=ACM HEAD --name-only ${
41+
staged ? "--staged" : ""
42+
}`
43+
)
44+
.toString()
45+
.trim()
46+
.split("\n")
47+
.map((filePath) => path.resolve(filePath));
48+
}
49+
return diffFileListCache;
4250
};
4351

4452
const isHunkHeader = (input: string) => {
@@ -63,12 +71,12 @@ const getRangeForChangedLines = (line: string) => {
6371
}
6472

6573
const linesCount: number =
66-
range.groups?.linesCountDelimiter && range.groups?.linesCount
74+
range.groups.linesCountDelimiter && range.groups.linesCount
6775
? parseInt(range.groups.linesCount)
6876
: 1;
6977

7078
const hasAddedLines = linesCount !== 0;
71-
const start: number = parseInt(range.groups?.start);
79+
const start: number = parseInt(range.groups.start);
7280
const end = start + linesCount;
7381

7482
return hasAddedLines ? new Range(start, end) : null;

src/processors.ts

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,28 @@
1-
import {
2-
getDiffForFile,
3-
getRangesForDiff,
4-
getDiffFileList,
5-
Range,
6-
} from "./git";
7-
import { Linter } from "eslint";
1+
import type { Range } from "./git";
2+
import { getDiffForFile, getRangesForDiff, getDiffFileList } from "./git";
3+
import type { Linter } from "eslint";
84

95
const STAGED = true;
106

117
const isLineWithinRange = (line: number) => (range: Range) =>
128
range.isWithinRange(line);
13-
let fileList: string[];
149

1510
const diff = {
1611
preprocess: (
1712
text: string,
1813
filename: string
19-
): { text: string; filename: string }[] => {
20-
if (
21-
(fileList ? fileList : (fileList = getDiffFileList())).includes(filename)
22-
) {
23-
return [{ text, filename }];
24-
} else {
25-
return [];
26-
}
27-
},
14+
): { text: string; filename: string }[] =>
15+
getDiffFileList().includes(filename) ? [{ text, filename }] : [],
2816

2917
postprocess: (
3018
messages: Linter.LintMessage[][],
3119
filename: string
3220
): Linter.LintMessage[] =>
3321
messages
3422
.map((message) =>
35-
message.filter((message) =>
23+
message.filter(({ line }) =>
3624
getRangesForDiff(getDiffForFile(filename)).some(
37-
isLineWithinRange(message.line)
25+
isLineWithinRange(line)
3826
)
3927
)
4028
)
@@ -57,26 +45,18 @@ const staged = {
5745
preprocess: (
5846
text: string,
5947
filename: string
60-
): { text: string; filename: string }[] => {
61-
if (
62-
(fileList ? fileList : (fileList = getDiffFileList(true))).includes(
63-
filename
64-
)
65-
) {
66-
return [{ text, filename }];
67-
} else {
68-
return [];
69-
}
70-
},
48+
): { text: string; filename: string }[] =>
49+
getDiffFileList(STAGED).includes(filename) ? [{ text, filename }] : [],
50+
7151
postprocess: (
7252
messages: Linter.LintMessage[][],
7353
filename: string
7454
): Linter.LintMessage[] =>
7555
messages
7656
.map((message) =>
77-
message.filter((message) =>
57+
message.filter(({ line }) =>
7858
getRangesForDiff(getDiffForFile(filename, STAGED)).some(
79-
isLineWithinRange(message.line)
59+
isLineWithinRange(line)
8060
)
8161
)
8262
)

0 commit comments

Comments
 (0)