Test Report

0
0
29
60
ID Title Duration (ms)
1 Purdy should display an error 9
2 Purdy should display an error with detail 4
3 Purdy should indent array correctly 6
4 Purdy allows for removal of array index 1
5 Purdy honors indent level 1
6 Purdy prints arguments function 0
7 Purdy should print plain 1
8 Purdy should handle circular references 1
9 Purdy should print a function 0
10 Purdy should print an anonymous function 1
11 Purdy should print a string 0
12 Purdy should print a date 2
13 Purdy should print a number 1
14 Purdy should print null 0
15 Purdy should print undefined 1
16 Purdy should print a regular expression 1
17 Purdy should print a false boolean 0
18 Purdy should print a true boolean 1
19 Purdy should print an empty array without extra indentation 1
20 Purdy should print an empty object without extra indentation 0
21 Purdy should print a more complex object 4
22 Purdy should not print circular after second use 1
23 Purdy shows circular reference with path 2
24 Purdy will keep a path for an object in Hoek format 5
25 Purdy indents object the way it should 1
26 Purdy aligns object the way it should 2
27 Purdy prints directly to console 4
28 Purdy prints symbols 1
29 Purdy prints only symbols 0

Code Coverage Report

99.48%
191
190
1

lib/index.js

99.48%
191
190
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 32 internals.seen = [];
46 32 internals.path = [];
47 32 internals.settings = Hoek.applyToDefaults(internals.defaults, options || {});
48 32 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 106 var type = global.toString.call(object).split(' ')[1].slice(0, -1);
61 106 var format = '';
62
63 106 if (internals[type]) {
64 58 format = internals[type](object, path);
65 }
66 else {
67 48 format = String(object);
68 }
69
70 106 return internals.colorize(format, type);
71 };
72
73
74 1 internals.colorize = function (string, type) {
75
76 177 if (internals.settings.plain) {
77 85 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
98 57 return a.length - b.length;
99 };
100
101
102 1 internals.tidyPath = function (path) {
103
104 4 return internals.colorize(path.slice(1, path.size), 'path');
105 };
106
107 1 internals.Object = function (object, path) {
108
109 24 var keys = Object.keys(object);
110
111
if (
Object.getOwnPropertySymbols
) {
112 24 keys = keys.concat(Object.getOwnPropertySymbols(object));
113 }
114
115 24 if (keys.length === 0) {
116 1 return '{}';
117 }
118
119 23 var index = internals.seen.indexOf(object);
120 23 if (index !== -1) {
121 3 return internals.showCircular(index);
122 }
123 20 internals.seen.push(object);
124 20 internals.path.push(path);
125
126 20 var keyLengths = Hoek.clone(keys);
127 20 internals.indentLevel = internals.indentLevel + 1;
128 20 var out = '{\n';
129
130 20 for (var i = 0, il = keys.length; i < il; ++i) {
131 32 var key = keys[i];
132 32 var item = object[key];
133 32 if (internals.settings.path && path.length > 0) {
134 3 keyLengths.push(internals.settings.pathPrefix);
135 3 out = out + internals.indent() +
136 internals.colorize(internals.settings.pathPrefix, 'path') +
137 internals.tidyPath(path + '.' + key) + '\n';
138 }
139 32 var longest = keyLengths.sort(internals.lengthCompare)[keyLengths.length - 1];
140 32 var keyStr = key.toString();
141 32 out = out + internals.indent() + '' + (internals.printMember(keyStr, longest) + ':') + ' ' + internals.travel(item, path + '.' + keyStr);
142 32 if (i !== il - 1) {
143 12 out = out + ',';
144 }
145 32 out = out + '\n';
146 }
147 20 internals.indentLevel = internals.indentLevel - 1;
148 20 out = out + internals.indent() + '}';
149 20 return out;
150 };
151
152
153 1 internals.showCircular = function (index) {
154
155 5 var showPath = internals.path[index];
156 5 showPath = showPath === '' ? '' : ' ' + showPath.slice(1, showPath.length);
157 5 return internals.colorize('[Circular~' + showPath + ']', 'Circular');
158 };
159
160
161 1 internals.Array = function (array, path) {
162
163 17 if (array.length === 0) {
164 1 return '[]';
165 }
166
167 16 var index = internals.seen.indexOf(array);
168 16 if (index !== -1) {
169 2 return internals.showCircular(index);
170 }
171 14 internals.seen.push(array);
172 14 internals.path.push(path);
173
174 14 var out = '[\n';
175 14 internals.indentLevel = internals.indentLevel + 1;
176
177 14 for (var i = 0, il = array.length; i < il; ++i) {
178 42 var item = array[i];
179 42 if (internals.settings.path && path.length > 0) {
180 1 out = out + internals.indent() +
181 internals.colorize(internals.settings.pathPrefix, 'path') +
182 internals.tidyPath(path + '.' + i) + '\n';
183 }
184 42 var indexStr = internals.settings.arrayIndex ? '[' + internals.printMember(i, il) + '] ' : '';
185 42 out = out + internals.indent() + '' + indexStr + internals.travel(item, path + '.' + i);
186 42 if (i !== il - 1) {
187 28 out = out + ',';
188 }
189 42 out = out + '\n';
190 }
191 14 internals.indentLevel = internals.indentLevel - 1;
192 14 out = out + internals.indent() + ']';
193 14 return out;
194 };
195
196
197 1 internals.Error = function (err) {
198
199 2 if (Object.keys(err).length === 0) {
200 1 return internals.colorize('[' + err + ']', 'error');
201 }
202 1 var obj = internals.Object(err);
203 1 return obj.replace(/^{/, '{ ' + internals.colorize('[Error: ' + err.message + ']', 'error') );
204 };
205
206
207 1 internals.String = function (str) {
208
209 12 return '\'' + str + '\'';
210 };
211
212 1 internals.Arguments = function (obj) {
213
214 1 var arr = Array.prototype.slice.call(obj);
215 1 return internals.Array(arr);
216 };
217
218
219 1 internals.Boolean = function (bool) {
220
221 2 if (bool === true) {
222 1 return internals.colorize(bool + '', 'BoolTrue');
223 }
224 1 return internals.colorize(bool + '', 'BoolFalse');
225 };
226
227
228 1 internals.Function = function (func) {
229
230 2 if (func.name) {
231 1 return internals.colorize('[Function: ' + func.name + ']', 'Function');
232 }
233 1 return internals.colorize('[Function: ?]', 'Function');
234 };
235
236
237 1 internals.indent = function () {
238
239 112 return internals.spaces(internals.indentLevel * internals.settings.indent);
240 };
241
242
243 1 internals.spaces = function (count) {
244
245 164 var out = '';
246 164 for (var i = 0; i < count; i++) {
247 596 out = out + ' ';
248 }
249
250 164 return out;
251 };
252
253
254 1 internals.printMember = function (member, max) {
255
256 52 if (internals.settings.align === 'left') {
257 24 max = 0;
258 }
259 52 var memberLength = member.length;
260 52 var maxLength = max.length;
261 52 var toShift = maxLength - memberLength;
262 52 return internals.colorize(internals.spaces(toShift) + member, 'Key');
263 };
264