Skip to content

Commit

Permalink
Fix tests and some bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
rekmarks committed Sep 14, 2021
1 parent 662f5ae commit 892a0a1
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 28 deletions.
29 changes: 19 additions & 10 deletions development/build/transforms/remove-fenced-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,13 @@ const CommandValidators = {
},
};

// Matches lines starting with "///:", optionally preceded by whitespace
const linesWithFenceRegex = /^\s*\/\/\/:.*$/gmu;
// Matches lines starting with "///:", and any preceding whitespace, except
// newlines. We except newlines to avoid eating blank lines preceding a fenced
// line.
// Double-negative RegEx credit: https://stackoverflow.com/a/3469155
const linesWithFenceRegex = /^[^\S\r\n]*\/\/\/:.*$/gmu;

// Matches the first "///:" in a string
// Matches the first "///:" in a string, and any preceding whitespace
const fenceSentinelRegex = /^\s*\/\/\/:/u;

// Breaks a fence directive into its constituent components
Expand Down Expand Up @@ -170,6 +173,7 @@ function removeFencedCode(filePath, typeOfCurrentBuild, fileContent) {
const parsedDirectives = matchedLines.map((matchArray) => {
const line = matchArray[0];

/* istanbul ignore next: should be impossible */
if (!fenceSentinelRegex.test(line)) {
throw new Error(
getInvalidFenceLineMessage(
Expand All @@ -185,8 +189,8 @@ function removeFencedCode(filePath, typeOfCurrentBuild, fileContent) {
// performing string operations.
const indices = [matchArray.index, matchArray.index + line.length + 1];

const unfencedLine = line.replace(fenceSentinelRegex, '');
if (!/^ \w\w+/u.test(unfencedLine)) {
const lineWithoutSentinel = line.replace(fenceSentinelRegex, '');
if (!/^ \w\w+/u.test(lineWithoutSentinel)) {
throw new Error(
getInvalidFenceLineMessage(
filePath,
Expand All @@ -196,7 +200,10 @@ function removeFencedCode(filePath, typeOfCurrentBuild, fileContent) {
);
}

const directiveMatches = unfencedLine.trim().match(directiveParsingRegex);
const directiveMatches = lineWithoutSentinel
.trim()
.match(directiveParsingRegex);

if (!directiveMatches) {
throw new Error(
getInvalidFenceLineMessage(
Expand Down Expand Up @@ -371,10 +378,12 @@ function multiSplice(toSplice, splicingIndices) {
// It iterates over all "end" indices of the array except the last one, and
// pushes the substring between each "end" index and the next "begin" index
// to the array of retained substrings.
for (let i = 1; i < splicingIndices.length; i += 2) {
retainedSubstrings.push(
toSplice.substring(splicingIndices[i], splicingIndices[i + 1]),
);
if (splicingIndices.length > 2) {
for (let i = 1; i < splicingIndices.length; i += 2) {
retainedSubstrings.push(
toSplice.substring(splicingIndices[i], splicingIndices[i + 1]),
);
}
}

// Get the last part to be included
Expand Down
62 changes: 44 additions & 18 deletions development/build/transforms/remove-fenced-code.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,50 @@ describe('build/transforms/remove-fenced-code', () => {
});
});

// This is an edge case for the splicing function
it('transforms file with two fence lines', () => {
expect(
removeFencedCode(
mockFileName,
BuildTypes.flask,
getMinimalFencedCode('main'),
),
).toStrictEqual(['', true]);
});

it('ignores sentinels preceded by non-whitespace', () => {
const validBeginDirective = '///: BEGIN:ONLY_INCLUDE_IN(flask)\n';
const ignoredLines = [
`a ${validBeginDirective}`,
`2 ${validBeginDirective}`,
`@ ${validBeginDirective}`,
];

ignoredLines.forEach((ignoredLine) => {
// These inputs will be transformed
expect(
removeFencedCode(
mockFileName,
BuildTypes.flask,
getMinimalFencedCode('main').concat(ignoredLine),
),
).toStrictEqual([ignoredLine, true]);

const modifiedInputWithoutFences = testData.validInputs.withoutFences.concat(
ignoredLine,
);

// These inputs will not be transformed
expect(
removeFencedCode(
mockFileName,
BuildTypes.flask,
modifiedInputWithoutFences,
),
).toStrictEqual([modifiedInputWithoutFences, false]);
});
});

// Invalid inputs
it('rejects empty fences', () => {
const jsComment = '// A comment\n';
Expand Down Expand Up @@ -177,24 +221,6 @@ describe('build/transforms/remove-fenced-code', () => {
});
});

it('rejects sentinels preceded by non-whitespace', () => {
// Matches the sentinel component of the first line beginning with "///:"
const fenceSentinelRegex = /^\/\/\/:/mu;
const replacements = ['a ///:', '2 ///:', '_ ///:'];

replacements.forEach((replacement) => {
expect(() =>
removeFencedCode(
mockFileName,
BuildTypes.flask,
getMinimalFencedCode().replace(fenceSentinelRegex, replacement),
),
).toThrow(
/Fence sentinel may only appear at the start of a line, optionally preceded by whitespace.$/u,
);
});
});

it('rejects sentinels not followed by a single space and a multi-character alphabetical string', () => {
// Matches the sentinel and terminus component of the first line
// beginning with "///: TERMINUS"
Expand Down

0 comments on commit 892a0a1

Please sign in to comment.