Test Report

1
0
27
96
ID Title Duration (ms)
1 Purdy should display an error 7
2 Purdy should display an error with detail 4
3 Purdy should indent array correctly 6
4 Purdy allows for removal of array index 0
5 Purdy honors indent level 1
6 Purdy should print plain 0
7 Purdy should handle circular references 2
8 Purdy should print a function 0
9 Purdy should print an anonymous function 1
10 Purdy should print a string 0
11 Purdy should print a date 2
12 Purdy should print a number 0
13 Purdy should print null 1
14 Purdy should print undefined 0
15 Purdy should print a regular expression 1
16 Purdy should print a false boolean 1
17 Purdy should print a true boolean 0
18 Purdy should print an empty array without extra indentation 0
19 Purdy should print an empty object without extra indentation 0
20 Purdy should print a more complex object 3
21 Purdy should not print circular after second use 1
22 Purdy shows circular reference with path 0
23 Purdy will keep a path for an object in Hoek format 6
24 Purdy indents object the way it should 0
25 Purdy aligns object the way it should 2
26 Purdy prints directly to console 3
27 Purdy prints symbols
Error: Cannot find module 'purdy' at Function.Module._resolveFilename (module.js:336:15) at Function.Module._load (module.js:286:25) at Module.require (module.js:365:17) at require (module.js:384:17) at /net/luffy/usr/home/daniel/work/purdy.js/test/purdy.js:273:17 at Immediate._onImmediate (/net/luffy/usr/home/daniel/work/purdy.js/node_modules/lab/lib/runner.js:453:17) at processImmediate [as _immediateCallback] (timers.js:371:17)
48

Code Coverage Report

99.47%
187
186
1

lib/index.js

99.47%
187
186
1
Line Hits Source
1 // Load modules
2
3 1 var Chalk = require('chalk');
4 1 var Hoek = require('hoek');
5
6
7 // declare internals
8
9 1 var internals = {
10 indentLevel: 0,
11 colors: {
12 BoolFalse: 'red.bold',
13 BoolTrue: 'green.bold',
14 Circular: 'grey.bold',
15 Date: 'green',
16 error: 'red',
17 Function: 'cyan',
18 Key: 'white.bold',
19 Null: 'red.bold',
20 Number: 'blue.bold',
21 RegExp: 'magenta',
22 String: 'yellow',
23 Undefined: 'red.inverse',
24 path: 'blue'
25 },
26 defaults: {
27 plain: false,
28 path: false,
29 indent: 4,
30 align: 'left',
31 arrayIndex: true,
32 pathPrefix: '// '
33 }
34 };
35
36
37 1 internals.purdy = function (object, options) {
38
39 1 return console.log(internals.stringify(object, options));
40 };
41
42
43 1 internals.stringify = function (object, options) {
44
45 29 internals.seen = [];
46 29 internals.path = [];
47 29 internals.settings = Hoek.applyToDefaults(internals.defaults, options || {});
48 29 return internals.travel(object, '');
49 };
50
51
52 1 internals.purdy.stringify = internals.stringify;
53
54
55 1 module.exports = internals.purdy;
56
57
58 1 internals.travel = function (object, path) {
59
60 98 var type = global.toString.call(object).split(' ')[1].slice(0, -1);
61 98 var format = '';
62
63 98 if (internals[type]) {
64 51 format = internals[type](object, path);
65 }
66 else {
67 47 format = String(object);
68 }
69
70 98 return internals.colorize(format, type);
71 };
72
73
74 1 internals.colorize = function (string, type) {
75
76 166 if (internals.settings.plain) {
77 74 return string;
78 }
79
80 92 var colors = internals.colors[type];
81 92 if (!colors) {
82 23 return string;
83 }
84
85 69 var colorArr = colors.split('.');
86
87 69 for (var i = 0, il = colorArr.length; i < il; ++i) {
88 118 var color = colorArr[i];
89 118 string = Chalk[color](string);
90 }
91
92 69 return string;
93 };
94
95
96 1 internals.lengthCompare = function (a, b) {
97 55 return a.length - b.length;
98 };
99
100
101 1 internals.tidyPath = function (path) {
102
103 4 return internals.colorize(path.slice(1, path.size), 'path');
104 };
105
106 1 internals.Object = function (object, path) {
107
108 22 if (Object.keys(object).length === 0) {
109 1 return '{}';
110 }
111
112 21 var index = internals.seen.indexOf(object);
113 21 if (index !== -1) {
114 3 return internals.showCircular(index);
115 }
116 18 internals.seen.push(object);
117 18 internals.path.push(path);
118
119 18 var keys = Object.keys(object);
120
if (
Object.getOwnPropertySymbols
) {
121 18 keys = keys.concat(Object.getOwnPropertySymbols(object));
122 }
123 18 var keyLengths = Hoek.clone(keys);
124 18 internals.indentLevel = internals.indentLevel + 1;
125 18 var out = '{\n';
126
127 18 for (var i = 0, il = keys.length; i < il; ++i) {
128 29 var key = keys[i];
129 29 var item = object[key];
130 29 if (internals.settings.path && path.length > 0) {
131 3 keyLengths.push(internals.settings.pathPrefix);
132 3 out = out + internals.indent() +
133 internals.colorize(internals.settings.pathPrefix, 'path') +
134 internals.tidyPath(path + '.' + key) + '\n';
135 }
136 29 var longest = keyLengths.sort(internals.lengthCompare)[keyLengths.length - 1];
137 29 var keyStr = key.toString();
138 29 out = out + internals.indent() + '' + (internals.printMember(keyStr, longest) + ':') + ' ' + internals.travel(item, path + '.' + keyStr);
139 29 if (i !== il - 1) {
140 11 out = out + ',';
141 }
142 29 out = out + '\n';
143 }
144 18 internals.indentLevel = internals.indentLevel - 1;
145 18 out = out + internals.indent() + '}';
146 18 return out;
147 };
148
149
150 1 internals.showCircular = function (index) {
151 5 var showPath = internals.path[index];
152 5 showPath = showPath === '' ? '' : ' ' + showPath.slice(1, showPath.length);
153 5 return internals.colorize('[Circular~' + showPath + ']', 'Circular');
154 };
155
156
157 1 internals.Array = function (array, path) {
158
159 16 if (array.length === 0) {
160 1 return '[]';
161 }
162
163 15 var index = internals.seen.indexOf(array);
164 15 if (index !== -1) {
165 2 return internals.showCircular(index);
166 }
167 13 internals.seen.push(array);
168 13 internals.path.push(path);
169
170 13 var out = '[\n';
171 13 internals.indentLevel = internals.indentLevel + 1;
172
173 13 for (var i = 0, il = array.length; i < il; ++i) {
174 40 var item = array[i];
175 40 if (internals.settings.path && path.length > 0) {
176 1 out = out + internals.indent() +
177 internals.colorize(internals.settings.pathPrefix, 'path') +
178 internals.tidyPath(path + '.' + i) + '\n';
179 }
180 40 var indexStr = internals.settings.arrayIndex ? '[' + internals.printMember(i, il) + '] ' : '';
181 40 out = out + internals.indent() + '' + indexStr + internals.travel(item, path + '.' + i);
182 40 if (i !== il - 1) {
183 27 out = out + ',';
184 }
185 40 out = out + '\n';
186 }
187 13 internals.indentLevel = internals.indentLevel - 1;
188 13 out = out + internals.indent() + ']';
189 13 return out;
190 };
191
192
193 1 internals.Error = function (err) {
194
195 2 if (Object.keys(err).length === 0) {
196 1 return internals.colorize('[' + err + ']', 'error');
197 }
198 1 var obj = internals.Object(err);
199 1 return obj.replace(/^{/, '{ ' + internals.colorize('[Error: ' + err.message + ']', 'error') );
200 };
201
202
203 1 internals.String = function (str) {
204
205 8 return '\'' + str + '\'';
206 };
207
208
209 1 internals.Boolean = function (bool) {
210
211 2 if (bool === true) {
212 1 return internals.colorize(bool + '', 'BoolTrue');
213 }
214 1 return internals.colorize(bool + '', 'BoolFalse');
215 };
216
217
218 1 internals.Function = function (func) {
219 2 if (func.name) {
220 1 return internals.colorize('[Function: ' + func.name + ']', 'Function');
221 }
222 1 return internals.colorize('[Function: ?]', 'Function');
223 };
224
225
226 1 internals.indent = function () {
227
228 104 return internals.spaces(internals.indentLevel * internals.settings.indent);
229 };
230
231
232 1 internals.spaces = function (count) {
233
234 153 var out = '';
235 153 for (var i = 0; i < count; i++) {
236 580 out = out + ' ';
237 }
238
239 153 return out;
240 };
241
242
243 1 internals.printMember = function (member, max) {
244
245 49 if (internals.settings.align === 'left') {
246 21 max = 0;
247 }
248 49 var memberLength = member.length;
249 49 var maxLength = max.length;
250 49 var toShift = maxLength - memberLength;
251 49 return internals.colorize(internals.spaces(toShift) + member, 'Key');
252 };
253