Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 71 additions & 13 deletions src/lib/Route/Route.svelte.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,8 +458,17 @@ function routeBindingTestsForUniverse(setup: ReturnType<typeof createRouterTestS
});

// Navigate to a matching path - determine URL format based on routing mode
const shouldUseHash = (ru.defaultHash === true) || (hash === true) || (typeof hash === 'string');
location.url.href = shouldUseHash ? "http://example.com/#/user/123" : "http://example.com/user/123";
const url = (() => {
if (hash === false) return "http://example.com/user/123"; // Path routing
if (hash === true) return "http://example.com/#/user/123"; // Single hash routing
if (typeof hash === 'string') return `http://example.com/#${hash}=/user/123`; // Multi-hash routing
// Implicit routing
if (ru.defaultHash === false) return "http://example.com/user/123"; // Implicit path routing
if (ru.defaultHash === true) return "http://example.com/#/user/123"; // Implicit single hash routing
if (typeof ru.defaultHash === 'string') return `http://example.com/#${ru.defaultHash}=/user/123`; // Implicit multi-hash routing
return "http://example.com/user/123"; // Default to path routing
})();
location.url.href = url;
await vi.waitFor(() => {});

// Assert.
Expand Down Expand Up @@ -494,8 +503,16 @@ function routeBindingTestsForUniverse(setup: ReturnType<typeof createRouterTestS
});

// Navigate to a matching path - determine URL format based on routing mode
const shouldUseHash = (ru.defaultHash === true) || (hash === true) || (typeof hash === 'string');
location.url.href = shouldUseHash ? "http://example.com/#/about" : "http://example.com/about";
const url = (() => {
if (hash === false) return "http://example.com/about";
if (hash === true) return "http://example.com/#/about";
if (typeof hash === 'string') return `http://example.com/#${hash}=/about`;
if (ru.defaultHash === false) return "http://example.com/about";
if (ru.defaultHash === true) return "http://example.com/#/about";
if (typeof ru.defaultHash === 'string') return `http://example.com/#${ru.defaultHash}=/about`;
return "http://example.com/about";
})();
location.url.href = url;
await vi.waitFor(() => {});

// Assert.
Expand Down Expand Up @@ -524,8 +541,16 @@ function routeBindingTestsForUniverse(setup: ReturnType<typeof createRouterTestS
});

// Navigate to a non-matching path - determine URL format based on routing mode
const shouldUseHash = (ru.defaultHash === true) || (hash === true) || (typeof hash === 'string');
location.url.href = shouldUseHash ? "http://example.com/#/other" : "http://example.com/other";
const url = (() => {
if (hash === false) return "http://example.com/other";
if (hash === true) return "http://example.com/#/other";
if (typeof hash === 'string') return `http://example.com/#${hash}=/other`;
if (ru.defaultHash === false) return "http://example.com/other";
if (ru.defaultHash === true) return "http://example.com/#/other";
if (typeof ru.defaultHash === 'string') return `http://example.com/#${ru.defaultHash}=/other`;
return "http://example.com/other";
})();
location.url.href = url;
await vi.waitFor(() => {});

// Assert.
Expand All @@ -552,8 +577,16 @@ function routeBindingTestsForUniverse(setup: ReturnType<typeof createRouterTestS
});

// Navigate to first matching path - determine URL format based on routing mode
const shouldUseHash = (ru.defaultHash === true) || (hash === true) || (typeof hash === 'string');
location.url.href = shouldUseHash ? "http://example.com/#/user/123" : "http://example.com/user/123";
const url = (() => {
if (hash === false) return "http://example.com/user/123";
if (hash === true) return "http://example.com/#/user/123";
if (typeof hash === 'string') return `http://example.com/#${hash}=/user/123`;
if (ru.defaultHash === false) return "http://example.com/user/123";
if (ru.defaultHash === true) return "http://example.com/#/user/123";
if (typeof ru.defaultHash === 'string') return `http://example.com/#${ru.defaultHash}=/user/123`;
return "http://example.com/user/123";
})();
location.url.href = url;
await vi.waitFor(() => {});

const firstParams = capturedParams;
Expand All @@ -567,7 +600,16 @@ function routeBindingTestsForUniverse(setup: ReturnType<typeof createRouterTestS
expect(firstParams).toEqual({ id: 123 }); // Number due to auto-conversion

// Act - Navigate to different matching path
location.url.href = shouldUseHash ? "http://example.com/#/user/456" : "http://example.com/user/456";
const url2 = (() => {
if (hash === false) return "http://example.com/user/456";
if (hash === true) return "http://example.com/#/user/456";
if (typeof hash === 'string') return `http://example.com/#${hash}=/user/456`;
if (ru.defaultHash === false) return "http://example.com/user/456";
if (ru.defaultHash === true) return "http://example.com/#/user/456";
if (typeof ru.defaultHash === 'string') return `http://example.com/#${ru.defaultHash}=/user/456`;
return "http://example.com/user/456";
})();
location.url.href = url2;
await vi.waitFor(() => {});

// Assert.
Expand Down Expand Up @@ -595,8 +637,16 @@ function routeBindingTestsForUniverse(setup: ReturnType<typeof createRouterTestS
});

// Navigate to a matching path - determine URL format based on routing mode
const shouldUseHash = (ru.defaultHash === true) || (hash === true) || (typeof hash === 'string');
location.url.href = shouldUseHash ? "http://example.com/#/user/123/post/456" : "http://example.com/user/123/post/456";
const url = (() => {
if (hash === false) return "http://example.com/user/123/post/456";
if (hash === true) return "http://example.com/#/user/123/post/456";
if (typeof hash === 'string') return `http://example.com/#${hash}=/user/123/post/456`;
if (ru.defaultHash === false) return "http://example.com/user/123/post/456";
if (ru.defaultHash === true) return "http://example.com/#/user/123/post/456";
if (typeof ru.defaultHash === 'string') return `http://example.com/#${ru.defaultHash}=/user/123/post/456`;
return "http://example.com/user/123/post/456";
})();
location.url.href = url;
await vi.waitFor(() => {});

// Assert.
Expand Down Expand Up @@ -631,8 +681,16 @@ function routeBindingTestsForUniverse(setup: ReturnType<typeof createRouterTestS
});

// Navigate to a matching path - determine URL format based on routing mode
const shouldUseHash = (ru.defaultHash === true) || (hash === true) || (typeof hash === 'string');
location.url.href = shouldUseHash ? "http://example.com/#/files/documents/readme.txt" : "http://example.com/files/documents/readme.txt";
const url = (() => {
if (hash === false) return "http://example.com/files/documents/readme.txt";
if (hash === true) return "http://example.com/#/files/documents/readme.txt";
if (typeof hash === 'string') return `http://example.com/#${hash}=/files/documents/readme.txt`;
if (ru.defaultHash === false) return "http://example.com/files/documents/readme.txt";
if (ru.defaultHash === true) return "http://example.com/#/files/documents/readme.txt";
if (typeof ru.defaultHash === 'string') return `http://example.com/#${ru.defaultHash}=/files/documents/readme.txt`;
return "http://example.com/files/documents/readme.txt";
})();
location.url.href = url;
await vi.waitFor(() => {});

// Assert.
Expand Down
2 changes: 1 addition & 1 deletion src/lib/kernel/LocationFull.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ describe("LocationFull", () => {
// Assert.
expect(location.getState(ALL_HASHES.path)).toEqual(state.path);
expect(location.getState(ALL_HASHES.single)).toEqual(state.hash.single);
expect(location.getState('p1')).toEqual(state.hash.p1);
expect(location.getState('tp')).toEqual(state.hash.tp);
});
});
});
10 changes: 8 additions & 2 deletions src/lib/kernel/RouterEngine.svelte.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { routePatternsKey, RouterEngine } from "./RouterEngine.svelte.js";
import { init } from "../init.js";
import { registerRouter } from "./trace.svelte.js";
import { location } from "./Location.js";
import type { State, RouteInfo, ExtendedRoutingOptions } from "../types.js";
import type { State, RouteInfo, ExtendedRoutingOptions, PatternRouteInfo } from "../types.js";
import { setupBrowserMocks, addRoutes, ROUTING_UNIVERSES, ALL_HASHES } from "$test/test-utils.js";
import { resetRoutingOptions, setRoutingOptions } from "./options.js";

Expand Down Expand Up @@ -295,7 +295,13 @@ ROUTING_UNIVERSES.forEach(universe => {
expectedState = state.hash[universe.hash];
} else {
// For implicit modes (hash === undefined), the behavior depends on defaultHash
expectedState = universe.defaultHash === false ? state.path : state.hash.single;
if (universe.defaultHash === false) {
expectedState = state.path;
} else if (universe.defaultHash === true) {
expectedState = state.hash.single;
} else if (typeof universe.defaultHash === 'string') {
expectedState = state.hash[universe.defaultHash];
}
}
expect(router.state).toBe(expectedState);
});
Expand Down
29 changes: 25 additions & 4 deletions src/lib/kernel/calculateHref.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe("calculateHref", () => {

const basePath = "/base/path";
const baseHash = universe.hashMode === 'multi'
? "#p1=path/one;p2=path/two"
? `#${universe.hash || universe.defaultHash}=path/one;p2=path/two`
: "#base/hash";

beforeEach(() => {
Expand All @@ -69,6 +69,11 @@ describe("calculateHref", () => {
if (universe.hash === ALL_HASHES.path) return '/sample/path';
if (universe.hash === ALL_HASHES.single) return '#/sample/path';
if (universe.hash === ALL_HASHES.implicit) {
// Handle implicit routing
if (universe.hashMode === 'multi' && typeof universe.defaultHash === 'string') {
// IMHR - implicit multi-hash routing
return `#${universe.defaultHash}=/sample/path;p2=path/two`;
}
return universe.defaultHash === false ? '/sample/path' : '#/sample/path';
}
// Multi-hash routing - preserves existing paths and adds/updates the specified hash
Expand All @@ -87,6 +92,11 @@ describe("calculateHref", () => {
if (universe.hash === ALL_HASHES.path) return `/sample/path${baseHash}`;
if (universe.hash === ALL_HASHES.single) return '#/sample/path';
if (universe.hash === ALL_HASHES.implicit) {
// Handle implicit routing
if (universe.hashMode === 'multi' && typeof universe.defaultHash === 'string') {
// IMHR - implicit multi-hash routing
return `#${universe.defaultHash}=/sample/path;p2=path/two`;
}
return universe.defaultHash === false ? `/sample/path${baseHash}` : '#/sample/path';
}
// Multi-hash routing - preserveHash doesn't apply to hash routing
Expand Down Expand Up @@ -121,6 +131,11 @@ describe("calculateHref", () => {
if (universe.hash === ALL_HASHES.path) return newPath;
if (universe.hash === ALL_HASHES.single) return `#${newPath}`;
if (universe.hash === ALL_HASHES.implicit) {
// Handle implicit routing
if (universe.hashMode === 'multi' && typeof universe.defaultHash === 'string') {
// IMHR - implicit multi-hash routing
return `#${universe.defaultHash}=${newPath};p2=path/two`;
}
return universe.defaultHash === false ? newPath : `#${newPath}`;
}
// Multi-hash routing
Expand Down Expand Up @@ -165,8 +180,8 @@ describe("calculateHref", () => {
test("Should preserve all existing paths when updating an existing path", () => {
// Arrange
const newPath = "/sample/path";
const existingHashId = 'p1';
const expected = baseHash.replace(/(p1=).+;/i, `$1${newPath};`);
const existingHashId = universe.hash || universe.defaultHash; // Use the universe's hash ID
const expected = baseHash.replace(new RegExp(`(${existingHashId}=)[^;]+`), `$1${newPath}`);

// Act
const href = calculateHref({ hash: existingHashId }, newPath);
Expand All @@ -182,7 +197,13 @@ describe("calculateHref", () => {
test("Should resolve implicit hash according to defaultHash", () => {
// Arrange
const newPath = "/sample/path";
const expectedHref = universe.defaultHash === false ? newPath : `#${newPath}`;
const expectedHref = (() => {
if (universe.hashMode === 'multi' && typeof universe.defaultHash === 'string') {
// IMHR - implicit multi-hash routing
return `#${universe.defaultHash}=${newPath};p2=path/two`;
}
return universe.defaultHash === false ? newPath : `#${newPath}`;
})();

// Act
const href = calculateHref({ hash: universe.hash }, newPath);
Expand Down
18 changes: 12 additions & 6 deletions src/lib/kernel/calculateState.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ describe('calculateState', () => {
const newState = calculateState(ALL_HASHES.path, { path: 'new' });

// Assert - All existing hash states should be preserved
if (universe.text === 'IMP') {
// IMP universe may not have existing state from setup
if (universe.text === 'IPR') {
// IPR universe may not have existing state from setup
expect(newState).toEqual({
path: { path: 'new' },
hash: {}
Expand All @@ -145,8 +145,8 @@ describe('calculateState', () => {
const newState = calculateState(ALL_HASHES.single, { single: 'new' });

// Assert - Path and other hash states should be preserved
if (universe.text === 'IMP') {
// IMP universe may not have existing state from setup
if (universe.text === 'IPR') {
// IPR universe may not have existing state from setup
expect(newState).toEqual({
path: undefined,
hash: { single: { single: 'new' } }
Expand Down Expand Up @@ -235,13 +235,19 @@ describe('calculateState', () => {
// Act - use single-parameter overload for implicit mode
const newState = calculateState(testState);

// Assert - calculateState preserves existing state
// Assert - calculateState preserves existing state and updates correct universe
if (universe.defaultHash === false) {
// Implicit resolves to path routing
expect(newState.path).toEqual(testState);
expect(newState.hash).toBeDefined(); // Hash state preserved
} else {
} else if (universe.defaultHash === true) {
// Implicit resolves to single hash routing
expect(newState.hash.single).toEqual(testState);
expect(newState.path).toBeDefined(); // Path state preserved
} else if (typeof universe.defaultHash === 'string') {
// Implicit resolves to multi-hash routing with specific hash ID
expect(newState.hash[universe.defaultHash]).toEqual(testState);
expect(newState.path).toBeDefined(); // Path state preserved
}
});
});
Expand Down
2 changes: 1 addition & 1 deletion src/lib/kernel/resolveHashValue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe("resolveHashValue", () => {
expect(result).toBe(newDefaultHash);
});
test.each<Hash>([
'p1',
'tp',
false,
true
])("Should return the provided hash %s value when defined.", (hash) => {
Expand Down
Loading