Skip to content

Commit 0c7505b

Browse files
committed
add test
1 parent 9e469c3 commit 0c7505b

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

src/router.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,13 @@ export function Router(props) {
133133
if (vnode.props.default) d = cloneElement(vnode, m);
134134
});
135135
const isHydratingSuspense = cur.current && cur.current.__u & MODE_HYDRATE && cur.current.__u & MODE_SUSPENDED;
136+
const isHydratingBool = cur.current && cur.current.__h;
136137
cur.current = h(RouteContext.Provider, { value: m }, pr || d);
137138
if (isHydratingSuspense) {
138139
cur.current.__u |= MODE_HYDRATE;
139140
cur.current.__u |= MODE_SUSPENDED;
140-
141+
} else if (isHydratingBool) {
142+
cur.current.__h = true;
141143
}
142144

143145
// Reset previous children - if rendering succeeds synchronously, we shouldn't render the previous children.
@@ -165,7 +167,13 @@ export function Router(props) {
165167
// Successful route transition: un-suspend after a tick and stop rendering the old route:
166168
prev.current = null;
167169
if (cur.current) {
170+
if (suspendedVNode.__h) {
171+
// _hydrating
172+
cur.current.__h = suspendedVNode.__h;
173+
}
174+
168175
if (suspendedVNode.__u & MODE_SUSPENDED) {
176+
// _flags
169177
cur.current.__u |= MODE_SUSPENDED;
170178
}
171179

test/router.test.js

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { jest, describe, it, beforeEach, expect } from '@jest/globals';
2-
import { h, render } from 'preact';
2+
import { h, hydrate, render } from 'preact';
33
import { useState } from 'preact/hooks';
44
import { html } from 'htm/preact';
55
import { LocationProvider, Router, useLocation, Route, useRoute } from '../src/router.js';
@@ -616,3 +616,60 @@ describe('Router', () => {
616616
replaceState.mockRestore();
617617
});
618618
});
619+
620+
describe('hydration', () => {
621+
let scratch;
622+
beforeEach(() => {
623+
if (scratch) {
624+
render(null, scratch);
625+
scratch.remove();
626+
}
627+
scratch = document.createElement('scratch');
628+
document.body.appendChild(scratch);
629+
history.replaceState(null, null, '/');
630+
});
631+
632+
it('should wait for asynchronous routes', async () => {
633+
scratch.innerHTML = '<div><h1>A</h1><p>hello</p></div>';
634+
const route = name => html`
635+
<div>
636+
<h1>${name}</h1>
637+
<p>hello</p>
638+
</div>
639+
`;
640+
const A = jest.fn(groggy(() => route('A'), 1));
641+
let loc;
642+
hydrate(
643+
html`
644+
<${ErrorBoundary}>
645+
<${LocationProvider}>
646+
<${Router}>
647+
<${A} path="/" />
648+
<//>
649+
<${() => {
650+
loc = useLocation();
651+
}} />
652+
<//>
653+
<//>
654+
`,
655+
scratch
656+
);
657+
658+
const mutations = [];
659+
const mutationObserver = new MutationObserver((x) => {
660+
mutations.push(...x)
661+
});
662+
mutationObserver.observe(scratch, { childList: true, subtree: true });
663+
664+
expect(scratch).toHaveProperty('innerHTML', '<div><h1>A</h1><p>hello</p></div>');
665+
expect(A).toHaveBeenCalledWith({ path: '/', query: {}, params: {}, rest: '' }, expect.anything());
666+
667+
A.mockClear();
668+
await sleep(10);
669+
await sleep(10);
670+
671+
expect(scratch).toHaveProperty('innerHTML', '<div><h1>A</h1><p>hello</p></div>');
672+
expect(A).toHaveBeenCalledWith({ path: '/', query: {}, params: {}, rest: '' }, expect.anything());
673+
expect(mutations).toHaveLength(0);
674+
});
675+
})

0 commit comments

Comments
 (0)