Skip to content

Commit

Permalink
backport fix for generateStaticParams
Browse files Browse the repository at this point in the history
  • Loading branch information
EvanBacon committed Nov 17, 2023
1 parent 3638006 commit 66af5d5
Show file tree
Hide file tree
Showing 2 changed files with 312 additions and 158 deletions.
195 changes: 163 additions & 32 deletions packages/expo-router/src/__tests__/loadStaticParamsAsync.test.node.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { RouteNode } from "../Route";
import { getExactRoutes } from "../getRoutes";
import { loadStaticParamsAsync } from "../loadStaticParamsAsync";
import {
loadStaticParamsAsync,
assertStaticParams,
} from "../loadStaticParamsAsync";
import { RequireContext } from "../types";

function createMockContextModule(
Expand All @@ -22,6 +25,53 @@ function dropFunctions({ loadRoute, ...node }: RouteNode) {
};
}

describe(assertStaticParams, () => {
it(`asserts parameters do not match supported dynamic properties`, () => {
expect(() =>
assertStaticParams(
{
contextKey: "./[post].tsx",
dynamic: [{ deep: false, name: "post" }],
},
{
shape: "square",
}
)
).toThrowErrorMatchingInlineSnapshot(`
"[./[post].tsx]: generateStaticParams() must return an array of params that match the dynamic route. Expected non-nullish values for key: "post".
Received:
{
"shape": square,
"post": undefined
}"
`);
});
it(`asserts nullish parameters`, () => {
expect(() =>
assertStaticParams(
{
contextKey: "./[post]/[other].tsx",
dynamic: [
{ deep: false, name: "post" },
{ deep: false, name: "other" },
],
},
{
// @ts-expect-error: expected
post: null,
}
)
).toThrowErrorMatchingInlineSnapshot(`
"[./[post]/[other].tsx]: generateStaticParams() must return an array of params that match the dynamic routes. Expected non-nullish values for keys: "post", "other".
Received:
{
"post": null,
"other": undefined
}"
`);
});
});

describe(loadStaticParamsAsync, () => {
it(`evaluates a single dynamic param`, async () => {
const route = getExactRoutes(
Expand Down Expand Up @@ -77,22 +127,26 @@ describe(loadStaticParamsAsync, () => {
});

it(`evaluates with nested dynamic routes`, async () => {
const generateStaticParamsParent = jest.fn(async () => {
return ["red", "blue"].map((color) => ({
color,
}));
});
const generateStaticParams = jest.fn(async ({ params }) => {
return ["square", "triangle"].map((shape) => ({
...params,
shape,
}));
});
const ctx = createMockContextModule({
"./_layout.tsx": { default() {} },
"./[color]/[shape].tsx": {
default() {},
async generateStaticParams({ params }) {
return ["square", "triangle"].map((shape) => ({
...params,
shape,
}));
},
generateStaticParams,
},
"./[color]/_layout.tsx": {
default() {},
generateStaticParams() {
return ["red", "blue"].map((color) => ({ color }));
},
generateStaticParams: generateStaticParamsParent,
},
});
const route = getExactRoutes(ctx);
Expand Down Expand Up @@ -132,18 +186,6 @@ describe(loadStaticParamsAsync, () => {
dynamic: [{ deep: false, name: "shape" }],
route: "[shape]",
},
{
children: [],
contextKey: "./[color]/square.tsx",
dynamic: null,
route: "square",
},
{
children: [],
contextKey: "./[color]/triangle.tsx",
dynamic: null,
route: "triangle",
},
],
contextKey: "./[color]/_layout.tsx",
dynamic: [{ deep: false, name: "color" }],
Expand Down Expand Up @@ -208,6 +250,19 @@ describe(loadStaticParamsAsync, () => {
initialRouteName: undefined,
route: "",
});

expect(generateStaticParamsParent).toBeCalledTimes(1);
expect(generateStaticParamsParent).toHaveBeenNthCalledWith(1, {
params: {},
});

expect(generateStaticParams).toBeCalledTimes(2);
expect(generateStaticParams).toHaveBeenNthCalledWith(1, {
params: { color: "red" },
});
expect(generateStaticParams).toHaveBeenNthCalledWith(2, {
params: { color: "blue" },
});
});

it(`throws when required parameter is missing`, async () => {
Expand All @@ -221,11 +276,84 @@ describe(loadStaticParamsAsync, () => {
},
})
)!;
await expect(
loadStaticParamsAsync(routes)
).rejects.toThrowErrorMatchingInlineSnapshot(
`"generateStaticParams() must return an array of params that match the dynamic route. Received {}"`
);
await expect(loadStaticParamsAsync(routes)).rejects
.toThrowErrorMatchingInlineSnapshot(`
"[./post/[post].tsx]: generateStaticParams() must return an array of params that match the dynamic route. Expected non-nullish values for key: "post".
Received:
{
"post": undefined
}"
`);
});

it(`preserves API routes`, async () => {
const ctx = createMockContextModule({
"./index.tsx": {
default() {},
},
"./foo+api.tsx": {
GET() {},
},
"./[post]+api.tsx": {
POST() {},
},
});

const route = getExactRoutes(ctx, { preserveApiRoutes: true })!;

expect(dropFunctions(route)).toEqual({
children: [
{
children: [],
contextKey: "./index.tsx",
dynamic: null,
route: "index",
},
{
children: [],
contextKey: "./foo+api.tsx",
dynamic: null,
route: "foo",
},
{
children: [],
contextKey: "./[post]+api.tsx",
dynamic: [{ deep: false, name: "post" }],
route: "[post]",
},
],
contextKey: "./_layout.tsx",
dynamic: null,
generated: true,
route: "",
});

expect(dropFunctions(await loadStaticParamsAsync(route))).toEqual({
children: [
{
children: [],
contextKey: "./index.tsx",
dynamic: null,
route: "index",
},
{
children: [],
contextKey: "./foo+api.tsx",
dynamic: null,
route: "foo",
},
{
children: [],
contextKey: "./[post]+api.tsx",
dynamic: [{ deep: false, name: "post" }],
route: "[post]",
},
],
contextKey: "./_layout.tsx",
dynamic: null,
generated: true,
route: "",
});
});

it(`evaluates with nested deep dynamic segments`, async () => {
Expand Down Expand Up @@ -510,11 +638,14 @@ describe(loadStaticParamsAsync, () => {
).rejects.toThrowErrorMatchingInlineSnapshot(
`"generateStaticParams() for route "./post/[...post].tsx" expected param "post" not to be empty while parsing "/"."`
);
await expect(
loadWithParam([{ post: null }])
).rejects.toThrowErrorMatchingInlineSnapshot(
`"generateStaticParams() must return an array of params that match the dynamic route. Received {"post":null}"`
);
await expect(loadWithParam([{ post: null }])).rejects
.toThrowErrorMatchingInlineSnapshot(`
"[./post/[...post].tsx]: generateStaticParams() must return an array of params that match the dynamic route. Expected non-nullish values for key: "post".
Received:
{
"post": null
}"
`);
await expect(
loadWithParam([{ post: false }])
).rejects.toThrowErrorMatchingInlineSnapshot(
Expand Down
Loading

0 comments on commit 66af5d5

Please sign in to comment.