| var treeify = require('../treeify'), |
| vows = require('vows'), |
| assert = require('assert'), |
| events = require('events'); |
| |
| // - helper functions ----------------- |
| |
| function treeifyByLineGuts(args) { |
| var emitter = new events.EventEmitter(), |
| lineNum = 0; |
| args.push(function(line) { |
| emitter.emit('success', line); |
| emitter.emit('line ' + (++lineNum), line); |
| }); |
| treeify.asLines.apply(this, args); |
| return emitter; |
| } |
| |
| function treeifyByLine(obj) { |
| return function(showValues) { |
| var arguments = [ obj, showValues ]; |
| return treeifyByLineGuts(arguments); |
| }; |
| } |
| |
| function treeifyByLineWithHideFunctionsArgument(obj) { |
| return function(showValues, hideFunctions) { |
| var arguments = [ obj, showValues, hideFunctions ]; |
| return treeifyByLineGuts(arguments); |
| }; |
| } |
| |
| function treeifyEntirely(obj) { |
| return function(showValues, hideFunctions) { |
| return treeify.asTree(obj, showValues, hideFunctions); |
| }; |
| } |
| |
| function withValuesShown(showValues) { |
| return function(func){ return func(showValues, false) }; |
| } |
| |
| function withValuesShownFunctionsHidden() { |
| return function(func){ return func(true, true) }; |
| |
| } |
| |
| function is(content, arrayIndex) { |
| return function(lines) { |
| var toCheck = lines; |
| if (arrayIndex !== undefined) { |
| toCheck = lines[arrayIndex]; |
| } |
| assert.strictEqual(toCheck, content, 'should be "' + content + '" but was "' + toCheck + '"'); |
| }; |
| } |
| |
| function checkLines(/* ... */) { |
| var ret = {}, entry; |
| for (var line = 1; line <= arguments.length; line++) { |
| if ( ! arguments[line - 1]) |
| continue; |
| entry = {}; |
| entry['branches correctly on line '+line] = is(arguments[line - 1]); |
| ret['line '+line] = entry; |
| } |
| return ret; |
| } |
| |
| // - the beautiful test suite --------- |
| |
| vows.describe('tree-test').addBatch({ |
| |
| 'A tree created from an empty object': { |
| topic: {}, |
| |
| 'when returned as a whole tree': { |
| topic: treeifyEntirely, |
| |
| 'with values hidden': { |
| topic: withValuesShown(false), |
| 'is an empty string': is('') |
| }, |
| 'with values shown': { |
| topic: withValuesShown(true), |
| 'is an empty string': is('') |
| } |
| } |
| }, |
| |
| 'A tree created from a single-level object': { |
| topic: { |
| apples: 'gala', // ├─ apples: gala |
| oranges: 'mandarin' // └─ oranges: mandarin |
| }, |
| |
| 'when returned line-by-line': { |
| topic: treeifyByLine, |
| |
| 'with values hidden': { |
| topic: withValuesShown(false), |
| |
| 'is two lines long': function(err, line) { |
| this.expect(2); |
| }, |
| on: checkLines('├─ apples', |
| '└─ oranges') |
| }, |
| 'with values shown': { |
| topic: withValuesShown(true), |
| |
| 'is two lines long': function(err, line) { |
| this.expect(2); |
| }, |
| on: checkLines('├─ apples: gala', |
| '└─ oranges: mandarin') |
| } |
| }, |
| |
| 'when returned as a whole tree': { |
| topic: treeifyEntirely, |
| |
| 'with values hidden': { |
| topic: withValuesShown(false), |
| |
| 'is not empty': function(tree) { |
| assert.notEqual(tree, '', 'should not be empty'); |
| }, |
| 'contains 2 line breaks': function(tree) { |
| assert.strictEqual(tree.match(/\n/g).length, 2, 'should contain 2 x \n'); |
| }, |
| '(split into an array of lines)': { |
| topic: function(tree) { return tree.split(/\n/g) }, |
| 'has a correct first line': is('├─ apples', 0), |
| 'has a correct second line': is('└─ oranges', 1), |
| 'has nothing at the end': is('', 2) |
| } |
| }, |
| 'with values shown': { |
| topic: withValuesShown(true), |
| |
| 'is not empty': function(tree) { |
| assert.notEqual(tree, '', 'should not be empty'); |
| }, |
| 'contains 2 line breaks': function(tree) { |
| assert.strictEqual(tree.match(/\n/g).length, 2, 'should contain 2 x \n'); |
| }, |
| '(split into an array of lines)': { |
| topic: function(tree) { return tree.split(/\n/g) }, |
| 'has a correct first line': is('├─ apples: gala', 0), |
| 'has a correct second line': is('└─ oranges: mandarin', 1), |
| 'has nothing at the end': is('', 2) |
| } |
| } |
| } |
| }, |
| |
| 'A tree created from a multi-level object': { |
| topic: { |
| oranges: { // ├─ oranges |
| 'mandarin': { // │ └─ mandarin |
| clementine: null, // │ ├─ clementine |
| tangerine: // │ └─ tangerine |
| 'so cheap and juicy!' |
| } |
| }, |
| apples: { // └─ apples |
| 'gala': null, // ├─ gala |
| 'pink lady': null // └─ pink lady |
| } |
| }, |
| |
| 'when returned line-by-line': { |
| topic: treeifyByLine, |
| |
| 'with values hidden': { |
| topic: withValuesShown(false), |
| |
| 'is seven lines long': function(err, line) { |
| this.expect(7); |
| }, |
| on: checkLines('├─ oranges', |
| '│ └─ mandarin', |
| '│ ├─ clementine', |
| '│ └─ tangerine', |
| '└─ apples', |
| ' ├─ gala', |
| ' └─ pink lady') |
| }, |
| 'with values shown': { |
| topic: withValuesShown(true), |
| on: checkLines(null, null, null, |
| '│ └─ tangerine: so cheap and juicy!') |
| } |
| }, |
| |
| 'when returned as a whole tree': { |
| topic: treeifyEntirely, |
| |
| 'with values shown': { |
| topic: withValuesShown(true), |
| |
| '(split into an array of lines)': { |
| topic: function(tree) { return tree.split(/\n/g) }, |
| 'has a correct first line': is('├─ oranges', 0), |
| 'has a correct third line': is('│ └─ tangerine: so cheap and juicy!', 3), |
| 'has nothing at the end': is('', 7) |
| } |
| } |
| } |
| }, |
| |
| 'A tree created from an object with not so circular references': { |
| topic: function() { |
| var obj = { one: 'one', two: { four: 'four' } }; |
| obj['three'] = obj.two; |
| return obj; |
| }, |
| |
| 'when returned line-by-line': { |
| topic: treeifyByLine, |
| |
| 'with values shown': { |
| topic: withValuesShown(true), |
| on: checkLines('├─ one: one', |
| '├─ two', |
| '│ └─ four: four', |
| '└─ three', |
| ' └─ four: four') |
| } |
| } |
| }, |
| |
| 'A tree created from an object with circular references': { |
| topic: function() { |
| var obj = { one: 'one', two: 'two' }; |
| obj['three'] = obj; |
| return obj; |
| }, |
| |
| 'when returned line-by-line': { |
| topic: treeifyByLine, |
| |
| 'with values shown': { |
| topic: withValuesShown(true), |
| on: checkLines('├─ one: one', |
| '├─ two: two', |
| '└─ three (circular ref.)') |
| } |
| } |
| }, |
| |
| 'A tree created from an object containing various types': { |
| topic: { |
| array: [ 'one', 'two' ], |
| numeric: 42, |
| decimal: 42.24, |
| bool: false, |
| nil: null, |
| undef: undefined, |
| date: new Date(2018,0,1) |
| }, |
| |
| 'when returned line-by-line': { |
| topic: treeifyByLine, |
| |
| 'with values shown': { |
| topic: withValuesShown(true), |
| on: checkLines('├─ array', |
| '│ ├─ 0: one', |
| '│ └─ 1: two', |
| '├─ numeric: 42', |
| '├─ decimal: 42.24', |
| '├─ bool: false', |
| '├─ nil', |
| '├─ undef: undefined', |
| '└─ date: Mon Jan 01 2018 00:00:00 GMT+0000 (UTC)') |
| } |
| } |
| }, |
| |
| 'A tree created from an object with prototyped functions': { |
| topic: function() { |
| var func = function(){ |
| this.Friendly = 'stuff'; |
| } |
| func.prototype.Nasty = function(){} |
| return new func(); |
| }, |
| |
| 'when returned as a whole tree': { |
| topic: treeifyEntirely, |
| |
| 'with values shown': { |
| topic: withValuesShown(true), |
| |
| 'and split into an array of lines': { |
| topic: function(tree) { return tree.split(/\n/g) }, |
| 'is a one liner output (with a following blank line)': function(lines) { |
| assert.equal(lines.length, 2); |
| }, |
| 'has a correct first line': is('└─ Friendly: stuff', 0) |
| } |
| } |
| } |
| }, |
| 'A tree with functions': { |
| topic: { |
| func:function(){}, |
| Friendly:"stuff", |
| Another:"stuff" |
| }, |
| |
| 'when returned line-by-line': { |
| topic: treeifyByLineWithHideFunctionsArgument, |
| |
| 'with values shown, but functions hidden': { |
| topic: withValuesShownFunctionsHidden(), |
| |
| 'is two lines long': function(err, line) { |
| this.expect(2); |
| }, |
| on: checkLines('├─ Friendly: stuff', |
| '└─ Another: stuff') |
| } |
| }, |
| |
| 'when returned as a whole tree': { |
| topic: treeifyEntirely, |
| |
| 'with values shown, but functions hidden': { |
| topic: withValuesShownFunctionsHidden(), |
| |
| 'and split into an array of lines': { |
| topic: function(tree) { |
| console.error(tree); |
| return tree.split(/\n/g) }, |
| 'is a one liner output (with a following blank line)': function(lines) { |
| assert.equal(lines.length, 3); |
| }, |
| 'has a correct first line': is('├─ Friendly: stuff', 0) |
| } |
| } |
| } |
| } |
| |
| }).export(module); |