Skip to content

Commit

Permalink
[FIX] Folder ignore sorts all folder starting with string (#972)
Browse files Browse the repository at this point in the history
* Implement isEqualOrSubPath

* Implement UnitTest for isEqualOrSubPath

* Replace separators with system seperator

* Improved seperator replacement
  • Loading branch information
4Source authored Jul 20, 2024
1 parent b175d22 commit 1dfd52e
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { NoteEaseCalculator } from "./NoteEaseCalculator";
import { DeckTreeStatsCalculator } from "./DeckTreeStatsCalculator";
import { NoteEaseList } from "./NoteEaseList";
import { QuestionPostponementList } from "./QuestionPostponementList";
import { isEqualOrSubPath } from "./util/utils";

interface PluginData {
settings: SRSettings;
Expand Down Expand Up @@ -379,7 +380,7 @@ export default class SRPlugin extends Plugin {
for (const noteFile of notes) {
if (
this.data.settings.noteFoldersToIgnore.some((folder) =>
noteFile.path.startsWith(folder),
isEqualOrSubPath(noteFile.path, folder),
)
) {
continue;
Expand Down Expand Up @@ -567,7 +568,11 @@ export default class SRPlugin extends Plugin {
fileCachedData.frontmatter || {};

const tags = getAllTags(fileCachedData) || [];
if (this.data.settings.noteFoldersToIgnore.some((folder) => note.path.startsWith(folder))) {
if (
this.data.settings.noteFoldersToIgnore.some((folder) =>
isEqualOrSubPath(note.path, folder),
)
) {
new Notice(t("NOTE_IN_IGNORED_FOLDER"));
return;
}
Expand Down
33 changes: 33 additions & 0 deletions src/util/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import moment from "moment";
import { Moment } from "moment";
import { normalize, sep } from "path";
import { PREFERRED_DATE_FORMAT, YAML_FRONT_MATTER_REGEX } from "src/constants";

type Hex = number;
Expand Down Expand Up @@ -96,6 +97,38 @@ export function stringTrimStart(str: string): [string, string] {
return [ws, trimmed];
}

/**
* Checks a path is equal or a subpath of the other rootPath
*
* @param toCheck The path to check it is equal or a subpath of path.
* @param rootPath The ref path to check the other is equal to or a subpath of this.
* @tutorial
* rootPath = "root/sub/sub2"
* if toCheck = "notRoot/..." -> false
* if toCheck = "root" -> true
* if toCheck = "root/sub" -> true
* if toCheck = "root/s" -> false
*/
export function isEqualOrSubPath(toCheck: string, rootPath: string): boolean {
const rootPathSections = normalize(rootPath.toLowerCase())
.replaceAll(/(\\|\/)/g, sep)
.split(sep)
.filter((p) => p !== "");
const pathSections = normalize(toCheck.toLowerCase())
.replaceAll(/(\\|\/)/g, sep)
.split(sep)
.filter((p) => p !== "");
if (pathSections.length < rootPathSections.length) {
return false;
}
for (let i = 0; i < rootPathSections.length; i++) {
if (rootPathSections[i] !== pathSections[i]) {
return false;
}
}
return true;
}

//
// This returns [frontmatter, content]
//
Expand Down
111 changes: 111 additions & 0 deletions tests/unit/util/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { YAML_FRONT_MATTER_REGEX } from "src/constants";
import {
extractFrontmatter,
findLineIndexOfSearchStringIgnoringWs,
isEqualOrSubPath,
literalStringReplace,
} from "src/util/utils";

Expand Down Expand Up @@ -243,3 +244,113 @@ describe("findLineIndexOfSearchStringIgnoringWs", () => {
expect(findLineIndexOfSearchStringIgnoringWs(lines, "??")).toEqual(2);
});
});

describe("isEqualOrSubPath", () => {
const winSep = "\\";
const linSep = "/";
const root = "root";
const sub_1 = "plugins";
const sub_2 = "obsidian-spaced-repetition";
const sub_3 = "data";
const noMatch = "notRoot";
const caseMatch = "Root";

describe("Windows", () => {
const sep = winSep;
const rootPath = root + sep + sub_1;

test("Upper and lower case letters", () => {
expect(isEqualOrSubPath(caseMatch, root)).toBe(true);
expect(isEqualOrSubPath(caseMatch.toUpperCase(), root)).toBe(true);
});

test("Seperator auto correction", () => {
expect(isEqualOrSubPath(root + winSep + sub_1, rootPath)).toBe(true);
expect(isEqualOrSubPath(root + winSep + sub_1 + winSep, rootPath)).toBe(true);

expect(isEqualOrSubPath(root + linSep + sub_1, rootPath)).toBe(true);
expect(isEqualOrSubPath(root + linSep + sub_1 + linSep, rootPath)).toBe(true);
});

test("Differnent path", () => {
expect(isEqualOrSubPath(noMatch, rootPath)).toBe(false);
expect(isEqualOrSubPath(noMatch + sep, rootPath)).toBe(false);
expect(isEqualOrSubPath(noMatch + sep + sub_1, rootPath)).toBe(false);
expect(isEqualOrSubPath(noMatch + sep + sub_1 + sep + sub_2, rootPath)).toBe(false);
});

test("Partially Match path", () => {
expect(isEqualOrSubPath("roo", rootPath)).toBe(false);
expect(isEqualOrSubPath("roo" + sep, rootPath)).toBe(false);
expect(isEqualOrSubPath(root + sep + "plug", rootPath)).toBe(false);
expect(isEqualOrSubPath(root + sep + "plug" + sep, rootPath)).toBe(false);
});

test("Same path", () => {
expect(isEqualOrSubPath(rootPath, rootPath)).toBe(true);
});

test("Subpath", () => {
expect(isEqualOrSubPath(root, rootPath)).toBe(false);
expect(isEqualOrSubPath(root + sep, rootPath)).toBe(false);
expect(isEqualOrSubPath(root + sep + sub_1, rootPath)).toBe(true);
expect(isEqualOrSubPath(rootPath, rootPath + sep)).toBe(true);
expect(isEqualOrSubPath(rootPath + sep, rootPath)).toBe(true);
expect(isEqualOrSubPath(root + sep + sub_1 + sep, rootPath)).toBe(true);
expect(isEqualOrSubPath(root + sep + sub_1 + sep + sub_2, rootPath)).toBe(true);
expect(isEqualOrSubPath(root + sep + sub_1 + sep + sub_2 + sep, rootPath)).toBe(true);
expect(isEqualOrSubPath(root + sep + sub_1 + sep + sub_2 + sep + sub_3, rootPath)).toBe(
true,
);
});
});
describe("Linux", () => {
const sep = linSep;
const rootPath = root + sep + sub_1;

test("Upper and lower case letters", () => {
expect(isEqualOrSubPath(caseMatch, root)).toBe(true);
expect(isEqualOrSubPath(caseMatch.toUpperCase(), root)).toBe(true);
});

test("Seperator auto correction", () => {
expect(isEqualOrSubPath(root + winSep + sub_1, rootPath)).toBe(true);
expect(isEqualOrSubPath(root + winSep + sub_1 + winSep, rootPath)).toBe(true);

expect(isEqualOrSubPath(root + linSep + sub_1, rootPath)).toBe(true);
expect(isEqualOrSubPath(root + linSep + sub_1 + linSep, rootPath)).toBe(true);
});

test("Differnent path", () => {
expect(isEqualOrSubPath(noMatch, rootPath)).toBe(false);
expect(isEqualOrSubPath(noMatch + sep, rootPath)).toBe(false);
expect(isEqualOrSubPath(noMatch + sep + sub_1, rootPath)).toBe(false);
expect(isEqualOrSubPath(noMatch + sep + sub_1 + sep + sub_2, rootPath)).toBe(false);
});

test("Partially Match path", () => {
expect(isEqualOrSubPath("roo", rootPath)).toBe(false);
expect(isEqualOrSubPath("roo" + sep, rootPath)).toBe(false);
expect(isEqualOrSubPath(root + sep + "plug", rootPath)).toBe(false);
expect(isEqualOrSubPath(root + sep + "plug" + sep, rootPath)).toBe(false);
});

test("Same path", () => {
expect(isEqualOrSubPath(rootPath, rootPath)).toBe(true);
});

test("Subpath", () => {
expect(isEqualOrSubPath(root, rootPath)).toBe(false);
expect(isEqualOrSubPath(root + sep, rootPath)).toBe(false);
expect(isEqualOrSubPath(root + sep + sub_1, rootPath)).toBe(true);
expect(isEqualOrSubPath(rootPath, rootPath + sep)).toBe(true);
expect(isEqualOrSubPath(rootPath + sep, rootPath)).toBe(true);
expect(isEqualOrSubPath(root + sep + sub_1 + sep, rootPath)).toBe(true);
expect(isEqualOrSubPath(root + sep + sub_1 + sep + sub_2, rootPath)).toBe(true);
expect(isEqualOrSubPath(root + sep + sub_1 + sep + sub_2 + sep, rootPath)).toBe(true);
expect(isEqualOrSubPath(root + sep + sub_1 + sep + sub_2 + sep + sub_3, rootPath)).toBe(
true,
);
});
});
});

0 comments on commit 1dfd52e

Please sign in to comment.