diff --git a/src/custom-sort/sorting-spec-processor.spec.ts b/src/custom-sort/sorting-spec-processor.spec.ts index be656bc..de04efa 100644 --- a/src/custom-sort/sorting-spec-processor.spec.ts +++ b/src/custom-sort/sorting-spec-processor.spec.ts @@ -1,7 +1,7 @@ import { CompoundDashNumberNormalizerFn, CompoundDashRomanNumberNormalizerFn, - CompoundDotNumberNormalizerFn, + CompoundDotNumberNormalizerFn, ConsumedFolderMatchingRegexp, consumeFolderByRegexpExpression, convertPlainStringToRegex, detectNumericSortingSymbols, escapeRegexUnsafeCharacters, @@ -13,7 +13,7 @@ import { SortingSpecProcessor } from "./sorting-spec-processor" import {CustomSortGroupType, CustomSortOrder, CustomSortSpec} from "./custom-sort-types"; -import {FolderMatchingTreeNode} from "./folder-matching-rules"; +import {FolderMatchingRegexp, FolderMatchingTreeNode} from "./folder-matching-rules"; const txtInputExampleA: string = ` order-asc: a-z @@ -849,7 +849,7 @@ const expectedSortSpecForRegexpTextCase = { ] } -const expectedTargetFolderRegexpArr = [ +const expectedTargetFolderRegexpArr: Array> = [ { regexp: /r9 [abc]+/, againstName: true, @@ -944,6 +944,64 @@ describe('SortingSpecProcessor target-folder by name and regex', () => { }) }) +const NOPRIO = 0 +const PRIO1 = 1 +const PRIO2 = 2 +const PRIO3 = 3 + +const consumedTargetFolderRegexp: Array = [ + { + regexp: /r4\d/, + againstName: true, + priority: undefined, + log: true + }, { + regexp: /r4\d/, + againstName: true, + priority: PRIO1, + log: true + }, { + regexp: /r4\d/, + againstName: true, + priority: PRIO2, + log: true + }, { + regexp: /r4\d/, + againstName: true, + priority: PRIO3, + log: true + }, +] + +describe( 'consumeFolderByRegexpExpression', () => { + // and accept priority in any order + // the last one is in effect + // and accept multiple + it.each([ + // Plain cases + ['for-name: /!: debug: r4\\d', PRIO1], + ['for-name: /!: debug: r4\\d', PRIO1], + ['/!!: for-name: debug: r4\\d', PRIO2], + ['/!: debug: for-name: r4\\d', PRIO1], + ['debug: for-name: /!!!: r4\\d', PRIO3], + ['debug: /!: for-name: r4\\d', PRIO1], + // Cases with duplication of same + ['for-name: for-name: /!: debug: r4\\d', PRIO1], + ['for-name: /!: /!: debug: debug: r4\\d', PRIO1], + ['/!!: for-name: /!!: debug: r4\\d', PRIO2], + ['/!: debug: debug: for-name: r4\\d', PRIO1], + ['debug: for-name: /!!!:/!!!: r4\\d', PRIO3], + ['debug: /!: for-name: /!: r4\\d', PRIO1], + // Cases with duplication of different priority + ['debug: /!!!: for-name: /!: r4\\d', PRIO1], + ['debug: /!: for-name: /!!: r4\\d', PRIO2], + ['debug: /!: for-name: /!!: /!!!: /!: /!!!: r4\\d', PRIO3], + ])('should recognize all modifiers in >%s< of priority %s', (regexpExpr: string, prio: number) => { + const result: ConsumedFolderMatchingRegexp = consumeFolderByRegexpExpression(regexpExpr) + expect(result).toEqual(consumedTargetFolderRegexp[prio]) + }) +}) + const txtInputPriorityGroups1: string = ` target-folder: / /:files diff --git a/src/custom-sort/sorting-spec-processor.ts b/src/custom-sort/sorting-spec-processor.ts index 00f1aa6..3aeb28c 100644 --- a/src/custom-sort/sorting-spec-processor.ts +++ b/src/custom-sort/sorting-spec-processor.ts @@ -614,23 +614,33 @@ export const consumeFolderByRegexpExpression = (expression: string): ConsumedFol let priority: number | undefined let logMatches: boolean | undefined - // For simplicity, strict imposed order of regexp-specific attributes - expression = eatPrefixIfPresent(expression, RegexpAgainstFolderName, () => { - againstName = true - }) + let nextRoundNeeded: boolean - for (const priorityPrefix of Object.keys(TargetFolderRegexpPriorityPrefixes)) { - expression = eatPrefixIfPresent(expression, priorityPrefix, () => { - priority = TargetFolderRegexpPriorityPrefixes[priorityPrefix] + do { + nextRoundNeeded = false + + expression = eatPrefixIfPresent(expression, RegexpAgainstFolderName, () => { + againstName = true + nextRoundNeeded = true }) - if (priority) { - break - } - } - expression = eatPrefixIfPresent(expression, DebugFolderRegexMatchesLexeme, () => { - logMatches = true - }) + for (const priorityPrefix of Object.keys(TargetFolderRegexpPriorityPrefixes)) { + let doBreak: boolean = false + expression = eatPrefixIfPresent(expression, priorityPrefix, () => { + priority = TargetFolderRegexpPriorityPrefixes[priorityPrefix] + nextRoundNeeded = true + doBreak = true + }) + if (doBreak) { + break + } + } + + expression = eatPrefixIfPresent(expression, DebugFolderRegexMatchesLexeme, () => { + logMatches = true + nextRoundNeeded = true + }) + } while (nextRoundNeeded) // do not allow empty regexp if (!expression || expression.trim() === '') {