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 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
88 changes: 57 additions & 31 deletions packages/jest-diff/README.md
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');` in CommonJS modules
SimenB marked this conversation as resolved.
Show resolved Hide resolved
- `import diffLinesUnified from 'jest-diff';` in ECMAScript or TypeScript 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 or TypeScript 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,90 @@ 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 or TypeScript 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

Here are all the named imports for the `diffStringsRaw` function:

// diffs[4][0] === DIFF_DELETE
// diffs[4][1] === 'm'
- `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 or TypeScript modules

If you write TypeScript declarations like `diff: Diff` or `diffs: Array<Diff>` in a **formatting** function, then `error TS2749: 'Diff' refers to a value, but is being used as a type here.` means you need to declare the **instance** type of the **constructor** function type, as follows:

```ts
type Diff = InstanceType<typeof Diff>;
```

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
35 changes: 35 additions & 0 deletions packages/jest-diff/src/__tests__/diffStringsRaw.test.ts
@@ -0,0 +1,35 @@
/**
* 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 jestDiff = require('../');
const {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff, diffStringsRaw} = jestDiff;

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);
});
});
10 changes: 3 additions & 7 deletions packages/jest-diff/src/index.ts
Expand Up @@ -8,12 +8,7 @@
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';
Expand Down Expand Up @@ -165,14 +160,15 @@ function compareObjects(

// 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;
diff.Diff = Diff;

export = diff;
SimenB marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 4 additions & 2 deletions packages/jest-matcher-utils/src/index.ts
Expand Up @@ -14,9 +14,11 @@ const {
DIFF_DELETE,
DIFF_EQUAL,
DIFF_INSERT,
Diff,
diffStringsRaw,
diffStringsUnified,
} = jestDiff;
type Diff = InstanceType<typeof Diff>;

const {
AsymmetricMatcher,
Expand Down Expand Up @@ -226,12 +228,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