mirror of
https://github.com/stablyai/orca.git
synced 2026-09-23 16:02:24 +00:00
* fix(file-explorer): sort numbered file names naturally The File Explorer compared names with bare localeCompare, so numbered files listed 100, 200 before 99. Hoist the numeric collator Source Control file rows already use (#10850) into src/shared and apply it to the local and runtime directory listings, the name-filtered view, and Source Control directory nodes, which were inconsistent with the file rows one line below (#11426). * fix(file-explorer): natural sort on SSH funnels, relay, and pickers Adversarial-review round 1 rework: - Both readDir funnels short-circuited to the SSH filesystem provider before the patched sort, so SSH workspaces kept lexicographic order; re-sort locally after the provider returns (the remote relay may be an older build), and fix the relay's own comparator for relay-native consumers. - sortDirEntries (shared, unit-tested) owns the directories-first + natural-order listing contract used by every funnel. - compareFileNames breaks numeric-collation ties ('2' vs '02') by code units so sibling order stays total instead of readdir order, and pins the collator locale to 'en' so every host produces one order. - The SSH folder browser and runtime server dir picker now match the Explorer they browse into. - Ordering pinned by tests at the relay, source-control tree, and shared helper. * fix(mobile): natural sort in the mobile file explorer Mobile re-sorted host readDir results with bare localeCompare, undoing the host funnel's natural order (round-2 review). Reuse the shared comparator and pin the order in the mobile suite. * fix(file-explorer): natural sort at the renderer choke point and remaining ties Round-3 review: the remote-runtime RPC and paired-web routes return the host's order verbatim, so re-sort in readFileExplorerDirectory where every desktop route converges; pin the SSH funnel with a handler-level test; and route Source Control path compares through compareFileNames so numeric-collation ties share one total order with the Explorer. * docs(file-name-sort): state the real perf baseline in the hoist comment * refactor(source-control): drop the dead collator export; pin the test oracle locale * fix(file-listings): cover remaining natural-sort surfaces
63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { compareFileNames, sortDirEntries } from './file-name-sort'
|
|
|
|
describe('compareFileNames', () => {
|
|
it('sorts numeric name segments naturally instead of lexicographically', () => {
|
|
const names = [
|
|
'1 - item.txt',
|
|
'100 - item.txt',
|
|
'2 - item.txt',
|
|
'200 - item.txt',
|
|
'409 - item.txt',
|
|
'41 - item.txt',
|
|
'410 - item.txt',
|
|
'9 - item.txt',
|
|
'99 - item.txt'
|
|
]
|
|
expect([...names].sort(compareFileNames)).toEqual([
|
|
'1 - item.txt',
|
|
'2 - item.txt',
|
|
'9 - item.txt',
|
|
'41 - item.txt',
|
|
'99 - item.txt',
|
|
'100 - item.txt',
|
|
'200 - item.txt',
|
|
'409 - item.txt',
|
|
'410 - item.txt'
|
|
])
|
|
})
|
|
|
|
it('sorts embedded numbers naturally within alphabetical order', () => {
|
|
expect(['b1.md', 'a10.md', 'a2.md', 'a1.md'].sort(compareFileNames)).toEqual([
|
|
'a1.md',
|
|
'a2.md',
|
|
'a10.md',
|
|
'b1.md'
|
|
])
|
|
})
|
|
|
|
it('breaks numeric-collation ties deterministically instead of readdir order', () => {
|
|
// numeric collation ties "2" with "02"; the code-unit fallback keeps a total order.
|
|
expect(['2.txt', '02.txt'].sort(compareFileNames)).toEqual(['02.txt', '2.txt'])
|
|
expect(['02.txt', '2.txt'].sort(compareFileNames)).toEqual(['02.txt', '2.txt'])
|
|
expect(compareFileNames('a.txt', 'a.txt')).toBe(0)
|
|
})
|
|
})
|
|
|
|
describe('sortDirEntries', () => {
|
|
it('keeps directories first, each group in natural order', () => {
|
|
const entries = [
|
|
{ name: '10 - notes', isDirectory: false },
|
|
{ name: '2 - src', isDirectory: true },
|
|
{ name: '9 - docs.txt', isDirectory: false },
|
|
{ name: '10 - assets', isDirectory: true }
|
|
]
|
|
expect(sortDirEntries(entries).map((e) => e.name)).toEqual([
|
|
'2 - src',
|
|
'10 - assets',
|
|
'9 - docs.txt',
|
|
'10 - notes'
|
|
])
|
|
})
|
|
})
|