Skip to content

Commit

Permalink
Added --fix option
Browse files Browse the repository at this point in the history
Right now the --fix option will find a random test pnr and replace the real one with that.

Future improvement: Find replacement a bit smarter. Perhaps with the same birth date.
  • Loading branch information
cederstrom committed Apr 26, 2018
1 parent 8c4699f commit a7a4436
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 3 deletions.
20 changes: 17 additions & 3 deletions bin/bin.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const pkg = require(`../package.json`);
const program = require(`commander`);
const path = require(`path`);
const Finder = require(`../lib/finder`);
const Fixer = require(`../lib/fixer`);

program
.version(pkg.version)
Expand All @@ -13,6 +14,7 @@ program
`-p, --pattern <pattern>`,
`Glob pattern default is !(node_modules){,/**}`
)
.option(`-f, --fix`, `Replace real pnrs with test pnrs`)
.parse(process.argv);

if (program.args.length !== 1) {
Expand All @@ -22,10 +24,22 @@ if (program.args.length !== 1) {

console.time("pnr-scan");
const directory = path.join(process.cwd(), program.args[0]);
Finder.findPnrs(directory, program.pattern).forEach(item => {
const result = Finder.findPnrs(directory, program.pattern);
console.timeEnd("pnr-scan");

if (program.fix && result.length > 0) {
console.time("pnr-fix");
Fixer.fixPnrs(result);
console.timeEnd("pnr-fix");
}

result.forEach(item => {
console.log(item.file);
item.results.forEach(hit => {
console.log(` ${hit.pnr} on line ${hit.line}`);
if (hit.replacement) {
console.log(` ${hit.pnr} => ${hit.replacement} on line ${hit.line}`);
} else {
console.log(` ${hit.pnr} on line ${hit.line}`);
}
});
});
console.timeEnd("pnr-scan");
55 changes: 55 additions & 0 deletions lib/fixer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const Substitutor = require("./substitutor");
const FileMockDataReader = require("./fileMockDataReader");
const fs = require(`fs`);

const substitutor = new Substitutor(FileMockDataReader.fetch());

class Fixer {
static fixPnrs(finderResult) {
finderResult.forEach(item => {
let fileContent = fs.readFileSync(item.file, "utf8");
item.results.forEach(result => {
const realPnr = result.pnr;
let testPnr = substitutor.getReplacement(realPnr);
testPnr = Fixer.matchFormat(realPnr, testPnr);
fileContent = fileContent.replace(realPnr, testPnr);
result.replacement = testPnr;
});
fs.writeFileSync(item.file, fileContent, "utf8");
});
}

static matchFormat(pnrToMatch, testPnr) {
let realPnrBackwards = pnrToMatch
.slice()
.split("")
.reverse();
let testPnrBackwards = testPnr
.slice()
.split("")
.reverse();
let lastReplacedIndex = -1;
testPnrBackwards.forEach(char => {
let charHasBeenReplaced = false;
while (
!charHasBeenReplaced &&
lastReplacedIndex < realPnrBackwards.length
) {
const nextIndexToReplace = lastReplacedIndex + 1;
if (Fixer.isCharDigit(realPnrBackwards[nextIndexToReplace])) {
realPnrBackwards[nextIndexToReplace] = char;
charHasBeenReplaced = true;
}
lastReplacedIndex = nextIndexToReplace;
}
});

return realPnrBackwards.reverse().join("");
}

static isCharDigit(char) {
return !!parseInt(char);
}
}

module.exports = Fixer;
78 changes: 78 additions & 0 deletions lib/fixer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
const mockFs = {
writeFileSync: jest.fn(),
readFileSync: jest.fn()
};
jest.mock("fs", () => mockFs);

const mockFileMockDataReader = {
fetch: jest.fn()
};
jest.mock("./fileMockDataReader", () => mockFileMockDataReader);

const mockSubstitutor = {
getReplacement: jest.fn()
};
jest.mock("./substitutor", () => {
return jest.fn().mockImplementation(() => mockSubstitutor);
});

const Fixer = require("./fixer");

describe("Fixer", () => {
test("overwrites file after replacment", () => {
mockFs.readFileSync = () => `file content`;
const finderResult = [
{
file: "file.js",
results: []
}
];

Fixer.fixPnrs(finderResult);
expect(mockFs.writeFileSync).toBeCalledWith(
`file.js`,
expect.any(String),
expect.any(String)
);
});

test("replaces real prn with test data", () => {
mockFs.readFileSync = () => `Bogus pnr: "199999999999".`;
mockSubstitutor.getReplacement = () => "198888888888";
const finderResult = [
{
file: "file.js",
results: [
{
pnr: "199999999999"
}
]
}
];

Fixer.fixPnrs(finderResult);
expect(mockFs.writeFileSync).toBeCalledWith(
expect.any(String),
`Bogus pnr: "198888888888".`,
expect.any(String)
);
});

describe("matchFormat", () => {
test("can format with spaces", () => {
expect(Fixer.matchFormat("1 2 3", "789")).toBe("7 8 9");
});
test("can format with hyphen", () => {
expect(Fixer.matchFormat("12-3", "789")).toBe("78-9");
});
test("can format with plus", () => {
expect(Fixer.matchFormat("12+3", "789")).toBe("78+9");
});
test("can format with spaces and hypen", () => {
expect(Fixer.matchFormat("12 - 3", "789")).toBe("78 - 9");
});
test("can format with spaces and plus", () => {
expect(Fixer.matchFormat("12 + 3", "789")).toBe("78 + 9");
});
});
});
27 changes: 27 additions & 0 deletions lib/substitutor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const Pnr = require("./pnr");

class Substitutor {
constructor(testPnrs) {
this.testPnrs = testPnrs;
this.prevSubstitutions = {};
}

/**
* Returns a random replacemennt PNR from the test data given to the constructor.
* This method will return the same replacement for the given `realPnr` over and over again.
* @param {String} realPnr
*/
getReplacement(realPnr) {
const normalizedRealPnr = Pnr.normalizePnr(realPnr);
if (normalizedRealPnr in this.prevSubstitutions) {
return this.prevSubstitutions[normalizedRealPnr];
}

const i = Math.floor(Math.random() * (this.testPnrs.length - 1));
const testPnr = this.testPnrs[i];
this.prevSubstitutions[normalizedRealPnr] = testPnr;
return testPnr;
}
}

module.exports = Substitutor;
17 changes: 17 additions & 0 deletions lib/substitutor.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const Substitutor = require("./substitutor");

describe("Substitutor", () => {
test("can pick a replacement test pnr", () => {
const substitutor = new Substitutor(["2"]);
expect(substitutor.getReplacement("1")).toBe("2");
});

test("shall return the same replacement over and over for a pnr", () => {
const substitutor = new Substitutor(["2"]);
const firstReplacement = substitutor.getReplacement("1");
expect(firstReplacement).toBe("2");

substitutor.testPnrs = [];
expect(substitutor.getReplacement("1")).toEqual(firstReplacement);
});
});

0 comments on commit a7a4436

Please sign in to comment.