Skip to content

Commit 642b8de

Browse files
committed
refactor to handle file modes
1 parent 33d18aa commit 642b8de

11 files changed

+780
-416
lines changed

property-based-tests/executeTestCase.ts

+16-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as path from "path"
33

44
import { spawnSafeSync } from "../src/spawnSafe"
55
import { executeEffects } from "../src/patch/apply"
6-
import { parsePatch } from "../src/patch/parse"
6+
import { parsePatchFile } from "../src/patch/parse"
77
import { reversePatch } from "../src/patch/reverse"
88

99
import { TestCase, Files } from "./testCases"
@@ -38,6 +38,11 @@ jest.mock("fs-extra", () => {
3838
getWorkingFiles()[to] = getWorkingFiles()[from]
3939
delete getWorkingFiles()[from]
4040
}),
41+
statSync: jest.fn(path => getWorkingFiles()[path]),
42+
chmodSync: jest.fn((path, mode) => {
43+
const { contents } = getWorkingFiles()[path]
44+
getWorkingFiles()[path] = { contents, mode }
45+
}),
4146
}
4247
})
4348

@@ -85,12 +90,14 @@ export function executeTestCase(testCase: TestCase) {
8590
writeFiles(tmpDir.name, testCase.cleanFiles)
8691

8792
spawnSafeSync("git", ["add", "-A"], { cwd: tmpDir.name })
88-
spawnSafeSync("git", ["commit", "-m", "blah"], {
89-
cwd: tmpDir.name,
90-
})
91-
spawnSafeSync("git", ["rm", "-rf", "*"], {
93+
spawnSafeSync("git", ["commit", "--allow-empty", "-m", "blah"], {
9294
cwd: tmpDir.name,
9395
})
96+
if (Object.keys(testCase.cleanFiles).length > 0) {
97+
spawnSafeSync("git", ["rm", "-rf", "*"], {
98+
cwd: tmpDir.name,
99+
})
100+
}
94101

95102
writeFiles(tmpDir.name, testCase.modifiedFiles)
96103
spawnSafeSync("git", ["add", "-A"], { cwd: tmpDir.name })
@@ -113,8 +120,8 @@ export function executeTestCase(testCase: TestCase) {
113120

114121
it("looks the same whether parsed with blank lines or not", () => {
115122
reportingFailures(() => {
116-
expect(parsePatch(patchFileContents)).toEqual(
117-
parsePatch(patchFileContentsWithBlankLines),
123+
expect(parsePatchFile(patchFileContents)).toEqual(
124+
parsePatchFile(patchFileContentsWithBlankLines),
118125
)
119126
})
120127
})
@@ -124,7 +131,7 @@ export function executeTestCase(testCase: TestCase) {
124131
it("works forwards", () => {
125132
fs.setWorkingFiles({ ...testCase.cleanFiles })
126133
reportingFailures(() => {
127-
const effects = parsePatch(patchFileContents)
134+
const effects = parsePatchFile(patchFileContents)
128135
executeEffects(effects, { dryRun: false })
129136
expect(fs.getWorkingFiles()).toEqual(testCase.modifiedFiles)
130137
})
@@ -133,7 +140,7 @@ export function executeTestCase(testCase: TestCase) {
133140
it("works backwards", () => {
134141
fs.setWorkingFiles({ ...testCase.modifiedFiles })
135142
reportingFailures(() => {
136-
const effects = reversePatch(parsePatch(patchFileContents))
143+
const effects = reversePatch(parsePatchFile(patchFileContents))
137144
executeEffects(effects, { dryRun: false })
138145
expect(fs.getWorkingFiles()).toEqual(testCase.cleanFiles)
139146
})

property-based-tests/regressionTests.test.ts

+12
Original file line numberDiff line numberDiff line change
@@ -181,4 +181,16 @@ describe("regression tests", () => {
181181
modifiedFiles: { cpz: { contents: "E\n", mode: 420 } },
182182
})
183183
})
184+
185+
describe("18", () => {
186+
executeTestCase({
187+
cleanFiles: {},
188+
modifiedFiles: {
189+
ww: {
190+
contents: "banana",
191+
mode: 420,
192+
},
193+
},
194+
})
195+
})
184196
})

property-based-tests/testCases.ts

+23-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
import { generate } from "randomstring"
2+
import {
3+
NON_EXECUTABLE_FILE_MODE,
4+
EXECUTABLE_FILE_MODE,
5+
} from "../src/patch/parse"
6+
import { assertNever } from "../src/assertNever"
27

38
export interface File {
49
contents: string
@@ -31,7 +36,7 @@ function makeFileContents(): File {
3136
length: Math.floor(Math.random() * 1000),
3237
charset: fileCharSet,
3338
}) || "",
34-
mode: 0o644,
39+
mode: Math.random() > 0.5 ? 0o644 : 0o755,
3540
}
3641
}
3742

@@ -69,11 +74,13 @@ type MutationKind =
6974
| "deleteLine"
7075
| "insertLine"
7176
| "renameFile"
77+
| "changeFileMode"
7278

7379
const mutationKindLikelihoods: Array<[MutationKind, number]> = [
7480
["deleteFile", 1],
7581
["createFile", 1],
7682
["renameFile", 1],
83+
["changeFileMode", 1],
7784
["deleteLine", 10],
7885
["insertLine", 10],
7986
]
@@ -126,7 +133,8 @@ function mutateFiles(files: Files): Files {
126133
const numMutations = Math.ceil(Math.random() * 1000)
127134

128135
for (let i = 0; i < numMutations; i++) {
129-
switch (getNextMutationKind()) {
136+
const mutationKind = getNextMutationKind()
137+
switch (mutationKind) {
130138
case "deleteFile": {
131139
if (Object.keys(mutatedFiles).length === 1) {
132140
break
@@ -160,6 +168,19 @@ function mutateFiles(files: Files): Files {
160168
mutatedFiles[pathToRename]
161169
delete mutatedFiles[pathToRename]
162170
break
171+
case "changeFileMode":
172+
const pathToChange = selectRandomElement(Object.keys(mutatedFiles))
173+
const { mode, contents } = mutatedFiles[pathToChange]
174+
mutatedFiles[pathToChange] = {
175+
contents,
176+
mode:
177+
mode === NON_EXECUTABLE_FILE_MODE
178+
? EXECUTABLE_FILE_MODE
179+
: NON_EXECUTABLE_FILE_MODE,
180+
}
181+
break
182+
default:
183+
assertNever(mutationKind)
163184
}
164185
}
165186

src/applyPatches.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { existsSync, readFileSync } from "fs-extra"
55
import { join, resolve } from "./path"
66
import { posix } from "path"
77
import { getPackageDetailsFromPatchFilename } from "./PackageDetails"
8-
import { parsePatch } from "./patch/parse"
8+
import { parsePatchFile } from "./patch/parse"
99
import { reversePatch } from "./patch/reverse"
1010

1111
function findPatchFiles(patchesDirectory: string): string[] {
@@ -115,7 +115,7 @@ export const applyPatch = (
115115
reverse: boolean,
116116
): boolean => {
117117
const patchFileContents = readFileSync(patchFilePath).toString()
118-
const patch = parsePatch(patchFileContents)
118+
const patch = parsePatchFile(patchFileContents)
119119
try {
120120
executeEffects(reverse ? reversePatch(patch) : patch, { dryRun: false })
121121
} catch (e) {

src/assertNever.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function assertNever(x: never): never {
2+
throw new Error("Unexpected object: " + x)
3+
}

0 commit comments

Comments
 (0)