版博士V2.0程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import * as diff from 'diff';
  2. import cliTruncate from 'cli-truncate';
  3. function formatLine(line, outputTruncateLength) {
  4. var _a;
  5. return cliTruncate(line, (outputTruncateLength ?? (((_a = process.stdout) == null ? void 0 : _a.columns) || 80)) - 4);
  6. }
  7. function unifiedDiff(actual, expected, options = {}) {
  8. if (actual === expected)
  9. return "";
  10. const { outputTruncateLength, outputDiffLines, outputDiffMaxLines, showLegend = true } = options;
  11. const indent = " ";
  12. const diffLimit = outputDiffLines || 15;
  13. const diffMaxLines = outputDiffMaxLines || 50;
  14. const counts = {
  15. "+": 0,
  16. "-": 0
  17. };
  18. let previousState = null;
  19. let previousCount = 0;
  20. const str = (str2) => str2;
  21. const dim = options.colorDim || str;
  22. const green = options.colorSuccess || str;
  23. const red = options.colorError || str;
  24. function preprocess(line) {
  25. if (!line || line.match(/\\ No newline/))
  26. return;
  27. const char = line[0];
  28. if ("-+".includes(char)) {
  29. if (previousState !== char) {
  30. previousState = char;
  31. previousCount = 0;
  32. }
  33. previousCount++;
  34. counts[char]++;
  35. if (previousCount === diffLimit)
  36. return dim(`${char} ...`);
  37. else if (previousCount > diffLimit)
  38. return;
  39. }
  40. return line;
  41. }
  42. const msg = diff.createPatch("string", expected, actual);
  43. let lines = msg.split("\n").slice(5).map(preprocess).filter(Boolean);
  44. let moreLines = 0;
  45. const isCompact = counts["+"] === 1 && counts["-"] === 1 && lines.length === 2;
  46. if (lines.length > diffMaxLines) {
  47. const firstDiff = lines.findIndex((line) => line[0] === "-" || line[0] === "+");
  48. const displayLines = lines.slice(firstDiff - 2, diffMaxLines);
  49. const lastDisplayedIndex = firstDiff - 2 + diffMaxLines;
  50. if (lastDisplayedIndex < lines.length)
  51. moreLines = lines.length - lastDisplayedIndex;
  52. lines = displayLines;
  53. }
  54. let formatted = lines.map((line) => {
  55. line = line.replace(/\\"/g, '"');
  56. if (line[0] === "-") {
  57. line = formatLine(line.slice(1), outputTruncateLength);
  58. if (isCompact)
  59. return green(line);
  60. return green(`- ${formatLine(line, outputTruncateLength)}`);
  61. }
  62. if (line[0] === "+") {
  63. line = formatLine(line.slice(1), outputTruncateLength);
  64. if (isCompact)
  65. return red(line);
  66. return red(`+ ${formatLine(line, outputTruncateLength)}`);
  67. }
  68. if (line.match(/@@/))
  69. return "--";
  70. return ` ${line}`;
  71. });
  72. if (moreLines)
  73. formatted.push(dim(`... ${moreLines} more lines`));
  74. if (showLegend) {
  75. if (isCompact) {
  76. formatted = [
  77. `${green("- Expected")} ${formatted[0]}`,
  78. `${red("+ Received")} ${formatted[1]}`
  79. ];
  80. } else {
  81. if (formatted[0].includes('"'))
  82. formatted[0] = formatted[0].replace('"', "");
  83. const last = formatted.length - 1;
  84. if (formatted[last].endsWith('"'))
  85. formatted[last] = formatted[last].slice(0, formatted[last].length - 1);
  86. formatted.unshift(
  87. green(`- Expected - ${counts["-"]}`),
  88. red(`+ Received + ${counts["+"]}`),
  89. ""
  90. );
  91. }
  92. }
  93. return formatted.map((i) => i ? indent + i : i).join("\n");
  94. }
  95. export { formatLine, unifiedDiff };