diff --git a/assets/js/live_vue/utils.test.ts b/assets/js/live_vue/utils.test.ts new file mode 100644 index 0000000..4989c73 --- /dev/null +++ b/assets/js/live_vue/utils.test.ts @@ -0,0 +1,88 @@ +import { describe, it, expect } from "vitest" +import { findComponent } from "./utils" +import type { ComponentMap } from "./types" + +describe("findComponent", () => { + const MockComponent = { + template: "
Mock Component
", + } + + const MockCreateWorkspaceComponent = { + template: "
Create Workspace Component
", + } + + it("should find exact component match for 'workspace'", () => { + const components: ComponentMap = { + "../../lib/live_vue/web/pages/workspace.vue": MockComponent, + "../../lib/live_vue/web/pages/create-workspace.vue": MockCreateWorkspaceComponent, + } + + const result = findComponent(components, "workspace") + + expect(result).toBe(MockComponent) + }) + + it("should NOT match 'workspace' to 'create-workspace'", () => { + const components: ComponentMap = { + "../../lib/live_vue/web/pages/create-workspace.vue": MockCreateWorkspaceComponent, + "../../lib/live_vue/web/pages/workspace.vue": MockComponent, + } + + const result = findComponent(components, "workspace") + + expect(result).toBe(MockComponent) + }) + + it("should find 'create-workspace' component when requested", () => { + const components: ComponentMap = { + "../../lib/live_vue/web/pages/workspace.vue": MockComponent, + "../../lib/live_vue/web/pages/create-workspace.vue": MockCreateWorkspaceComponent, + } + + const result = findComponent(components, "create-workspace") + + expect(result).toBe(MockCreateWorkspaceComponent) + }) + + it("should throw error when component is not found", () => { + const components: ComponentMap = { + "../../lib/leuchtturm/web/pages/workspace.vue": MockComponent, + } + + expect(() => findComponent(components, "nonexistent")).toThrow("Component 'nonexistent' not found!") + }) + + it("should handle index.vue files", () => { + const components: ComponentMap = { + "../../lib/live_vue/web/pages/workspace/index.vue": MockComponent, + } + + const result = findComponent(components, "workspace") + + expect(result).toBe(MockComponent) + }) + + it("should handle index.vue files with multiple nested paths", () => { + const components: ComponentMap = { + "../../lib/live_vue/web/pages/admin/workspace/index.vue": MockComponent, + "../../lib/live_vue/web/pages/public/dashboard/index.vue": MockCreateWorkspaceComponent, + } + + const result1 = findComponent(components, "workspace") + const result2 = findComponent(components, "dashboard") + + expect(result1).toBe(MockComponent) + expect(result2).toBe(MockCreateWorkspaceComponent) + }) + + it("should avoid false matches due to substring matching", () => { + const components: ComponentMap = { + "../../lib/live_vue/web/pages/create-workspace.vue": MockCreateWorkspaceComponent, + "../../lib/live_vue/web/pages/workspace.vue": MockComponent, + } + + const result = findComponent(components, "workspace") + + expect(result).toBe(MockComponent) + }) +}) diff --git a/assets/js/live_vue/utils.ts b/assets/js/live_vue/utils.ts index 84e830a..a1c3bdf 100644 --- a/assets/js/live_vue/utils.ts +++ b/assets/js/live_vue/utils.ts @@ -33,9 +33,10 @@ export const flatMapKeys = ( * @returns The component if found, otherwise throws an error with a list of available components. */ export const findComponent = (components: ComponentMap, name: string): ComponentOrComponentPromise => { - // we're looking for a component by name or path suffix. + // we're looking for a component by exact filename match for (const [key, value] of Object.entries(components)) { - if (key.endsWith(`${name}.vue`) || key.endsWith(`${name}/index.vue`)) { + const fileName = key.split('/').pop() // Get the actual filename + if (fileName === `${name}.vue` || (fileName === 'index.vue' && key.endsWith(`/${name}/index.vue`))) { return value } }