diff --git a/frontend/src/lib/components/breadcrumbPath.test.ts b/frontend/src/lib/components/breadcrumbPath.test.ts new file mode 100644 index 0000000000..987403e2e2 --- /dev/null +++ b/frontend/src/lib/components/breadcrumbPath.test.ts @@ -0,0 +1,20 @@ +import { describe, it, expect } from 'vitest' +import { splitItemPath } from './breadcrumbPath' + +describe('splitItemPath', () => { + it('walks the scope, each subfolder, then the item, each with its cumulative path', () => { + expect(splitItemPath('f/demo/sub/weather_report')).toEqual({ + dirs: [ + { name: 'f/demo', fullPath: 'f/demo' }, + { name: 'sub', fullPath: 'f/demo/sub' } + ], + leaf: { name: 'weather_report', fullPath: 'f/demo/sub/weather_report' } + }) + }) + + it('gives up on a path that names nothing yet, trailing separator included', () => { + // The editor binds the path live, so every keystroke reaches the breadcrumb. + expect(splitItemPath('f/demo')).toBeUndefined() + expect(splitItemPath('f/demo/')).toBeUndefined() + }) +}) diff --git a/frontend/src/lib/components/breadcrumbPath.ts b/frontend/src/lib/components/breadcrumbPath.ts index 8c041518f5..25834181ad 100644 --- a/frontend/src/lib/components/breadcrumbPath.ts +++ b/frontend/src/lib/components/breadcrumbPath.ts @@ -13,6 +13,9 @@ export function splitItemPath(path: string): { dirs: PathDir[]; leaf: PathDir } if (parts.length < 3) return undefined const scope = parts.slice(0, 2).join('/') const slug = parts.slice(2) + // `f/demo/` is three parts but names nothing yet, and a leaf with an empty name draws a blank + // segment. The editor's path is bound live, so the breadcrumb sees every keystroke. + if (slug[slug.length - 1] === '') return undefined const dirs: PathDir[] = [{ name: scope, fullPath: scope }] let acc = scope for (let i = 0; i < slug.length - 1; i++) { diff --git a/frontend/src/lib/components/sidebar/navPages.test.ts b/frontend/src/lib/components/sidebar/navPages.test.ts index 73f5ea456e..6e68912a15 100644 --- a/frontend/src/lib/components/sidebar/navPages.test.ts +++ b/frontend/src/lib/components/sidebar/navPages.test.ts @@ -6,7 +6,7 @@ describe('navPageFor', () => { expect(navPageFor('/base/runs', '/base')?.label).toBe('Runs') }) - it('keeps an item route on its page (longest prefix wins)', () => { + it('keeps an item route on its page', () => { expect(navPageFor('/runs/f/demo/x', '')?.label).toBe('Runs') })