Skip to content
This repository has been archived by the owner on Oct 25, 2023. It is now read-only.

Commit

Permalink
feat: add function to stringify objects with Buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
imurchie committed Oct 26, 2019
1 parent 923f815 commit 7a537c8
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 1 deletion.
35 changes: 35 additions & 0 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,40 @@ function safeJsonParse (obj) {
}
}

/*
* Stringifies the object passed in, converting Buffers into Strings for better
* display. This mimics JSON.stringify (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)
* except the `replacer` argument can only be a function.
*
* @param {object} obj - the object to be serialized
* @param {?function} replacer - function to transform the properties added to the
* serialized object
* @param {?number|string} space - used to insert white space into the output JSON
* string for readability purposes. Defaults to 2
* returns {string} - the JSON object serialized as a string
*/
function jsonStringify (obj, replacer, space = 2) {
// if no replacer is passed, or it is not a function, just use a pass-through
if (!_.isFunction(replacer)) {
replacer = (k, v) => v;
}

// Buffers cannot be serialized in a readable way
const bufferToJSON = Buffer.prototype.toJSON;
delete Buffer.prototype.toJSON;
try {
return JSON.stringify(obj, (key, value) => {
const updatedValue = Buffer.isBuffer(value)
? value.toString('utf8')
: value;
return replacer(key, updatedValue);
}, space);
} finally {
// restore the function, so as to not break further serialization
Buffer.prototype.toJSON = bufferToJSON;
}
}

/*
* Removes the wrapper from element, if it exists.
* { ELEMENT: 4 } becomes 4
Expand Down Expand Up @@ -300,4 +334,5 @@ export {
multiResolve, safeJsonParse, wrapElement, unwrapElement, filterObject,
toReadableSizeString, isSubPath, W3C_WEB_ELEMENT_IDENTIFIER,
isSameDestination, compareVersions, coerceVersion, quote, unleakString,
jsonStringify,
};
68 changes: 67 additions & 1 deletion test/util-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,77 @@ describe('util', function () {
util.safeJsonParse(num).should.eql(num);
});
it('should make a number from a string representation', function () {
let num = 42;
const num = 42;
util.safeJsonParse(String(num)).should.eql(num);
});
});

describe('jsonStringify', function () {
it('should use JSON.stringify if no Buffer involved', function () {
const obj = {
k1: 'v1',
k2: 'v2',
k3: 'v3',
};
const jsonString = JSON.stringify(obj, null, 2);
util.jsonStringify(obj).should.eql(jsonString);
});
it('should serialize a Buffer', function () {
const obj = {
k1: 'v1',
k2: 'v2',
k3: Buffer.from('hi how are you today'),
};
util.jsonStringify(obj).should.include('hi how are you today');
});
it('should use the replacer function on non-buffer values', function () {
const obj = {
k1: 'v1',
k2: 'v2',
k3: 'v3',
};
function replacer (key, value) {
return _.isString(value) ? value.toUpperCase() : value;
}
const jsonString = util.jsonStringify(obj, replacer);
jsonString.should.include('V1');
jsonString.should.include('V2');
jsonString.should.include('V3');
});
it('should use the replacer function on buffers', function () {
const obj = {
k1: 'v1',
k2: 'v2',
k3: Buffer.from('hi how are you today'),
};
function replacer (key, value) {
return _.isString(value) ? value.toUpperCase() : value;
}
const jsonString = util.jsonStringify(obj, replacer);
jsonString.should.include('V1');
jsonString.should.include('V2');
jsonString.should.include('HI HOW ARE YOU TODAY');
});
it('should use the replacer function recursively', function () {
const obj = {
k1: 'v1',
k2: 'v2',
k3: Buffer.from('hi how are you today'),
k4: {
k5: 'v5',
},
};
function replacer (key, value) {
return _.isString(value) ? value.toUpperCase() : value;
}
const jsonString = util.jsonStringify(obj, replacer);
jsonString.should.include('V1');
jsonString.should.include('V2');
jsonString.should.include('HI HOW ARE YOU TODAY');
jsonString.should.include('V5');
});
});

describe('unwrapElement', function () {
it('should pass through an unwrapped element', function () {
let el = 4;
Expand Down

0 comments on commit 7a537c8

Please sign in to comment.