From 42b020f2931ac04820521cc8037b7c430eb2fa2f Mon Sep 17 00:00:00 2001 From: Raymond Ng Date: Thu, 11 Nov 2021 00:28:32 -0800 Subject: [PATCH] Remove cycle in printDiffs, diffLines and joinAlignedDiffs (#10818) --- CHANGELOG.md | 1 + packages/jest-diff/src/diffLines.ts | 88 ++++++++- packages/jest-diff/src/joinAlignedDiffs.ts | 100 ++++++++++- packages/jest-diff/src/printDiffs.ts | 198 +-------------------- 4 files changed, 184 insertions(+), 203 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e3137df2d1f..5ac4d97d3e95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - `[expect]` Allow again `expect.Matchers` generic with single value ([#11986](https://github.com/facebook/jest/pull/11986)) - `[jest-core]` Incorrect detection of open ZLIB handles ([#12022](https://github.com/facebook/jest/pull/12022)) +- `[jest-diff]` Break dependency cycle ([#10818](https://github.com/facebook/jest/pull/10818)) - `[jest-environment-jsdom]` Add `@types/jsdom` dependency ([#11999](https://github.com/facebook/jest/pull/11999)) - `[jest-environment-jsdom]` Do not reset the global.document too early on teardown ([#11871](https://github.com/facebook/jest/pull/11871)) - `[jest-transform]` Improve error and warning messages ([#11998](https://github.com/facebook/jest/pull/11998)) diff --git a/packages/jest-diff/src/diffLines.ts b/packages/jest-diff/src/diffLines.ts index 89e71f866b49..6997250adcdd 100644 --- a/packages/jest-diff/src/diffLines.ts +++ b/packages/jest-diff/src/diffLines.ts @@ -7,13 +7,97 @@ import diff from 'diff-sequences'; import {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff} from './cleanupSemantic'; +import { + joinAlignedDiffsExpand, + joinAlignedDiffsNoExpand, +} from './joinAlignedDiffs'; import {normalizeDiffOptions} from './normalizeDiffOptions'; -import {printDiffLines} from './printDiffs'; -import type {DiffOptions} from './types'; +import type {DiffOptions, DiffOptionsNormalized} from './types'; const isEmptyString = (lines: Array) => lines.length === 1 && lines[0].length === 0; +type ChangeCounts = { + a: number; + b: number; +}; + +const countChanges = (diffs: Array): ChangeCounts => { + let a = 0; + let b = 0; + + diffs.forEach(diff => { + switch (diff[0]) { + case DIFF_DELETE: + a += 1; + break; + + case DIFF_INSERT: + b += 1; + break; + } + }); + + return {a, b}; +}; + +const printAnnotation = ( + { + aAnnotation, + aColor, + aIndicator, + bAnnotation, + bColor, + bIndicator, + includeChangeCounts, + omitAnnotationLines, + }: DiffOptionsNormalized, + changeCounts: ChangeCounts, +): string => { + if (omitAnnotationLines) { + return ''; + } + + let aRest = ''; + let bRest = ''; + + if (includeChangeCounts) { + const aCount = String(changeCounts.a); + const bCount = String(changeCounts.b); + + // Padding right aligns the ends of the annotations. + const baAnnotationLengthDiff = bAnnotation.length - aAnnotation.length; + const aAnnotationPadding = ' '.repeat(Math.max(0, baAnnotationLengthDiff)); + const bAnnotationPadding = ' '.repeat(Math.max(0, -baAnnotationLengthDiff)); + + // Padding left aligns the ends of the counts. + const baCountLengthDiff = bCount.length - aCount.length; + const aCountPadding = ' '.repeat(Math.max(0, baCountLengthDiff)); + const bCountPadding = ' '.repeat(Math.max(0, -baCountLengthDiff)); + + aRest = + aAnnotationPadding + ' ' + aIndicator + ' ' + aCountPadding + aCount; + bRest = + bAnnotationPadding + ' ' + bIndicator + ' ' + bCountPadding + bCount; + } + + return ( + aColor(aIndicator + ' ' + aAnnotation + aRest) + + '\n' + + bColor(bIndicator + ' ' + bAnnotation + bRest) + + '\n\n' + ); +}; + +export const printDiffLines = ( + diffs: Array, + options: DiffOptionsNormalized, +): string => + printAnnotation(options, countChanges(diffs)) + + (options.expand + ? joinAlignedDiffsExpand(diffs, options) + : joinAlignedDiffsNoExpand(diffs, options)); + // Compare two arrays of strings line-by-line. Format as comparison lines. export const diffLinesUnified = ( aLines: Array, diff --git a/packages/jest-diff/src/joinAlignedDiffs.ts b/packages/jest-diff/src/joinAlignedDiffs.ts index 3b3a079eaa6a..4124853fcf93 100644 --- a/packages/jest-diff/src/joinAlignedDiffs.ts +++ b/packages/jest-diff/src/joinAlignedDiffs.ts @@ -6,13 +6,99 @@ */ import {DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT, Diff} from './cleanupSemantic'; -import { - createPatchMark, - printCommonLine, - printDeleteLine, - printInsertLine, -} from './printDiffs'; -import type {DiffOptionsNormalized} from './types'; +import type {DiffOptionsColor, DiffOptionsNormalized} from './types'; + +const formatTrailingSpaces = ( + line: string, + trailingSpaceFormatter: DiffOptionsColor, +): string => line.replace(/\s+$/, match => trailingSpaceFormatter(match)); + +const printDiffLine = ( + line: string, + isFirstOrLast: boolean, + color: DiffOptionsColor, + indicator: string, + trailingSpaceFormatter: DiffOptionsColor, + emptyFirstOrLastLinePlaceholder: string, +): string => + line.length !== 0 + ? color( + indicator + ' ' + formatTrailingSpaces(line, trailingSpaceFormatter), + ) + : indicator !== ' ' + ? color(indicator) + : isFirstOrLast && emptyFirstOrLastLinePlaceholder.length !== 0 + ? color(indicator + ' ' + emptyFirstOrLastLinePlaceholder) + : ''; + +const printDeleteLine = ( + line: string, + isFirstOrLast: boolean, + { + aColor, + aIndicator, + changeLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder, + }: DiffOptionsNormalized, +): string => + printDiffLine( + line, + isFirstOrLast, + aColor, + aIndicator, + changeLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder, + ); + +const printInsertLine = ( + line: string, + isFirstOrLast: boolean, + { + bColor, + bIndicator, + changeLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder, + }: DiffOptionsNormalized, +): string => + printDiffLine( + line, + isFirstOrLast, + bColor, + bIndicator, + changeLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder, + ); + +const printCommonLine = ( + line: string, + isFirstOrLast: boolean, + { + commonColor, + commonIndicator, + commonLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder, + }: DiffOptionsNormalized, +): string => + printDiffLine( + line, + isFirstOrLast, + commonColor, + commonIndicator, + commonLineTrailingSpaceColor, + emptyFirstOrLastLinePlaceholder, + ); + +// In GNU diff format, indexes are one-based instead of zero-based. +const createPatchMark = ( + aStart: number, + aEnd: number, + bStart: number, + bEnd: number, + {patchColor}: DiffOptionsNormalized, +): string => + patchColor( + `@@ -${aStart + 1},${aEnd - aStart} +${bStart + 1},${bEnd - bStart} @@`, + ); // jest --no-expand // diff --git a/packages/jest-diff/src/printDiffs.ts b/packages/jest-diff/src/printDiffs.ts index 05f8619e2b93..cde7b881fc27 100644 --- a/packages/jest-diff/src/printDiffs.ts +++ b/packages/jest-diff/src/printDiffs.ts @@ -5,111 +5,14 @@ * LICENSE file in the root directory of this source tree. */ -import { - DIFF_DELETE, - DIFF_EQUAL, - DIFF_INSERT, - Diff, - cleanupSemantic, -} from './cleanupSemantic'; -import {diffLinesUnified} from './diffLines'; +import {DIFF_EQUAL, Diff, cleanupSemantic} from './cleanupSemantic'; +import {diffLinesUnified, printDiffLines} from './diffLines'; import diffStrings from './diffStrings'; import getAlignedDiffs from './getAlignedDiffs'; -import { - joinAlignedDiffsExpand, - joinAlignedDiffsNoExpand, -} from './joinAlignedDiffs'; import {normalizeDiffOptions} from './normalizeDiffOptions'; -import type { - DiffOptions, - DiffOptionsColor, - DiffOptionsNormalized, -} from './types'; +import type {DiffOptions} from './types'; -const formatTrailingSpaces = ( - line: string, - trailingSpaceFormatter: DiffOptionsColor, -): string => line.replace(/\s+$/, match => trailingSpaceFormatter(match)); - -const printDiffLine = ( - line: string, - isFirstOrLast: boolean, - color: DiffOptionsColor, - indicator: string, - trailingSpaceFormatter: DiffOptionsColor, - emptyFirstOrLastLinePlaceholder: string, -): string => - line.length !== 0 - ? color( - indicator + ' ' + formatTrailingSpaces(line, trailingSpaceFormatter), - ) - : indicator !== ' ' - ? color(indicator) - : isFirstOrLast && emptyFirstOrLastLinePlaceholder.length !== 0 - ? color(indicator + ' ' + emptyFirstOrLastLinePlaceholder) - : ''; - -export const printDeleteLine = ( - line: string, - isFirstOrLast: boolean, - { - aColor, - aIndicator, - changeLineTrailingSpaceColor, - emptyFirstOrLastLinePlaceholder, - }: DiffOptionsNormalized, -): string => - printDiffLine( - line, - isFirstOrLast, - aColor, - aIndicator, - changeLineTrailingSpaceColor, - emptyFirstOrLastLinePlaceholder, - ); - -export const printInsertLine = ( - line: string, - isFirstOrLast: boolean, - { - bColor, - bIndicator, - changeLineTrailingSpaceColor, - emptyFirstOrLastLinePlaceholder, - }: DiffOptionsNormalized, -): string => - printDiffLine( - line, - isFirstOrLast, - bColor, - bIndicator, - changeLineTrailingSpaceColor, - emptyFirstOrLastLinePlaceholder, - ); - -export const printCommonLine = ( - line: string, - isFirstOrLast: boolean, - { - commonColor, - commonIndicator, - commonLineTrailingSpaceColor, - emptyFirstOrLastLinePlaceholder, - }: DiffOptionsNormalized, -): string => - printDiffLine( - line, - isFirstOrLast, - commonColor, - commonIndicator, - commonLineTrailingSpaceColor, - emptyFirstOrLastLinePlaceholder, - ); - -export const hasCommonDiff = ( - diffs: Array, - isMultiline: boolean, -): boolean => { +const hasCommonDiff = (diffs: Array, isMultiline: boolean): boolean => { if (isMultiline) { // Important: Ignore common newline that was appended to multiline strings! const iLast = diffs.length - 1; @@ -121,99 +24,6 @@ export const hasCommonDiff = ( return diffs.some(diff => diff[0] === DIFF_EQUAL); }; -export type ChangeCounts = { - a: number; - b: number; -}; - -export const countChanges = (diffs: Array): ChangeCounts => { - let a = 0; - let b = 0; - - diffs.forEach(diff => { - switch (diff[0]) { - case DIFF_DELETE: - a += 1; - break; - - case DIFF_INSERT: - b += 1; - break; - } - }); - - return {a, b}; -}; - -export const printAnnotation = ( - { - aAnnotation, - aColor, - aIndicator, - bAnnotation, - bColor, - bIndicator, - includeChangeCounts, - omitAnnotationLines, - }: DiffOptionsNormalized, - changeCounts: ChangeCounts, -): string => { - if (omitAnnotationLines) { - return ''; - } - - let aRest = ''; - let bRest = ''; - - if (includeChangeCounts) { - const aCount = String(changeCounts.a); - const bCount = String(changeCounts.b); - - // Padding right aligns the ends of the annotations. - const baAnnotationLengthDiff = bAnnotation.length - aAnnotation.length; - const aAnnotationPadding = ' '.repeat(Math.max(0, baAnnotationLengthDiff)); - const bAnnotationPadding = ' '.repeat(Math.max(0, -baAnnotationLengthDiff)); - - // Padding left aligns the ends of the counts. - const baCountLengthDiff = bCount.length - aCount.length; - const aCountPadding = ' '.repeat(Math.max(0, baCountLengthDiff)); - const bCountPadding = ' '.repeat(Math.max(0, -baCountLengthDiff)); - - aRest = - aAnnotationPadding + ' ' + aIndicator + ' ' + aCountPadding + aCount; - bRest = - bAnnotationPadding + ' ' + bIndicator + ' ' + bCountPadding + bCount; - } - - return ( - aColor(aIndicator + ' ' + aAnnotation + aRest) + - '\n' + - bColor(bIndicator + ' ' + bAnnotation + bRest) + - '\n\n' - ); -}; - -export const printDiffLines = ( - diffs: Array, - options: DiffOptionsNormalized, -): string => - printAnnotation(options, countChanges(diffs)) + - (options.expand - ? joinAlignedDiffsExpand(diffs, options) - : joinAlignedDiffsNoExpand(diffs, options)); - -// In GNU diff format, indexes are one-based instead of zero-based. -export const createPatchMark = ( - aStart: number, - aEnd: number, - bStart: number, - bEnd: number, - {patchColor}: DiffOptionsNormalized, -): string => - patchColor( - `@@ -${aStart + 1},${aEnd - aStart} +${bStart + 1},${bEnd - bStart} @@`, - ); - // Compare two strings character-by-character. // Format as comparison lines in which changed substrings have inverse colors. export const diffStringsUnified = (