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

Allow importing Jest as an ES6 module #7571

Closed
wants to merge 2 commits into from
Closed

Allow importing Jest as an ES6 module #7571

wants to merge 2 commits into from

Conversation

Symbitic
Copy link

@Symbitic Symbitic commented Jan 1, 2019

Summary

Allows importing jest as an ES6 module instead of using globals (see below for an example).

Everything still works the same as before, but if you prefer Ava's approach of no global variables, this allows using the same type of syntax. Also might be useful if your editor complains if you are using global variables.

I added a test and documentation. Please see docs/Es6Import.md for more info.

I realize most users probably won't use this, but I just thought it might be useful to make it available as an option in case someone does want it. Also might be useful for exposing new functions in the future.

Please let me know if I did anything wrong or need to make any more changes.

Test plan

import jest from 'jest';

jest.test('it works', () => {
  jest.expect('Hello, World!').toHaveLength(13);
});

Allows importing Jest as an ES6 module to replace using global function names (ex. jest.expect, jest.describe, jest.test, etc).
@codecov-io
Copy link

Codecov Report

Merging #7571 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master   #7571      +/-   ##
=========================================
+ Coverage   67.99%     68%   +<.01%     
=========================================
  Files         248     249       +1     
  Lines        9490    9491       +1     
  Branches        5       6       +1     
=========================================
+ Hits         6453    6454       +1     
  Misses       3035    3035              
  Partials        2       2
Impacted Files Coverage Δ
packages/jest/src/jest.js 100% <100%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fd1a693...8adfdca. Read the comment docs.

@jeysal
Copy link
Contributor

jeysal commented Jan 2, 2019

@SimenB has there been discussion on this before? Couldn't find any relevant issues/PRs. I'm wondering whether there are any downsides, because the way AVA does this seems so much cleaner to me.

@SimenB
Copy link
Member

SimenB commented Jan 2, 2019

Yeah, #4473 and #5192. I know @rubennorte wants it as well.


When it comes to this PR, I think it's more likely that we'll support it by binding e.g. expect to a single test, providing it in the callback (similar to ava (and tap, which is where Ava got its API from)). However, that will be quite a bit of work (and super breaking, since we currently have a done callback).

The approach in this PR is no different from something you can do in userland, just copy packages/jest/src/jest.js and import it. Difference would be import {expect} from './my-jest-thing' instead of import {expect} from 'jest'.

@Symbitic
Copy link
Author

Symbitic commented Jan 3, 2019

@SimenB it's true this is different from Ava, which provides all assertions through a callback param. I wasn't trying to achieve that. I was just trying to add the option of importing functions instead of relying on globals.

Also, this isn't exactly the same as importing from packages/jest/src/jest.js, since that doesn't have named exports. That's why I use spreading to merge the default global jest object with other globals like expect, test, etc. So I don't think named imports are possible right now. But something like this might be:

import jest from 'jest'
const { expect } = jest

And finally, something like this might make a more ava-like test() function possible without breaking anything, by using something like import { test } from 'jest/v2'. That would enable breaking features to be added and tested until the next major release.

@SimenB
Copy link
Member

SimenB commented Jan 3, 2019

I was just trying to add the option of importing functions instead of relying on globals.

Yeah, but I don't think that's something we necessarily want in core - if we do this, I think we want to fully implement it, not fake it. And it's as mentioned pretty easy to add in userland.

Also, this isn't exactly the same as importing from packages/jest/src/jest.js, since that doesn't have named exports.

I meant to copy the version of that file from this PR. To get named exports, just do something like this:

// custom-jest.js
export const expect = global.expect;
export const test = global.test;
//  etc
// test.js

import {test, expect} from './custom-jest';

Having a separate export is actually a pretty neat idea. I had a working implementation of passing expect into a test (unfortunately lost due to it residing on my old work laptop), but it required a config option. Just doing import test from 'jest/no-globals'; at some point is better (then we can switch to import jest/globals at some point in the future if people want that and flip the default).

We are currently looking to migrate away from Jasmine over to something called jest-circus, and it already has named exports for all globals except for jest (not actually a global, but close enough) and expect, so this is something we've worked towards. See https://github.com/facebook/jest/blob/103f0685f90495df3b0e0a06b23ab182b6aea4e4/packages/jest-circus/src/index.js

@mcblum
Copy link

mcblum commented Apr 9, 2019

If there's any chance for this to happen it would be amazing. A problem we have right now is that in the monorepo in which I'm working most of the libs are being tested with Karma. My idea is to convert to Jest feature-by-feature, but we (as far as I know) can't have both Jasmine and Jest declaring the same things on the global scope.

The solution to this as I saw it was to import jest and use jest.describe and then once everything was jest, just find / replace all instances of jest.describe and leave them as describe and remove Karma completely.

@stropho
Copy link

stropho commented Apr 9, 2019

I like the idea of import {describe, test, jest} from 'jest/no-globals'; Possibly with a config option useJestGlobals: false so the global namespace is not polluted.

@mcblum

can't have both Jasmine and Jest declaring the same things on the global scope.

As I understand, you want to run the same test files with both karma and jest. If this PR is just for migrating current tests to jest, you can use the described approach e.g. import {test, testJest, expectJest} from './custom-testing'; and create named exports for anything you need including the Jasmine globals. I assume that in './custom-testing' you can figure out which test runner is being used.

@limeandcoconut
Copy link

Any movement on this? I'd love this feature!

@stoikerty
Copy link

stoikerty commented Jun 4, 2019

We're also waiting for this feature to be merged. Upon moving some tests from mocha to jest, I'm surprised this isn't a feature by default. Hopefully there will be movement on this PR.

In the meantime, the following fix will make it almost transparent.

// <rootDir>/test/jest.js
export default jest;
export const { expect, test } = global;
// <rootDir>/jest.config.js
module.exports = {
  moduleNameMapper: {
    '^jest$': '<rootDir>/test/jest.js'
  }
};

Now we can import jest, { expect, test } from 'jest'; all we want!

@StragaSevera
Copy link

It would be really great to use Jest in this way! Please, give us the option to import Jest!

@cyrilchapon

This comment has been minimized.

it: test,
test,
xdescribe: describe.skip,
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems to be missing fit, xit, and xtest. (full list is at https://jestjs.io/docs/en/api)

@agilgur5
Copy link

agilgur5 commented Dec 10, 2019

So since it doesn't seem like this feature will be added to core jest, I decided to implement the user-land solution as a micro-package called jest-without-globals. Per the docs, it just allows you to explicitly import jest's globals as such:

import { describe, it, expect } from 'jest-without-globals'

describe('describe should create a section', () => {
  it('it should checkmark', () => {
    expect('').toBe('')
  })
})

I'm currently using it in a few of my projects already and am planning on using it in all of my jest-tested projects.




The global namespace is unfortunately still polluted (jest-without-globals is like this PR and the solutions here in that it retrieves the variables from the global namespace in order to export them), but I think it's a good stop-gap solution until jest-circus is officially released, a useJestGlobals: false config is added, etc. jest-without-globals should also work for older versions of jest once a non-global version is released. See my PR at #9306 for a config option to not pollute globals.
In current jest, this would seem to require a decent bit of refactoring of jest-jasmine2 in order for it to optionally add things to the global namespace, so it probably makes sense to wait for jest-circus to fully replace it internally.

If the Jest team is amenable to linking to an external package, I could submit a PR to add jest-without-globals to the docs.

@silverwind
Copy link
Contributor

const {test, expect} = global also works but I do agree jest should just export those values.

@SimenB
Copy link
Member

SimenB commented Apr 12, 2020

I just landed #9801 which has support for this. It doesn't prevent setting of globals, but it gives you a (type safe) way to import them. Will add a way to avoid mutating the global env soonish

@github-actions
Copy link

This pull request 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 May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet