Skip to content

Commit

Permalink
Merge branch 'main' into feat-jest-expect
Browse files Browse the repository at this point in the history
  • Loading branch information
mrazauskas committed Feb 16, 2022
2 parents c2f0a81 + 199f981 commit 7112401
Show file tree
Hide file tree
Showing 98 changed files with 767 additions and 573 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Expand Up @@ -12,8 +12,10 @@
- `[jest-environment-node]` [**BREAKING**] Add default `node` and `node-addon` conditions to `exportConditions` for `node` environment ([#11924](https://github.com/facebook/jest/pull/11924))
- `[@jest/expect-utils]` New module exporting utils for `expect` ([#12323](https://github.com/facebook/jest/pull/12323))
- `[jest-resolver]` [**BREAKING**] Add support for `package.json` `exports` ([11961](https://github.com/facebook/jest/pull/11961))
- `[@jes/schemas]` New module for JSON schemas for Jest's config ([#12384](https://github.com/facebook/jest/pull/12384))
- `[jest-resolve, jest-runtime]` Add support for `data:` URI import and mock ([#12392](https://github.com/facebook/jest/pull/12392))
- `[@jest/schemas]` New module for JSON schemas for Jest's config ([#12384](https://github.com/facebook/jest/pull/12384))
- `[jest-worker]` [**BREAKING**] Allow only absolute `workerPath` ([#12343](https://github.com/facebook/jest/pull/12343))
- `[pretty-format]` New `maxWidth` parameter ([#12402](https://github.com/facebook/jest/pull/12402))

### Fixes

Expand All @@ -22,12 +24,14 @@
- `[jest-config]` Pass `moduleTypes` to `ts-node` to enforce CJS when transpiling ([#12397](https://github.com/facebook/jest/pull/12397))
- `[jest-environment-jsdom]` Make `jsdom` accessible to extending environments again ([#12232](https://github.com/facebook/jest/pull/12232))
- `[jest-jasmine2, jest-types]` [**BREAKING**] Move all `jasmine` specific types from `@jest/types` to its own package ([#12125](https://github.com/facebook/jest/pull/12125))
- `[jest-matcher-utils]` Pass maxWidth to `pretty-format` to avoid printing every element in arrays by default ([#12402](https://github.com/facebook/jest/pull/12402))

### Chore & Maintenance

- `[*]` [**BREAKING**] Drop support for Node v10 and v15 and target first LTS `16.13.0` ([#12220](https://github.com/facebook/jest/pull/12220))
- `[*]` [**BREAKING**] Drop support for `typescript@3.8`, minimum version is now `4.2` ([#11142](https://github.com/facebook/jest/pull/11142))
- `[*]` Bundle all `.d.ts` files into a single `index.d.ts` per module ([#12345](https://github.com/facebook/jest/pull/12345))
- `[docs]` Add note about not mixing `done()` with Promises ([#11077](https://github.com/facebook/jest/pull/11077))
- `[docs, examples]` Update React examples to match with the new React guidelines for code examples ([#12217](https://github.com/facebook/jest/pull/12217))
- `[expect]` [**BREAKING**] Remove support for importing `build/utils` ([#12323](https://github.com/facebook/jest/pull/12323))
- `[expect]` [**BREAKING**] Migrate to ESM ([#12344](https://github.com/facebook/jest/pull/12344))
Expand All @@ -44,8 +48,8 @@
- `[jest-serializer]` [**BREAKING**] Deprecate package in favour of using `v8` APIs directly ([#12391](https://github.com/facebook/jest/pull/12391))
- `[jest-snapshot]` [**BREAKING**] Migrate to ESM ([#12342](https://github.com/facebook/jest/pull/12342))
- `[jest-transform]` Update `write-file-atomic` to v4 ([#12357](https://github.com/facebook/jest/pull/12357))
- `[jest-types]` [**BREAKING**] Remove `Config.Glob` and `Config.Path` ([#12406](https://github.com/facebook/jest/pull/12406))
- `[jest]` Use `index.ts` instead of `jest.ts` as main export ([#12329](https://github.com/facebook/jest/pull/12329))
- `[docs]` Add note about not mixing `done()` with Promises ([#11077](https://github.com/facebook/jest/pull/11077))

### Performance

Expand Down
11 changes: 4 additions & 7 deletions e2e/Utils.ts
Expand Up @@ -20,7 +20,7 @@ interface RunResult extends ExecaReturnValue {
}
export const run = (
cmd: string,
cwd?: Config.Path,
cwd?: string,
env?: Record<string, string>,
): RunResult => {
const args = cmd.split(/\s/).slice(1);
Expand All @@ -44,10 +44,7 @@ export const run = (
return result;
};

export const runYarnInstall = (
cwd: Config.Path,
env?: Record<string, string>,
) => {
export const runYarnInstall = (cwd: string, env?: Record<string, string>) => {
const lockfilePath = path.resolve(cwd, 'yarn.lock');
let exists = true;

Expand All @@ -60,7 +57,7 @@ export const runYarnInstall = (
return run(exists ? 'yarn install --immutable' : 'yarn install', cwd, env);
};

export const linkJestPackage = (packageName: string, cwd: Config.Path) => {
export const linkJestPackage = (packageName: string, cwd: string) => {
const packagesDir = path.resolve(__dirname, '../packages');
const packagePath = path.resolve(packagesDir, packageName);
const destination = path.resolve(cwd, 'node_modules/', packageName);
Expand Down Expand Up @@ -182,7 +179,7 @@ const DEFAULT_PACKAGE_JSON: JestPackageJson = {
};

export const createEmptyPackage = (
directory: Config.Path,
directory: string,
packageJson: PackageJson = DEFAULT_PACKAGE_JSON,
) => {
const packageJsonWithDefaults = {
Expand Down
4 changes: 2 additions & 2 deletions e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap
Expand Up @@ -41,7 +41,7 @@ exports[`moduleNameMapper wrong array configuration 1`] = `
12 | module.exports = () => 'test';
13 |
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:568:17)
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:572:17)
at Object.require (index.js:10:1)"
`;

Expand Down Expand Up @@ -70,6 +70,6 @@ exports[`moduleNameMapper wrong configuration 1`] = `
12 | module.exports = () => 'test';
13 |
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:568:17)
at createNoMappedModuleFoundError (../../packages/jest-resolve/build/resolver.js:572:17)
at Object.require (index.js:10:1)"
`;
2 changes: 1 addition & 1 deletion e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap
Expand Up @@ -2,7 +2,7 @@

exports[`on node >=12.16.0 runs test with native ESM 1`] = `
"Test Suites: 1 passed, 1 total
Tests: 21 passed, 21 total
Tests: 32 passed, 32 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites matching /native-esm.test.js/i."
Expand Down
95 changes: 95 additions & 0 deletions e2e/native-esm/__tests__/native-esm.test.js
Expand Up @@ -195,3 +195,98 @@ test('can mock module', async () => {
test('supports imports using "node:" prefix', () => {
expect(dns).toBe(prefixDns);
});

test('supports imports from "data:text/javascript" URI with charset=utf-8 encoding', async () => {
const code = 'export const something = "some value"';
const importedEncoded = await import(
`data:text/javascript;charset=utf-8,${encodeURIComponent(code)}`
);
expect(importedEncoded.something).toBe('some value');
});

test('supports imports from "data:text/javascript" URI with base64 encoding', async () => {
const code = 'export const something = "some value"';
const importedBase64 = await import(
`data:text/javascript;base64,${Buffer.from(code).toString('base64')}`
);
expect(importedBase64.something).toBe('some value');
});

test('supports imports from "data:text/javascript" URI without explicit encoding', async () => {
const code = 'export const something = "some value"';
const importedEncoded = await import(
`data:text/javascript,${encodeURIComponent(code)}`
);
expect(importedEncoded.something).toBe('some value');
});

test('imports from "data:text/javascript" URI with invalid encoding fail', async () => {
const code = 'export const something = "some value"';
await expect(
async () =>
await import(
`data:text/javascript;charset=badEncoding,${encodeURIComponent(code)}`
),
).rejects.toThrow('Invalid data URI');
});

test('imports from "data:" URI with invalid mime type fail', async () => {
const code = 'export const something = "some value"';
await expect(
async () => await import(`data:something/else,${encodeURIComponent(code)}`),
).rejects.toThrow('Invalid data URI');
});

test('imports from "data:text/javascript" URI with invalid data fail', async () => {
await expect(
async () =>
await import('data:text/javascript;charset=utf-8,so(me)+.-gibberish'),
).rejects.toThrow("Unexpected token '.'");
});

test('imports from "data:application/wasm" URI not supported', async () => {
await expect(
async () => await import('data:application/wasm,96cafe00babe'),
).rejects.toThrow('WASM is currently not supported');
});

test('supports imports from "data:application/json" URI', async () => {
const data = await import('data:application/json,{"foo": "bar"}');
expect(data.default).toEqual({foo: 'bar'});
});

test('supports static "data:" URI import', async () => {
const module = await import('../staticDataImport.js');
expect(module.value()).toEqual({bar: {obj: 456}, foo: '123'});
});

test('imports from "data:" URI is properly cached', async () => {
const code =
'export const wrapper = {value: 123}\nexport const set = (value) => wrapper.value = value';
const data1 = await import(
`data:text/javascript;charset=utf-8,${encodeURIComponent(code)}`
);
expect(data1.wrapper.value).toBe(123);
data1.set(234);
expect(data1.wrapper.value).toBe(234);
const data2 = await import(
`data:text/javascript;base64,${Buffer.from(code).toString('base64')}`
);
expect(data2.wrapper.value).toBe(123);
const data3 = await import(
`data:text/javascript;charset=utf-8,${encodeURIComponent(code)}`
);
expect(data3.wrapper.value).toBe(234);
});

test('can mock "data:" URI module', async () => {
const code = 'export const something = "some value"';
const dataModule = `data:text/javascript;base64,${Buffer.from(code).toString(
'base64',
)}`;
jestObject.unstable_mockModule(dataModule, () => ({foo: 'bar'}), {
virtual: true,
});
const mocked = await import(dataModule);
expect(mocked.foo).toBe('bar');
});
13 changes: 13 additions & 0 deletions e2e/native-esm/staticDataImport.js
@@ -0,0 +1,13 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import bar from 'data:application/json,{"obj": 456}';
import {foo} from 'data:text/javascript,export const foo = "123"';

export function value() {
return {bar, foo};
}
59 changes: 32 additions & 27 deletions examples/expect-extend/toBeWithinRange.ts
Expand Up @@ -8,34 +8,39 @@
import {expect} from '@jest/globals';
import type {MatcherFunction} from 'expect';

const toBeWithinRange: MatcherFunction<[floor: number, ceiling: number]> = (
actual: unknown,
floor: unknown,
ceiling: unknown,
) => {
if (
typeof actual !== 'number' ||
typeof floor !== 'number' ||
typeof ceiling !== 'number'
) {
throw new Error('These must be of type number!');
}
const toBeWithinRange: MatcherFunction<[floor: number, ceiling: number]> =
function (actual: unknown, floor: unknown, ceiling: unknown) {
if (
typeof actual !== 'number' ||
typeof floor !== 'number' ||
typeof ceiling !== 'number'
) {
throw new Error('These must be of type number!');
}

const pass = actual >= floor && actual <= ceiling;
if (pass) {
return {
message: () =>
`expected ${actual} not to be within range ${floor} - ${ceiling}`,
pass: true,
};
} else {
return {
message: () =>
`expected ${actual} to be within range ${floor} - ${ceiling}`,
pass: false,
};
}
};
const pass = actual >= floor && actual <= ceiling;
if (pass) {
return {
message: () =>
`expected ${this.utils.printReceived(
actual,
)} not to be within range ${this.utils.printExpected(
`${floor} - ${ceiling}`,
)}`,
pass: true,
};
} else {
return {
message: () =>
`expected ${this.utils.printReceived(
actual,
)} to be within range ${this.utils.printExpected(
`${floor} - ${ceiling}`,
)}`,
pass: false,
};
}
};

expect.extend({
toBeWithinRange,
Expand Down
1 change: 0 additions & 1 deletion packages/babel-jest/package.json
Expand Up @@ -19,7 +19,6 @@
},
"dependencies": {
"@jest/transform": "^28.0.0-alpha.1",
"@jest/types": "^28.0.0-alpha.1",
"@types/babel__core": "^7.1.14",
"babel-plugin-istanbul": "^6.1.1",
"babel-preset-jest": "^28.0.0-alpha.0",
Expand Down
25 changes: 12 additions & 13 deletions packages/babel-jest/src/index.ts
Expand Up @@ -20,7 +20,6 @@ import type {
TransformOptions as JestTransformOptions,
SyncTransformer,
} from '@jest/transform';
import type {Config} from '@jest/types';
import {loadPartialConfig, loadPartialConfigAsync} from './loadBabelConfig';

const THIS_FILE = fs.readFileSync(__filename);
Expand All @@ -31,8 +30,8 @@ type CreateTransformer = SyncTransformer<TransformOptions>['createTransformer'];

function assertLoadedBabelConfig(
babelConfig: Readonly<PartialConfig> | null,
cwd: Config.Path,
filename: Config.Path,
cwd: string,
filename: string,
): asserts babelConfig {
if (!babelConfig) {
throw new Error(
Expand Down Expand Up @@ -72,7 +71,7 @@ function addIstanbulInstrumentation(

function getCacheKeyFromConfig(
sourceText: string,
sourcePath: Config.Path,
sourcePath: string,
babelOptions: PartialConfig,
transformOptions: JestTransformOptions,
): string {
Expand Down Expand Up @@ -104,8 +103,8 @@ function getCacheKeyFromConfig(
}

function loadBabelConfig(
cwd: Config.Path,
filename: Config.Path,
cwd: string,
filename: string,
transformOptions: TransformOptions,
): PartialConfig {
const babelConfig = loadPartialConfig(transformOptions);
Expand All @@ -116,8 +115,8 @@ function loadBabelConfig(
}

async function loadBabelConfigAsync(
cwd: Config.Path,
filename: Config.Path,
cwd: string,
filename: string,
transformOptions: TransformOptions,
): Promise<PartialConfig> {
const babelConfig = await loadPartialConfigAsync(transformOptions);
Expand All @@ -128,8 +127,8 @@ async function loadBabelConfigAsync(
}

function loadBabelOptions(
cwd: Config.Path,
filename: Config.Path,
cwd: string,
filename: string,
transformOptions: TransformOptions,
jestTransformOptions: JestTransformOptions,
): TransformOptions {
Expand All @@ -139,8 +138,8 @@ function loadBabelOptions(
}

async function loadBabelOptionsAsync(
cwd: Config.Path,
filename: Config.Path,
cwd: string,
filename: string,
transformOptions: TransformOptions,
jestTransformOptions: JestTransformOptions,
): Promise<TransformOptions> {
Expand Down Expand Up @@ -169,7 +168,7 @@ export const createTransformer: CreateTransformer = userOptions => {
} as const;

function mergeBabelTransformOptions(
filename: Config.Path,
filename: string,
transformOptions: JestTransformOptions,
): TransformOptions {
const {cwd} = transformOptions.config;
Expand Down
6 changes: 1 addition & 5 deletions packages/babel-jest/tsconfig.json
Expand Up @@ -7,9 +7,5 @@
"include": ["./src/**/*"],
"exclude": ["./**/__tests__/**/*"],
// TODO: include `babel-preset-jest` if it's ever in TS even though we don't care about its types
"references": [
{"path": "../jest-transform"},
{"path": "../jest-types"},
{"path": "../test-utils"}
]
"references": [{"path": "../jest-transform"}, {"path": "../test-utils"}]
}
1 change: 0 additions & 1 deletion packages/expect/package.json
Expand Up @@ -19,7 +19,6 @@
},
"dependencies": {
"@jest/expect-utils": "^28.0.0-alpha.1",
"@jest/types": "^28.0.0-alpha.1",
"jest-get-type": "^28.0.0-alpha.0",
"jest-matcher-utils": "^28.0.0-alpha.1",
"jest-message-util": "^28.0.0-alpha.1"
Expand Down

0 comments on commit 7112401

Please sign in to comment.