Ticket #1: added support for imposed sorting rules inheritance by subfolders

- bugfix: detection of duplicate specifications for the same folder across multiple (yaml) source files
This commit is contained in:
SebastianMC 2022-08-30 23:25:39 +02:00
parent d798f4a96c
commit 5838a81b9c
3 changed files with 34 additions and 8 deletions

View File

@ -957,6 +957,24 @@ describe('SortingSpecProcessor error detection and reporting', () => {
}) })
}) })
const txtInputTargetFolderCCC: string = `
target-folder: CCC
`
describe('SortingSpecProcessor advanced error detection', () => {
it('should retain state of duplicates detection in the instance', () => {
let processor: SortingSpecProcessor = new SortingSpecProcessor(errorsLogger);
errorsLogger.mockReset()
const inputTxtArr: Array<string> = txtInputTargetFolderCCC.split('\n')
const result1 = processor.parseSortSpecFromText(inputTxtArr, 'another-mock-folder', 'sortspec.md')
const result2 = processor.parseSortSpecFromText(inputTxtArr, 'mock-folder', 'custom-name-note.md')
expect(result1).not.toBeNull()
expect(result2).toBeNull()
expect(errorsLogger).toHaveBeenCalledTimes(1)
expect(errorsLogger).toHaveBeenCalledWith(`${ERR_PREFIX} 2:DuplicateSortSpecForSameFolder Duplicate sorting spec for folder CCC ${ERR_SUFFIX}`)
})
})
describe('convertPlainStringSortingGroupSpecToArraySpec', () => { describe('convertPlainStringSortingGroupSpecToArraySpec', () => {
let processor: SortingSpecProcessor; let processor: SortingSpecProcessor;
beforeEach(() => { beforeEach(() => {

View File

@ -359,6 +359,11 @@ export class SortingSpecProcessor {
problemAlreadyReportedForCurrentLine: boolean problemAlreadyReportedForCurrentLine: boolean
recentErrorMessage: string recentErrorMessage: string
// Helper map to deal with rule priorities for the same path
// and also detect non-wildcard duplicates.
// The wildcard duplicates were detected prior to this point, no need to bother about them
pathMatchPriorityForPath: {[key: string]: WildcardPriority} = {}
// Logger parameter exposed to support unit testing of error cases as well as capturing error messages // Logger parameter exposed to support unit testing of error cases as well as capturing error messages
// for in-app presentation // for in-app presentation
constructor(private errorLogger?: typeof console.log) { constructor(private errorLogger?: typeof console.log) {
@ -370,10 +375,17 @@ export class SortingSpecProcessor {
sortingSpecFileName: string, sortingSpecFileName: string,
collection?: SortSpecsCollection collection?: SortSpecsCollection
): SortSpecsCollection { ): SortSpecsCollection {
// reset / init processing state after potential previous invocation
this.ctx = { this.ctx = {
folderPath: folderPath, // location of the sorting spec file folderPath: folderPath, // location of the sorting spec file
specs: [] specs: []
}; };
this.currentEntryLine = null
this.currentEntryLineIdx = null
this.currentSortingSpecContainerFilePath = null
this.problemAlreadyReportedForCurrentLine = null
this.recentErrorMessage = null
let success: boolean = false; let success: boolean = false;
let lineIdx: number = 0; let lineIdx: number = 0;
for (let entryLine of text) { for (let entryLine of text) {
@ -439,11 +451,6 @@ export class SortingSpecProcessor {
collection.sortSpecByWildcard = sortspecByWildcard collection.sortSpecByWildcard = sortspecByWildcard
} }
// Helper transient map to deal with rule priorities for the same path
// and also detect non-wildcard duplicates.
// The wildcard duplicates were detected prior to this point, no need to bother about them
const pathMatchPriorityForPath: {[key: string]: WildcardPriority} = {}
for (let spec of this.ctx.specs) { for (let spec of this.ctx.specs) {
for (let idx = 0; idx < spec.targetFoldersPaths.length; idx++) { for (let idx = 0; idx < spec.targetFoldersPaths.length; idx++) {
const originalPath = spec.targetFoldersPaths[idx] const originalPath = spec.targetFoldersPaths[idx]
@ -452,7 +459,7 @@ export class SortingSpecProcessor {
let path: string let path: string
[path, detectedWildcardPriority] = stripWildcardPatternSuffix(originalPath) [path, detectedWildcardPriority] = stripWildcardPatternSuffix(originalPath)
let storeTheSpec: boolean = true let storeTheSpec: boolean = true
const preexistingSortSpecPriority: WildcardPriority = pathMatchPriorityForPath[path] const preexistingSortSpecPriority: WildcardPriority = this.pathMatchPriorityForPath[path]
if (preexistingSortSpecPriority) { if (preexistingSortSpecPriority) {
if (preexistingSortSpecPriority === WildcardPriority.NO_WILDCARD && detectedWildcardPriority === WildcardPriority.NO_WILDCARD) { if (preexistingSortSpecPriority === WildcardPriority.NO_WILDCARD && detectedWildcardPriority === WildcardPriority.NO_WILDCARD) {
this.problem(ProblemCode.DuplicateSortSpecForSameFolder, `Duplicate sorting spec for folder ${path}`) this.problem(ProblemCode.DuplicateSortSpecForSameFolder, `Duplicate sorting spec for folder ${path}`)
@ -464,7 +471,7 @@ export class SortingSpecProcessor {
} }
if (storeTheSpec) { if (storeTheSpec) {
collection.sortSpecByPath[path] = spec collection.sortSpecByPath[path] = spec
pathMatchPriorityForPath[path] = detectedWildcardPriority this.pathMatchPriorityForPath[path] = detectedWildcardPriority
} }
} }
} }

View File

@ -55,6 +55,8 @@ export default class CustomSortPlugin extends Plugin {
let errorMessage: string let errorMessage: string
// reset cache // reset cache
this.sortSpecCache = null this.sortSpecCache = null
const processor: SortingSpecProcessor = new SortingSpecProcessor()
Vault.recurseChildren(this.app.vault.getRoot(), (file: TAbstractFile) => { Vault.recurseChildren(this.app.vault.getRoot(), (file: TAbstractFile) => {
if (failed) return if (failed) return
if (file instanceof TFile) { if (file instanceof TFile) {
@ -68,7 +70,6 @@ export default class CustomSortPlugin extends Plugin {
const sortingSpecTxt: string = mCache.getCache(aFile.path)?.frontmatter?.[SORTINGSPEC_YAML_KEY] const sortingSpecTxt: string = mCache.getCache(aFile.path)?.frontmatter?.[SORTINGSPEC_YAML_KEY]
if (sortingSpecTxt) { if (sortingSpecTxt) {
anySortingSpecFound = true anySortingSpecFound = true
const processor: SortingSpecProcessor = new SortingSpecProcessor()
this.sortSpecCache = processor.parseSortSpecFromText( this.sortSpecCache = processor.parseSortSpecFromText(
sortingSpecTxt.split('\n'), sortingSpecTxt.split('\n'),
parent.path, parent.path,