Skip to content
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

fix diff output for String objects; closes #2496 #2499

Merged
merged 1 commit into from
Sep 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 37 additions & 26 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ exports.map = function(arr, fn, scope) {
* @param {number} start
* @return {number}
*/
exports.indexOf = function(arr, obj, start) {
var indexOf = exports.indexOf = function(arr, obj, start) {
for (var i = start || 0, l = arr.length; i < l; i++) {
if (arr[i] === obj) {
return i;
Expand All @@ -107,7 +107,7 @@ exports.indexOf = function(arr, obj, start) {
* @param {Object} val Initial value.
* @return {*}
*/
exports.reduce = function(arr, fn, val) {
var reduce = exports.reduce = function(arr, fn, val) {
var rval = val;

for (var i = 0, l = arr.length; i < l; i++) {
Expand Down Expand Up @@ -313,7 +313,7 @@ exports.trim = function(str) {
* @return {Object}
*/
exports.parseQuery = function(qs) {
return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair) {
return reduce(qs.replace('?', '').split('&'), function(obj, pair) {
var i = pair.indexOf('=');
var key = pair.slice(0, i);
var val = pair.slice(++i);
Expand Down Expand Up @@ -366,13 +366,11 @@ exports.highlightTags = function(name) {
*
* @api private
* @param {*} value The value to inspect.
* @param {string} [type] The type of the value, if known.
* @param {string} typeHint The type of the value
* @returns {string}
*/
function emptyRepresentation(value, type) {
type = type || exports.type(value);

switch (type) {
function emptyRepresentation(value, typeHint) {
switch (typeHint) {
case 'function':
return '[Function]';
case 'object':
Expand All @@ -391,7 +389,7 @@ function emptyRepresentation(value, type) {
* @api private
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
* @param {*} value The value to test.
* @returns {string}
* @returns {string} Computed type
* @example
* type({}) // 'object'
* type([]) // 'array'
Expand All @@ -403,8 +401,9 @@ function emptyRepresentation(value, type) {
* type(/foo/) // 'regexp'
* type('type') // 'string'
* type(global) // 'global'
* type(new String('foo') // 'object'
*/
exports.type = function type(value) {
var type = exports.type = function type(value) {
if (value === undefined) {
return 'undefined';
} else if (value === null) {
Expand Down Expand Up @@ -433,25 +432,36 @@ exports.type = function type(value) {
* @return {string}
*/
exports.stringify = function(value) {
var type = exports.type(value);
var typeHint = type(value);

if (!~indexOf(['object', 'array', 'function'], typeHint)) {
if (typeHint === 'buffer') {
var json = value.toJSON();
// Based on the toJSON result
return jsonStringify(json.data && json.type ? json.data : json, 2)
.replace(/,(\n|$)/g, '$1');
}

if (!~exports.indexOf(['object', 'array', 'function'], type)) {
if (type !== 'buffer') {
// IE7/IE8 has a bizarre String constructor; needs to be coerced
// into an array and back to obj.
if (typeHint === 'string' && typeof value === 'object') {
value = reduce(value.split(''), function(acc, char, idx) {
acc[idx] = char;
return acc;
}, {});
typeHint = 'object';
} else {
return jsonStringify(value);
}
var json = value.toJSON();
// Based on the toJSON result
return jsonStringify(json.data && json.type ? json.data : json, 2)
.replace(/,(\n|$)/g, '$1');
}

for (var prop in value) {
if (Object.prototype.hasOwnProperty.call(value, prop)) {
return jsonStringify(exports.canonicalize(value), 2).replace(/,(\n|$)/g, '$1');
return jsonStringify(exports.canonicalize(value, null, typeHint), 2).replace(/,(\n|$)/g, '$1');
}
}

return emptyRepresentation(value, type);
return emptyRepresentation(value, typeHint);
};

/**
Expand Down Expand Up @@ -480,7 +490,7 @@ function jsonStringify(object, spaces, depth) {
}

function _stringify(val) {
switch (exports.type(val)) {
switch (type(val)) {
case 'null':
case 'undefined':
val = '[' + val + ']';
Expand Down Expand Up @@ -563,14 +573,15 @@ exports.isBuffer = function(value) {
* @see {@link exports.stringify}
* @param {*} value Thing to inspect. May or may not have properties.
* @param {Array} [stack=[]] Stack of seen values
* @param {string} [typeHint] Type hint
* @return {(Object|Array|Function|string|undefined)}
*/
exports.canonicalize = function(value, stack) {
exports.canonicalize = function canonicalize(value, stack, typeHint) {
var canonicalizedObj;
/* eslint-disable no-unused-vars */
var prop;
/* eslint-enable no-unused-vars */
var type = exports.type(value);
typeHint = typeHint || type(value);
function withStack(value, fn) {
stack.push(value);
fn();
Expand All @@ -579,11 +590,11 @@ exports.canonicalize = function(value, stack) {

stack = stack || [];

if (exports.indexOf(stack, value) !== -1) {
if (indexOf(stack, value) !== -1) {
return '[Circular]';
}

switch (type) {
switch (typeHint) {
case 'undefined':
case 'buffer':
case 'null':
Expand All @@ -604,7 +615,7 @@ exports.canonicalize = function(value, stack) {
}
/* eslint-enable guard-for-in */
if (!canonicalizedObj) {
canonicalizedObj = emptyRepresentation(value, type);
canonicalizedObj = emptyRepresentation(value, typeHint);
break;
}
/* falls through */
Expand Down Expand Up @@ -745,7 +756,7 @@ exports.stackTraceFilter = function() {
return function(stack) {
stack = stack.split('\n');

stack = exports.reduce(stack, function(list, line) {
stack = reduce(stack, function(list, line) {
if (isMochaInternal(line)) {
return list;
}
Expand Down
4 changes: 4 additions & 0 deletions test/acceptance/utils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ describe('lib/utils', function () {

var stringify = utils.stringify;

it('should return an object representation of a string created with a String constructor', function() {
expect(stringify(new String('foo'))).to.equal('{\n "0": "f"\n "1": "o"\n "2": "o"\n}');
});

it('should return Buffer with .toJSON representation', function() {
expect(stringify(new Buffer([0x01]))).to.equal('[\n 1\n]');
expect(stringify(new Buffer([0x01, 0x02]))).to.equal('[\n 1\n 2\n]');
Expand Down