This:
* Sets the stage for getting suite and spec execution in one place
* Greatly simplifies the interaction between Runner and TreeProcessor
* Focuses TreeProcessor more on building execution trees
All current shipped versions of zone.js contain a monkey patch that fails
to pass constructor arguments on to GlobalErrors. That would crash Jasmine
if it was applied early enough to have any effect.
See <https://github.com/angular/angular/issues/63072>.
This commit attempts to ensure that the timers created by jasmine mock
clock do not conflict with the native timers. This also retains
pre-existing behavior whereby a native scheduled function cannot be
cleared if it was created prior to the mock clock being installed
(unless the mock clock is uninstalled first).
Prior to this commit, attempting to clear a native timer would result in
clearing a mocked scheduled function instead, in some scenarios where
the IDs conflicted.
fixes#2068
This helps make matcher errors and spy strategy mismatch errors easier
to understand in cases where the difference involves expecting one
function but getting a different one.
The autotick feature mistakenly does not account for the clock being a
singleton and the re-installation of the clock causes the auto ticking
exit conditions to become true again, before it has a chance to break.
This is in addition to the existing concatenated name. It's meant to
support tools like IDE integrations that want to be able to filter a
run to an exact set of suites/specs.
This isn't officially compatible with the oldest version of Node that
Jasmine supports, but it works. If it stops working, we can always disable
linting in CI builds on older Node versions.
Testing with mock clocks can often turn into a real struggle when
dealing with situations where some work in the test is truly async and
other work is captured by the mock clock. This can happen for many
reasons, but as one example:
An asynchonrous change from a task in the mocked clock may change DOM where
a resize observer then gets triggered. This browser API is truly asynchronous
and would require the user to wait real time for it to fire. If there is
follow-up work after the resize observer fires, it may be captured by the mock
clock again. This would require the tester to write something like the
following:
```
// flush the timer
jasmine.clock().tick();
// wait for resize observer
await new Promise(resolve => setTimeout(resolve));
// flush follow-up work from the resize observer callback
jasmine.clock().tick();
```
When using mock clocks, testers are always forced to write tests with intimate
knowledge of when the mock clock needs to be ticked. Oftentimes, the
purpose of using a mock clock is to speed up the execution time of the
test when there are timeouts involved. It is not often a goal to test
the exact timeout values. This can cause tests to be riddled with
`tick`. It ideal for test code to be written in a way
that is independent of whether a mock clock is installed. For example:
```
document.getElementById('submit');
// https://testing-library.com/docs/dom-testing-library/api-async/#waitfor
await waitFor(() => expect(mockAPI).toHaveBeenCalledTimes(1))
```
When mock clocks are involved, the above may not be possible if there is
some delay involved between the click and the request to the API.
Instead, developers would need to manually tick the clock beyond the
delay to trigger the API call.
This commit attempts to resolve these issues by adding a feature to the
clock which allows it to advance on its own with the passage of time,
just as clocks do without mocks installed. It also allows for some
breathing time so any unmocked micro and macrotasks are given space to
execute as well.
This feature would also address both #1725 and #1932. `asyncTick` can be
accomplished by enabling the auto tick feature and then waiting for a
promise with a timout to be resolved
(`await new Promise(resolve => setTimeout(resolve, 20))`) where
`setTimeout` is captured by the mock clock and flushed while the code is
waiting for the promise to resolve.
resolves#1725resolves#1932
All credit goes to @stephenfarrar for this.