* Allows to verify behavior of defer blocks by providing a set of * [time, expected output] pairs. Also allows to provide a function * instead of an expected output string, in which case the function * is invoked at a specified time.
( fixture: ComponentFixture<unknown>, ...slots: Array<[time: number, expected: string | VoidFunction]> )
| 102 | * is invoked at a specified time. |
| 103 | */ |
| 104 | async function verifyTimeline( |
| 105 | fixture: ComponentFixture<unknown>, |
| 106 | ...slots: Array<[time: number, expected: string | VoidFunction]> |
| 107 | ) { |
| 108 | let actualTime = 0; |
| 109 | for (let i = 0; i < slots.length; i++) { |
| 110 | const targetVirtualTime = slots[i][0]; |
| 111 | const slotValue = slots[i][1]; |
| 112 | |
| 113 | if (typeof slotValue === 'function') { |
| 114 | const waitTime = Math.max(0, targetVirtualTime - actualTime); |
| 115 | if (waitTime > 0) { |
| 116 | await timeout(waitTime); |
| 117 | actualTime += waitTime; |
| 118 | } |
| 119 | slotValue(); |
| 120 | } else { |
| 121 | const waitTime = Math.max(0, targetVirtualTime - actualTime); |
| 122 | if (waitTime > 0) { |
| 123 | await timeout(waitTime); |
| 124 | actualTime += waitTime; |
| 125 | } |
| 126 | |
| 127 | let actual = ''; |
| 128 | let waited = 0; |
| 129 | const maxWait = 40; // max ms to poll for the expected state |
| 130 | |
| 131 | while (waited <= maxWait) { |
| 132 | fixture.detectChanges(); |
| 133 | actual = fixture.nativeElement.textContent.trim(); |
| 134 | if (actual === slotValue) { |
| 135 | break; |
| 136 | } |
| 137 | await timeout(1); |
| 138 | waited += 1; |
| 139 | actualTime += 1; |
| 140 | } |
| 141 | |
| 142 | expect(actual).withContext(`${targetVirtualTime}ms (actual ${actualTime}ms)`).toBe(slotValue); |
| 143 | } |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | class FakeTimerScheduler { |
| 148 | cbs: VoidFunction[] = []; |
no test coverage detected