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

Custom environment support #1961

Closed
4 tasks done
nickmccurdy opened this issue Sep 3, 2022 · 10 comments · Fixed by #1963
Closed
4 tasks done

Custom environment support #1961

nickmccurdy opened this issue Sep 3, 2022 · 10 comments · Fixed by #1963
Labels
enhancement New feature or request

Comments

@nickmccurdy
Copy link
Contributor

nickmccurdy commented Sep 3, 2022

Clear and concise description of the problem

Jest supports running tests in custom environments using the testEnvironment option. I'd like to have a similar feature in Vitest, both to make it easier to migrate from Jest to Vitest, and so users of my custom environment can use Vitest. This would also make it easier to support Vitest in the Testing Library Recorder Extension, since it uses my custom environment.

Suggested solution

  1. Support using custom strings with the environment option
    • Optionally, we could also support passing an environment class directly to the option
  2. Support using custom strings with @vitest-environment (also @jest-environment for compatibility)
  3. Resolve strings like jsdom to vite-environment-jsdom (or jest-environment-jsdom if we can figure out how to support Jest environments directly)

Alternative

Use the adapter pattern to load Jest environments instead of supporting them directly

Additional context

No response

Validations

@sheremet-va
Copy link
Member

We don't support jest environments, it has a different logic to how we run tests.

@nickmccurdy
Copy link
Contributor Author

nickmccurdy commented Sep 3, 2022

Do you think it would be possible using the adapter pattern? If not, I can edit the issue to focus on supporting new Vitest environments instead.

@sheremet-va
Copy link
Member

sheremet-va commented Sep 3, 2022

Do you think it would be possible using the adapter pattern? If not, I can edit the issue to focus on supporting new Vitest environments instead.

Currently Vitest environments are just objects:

{ name, setup(global, options): { teardown() } }

Global argument doesn't really matter, because it's always globalThis. We don't isolate context with vm, like jest does. We rely on running workers with isolated flag.

These functions are called inside a worker, but config is resolved in the main thread, so we can't pass down any unserializable data, but we can import anything inside, so importing vitest-environment-#{name} is possible.

Support using custom strings with @vitest-environment (also @jest-environment for compatibility)

@jest-environment is already supported for our envs, btw.

@sheremet-va
Copy link
Member

Currently Vitest environments are just objects

So technically, you can do everything that you do with envs inside test.setupFiles

@nickmccurdy
Copy link
Contributor Author

nickmccurdy commented Sep 3, 2022

Perhaps we could support environment: custom or @vitest-environment custom as a shortcut for:

test: { ..., setupFiles: [..., `vitest-environment-${custom}`] }

This is technically a breaking change because it changes which environment strings a reporter could receive in its config.

This would also make it easier to support Vitest in Testing Library Recorder Extension because Chrome DevTools only lets you export a single JS file, so I can only dynamically generate Vitest config options with comments.

@sheremet-va
Copy link
Member

I think your original proposal is fine. We would have:

// vitest.config
export default {
  test: {
    environment: 'custom',
    environmentOptions: {
       custom: {} // options
   }
  }
}

// package "vitest-environment-custom"
import {
  type EnvironmentSetup,
  environments // default env if needed
  populateGlobal, // copies values to global, should only really be used for browser APIs
} from 'vitest/node'
export default <EnvironmentSetup>{
  name: 'custom',
  setup() {
    return { teardown: () => {} }
  }
}

@sheremet-va sheremet-va added the enhancement New feature or request label Sep 3, 2022
@sheremet-va
Copy link
Member

We can also move to classes and adapter pattern, of course, so it's easier to overwrite.

@nickmccurdy
Copy link
Contributor Author

nickmccurdy commented Sep 3, 2022

We would also need to support @{vitest/jest}-environment-options comments if we're maintaining compatibility with Jest. If not, I'd still find it helpful so I can configure my Vitest environment dynamically.

Edit: I opened #1962 since it also affects using built-in environments.

@nickmccurdy
Copy link
Contributor Author

nickmccurdy commented Sep 3, 2022

We can also move to classes and adapter pattern, of course, so it's easier to overwrite.

So are you suggesting an API similar to JestEnvironment? Personally I'm not really a fan of this approach. It encourages inheritance over composition, and inheritance wouldn't be very useful without adapters for the built-in environments anyway. Also, since Jest similarly runs tests in separate environments (using VMs instead of workers), the instances aren't really shared much outside of Jest's internal APIs, so I feel like there isn't much advantage to having class instances. If we have to support an environment API that isn't compatible with Jest's anyway, it would give us an opportunity to simplify things.

Edit: I since found Environment, maybe it could be more like that

@sheremet-va
Copy link
Member

@nickmccurdy I've opened #1963. Feedback appreciated

@github-actions github-actions bot locked and limited conversation to collaborators Jun 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants