|
1 | 1 | import { $, _wrapProp, isBrowser } from '@qwik.dev/core'; |
2 | 2 | import { createDocument } from '@qwik.dev/core/testing'; |
3 | | -import { afterEach, beforeEach, describe, expect, expectTypeOf, it } from 'vitest'; |
| 3 | +import { afterEach, beforeEach, describe, expect, expectTypeOf, it, vi } from 'vitest'; |
4 | 4 | import { getDomContainer } from '../../client/dom-container'; |
5 | 5 | import { implicit$FirstArg } from '../../shared/qrl/implicit_dollar'; |
6 | 6 | import { inlinedQrl } from '../../shared/qrl/qrl'; |
@@ -28,6 +28,7 @@ import { |
28 | 28 | import { getSubscriber } from '../subscriber'; |
29 | 29 | import { vnode_newVirtual, vnode_setProp } from '../../client/vnode-utils'; |
30 | 30 | import { ELEMENT_SEQ } from '../../shared/utils/markers'; |
| 31 | +import type { ComputedSignalImpl } from './computed-signal-impl'; |
31 | 32 |
|
32 | 33 | class Foo { |
33 | 34 | constructor(public val: number = 0) {} |
@@ -111,10 +112,12 @@ describe('signal', () => { |
111 | 112 | const log: any[] = []; |
112 | 113 | const delayMap = new Map(); |
113 | 114 | let container: Container = null!; |
| 115 | + let task: Task | null = null; |
114 | 116 | beforeEach(() => { |
115 | 117 | log.length = 0; |
116 | 118 | const document = createDocument({ html: '<html><body q:container="paused"></body></html>' }); |
117 | 119 | container = getDomContainer(document.body); |
| 120 | + task = null; |
118 | 121 | }); |
119 | 122 |
|
120 | 123 | afterEach(async () => { |
@@ -189,25 +192,39 @@ describe('signal', () => { |
189 | 192 | await withContainer(async () => { |
190 | 193 | const a = createSignal(true) as InternalSignal<boolean>; |
191 | 194 | const b = createSignal(true) as InternalSignal<boolean>; |
192 | | - let signal!: InternalReadonlySignal<boolean>; |
| 195 | + let signal!: ComputedSignalImpl<boolean>; |
| 196 | + |
| 197 | + (globalThis as any).waitPromiseResolve = null; |
| 198 | + const waitPromise = new Promise<void>((resolve) => { |
| 199 | + (globalThis as any).waitPromiseResolve = resolve; |
| 200 | + }); |
| 201 | + |
193 | 202 | await retryOnPromise(() => |
194 | 203 | effect$(async () => { |
195 | 204 | signal = |
196 | 205 | signal || |
197 | 206 | createComputedQrl( |
198 | 207 | delayQrl( |
199 | 208 | $(() => { |
200 | | - return a.value || b.value; |
| 209 | + const val = a.value || b.value; |
| 210 | + if (!val) { |
| 211 | + // resolve promise after next macro task |
| 212 | + setTimeout(() => { |
| 213 | + (globalThis as any).waitPromiseResolve!(); |
| 214 | + }); |
| 215 | + } |
| 216 | + return val; |
201 | 217 | }) |
202 | 218 | ) |
203 | 219 | ); |
204 | | - const signalValue = await retryOnPromise(() => signal.value); |
205 | | - log.push(signalValue); // causes subscription |
| 220 | + log.push(signal.value); // causes subscription |
206 | 221 | }) |
207 | 222 | ); |
208 | 223 | expect(log).toEqual([true]); |
209 | 224 | a.value = !a.untrackedValue; |
210 | 225 | b.value = !b.untrackedValue; |
| 226 | + |
| 227 | + await waitPromise; |
211 | 228 | expect(log).toEqual([true, false]); |
212 | 229 | }); |
213 | 230 | }); |
@@ -286,7 +303,7 @@ describe('signal', () => { |
286 | 303 | function effectQrl(fnQrl: QRL<() => void>) { |
287 | 304 | const qrl = fnQrl as QRLInternal<() => void>; |
288 | 305 | const element: HostElement = vnode_newVirtual(); |
289 | | - const task = new Task(0, 0, element, fnQrl as QRLInternal, undefined, null); |
| 306 | + task = task || new Task(0, 0, element, fnQrl as QRLInternal, undefined, null); |
290 | 307 | vnode_setProp(element, ELEMENT_SEQ, [task]); |
291 | 308 | if (!qrl.resolved) { |
292 | 309 | throw qrl.resolve(); |
|
0 commit comments