one
Version:
One is a new React Framework that makes Vite serve both native and web.
345 lines (344 loc) • 8.74 kB
JavaScript
import { describe, expect, it } from "vitest";
import { setClientMatches } from "./useMatches.native.js";
describe("useMatches", function () {
describe("setClientMatches", function () {
it("should update client matches without errors", function () {
var matches = [{
routeId: "/_layout",
pathname: "/",
params: {},
loaderData: {
title: "Root"
}
}, {
routeId: "/page",
pathname: "/page",
params: {},
loaderData: {
content: "Page content"
}
}];
expect(function () {
return setClientMatches(matches);
}).not.toThrow();
});
it("should accept empty matches array", function () {
expect(function () {
return setClientMatches([]);
}).not.toThrow();
});
});
describe("type safety", function () {
it("should have correct RouteMatch type", function () {
var match = {
routeId: "test",
pathname: "/test",
params: {
id: "123"
},
loaderData: {
foo: "bar"
}
};
expect(match.routeId).toBe("test");
expect(match.pathname).toBe("/test");
expect(match.params.id).toBe("123");
expect(match.loaderData).toEqual({
foo: "bar"
});
});
it("should allow string[] params", function () {
var match = {
routeId: "test",
pathname: "/test",
params: {
slugs: ["a", "b", "c"]
},
loaderData: null
};
expect(match.params.slugs).toEqual(["a", "b", "c"]);
});
it("should allow undefined loaderData", function () {
var match = {
routeId: "test",
pathname: "/test",
params: {},
loaderData: void 0
};
expect(match.loaderData).toBeUndefined();
});
});
});
describe("RouteMatch ordering", function () {
it("matches should be ordered parent to child (root layout first)", function () {
var matches = [{
routeId: "/_layout",
pathname: "/",
params: {},
loaderData: {
level: "root"
}
}, {
routeId: "/docs/_layout",
pathname: "/docs",
params: {},
loaderData: {
level: "docs"
}
}, {
routeId: "/docs/intro",
pathname: "/docs/intro",
params: {},
loaderData: {
level: "page"
}
}];
expect(matches[0].routeId).toBe("/_layout");
expect(matches[0].loaderData.level).toBe("root");
expect(matches[1].routeId).toBe("/docs/_layout");
expect(matches[1].loaderData.level).toBe("docs");
expect(matches[2].routeId).toBe("/docs/intro");
expect(matches[2].loaderData.level).toBe("page");
});
it("last match should be the current page", function () {
var matches = [{
routeId: "/_layout",
pathname: "/",
params: {},
loaderData: {}
}, {
routeId: "/page",
pathname: "/page",
params: {
id: "123"
},
loaderData: {
title: "Page"
}
}];
var pageMatch = matches[matches.length - 1];
expect(pageMatch.routeId).toBe("/page");
expect(pageMatch.loaderData.title).toBe("Page");
});
});
describe("setClientMatches reactivity", function () {
it("should notify listeners when matches change", function () {
var notifyCount = 0;
var listener = function () {
notifyCount++;
};
var matches1 = [{
routeId: "/page1",
pathname: "/page1",
params: {},
loaderData: {}
}];
var matches2 = [{
routeId: "/page2",
pathname: "/page2",
params: {},
loaderData: {}
}];
setClientMatches(matches1);
setClientMatches(matches2);
expect(notifyCount).toBe(0);
});
it("should handle multiple sequential updates", function () {
var matches1 = [{
routeId: "/a",
pathname: "/a",
params: {},
loaderData: {
n: 1
}
}];
var matches2 = [{
routeId: "/b",
pathname: "/b",
params: {},
loaderData: {
n: 2
}
}];
var matches3 = [{
routeId: "/c",
pathname: "/c",
params: {},
loaderData: {
n: 3
}
}];
expect(function () {
setClientMatches(matches1);
setClientMatches(matches2);
setClientMatches(matches3);
}).not.toThrow();
});
});
describe("RouteMatch with dynamic params", function () {
it("should handle single dynamic param", function () {
var match = {
routeId: "/users/[id]",
pathname: "/users/123",
params: {
id: "123"
},
loaderData: {
user: {
name: "John"
}
}
};
expect(match.params.id).toBe("123");
});
it("should handle multiple dynamic params", function () {
var match = {
routeId: "/users/[userId]/posts/[postId]",
pathname: "/users/123/posts/456",
params: {
userId: "123",
postId: "456"
},
loaderData: {
post: {
title: "Hello"
}
}
};
expect(match.params.userId).toBe("123");
expect(match.params.postId).toBe("456");
});
it("should handle catch-all params", function () {
var match = {
routeId: "/docs/[...slug]",
pathname: "/docs/getting-started/intro",
params: {
slug: ["getting-started", "intro"]
},
loaderData: {
doc: {
content: "Hello"
}
}
};
expect(match.params.slug).toEqual(["getting-started", "intro"]);
});
});
describe("RouteMatch loaderData scenarios", function () {
it("should handle complex nested loaderData", function () {
var match = {
routeId: "/dashboard",
pathname: "/dashboard",
params: {},
loaderData: {
user: {
id: 1,
profile: {
name: "John",
settings: {
theme: "dark",
notifications: true
}
}
},
posts: [{
id: 1,
title: "Post 1"
}, {
id: 2,
title: "Post 2"
}]
}
};
var data = match.loaderData;
expect(data.user.profile.settings.theme).toBe("dark");
expect(data.posts).toHaveLength(2);
});
it("should handle null loaderData", function () {
var match = {
routeId: "/empty",
pathname: "/empty",
params: {},
loaderData: null
};
expect(match.loaderData).toBeNull();
});
it("should handle array loaderData", function () {
var match = {
routeId: "/list",
pathname: "/list",
params: {},
loaderData: [1, 2, 3, 4, 5]
};
expect(match.loaderData).toEqual([1, 2, 3, 4, 5]);
});
it("should handle primitive loaderData", function () {
var match = {
routeId: "/count",
pathname: "/count",
params: {},
loaderData: 42
};
expect(match.loaderData).toBe(42);
});
});
describe("finding matches", function () {
var createMatches = function () {
return [{
routeId: "/_layout",
pathname: "/",
params: {},
loaderData: {
root: true
}
}, {
routeId: "/docs/_layout",
pathname: "/docs",
params: {},
loaderData: {
navItems: ["intro", "guide"]
}
}, {
routeId: "/docs/[slug]",
pathname: "/docs/intro",
params: {
slug: "intro"
},
loaderData: {
title: "Introduction",
headings: ["h1", "h2"]
}
}];
};
it("should find match by exact routeId", function () {
var matches = createMatches();
var found = matches.find(function (m) {
return m.routeId === "/docs/_layout";
});
expect(found).toBeDefined();
expect(found.loaderData.navItems).toEqual(["intro", "guide"]);
});
it("should find match by routeId pattern", function () {
var matches = createMatches();
var found = matches.find(function (m) {
return m.routeId.includes("_layout");
});
expect(found).toBeDefined();
expect(found.routeId).toBe("/_layout");
});
it("should get page match (last in array)", function () {
var matches = createMatches();
var pageMatch = matches[matches.length - 1];
expect(pageMatch.routeId).toBe("/docs/[slug]");
expect(pageMatch.loaderData.title).toBe("Introduction");
});
it("should get layout match for a page", function () {
var matches = createMatches();
var layoutMatch = matches.find(function (m) {
return m.routeId.includes("/docs/") && m.routeId.includes("_layout");
});
expect(layoutMatch).toBeDefined();
expect(layoutMatch.loaderData.navItems).toBeDefined();
});
});
//# sourceMappingURL=useMatches.test.native.js.map