Skip to content

[jasmine] Improve various library types#38412

Merged
mrcrane merged 13 commits intoDefinitelyTyped:masterfrom
zvirja:improve-jasmine-basic-typings
Sep 26, 2019
Merged

[jasmine] Improve various library types#38412
mrcrane merged 13 commits intoDefinitelyTyped:masterfrom
zvirja:improve-jasmine-basic-typings

Conversation

@zvirja
Copy link
Copy Markdown
Contributor

@zvirja zvirja commented Sep 16, 2019

  • Use a meaningful title for the pull request. Include the name of the package modified.
  • Test the change in your own code. (Compile and run.)
  • Add or edit tests to reflect the change. (Run with npm test.)
  • Follow the advice from the readme.
  • Avoid common mistakes.
  • Run npm run lint package-name (or tsc if no tslint.json is present).

Motivation

Found a couple of typing gaps in the library and decided to fix those. Also slightly refactored the library typing to simplify project maintenance.

Issues

Closes #30552
Closes #34080

Changes

The following enhancements has been done:

Spy

  • Added typings for expect(spy).toHaveBeenCalledWith()
  • Fix missing typing for unnamed createSpyObj
  • Fix typing for spyOnAllFunctions
  • Move call assertions to a separate FunctionMatchers interface

Matching

  • Remove wrong deep equality from toBe()
  • Allow any matcher to receive prototypes and symbols only
  • Enhance types and doc for toHaveClass to avoid misuse

Maintenance / other

  • Move all helper types to the jasmine namespace to not pollute global namespace
  • Remove AnyMethods<> in favor of NonTypedSpyObj<T> (see motivation here)
  • Remove undefined Any property from Matchers<T>
  • Synchronize tests for default and 3.1+ projects
  • Update jasminewd2 to depend on jasmine v2 types

@zvirja zvirja requested a review from borisyankov as a code owner September 16, 2019 16:45
@typescript-bot typescript-bot added Popular package This PR affects a popular package (as counted by NPM download counts). Awaiting reviewer feedback labels Sep 16, 2019
@typescript-bot
Copy link
Copy Markdown
Contributor

typescript-bot commented Sep 16, 2019

@zvirja Thank you for submitting this PR!

🔔 @borisyankov @theodorejb @davidparsson @gmoothart @lukas-zech-software @Engineer2B @cyungmann @Roaders @devoto13 @FDIM @pe8ter @kolodny @stephenfarrar @ndunks @sjelin @gkalpak @SeanSobey - please review this PR in the next few days. Be sure to explicitly select Approve or Request Changes in the GitHub UI so I know what's going on.

If no reviewer appears after a week, a DefinitelyTyped maintainer will review the PR instead.

@typescript-bot
Copy link
Copy Markdown
Contributor

👋 Hi there! I’ve run some quick performance metrics against master and your PR. This is still an experiment, so don’t panic if I say something crazy! I’m still learning how to interpret these metrics.

Let’s review the numbers, shall we?

jasmine/v3

Comparison details for jasmine/v3 📊
master #38412 diff
Batch compilation
Memory usage (MiB) 83.7 86.7 +3.6%
Type count 12609 12896 +2.3%
Assignability cache size 35133 35146 0.0%
Subtype cache size 104 129 +24.0%
Identity cache size 33 40 +21.2%
Language service
Samples taken 1892 2210 +16.8%
Identifiers in tests 1892 2210 +16.8%
getCompletionsAtPosition
    Mean duration (ms) 445.3 465.2 +4.5%
    Median duration (ms) 443.5 463.1 +4.4%
    Mean CV 12.8% 12.4% -3.5%
    Worst duration (ms) 621.7 657.2 +5.7%
    Worst identifier foo resolve
getQuickInfoAtPosition
    Mean duration (ms) 425.0 447.5 +5.3%
    Median duration (ms) 422.5 444.7 +5.2%
    Mean CV 13.0% 12.6% -3.3%
    Worst duration (ms) 577.8 602.7 +4.3%
    Worst identifier createSpyObj it

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

jasminewd2/v2

master #38412 diff
Batch compilation
Memory usage (MiB) 38.3 36.2 -5.5%
Type count 2632 2420 -8.1%
Assignability cache size 237 189 -20.3%
Subtype cache size 81 81 0.0%
Identity cache size 0 0
Language service
Samples taken 282 282 0.0%
Identifiers in tests 282 282 0.0%
getCompletionsAtPosition
    Mean duration (ms) 111.4 101.4 -8.9%
    Median duration (ms) 120.1 78.0 -35.0% 🌟
    Mean CV 25.8% 21.8% -15.4%
    Worst duration (ms) 168.8 140.6 -16.7%
    Worst identifier toThrowError expectedString
getQuickInfoAtPosition
    Mean duration (ms) 105.1 94.5 -10.1%
    Median duration (ms) 121.4 85.5 -29.5% 🌟
    Mean CV 24.8% 19.1% -23.0%
    Worst duration (ms) 160.1 130.8 -18.3%
    Worst identifier expect expect

Wow, it looks like all the big movers moved in the right direction! Way to go! 🌟

saywhen/v1

Comparison details for saywhen/v1 📊
master #38412 diff
Batch compilation
Memory usage (MiB) 32.5 35.6 +9.4%
Type count 2674 2737 +2.4%
Assignability cache size 329 429 +30.4%
Subtype cache size 0 0
Identity cache size 0 0
Language service
Samples taken 36 36 0.0%
Identifiers in tests 36 36 0.0%
getCompletionsAtPosition
    Mean duration (ms) 108.4 106.4 -1.8%
    Median duration (ms) 111.7 123.7 +10.7%
    Mean CV 29.4% 25.4% -13.6%
    Worst duration (ms) 158.4 140.5 -11.3%
    Worst identifier JasmineSpy Number
getQuickInfoAtPosition
    Mean duration (ms) 109.0 105.5 -3.2%
    Median duration (ms) 113.0 121.3 +7.4%
    Mean CV 28.1% 28.4% +1.2%
    Worst duration (ms) 161.6 145.2 -10.1%
    Worst identifier when arg
System information
Node version v10.16.3 v10.16.3
CPU count 2 2
CPU speed 2.294 GHz 2.397 GHz
CPU model Intel(R) Xeon(R) CPU E5-2673 v4 @ 2.30GHz Intel(R) Xeon(R) CPU E5-2673 v3 @ 2.40GHz
CPU Architecture x64 x64
Memory 6.8 GiB 6.8 GiB
Platform linux linux
Release 4.15.0-1055-azure 4.15.0-1055-azure

First off, note that the system varied slightly between these two runs, so you’ll have to take these measurements with a grain of salt.

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.


If you have any questions or comments about me, you can ping @andrewbranch. Have a nice day!

Copy link
Copy Markdown
Contributor

@sjelin sjelin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can only sign off on the jasminewd2 dependency update, since that's the only one I'm a maintainer of. That bit LGTM though.

@kolodny
Copy link
Copy Markdown
Contributor

kolodny commented Sep 19, 2019

This broke a couple of build targets at Google, I'm still digging in to figure out what and why. I can update when I have some more time

@zvirja
Copy link
Copy Markdown
Contributor Author

zvirja commented Sep 19, 2019

@sjelin Thanks for giving a look! 🤝

@kolodny I've refined my changes one more time eliminating ones which could potentially lead to failures. The remainder should be super compatible. Please take another look 😉

Looking forward to the feedback. Thanks!

@typescript-bot
Copy link
Copy Markdown
Contributor

Updated numbers for you here from 87bfbdf:

jasmine/v3

Comparison details for jasmine/v3 📊
master #38412 diff
Batch compilation
Memory usage (MiB) 85.9 76.5 -10.9%
Type count 12609 12899 +2.3%
Assignability cache size 35133 35146 0.0%
Subtype cache size 104 129 +24.0%
Identity cache size 33 40 +21.2%
Language service
Samples taken 1892 2210 +16.8%
Identifiers in tests 1892 2210 +16.8%
getCompletionsAtPosition
    Mean duration (ms) 411.6 434.6 +5.6%
    Median duration (ms) 409.2 432.4 +5.7%
    Mean CV 13.5% 13.3% -1.1%
    Worst duration (ms) 571.5 601.2 +5.2%
    Worst identifier Function undefined
getQuickInfoAtPosition
    Mean duration (ms) 392.8 415.7 +5.8%
    Median duration (ms) 389.9 413.6 +6.1%
    Mean CV 13.8% 13.1% -4.5%
    Worst duration (ms) 569.0 554.6 -2.5%
    Worst identifier foo toEqual

It looks like nothing changed too much. I’m pretty lenient since I’m still an experiment, so take a look anyways and make sure nothing looks out of place.

jasminewd2/v2

Comparison details for jasminewd2/v2 📊
master #38412 diff
Batch compilation
Memory usage (MiB) 38.3 35.5 -7.2%
Type count 2632 2420 -8.1%
Assignability cache size 237 189 -20.3%
Subtype cache size 81 81 0.0%
Identity cache size 0 0
Language service
Samples taken 282 282 0.0%
Identifiers in tests 282 282 0.0%
getCompletionsAtPosition
    Mean duration (ms) 102.7 99.9 -2.7%
    Median duration (ms) 129.3 79.6 -38.5% 🌟
    Mean CV 25.9% 25.3% -2.1%
    Worst duration (ms) 139.1 152.7 +9.8%
    Worst identifier expectedNumber toThrowError
getQuickInfoAtPosition
    Mean duration (ms) 98.4 93.3 -5.2%
    Median duration (ms) 81.8 83.2 +1.7%
    Mean CV 25.8% 24.2% -6.2%
    Worst duration (ms) 131.1 133.7 +1.9%
    Worst identifier expect then

Wow, it looks like all the big movers moved in the right direction! Way to go! 🌟

saywhen/v1

Comparison details for saywhen/v1 📊
master #38412 diff
Batch compilation
Memory usage (MiB) 35.1 35.9 +2.3%
Type count 2674 2768 +3.5%
Assignability cache size 329 449 +36.5%
Subtype cache size 0 0
Identity cache size 0 0
Language service
Samples taken 36 36 0.0%
Identifiers in tests 36 36 0.0%
getCompletionsAtPosition
    Mean duration (ms) 111.7 100.0 -10.5%
    Median duration (ms) 134.8 83.9 -37.8% 🌟
    Mean CV 30.0% 29.5% -1.5%
    Worst duration (ms) 155.5 126.0 -19.0%
    Worst identifier when x
getQuickInfoAtPosition
    Mean duration (ms) 109.7 99.4 -9.4%
    Median duration (ms) 130.6 88.3 -32.4% 🌟
    Mean CV 28.5% 26.8% -6.0%
    Worst duration (ms) 150.4 119.7 -20.4%
    Worst identifier expectMatcherProxyTop when
System information
Node version v10.16.3 v10.16.3
CPU count 2 2
CPU speed 2.397 GHz 2.394 GHz
CPU model Intel(R) Xeon(R) CPU E5-2673 v3 @ 2.40GHz Intel(R) Xeon(R) CPU E5-2673 v3 @ 2.40GHz
CPU Architecture x64 x64
Memory 6.8 GiB 6.8 GiB
Platform linux linux
Release 4.15.0-1055-azure 4.15.0-1055-azure

Wow, it looks like all the big movers moved in the right direction! Way to go! 🌟

@typescript-bot typescript-bot added the Unmerged The author did not merge the PR when it was ready. label Sep 24, 2019
@typescript-bot
Copy link
Copy Markdown
Contributor

typescript-bot commented Sep 24, 2019

A definition owner has approved this PR ⭐️. A maintainer will merge this PR shortly. If it shouldn't be merged yet, please leave a comment saying so and we'll wait. Thank you for your contribution to DefinitelyTyped!

@kolodny
Copy link
Copy Markdown
Contributor

kolodny commented Sep 24, 2019

Whoops, sorry, this LGTM, I spot checked this and it broke things that should be broken which this PR caught. Good job and thanks!

@typescript-bot typescript-bot added Owner Approved A listed owner of this package signed off on the pull request. Merge:Express and removed Awaiting reviewer feedback labels Sep 24, 2019
@typescript-bot typescript-bot removed the Unmerged The author did not merge the PR when it was ready. label Sep 24, 2019
@mrcrane mrcrane merged commit 7456aa4 into DefinitelyTyped:master Sep 26, 2019
@typescript-bot
Copy link
Copy Markdown
Contributor

I just published @types/[email protected] to npm.

@typescript-bot
Copy link
Copy Markdown
Contributor

I just published @types/[email protected] to npm.

Copy link
Copy Markdown
Contributor

@gkalpak gkalpak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for joining the party late, but:

From a quick look, the changes in this PR seem to be breaking. Wouldn't a major (or at least minor) version bumb be appropriate (based on this doc)?

// TypeScript Version: 2.8

/// <reference types="jasmine" />
/// <reference types="jasmine/v2" />
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Joining the party late, but I don't think this change is correct. According to the docs, jasminewd2/tsconfig.json should have been updated instead, mapping jasmine to jasmine/v2.

Copy link
Copy Markdown

@AndrejSzasz AndrejSzasz Sep 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this change published, I have errors similar to Argument of type 'Whatever' is not assignable to parameter of type 'string'. in the parameter of withArgs().

Also i'm no longer able to use jasmine.ObjectContaining() to match a partial representation of a type in withArgs().

Argument of type 'ObjectContaining<{ property: string; }>' is not assignable to parameter of type 'SomeObject'.
Type 'ObjectContaining<{ property: string; }>' is missing the following properties from type 'SomeObject': otherProperty, blah-blah, and 10 more.

I have yet to come up with a bare reproduction, however any tips are welcome in the meantime.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm very sorry for the mess created around - it's always annoying 😖 I had only good intentions to make jasmine usage better.

@gkalpak

Wouldn't a major (or at least minor) version bumb be appropriate (based on this doc)?

If you are speaking about jasmine library, then no. There are no breaking changes in the types itself and the previously compatible code is still compatible. Of course, new types are more stricter, but that's always the case when you improve type coverage.

The reason jasminewd2 got affected is because that project was not configured correctly. They must have depended on jasmine v2 instead of pretending being compatible with v3. See more detail here.

According to the docs, jasminewd2/tsconfig.json should have been updated instead, mapping jasmine to jasmine/v2.

That's for spotting it - I read that article, but missed the part about dependent packages. I'll try to give it a go. Anyway, I think it still could have limitations according to this answer.

@AndrejEPAM

With this change published, I have errors similar to Argument of type 'Whatever' is not assignable to parameter of type 'string'. in the parameter of withArgs().

Indeed now we check types for the parameters. You should pass only compatible types. In your case typescript is not making widening, which has been fixed in later versions of TS. Notice, if you don't care about value, just use jasmine.anything() matcher.

Also i'm no longer able to use jasmine.ObjectContaining() to match a partial representation of a type in withArgs().

Strange, as we have test case for that. I've just tried again and the code below worked as a charm:

const spy = jasmine.createSpyObj<{
    method: (arg: { prop1: string, prop2: number }) => void }
    >(['method']);

expect(spy.method)
    .toHaveBeenCalledWith(jasmine.objectContaining({ prop1: "forty-two" }));

If everything is fine with code and it fails, please create a standalone GitHub issue and share scenarios, so they could be investigated in more detail.

Notice, you could also use NonTypedSpyObj<T> instead of SpyObj<T> if you would like to opt-out from type checking. Sometimes it's required if method signature is tricky and typescript cannot deduce type correctly (e.g. you have multiple overloads).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zvirja thanks for the valuable tips, will try them and create reproduction, if still applicable. I was using jasmine.objectContaining within withArgs, specifically, it worked like a charm, but it may be unintended/unsupported use of objectContaining.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AndrejEPAM Oooh, you mean withArgs. Silly me, overlooked that twice, sorry 😖 See it now. Yes, that's a regression and it should be fixed - I overlooked that you could specify argument matchers there 😟

Copy link
Copy Markdown
Contributor Author

@zvirja zvirja Sep 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AndrejEPAM JFYI Created a PR to allow arg matchers in withArgs() method: #38738. Thanks for highlighting.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a similar issue with 3.4.2. This code no longer compiles:

expect(ga).toHaveBeenCalledWith("send", jasmine.objectContaining({
    hitType: "event",
    eventCategory: category,
    eventAction: action,
    eventLabel: label
}));

@wzhudev
Copy link
Copy Markdown

wzhudev commented Oct 7, 2019

This pull request breaks our test of all PRs, like this one NG-ZORRO/ng-zorro-antd#4231.

Now travis reports:

date-picker/nz-month-picker.component.spec.ts:243:51 - error TS2554: Expected 0 arguments, but got 1.
243       expect(nzOnOpenChange).toHaveBeenCalledWith(true);
                                                      ~~~~

Looking for a fix from your side. 😢

@zvirja
Copy link
Copy Markdown
Contributor Author

zvirja commented Oct 8, 2019

@wendzhue Would you be so kind to provide me with a Minimal, Complete, and Verifiable example of code that helps to reproduce the scenario? I'm not familiar with your codebase.

Also consider creating an issue for easier tracking.

@davidje13
Copy link
Copy Markdown
Contributor

This has broken our codebase, where we use nested matchers in toHaveBeenCalledWith like so:

expect(mySpy).toHaveBeenCalledWith({
  foo: 'hello',
  bar: jasmine.any(String),
  baz: jasmine.stringMatching('[a-z]*'),
});

From the code, it looks like matchers are supported for individual arguments, but not for nested properties of arguments, yet Jasmine supports this usage.

The workaround is to use jasmine.objectContaining({/* same object */}) but note that that will not report extra fields (e.g. if the implementation for the test above also included a property zig)

@davidje13
Copy link
Copy Markdown
Contributor

This pull request breaks our test of all PRs, like this one NG-ZORRO/ng-zorro-antd#4231.

Now travis reports:

date-picker/nz-month-picker.component.spec.ts:243:51 - error TS2554: Expected 0 arguments, but got 1.
243       expect(nzOnOpenChange).toHaveBeenCalledWith(true);
                                                      ~~~~

Looking for a fix from your side. 😢

@wendzhue Looks like your issue is this line: https://github.com/NG-ZORRO/ng-zorro-antd/blob/f0ddb79f1d543aa215a2b25abff6079b43eff9e1/components/date-picker/nz-date-picker.component.spec.ts#L940 (and maybe other similar lines) where the function is declared to take no parameters. Makes it look like the change is now correctly warning you that the function shouldn't be given a parameter. Not sure what you're use-case is so I don't know how to advise, but if you have legitimate reasons for this you could always use ...args: any[] as the signature to opt out of this (better to decide whether it should or should not be given a boolean argument though)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Owner Approved A listed owner of this package signed off on the pull request. Popular package This PR affects a popular package (as counted by NPM download counts).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@types/jasmine: False compile error when methods are overloaded Jasmine 3 typings

10 participants