Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

should-format

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

should-format - npm Package Compare versions

Comparing version 0.0.7 to 0.1.0

.eslintrc

388

index.js
var getType = require('should-type');
var util = require('./util');

@@ -8,29 +9,124 @@ function genKeysFunc(f) {

return k;
}
};
}
//XXX add ability to only inspect some paths
var format = function(value, opts) {
function Formatter(opts) {
opts = opts || {};
if(!('seen' in opts)) opts.seen = [];
opts.keys = genKeysFunc('keys' in opts && opts.keys === false ? Object.getOwnPropertyNames : Object.keys);
this.seen = [];
this.keys = genKeysFunc(opts.keys === false ? Object.getOwnPropertyNames : Object.keys);
if(!('maxLineLength' in opts)) opts.maxLineLength = 60;
if(!('propSep' in opts)) opts.propSep = ',';
this.maxLineLength = typeof opts.maxLineLength === 'number' ? opts.maxLineLength : 60;
this.propSep = opts.propSep || ',';
}
var type = getType(value);
return (format.formats[type] || format.formats['object'])(value, opts);
Formatter.prototype = {
constructor: Formatter,
format: function(value) {
var t = getType(value);
var name1 = t.type, name2 = t.type;
if(t.cls) {
name1 += '_' + t.cls;
name2 += '_' + t.cls;
}
if(t.sub) {
name2 += '_' + t.sub;
}
var f = this['_format_' + name2] || this['_format_' + name1] || this['_format_' + t.type] || this.defaultFormat;
return f.call(this, value);
},
formatObject: function(value, prefix, props) {
props = props || this.keys(value);
var len = 0;
this.seen.push(value);
props = props.map(function(prop) {
var f = this.formatProperty(value, prop);
len += f.length;
return f;
}, this);
this.seen.pop();
if(props.length === 0) return '{}';
if(len <= this.maxLineLength) {
return '{ ' + (prefix ? prefix + ' ' : '') + props.join(this.propSep + ' ') + ' }';
} else {
return '{' + '\n' + (prefix ? ' ' + prefix + '\n' : '') + props.map(util.addSpaces).join(this.propSep + '\n') + '\n' + '}';
}
},
formatPropertyName: function(name) {
return name.match(/^[a-zA-Z_$][a-zA-Z_$0-9]*$/) ? name : this.format(name);
},
formatProperty: function(value, prop) {
var desc;
try {
desc = Object.getOwnPropertyDescriptor(value, prop) || {value: value[prop]};
} catch(e) {
desc = {value: e};
}
var propName = this.formatPropertyName(prop);
var propValue = desc.get && desc.set ?
'[Getter/Setter]' : desc.get ?
'[Getter]' : desc.set ?
'[Setter]' : this.seen.indexOf(desc.value) >= 0 ?
'[Circular]' :
this.format(desc.value);
return propName + ': ' + propValue;
}
};
module.exports = format;
Formatter.add = function add(type, cls, sub, f) {
var args = Array.prototype.slice.call(arguments);
f = args.pop();
Formatter.prototype['_format_' + args.join('_')] = f;
};
format.formats = {};
Formatter.formatObjectWithPrefix = function formatObjectWithPrefix(f) {
return function(value) {
var prefix = f.call(this, value);
var props = this.keys(value);
if(props.length == 0) return prefix;
else return this.formatObject(value, prefix, props);
};
};
function add(t, f) {
format.formats[t] = f;
}
var functionNameRE = /^\s*function\s*(\S*)\s*\(/;
[ 'undefined', 'boolean', 'null'].forEach(function(name) {
add(name, String);
Formatter.functionName = function functionName(f) {
if(f.name) {
return f.name;
}
var name = f.toString().match(functionNameRE)[1];
return name;
};
Formatter.generateFunctionForIndexedArray = function generateFunctionForIndexedArray(lengthProp, name, padding) {
return function(value) {
var str = '';
var max = 50;
var len = value[lengthProp];
if(len > 0) {
for(var i = 0; i < max && i < len; i++) {
var b = value[i] || 0;
str += ' ' + util.pad0(b.toString(16), padding);
}
if(len > max)
str += ' ... ';
}
return '[' + (value.constructor.name || name) + (str ? ':' + str : '') + ']';
};
};
['undefined', 'boolean', 'null', 'symbol'].forEach(function(name) {
Formatter.add(name, String);
});

@@ -40,11 +136,12 @@

var capName = name.substring(0, 1).toUpperCase() + name.substring(1);
add('object-' + name, formatObjectWithPrefix(function(value) {
return '[' + capName + ': ' + format(value.valueOf()) + ']';
Formatter.add('object', name, Formatter.formatObjectWithPrefix(function(value) {
return '[' + capName + ': ' + this.format(value.valueOf()) + ']';
}));
});
add('object-string', function(value, opts) {
Formatter.add('object', 'string', function(value) {
var realValue = value.valueOf();
var prefix = '[String: ' + format(realValue) + ']';
var props = opts.keys(value);
var prefix = '[String: ' + this.format(realValue) + ']';
var props = this.keys(value);
props = props.filter(function(p) {

@@ -55,8 +152,8 @@ return !(p.match(/\d+/) && parseInt(p, 10) < realValue.length);

if(props.length == 0) return prefix;
else return formatObject(value, opts, prefix, props);
else return this.formatObject(value, prefix, props);
});
add('regexp', formatObjectWithPrefix(String));
Formatter.add('object', 'regexp', Formatter.formatObjectWithPrefix(String));
add('number', function(value) {
Formatter.add('number', function(value) {
if(value === 0 && 1 / value < 0) return '-0';

@@ -66,3 +163,3 @@ return String(value);

add('string', function(value) {
Formatter.add('string', function(value) {
return '\'' + JSON.stringify(value).replace(/^"|"$/g, '')

@@ -73,9 +170,11 @@ .replace(/'/g, "\\'")

add('object', formatObject);
Formatter.add('object', function(value) {
return this.formatObject(value);
});
add('array', function(value, opts) {
var keys = opts.keys(value);
Formatter.add('object', 'array', function(value) {
var keys = this.keys(value);
var len = 0;
opts.seen.push(value);
this.seen.push(value);

@@ -92,167 +191,160 @@ var props = keys.map(function(prop) {

if(prop.match(/\d+/)) {
f = format(desc.value, opts);
f = this.format(desc.value);
} else {
f = formatProperty(desc.value, opts, prop)
f = this.formatProperty(desc.value, prop);
}
len += f.length;
return f;
});
}, this);
opts.seen.pop();
this.seen.pop();
if(props.length === 0) return '[]';
if(len <= opts.maxLineLength) {
return '[ ' + props.join(opts.propSep + ' ') + ' ]';
if(len <= this.maxLineLength) {
return '[ ' + props.join(this.propSep + ' ') + ' ]';
} else {
return '[' + '\n' + props.map(addSpaces).join(opts.propSep + '\n') + '\n' + ']';
return '[' + '\n' + props.map(util.addSpaces).join(this.propSep + '\n') + '\n' + ']';
}
});
function addSpaces(v) {
return v.split('\n').map(function(vv) { return ' ' + vv; }).join('\n');
function formatDate(value) {
var to = value.getTimezoneOffset();
var absTo = Math.abs(to);
var hours = Math.floor(absTo / 60);
var minutes = absTo - hours * 60;
var tzFormat = 'GMT' + (to < 0 ? '+' : '-') + util.pad0(hours, 2) + util.pad0(minutes, 2);
return value.toLocaleDateString() + ' '
+ value.toLocaleTimeString() + '.'
+ util.pad0(value.getMilliseconds(), 3) + ' ' + tzFormat;
}
function formatObject(value, opts, prefix, props) {
props = props || opts.keys(value);
Formatter.add('object', 'date', Formatter.formatObjectWithPrefix(formatDate));
var len = 0;
Formatter.add('function', Formatter.formatObjectWithPrefix(function(value) {
var name = Formatter.functionName(value);
return '[Function' + (name ? ': ' + name : '') + ']';
}));
opts.seen.push(value);
props = props.map(function(prop) {
var f = formatProperty(value, opts, prop);
len += f.length;
return f;
});
opts.seen.pop();
Formatter.add('object', 'error', Formatter.formatObjectWithPrefix(function(value) {
var name = value.name;
var message = value.message;
return '[' + name + (message ? ': ' + message : '') + ']';
}));
if(props.length === 0) return '{}';
Formatter.add('object', 'buffer', Formatter.generateFunctionForIndexedArray('length', 'Buffer', 2));
if(len <= opts.maxLineLength) {
return '{ ' + (prefix ? prefix + ' ' : '') + props.join(opts.propSep + ' ') + ' }';
} else {
return '{' + '\n' + (prefix ? prefix + '\n' : '') + props.map(addSpaces).join(opts.propSep + '\n') + '\n' + '}';
}
}
Formatter.add('object', 'array-buffer', Formatter.generateFunctionForIndexedArray('byteLength', 'ArrayBuffer', 2));
format.formatPropertyName = function(name, opts) {
return name.match(/^[a-zA-Z_$][a-zA-Z_$0-9]*$/) ? name : format(name, opts)
};
Formatter.add('object', 'typed-array', 'int8', Formatter.generateFunctionForIndexedArray('length', 'Int8Array', 2));
Formatter.add('object', 'typed-array', 'uint8', Formatter.generateFunctionForIndexedArray('length', 'Uint8Array', 2));
Formatter.add('object', 'typed-array', 'uint8clamped', Formatter.generateFunctionForIndexedArray('length', 'Uint8ClampedArray', 2));
Formatter.add('object', 'typed-array', 'int16', Formatter.generateFunctionForIndexedArray('length', 'Int16Array', 4));
Formatter.add('object', 'typed-array', 'uint16', Formatter.generateFunctionForIndexedArray('length', 'Uint16Array', 4));
function formatProperty(value, opts, prop) {
var desc;
try {
desc = Object.getOwnPropertyDescriptor(value, prop) || {value: value[prop]};
} catch(e) {
desc = {value: e};
}
Formatter.add('object', 'typed-array', 'int32', Formatter.generateFunctionForIndexedArray('length', 'Int32Array', 8));
Formatter.add('object', 'typed-array', 'uint32', Formatter.generateFunctionForIndexedArray('length', 'Uint32Array', 8));
var propName = format.formatPropertyName(prop, opts);
//TODO add float32 and float64
var propValue = desc.get && desc.set ?
'[Getter/Setter]' : desc.get ?
'[Getter]' : desc.set ?
'[Setter]' : opts.seen.indexOf(desc.value) >= 0 ?
'[Circular]' :
format(desc.value, opts);
Formatter.add('object', 'promise', function() {
return '[Promise]';//TODO it could be nice to inspect its state and value
});
return propName + ': ' + propValue;
}
Formatter.add('object', 'xhr', function() {
return '[XMLHttpRequest]';//TODO it could be nice to inspect its state
});
Formatter.add('object', 'html-element', function(value) {
return value.outerHTML;
});
function pad2Zero(n) {
return n < 10 ? '0' + n : '' + n;
}
Formatter.add('object', 'html-element', '#text', function(value) {
return value.nodeValue;
});
function pad3Zero(n) {
return n < 100 ? '0' + pad2Zero(n) : '' + n;
}
Formatter.add('object', 'html-element', '#document', function(value) {
return value.documentElement.outerHTML;
});
function formatDate(value) {
var to = value.getTimezoneOffset();
var absTo = Math.abs(to);
var hours = Math.floor(absTo / 60);
var minutes = absTo - hours * 60;
var tzFormat = 'GMT' + (to < 0 ? '+' : '-') + pad2Zero(hours) + pad2Zero(minutes);
return value.toLocaleDateString() + ' ' + value.toLocaleTimeString() + '.' + pad3Zero(value.getMilliseconds()) + ' ' + tzFormat;
}
Formatter.add('object', 'window', function() {
return '[Window]';
});
function formatObjectWithPrefix(f) {
return function(value, opts) {
var prefix = f(value);
var props = opts.keys(value);
if(props.length == 0) return prefix;
else return formatObject(value, opts, prefix, props);
Formatter.add('object', 'set', function(value) {
var iter = value.values();
var len = 0;
this.seen.push(value);
var props = [];
var next = iter.next();
while(!next.done) {
var val = next.value;
var f = this.format(val);
len += f.length;
props.push(f);
next = iter.next();
}
}
add('date', formatObjectWithPrefix(formatDate));
this.seen.pop();
var functionNameRE = /^\s*function\s*(\S*)\s*\(/;
if(props.length === 0) return '{ [Set] }';
function functionName(f) {
if(f.name) {
return f.name;
if(len <= this.maxLineLength) {
return '{ [Set] ' + props.join(this.propSep + ' ') + ' }';
} else {
return '{\n [Set]\n' + props.map(util.addSpaces).join(this.propSep + '\n') + '\n' + '}';
}
var name = f.toString().match(functionNameRE)[1];
return name;
}
});
add('function', formatObjectWithPrefix(function(value) {
var name = functionName(value);
return '[Function' + (name ? ': ' + name : '') + ']';
}));
Formatter.add('object', 'map', function(value) {
var iter = value.entries();
var len = 0;
add('error', formatObjectWithPrefix(function(value) {
var name = value.name;
var message = value.message;
return '[' + name + (message ? ': ' + message : '') + ']';
}));
this.seen.push(value);
function generateFunctionForIndexedArray(lengthProp, name) {
return function(value) {
var str = '';
var max = 50;
var len = value[lengthProp];
if(len > 0) {
for(var i = 0; i < max && i < len; i++) {
var b = value[i] || 0;
str += ' ' + pad2Zero(b.toString(16));
}
if(len > max)
str += ' ... ';
var props = [];
var next = iter.next();
while(!next.done) {
var val = next.value;
var fK = this.format(val[0]);
var fV = this.format(val[1]);
var f;
if((fK.length + fV.length + 4) <= this.maxLineLength) {
f = fK + ' => ' + fV;
} else {
f = fK + ' =>\n' + fV;
}
return '[' + (value.constructor.name || name) + (str ? ':' + str : '') + ']';
}
}
add('buffer', generateFunctionForIndexedArray('length', 'Buffer'));
len += fK.length + fV.length + 4;
props.push(f);
add('array-buffer', generateFunctionForIndexedArray('byteLength'));
next = iter.next();
}
add('typed-array', generateFunctionForIndexedArray('byteLength'));
this.seen.pop();
add('promise', function(value) {
return '[Promise]';
});
if(props.length === 0) return '{ [Map] }';
add('xhr', function(value) {
return '[XMLHttpRequest]';
if(len <= this.maxLineLength) {
return '{ [Map] ' + props.join(this.propSep + ' ') + ' }';
} else {
return '{\n [Map]\n' + props.map(util.addSpaces).join(this.propSep + '\n') + '\n' + '}';
}
});
add('html-element', function(value) {
return value.outerHTML;
});
Formatter.prototype.defaultFormat = Formatter.prototype._format_object;
add('html-element-text', function(value) {
return value.nodeValue;
});
function defaultFormat(value, opts) {
return new Formatter(opts).format(value);
}
add('document', function(value) {
return value.documentElement.outerHTML;
});
add('window', function(value) {
return '[Window]';
});
defaultFormat.Formatter = Formatter;
module.exports = defaultFormat;
{
"name": "should-format",
"version": "0.0.7",
"version": "0.1.0",
"description": "Formatting of objects for should.js",

@@ -21,9 +21,9 @@ "main": "index.js",

"devDependencies": {
"browserify": "^6.2.0",
"mocha": "^2.0.1",
"mocha-better-spec-reporter": "^1.1.1"
"browserify": "latest",
"mocha": "latest",
"mocha-better-spec-reporter": "latest"
},
"dependencies": {
"should-type": "0.0.4"
"should-type": "0.1.1"
}
}

@@ -1,4 +0,5 @@

var format = require('../');
var assert = require('assert');
var format = require('../');
it('should format numbers', function() {

@@ -146,2 +147,7 @@ assert.equal(format(10), '10');

var int16 = new Int16Array(3);
int16[0] = 0x201;
int16[1] = 0x2;
assert.equal(format(int16), '[Int16Array: 0201 0002 0000]');
//var dataView = new DataView(buffer);

@@ -166,2 +172,20 @@ //assert.equal(format(dataView), '[DataView: 00 20 02 00 00 00 00 00]');

assert.equal(format({ a: { b: 'abc' }, d: 'abc'}, { maxLineLength: 0 }), '{\n a: {\n b: \'abc\'\n },\n d: \'abc\'\n}')
});
});
it('should format set', function() {
if(typeof Set !== 'undefined') {
assert.equal(format(new Set([1, 2, { a: 10}, 'abc'])),
'{ [Set] 1, 2, { a: 10 }, \'abc\' }');
assert.equal(format(new Set([1, 2, { a: 10}, 'abc']), { maxLineLength: 0 }),
'{\n [Set]\n 1,\n 2,\n {\n a: 10\n },\n \'abc\'\n}');
}
});
it('should format map', function() {
if(typeof Map !== 'undefined') {
assert.equal(format(new Map([[1, 2], [2, 'abc'], [{ a: 10}, new Set()], ['abc', null]])),
'{ [Map] 1 => 2, 2 => \'abc\', { a: 10 } => { [Set] }, \'abc\' => null }');
assert.equal(format(new Map([[1, 2], [2, 'abc'], [{ a: 10}, new Set()], ['abc', null]]), { maxLineLength: 10 }),
'{\n [Map]\n 1 => 2,\n 2 => \'abc\',\n { a: 10 } =>\n { [Set] },\n \'abc\' =>\n null\n}');
}
});

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc