test: add unit tests for next/document shim#319
Conversation
commit: |
|
/bigbonk review |
| describe("Head", () => { | ||
| it("injects default charset and viewport meta tags", () => { | ||
| const html = render(React.createElement(Head)); | ||
| expect(html).toContain('charSet="utf-8"'); |
There was a problem hiding this comment.
This works today because React's renderToString preserves the JSX prop name charSet (camelCase) in the output HTML attribute. If React ever normalizes this to the standard HTML charset (lowercase), this assertion would break. Not a real concern for now since React has been consistent about this, but worth noting.
If you wanted to be resilient, you could match the actual <meta> element more broadly, e.g.:
| expect(html).toContain('charSet="utf-8"'); | |
| expect(html).toMatch(/charset/i); | |
| expect(html).toContain('content="width=device-width, initial-scale=1"'); |
That said, matching exactly what the source renders is also a reasonable choice — you'd want the test to break if React changes the output, so you can update the shim accordingly.
|
Review posted. Here's a summary of my feedback on PR #319: Overall: Good PR. The tests are well-structured, correctly verify the placeholder contracts that Comments posted:
|
Cover Html, Head, Main, NextScript, and default Document with renderToString assertions for attributes, children, placeholder content, and correct nesting order.
1928625 to
5d79dc1
Compare
|
/bigbonk review |
There was a problem hiding this comment.
Clean, well-scoped test file. The tests correctly verify the placeholder contracts that dev-server.ts, index.ts, and static-export.ts all depend on for string replacement. All 7 tests pass. The structural ordering test in "Default Document" is particularly valuable — it would catch regressions in component nesting that would silently break SSR output.
A couple of minor observations below, none blocking.
| describe("Head", () => { | ||
| it("injects default charset and viewport meta tags", () => { | ||
| const html = render(React.createElement(Head)); | ||
| expect(html).toContain('charSet="utf-8"'); |
There was a problem hiding this comment.
The charSet="utf-8" assertion is correct — that's what React 18/19's renderToString produces for <meta charSet="utf-8" />. This is the right thing to assert against since the source shim (document.tsx:29) uses the JSX charSet prop, and renderToString preserves it as-is in the attribute output.
The prior review suggested matching case-insensitively to be resilient against React changes, but I agree with the PR author's approach: if React ever changes how it serializes this attribute, we'd want the test to fail so we can investigate whether the dev-server's string replacements are affected.
| it("renders the __NEXT_SCRIPTS__ comment that dev-server replaces with hydration scripts", () => { | ||
| const html = render(React.createElement(NextScript)); | ||
| // Dev-server replaces this HTML comment with __NEXT_DATA__ + module script tags | ||
| expect(html).toContain("<!-- __NEXT_SCRIPTS__ -->"); |
There was a problem hiding this comment.
Worth noting: the dev-server replaces the exact string "<!-- __NEXT_SCRIPTS__ -->" (with the space padding inside the comment). If someone ever changed the shim to use <!--__NEXT_SCRIPTS__--> (no spaces), the dev-server would silently stop replacing it. This test correctly pins the exact format, which is good — it would catch that kind of drift.
| expect(bodyOpen).toBeLessThan(mainDiv); | ||
| expect(mainDiv).toBeLessThan(placeholder); | ||
| expect(placeholder).toBeLessThan(scripts); | ||
| expect(scripts).toBeLessThan(bodyClose); |
There was a problem hiding this comment.
Minor: this checks that __NEXT_SCRIPTS__ comes before </body>, but doesn't assert that </body> itself is present (only that indexOf returns something). If </body> were somehow missing, indexOf would return -1, and scripts < -1 would fail — so it does catch it indirectly. Just noting for clarity.
Also, the bodyClose variable is declared on line 72 but only used here. Since it's only needed for one assertion, you could inline it, but the current style is fine for readability.
|
Review submitted. Here's a summary of my review on PR #319: Verdict: Approved The PR adds a well-structured test file ( Key observations in my review:
The |
Summary
next/documentshim components (Main,NextScript,Head, defaultDocument)Mainrendersid="__next"with__NEXT_MAIN__placeholder (dev-server replaces with page content)NextScriptrenders<!-- __NEXT_SCRIPTS__ -->comment (dev-server replaces with hydration scripts)Headinjects default charset + viewport meta, preserves custom childrenDocumentassembles all sub-components in the correct nesting order (head < body < main < scripts)Test plan
npx vitest run tests/document.test.ts— 5/5 passing