From 5d4090015b934077174f26d010ddc4ad5af8b786 Mon Sep 17 00:00:00 2001 From: Mark Pedrotti Date: Wed, 4 Sep 2019 14:05:55 -0400 Subject: [PATCH 1/6] jest-diff: Add changeColor and patchColor options --- packages/jest-diff/README.md | 66 +++-- .../__tests__/__snapshots__/diff.test.ts.snap | 17 +- .../getAlignedDiffs.test.ts.snap | 172 +++++------ .../joinAlignedDiffs.test.ts.snap | 274 +++++++++--------- packages/jest-diff/src/__tests__/diff.test.ts | 40 ++- .../src/__tests__/getAlignedDiffs.test.ts | 22 +- .../src/__tests__/joinAlignedDiffs.test.ts | 66 ++++- packages/jest-diff/src/diffLines.ts | 4 +- packages/jest-diff/src/getAlignedDiffs.ts | 42 ++- packages/jest-diff/src/joinAlignedDiffs.ts | 10 +- .../jest-diff/src/normalizeDiffOptions.ts | 2 + packages/jest-diff/src/printDiffs.ts | 29 +- packages/jest-diff/src/types.ts | 6 +- 13 files changed, 441 insertions(+), 309 deletions(-) diff --git a/packages/jest-diff/README.md b/packages/jest-diff/README.md index 0ac49f1f894b..c3081376483d 100644 --- a/packages/jest-diff/README.md +++ b/packages/jest-diff/README.md @@ -91,7 +91,7 @@ const difference = diffStringsUnified(a, b); The returned **string** consists of: - annotation lines: describe the two change indicators 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) +- comparison lines: similar to “unified” view on GitHub, and **changed substrings** have **inverse** foreground and background colors (which the following example does not show) ```diff - Expected @@ -212,20 +212,22 @@ For other applications, you can provide an options object as a third argument: ### Properties of options object -| name | default | -| :-------------------- | :------------ | -| `aAnnotation` | `'Expected'` | -| `aColor` | `chalk.green` | -| `aIndicator` | `'-'` | -| `bAnnotation` | `'Received'` | -| `bColor` | `chalk.red` | -| `bIndicator` | `'+'` | -| `commonColor` | `chalk.dim` | -| `commonIndicator` | `' '` | -| `contextLines` | `5` | -| `expand` | `true` | -| `includeChangeCounts` | `false` | -| `omitAnnotationLines` | `false` | +| name | default | +| :-------------------- | :-------------- | +| `aAnnotation` | `'Expected'` | +| `aColor` | `chalk.green` | +| `aIndicator` | `'-'` | +| `bAnnotation` | `'Received'` | +| `bColor` | `chalk.red` | +| `bIndicator` | `'+'` | +| `changeColor` | `chalk.inverse` | +| `commonColor` | `chalk.dim` | +| `commonIndicator` | `' '` | +| `contextLines` | `5` | +| `expand` | `true` | +| `includeChangeCounts` | `false` | +| `omitAnnotationLines` | `false` | +| `patchColor` | `chalk.yellow` | ### Example of options for labels @@ -240,7 +242,7 @@ const options = { The `jest-diff` package does not assume that the 2 labels have equal length. -### Example of options for colors +### Example of options for colors of change lines For consistency with most diff tools, you might exchange the colors: @@ -252,16 +254,31 @@ const options = { bColor: chalk.green, }; ``` +### Example of option for color of change substrings -### Example of option to keep the default color +Although the default inverse of foreground and background colors is hard to beat for change substrings **within lines**, especially because it highlights spaces, if you want bold font weight on yellow background: + +```js +const options = { + changeColor: chalk.bold.bgAnsi256(226), // #ffff00 +}; +``` + +### Example of options for no colors 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: +To store the difference in a file without escape codes for colors, provide an identity function: ```js +const identity = string => string; + const options = { - commonColor: line => line, + aColor: identity, + bColor: identity, + changeColor: identity, + commonColor: identity, + patchColor: identity, }; ``` @@ -293,6 +310,17 @@ const options = { A patch mark like `@@ -12,7 +12,9 @@` accounts for omitted common lines. +### Example of option for color of patch marks + +If you want patch marks to have the same dim color as common lines: + +```js +const options = { + expand: false, + patchColor: chalk.dim, +}; +``` + ### Example of option to include change counts To display the number of change lines at the right of annotation lines: diff --git a/packages/jest-diff/src/__tests__/__snapshots__/diff.test.ts.snap b/packages/jest-diff/src/__tests__/__snapshots__/diff.test.ts.snap index 493fd9df66c8..8a9e97253172 100644 --- a/packages/jest-diff/src/__tests__/__snapshots__/diff.test.ts.snap +++ b/packages/jest-diff/src/__tests__/__snapshots__/diff.test.ts.snap @@ -103,7 +103,7 @@ exports[`context number of lines: -1 (5 default) 1`] = ` "- Expected 1 - + Received 1 + -@@ -6,9 +6,9 @@ +@@ -6,9 +6,9 @@ 4, 5, 6, @@ -156,7 +156,7 @@ exports[`context number of lines: 3.1 (5 default) 1`] = ` "- Expected 1 - + Received 1 + -@@ -6,9 +6,9 @@ +@@ -6,9 +6,9 @@ 4, 5, 6, @@ -173,7 +173,7 @@ exports[`context number of lines: undefined (5 default) 1`] = ` "- Expected 1 - + Received 1 + -@@ -6,9 +6,9 @@ +@@ -6,9 +6,9 @@ 4, 5, 6, @@ -322,6 +322,17 @@ exports[`options 7980 diffStringsUnified 1`] = ` + \`\${Ti.App.getName()} \${Ti.App.getVersion()} \${Ti.Platform.getName()} \${Ti.Platform.getVersion()}\`" `; +exports[`options change color diffStringsUnified 1`] = ` +"- Expected ++ Received + +- delete +- changed from ++ changed to ++ insert + common" +`; + exports[`options change indicators diff 1`] = ` "< Expected > Received diff --git a/packages/jest-diff/src/__tests__/__snapshots__/getAlignedDiffs.test.ts.snap b/packages/jest-diff/src/__tests__/__snapshots__/getAlignedDiffs.test.ts.snap index 48f282bf8a3e..44c519c9f6d4 100644 --- a/packages/jest-diff/src/__tests__/__snapshots__/getAlignedDiffs.test.ts.snap +++ b/packages/jest-diff/src/__tests__/__snapshots__/getAlignedDiffs.test.ts.snap @@ -1,160 +1,160 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`getAlignedDiffs lines change preceding and following common 1`] = ` -"- delete -+ insert - common between changes -- prev -+ next" +- delete ++ insert + common between changes +- prev ++ next `; exports[`getAlignedDiffs lines common at end when both current change lines are empty 1`] = ` -"- delete - common at end" +- delete + common at end `; exports[`getAlignedDiffs lines common between delete and insert 1`] = ` -"- delete - common between changes -+ insert" +- delete + common between changes ++ insert `; exports[`getAlignedDiffs lines common between insert and delete 1`] = ` -"+ insert - common between changes -- delete" ++ insert + common between changes +- delete `; exports[`getAlignedDiffs lines common preceding and following change 1`] = ` -" common preceding -- delete -+ insert - common following" + common preceding +- delete ++ insert + common following `; exports[`getAlignedDiffs newline change from space 1`] = ` -"- preceding following -+ preceding -+ following" +- preceding following ++ preceding ++ following `; exports[`getAlignedDiffs newline change to space 1`] = ` -"- preceding -- following -+ preceding following" +- preceding +- following ++ preceding following `; exports[`getAlignedDiffs newline delete only 1`] = ` -"- preceding -- following -+ precedingfollowing" +- preceding +- following ++ precedingfollowing `; exports[`getAlignedDiffs newline delete with adjacent change 1`] = ` -"- preceding -- following -+ precededfollowing" +- preceding +- following ++ precededfollowing `; exports[`getAlignedDiffs newline insert only 1`] = ` -"- precedingfollowing -+ preceding -+ following" +- precedingfollowing ++ preceding ++ following `; exports[`getAlignedDiffs newline insert with adjacent changes 1`] = ` -"- precededfollowing -+ preceding -+ Following" +- precededfollowing ++ preceding ++ Following `; exports[`getAlignedDiffs strings change at start and delete or insert at end 1`] = ` -"- prev change common delete -+ next change common - unchanged -- expected change common -+ received change common insert" +- prev change common delete ++ next change common + unchanged +- expected change common ++ received change common insert `; exports[`getAlignedDiffs strings delete or insert at start and change at end 1`] = ` -"- common change prev -+ insert common change next - unchanged -- delete common change this -+ common change that" +- common change prev ++ insert common change next + unchanged +- delete common change this ++ common change that `; exports[`getAlignedDiffs substrings first common when both current change lines are empty 1`] = ` -"+ insert - first - middle -- last prev -+ last next" ++ insert + first + middle +- last prev ++ last next `; exports[`getAlignedDiffs substrings first common when either current change line is non-empty 1`] = ` -"- expected first -+ first +- expected first ++ first - last" + last `; exports[`getAlignedDiffs substrings first delete completes the current line 1`] = ` -"- common preceding first -- middle -- last and following -+ common preceding and following" +- common preceding first +- middle +- last and following ++ common preceding and following `; exports[`getAlignedDiffs substrings first insert completes the current line 1`] = ` -"- common preceding -+ common preceding first -+ middle -+" +- common preceding ++ common preceding first ++ middle ++ `; exports[`getAlignedDiffs substrings last is empty in delete at end 1`] = ` -"- common string preceding prev -- -+ common string preceding next" +- common string preceding prev +- ++ common string preceding next `; exports[`getAlignedDiffs substrings last is empty in insert at end 1`] = ` -"- common string preceding prev -+ common string preceding next -+" +- common string preceding prev ++ common string preceding next ++ `; exports[`getAlignedDiffs substrings last is non-empty in common not at end 1`] = ` -" common first -- last expected -+ last received" + common first +- last expected ++ last received `; exports[`getAlignedDiffs substrings middle is empty in delete between common 1`] = ` -"- common at start precedes delete -- -- expected common at end -+ common at start precedes received common at end" +- common at start precedes delete +- +- expected common at end ++ common at start precedes received common at end `; exports[`getAlignedDiffs substrings middle is empty in insert at start 1`] = ` -"- expected common at end -+ insert line -+ -+ received common at end" +- expected common at end ++ insert line ++ ++ received common at end `; exports[`getAlignedDiffs substrings middle is non-empty in delete at end 1`] = ` -"- common at start precedes delete -- non-empty line -- next -+ common at start precedes prev" +- common at start precedes delete +- non-empty line +- next ++ common at start precedes prev `; exports[`getAlignedDiffs substrings middle is non-empty in insert between common 1`] = ` -"- common at start precedes delete expected -+ common at start precedes insert -+ non-empty -+ received" +- common at start precedes delete expected ++ common at start precedes insert ++ non-empty ++ received `; diff --git a/packages/jest-diff/src/__tests__/__snapshots__/joinAlignedDiffs.test.ts.snap b/packages/jest-diff/src/__tests__/__snapshots__/joinAlignedDiffs.test.ts.snap index 588beca3a445..cbc041c3ac19 100644 --- a/packages/jest-diff/src/__tests__/__snapshots__/joinAlignedDiffs.test.ts.snap +++ b/packages/jest-diff/src/__tests__/__snapshots__/joinAlignedDiffs.test.ts.snap @@ -1,160 +1,160 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`joinAlignedDiffsExpand first line is empty common 1`] = ` -" ↵ - common 2 preceding A - common 1 preceding A -- delete line -- change expected A -+ change received A - common 1 following A - common 2 following A - common 3 following A - common 4 following A - common 4 preceding B - common 3 preceding B - common 2 preceding B - common 1 preceding B -- change expected B -+ change received B -+ insert line - common 1 following B - common 2 following B - common 3 between B and C - common 2 preceding C - common 1 preceding C -- change expected C -+ change received C - common 1 following C - common 2 following C - common 3 following C + ↵ + common 2 preceding A + common 1 preceding A +- delete line +- change expected A ++ change received A + common 1 following A + common 2 following A + common 3 following A + common 4 following A + common 4 preceding B + common 3 preceding B + common 2 preceding B + common 1 preceding B +- change expected B ++ change received B ++ insert line + common 1 following B + common 2 following B + common 3 between B and C + common 2 preceding C + common 1 preceding C +- change expected C ++ change received C + common 1 following C + common 2 following C + common 3 following C - common 5 following C" + common 5 following C `; exports[`joinAlignedDiffsNoExpand patch 0 with context 1 and change at start and end 1`] = ` -"- delete - common following delete - common preceding insert -+ insert" +- delete + common following delete + common preceding insert ++ insert `; exports[`joinAlignedDiffsNoExpand patch 0 with context 5 and first line is empty common 1`] = ` -" ↵ - common 2 preceding A - common 1 preceding A -- delete line -- change expected A -+ change received A - common 1 following A - common 2 following A - common 3 following A - common 4 following A - common 4 preceding B - common 3 preceding B - common 2 preceding B - common 1 preceding B -- change expected B -+ change received B -+ insert line - common 1 following B - common 2 following B - common 3 between B and C - common 2 preceding C - common 1 preceding C -- change expected C -+ change received C - common 1 following C - common 2 following C - common 3 following C + ↵ + common 2 preceding A + common 1 preceding A +- delete line +- change expected A ++ change received A + common 1 following A + common 2 following A + common 3 following A + common 4 following A + common 4 preceding B + common 3 preceding B + common 2 preceding B + common 1 preceding B +- change expected B ++ change received B ++ insert line + common 1 following B + common 2 following B + common 3 between B and C + common 2 preceding C + common 1 preceding C +- change expected C ++ change received C + common 1 following C + common 2 following C + common 3 following C - common 5 following C" + common 5 following C `; exports[`joinAlignedDiffsNoExpand patch 1 with context 4 and last line is empty common 1`] = ` -"@@ -1,24 +1,24 @@ +@@ -1,24 +1,24 @@ - common 2 preceding A - common 1 preceding A -- delete line -- change expected A -+ change received A - common 1 following A - common 2 following A - common 3 following A - common 4 following A - common 4 preceding B - common 3 preceding B - common 2 preceding B - common 1 preceding B -- change expected B -+ change received B -+ insert line - common 1 following B - common 2 following B - common 3 between B and C - common 2 preceding C - common 1 preceding C -- change expected C -+ change received C - common 1 following C - common 2 following C - common 3 following C - ↵" + common 2 preceding A + common 1 preceding A +- delete line +- change expected A ++ change received A + common 1 following A + common 2 following A + common 3 following A + common 4 following A + common 4 preceding B + common 3 preceding B + common 2 preceding B + common 1 preceding B +- change expected B ++ change received B ++ insert line + common 1 following B + common 2 following B + common 3 between B and C + common 2 preceding C + common 1 preceding C +- change expected C ++ change received C + common 1 following C + common 2 following C + common 3 following C + ↵ `; exports[`joinAlignedDiffsNoExpand patch 2 with context 3 1`] = ` -"@@ -1,8 +1,7 @@ +@@ -1,8 +1,7 @@ - common 2 preceding A - common 1 preceding A -- delete line -- change expected A -+ change received A - common 1 following A - common 2 following A - common 3 following A -@@ -11,13 +10,14 @@ - common 3 preceding B - common 2 preceding B - common 1 preceding B -- change expected B -+ change received B -+ insert line - common 1 following B - common 2 following B - common 3 between B and C - common 2 preceding C - common 1 preceding C -- change expected C -+ change received C - common 1 following C - common 2 following C - common 3 following C" + common 2 preceding A + common 1 preceding A +- delete line +- change expected A ++ change received A + common 1 following A + common 2 following A + common 3 following A +@@ -11,13 +10,14 @@ + common 3 preceding B + common 2 preceding B + common 1 preceding B +- change expected B ++ change received B ++ insert line + common 1 following B + common 2 following B + common 3 between B and C + common 2 preceding C + common 1 preceding C +- change expected C ++ change received C + common 1 following C + common 2 following C + common 3 following C `; exports[`joinAlignedDiffsNoExpand patch 3 with context 2 and omit excess common at start 1`] = ` -"@@ -2,6 +2,5 @@ - common 2 preceding A - common 1 preceding A -- delete line -- change expected A -+ change received A - common 1 following A - common 2 following A -@@ -12,5 +11,6 @@ - common 2 preceding B - common 1 preceding B -- change expected B -+ change received B -+ insert line - common 1 following B - common 2 following B -@@ -18,5 +18,5 @@ - common 2 preceding C - common 1 preceding C -- change expected C -+ change received C - common 1 following C - common 2 following C" +@@ -2,6 +2,5 @@ + common 2 preceding A + common 1 preceding A +- delete line +- change expected A ++ change received A + common 1 following A + common 2 following A +@@ -12,5 +11,6 @@ + common 2 preceding B + common 1 preceding B +- change expected B ++ change received B ++ insert line + common 1 following B + common 2 following B +@@ -18,5 +18,5 @@ + common 2 preceding C + common 1 preceding C +- change expected C ++ change received C + common 1 following C + common 2 following C `; diff --git a/packages/jest-diff/src/__tests__/diff.test.ts b/packages/jest-diff/src/__tests__/diff.test.ts index 4ad245bd119f..68cb65845b66 100644 --- a/packages/jest-diff/src/__tests__/diff.test.ts +++ b/packages/jest-diff/src/__tests__/diff.test.ts @@ -838,23 +838,27 @@ test('collapses big diffs to patch format', () => { describe('context', () => { const testDiffContextLines = (contextLines?: number) => { - test(`number of lines: ${ - typeof contextLines === 'number' ? contextLines : 'undefined' - } ${ + const validContextLines = typeof contextLines === 'number' && Number.isSafeInteger(contextLines) && - contextLines >= 0 - ? '' - : '(5 default)' - }`, () => { + contextLines >= 0; + + test(`number of lines: ${ + typeof contextLines === 'number' ? contextLines : 'undefined' + } ${validContextLines ? '' : '(5 default)'}`, () => { + const options = { + ...optionsCounts, + contextLines, + expand: false, + }; + if (!validContextLines) { + options.patchColor = chalk.dim; + } + const result = diff( {test: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}, {test: [1, 2, 3, 4, 5, 6, 7, 8, 10, 9]}, - { - contextLines, - expand: false, - ...optionsCounts, - }, + options, ); expect(result).toMatchSnapshot(); }); @@ -952,6 +956,18 @@ describe('options', () => { }); }); + describe('change color', () => { + const options = { + changeColor: chalk.bold, + }; + + test('diffStringsUnified', () => { + const aChanged = a.join('\n').replace('change', 'changed'); + const bChanged = b.join('\n').replace('change', 'changed'); + expect(diffStringsUnified(aChanged, bChanged, options)).toMatchSnapshot(); + }); + }); + describe('common', () => { const options = { commonColor: line => line, diff --git a/packages/jest-diff/src/__tests__/getAlignedDiffs.test.ts b/packages/jest-diff/src/__tests__/getAlignedDiffs.test.ts index df825a822c6a..c1a05b9ed56c 100644 --- a/packages/jest-diff/src/__tests__/getAlignedDiffs.test.ts +++ b/packages/jest-diff/src/__tests__/getAlignedDiffs.test.ts @@ -7,8 +7,28 @@ import {diffStringsUnified} from '../printDiffs'; +// To align columns so people can review snapshots confidently: + +// 1. Use options to omit line colors. +const identity = (string: string) => string; +const changeColor = (string: string) => '' + string + ''; +const options = { + aColor: identity, + bColor: identity, + changeColor, + commonColor: identity, + omitAnnotationLines: true, + patchColor: identity, +}; + const testAlignedDiffs = (a: string, b: string): string => - diffStringsUnified(a, b, {omitAnnotationLines: true}); + diffStringsUnified(a, b, options); + +// 2. Add string serializer to omit double quote marks. +expect.addSnapshotSerializer({ + serialize: (val: string) => val, + test: (val: unknown) => typeof val === 'string', +}); describe('getAlignedDiffs', () => { describe('lines', () => { diff --git a/packages/jest-diff/src/__tests__/joinAlignedDiffs.test.ts b/packages/jest-diff/src/__tests__/joinAlignedDiffs.test.ts index 51ceeb874390..01c08878e935 100644 --- a/packages/jest-diff/src/__tests__/joinAlignedDiffs.test.ts +++ b/packages/jest-diff/src/__tests__/joinAlignedDiffs.test.ts @@ -6,20 +6,38 @@ */ import {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff} from '../cleanupSemantic'; -import {INVERTED_COLOR} from '../printDiffs'; import { joinAlignedDiffsExpand, joinAlignedDiffsNoExpand, } from '../joinAlignedDiffs'; import {normalizeDiffOptions} from '../normalizeDiffOptions'; +// To align columns so people can review snapshots confidently: + +// 1. Use options to omit line colors. +const identity = (string: string) => string; +const changeColor = (string: string) => '' + string + ''; +const optionsNoColor = { + aColor: identity, + bColor: identity, + changeColor, + commonColor: identity, + patchColor: identity, +}; + +// 2. Add string serializer to omit double quote marks. +expect.addSnapshotSerializer({ + serialize: (val: string) => val, + test: (val: unknown) => typeof val === 'string', +}); + const diffsCommonStartEnd = [ new Diff(DIFF_EQUAL, ''), new Diff(DIFF_EQUAL, 'common 2 preceding A'), new Diff(DIFF_EQUAL, 'common 1 preceding A'), new Diff(DIFF_DELETE, 'delete line'), - new Diff(DIFF_DELETE, ['change ', INVERTED_COLOR('expect'), 'ed A'].join('')), - new Diff(DIFF_INSERT, ['change ', INVERTED_COLOR('receiv'), 'ed A'].join('')), + new Diff(DIFF_DELETE, ['change ', changeColor('expect'), 'ed A'].join('')), + new Diff(DIFF_INSERT, ['change ', changeColor('receiv'), 'ed A'].join('')), new Diff(DIFF_EQUAL, 'common 1 following A'), new Diff(DIFF_EQUAL, 'common 2 following A'), new Diff(DIFF_EQUAL, 'common 3 following A'), @@ -28,16 +46,16 @@ const diffsCommonStartEnd = [ new Diff(DIFF_EQUAL, 'common 3 preceding B'), new Diff(DIFF_EQUAL, 'common 2 preceding B'), new Diff(DIFF_EQUAL, 'common 1 preceding B'), - new Diff(DIFF_DELETE, ['change ', INVERTED_COLOR('expect'), 'ed B'].join('')), - new Diff(DIFF_INSERT, ['change ', INVERTED_COLOR('receiv'), 'ed B'].join('')), + new Diff(DIFF_DELETE, ['change ', changeColor('expect'), 'ed B'].join('')), + new Diff(DIFF_INSERT, ['change ', changeColor('receiv'), 'ed B'].join('')), new Diff(DIFF_INSERT, 'insert line'), new Diff(DIFF_EQUAL, 'common 1 following B'), new Diff(DIFF_EQUAL, 'common 2 following B'), new Diff(DIFF_EQUAL, 'common 3 between B and C'), new Diff(DIFF_EQUAL, 'common 2 preceding C'), new Diff(DIFF_EQUAL, 'common 1 preceding C'), - new Diff(DIFF_DELETE, ['change ', INVERTED_COLOR('expect'), 'ed C'].join('')), - new Diff(DIFF_INSERT, ['change ', INVERTED_COLOR('receiv'), 'ed C'].join('')), + new Diff(DIFF_DELETE, ['change ', changeColor('expect'), 'ed C'].join('')), + new Diff(DIFF_INSERT, ['change ', changeColor('receiv'), 'ed C'].join('')), new Diff(DIFF_EQUAL, 'common 1 following C'), new Diff(DIFF_EQUAL, 'common 2 following C'), new Diff(DIFF_EQUAL, 'common 3 following C'), @@ -54,7 +72,8 @@ const diffsChangeStartEnd = [ describe('joinAlignedDiffsExpand', () => { test('first line is empty common', () => { - const options = normalizeDiffOptions(); + const options = normalizeDiffOptions(optionsNoColor); + expect( joinAlignedDiffsExpand(diffsCommonStartEnd, options), ).toMatchSnapshot(); @@ -63,35 +82,56 @@ describe('joinAlignedDiffsExpand', () => { describe('joinAlignedDiffsNoExpand', () => { test('patch 0 with context 1 and change at start and end', () => { - const options = normalizeDiffOptions({contextLines: 1, expand: false}); + const options = normalizeDiffOptions({ + ...optionsNoColor, + contextLines: 1, + expand: false, + }); + expect( joinAlignedDiffsNoExpand(diffsChangeStartEnd, options), ).toMatchSnapshot(); }); test('patch 0 with context 5 and first line is empty common', () => { - const options = normalizeDiffOptions({expand: false}); + const options = normalizeDiffOptions({...optionsNoColor, expand: false}); + expect( joinAlignedDiffsNoExpand(diffsCommonStartEnd, options), ).toMatchSnapshot(); }); test('patch 1 with context 4 and last line is empty common', () => { - const options = normalizeDiffOptions({contextLines: 4, expand: false}); + const options = normalizeDiffOptions({ + ...optionsNoColor, + contextLines: 4, + expand: false, + }); + expect( joinAlignedDiffsNoExpand(diffsCommonStartEnd, options), ).toMatchSnapshot(); }); test('patch 2 with context 3', () => { - const options = normalizeDiffOptions({contextLines: 3, expand: false}); + const options = normalizeDiffOptions({ + ...optionsNoColor, + contextLines: 3, + expand: false, + }); + expect( joinAlignedDiffsNoExpand(diffsCommonStartEnd, options), ).toMatchSnapshot(); }); test('patch 3 with context 2 and omit excess common at start', () => { - const options = normalizeDiffOptions({contextLines: 2, expand: false}); + const options = normalizeDiffOptions({ + ...optionsNoColor, + contextLines: 2, + expand: false, + }); + expect( joinAlignedDiffsNoExpand(diffsCommonStartEnd, options), ).toMatchSnapshot(); diff --git a/packages/jest-diff/src/diffLines.ts b/packages/jest-diff/src/diffLines.ts index 305b8a19fd16..3855f7d2e935 100644 --- a/packages/jest-diff/src/diffLines.ts +++ b/packages/jest-diff/src/diffLines.ts @@ -291,7 +291,7 @@ const diffNoExpand = ( aEnd += nContextLines; bEnd += nContextLines; - array[iPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd); + array[iPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd, options); // If common subsequence is not at end, another patch follows it. if (!isAtEnd) { @@ -332,7 +332,7 @@ const diffNoExpand = ( if (aStart === 0 && aEnd === aLength && bStart === 0 && bEnd === bLength) { array.splice(0, 1); // delete placeholder line for patch mark } else { - array[iPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd); + array[iPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd, options); } return printAnnotation(options, changeCounts) + array.join('\n'); diff --git a/packages/jest-diff/src/getAlignedDiffs.ts b/packages/jest-diff/src/getAlignedDiffs.ts index 2dae77412fd0..33d05ee23e67 100644 --- a/packages/jest-diff/src/getAlignedDiffs.ts +++ b/packages/jest-diff/src/getAlignedDiffs.ts @@ -5,19 +5,41 @@ * LICENSE file in the root directory of this source tree. */ -import {DIFF_DELETE, DIFF_INSERT, Diff} from './cleanupSemantic'; -import {invertChangedSubstrings} from './printDiffs'; +import {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff} from './cleanupSemantic'; +import {DiffOptionsColor} from './types'; + +// Given change op and array of diffs, return concatenateRelevantDiffsd string: +// * include common strings +// * include change strings which have argument op with changeColor +// * exclude change strings which have opposite op +const concatenateRelevantDiffs = ( + op: number, + diffs: Array, + changeColor: DiffOptionsColor, +): string => + diffs.reduce( + (reduced: string, diff: Diff): string => + reduced + + (diff[0] === DIFF_EQUAL + ? diff[1] + : diff[0] === op && diff[1].length !== 0 // empty if change is newline + ? changeColor(diff[1]) + : ''), + '', + ); // Encapsulate change lines until either a common newline or the end. class ChangeBuffer { private op: number; private line: Array; // incomplete line private lines: Array; // complete lines + private changeColor: DiffOptionsColor; - constructor(op: number) { + constructor(op: number, changeColor: DiffOptionsColor) { this.op = op; this.line = []; this.lines = []; + this.changeColor = changeColor; } private pushSubstring(substring: string): void { @@ -33,7 +55,10 @@ class ChangeBuffer { // otherwise then it has line color only. this.lines.push( this.line.length !== 1 - ? new Diff(this.op, invertChangedSubstrings(this.op, this.line)) + ? new Diff( + this.op, + concatenateRelevantDiffs(this.op, this.line, this.changeColor), + ) : this.line[0][0] === this.op ? this.line[0] // can use instance : new Diff(this.op, this.line[0][1]), // was common diff @@ -180,9 +205,12 @@ class CommonBuffer { // Assume the function is not called: // * if either expected or received is empty string // * if neither expected nor received is multiline string -const getAlignedDiffs = (diffs: Array): Array => { - const deleteBuffer = new ChangeBuffer(DIFF_DELETE); - const insertBuffer = new ChangeBuffer(DIFF_INSERT); +const getAlignedDiffs = ( + diffs: Array, + changeColor: DiffOptionsColor, +): Array => { + const deleteBuffer = new ChangeBuffer(DIFF_DELETE, changeColor); + const insertBuffer = new ChangeBuffer(DIFF_INSERT, changeColor); const commonBuffer = new CommonBuffer(deleteBuffer, insertBuffer); diffs.forEach(diff => { diff --git a/packages/jest-diff/src/joinAlignedDiffs.ts b/packages/jest-diff/src/joinAlignedDiffs.ts index db00e5720bc5..7ae7a9b41ff4 100644 --- a/packages/jest-diff/src/joinAlignedDiffs.ts +++ b/packages/jest-diff/src/joinAlignedDiffs.ts @@ -144,7 +144,13 @@ export const joinAlignedDiffsNoExpand = ( pushCommonLine(diffs[iCommon][1]); } - lines[jPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd); + lines[jPatchMark] = createPatchMark( + aStart, + aEnd, + bStart, + bEnd, + options, + ); jPatchMark = lines.length; lines.push(''); // placeholder line for next patch mark @@ -177,7 +183,7 @@ export const joinAlignedDiffsNoExpand = ( } if (hasPatch) { - lines[jPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd); + lines[jPatchMark] = createPatchMark(aStart, aEnd, bStart, bEnd, options); } return lines.join('\n'); diff --git a/packages/jest-diff/src/normalizeDiffOptions.ts b/packages/jest-diff/src/normalizeDiffOptions.ts index efdeab6701ab..4433edb8f84c 100644 --- a/packages/jest-diff/src/normalizeDiffOptions.ts +++ b/packages/jest-diff/src/normalizeDiffOptions.ts @@ -18,12 +18,14 @@ const OPTIONS_DEFAULT: DiffOptionsNormalized = { bAnnotation: 'Received', bColor: chalk.red, bIndicator: '+', + changeColor: chalk.inverse, commonColor: chalk.dim, commonIndicator: ' ', contextLines: DIFF_CONTEXT_DEFAULT, expand: true, includeChangeCounts: false, omitAnnotationLines: false, + patchColor: chalk.yellow, }; const getContextLines = (contextLines?: number): number => diff --git a/packages/jest-diff/src/printDiffs.ts b/packages/jest-diff/src/printDiffs.ts index 1abad0c3b416..93ada7d8e8e1 100644 --- a/packages/jest-diff/src/printDiffs.ts +++ b/packages/jest-diff/src/printDiffs.ts @@ -5,8 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import chalk from 'chalk'; - import { DIFF_DELETE, DIFF_EQUAL, @@ -24,28 +22,6 @@ import { import {normalizeDiffOptions} from './normalizeDiffOptions'; import {DiffOptions, DiffOptionsNormalized} from './types'; -export const INVERTED_COLOR = chalk.inverse; // export for joinAlignedDiffs test -const PATCH_COLOR = chalk.yellow; - -// Given change op and array of diffs, return concatenated string: -// * include common strings -// * include change strings which have argument op (inverse highlight) -// * exclude change strings which have opposite op -export const invertChangedSubstrings = ( - op: number, - diffs: Array, -): string => - diffs.reduce( - (reduced: string, diff: Diff): string => - reduced + - (diff[0] === DIFF_EQUAL - ? diff[1] - : diff[0] === op - ? INVERTED_COLOR(diff[1]) - : ''), - '', - ); - const NEWLINE_SYMBOL = '\u{21B5}'; // downwards arrow with corner leftwards const SPACE_SYMBOL = '\u{00B7}'; // middle dot @@ -172,8 +148,9 @@ export const createPatchMark = ( aEnd: number, bStart: number, bEnd: number, + {patchColor}: DiffOptionsNormalized, ): string => - PATCH_COLOR( + patchColor( `@@ -${aStart + 1},${aEnd - aStart} +${bStart + 1},${bEnd - bStart} @@`, ); @@ -243,7 +220,7 @@ export const diffStringsUnified = ( ); if (hasCommonDiff(diffs, isMultiline)) { - const lines = getAlignedDiffs(diffs); + const lines = getAlignedDiffs(diffs, optionsNormalized.changeColor); return ( printAnnotation(optionsNormalized, countChanges(lines)) + (optionsNormalized.expand diff --git a/packages/jest-diff/src/types.ts b/packages/jest-diff/src/types.ts index 5647286e30fe..f79ff163c956 100644 --- a/packages/jest-diff/src/types.ts +++ b/packages/jest-diff/src/types.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -type DiffOptionsColor = (arg: string) => string; // subset of Chalk type +export type DiffOptionsColor = (arg: string) => string; // subset of Chalk type export type DiffOptions = { aAnnotation?: string; @@ -14,12 +14,14 @@ export type DiffOptions = { bAnnotation?: string; bColor?: DiffOptionsColor; bIndicator?: string; + changeColor?: DiffOptionsColor; commonColor?: DiffOptionsColor; commonIndicator?: string; contextLines?: number; expand?: boolean; includeChangeCounts?: boolean; omitAnnotationLines?: boolean; + patchColor?: DiffOptionsColor; }; export type DiffOptionsNormalized = { @@ -29,10 +31,12 @@ export type DiffOptionsNormalized = { bAnnotation: string; bColor: DiffOptionsColor; bIndicator: string; + changeColor: DiffOptionsColor; commonColor: DiffOptionsColor; commonIndicator: string; contextLines: number; expand: boolean; includeChangeCounts: boolean; omitAnnotationLines: boolean; + patchColor: DiffOptionsColor; }; From c2226b080c656cdc275e1cad667aa79ae8207b9f Mon Sep 17 00:00:00 2001 From: Mark Pedrotti Date: Wed, 4 Sep 2019 14:17:12 -0400 Subject: [PATCH 2/6] Edit comment --- packages/jest-diff/src/getAlignedDiffs.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-diff/src/getAlignedDiffs.ts b/packages/jest-diff/src/getAlignedDiffs.ts index 33d05ee23e67..c17117b4a199 100644 --- a/packages/jest-diff/src/getAlignedDiffs.ts +++ b/packages/jest-diff/src/getAlignedDiffs.ts @@ -8,7 +8,7 @@ import {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff} from './cleanupSemantic'; import {DiffOptionsColor} from './types'; -// Given change op and array of diffs, return concatenateRelevantDiffsd string: +// Given change op and array of diffs, return concatenated string: // * include common strings // * include change strings which have argument op with changeColor // * exclude change strings which have opposite op From 8ee0ac56966baac9b614168646b000820c1b8155 Mon Sep 17 00:00:00 2001 From: Mark Pedrotti Date: Wed, 4 Sep 2019 14:21:21 -0400 Subject: [PATCH 3/6] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc78d401485a..c8bd846baeb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - `[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-diff]` Add `includeChangeCounts` and rename `Indicator` options ([#8881](https://github.com/facebook/jest/pull/8881)) +- `[jest-diff]` Add `changeColor` and `patchColor` options ([#8911](https://github.com/facebook/jest/pull/8911)) - `[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)) From c0676bab4fdabc2b0d998baa314dc6dbb1b24a85 Mon Sep 17 00:00:00 2001 From: Mark Pedrotti Date: Wed, 4 Sep 2019 14:31:48 -0400 Subject: [PATCH 4/6] Fix prettier lint error in README.md --- packages/jest-diff/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/jest-diff/README.md b/packages/jest-diff/README.md index c3081376483d..f9899b5a63f1 100644 --- a/packages/jest-diff/README.md +++ b/packages/jest-diff/README.md @@ -254,6 +254,7 @@ const options = { bColor: chalk.green, }; ``` + ### Example of option for color of change substrings Although the default inverse of foreground and background colors is hard to beat for change substrings **within lines**, especially because it highlights spaces, if you want bold font weight on yellow background: From 9be9c2617e5ee81f8b30ad28eb6aae1ded064fed Mon Sep 17 00:00:00 2001 From: Mark Pedrotti Date: Wed, 4 Sep 2019 16:11:39 -0400 Subject: [PATCH 5/6] Replace 4 occurrences of change with changed --- packages/jest-diff/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/jest-diff/README.md b/packages/jest-diff/README.md index f9899b5a63f1..60ee1846534f 100644 --- a/packages/jest-diff/README.md +++ b/packages/jest-diff/README.md @@ -242,7 +242,7 @@ const options = { The `jest-diff` package does not assume that the 2 labels have equal length. -### Example of options for colors of change lines +### Example of options for colors of changes lines For consistency with most diff tools, you might exchange the colors: @@ -255,9 +255,9 @@ const options = { }; ``` -### Example of option for color of change substrings +### Example of option for color of changes substringss -Although the default inverse of foreground and background colors is hard to beat for change substrings **within lines**, especially because it highlights spaces, if you want bold font weight on yellow background: +Although the default inverse of foreground and background colors is hard to beat for changes substringss **within lines**, especially because it highlights spaces, if you want bold font weight on yellow background: ```js const options = { @@ -324,7 +324,7 @@ const options = { ### Example of option to include change counts -To display the number of change lines at the right of annotation lines: +To display the number of changes lines at the right of annotation lines: ```js const a = ['change from', 'common']; From e5916a5ae4f92231592db238c479948922b204be Mon Sep 17 00:00:00 2001 From: Mark Pedrotti Date: Wed, 4 Sep 2019 16:43:21 -0400 Subject: [PATCH 6/6] Replace 4 occurrences of change with changed correctly this time --- packages/jest-diff/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/jest-diff/README.md b/packages/jest-diff/README.md index 60ee1846534f..32d2670572ff 100644 --- a/packages/jest-diff/README.md +++ b/packages/jest-diff/README.md @@ -242,7 +242,7 @@ const options = { The `jest-diff` package does not assume that the 2 labels have equal length. -### Example of options for colors of changes lines +### Example of options for colors of changed lines For consistency with most diff tools, you might exchange the colors: @@ -255,9 +255,9 @@ const options = { }; ``` -### Example of option for color of changes substringss +### Example of option for color of changed substrings -Although the default inverse of foreground and background colors is hard to beat for changes substringss **within lines**, especially because it highlights spaces, if you want bold font weight on yellow background: +Although the default inverse of foreground and background colors is hard to beat for changed substrings **within lines**, especially because it highlights spaces, if you want bold font weight on yellow background: ```js const options = { @@ -324,7 +324,7 @@ const options = { ### Example of option to include change counts -To display the number of changes lines at the right of annotation lines: +To display the number of changed lines at the right of annotation lines: ```js const a = ['change from', 'common'];