Jest: prettier called by `toMatchInlineSnapshot` throws in typescript test containing any comments

Created on 27 Jun 2020  路  10Comments  路  Source: facebook/jest

馃悰 Bug Report

When using toMatchInlineSnapshot in a typescript test with a comment, an error is thrown:

TypeError: Property comments[0] of File expected node to be of a type ["Comment"] but instead got "Line"

      at validate (node_modules/@babel/types/lib/definitions/utils.js:132:11)
      at Object.validator [as validate] (node_modules/@babel/types/lib/definitions/utils.js:103:7)
      at validateField (node_modules/@babel/types/lib/validators/validate.js:24:9)
      at validate (node_modules/@babel/types/lib/validators/validate.js:17:3)
      at builder (node_modules/@babel/types/lib/builders/builder.js:38:27)
      at File (node_modules/@babel/types/lib/builders/generated/index.js:318:31)
      at Object.parse (node_modules/prettier/index.js:9739:19)
      at coreFormat (node_modules/prettier/index.js:13252:23)
      at format (node_modules/prettier/index.js:13510:73)
      at formatWithCursor (node_modules/prettier/index.js:13526:12)
      at node_modules/prettier/index.js:44207:15
      at Object.format (node_modules/prettier/index.js:44226:12)

This seems to be because of a change in a dependency, as it doesn't happen with eslint-plugin-eslint-config which I was working on last week.

To Reproduce

// file.test.ts
it('is true', () => {
  // this will not end well...

  expect(true).toMatchInlineSnapshot();
});

Expected behavior

The test to pass, and the snapshot to be written.

Link to repl or repo (highly encouraged)

envinfo

  System:
    OS: Linux 4.4 Ubuntu 18.04.4 LTS (Bionic Beaver)
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
  Binaries:
    Node: 14.4.0 - ~/.nodenv/versions/14.4.0/bin/node
    Yarn: 1.22.4 - ~/.nodenv/versions/14.4.0/bin/yarn
    npm: 6.14.5 - ~/.nodenv/versions/14.4.0/bin/npm
  npmPackages:
    jest: ^26.0.0 => 26.1.0 
Upstream Bug

Most helpful comment

It is fixed in @babel/types 7.10.4

All 10 comments

So far I've tracked this down to @babel/types v7.10.3, specifically this change

diff --git a/package-lock.json b/package-lock.json
index 83e846e..4ac1ecd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -309,14 +309,22 @@
       }
     },
     "@babel/types": {
-      "version": "7.10.2",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz",
-      "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==",
+      "version": "7.10.3",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.3.tgz",
+      "integrity": "sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA==",
       "dev": true,
       "requires": {
-        "@babel/helper-validator-identifier": "^7.10.1",
+        "@babel/helper-validator-identifier": "^7.10.3",
         "lodash": "^4.17.13",
         "to-fast-properties": "^2.0.0"
+      },
+      "dependencies": {
+        "@babel/helper-validator-identifier": {
+          "version": "7.10.3",
+          "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz",
+          "integrity": "sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw==",
+          "dev": true
+        }
       }
     },
     "@bcoe/v8-coverage": {

Adding a console.log to node_modules/jest-snapshot/build/inline_snapshots.js in getAst produces this:

console.log
    [
      {
        type: 'Line',
        value: ' this will not end well...',
        range: [ 0, 28 ],
        loc: { start: [Object], end: [Object] }
      }
    ]

Created a repl reproducing this with both yarn & npm: https://repl.it/repls/ThoseRectangularMonitors#sum.test.ts

This has been confirmed as a regression in @babel/types, which will be fixed by https://github.com/babel/babel/pull/11752.

In the meantime, you can use patch-package with the following patch:

in patches/@babel+types+7.10.3.patch:

diff --git a/node_modules/@babel/types/lib/definitions/core.js b/node_modules/@babel/types/lib/definitions/core.js
index e778991..24f69fc
--- a/node_modules/@babel/types/lib/definitions/core.js
+++ b/node_modules/@babel/types/lib/definitions/core.js
@@ -232,10 +232,6 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
     program: {
       validate: (0, _utils.assertNodeType)("Program")
     },
-    comments: {
-      validate: (0, _utils.assertEach)((0, _utils.assertNodeType)("Comment")),
-      optional: true
-    },
     tokens: {
       validate: (0, _utils.assertEach)(Object.assign(() => {}, {
         type: "any"

It is fixed in @babel/types 7.10.4

@JLHwung awesome, cheers for such a fast turnaround!

Alright, I'm going to close this now since it's been a working week and the fix has shipped in a patch version, so we should be in the clear :)

(if someone with permissions could chuck a few labels on for visibility, like "Fixed" and "Upstream Bug", that would be awesome)

We can bump the minimum version of @babel/types here if you want. It is of course within semver reach, so no biggie

Ergh, looking at the linked pull request

In #11687 we introduced a new valid check, but it breaks Jest. Let's defer it to Babel 8.

Seems we need to fix some code on our side? @nicolo-ribaudo could you share some details about what Jest is doing that will break in next version of Babel?

We can bump the minimum version of @babel/types

I think that could be useful :)

Seems we need to fix some code on our side?

ugh yeah I meant to ask about that - I spent a decent amount of time trying to pin down where this was coming from in the jest codebase, but couldn't find it.

https://github.com/facebook/jest/blob/7e37b0ff06de590efd6678db30e0ca73969dc2df/packages/jest-snapshot/src/inline_snapshots.ts#L165-L177

This is the "entry" point where the problem starts from, but when tracing that back I couldn't find evidence that it was coming from jest itself; instead it seemed to be a result of the parser being used by prettier, which in turn is meant to be @typescript-eslint, which does indeed output "Line", but it's always done so that I don't know how it didn't break other CIs...

Additionally, prettier rolls with the parser bundled up, so that's another complexity layer 馃槵

This is where I tracked it to in the parser:

https://github.com/typescript-eslint/typescript-eslint/blob/16667b1d5e24d0c3d4a30ca43f7e9e388f8d1ca6/packages/typescript-estree/src/convert-comments.ts#L22-L25

If I changed that to CommentLine (by editing the minified version of the parser in the prettier package), it would "work" but break on other comments because theres something like CommentLine & CommentBlock (iirc). It was around there I bailed out because of the complexity level, having to try and pin the bug across 4 or 5 major libraries.

Was this page helpful?
0 / 5 - 0 ratings