Skip to content

Fixture do not work when esbuild target is set to ES2015, ES2016 or esbuild.supported.['async-await'] = false #6042

@kasperpeulen

Description

@kasperpeulen

Describe the bug

I'm not 100% sure if this is a bug or by design.

If you set the vite config to target ES2015, async/await will be transpiled and Vitest can not analyse the fn.toString() call correctly to determine where the fixture depends on.

import { defineConfig } from 'vite';

export default defineConfig({
  esbuild: {
    target: 'ES2015',
    // OR
    target: 'ES2016',
    // OR
    supported: {
      'async-await': false,
    }
  },
});

With the following test:

import { test as base, expect } from 'vitest';

// Edit an assertion and save to see HMR in action

const test = base.extend({
  todos: async ({}, use) => {
    await use(['todo']);
  },
});

test('fixture', ({ todos }) => {
  expect(todos).toContain('todo');
});

Gives the following error:

 ❯ test/basic.test.ts (0)

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Suites 1 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

 FAIL  test/basic.test.ts [ test/basic.test.ts ]
Error: The first argument inside a fixture must use object destructuring pattern, e.g. ({ test } => {}). Instead, received "_0".
 ❯ eval test/basic.test.ts:5:19
      3| // Edit an assertion and save to see HMR in action
      4| 
      5| const test = base.extend({
       |                   ^
      6|   todos: async ({}, use) => {
      7|     await use(['todo']);

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯

 Test Files  1 failed (1)
      Tests  no tests
   Start at  20:36:33
   Duration  1.02s (transform 36ms, setup 0ms, collect 0ms, tests 0ms, environment 1ms, prepare 233ms)


 FAIL  Tests failed. Watching for file changes...
       press h to show help, press q to quit

See the reproduction.

In storybook we are considering also adopting fixture, and we started to use some similar as vitest to implement the mount RFC:
storybookjs/storybook#27389

Which you can see as the first fixture.

However, we found that our fixture code breaks in Angular, which always transpiles away async/await when Zone.js is used.

When looking at the output code of esbuild, the destructure gets kind of preserved:

const Story = {
    async play ({mount}) {
        console.log(mount)
    },
}

gets transpiled to:

const Story = {
  play(_0) {
    return __async(this, arguments, function* ({ mount }) {
      console.log(mount);
    });
  }
};

So, it might be possible to improve the regex to cover to extract the fixture dependency information reliably.

My general feeling is that it might be just to fragile, but I am wondering what you here think about this.

Reproduction

https://stackblitz.com/edit/vitest-dev-vitest-tdu2jo?file=test%2Fbasic.test.ts

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.20.3 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.15.6 - /usr/local/bin/pnpm
  npmPackages:
    @vitest/ui: latest => 1.6.0 
    vite: latest => 5.3.3 
    vitest: latest => 1.6.0

Used Package Manager

npm

Validations

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions