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

jest-diff: Export as ECMAScript module #8873

Merged
merged 7 commits into from
Aug 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- `[babel-plugin-jest-hoist]` Show codeframe on static hoisting issues ([#8865](https://github.com/facebook/jest/pull/8865))
- `[jest-config]` [**BREAKING**] Set default display name color based on runner ([#8689](https://github.com/facebook/jest/pull/8689))
- `[jest-diff]` Add options for colors and symbols ([#8841](https://github.com/facebook/jest/pull/8841))
- `[jest-diff]` [**BREAKING**] Export as ECMAScript module ([#8873](https://github.com/facebook/jest/pull/8873))
- `[jest-runner]` Warn if a worker had to be force exited ([#8206](https://github.com/facebook/jest/pull/8206))
- `[@jest/test-result]` Create method to create empty `TestResult` ([#8867](https://github.com/facebook/jest/pull/8867))
- `[jest-worker]` [**BREAKING**] Return a promise from `end()`, resolving with the information whether workers exited gracefully ([#8206](https://github.com/facebook/jest/pull/8206))
Expand Down
84 changes: 53 additions & 31 deletions packages/jest-diff/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ Given values and optional options, `diffLinesUnified(a, b, options?)` does the f

To use this function, write either of the following:

- `const diffLinesUnified = require('jest-diff');` in a CommonJS module
- `import diffLinesUnified from 'jest-diff';` in an ECMAScript module
- `const diffLinesUnified = require('jest-diff').default;` in CommonJS modules
- `import diffLinesUnified from 'jest-diff';` in ECMAScript modules

### Example of default export

Expand All @@ -40,8 +40,7 @@ const difference = diffLinesUnified(a, b);

The returned **string** consists of:

- annotation lines which describe the change symbols with labels
- blank line
- annotation lines: describe the two change symbols with labels, and a blank line
- comparison lines: similar to “unified” view on GitHub, but `Expected` lines are green, `Received` lines are red, and common lines are dim (by default, see Options)

```diff
Expand Down Expand Up @@ -77,8 +76,8 @@ Although the function is mainly for **multiline** strings, it compares any strin

Write either of the following:

- `const {diffStringsUnified} = require('jest-diff');` in a CommonJS module
- `import {diffStringsUnified} from 'jest-diff';` in an ECMAScript module
- `const {diffStringsUnified} = require('jest-diff');` in CommonJS modules
- `import {diffStringsUnified} from 'jest-diff';` in ECMAScript modules

### Example of diffStringsUnified

Expand All @@ -91,9 +90,8 @@ const difference = diffStringsUnified(a, b);

The returned **string** consists of:

- annotation lines which describe the change symbols with labels
- blank line
- comparison lines: similar to “unified” view on GitHub, and **changed substrings** have **inverted** foreground and background colors
- annotation lines: describe the two change symbols with labels, and a blank line
- comparison lines: similar to “unified” view on GitHub, and **changed substrings** have **inverted** foreground and background colors (which the following example does not show)

```diff
- Expected
Expand Down Expand Up @@ -121,62 +119,86 @@ If the input strings can have **arbitrary length**, we recommend that the callin

## Usage of diffStringsRaw

Given strings, `diffStringsRaw(a, b, cleanup)` does the following:
Given strings and boolean, `diffStringsRaw(a, b, cleanup)` does the following:

- **compare** the strings character-by-character using the `diff-sequences` package
- optionally **clean up** small (often coincidental) common substrings, also known as chaff

Write one of the following:

- `const {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, diffStringsRaw} = require('jest-diff');` in a CommonJS module
- `import {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, diffStringsRaw} from 'jest-diff';` in an ECMAScript module
- `import {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff, diffStringsRaw} from 'jest-diff';` in a TypeScript module
- `const {diffStringsRaw} = require('jest-diff');` in CommonJS modules
- `import {diffStringsRaw} from 'jest-diff';` in ECMAScript modules

The returned **array** describes substrings as instances of the `Diff` class (which calling code can access like array tuples).
Because `diffStringsRaw` returns the difference as **data** instead of a string, you can format it as your application requires (for example, enclosed in HTML markup for browser instead of escape sequences for console).

The returned **array** describes substrings as instances of the `Diff` class, which calling code can access like array tuples:

The value at index `0` is one of the following:

| value | named export | description |
| ----: | :------------ | :-------------------- |
| `0` | `DIFF_EQUAL` | in `a` and in `b` |
| `-1` | `DIFF_DELETE` | in `a` but not in `b` |
| `1` | `DIFF_INSERT` | in `b` but not in `a` |

Because `diffStringsRaw` returns the difference as **data** instead of a string, you are free to format it as your application requires (for example, enclosed in HTML markup for browser instead of escape sequences for console).
The value at index `1` is a substring of `a` or `b` or both.

### Example of diffStringsRaw with cleanup

```js
const diffs = diffStringsRaw('change from', 'change to', true);

// diffs[0][0] === DIFF_EQUAL
// diffs[0][1] === 'change '
/*
diffs[0][0] === 0 // DIFF_EQUAL
diffs[0][1] === 'change '

// diffs[1][0] === DIFF_DELETE
// diffs[1][1] === 'from'
diffs[1][0] === -1 // DIFF_DELETE
diffs[1][1] === 'from'

// diffs[2][0] === DIFF_INSERT
// diffs[2][1] === 'to'
diffs[2][0] === 1 // DIFF_INSERT
diffs[2][1] === 'to'
*/
```

### Example of diffStringsRaw without cleanup

```js
const diffs = diffStringsRaw('change from', 'change to', false);

// diffs[0][0] === DIFF_EQUAL
// diffs[0][1] === 'change '
/*
diffs[0][0] === 0 // DIFF_EQUAL
diffs[0][1] === 'change '

// diffs[1][0] === DIFF_DELETE
// diffs[1][1] === 'fr'
diffs[1][0] === -1 // DIFF_DELETE
diffs[1][1] === 'fr'

// diffs[2][0] === DIFF_INSERT
// diffs[2][1] === 't'
diffs[2][0] === 1 // DIFF_INSERT
diffs[2][1] === 't'

// Here is a small coincidental common substring:
// diffs[3][0] === DIFF_EQUAL
// diffs[3][1] === 'o'
diffs[3][0] === 0 // DIFF_EQUAL
diffs[3][1] === 'o'

diffs[4][0] === -1 // DIFF_DELETE
diffs[4][1] === 'm'
*/
```

## Advanced import for diffStringsRaw

// diffs[4][0] === DIFF_DELETE
// diffs[4][1] === 'm'
Here are all the named imports for the `diffStringsRaw` function:

- `const {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff, diffStringsRaw} = require('jest-diff');` in CommonJS modules
- `import {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff, diffStringsRaw} from 'jest-diff';` in ECMAScript modules

To write a **formatting** function, you might need the named constants (and `Diff` in TypeScript annotations).

If you write an application-specific **cleanup** algorithm, then you might need to call the `Diff` constructor:

```js
const diffCommon = new Diff(DIFF_EQUAL, 'change ');
const diffDelete = new Diff(DIFF_DELETE, 'from');
const diffInsert = new Diff(DIFF_INSERT, 'to');
```

## Options
Expand Down
34 changes: 34 additions & 0 deletions packages/jest-diff/src/__tests__/diffStringsRaw.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* 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 {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff, diffStringsRaw} from '../';

describe('diffStringsRaw', () => {
test('one-line with cleanup', () => {
const expected: Array<Diff> = [
new Diff(DIFF_EQUAL, 'change '),
new Diff(DIFF_DELETE, 'from'),
new Diff(DIFF_INSERT, 'to'),
];
const received = diffStringsRaw('change from', 'change to', true);

expect(received).toEqual(expected);
});

test('one-line without cleanup', () => {
const expected: Array<Diff> = [
new Diff(DIFF_EQUAL, 'change '),
new Diff(DIFF_DELETE, 'fr'),
new Diff(DIFF_INSERT, 't'),
new Diff(DIFF_EQUAL, 'o'),
new Diff(DIFF_DELETE, 'm'),
];
const received = diffStringsRaw('change from', 'change to', false);

expect(received).toEqual(expected);
});
});
30 changes: 9 additions & 21 deletions packages/jest-diff/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
import prettyFormat = require('pretty-format');
import chalk from 'chalk';
import getType = require('jest-get-type');
import {
DIFF_DELETE,
DIFF_EQUAL,
DIFF_INSERT,
Diff as DiffClass,
} from './cleanupSemantic';
import {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff} from './cleanupSemantic';
import diffLines from './diffLines';
import {normalizeDiffOptions} from './normalizeDiffOptions';
import {diffStringsRaw, diffStringsUnified} from './printDiffs';
import {NO_DIFF_MESSAGE, SIMILAR_MESSAGE} from './constants';
import {DiffOptionsNormalized, DiffOptions as JestDiffOptions} from './types';
import {DiffOptionsNormalized, DiffOptions as ImportDiffOptions} from './types';

export type DiffOptions = ImportDiffOptions;

export {diffStringsRaw, diffStringsUnified};
export {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff};

const {
AsymmetricMatcher,
Expand Down Expand Up @@ -50,7 +50,7 @@ const FALLBACK_FORMAT_OPTIONS_0 = {...FALLBACK_FORMAT_OPTIONS, indent: 0};

// Generate a string that will highlight the difference between two values
// with green and red. (similar to how github does code diffing)
function diff(a: any, b: any, options?: JestDiffOptions): string | null {
function diff(a: any, b: any, options?: DiffOptions): string | null {
if (Object.is(a, b)) {
return NO_DIFF_MESSAGE;
}
Expand Down Expand Up @@ -163,16 +163,4 @@ function compareObjects(
return diffMessage;
}

// eslint-disable-next-line no-redeclare
namespace diff {
export type Diff = DiffClass;
export type DiffOptions = JestDiffOptions;
}

diff.diffStringsUnified = diffStringsUnified;
diff.diffStringsRaw = diffStringsRaw;
diff.DIFF_DELETE = DIFF_DELETE;
diff.DIFF_EQUAL = DIFF_EQUAL;
diff.DIFF_INSERT = DIFF_INSERT;

export = diff;
export default diff;
SimenB marked this conversation as resolved.
Show resolved Hide resolved
22 changes: 11 additions & 11 deletions packages/jest-matcher-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
*/

import chalk from 'chalk';
import jestDiff = require('jest-diff');
import getType = require('jest-get-type');
import prettyFormat = require('pretty-format');

const {
import diffLinesUnified, {
DIFF_DELETE,
DIFF_EQUAL,
DIFF_INSERT,
Diff,
DiffOptions as ImportDiffOptions,
diffStringsRaw,
diffStringsUnified,
} = jestDiff;
} from 'jest-diff';
import getType = require('jest-get-type');
import prettyFormat = require('pretty-format');

const {
AsymmetricMatcher,
Expand Down Expand Up @@ -49,7 +49,7 @@ export type MatcherHintOptions = {
secondArgumentColor?: MatcherHintColor;
};

export type DiffOptions = jestDiff.DiffOptions;
export type DiffOptions = ImportDiffOptions;

export const EXPECTED_COLOR = chalk.green;
export const RECEIVED_COLOR = chalk.red;
Expand Down Expand Up @@ -226,12 +226,12 @@ export const ensureExpectedIsNonNegativeInteger = (
// * include change substrings which have argument op
// with inverse highlight only if there is a common substring
const getCommonAndChangedSubstrings = (
diffs: Array<jestDiff.Diff>,
diffs: Array<Diff>,
op: number,
hasCommonDiff: boolean,
): string =>
diffs.reduce(
(reduced: string, diff: jestDiff.Diff): string =>
(reduced: string, diff: Diff): string =>
reduced +
(diff[0] === DIFF_EQUAL
? diff[1]
Expand Down Expand Up @@ -338,7 +338,7 @@ export const printDiffOrStringify = (
}

if (isLineDiffable(expected, received)) {
const difference = jestDiff(expected, received, {
const difference = diffLinesUnified(expected, received, {
aAnnotation: expectedLabel,
bAnnotation: receivedLabel,
expand,
Expand Down Expand Up @@ -378,7 +378,7 @@ const shouldPrintDiff = (actual: unknown, expected: unknown) => {
};

export const diff = (a: any, b: any, options?: DiffOptions): string | null =>
shouldPrintDiff(a, b) ? jestDiff(a, b, options) : null;
shouldPrintDiff(a, b) ? diffLinesUnified(a, b, options) : null;

export const pluralize = (word: string, count: number) =>
(NUMBERS[count] || count) + ' ' + word + (count === 1 ? '' : 's');
Expand Down
4 changes: 2 additions & 2 deletions packages/jest-snapshot/src/print.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

import diff = require('jest-diff');
import diff, {diffStringsUnified} from 'jest-diff';
import getType = require('jest-get-type');
import {
EXPECTED_COLOR,
Expand Down Expand Up @@ -86,7 +86,7 @@ export const printDiffOrStringified = (
receivedSerializedTrimmed.length <= MAX_DIFF_STRING_LENGTH &&
expectedSerializedTrimmed !== receivedSerializedTrimmed
) {
return diff.diffStringsUnified(
return diffStringsUnified(
expectedSerializedTrimmed,
receivedSerializedTrimmed,
{
Expand Down