ID | Title | Duration (ms) |
---|---|---|
1 | Purdy should display an error | 12 |
2 | Purdy should display an error with properties | 4 |
3 | Purdy should display an error with detail | 2 |
4 | Purdy should indent array correctly | 6 |
5 | Purdy allows for removal of array index | 1 |
6 | Purdy honors indent level | 1 |
7 | Purdy prints arguments function | 1 |
8 | Purdy should print plain | 1 |
9 | Purdy should handle circular references | 2 |
10 | Purdy should print a function | 1 |
11 | Purdy should print an anonymous function | 0 |
12 | Purdy should print a string | 1 |
13 | Purdy should print a date | 3 |
14 | Purdy should print a number | 1 |
15 | Purdy should print null | 0 |
16 | Purdy should print undefined | 1 |
17 | Purdy should print a regular expression | 1 |
18 | Purdy should print a false boolean | 1 |
19 | Purdy should print a true boolean | 1 |
20 | Purdy should print an empty array without extra indentation | 0 |
21 | Purdy should print an empty object without extra indentation | 0 |
22 | Purdy should print a more complex object | 4 |
23 | Purdy should not print circular after second use | 2 |
24 | Purdy shows circular reference with path | 1 |
25 | Purdy will keep a path for an object in Hoek format | 5 |
26 | Purdy indents object the way it should | 1 |
27 | Purdy aligns object the way it should | 1 |
28 | Purdy prints directly to console | 4 |
29 | Purdy prints symbols | 2 |
30 | Purdy prints only symbols | 0 |
31 | Purdy obeys depth printing | 1 |
32 | Purdy should handle depth printing for array | 1 |
33 | Purdy should print using zero depth | 1 |
34 | Purdy should handle depth printing for mixed | 2 |
35 | Purdy should handle depth printing using null depth | 1 |
Line | Lint | Hits | Source |
---|---|---|---|
1 | // Load modules | ||
2 | |||
3 | 1 | var Chalk = require('chalk'); | |
4 | 1 | var Hoek = require('hoek'); | |
5 | 1 | var Joi = require('joi'); | |
6 | |||
7 | |||
8 | // declare internals | ||
9 | |||
10 | 1 | var internals = { | |
11 | colors: { | ||
12 | BoolFalse: 'red.bold', | ||
13 | BoolTrue: 'green.bold', | ||
14 | Circular: 'grey.bold', | ||
15 | Date: 'green', | ||
16 | Function: 'cyan', | ||
17 | Key: 'white.bold', | ||
18 | Null: 'red.bold', | ||
19 | Number: 'blue.bold', | ||
20 | RegExp: 'magenta', | ||
21 | String: 'yellow', | ||
22 | Symbol: 'magenta.bold', | ||
23 | Undefined: 'red.inverse', | ||
24 | depth: 'grey', | ||
25 | error: 'red', | ||
26 | path: 'blue' | ||
27 | }, | ||
28 | defaults: { | ||
29 | depth: Joi.number().min(0).allow(null).default(2), | ||
30 | plain: Joi.boolean().default(false), | ||
31 | path: Joi.boolean().default(false), | ||
32 | indent: Joi.number().default(4), | ||
33 | align: Joi.string().valid(['left', 'right']).default('left'), | ||
34 | arrayIndex: Joi.boolean().default(true), | ||
35 | pathPrefix: Joi.string().default('// ') | ||
36 | } | ||
37 | }; | ||
38 | |||
39 | 1 | internals.purdy = function (object, options) { | |
40 | |||
41 | 38 | this.indentLevel = 0; | |
42 | 38 | this.seen = []; | |
43 | 38 | this.path = []; | |
44 | 38 | this.object = object; | |
45 | |||
46 | 38 | this.settings = Joi.attempt(options || {}, internals.defaults); | |
47 | }; | ||
48 | |||
49 | |||
50 | |||
51 | 1 | module.exports = function (object, options) { | |
52 | |||
53 | 1 | var Purdy = new internals.purdy(object, options); | |
54 | 1 | return console.log(Purdy.stringify()); | |
55 | }; | ||
56 | |||
57 | 1 | module.exports.stringify = function (object, options) { | |
58 | |||
59 | 37 | var Purdy = new internals.purdy(object, options); | |
60 | 37 | return Purdy.stringify(); | |
61 | } | ||
62 | |||
63 | |||
64 | 1 | internals.purdy.prototype.stringify = function (object, options) { | |
65 | |||
66 | 38 | return this.travel(this.object, '', 0); | |
67 | }; | ||
68 | |||
69 | |||
70 | 1 | internals.purdy.prototype.travel = function (object, path, depth) { | |
71 | |||
72 | 132 | var type = toString.call(object).split(' ')[1].slice(0, -1); | |
73 | 132 | var format = ''; | |
74 | |||
75 | 132 | if (this[type]) { | |
76 | 76 | format = this[type](object, path, depth); | |
77 | } | ||
78 | else { | ||
79 | 56 | format = String(object); | |
80 | } | ||
81 | |||
82 | 132 | return this.colorize(format, type); | |
83 | }; | ||
84 | |||
85 | |||
86 | 1 | internals.purdy.prototype.colorize = function (string, type) { | |
87 | |||
88 | 226 | if (this.settings.plain) { | |
89 | 130 | return string; | |
90 | } | ||
91 | |||
92 | 96 | var colors = internals.colors[type]; | |
93 | 96 | if (!colors) { | |
94 | 24 | return string; | |
95 | } | ||
96 | |||
97 | 72 | var colorArr = colors.split('.'); | |
98 | |||
99 | 72 | for (var i = 0, il = colorArr.length; i < il; ++i) { | |
100 | 122 | var color = colorArr[i]; | |
101 | 122 | string = Chalk[color](string); | |
102 | } | ||
103 | |||
104 | 72 | return string; | |
105 | }; | ||
106 | |||
107 | |||
108 | 1 | internals.lengthCompare = function (a, b) { | |
109 | |||
110 | 78 | return a.length - b.length; | |
111 | }; | ||
112 | |||
113 | |||
114 | 1 | internals.purdy.prototype.tidyPath = function (path) { | |
115 | |||
116 | 4 | return this.colorize(path.slice(1, path.size), 'path'); | |
117 | }; | ||
118 | |||
119 | 1 | internals.purdy.prototype.Object = internals.purdy.prototype.process = internals.purdy.prototype.global = function (object, path, depth) { | |
120 | |||
121 | 35 | var keys = Object.keys(object); | |
122 | |||
123 | if ( Object.getOwnPropertySymbols ) { |
||
124 | 35 | keys = keys.concat(Object.getOwnPropertySymbols(object)); | |
125 | } | ||
126 | |||
127 | 35 | if (keys.length === 0) { | |
128 | 1 | return '{}'; | |
129 | } | ||
130 | |||
131 | 34 | ++depth; | |
132 | 34 | var index = this.seen.indexOf(object); | |
133 | 34 | if (index !== -1) { | |
134 | 3 | return this.showCircular(index); | |
135 | } | ||
136 | 31 | this.seen.push(object); | |
137 | 31 | this.path.push(path); | |
138 | |||
139 | 31 | var keyLengths = Hoek.clone(keys); | |
140 | 31 | this.indentLevel = this.indentLevel + 1; | |
141 | 31 | var out = '{\n'; | |
142 | |||
143 | 31 | for (var i = 0, il = keys.length; i < il; ++i) { | |
144 | 51 | var key = keys[i]; | |
145 | 51 | var item = object[key]; | |
146 | 51 | if (this.settings.path && path.length > 0) { | |
147 | 3 | keyLengths.push(this.settings.pathPrefix); | |
148 | 3 | out = out + this.indent() + | |
149 | this.colorize(this.settings.pathPrefix, 'path') + | ||
150 | this.tidyPath(path + '.' + key) + '\n'; | ||
151 | } | ||
152 | 51 | var longest = keyLengths.sort(internals.lengthCompare)[keyLengths.length - 1]; | |
153 | 51 | var keyStr = key.toString(); | |
154 | |||
155 | 51 | if (this.settings.depth === null || this.settings.depth + 1 >= depth) { | |
156 | 49 | out = out + this.indent() + '' + (this.printMember(keyStr, longest) + ':') + ' ' + this.travel(item, path + '.' + keyStr, depth); | |
157 | } | ||
158 | else { | ||
159 | 2 | this.indentLevel = this.indentLevel - 1; | |
160 | 2 | return this.colorize('[Object]', 'depth'); | |
161 | } | ||
162 | 49 | if (i !== il - 1) { | |
163 | 20 | out = out + ','; | |
164 | } | ||
165 | 49 | out = out + '\n'; | |
166 | } | ||
167 | 29 | this.indentLevel = this.indentLevel - 1; | |
168 | 29 | out = out + this.indent() + '}'; | |
169 | 29 | return out; | |
170 | }; | ||
171 | |||
172 | |||
173 | 1 | internals.purdy.prototype.showCircular = function (index) { | |
174 | |||
175 | 5 | var showPath = this.path[index]; | |
176 | 5 | showPath = showPath === '' ? '' : ' ' + showPath.slice(1, showPath.length); | |
177 | 5 | return this.colorize('[Circular~' + showPath + ']', 'Circular'); | |
178 | }; | ||
179 | |||
180 | |||
181 | 1 | internals.purdy.prototype.Array = function (array, path, depth) { | |
182 | |||
183 | 23 | if (array.length === 0) { | |
184 | 1 | return '[]'; | |
185 | } | ||
186 | |||
187 | 22 | ++depth; | |
188 | 22 | var index = this.seen.indexOf(array); | |
189 | 22 | if (index !== -1) { | |
190 | 2 | return this.showCircular(index); | |
191 | } | ||
192 | 20 | this.seen.push(array); | |
193 | 20 | this.path.push(path); | |
194 | |||
195 | 20 | var out = '[\n'; | |
196 | 20 | this.indentLevel = this.indentLevel + 1; | |
197 | |||
198 | 20 | for (var i = 0, il = array.length; i < il; ++i) { | |
199 | 48 | var item = array[i]; | |
200 | 48 | if (this.settings.path && path.length > 0) { | |
201 | 1 | out = out + this.indent() + | |
202 | this.colorize(this.settings.pathPrefix, 'path') + | ||
203 | this.tidyPath(path + '.' + i) + '\n'; | ||
204 | } | ||
205 | 48 | var indexStr = this.settings.arrayIndex ? '[' + this.printMember(i, il) + '] ' : ''; | |
206 | 48 | if (this.settings.depth === null || this.settings.depth + 1 >= depth) { | |
207 | 45 | out = out + this.indent() + '' + indexStr + this.travel(item, path + '.' + i, depth); | |
208 | } | ||
209 | else { | ||
210 | 3 | this.indentLevel = this.indentLevel - 1; | |
211 | 3 | return this.colorize('[Object]', 'depth'); | |
212 | } | ||
213 | 45 | if (i !== il - 1) { | |
214 | 28 | out = out + ','; | |
215 | } | ||
216 | 45 | out = out + '\n'; | |
217 | } | ||
218 | 17 | this.indentLevel = this.indentLevel - 1; | |
219 | 17 | out = out + this.indent() + ']'; | |
220 | 17 | return out; | |
221 | }; | ||
222 | |||
223 | |||
224 | 1 | internals.purdy.prototype.Error = function (err) { | |
225 | |||
226 | 3 | if (Object.keys(err).length === 0) { | |
227 | 1 | return this.colorize('[' + err + ']', 'error'); | |
228 | } | ||
229 | 2 | var obj = this.Object(err, '', null); | |
230 | 2 | return obj.replace(/^{/, '{ ' + this.colorize('[Error: ' + err.message + ']', 'error') ); | |
231 | }; | ||
232 | |||
233 | |||
234 | 1 | internals.purdy.prototype.String = function (str) { | |
235 | |||
236 | 13 | return '\'' + str + '\''; | |
237 | }; | ||
238 | |||
239 | 1 | internals.purdy.prototype.Arguments = function (obj) { | |
240 | |||
241 | 1 | var arr = Array.prototype.slice.call(obj); | |
242 | 1 | return this.Array(arr); | |
243 | }; | ||
244 | |||
245 | |||
246 | 1 | internals.purdy.prototype.Boolean = function (bool) { | |
247 | |||
248 | 2 | if (bool === true) { | |
249 | 1 | return this.colorize(bool + '', 'BoolTrue'); | |
250 | } | ||
251 | 1 | return this.colorize(bool + '', 'BoolFalse'); | |
252 | }; | ||
253 | |||
254 | |||
255 | 1 | internals.purdy.prototype.Function = function (func) { | |
256 | |||
257 | 2 | if (func.name) { | |
258 | 1 | return this.colorize('[Function: ' + func.name + ']', 'Function'); | |
259 | } | ||
260 | 1 | return this.colorize('[Function: ?]', 'Function'); | |
261 | }; | ||
262 | |||
263 | |||
264 | 1 | internals.purdy.prototype.indent = function () { | |
265 | |||
266 | 144 | return internals.spaces(this.indentLevel * this.settings.indent); | |
267 | }; | ||
268 | |||
269 | |||
270 | 1 | internals.spaces = function (count) { | |
271 | |||
272 | 213 | var out = ''; | |
273 | 213 | for (var i = 0; i < count; i++) { | |
274 | 769 | out = out + ' '; | |
275 | } | ||
276 | |||
277 | 213 | return out; | |
278 | }; | ||
279 | |||
280 | |||
281 | 1 | internals.purdy.prototype.printMember = function (member, max) { | |
282 | |||
283 | 69 | if (this.settings.align === 'left') { | |
284 | 41 | max = 0; | |
285 | } | ||
286 | 69 | var memberLength = member.length; | |
287 | 69 | var maxLength = max.length; | |
288 | 69 | var toShift = maxLength - memberLength; | |
289 | 69 | return this.colorize(internals.spaces(toShift) + member, 'Key'); | |
290 | }; | ||
291 |