Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inline Snapshots with non literal can't be found #6744

Closed
elicwhite opened this issue Jul 23, 2018 · 28 comments
Closed

Inline Snapshots with non literal can't be found #6744

elicwhite opened this issue Jul 23, 2018 · 28 comments
Labels

Comments

@elicwhite
Copy link
Contributor

🐛 Bug Report

When I try to add a test with an inline snapshot:

it('works with inline snapshots', () => {
  expect({a: 1}).toMatchInlineSnapshot();
});

I get this error:

Jest: Couldn't locate all inline snapshots.

I can't repro this in repl.it because that version does not have inline snapshots yet:

TypeError: expect(...).toMatchInlineSnapshot is not a function

I cloned the github repo and added a test to inline_snapshots.test.js

test('saveInlineSnapshots() replaces empty function call with a template literal for objects', () => {
  const filename = path.join(__dirname, 'my.test.js');
  fs.readFileSync = (jest.fn(
    () => `expect({a: 'a'}).toMatchInlineSnapshot();\n`,
  ): any);

  saveInlineSnapshots(
    [
      {
        frame: {column: 11, file: filename, line: 1},
        snapshot: `{a: 'a'}`,
      },
    ],
    prettier,
    babelTraverse,
  );

  expect(fs.writeFileSync).toHaveBeenCalledWith(
    filename,
    "expect({a: 'a'}).toMatchInlineSnapshot(`{a: 'a'}`);\n",
  );
});

and this reproes the issue:

 FAIL  packages/jest-snapshot/src/__tests__/inline_snapshots.test.js
  ✓ saveInlineSnapshots() replaces empty function call with a template literal (67ms)
  ✕ saveInlineSnapshots() replaces empty function call with a template literal for objects (19ms)
  ✓ saveInlineSnapshots() replaces existing template literal - babylon parser (4ms)
  ✓ saveInlineSnapshots() replaces existing template literal - flow parser (2ms)
  ✓ saveInlineSnapshots() replaces existing template literal - typescript parser (2ms)
  ✓ saveInlineSnapshots() replaces existing template literal with property matchers (3ms)
  ✓ saveInlineSnapshots() throws if frame does not match (2ms)
  ✓ saveInlineSnapshots() throws if multiple calls to to the same location (2ms)
  ✓ saveInlineSnapshots() uses escaped backticks (2ms)

  ● saveInlineSnapshots() replaces empty function call with a template literal for objects

    Jest: Couldn't locate all inline snapshots.

      at Object.parse (packages/jest-snapshot/src/inline_snapshots.js:168:11)
@SimenB
Copy link
Member

SimenB commented Jul 24, 2018

@azz

@azz
Copy link
Contributor

azz commented Jul 28, 2018

Looking into it. If you change the test to say column: 18 it passes.

azz added a commit to azz/jest that referenced this issue Jul 28, 2018
@azz
Copy link
Contributor

azz commented Jul 28, 2018

Can't reproduce, even with an e2e test:
azz@6aab35c#diff-c11487324544dcc655192a3678badb27

azz added a commit to azz/jest that referenced this issue Jul 28, 2018
@elicwhite
Copy link
Contributor Author

Hmm. I wonder why I was hitting this in our test suite at Facebook then with that same error Jest: Couldn't locate all inline snapshots..

Do you have any debugging recommendations?

@azz
Copy link
Contributor

azz commented Jul 29, 2018

You want to determine why this line is not matching.

https://github.com/facebook/jest/blob/0f525c54f268a16b0a7c2de66c3354ec25453e24/packages/jest-snapshot/src/inline_snapshots.js#L137

It could be related to source maps, or a flow parser bug reporting an incorrect location for an AST node.

thymikee pushed a commit that referenced this issue Aug 8, 2018
thymikee added a commit to rhysawilliams2010/jest that referenced this issue Aug 8, 2018
* upstream/master: (122 commits)
  fix: don't report promises as open handles (jestjs#6716)
  support serializing `DocumentFragment` (jestjs#6705)
  Allow test titles to include array index (jestjs#6414)
  fix `toContain` suggest to contain equal message (jestjs#6810)
  fix: testMatch not working with negations (jestjs#6648)
  Add test cases for jestjs#6744 (jestjs#6772)
  print stack trace on calls to process.exit (jestjs#6714)
  Updates SnapshotTesting.md to provide more info. on snapshot scope (jestjs#6735)
  Mark snapshots as obsolete when moved to an inline snapshot (jestjs#6773)
  [Docs] Clarified the use of literal values as property matchers in toMatchSnapshot() (jestjs#6807)
  Update CHANGELOG.md (jestjs#6799)
  fix changelog entry that is not in 23.4.2 (jestjs#6796)
  Fix --coverage with --findRelatedTests overwriting collectCoverageFrom options (jestjs#6736)
  Update testURL default value from about:blank to localhost (jestjs#6792)
  fix: `matchInlineSnapshot` when prettier dependencies are mocked (jestjs#6776)
  Fix retryTimes and add e2e regression test (jestjs#6762)
  Release v23.4.2
  Docs/ExpectAPI: Correct docs for `objectContaining` (jestjs#6754)
  chore(packages/babel-jest) readme (jestjs#6746)
  docs: noted --coverage aliased by --collectCoverage (jestjs#6741)
  ...
@brunoreis
Copy link

brunoreis commented Aug 31, 2018

expect(result)... 

works ( 1 snapshot updated. )

expect( result )... 

doesn't work ( Jest: Couldn't locate all inline snapshots. )

@jack-wood
Copy link

Debugging where @azz indicated I found the column value to be the mismatch.
This was because my prettier.config had tabWidth set to 4 meaning the column was 17 not 15 which is what was inputted into groupedSnapshots.

Changing the config to use tabWidth 2 fixed this so looks like generator is not picking up values from the prettier config in my case tabWidth.

@elicwhite
Copy link
Contributor Author

I just ran into this again with:

  it('foo', () => {
    const fixture = fixtures['SINGLE_COMPONENT_WITH_BOOLEAN_PROP'];
    expect(schemaValidator.validate(fixture)).toMatchInlineSnapshot();
    // -------------------------------------------------------^
  });

Adding a console.log for groupedSnapshots, I get

{ '20:63': [ { frame: [Object], snapshot: 'Array []' } ] }

which points to the p of Snapshot.


On this line:

const snapshotsForFrame = groupedSnapshots[`${line}:${column}`];

${line}:${column} points to the correct location in the source file(20:46), but doesn't match the item in groupedSnapshots. Tracing the invalid data back, the snapshots argument passed to saveInlineSnapshots has the wrong location:

{
  "path/__tests__/MyFile-test.js": [
    {
      "frame": {
        "line": 20,
        "column": 64,
        "file": "path/__tests__/MyFile-test.js",
        "function": "Object.<anonymous>"
      },
      "snapshot": "Array []"
    }
  ]
}

It looks like that data flows in from this code: https://github.com/facebook/jest/blob/master/packages/jest-snapshot/src/State.js#L93-L95

It is creating a new Error() and using that to get the line information which is wrong.

[ 
  'Error',
  '    at SnapshotState._addSnapshot (projectroot/node_modules/jest-snapshot/build/State.js:60:38)',
  '    at Object.throwingMatcher [as toMatchInlineSnapshot] (projectroot/node_modules/expect/build/index.js:321:33)',
  '    at Object.<anonymous> (projectroot/__tests__/MyFile-test.js:20:64)' 
]

I'm not familiar with what is responsible for the line numbers that get calculated for error stack frames so my debugging ends there. Any ideas?

@kristerkari
Copy link

I'm also getting the error Jest: Couldn't locate all inline snapshots. when using inline snapshots in a React Native (v0.56.0) project.

The interesting thing is that the inline snapshot works when rendering a component with react-test-renderer, but fails for anything else.

@SimenB
Copy link
Member

SimenB commented Jan 20, 2019

I'm not familiar with what is responsible for the line numbers that get calculated for error stack frames so my debugging ends there. Any ideas?

Sourcemaps must be setup correctly, then it's https://github.com/evanw/node-source-map-support

@SpaghettiC0des
Copy link

I'm still experiencing this issue on a fresh install of react-native: 0.57.8. File snapshots works fine, but inline snapshots throws an error.

I've only added the transform option in the jest config on package.json

...
   "jest": {
       "preset": "react-native",
       "transform": {
          "^.+\\.(js)$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
          }
}

@SimenB
Copy link
Member

SimenB commented Jan 22, 2019

@karlmarxlopez mind setting up a quick repository we could pull down and check?

@eps1lon
Copy link
Contributor

eps1lon commented Dec 18, 2020

@karlmarxlopez mind setting up a quick repository we could pull down and check?

@SimenB I don't have a minimal repro yet. I can reproduce it in react's codebase though:

$ git clone --branch jest-repro-locate-inline-snapshots https://github.com/eps1lon/react.git
$ yarn install
$ yarn build-for-devtools
$ yarn test-build-devtools treeContext

Produces

 FAIL  packages/react-devtools-shared/src/__tests__/treeContext-test.js
  ● Test suite failed to run

    Jest: Couldn't locate all inline snapshots.

      at Object.parse (node_modules/jest-snapshot/build/inline_snapshots.js:321:11)
      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)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        3.05s
Ran all test suites matching /treeContext/i.

Applying

diff --git a/packages/react-devtools-shared/src/__tests__/treeContext-test.js b/packages/react-devtools-shared/src/__tests__/treeContext-test.js
index 3f97970d63..55265dd911 100644
--- a/packages/react-devtools-shared/src/__tests__/treeContext-test.js
+++ b/packages/react-devtools-shared/src/__tests__/treeContext-test.js
@@ -943,7 +943,7 @@ describe('TreeListContext', () => {
       );
 
       utils.act(() => TestRenderer.create(<Contexts />));
-      expect({state, store}).toMatchInlineSnapshot();
+      expect({ state: state, store: store }).toMatchInlineSnapshot();
 
       selectNextErrorOrWarning();
       let statefulStore = {state, store};

Fixes the issue.

So it looks like the stack trace is based on the code after transpilation (particularly after @babel/plugin-transform-shorthand-properties).

@bvaughn
Copy link
Contributor

bvaughn commented Jan 13, 2021

Finding myself here again, having gotten burned by this issue while trying to rewrite some other React DevTools tests to use inline snapshots. They're so much better (when they work!)

@eps1lon
Copy link
Contributor

eps1lon commented Feb 14, 2021

As far as I can tell the cause of #6744 (comment) is missing source-maps.

React's jest config has a custom preprocessor that transpiles the files without source maps. So expect({state, store}).toMatchInlineSnapshot(); will be transpiled to expect({ state: state, store: store }).toMatchInlineSnapshot(); which means that the generated snapshot will point to a different column (it's using the stack trace) compared to the original source code.

I could fix #6744 (comment) with

diff --git a/scripts/jest/preprocessor.js b/scripts/jest/preprocessor.js
index f57005c940..32836141a3 100644
--- a/scripts/jest/preprocessor.js
+++ b/scripts/jest/preprocessor.js
@@ -86,7 +86,10 @@ module.exports = {
       return babel.transform(
         src,
         Object.assign(
-          {filename: path.relative(process.cwd(), filePath)},
+          {
+            filename: path.relative(process.cwd(), filePath),
+            sourceMaps: isTestFile ? 'inline' : false,
+          },
           babelOptions,
           {
             plugins,

But I don't understand how jest creates accurate frames for other cases. For example expect({stat, store}).toMatchInlineSnapshot(); will throw a ReferenceError that points to the correct column.

@kirillgroshkov
Copy link

What helped for me with Jest 27 and typescript is to add sourceMap: true in my tsconfig.json. It immediately fixed the problem.

ts-jest used to have it on by default, but changed it in v27.

@rkesters
Copy link

rkesters commented Jan 7, 2022

I'm seeing this problem as well:

Jest: 27.4.7
ts-jest: 27.1.2

repo and branch with error : https://github.com/rkesters/typescript-json-validator/tree/rkesters/deps2

run: npx jest index

I have sourceMap set to true.

Error Message:

FAIL src/tests/index.test.ts
● Test suite failed to run

Jest: Couldn't locate all inline snapshots.

  at traverseAst (node_modules/jest-snapshot/build/InlineSnapshots.js:377:11)

@rkesters
Copy link

@SimenB can you look at my comment?

@eps1lon
Copy link
Contributor

eps1lon commented Apr 25, 2022

Another repro with the same symptoms: https://github.com/eps1lon/types-react-codemod/tree/jest-inline-snapshot-repro

describe("transform deprecated-react-type", () => {
	test("named import", () => {
		expect(`
      import { ReactType } from 'react';
      ReactType;
    `).toMatchInlineSnapshot(`
		"import { ElementType } from 'react';
		ElementTye;"
	`);
	});
});

Here the fix is easier by removing

  "resolutions": {
		"source-map": "^0.8.0-beta.0"
	},

from the package.json. The resolution is required to get a fix for mozilla/source-map#432 i.e. make source-map work with Node 18.

So it seems like this issue is caused by source-map. It's not really about a mismatch as far as I can tell since resolutions would force a single version. But some part of the code does not work well with how source-map behaves in some? versions.

@SimenB
Copy link
Member

SimenB commented Apr 25, 2022

That sounds like nodejs/node#42638, and separate from OP

@eps1lon
Copy link
Contributor

eps1lon commented Apr 25, 2022

That sounds like nodejs/node#42638, and separate from OP

Not really since their beta resolves that particular issue. However, forcing their beta as the single version in the dependency tree will break jests inline snapshots.

@SimenB
Copy link
Member

SimenB commented Apr 25, 2022

source-map being broken with global fetch is that. However, Jest doesn't pull in the broken 0.7 version, so shouldn't matter. At least I think so 😅 What's the dependency chain in your repo?

@eps1lon
Copy link
Contributor

eps1lon commented Apr 25, 2022

Upgrading to jest 28 allowed removing the source-map beta resolution. With jest 27 I got "Error: You must provide the URL of lib/mappings.wasm by calling SourceMapConsumer.initialize({ 'lib/mappings.wasm': ... }) before using SourceMapConsumer" in eps1lon/types-react-codemod@b785bcd (#27).

So Jest 28 is fine. Jest 27 + Node 18 requires source-map beta which breaks --updateSnapshot with inline snapshots.

@SimenB
Copy link
Member

SimenB commented Apr 25, 2022

If you use v8 coverage provider, jest@27 is broken with global fetch (node 17 with --experimental-fetch or node 18 without --no-experimental-fetch). Jest 28 should work (due to istanbuljs/v8-to-istanbul#186)

Babel coverage (the default) should work fine in either version

@SimenB
Copy link
Member

SimenB commented Sep 28, 2022

@rkesters the branch from #6744 (comment) seems to be deleted - do you still have it somewhere? I somehow missed a reproduction being posted, sorry! 😬

@github-actions
Copy link

This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days.

@github-actions github-actions bot added the Stale label Sep 28, 2023
@github-actions
Copy link

This issue was closed because it has been stalled for 30 days with no activity. Please open a new issue if the issue is still relevant, linking to this one.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Oct 28, 2023
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 28, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests