Jest-preset-angular: Serialiszation Determinism

Created on 10 May 2018  路  8Comments  路  Source: thymikee/jest-preset-angular

I am currently running in a problem that could easily be fixed by this library. I'm passing a date to a child component and it doesn't get serialized in the same way on my machine and in the CI. Here's the error that I'm getting.

2018-05-10T16:04:19.7314457Z     Received value does not match stored snapshot 1.
2018-05-10T16:04:19.7314563Z     
2018-05-10T16:04:19.7314651Z     - Snapshot
2018-05-10T16:04:19.7314767Z     + Received
2018-05-10T16:04:19.7314853Z     
2018-05-10T16:04:19.7314946Z     @@ -360,11 +360,11 @@
2018-05-10T16:04:19.7315040Z             
2018-05-10T16:04:19.7315148Z         
2018-05-10T16:04:19.7315238Z                 
2018-05-10T16:04:19.7315338Z             <app-portfolio-cards
2018-05-10T16:04:19.7315449Z               ng-reflect-currency="CAD"
2018-05-10T16:04:19.7315598Z     -         ng-reflect-date="Fri Dec 29 2017 00:00:00 GMT-0"
2018-05-10T16:04:19.7315766Z     +         ng-reflect-date="Fri Dec 29 2017 00:00:00 GMT+0"
2018-05-10T16:04:19.7315888Z               ng-reflect-portfolios=""
2018-05-10T16:04:19.7316033Z               ng-reflect-return-period="DTD"
2018-05-10T16:04:19.7316150Z               ng-reflect-return-type="ABS"
2018-05-10T16:04:19.7316250Z             >
2018-05-10T16:04:19.7316313Z 
2018-05-10T16:04:19.7316410Z       49 |     it('renders', () => {
2018-05-10T16:04:19.7316544Z       50 |         expect(fixture).toBeTruthy();
2018-05-10T16:04:19.7316665Z     > 51 |         expect(fixture).toMatchSnapshot();
2018-05-10T16:04:19.7316771Z       52 |     });
2018-05-10T16:04:19.7316865Z       53 | });
2018-05-10T16:04:19.7316976Z       54 | 

Probable cause

If i'm reading the code correctly, this is due to this line. It seems that node's implicit date to string conversion is non-deterministic. My problem could be fixed at this library's level by using val.componentInstance[attribute].toISOString() when val.componentInstance[attribute] is a date. A similar treatment could be applied to floating-point numbers (probably by rounding them to a fixed number of significant digits) to avoid non-determinism.

Reproductibility

Unfortunately, I am not able to reproduce the bug since it happens on my CI environment on which I have no control over. The code is also proprietary. If anyone has an idea on how I can try to reproduce it more accurately, please let me know.

As final toughts, I think that determinism should be added as a feature regardless of this is a bug or not. However, this would be a breaking change (albeit a painless one) and users would have to regenerate their snapshots when upgrading jest-preset-angular if they pass dates or floating-point numbers between components.

Edit: By the way, I'm willing to make a PR if it can help.

All 8 comments

Happy to accept a PR with the fix 馃檪

What about the fact that it would be a breaking change ?

I can live with it, we can always release it with the next Jest major version, which will be in ~2 weeks.

Also, maybe we can just pass these strings through print? makes more sense actually and should handle your cases hopefully.

After much more digging into this yesterday, my problem comes from the way angular serializes dates to be put in ng-reclect-* properties. It calls date.toString() which doesn't seem to be deterministic. Angular wasn't made with snapshot testing in mind and the codebase is way too convoluted for me to comprehend. So, I had to resort to disabling the test.

That being said, it could be a good thing to recursively call print on val.componentInstance[attribute] instead of implicitely converting it to a string. This is the way jest formats react components for snapshots. We might run into issues with multiline objects though. It wouldn't solve my use case, but it would be a little improvement.


If someone else ever runs in a similar issue, note that the outer component tag is formatted by this library, but the inner html is formatted by jest. (that took me a while to figure out)

It would be nice to have this. We are happy to accept new PR for improvement 馃榾

This should fix it, shouldn't it? #97

It should ! I don't have access to the project I was facing this issue with, but I'd happily consider this closed if that's fine with everyone.

Was this page helpful?
0 / 5 - 0 ratings