Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: search and replace improvements #31

Merged
merged 13 commits into from
May 2, 2024
21 changes: 5 additions & 16 deletions packages/bumpgen-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,22 +324,11 @@ const bumpgen = ({
let fileContents = await services.filesystem.read(planNode.path);

for (const replacement of replacements) {
// this accounts for interline replacements but not formatting
let newFileContents = fileContents.replace(
replacement.oldCode.trim(),
replacement.newCode,
);

// this accounts for formatting but not interline replacements
if (newFileContents === fileContents) {
newFileContents = services.matching.replacements.fuzzy({
content: fileContents,
oldCode: replacement.oldCode,
newCode: replacement.newCode,
});
}

fileContents = newFileContents;
fileContents = services.matching.replacements.fuzzy({
content: fileContents,
oldCode: replacement.oldCode,
newCode: replacement.newCode,
});
}

const originalSignature = planNode.typeSignature;
Expand Down
104 changes: 90 additions & 14 deletions packages/bumpgen-core/src/services/matching/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import fs from "fs/promises";
import path from "path";

import { searchAndReplace, splitMultiImportOldCode } from ".";
import {
findMatchedBlockIndices,
formatNewCode,
advancedSearchAndReplace,
} from ".";

const getFileBefore = async (filename: string) => {
return (
Expand All @@ -19,30 +23,102 @@ const getFileAfter = async (filename: string) => {
).toString();
};

describe("searchAndReplace", () => {
describe("advancedSearchAndReplace", () => {
it("searchAndReplace glob.txt", async () => {
const fileBefore = await getFileBefore("glob.txt");
const fileAfter = await getFileAfter("glob.txt");

const oldCode = "import * as rawGlob from 'glob';";
const oldCode = "import * as rawGlob from 'glob'";
const newCode = "import { glob as rawGlob } from 'glob';";

const result = searchAndReplace(fileBefore, oldCode, newCode);

const result = advancedSearchAndReplace(fileBefore, oldCode, newCode);
expect(result).toBe(fileAfter);
});
});

describe("splitMultiImportOldCode", () => {
it("splitMultiImportOldCode", () => {
const oldCode =
"import * as rawGlob from 'glob';\n\n\nconst glob = promisify(rawGlob);";
describe("formatNewCode", () => {
it("should format replacement code correctly for missing indents", () => {
const line = " import * as Sentry from '@sentry/line';";
const replace = "import * as Sentry from '@sentry/replace';";

const result = formatNewCode(line, replace);

expect(result).toEqual([" import * as Sentry from '@sentry/replace';"]);
});

it("should format replacement code correctly for extra indents", () => {
const line = "import * as Sentry from '@sentry/line';";
const replace = " import * as Sentry from '@sentry/replace';";

const result = splitMultiImportOldCode(oldCode);
const result = formatNewCode(line, replace);

expect(result).toEqual([
"import * as rawGlob from 'glob';",
"const glob = promisify(rawGlob);",
]);
expect(result).toEqual(["import * as Sentry from '@sentry/replace';"]);
});

it("should format replacement code correctly for tabs", () => {
const line = "\t\timport * as Sentry from '@sentry/line';";
const replace = "import * as Sentry from '@sentry/replace';";

const result = formatNewCode(line, replace);

expect(result).toEqual(["\t\timport * as Sentry from '@sentry/replace';"]);
});
});

describe("findMatchedBlockIndices", () => {
it("should find the right indices for the block of code to replace", () => {
const matchedIndices = [
[1, 5, 6],
[2, 9, 16],
[0, 3],
];

const result = findMatchedBlockIndices(matchedIndices);

expect(result).toEqual({"startIndex": 1, "endIndex": 3});
});

it("should return -1 indices if no matching block found", () => {
const matchedIndices = [
[1, 5, 6],
[3, 9, 16],
[0, 3],
];

const result = findMatchedBlockIndices(matchedIndices);

expect(result).toEqual({"startIndex": -1, "endIndex": -1});
});

it("should handle empty lists edge case", () => {
const matchedIndices = [
[1, 7],
[],
[2, 3, 4],
];

const result = findMatchedBlockIndices(matchedIndices);

expect(result).toEqual({"startIndex": -1, "endIndex": -1});
});

it("should handle only one single line", () => {
const matchedIndices = [
[1, 7]
];

const result = findMatchedBlockIndices(matchedIndices);

expect(result).toEqual({"startIndex": 1, "endIndex": 1});
});

it("should handle no matched indices", () => {
const matchedIndices = [
[]
];

const result = findMatchedBlockIndices(matchedIndices);

expect(result).toEqual({"startIndex": -1, "endIndex": -1});
});
});
Loading
Loading