blob: c5841e96f78ff7d78c18fa94f588a6d288da7abb [file] [log] [blame]
Paul Lewis911c1b82019-12-02 12:46:15 +00001var treeify = require('../treeify'),
2 vows = require('vows'),
3 assert = require('assert'),
4 events = require('events');
5
6// - helper functions -----------------
7
8function treeifyByLineGuts(args) {
9 var emitter = new events.EventEmitter(),
10 lineNum = 0;
11 args.push(function(line) {
12 emitter.emit('success', line);
13 emitter.emit('line ' + (++lineNum), line);
14 });
15 treeify.asLines.apply(this, args);
16 return emitter;
17}
18
19function treeifyByLine(obj) {
20 return function(showValues) {
21 var arguments = [ obj, showValues ];
22 return treeifyByLineGuts(arguments);
23 };
24}
25
26function treeifyByLineWithHideFunctionsArgument(obj) {
27 return function(showValues, hideFunctions) {
28 var arguments = [ obj, showValues, hideFunctions ];
29 return treeifyByLineGuts(arguments);
30 };
31}
32
33function treeifyEntirely(obj) {
34 return function(showValues, hideFunctions) {
35 return treeify.asTree(obj, showValues, hideFunctions);
36 };
37}
38
39function withValuesShown(showValues) {
40 return function(func){ return func(showValues, false) };
41}
42
43function withValuesShownFunctionsHidden() {
44 return function(func){ return func(true, true) };
45
46}
47
48function is(content, arrayIndex) {
49 return function(lines) {
50 var toCheck = lines;
51 if (arrayIndex !== undefined) {
52 toCheck = lines[arrayIndex];
53 }
54 assert.strictEqual(toCheck, content, 'should be "' + content + '" but was "' + toCheck + '"');
55 };
56}
57
58function checkLines(/* ... */) {
59 var ret = {}, entry;
60 for (var line = 1; line <= arguments.length; line++) {
61 if ( ! arguments[line - 1])
62 continue;
63 entry = {};
64 entry['branches correctly on line '+line] = is(arguments[line - 1]);
65 ret['line '+line] = entry;
66 }
67 return ret;
68}
69
70// - the beautiful test suite ---------
71
72vows.describe('tree-test').addBatch({
73
74 'A tree created from an empty object': {
75 topic: {},
76
77 'when returned as a whole tree': {
78 topic: treeifyEntirely,
79
80 'with values hidden': {
81 topic: withValuesShown(false),
82 'is an empty string': is('')
83 },
84 'with values shown': {
85 topic: withValuesShown(true),
86 'is an empty string': is('')
87 }
88 }
89 },
90
91 'A tree created from a single-level object': {
92 topic: {
93 apples: 'gala', // ├─ apples: gala
94 oranges: 'mandarin' // └─ oranges: mandarin
95 },
96
97 'when returned line-by-line': {
98 topic: treeifyByLine,
99
100 'with values hidden': {
101 topic: withValuesShown(false),
102
103 'is two lines long': function(err, line) {
104 this.expect(2);
105 },
106 on: checkLines('├─ apples',
107 '└─ oranges')
108 },
109 'with values shown': {
110 topic: withValuesShown(true),
111
112 'is two lines long': function(err, line) {
113 this.expect(2);
114 },
115 on: checkLines('├─ apples: gala',
116 '└─ oranges: mandarin')
117 }
118 },
119
120 'when returned as a whole tree': {
121 topic: treeifyEntirely,
122
123 'with values hidden': {
124 topic: withValuesShown(false),
125
126 'is not empty': function(tree) {
127 assert.notEqual(tree, '', 'should not be empty');
128 },
129 'contains 2 line breaks': function(tree) {
130 assert.strictEqual(tree.match(/\n/g).length, 2, 'should contain 2 x \n');
131 },
132 '(split into an array of lines)': {
133 topic: function(tree) { return tree.split(/\n/g) },
134 'has a correct first line': is('├─ apples', 0),
135 'has a correct second line': is('└─ oranges', 1),
136 'has nothing at the end': is('', 2)
137 }
138 },
139 'with values shown': {
140 topic: withValuesShown(true),
141
142 'is not empty': function(tree) {
143 assert.notEqual(tree, '', 'should not be empty');
144 },
145 'contains 2 line breaks': function(tree) {
146 assert.strictEqual(tree.match(/\n/g).length, 2, 'should contain 2 x \n');
147 },
148 '(split into an array of lines)': {
149 topic: function(tree) { return tree.split(/\n/g) },
150 'has a correct first line': is('├─ apples: gala', 0),
151 'has a correct second line': is('└─ oranges: mandarin', 1),
152 'has nothing at the end': is('', 2)
153 }
154 }
155 }
156 },
157
158 'A tree created from a multi-level object': {
159 topic: {
160 oranges: { // ├─ oranges
161 'mandarin': { // │ └─ mandarin
162 clementine: null, // │ ├─ clementine
163 tangerine: // │ └─ tangerine
164 'so cheap and juicy!'
165 }
166 },
167 apples: { // └─ apples
168 'gala': null, // ├─ gala
169 'pink lady': null // └─ pink lady
170 }
171 },
172
173 'when returned line-by-line': {
174 topic: treeifyByLine,
175
176 'with values hidden': {
177 topic: withValuesShown(false),
178
179 'is seven lines long': function(err, line) {
180 this.expect(7);
181 },
182 on: checkLines('├─ oranges',
183 '│ └─ mandarin',
184 '│ ├─ clementine',
185 '│ └─ tangerine',
186 '└─ apples',
187 ' ├─ gala',
188 ' └─ pink lady')
189 },
190 'with values shown': {
191 topic: withValuesShown(true),
192 on: checkLines(null, null, null,
193 '│ └─ tangerine: so cheap and juicy!')
194 }
195 },
196
197 'when returned as a whole tree': {
198 topic: treeifyEntirely,
199
200 'with values shown': {
201 topic: withValuesShown(true),
202
203 '(split into an array of lines)': {
204 topic: function(tree) { return tree.split(/\n/g) },
205 'has a correct first line': is('├─ oranges', 0),
206 'has a correct third line': is('│ └─ tangerine: so cheap and juicy!', 3),
207 'has nothing at the end': is('', 7)
208 }
209 }
210 }
211 },
212
213 'A tree created from an object with not so circular references': {
214 topic: function() {
215 var obj = { one: 'one', two: { four: 'four' } };
216 obj['three'] = obj.two;
217 return obj;
218 },
219
220 'when returned line-by-line': {
221 topic: treeifyByLine,
222
223 'with values shown': {
224 topic: withValuesShown(true),
225 on: checkLines('├─ one: one',
226 '├─ two',
227 '│ └─ four: four',
228 '└─ three',
229 ' └─ four: four')
230 }
231 }
232 },
233
234 'A tree created from an object with circular references': {
235 topic: function() {
236 var obj = { one: 'one', two: 'two' };
237 obj['three'] = obj;
238 return obj;
239 },
240
241 'when returned line-by-line': {
242 topic: treeifyByLine,
243
244 'with values shown': {
245 topic: withValuesShown(true),
246 on: checkLines('├─ one: one',
247 '├─ two: two',
248 '└─ three (circular ref.)')
249 }
250 }
251 },
252
253 'A tree created from an object containing various types': {
254 topic: {
255 array: [ 'one', 'two' ],
256 numeric: 42,
257 decimal: 42.24,
258 bool: false,
259 nil: null,
260 undef: undefined,
261 date: new Date(2018,0,1)
262 },
263
264 'when returned line-by-line': {
265 topic: treeifyByLine,
266
267 'with values shown': {
268 topic: withValuesShown(true),
269 on: checkLines('├─ array',
270 '│ ├─ 0: one',
271 '│ └─ 1: two',
272 '├─ numeric: 42',
273 '├─ decimal: 42.24',
274 '├─ bool: false',
275 '├─ nil',
276 '├─ undef: undefined',
277 '└─ date: Mon Jan 01 2018 00:00:00 GMT+0000 (UTC)')
278 }
279 }
280 },
281
282 'A tree created from an object with prototyped functions': {
283 topic: function() {
284 var func = function(){
285 this.Friendly = 'stuff';
286 }
287 func.prototype.Nasty = function(){}
288 return new func();
289 },
290
291 'when returned as a whole tree': {
292 topic: treeifyEntirely,
293
294 'with values shown': {
295 topic: withValuesShown(true),
296
297 'and split into an array of lines': {
298 topic: function(tree) { return tree.split(/\n/g) },
299 'is a one liner output (with a following blank line)': function(lines) {
300 assert.equal(lines.length, 2);
301 },
302 'has a correct first line': is('└─ Friendly: stuff', 0)
303 }
304 }
305 }
306 },
307 'A tree with functions': {
308 topic: {
309 func:function(){},
310 Friendly:"stuff",
311 Another:"stuff"
312 },
313
314 'when returned line-by-line': {
315 topic: treeifyByLineWithHideFunctionsArgument,
316
317 'with values shown, but functions hidden': {
318 topic: withValuesShownFunctionsHidden(),
319
320 'is two lines long': function(err, line) {
321 this.expect(2);
322 },
323 on: checkLines('├─ Friendly: stuff',
324 '└─ Another: stuff')
325 }
326 },
327
328 'when returned as a whole tree': {
329 topic: treeifyEntirely,
330
331 'with values shown, but functions hidden': {
332 topic: withValuesShownFunctionsHidden(),
333
334 'and split into an array of lines': {
335 topic: function(tree) {
336 console.error(tree);
337 return tree.split(/\n/g) },
338 'is a one liner output (with a following blank line)': function(lines) {
339 assert.equal(lines.length, 3);
340 },
341 'has a correct first line': is('├─ Friendly: stuff', 0)
342 }
343 }
344 }
345 }
346
347}).export(module);