44 CompoundDotNumberNormalizerFn ,
55 ConsumedFolderMatchingRegexp ,
66 consumeFolderByRegexpExpression ,
7- convertPlainStringToRegex , Date_dd_Mmm_yyyy_NormalizerFn ,
7+ convertPlainStringToRegex ,
8+ Date_dd_Mmm_yyyy_NormalizerFn ,
89 detectSortingSymbols ,
910 escapeRegexUnsafeCharacters ,
1011 extractSortingSymbol ,
@@ -14,8 +15,14 @@ import {
1415 RomanNumberNormalizerFn ,
1516 SortingSpecProcessor
1617} from "../../custom-sort/sorting-spec-processor"
17- import { CustomSortGroupType , CustomSortOrder , CustomSortSpec , IdentityNormalizerFn } from "../../custom-sort/custom-sort-types" ;
18+ import {
19+ CustomSortGroupType ,
20+ CustomSortOrder ,
21+ CustomSortSpec ,
22+ IdentityNormalizerFn
23+ } from "../../custom-sort/custom-sort-types" ;
1824import { FolderMatchingRegexp , FolderMatchingTreeNode } from "../../custom-sort/folder-matching-rules" ;
25+ import { _unitTests } from "../../custom-sort/mdata-extractors" ;
1926
2027const txtInputExampleA : string = `
2128order-asc: a-z
@@ -356,6 +363,17 @@ const expectedSortSpecsExampleA: { [key: string]: CustomSortSpec } = {
356363 }
357364}
358365
366+ const txtInputExampleSortingSymbols : string = `
367+ /folders Chapter \\.d+ ...
368+ /:files ...section \\-r+.
369+ % Appendix \\-d+ (attachments)
370+ Plain syntax\\R+ ... works?
371+ And this kind of... \\D+plain syntax???
372+ Here goes ASCII word \\a+
373+ \\A+. is for any modern language word
374+ \\[dd-Mmm-yyyy] for the specific date format of 12-Apr-2024
375+ `
376+
359377const expectedSortSpecsExampleSortingSymbols : { [ key : string ] : CustomSortSpec } = {
360378 "mock-folder" : {
361379 groups : [ {
@@ -418,17 +436,67 @@ const expectedSortSpecsExampleSortingSymbols: { [key: string]: CustomSortSpec }
418436 }
419437}
420438
421- const txtInputExampleSortingSymbols : string = `
422- /folders Chapter \\.d+ ...
423- /:files ...section \\-r+.
424- % Appendix \\-d+ (attachments)
425- Plain syntax\\R+ ... works?
426- And this kind of... \\D+plain syntax???
427- Here goes ASCII word \\a+
428- \\A+. is for any modern language word
429- \\[dd-Mmm-yyyy] for the specific date format of 12-Apr-2024
439+ const txtInputExampleMDataExtractors1 : string = `
440+ < a-z by-metadata: created-by using-extractor: date(dd/mm/yyyy)
441+ /folders Chapter...
442+ > a-z by-metadata: updated-on using-extractor: date(mm/dd/yyyy)
443+ `
444+
445+ // Tricky elements captured:
446+ // - Order a-z. for by metadata is transformed to a-z (there is no notion of 'file extension' in metadata values)
447+
448+ const txtInputExampleMDataExtractors2 : string = `
449+ < a-z. by-metadata: created by using-extractor: date(mm/dd/yyyy), < true a-z. by-metadata: using-extractor: date(dd/mm/yyyy)
450+ /folders ...Chapter
451+ > a-z. by-metadata: updated-on using-extractor: date(dd/mm/yyyy), > true a-z by-metadata: md2 using-extractor: date(mm/dd/yyyy)
430452`
431453
454+ const expectedSortSpecsExampleMDataExtractors1 : { [ key : string ] : CustomSortSpec } = {
455+ "mock-folder" : {
456+ defaultOrder : CustomSortOrder . byMetadataFieldAlphabetical ,
457+ byMetadataField : 'created-by' ,
458+ metadataFieldValueExtractor : _unitTests . extractorFnForDate_ddmmyyyy ,
459+ groups : [ {
460+ foldersOnly : true ,
461+ type : CustomSortGroupType . ExactPrefix ,
462+ exactPrefix : 'Chapter' ,
463+ order : CustomSortOrder . byMetadataFieldAlphabeticalReverse ,
464+ byMetadataField : 'updated-on' ,
465+ metadataFieldValueExtractor : _unitTests . extractorFnForDate_mmddyyyy
466+ } , {
467+ type : CustomSortGroupType . Outsiders
468+ } ] ,
469+ targetFoldersPaths : [ 'mock-folder' ] ,
470+ outsidersGroupIdx : 1
471+ }
472+ }
473+
474+ const expectedSortSpecsExampleMDataExtractors2 : { [ key : string ] : CustomSortSpec } = {
475+ "mock-folder" : {
476+ defaultOrder : CustomSortOrder . byMetadataFieldAlphabetical ,
477+ byMetadataField : 'created by' ,
478+ metadataFieldValueExtractor : _unitTests . extractorFnForDate_mmddyyyy ,
479+ defaultSecondaryOrder : CustomSortOrder . byMetadataFieldTrueAlphabetical ,
480+ byMetadataFieldSecondary : '' ,
481+ metadataFieldSecondaryValueExtractor : _unitTests . extractorFnForDate_ddmmyyyy ,
482+ groups : [ {
483+ foldersOnly : true ,
484+ type : CustomSortGroupType . ExactSuffix ,
485+ exactSuffix : 'Chapter' ,
486+ order : CustomSortOrder . byMetadataFieldAlphabeticalReverse ,
487+ byMetadataField : 'updated-on' ,
488+ metadataFieldValueExtractor : _unitTests . extractorFnForDate_ddmmyyyy ,
489+ secondaryOrder : CustomSortOrder . byMetadataFieldTrueAlphabeticalReverse ,
490+ byMetadataFieldSecondary : 'md2' ,
491+ metadataFieldSecondaryValueExtractor : _unitTests . extractorFnForDate_mmddyyyy
492+ } , {
493+ type : CustomSortGroupType . Outsiders
494+ } ] ,
495+ targetFoldersPaths : [ 'mock-folder' ] ,
496+ outsidersGroupIdx : 1
497+ }
498+ }
499+
432500describe ( 'SortingSpecProcessor' , ( ) => {
433501 let processor : SortingSpecProcessor ;
434502 beforeEach ( ( ) => {
@@ -449,6 +517,16 @@ describe('SortingSpecProcessor', () => {
449517 const result = processor . parseSortSpecFromText ( inputTxtArr , 'mock-folder' , 'custom-name-note.md' )
450518 expect ( result ?. sortSpecByPath ) . toEqual ( expectedSortSpecsExampleSortingSymbols )
451519 } )
520+ it ( 'should generate correct SortSpecs (example with mdata extractors)' , ( ) => {
521+ const inputTxtArr : Array < string > = txtInputExampleMDataExtractors1 . split ( '\n' )
522+ const result = processor . parseSortSpecFromText ( inputTxtArr , 'mock-folder' , 'custom-name-note.md' )
523+ expect ( result ?. sortSpecByPath ) . toEqual ( expectedSortSpecsExampleMDataExtractors1 )
524+ } )
525+ it ( 'should generate correct SortSpecs (example with mdata extractors, advanced)' , ( ) => {
526+ const inputTxtArr : Array < string > = txtInputExampleMDataExtractors2 . split ( '\n' )
527+ const result = processor . parseSortSpecFromText ( inputTxtArr , 'mock-folder' , 'custom-name-note.md' )
528+ expect ( result ?. sortSpecByPath ) . toEqual ( expectedSortSpecsExampleMDataExtractors2 )
529+ } )
452530} )
453531
454532const txtInputNotDuplicatedSortSpec : string = `
@@ -2922,6 +3000,17 @@ describe('SortingSpecProcessor error detection and reporting', () => {
29223000 `${ ERR_PREFIX } 7:InvalidAttributeValue Secondary sorting direction order-asc: and desc are contradicting ${ ERR_SUFFIX_IN_LINE ( 2 ) } ` )
29233001 expect ( errorsLogger ) . toHaveBeenNthCalledWith ( 2 , ERR_LINE_TXT ( 'sorting: standard, order-asc: modified desc by-metadata: xyz // <-- and it is checked earlier than the by-metadata incompatible order' ) )
29243002 } )
3003+ it ( 'should reject unknown value extractor' , ( ) => {
3004+ const inputTxtArr : Array < string > = `
3005+ < a-z. by-metadata: created by using-extractor: date(mm/dd/YYYY)
3006+ ` . replace ( / \t / gi, '' ) . split ( '\n' )
3007+ const result = processor . parseSortSpecFromText ( inputTxtArr , 'mock-folder' , 'custom-name-note.md' )
3008+ expect ( result ) . toBeNull ( )
3009+ expect ( errorsLogger ) . toHaveBeenCalledTimes ( 2 )
3010+ expect ( errorsLogger ) . toHaveBeenNthCalledWith ( 1 ,
3011+ `${ ERR_PREFIX } 7:InvalidAttributeValue Primary sorting order contains unrecognized value extractor: >>> date(mm/dd/YYYY) <<< ${ ERR_SUFFIX_IN_LINE ( 2 ) } ` )
3012+ expect ( errorsLogger ) . toHaveBeenNthCalledWith ( 2 , ERR_LINE_TXT ( '< a-z. by-metadata: created by using-extractor: date(mm/dd/YYYY)' ) )
3013+ } )
29253014} )
29263015
29273016const txtInputTargetFolderCCC : string = `
0 commit comments