index.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. 'use strict';
  2. var BaseRenderer = require('power-assert-renderer-base');
  3. var inherits = require('util').inherits;
  4. var typeName = require('type-name');
  5. var keys = require('core-js/library/fn/object/keys');
  6. var forEach = require('core-js/library/fn/array/for-each');
  7. var udiff = require('./lib/udiff');
  8. var stringifier = require('stringifier');
  9. var assign = require('core-js/library/fn/object/assign');
  10. var defaultOptions = require('./lib/default-options');
  11. var literalPattern = /^(?:String|Numeric|Null|Boolean|RegExp)?Literal$/;
  12. function isLiteral (node) {
  13. return literalPattern.test(node.type);
  14. }
  15. /**
  16. * options.stringify [function]
  17. * options.maxDepth [number]
  18. * options.lineSeparator [string]
  19. * options.anonymous [string]
  20. * options.circular [string]
  21. *
  22. * options.diff [function]
  23. * options.lineDiffThreshold [number]
  24. */
  25. function ComparisonRenderer (config) {
  26. BaseRenderer.call(this);
  27. this.config = assign({}, defaultOptions(), config);
  28. if (typeof this.config.stringify === 'function') {
  29. this.stringify = this.config.stringify;
  30. } else {
  31. this.stringify = stringifier(this.config);
  32. }
  33. if (typeof this.config.diff === 'function') {
  34. this.diff = this.config.diff;
  35. } else {
  36. this.diff = udiff(this.config);
  37. }
  38. this.espathToPair = {};
  39. }
  40. inherits(ComparisonRenderer, BaseRenderer);
  41. ComparisonRenderer.prototype.onData = function (esNode) {
  42. var pair;
  43. if (!esNode.isCaptured) {
  44. if (isTargetBinaryExpression(esNode.parent) && isLiteral(esNode.node)) {
  45. this.espathToPair[esNode.parent.espath][esNode.key] = {code: esNode.code, value: esNode.value};
  46. }
  47. return;
  48. }
  49. if (isTargetBinaryExpression(esNode.parent)) {
  50. this.espathToPair[esNode.parent.espath][esNode.key] = {code: esNode.code, value: esNode.value};
  51. }
  52. if (isTargetBinaryExpression(esNode)) {
  53. pair = {
  54. operator: esNode.node.operator,
  55. value: esNode.value
  56. };
  57. this.espathToPair[esNode.espath] = pair;
  58. }
  59. };
  60. ComparisonRenderer.prototype.onEnd = function () {
  61. var _this = this;
  62. var pairs = [];
  63. forEach(keys(this.espathToPair), function (espath) {
  64. var pair = _this.espathToPair[espath];
  65. if (pair.left && pair.right) {
  66. pairs.push(pair);
  67. }
  68. });
  69. forEach(pairs, function (pair) {
  70. _this.compare(pair);
  71. });
  72. };
  73. ComparisonRenderer.prototype.compare = function (pair) {
  74. if (isStringDiffTarget(pair)) {
  75. this.showStringDiff(pair);
  76. } else {
  77. this.showExpectedAndActual(pair);
  78. }
  79. };
  80. ComparisonRenderer.prototype.showExpectedAndActual = function (pair) {
  81. this.write('');
  82. this.write('[' + typeName(pair.right.value) + '] ' + pair.right.code);
  83. this.write('=> ' + this.stringify(pair.right.value));
  84. this.write('[' + typeName(pair.left.value) + '] ' + pair.left.code);
  85. this.write('=> ' + this.stringify(pair.left.value));
  86. };
  87. ComparisonRenderer.prototype.showStringDiff = function (pair) {
  88. this.write('');
  89. this.write('--- [string] ' + pair.right.code);
  90. this.write('+++ [string] ' + pair.left.code);
  91. this.write(this.diff(pair.right.value, pair.left.value, this.config));
  92. };
  93. function isTargetBinaryExpression (esNode) {
  94. return esNode &&
  95. esNode.node.type === 'BinaryExpression' &&
  96. (esNode.node.operator === '===' || esNode.node.operator === '==') &&
  97. esNode.isCaptured &&
  98. !(esNode.value);
  99. }
  100. function isStringDiffTarget(pair) {
  101. return typeof pair.left.value === 'string' && typeof pair.right.value === 'string';
  102. }
  103. ComparisonRenderer.udiff = udiff;
  104. module.exports = ComparisonRenderer;