-
-
Notifications
You must be signed in to change notification settings - Fork 6.6k
jest-diff: Add options for colors and symbols #8841
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
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
d375c26
jest-diff: Add options for colors and symbols
pedrottimark 707fa69
Fix prettier lint errors in README
pedrottimark 664f191
Delete unneeded prettier-ignore comment from README
pedrottimark c23118b
Edit name of function in comment
pedrottimark 0246ae0
Update CHANGELOG.md
pedrottimark ddee70f
Add copyright and license comment to added source file
pedrottimark d03a394
Update packages/jest-diff/README.md
pedrottimark e4b2ba0
Resolve merge conflict related to sort-imports rule
pedrottimark bf23383
Fix lint error sort-imports
pedrottimark 9a4a7f7
Rename diffStringsAligned as diffStringsUnified
pedrottimark 43b2d4c
Remove diffStringsUnaligned call from jest-snapshot
pedrottimark 7829d51
Replace diffStringsUnaligned with diffStringsRaw
pedrottimark 67b2127
Add omitAnnotationLines option
pedrottimark 97d13bd
Example of option to omit annotation lines
pedrottimark 81ba9ee
Resolve merge conflicts
pedrottimark a2ad226
Correct reference to exported Diff type
pedrottimark 61b18f7
Add sentence about diffStringsRaw to jest-diff README
pedrottimark 109d706
Refactor to call diffStringsRaw from diffStringsUnified
pedrottimark 27b3313
Resolve merge conflict in CHANGELOG.md
pedrottimark File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,291 @@ | ||
# jest-diff | ||
|
||
Display differences clearly so people can review changes confidently. | ||
|
||
The default export serializes JavaScript **values** and compares them line-by-line. | ||
|
||
Two named exports compare **strings** character-by-character: | ||
|
||
- `diffStringsUnified` returns a string which includes comparison lines. | ||
- `diffStringsRaw` returns an array of `Diff` objects. | ||
|
||
## Installation | ||
|
||
To add this package as a dependency of a project, run either of the following commands: | ||
|
||
- `npm install jest-diff` | ||
- `yarn add jest-diff` | ||
|
||
## Usage of default export | ||
|
||
Given values and optional options, `diffLinesUnified(a, b, options?)` does the following: | ||
|
||
- **serialize** the values as strings using the `pretty-format` package | ||
- **compare** the strings line-by-line using the `diff-sequences` package | ||
- **format** the changed or common lines using the `chalk` package | ||
|
||
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 | ||
|
||
### Example of default export | ||
|
||
```js | ||
const a = ['delete', 'change from', 'common']; | ||
const b = ['change to', 'insert', 'common']; | ||
|
||
const difference = diffLinesUnified(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, but `Expected` lines are green, `Received` lines are red, and common lines are dim (by default, see Options) | ||
|
||
```diff | ||
- Expected | ||
+ Received | ||
|
||
Array [ | ||
- "delete", | ||
- "change from", | ||
+ "change to", | ||
+ "insert", | ||
"common", | ||
] | ||
``` | ||
|
||
### Edge cases of default export | ||
|
||
Here are edge cases for the return value: | ||
|
||
- `' Comparing two different types of values. …'` if the arguments have **different types** according to the `jest-get-type` package (instances of different classes have the same `'object'` type) | ||
- `'Compared values have no visual difference.'` if the arguments have either **referential identity** according to `Object.is` method or **same serialization** according to the `pretty-format` package | ||
- `null` if either argument is a so-called **asymmetric matcher** in Jasmine or Jest | ||
|
||
## Usage of diffStringsUnified | ||
|
||
Given strings and optional options, `diffStringsUnified(a, b, options?)` does the following: | ||
|
||
- **compare** the strings character-by-character using the `diff-sequences` package | ||
- **clean up** small (often coincidental) common substrings, also known as chaff | ||
- **format** the changed or common lines using the `chalk` package | ||
|
||
Although the function is mainly for **multiline** strings, it compares any strings. | ||
|
||
Write either of the following: | ||
|
||
- `const {diffStringsUnified} = require('jest-diff');` in a CommonJS module | ||
- `import {diffStringsUnified} from 'jest-diff';` in an ECMAScript module | ||
|
||
### Example of diffStringsUnified | ||
|
||
```js | ||
const a = 'change from\ncommon'; | ||
const b = 'change to\ncommon'; | ||
|
||
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 | ||
|
||
```diff | ||
- Expected | ||
+ Received | ||
|
||
- change from | ||
+ change to | ||
common | ||
``` | ||
|
||
### Edge cases of diffStringsUnified | ||
|
||
Here are edge cases for the return value: | ||
|
||
- both `a` and `b` are empty strings: no comparison lines | ||
- only `a` is empty string: all comparison lines have `bColor` and `bSymbol` (see Options) | ||
- only `b` is empty string: all comparison lines have `aColor` and `aSymbol` (see Options) | ||
- `a` and `b` are equal non-empty strings: all comparison lines have `commonColor` and `commonSymbol` (see Options) | ||
|
||
### Performance of diffStringsUnified | ||
|
||
To get the benefit of **changed substrings** within the comparison lines, a character-by-character comparison has a higher computational cost (in time and space) than a line-by-line comparison. | ||
|
||
If the input strings can have **arbitrary length**, we recommend that the calling code set a limit, beyond which it calls the default export instead. For example, Jest falls back to line-by-line comparison if either string has length greater than 20K characters. | ||
|
||
## Usage of diffStringsRaw | ||
|
||
Given strings, `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 | ||
|
||
The returned **array** describes substrings as instances of the `Diff` class (which calling code can access like array tuples). | ||
|
||
| 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). | ||
|
||
### Example of diffStringsRaw with cleanup | ||
|
||
```js | ||
const diffs = diffStringsRaw('change from', 'change to', true); | ||
|
||
// diffs[0][0] === DIFF_EQUAL | ||
// diffs[0][1] === 'change ' | ||
|
||
// diffs[1][0] === DIFF_DELETE | ||
// diffs[1][1] === 'from' | ||
|
||
// diffs[2][0] === 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[1][0] === DIFF_DELETE | ||
// diffs[1][1] === 'fr' | ||
|
||
// diffs[2][0] === DIFF_INSERT | ||
// diffs[2][1] === 't' | ||
|
||
// Here is a small coincidental common substring: | ||
// diffs[3][0] === DIFF_EQUAL | ||
// diffs[3][1] === 'o' | ||
|
||
// diffs[4][0] === DIFF_DELETE | ||
// diffs[4][1] === 'm' | ||
``` | ||
|
||
## Options | ||
|
||
The default options are for the report when an assertion fails from the `expect` package used by Jest. | ||
|
||
For other applications, you can provide an options object as a third argument: | ||
|
||
- `diffLinesUnified(a, b, options)` | ||
- `diffStringsUnified(a, b, options)` | ||
|
||
### Properties of options object | ||
|
||
| name | default | | ||
| :-------------------- | :------------ | | ||
| `aAnnotation` | `'Expected'` | | ||
| `aColor` | `chalk.green` | | ||
| `aSymbol` | `'-'` | | ||
| `bAnnotation` | `'Received'` | | ||
| `bColor` | `chalk.red` | | ||
| `bSymbol` | `'+'` | | ||
| `commonColor` | `chalk.dim` | | ||
| `commonSymbol` | `' '` | | ||
| `contextLines` | `5` | | ||
| `expand` | `true` | | ||
| `omitAnnotationLines` | `false` | | ||
SimenB marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Example of options for labels | ||
|
||
If the application is code modification, you might replace the labels: | ||
|
||
```js | ||
const options = { | ||
aAnnotation: 'Original', | ||
bAnnotation: 'Modified', | ||
}; | ||
``` | ||
|
||
The `jest-diff` package does not assume that the 2 labels have equal length. | ||
|
||
### Example of options for colors | ||
|
||
For consistency with most diff tools, you might exchange the colors: | ||
|
||
```js | ||
import chalk from 'chalk'; | ||
|
||
const options = { | ||
aColor: chalk.red, | ||
bColor: chalk.green, | ||
}; | ||
``` | ||
|
||
### Example of option to keep the default color | ||
|
||
The value of a color option is a function, which given a string, returns a string. | ||
|
||
For common lines to keep the default (usually black) color, you might provide an identity function: | ||
|
||
```js | ||
const options = { | ||
commonColor: line => line, | ||
}; | ||
``` | ||
|
||
### Example of options for symbols | ||
|
||
For consistency with the `diff` command, you might replace the symbols: | ||
|
||
```js | ||
const options = { | ||
aSymbol: '<', | ||
bSymbol: '>', | ||
}; | ||
``` | ||
|
||
The `jest-diff` package assumes (but does not enforce) that the 3 symbols have equal length. | ||
|
||
### Example of options to limit common lines | ||
|
||
By default, the output includes all common lines. | ||
|
||
To emphasize the changes, you might limit the number of common “context” lines: | ||
|
||
```js | ||
const options = { | ||
contextLines: 1, | ||
expand: false, | ||
}; | ||
``` | ||
|
||
A patch mark like `@@ -12,7 +12,9 @@` accounts for omitted common lines. | ||
|
||
### Example of option to omit annotation lines | ||
|
||
To display only the comparison lines: | ||
|
||
```js | ||
const a = 'change from\ncommon'; | ||
const b = 'change to\ncommon'; | ||
const options = { | ||
omitAnnotationLines: true, | ||
}; | ||
|
||
const difference = diffStringsUnified(a, b, options); | ||
``` | ||
|
||
```diff | ||
- change from | ||
+ change to | ||
common | ||
``` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.