diff --git a/src/component/component.ts b/src/component/component.ts
index 93fa3ec7..942f2dea 100644
--- a/src/component/component.ts
+++ b/src/component/component.ts
@@ -373,6 +373,9 @@ export class Component
+
+
+
+ `;
+ static components = { B };
+ state = useState({ fromA: 1 });
+ }
+ const a = new A();
+ await a.mount(fixture);
+ expect(fixture.innerHTML).toBe(
+ " 123
123
" + ); + + // trigger a re-rendering from C, which will remap its new fiber + c!.state.fromC += 10; + // trigger a re-rendering from B, which will remap its new fiber as well + b!.state.fromB += 10; + + await nextTick(); + // at this point, all re-renderings should have been done correctly, and + // the root fiber (A) counter should have been reset to 0, so the DOM should + // have been patched with the updated version of each component + expect(fixture.innerHTML).toBe( + "111213
" + ); + }); + + test("concurrent renderings scenario 15", async () => { + let b: B | undefined = undefined; + let c: C | undefined = undefined; + class C extends Component { + static template = xml` ++ + + +
`; + + state = useState({ fromC: 3 }); + constructor(parent, props) { + super(parent, props); + c = this; + } + } + class B extends Component { + static template = xml``; + static components = { B }; + state = useState({ fromA: 1 }); + } + const a = new A(); + await a.mount(fixture); + expect(fixture.innerHTML).toBe( + "
123
" + ); + + // trigger a re-rendering of the whole tree + a.state.fromA += 10; + // wait enough for the whole tree to be re-rendered, but not patched yet + await nextMicroTick(); + await nextMicroTick(); + await nextMicroTick(); + await nextMicroTick(); + await nextMicroTick(); + expect(fixture.innerHTML).toBe( + "123
" + ); + + // trigger a re-rendering from C, which will remap its new fiber + c!.state.fromC += 10; + // trigger a re-rendering from B, which will remap its new fiber as well + b!.state.fromB += 10; + + // simulate a flush (nothing should have changed as no fiber should have its + // counter to 0) + Component.scheduler.flush(); + expect(fixture.innerHTML).toBe( + "123
" + ); + + // wait a bit and simulate another flush (we expect nothing to change as well) + await nextMicroTick(); + Component.scheduler.flush(); + expect(fixture.innerHTML).toBe( + "123
" + ); + + await nextTick(); + expect(fixture.innerHTML).toBe( + "111213
" + ); + }); + + test("concurrent renderings scenario 16", async () => { + expect.assertions(4); + let b: B | undefined = undefined; + let c: C | undefined = undefined; + class D extends Component { + static template = xml`
+
+
+
+
`; + static components = { B }; + state = useState({ fromA: 1 }); + } + const a = new A(); + await a.mount(fixture); + expect(fixture.innerHTML).toBe( + "
123
" + ); + + // trigger a re-rendering of the whole tree + a.state.fromA += 10; + // wait enough for the whole tree to be re-rendered, but not patched yet + await nextMicroTick(); + await nextMicroTick(); + await nextMicroTick(); + await nextMicroTick(); + await nextMicroTick(); + expect(fixture.innerHTML).toBe( + "123
" + ); + + // trigger a re-rendering from C, which will remap its new fiber + c!.state.fromC += 10; + const prom = c!.render().then(() => { + expect(fixture.innerHTML).toBe( + "111213
123
" + ); + await prom; + }); + test("change state and call manually render: no unnecessary rendering", async () => { class Widget extends Component { static template = xml`