Extracted and extended a basic integration test

This commit is contained in:
SebastianMC 2024-02-19 10:40:38 +01:00
parent 2c3de3d609
commit 702fe9e027
4 changed files with 190 additions and 99 deletions

View File

@ -618,6 +618,22 @@ export const sortOrderNeedsBookmarksOrder = (...orders: Array<CustomSortOrder |
export type ModifiedTime = number export type ModifiedTime = number
export type CreatedTime = number export type CreatedTime = number
// TODO: determine how to selectively unmock the Vault.recurseChildren in integration jest test.
// Until then the implementation for testing is supplied explicitly below, copied from Obsidian code
const recurseChildrenForUnitTests = ((root: TFolder, cb: (file: TAbstractFile) => any) => {
for (let itemsToIterate: TAbstractFile[] = [root]; itemsToIterate.length > 0;) {
let firstItem = itemsToIterate.pop();
if (firstItem) {
cb(firstItem)
if (isFolder(firstItem)) {
let childrenOfFolder = (firstItem as TFolder).children;
itemsToIterate = itemsToIterate.concat(childrenOfFolder)
}
}
}
})
export const determineDatesForFolder = (folder: TFolder, recursive?: boolean): [ModifiedTime, CreatedTime] => { export const determineDatesForFolder = (folder: TFolder, recursive?: boolean): [ModifiedTime, CreatedTime] => {
let mtimeOfFolder: ModifiedTime = DEFAULT_FOLDER_MTIME let mtimeOfFolder: ModifiedTime = DEFAULT_FOLDER_MTIME
let ctimeOfFolder: CreatedTime = DEFAULT_FOLDER_CTIME let ctimeOfFolder: CreatedTime = DEFAULT_FOLDER_CTIME
@ -635,7 +651,7 @@ export const determineDatesForFolder = (folder: TFolder, recursive?: boolean): [
} }
if (recursive) { if (recursive) {
Vault.recurseChildren(folder, checkFile) (Vault?.recurseChildren ?? recurseChildrenForUnitTests)(folder, checkFile)
} else { } else {
folder.children.forEach((item) => checkFile(item)) folder.children.forEach((item) => checkFile(item))
} }

View File

@ -0,0 +1,112 @@
import {
TAbstractFile,
TFolder,
Vault
} from "obsidian";
import {
DEFAULT_FOLDER_CTIME,
determineFolderDatesIfNeeded,
determineSortingGroup,
FolderItemForSorting
} from "../../custom-sort/custom-sort";
import {
CustomSortGroupType,
CustomSortOrder,
CustomSortSpec
} from "../../custom-sort/custom-sort-types";
import {
TIMESTAMP_OLDEST,
TIMESTAMP_NEWEST,
mockTFolderWithChildren, TIMESTAMP_DEEP_NEWEST, TIMESTAMP_DEEP_OLDEST
} from "../mocks";
describe('determineFolderDatesIfNeeded', () => {
it('should not be triggered if not needed - sorting method does not require it', () => {
// given
const folder: TFolder = mockTFolderWithChildren('Test folder 1')
const OUTSIDERS_GROUP_IDX = 0
const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'],
groups: [{
type: CustomSortGroupType.Outsiders,
order: CustomSortOrder.alphabetical
}],
outsidersGroupIdx: OUTSIDERS_GROUP_IDX
}
// when
const result: FolderItemForSorting = determineSortingGroup(folder, sortSpec)
determineFolderDatesIfNeeded([result], sortSpec)
// then
expect(result.ctime).toEqual(DEFAULT_FOLDER_CTIME)
expect(result.mtime).toEqual(DEFAULT_FOLDER_CTIME)
})
it.each(
[
[CustomSortOrder.byCreatedTimeReverseAdvanced, undefined],
[CustomSortOrder.byCreatedTimeAdvanced, undefined],
[CustomSortOrder.byModifiedTimeAdvanced, undefined],
[CustomSortOrder.byModifiedTimeReverseAdvanced, undefined],
[CustomSortOrder.alphabetical, CustomSortOrder.byCreatedTimeReverseAdvanced],
[CustomSortOrder.alphabetical, CustomSortOrder.byCreatedTimeAdvanced],
[CustomSortOrder.alphabetical, CustomSortOrder.byModifiedTimeAdvanced],
[CustomSortOrder.alphabetical, CustomSortOrder.byModifiedTimeReverseAdvanced],
])('should correctly determine dates, if triggered by %s under default %s (no deep orders requested)', (order: CustomSortOrder, folderOrder: CustomSortOrder | undefined) => {
// given
const folder: TFolder = mockTFolderWithChildren('Test folder 1')
const OUTSIDERS_GROUP_IDX = 0
const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'],
defaultOrder: folderOrder,
groups: [{
type: CustomSortGroupType.Outsiders,
order: order
}],
outsidersGroupIdx: OUTSIDERS_GROUP_IDX
}
// when
const result: FolderItemForSorting = determineSortingGroup(folder, sortSpec)
determineFolderDatesIfNeeded([result], sortSpec)
// then
expect(result.ctime).toEqual(TIMESTAMP_OLDEST)
expect(result.mtime).toEqual(TIMESTAMP_NEWEST)
})
it.each(
[
[CustomSortOrder.alphabetical, CustomSortOrder.byCreatedTimeReverseAdvancedRecursive],
[CustomSortOrder.alphabetical, CustomSortOrder.byCreatedTimeAdvancedRecursive],
[CustomSortOrder.alphabetical, CustomSortOrder.byModifiedTimeAdvancedRecursive],
[CustomSortOrder.alphabetical, CustomSortOrder.byModifiedTimeReverseAdvancedRecursive],
[CustomSortOrder.byCreatedTimeReverseAdvancedRecursive, CustomSortOrder.byCreatedTimeReverseAdvanced],
[CustomSortOrder.byCreatedTimeAdvancedRecursive, CustomSortOrder.byCreatedTimeAdvanced],
[CustomSortOrder.byModifiedTimeAdvancedRecursive, CustomSortOrder.byModifiedTimeAdvanced],
[CustomSortOrder.byModifiedTimeReverseAdvancedRecursive, CustomSortOrder.byModifiedTimeReverseAdvanced],
])('should correctly determine dates, if triggered by %s under default %s (deep orders)', (order: CustomSortOrder, folderOrder: CustomSortOrder | undefined) => {
// given
const folder: TFolder = mockTFolderWithChildren('Test folder 1')
const OUTSIDERS_GROUP_IDX = 0
const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'],
defaultOrder: folderOrder,
groups: [{
type: CustomSortGroupType.Outsiders,
order: order
}],
outsidersGroupIdx: OUTSIDERS_GROUP_IDX
}
// when
const result: FolderItemForSorting = determineSortingGroup(folder, sortSpec)
determineFolderDatesIfNeeded([result], sortSpec)
// then
expect(result.ctime).toEqual(TIMESTAMP_DEEP_OLDEST)
expect(result.mtime).toEqual(TIMESTAMP_DEEP_NEWEST)
})
})

55
src/test/mocks.ts Normal file
View File

@ -0,0 +1,55 @@
import {
TFile,
TFolder,
Vault
} from "obsidian";
export const mockTFile = (basename: string, ext: string, size?: number, ctime?: number, mtime?: number): TFile => {
return {
stat: {
ctime: ctime ?? 0,
mtime: mtime ?? 0,
size: size ?? 0
},
basename: basename,
extension: ext,
vault: {} as Vault, // To satisfy TS typechecking
path: `Some parent folder/${basename}.${ext}`,
name: `${basename}.${ext}`,
parent: {} as TFolder // To satisfy TS typechecking
}
}
export const mockTFolder = (name: string, children?: Array<TFolder|TFile>, parent?: TFolder): TFolder => {
return {
isRoot(): boolean { return name === '/' },
vault: {} as Vault, // To satisfy TS typechecking
path: `${name}`,
name: name,
parent: parent ?? ({} as TFolder), // To satisfy TS typechecking
children: children ?? []
}
}
export const MOCK_TIMESTAMP: number = 1656417542418
export const TIMESTAMP_OLDEST: number = MOCK_TIMESTAMP
export const TIMESTAMP_DEEP_OLDEST: number = TIMESTAMP_OLDEST - 1000
export const TIMESTAMP_NEWEST: number = MOCK_TIMESTAMP + 1000
export const TIMESTAMP_DEEP_NEWEST: number = TIMESTAMP_NEWEST + 1000
export const TIMESTAMP_INBETWEEN: number = MOCK_TIMESTAMP + 500
export const mockTFolderWithChildren = (name: string): TFolder => {
const subchild1: TFile = mockTFile('Sub-child file 1 created as deep oldest, modified recently', 'md', 100, TIMESTAMP_DEEP_OLDEST, TIMESTAMP_NEWEST)
const subfolder1: TFolder = mockTFolder('Subfolder with deep-oldest child file', [subchild1])
const subchild2: TFile = mockTFile('Sub-child file 1 created as deep newest, modified recently', 'md', 100, TIMESTAMP_OLDEST, TIMESTAMP_DEEP_NEWEST)
const subfolder2: TFolder = mockTFolder('Subfolder with deep-newest child file', [subchild2])
const child1: TFolder = mockTFolder('Section A')
const child2: TFolder = mockTFolder('Section B')
const child3: TFile = mockTFile('Child file 1 created as oldest, modified recently', 'md', 100, TIMESTAMP_OLDEST, TIMESTAMP_NEWEST)
const child4: TFile = mockTFile('Child file 2 created as newest, not modified at all', 'md', 100, TIMESTAMP_NEWEST, TIMESTAMP_NEWEST)
const child5: TFile = mockTFile('Child file 3 created inbetween, modified inbetween', 'md', 100, TIMESTAMP_INBETWEEN, TIMESTAMP_INBETWEEN)
return mockTFolder(name, [child1, child2, child3, child4, child5, subfolder1, subfolder2])
}

View File

@ -43,48 +43,12 @@ import {
ObsidianIconFolder_PluginInstance, ObsidianIconFolder_PluginInstance,
ObsidianIconFolderPlugin_Data ObsidianIconFolderPlugin_Data
} from "../../utils/ObsidianIconFolderPluginSignature"; } from "../../utils/ObsidianIconFolderPluginSignature";
import {
const mockTFile = (basename: string, ext: string, size?: number, ctime?: number, mtime?: number): TFile => { MOCK_TIMESTAMP,
return { mockTFile,
stat: { mockTFolder,
ctime: ctime ?? 0, mockTFolderWithChildren
mtime: mtime ?? 0, } from "../mocks";
size: size ?? 0
},
basename: basename,
extension: ext,
vault: {} as Vault, // To satisfy TS typechecking
path: `Some parent folder/${basename}.${ext}`,
name: `${basename}.${ext}`,
parent: {} as TFolder // To satisfy TS typechecking
}
}
const mockTFolder = (name: string, children?: Array<TFolder|TFile>, parent?: TFolder): TFolder => {
return {
isRoot(): boolean { return name === '/' },
vault: {} as Vault, // To satisfy TS typechecking
path: `${name}`,
name: name,
parent: parent ?? ({} as TFolder), // To satisfy TS typechecking
children: children ?? []
}
}
const MOCK_TIMESTAMP: number = 1656417542418
const TIMESTAMP_OLDEST: number = MOCK_TIMESTAMP
const TIMESTAMP_NEWEST: number = MOCK_TIMESTAMP + 1000
const TIMESTAMP_INBETWEEN: number = MOCK_TIMESTAMP + 500
const mockTFolderWithChildren = (name: string): TFolder => {
const child1: TFolder = mockTFolder('Section A')
const child2: TFolder = mockTFolder('Section B')
const child3: TFile = mockTFile('Child file 1 created as oldest, modified recently', 'md', 100, TIMESTAMP_OLDEST, TIMESTAMP_NEWEST)
const child4: TFile = mockTFile('Child file 2 created as newest, not modified at all', 'md', 100, TIMESTAMP_NEWEST, TIMESTAMP_NEWEST)
const child5: TFile = mockTFile('Child file 3 created inbetween, modified inbetween', 'md', 100, TIMESTAMP_INBETWEEN, TIMESTAMP_INBETWEEN)
return mockTFolder(name, [child1, child2, child3, child4, child5])
}
const MockedLoc: Pos = { const MockedLoc: Pos = {
start: {col:0,offset:0,line:0}, start: {col:0,offset:0,line:0},
@ -2520,62 +2484,6 @@ describe('determineSortingGroup', () => {
}) })
}) })
describe('determineFolderDatesIfNeeded', () => {
it('should not be triggered if not needed - sorting method does not require it', () => {
// given
const folder: TFolder = mockTFolderWithChildren('Test folder 1')
const OUTSIDERS_GROUP_IDX = 0
const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'],
groups: [{
type: CustomSortGroupType.Outsiders,
order: CustomSortOrder.alphabetical
}],
outsidersGroupIdx: OUTSIDERS_GROUP_IDX
}
// when
const result: FolderItemForSorting = determineSortingGroup(folder, sortSpec)
determineFolderDatesIfNeeded([result], sortSpec)
// then
expect(result.ctime).toEqual(DEFAULT_FOLDER_CTIME)
expect(result.mtime).toEqual(DEFAULT_FOLDER_CTIME)
})
it.each(
[
[CustomSortOrder.byCreatedTimeReverseAdvanced, undefined],
[CustomSortOrder.byCreatedTimeAdvanced, undefined],
[CustomSortOrder.byModifiedTimeAdvanced, undefined],
[CustomSortOrder.byModifiedTimeReverseAdvanced, undefined],
[CustomSortOrder.alphabetical, CustomSortOrder.byCreatedTimeReverseAdvanced],
[CustomSortOrder.alphabetical, CustomSortOrder.byCreatedTimeAdvanced],
[CustomSortOrder.alphabetical, CustomSortOrder.byModifiedTimeAdvanced],
[CustomSortOrder.alphabetical, CustomSortOrder.byModifiedTimeReverseAdvanced]
])('should correctly determine dates, if triggered by %s under default %s', (order: CustomSortOrder, folderOrder: CustomSortOrder | undefined) => {
// given
const folder: TFolder = mockTFolderWithChildren('Test folder 1')
const OUTSIDERS_GROUP_IDX = 0
const sortSpec: CustomSortSpec = {
targetFoldersPaths: ['/'],
defaultOrder: folderOrder,
groups: [{
type: CustomSortGroupType.Outsiders,
order: order
}],
outsidersGroupIdx: OUTSIDERS_GROUP_IDX
}
// when
const result: FolderItemForSorting = determineSortingGroup(folder, sortSpec)
determineFolderDatesIfNeeded([result], sortSpec)
// then
expect(result.ctime).toEqual(TIMESTAMP_OLDEST)
expect(result.mtime).toEqual(TIMESTAMP_NEWEST)
})
})
describe('matchGroupRegex', () => { describe('matchGroupRegex', () => {
it( 'should correctly handle no match', () => { it( 'should correctly handle no match', () => {
// given // given