GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — `@angular-devkit/build-angular` breaks Jasmine's mock clock · Issue #11626 · angular/angular-cli

@angular-devkit/build-angular breaks Jasmine's mock clock #11626

New issue
Copy link
New issue
Copy link
Closed
#11627
Closed
@angular-devkit/build-angular breaks Jasmine's mock clock#11626
#11627
Copy link
Labels
area: @angular-devkit/build-angular

Description

@gkalpak
gkalpak
opened on Jul 23, 2018
Issue body actions

Bug Report or Feature Request (mark with an x)

- [x] bug report -> please search issues before submitting
- [ ] feature request

Command (mark with an x)

- [x] test

Versions

> node --version
v8.11.3

> npm --version
5.6.0

> ng --version
Angular CLI: 6.1.0-rc.3
Node: 8.11.3
OS: win32 x64
Angular: 6.0.9
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.7.0-rc.3
@angular-devkit/build-angular     0.7.0-rc.3
@angular-devkit/build-optimizer   0.7.0-rc.3
@angular-devkit/build-webpack     0.7.0-rc.3
@angular-devkit/core              0.7.0-rc.3
@angular-devkit/schematics        0.7.0-rc.3
@angular/cli                      6.1.0-rc.3
@ngtools/webpack                  6.1.0-rc.3
@schematics/angular               0.7.0-rc.3
@schematics/update                0.7.0-rc.3
rxjs                              6.2.2
typescript                        2.7.2
webpack                           4.9.2

OS: Windows 10

Repro steps

  1. npm install --global @angular/cli.
  2. ng new test-app && cd test-app.
  3. npm test --> Passed ✔️
  4. Add a test in src/app/app.component.spec.ts that uses jasmine.clock().install(). E.g.:
    it('should pass', () => {
      jasmine.clock().install();
      expect(true).toBe(true);
      jasmine.clock().uninstall();
    });
  5. npm test --> Fails ❌

    Error: Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?

The log given by the failure

Chrome 67.0.3396 (Windows 10.0.0) AppComponent should pass FAILED
        Error: Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?
            at UserContext.eval (webpack:///./src/app/app.component.spec.ts?:31:25)
            at ZoneDelegate.invoke (webpack:///./node_modules/zone.js/dist/zone.js?:387:26)
            at ProxyZoneSpec.onInvoke (webpack:///./node_modules/zone.js/dist/zone-testing.js?:287:39)
            at ZoneDelegate.invoke (webpack:///./node_modules/zone.js/dist/zone.js?:386:32)
            at Zone.run (webpack:///./node_modules/zone.js/dist/zone.js?:137:43)
            at runInTestZone (webpack:///./node_modules/zone.js/dist/zone-testing.js?:508:34)
Chrome 67.0.3396 (Windows 10.0.0) AppComponent should pass FAILED
        Error: Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?
            at UserContext.eval (webpack:///./src/app/app.component.spec.ts?:31:25)
            at ZoneDelegate.invoke (webpack:///./node_modules/zone.js/dist/zone.js?:387:26)
            at ProxyZoneSpec.onInvoke (webpack:///./node_modules/zone.js/dist/zone-testing.js?:287:39)
            at ZoneDelegate.invoke (webpack:///./node_modules/zone.js/dist/zone.js?:386:32)
            at Zone.run (webpack:///./node_modules/zone.js/dist/zone.js?:137:43)
            at runInTestZone (webpack:///./node_modules/zone.js/dist/zone-testing.js?:508:34)
            at UserContext.eval (webpack:///./node_modules/zone.js/dist/zone-testing.js?:523:20)
Chrome 67.0.3396 (Windows 10.0.0): Executed 4 of 4 (1 FAILED) (0 secs / 0.433 secs)
Chrome 67.0.3396 (Windows 10.0.0) AppComponent should pass FAILED
        Error: Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?
            at UserContext.eval (webpack:///./src/app/app.component.spec.ts?:31:25)
            at ZoneDelegate.invoke (webpack:///./node_modules/zone.js/dist/zone.js?:387:26)
            at ProxyZoneSpec.onInvoke (webpack:///./node_modules/zone.js/dist/zone-testing.js?:287:39)
            at ZoneDelegate.invoke (webpack:///./node_modules/zone.js/dist/zone.js?:386:32)
            at Zone.run (webpack:///./node_modules/zone.js/dist/zone.js?:137:43)
            at runInTestZone (webpack:///./node_modules/zone.js/dist/zone-testing.js?:508:34)
Chrome 67.0.3396 (Windows 10.0.0): Executed 4 of 4 (1 FAILED) (0.462 secs / 0.433 secs)

Desired functionality

No errors 😁

Mention any other details that might be useful

AFAICT, the problem is caused by incorrect order of code execution. More specifically:

  • Jasmine stores the global timing functions (such as setTimeout).
  • When calling jasmine.clock().install(), it overwrites the timing functions with mocks.
  • Before doign so, it checks whether the currently global timing functions are different than what it has stored in step 1. If so, it assumes the clock is already installed (i.e. the functions are overwritten) and throws.
  • Zone.js also overwrites the global timing functions to make them zone-aware.

In order for this to work, Zone.js must patch the global functions before Jasmine stores the "original" global functions (to later compare them and determine if the clock is already installed). For some reason, it seems that Jasmine is storing the global functions before Zone.js has patched them. Then, once we call jasmine.clock().install(), Jasmine compares the orignal, unpatched global functions with the current global functions (which have since been patched by Zone.js) and finds that they are not the same (and throws).

I have no idea why this is happening, but by trying out several versions I have found out this is broken in @angular-devkit/build-angular v0.6.8 (and all the way through v0.7.0-rc.3). The commit that broke it is 0b126f6 and more specifically this change.

Reverting the test property back to also check !chunks.some(({ name }) => name === 'polyfills') fixes the issue.

Reacted by Job

Activity

Next
  1. gkalpak commented on Jul 23, 2018

    @gkalpak
    gkalpak
    on Jul 23, 2018
    MemberAuthor
    More actions

    I assume the fix would be just restoring the test property to be a function that also checks chunks, but since I have no idea what consequences it has (or how to test this), I'll leave it to someone more knowledgeable 😁

  2. filipesilva commented on Jul 23, 2018

    @filipesilva
    filipesilva
    on Jul 23, 2018
    Contributor
    More actions

    This might be the root cause of #11164 as well.

  3. filipesilva
    added
    area: @angular-devkit/build-angular
    on Jul 23, 2018
  4. gkalpak commented on Jul 23, 2018

    @gkalpak
    gkalpak
    on Jul 23, 2018
    MemberAuthor
    More actions

    Yes, I tried it and the proposed fix (reverting test to also check chunks) does fix #11164.

  5. gkalpak commented on Jul 23, 2018

    @gkalpak
    gkalpak
    on Jul 23, 2018
    MemberAuthor
    More actions

    I have also confirmed that the proposed fix does affect the actual fix for #10485 (used the repro in #10485 (comment)). I will submit a PR.

  6. gkalpak
    added 4 commits that reference this issue on Jul 23, 2018

    fix(@angular-devkit/build-angular): do not break with Jasmine's mock …

    This issue will close once commit b3a6840 is merged into the 'main' branch.
    b3a6840

    fix(@angular-devkit/build-angular): do not break with Jasmine's mock …

    This issue will close once commit e649789 is merged into the 'main' branch.
    e649789

    fix(@angular-devkit/build-angular): do not break with Jasmine's mock …

    This issue will close once commit c41a45c is merged into the 'main' branch.
    c41a45c
  7. filipesilva
    closed this as completedin #11627on Jul 23, 2018
  8. filipesilva
    added a commit that references this issue on Jul 23, 2018

    fix(@angular-devkit/build-angular): do not break with Jasmine's mock …

    This issue will close once commit e17a2ed is merged into the 'main' branch.
    e17a2ed
  9. filipesilva
    added a commit that references this issue on Aug 16, 2018

    fix(@angular-devkit/build-angular): do not break with Jasmine's mock …

    This issue will close once commit d7e3b84 is merged into the 'main' branch.
    d7e3b84
  10. 1 remaining item

  11. matsko
    added a commit that references this issue on Aug 27, 2018

    build(docs-infra): downgrade @angular-devkit/build-angular to 0.6.7 (#…

    b3c56f0
  12. alxhub
    added a commit that references this issue on Oct 3, 2018

    build(docs-infra): downgrade @angular-devkit/build-angular to 0.6.7 (#…

    a273491
  13. whyboris commented on Nov 16, 2018

    @whyboris
    whyboris
    on Nov 16, 2018
    More actions

    Turns out running jasmine.clock() in fakeAsync fails, but passes without that

    with "@angular-devkit/build-angular": "0.10.6" and "jasmine-core": "3.3.0" I run the following test:

      it('should do stuff', fakeAsync(() =>
          jasmine.clock().install();
          const baseTime: Date = new Date(2017, 3, 21);
          jasmine.clock().mockDate(baseTime);
    
          expect(...some-code...).toEqual('20170421');
      ));

    but the actual outcome is 20181116 (today's date, not the mocked date).

    Without fakeAsync it passes. Thank you for comment: https://github.com/angular/zone.js/issues/1063#issuecomment-377674202

    Note: test worked in Angular 5 before I upgraded to Angular 7

  14. angular-automatic-lock-bot commented on Sep 8, 2019

    @angular-automatic-lock-bot
    angular-automatic-lock-botBot
    on Sep 8, 2019
    More actions

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  15. angular-automatic-lock-bot
    locked and limited conversation to collaborators on Sep 8, 2019
  16. mostafaibr
    added a commit that references this issue on May 29, 2026

    fix(@angular-devkit/build-angular): do not break with Jasmine's mock …

    This issue will close once commit 0e890b8 is merged into the 'master' branch.
    0e890b8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: @angular-devkit/build-angular

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402520 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.