Skip to content

Commit

Permalink
Fix partial class replace operation
Browse files Browse the repository at this point in the history
  • Loading branch information
rob-gordon committed May 8, 2023
1 parent 1fc6023 commit 9f82d79
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 12 deletions.
23 changes: 23 additions & 0 deletions graph-selector/src/operate/operate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,27 @@ describe("operate", () => {
}),
).toBe("hello .world");
});

/* This test is combatting a specific bug found in the wild. */
test("can add/remove classes from edges with similar names", () => {
const classes = ["triangle", "source-triangle-tee", "source-circle-triangle"];

// removes all classes and then adds one
function addClass(text: string, c: string) {
let newText = operate(text, {
lineNumber: 1,
operation: ["removeClassesFromEdge", { classNames: classes }],
});
newText = operate(newText, {
lineNumber: 1,
operation: ["addClassesToEdge", { classNames: [c] }],
});
return newText;
}

let text = " foo";
text = addClass(text, "source-triangle-tee");
text = addClass(text, "source-circle-triangle");
expect(text).toBe(" .source-circle-triangle: foo");
});
});
32 changes: 23 additions & 9 deletions graph-selector/src/operate/removeClassesFromEdge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,27 @@ describe("removeClassesFromEdge", () => {
expect(result).toBe(" edge: container {");
});

it.todo("should not remove partial class");
// 👇
// it("should not remove partial class", () => {
// const result = removeClassesFromEdge({
// line: " .some-class edge: my node",
// classNames: ["some"],
// });
// expect(result).toBe(" .some-class edge: my node");
// });
it("should not remove partial class", () => {
const result = removeClassesFromEdge({
line: " .some-class edge: my node",
classNames: ["some"],
});
expect(result).toBe(" .some-class edge: my node");
});

it("should not remove partial class when valid part of label", () => {
const result = removeClassesFromEdge({
line: " period.cool: my node",
classNames: ["cool"],
});
expect(result).toBe(" period.cool: my node");
});

it("doesn't remove class from node obviously", () => {
const result = removeClassesFromEdge({
line: " my node .some-class",
classNames: ["some-class"],
});
expect(result).toBe(" my node .some-class");
});
});
28 changes: 26 additions & 2 deletions graph-selector/src/operate/removeClassesFromEdge.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getEdgeBreakIndex } from "../regexps";
import { getEdgeBreakIndex, getFeaturesIndex } from "../regexps";

export function removeClassesFromEdge({
line,
Expand Down Expand Up @@ -29,9 +29,33 @@ export function removeClassesFromEdge({
line = line.slice(edgeBreakIndex + 1);
}

// need to check for start of label
// if label start is before feature data start, then everything that
// looks like a feature is actually in the label
// and we don't have anything to change
if (edge.trim()) {
const labelStart = /\w/.exec(edge)?.index ?? -1;
const featuresStart = getFeaturesIndex(edge);
if (labelStart < featuresStart) {
return indent + edge + line + containerStart;
}
}

// remove class names from edge
for (const className of classNames) {
edge = edge.replace(new RegExp(`\.${className}`), "");
// match class and stop character
const match = new RegExp(`\.${className}(?<stopCharacter>\\.|$| |:|:)`).exec(edge);
// if it's not there, continue
if (!match) continue;

// get stop character
const stopCharacter = match.groups?.stopCharacter || "";

// get the index of the match
const index = match.index;

// remove the match up to the stop character
edge = edge.slice(0, index) + stopCharacter + edge.slice(index + match[0].length);
}

// remove leading whitespace before beginning of line if it exists
Expand Down
9 changes: 9 additions & 0 deletions graph-selector/src/operate/removeClassesFromNode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,13 @@ describe("removeClassFromNode", () => {
});
expect(line).toBe("hello {");
});

test("doesn't remove a partial class", () => {
let line = "hello .some-class";
line = removeClassesFromNode({
line,
classNames: ["some"],
});
expect(line).toBe("hello .some-class");
});
});
14 changes: 13 additions & 1 deletion graph-selector/src/operate/removeClassesFromNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,19 @@ export function removeClassesFromNode({

// remove class names
for (const className of classNames) {
line = line.replace(new RegExp(`\.${className}`), "");
// need to match class and stop character to avoid partial matching
const match = new RegExp(`\.${className}(?<stopCharacter>\\.|$| |:|:)`).exec(line);
// if no match, continue
if (!match) continue;

// get the stop character
const stopCharacter = match.groups?.stopCharacter || "";

// get the index of the match
const index = match.index;

// remove the match up to the stop character
line = line.slice(0, index) + stopCharacter + line.slice(index + match[0].length);
}

// remove trailing whitespace before end of line if it exists
Expand Down

0 comments on commit 9f82d79

Please sign in to comment.