mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-28 11:16:37 +08:00
93 lines
3.1 KiB
TypeScript
93 lines
3.1 KiB
TypeScript
import {
|
|
DEFAULT_LIBRARY_LIST_SORT_FIELD,
|
|
DEFAULT_LIBRARY_LIST_SORT_ORDER,
|
|
readLibraryListSort,
|
|
sortLibrariesByField,
|
|
sortLibraryPreviewsByField,
|
|
} from './libraryListSort.ts'
|
|
import type { Library } from '../types/index.ts'
|
|
|
|
function check(name: string, condition: boolean) {
|
|
if (!condition) throw new Error(`libraryListSort: ${name}`)
|
|
}
|
|
|
|
function lib(id: string, name: string, sortOrder = 0): Library {
|
|
return { id, name, sort_order: sortOrder } as Library
|
|
}
|
|
|
|
const ordered = (libs: Library[]) => libs.map((item) => item.id).join(',')
|
|
|
|
// 首页默认就是「库名倒序」,所以没写过偏好时要拿到 name/desc。
|
|
const fallback = readLibraryListSort()
|
|
check(
|
|
'default preference is name descending',
|
|
fallback.field === 'name' && fallback.order === 'desc',
|
|
)
|
|
check(
|
|
'default constants stay in sync with the fallback',
|
|
DEFAULT_LIBRARY_LIST_SORT_FIELD === 'name' && DEFAULT_LIBRARY_LIST_SORT_ORDER === 'desc',
|
|
)
|
|
|
|
const alpha = [lib('a', '动画'), lib('b', '电影'), lib('c', '纪录片')]
|
|
// zh-CN 拼音升序是 电影(b) → 动画(a) → 纪录片(c)。
|
|
check(
|
|
'name descending is the default order',
|
|
ordered(sortLibrariesByField(alpha, [], 'name', 'desc')) === 'c,a,b',
|
|
)
|
|
check(
|
|
'name ascending reverses it',
|
|
ordered(sortLibrariesByField(alpha, [], 'name', 'asc')) === 'b,a,c',
|
|
)
|
|
|
|
const manual = [lib('a', '动画', 2), lib('b', '电影', 0), lib('c', '纪录片', 1)]
|
|
check(
|
|
'manual order ascending follows sort_order',
|
|
ordered(sortLibrariesByField(manual, [], 'sort_order', 'asc')) === 'b,c,a',
|
|
)
|
|
check(
|
|
'manual order descending flips sort_order',
|
|
ordered(sortLibrariesByField(manual, [], 'sort_order', 'desc')) === 'a,c,b',
|
|
)
|
|
|
|
// 置顶只决定分组:置顶库整体在前,组内仍然按当前字段/方向排。
|
|
check(
|
|
'pinned libraries always come first',
|
|
ordered(sortLibrariesByField(alpha, ['c'], 'name', 'desc')) === 'c,a,b',
|
|
)
|
|
check(
|
|
'pinned group is sorted by the active field too',
|
|
ordered(sortLibrariesByField(alpha, ['a', 'c'], 'name', 'desc')) === 'c,a,b',
|
|
)
|
|
check(
|
|
'pinned ids that no longer exist are ignored',
|
|
ordered(sortLibrariesByField(alpha, ['missing'], 'name', 'desc')) === 'c,a,b',
|
|
)
|
|
|
|
// 同名时按 sort_order 兜底,再按 id 兜底,保证顺序稳定。
|
|
const sameName = [lib('b', '动画', 1), lib('a', '动画', 1), lib('c', '动画', 0)]
|
|
check(
|
|
'equal names fall back to sort_order then id',
|
|
ordered(sortLibrariesByField(sameName, [], 'name', 'desc')) === 'c,a,b',
|
|
)
|
|
|
|
check('single library is returned as-is', sortLibrariesByField([lib('a', '动画')], [], 'name', 'desc').length === 1)
|
|
|
|
const previews = [
|
|
{ library: lib('a', '动画'), total: 1 },
|
|
{ library: lib('b', '电影'), total: 2 },
|
|
]
|
|
check(
|
|
'previews follow the library order',
|
|
sortLibraryPreviewsByField(previews, [], 'name', 'desc').map((item) => item.library.id).join(',') === 'a,b',
|
|
)
|
|
check(
|
|
'previews keep their payload after sorting',
|
|
sortLibraryPreviewsByField(previews, [], 'name', 'desc')[0].total === 1,
|
|
)
|
|
check(
|
|
'previews respect pinning',
|
|
sortLibraryPreviewsByField(previews, ['b'], 'name', 'desc').map((item) => item.library.id).join(',') === 'b,a',
|
|
)
|
|
|
|
console.log('libraryListSort.test.ts ok')
|