From 3543c0ef5921d0645cb072bafaf4853dcc33ef0e Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Wed, 3 Aug 2011 15:45:16 +0700 Subject: [PATCH 01/28] [isolate] added command line option --- bin/vows | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bin/vows b/bin/vows index 15ccf13..222a86f 100755 --- a/bin/vows +++ b/bin/vows @@ -49,6 +49,7 @@ var help = [ " -v, --verbose Enable verbose output", " -w, --watch Watch mode", " -s, --silent Don't report", + " -i, --isolate Run each test in it's own vows process", " -m PATTERN Only run tests matching the PATTERN string", " -r PATTERN Only run tests matching the PATTERN regexp", " --json Use JSON reporter", @@ -66,7 +67,8 @@ var options = { reporter: reporter, matcher: /.*/, watch: false, - coverage: false + coverage: false, + isolate: false }; var files = []; @@ -134,6 +136,10 @@ while (arg = argv.shift()) { case 'w': options.watch = true; break; + case 'isolate': + case 'i': + options.isolate = true; + break; case 'no-color': options.nocolor = true; break; From b275024a3e385ad90c1475bbab351cea97a6fcd0 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Wed, 3 Aug 2011 17:09:45 +0700 Subject: [PATCH 02/28] [isolate] implement runner --- bin/vows | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/bin/vows b/bin/vows index 222a86f..cddcc15 100755 --- a/bin/vows +++ b/bin/vows @@ -384,7 +384,36 @@ function runSuites(suites, callback) { function importSuites(files) { msg(options.watcher ? 'watcher' : 'runner', 'loading', files); - return files.reduce(function (suites, f) { + var exec = require('child_process').exec; + + function wrapExec(f) { + return function(options, callback) { + var cmd = process.argv.slice(0, 2).concat('--json'); + + exec(cmd.join(' '), function (err, stdout, stderr) { + if (err) { + reporter.report(['error', stderr]); + callback({ + errored: 1, + total: 1 + }); + return; + } + + var result = stdout.split(/\n/g).map(function(i) { + if (i) { + reporter.report(JSON.parse(i)); + } + }); + }) + } + } + + return files.reduce(options.isolate ? function (suites, f) { + return suites.concat({ + run: wrapExec(f) + }); + } : function (suites, f) { var obj = require(f); return suites.concat(Object.keys(obj).map(function (s) { obj[s]._filename = f.replace(process.cwd() + '/', '') + '.js'; From c2a1d6013537bdbe1f71a1e1116f9a86e835d2c0 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Wed, 3 Aug 2011 17:13:16 +0700 Subject: [PATCH 03/28] [isolate] collect results --- bin/vows | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/bin/vows b/bin/vows index cddcc15..92855a8 100755 --- a/bin/vows +++ b/bin/vows @@ -400,9 +400,17 @@ function importSuites(files) { return; } - var result = stdout.split(/\n/g).map(function(i) { + stdout = stdout.split(/\n/g); + + var result = stdout.pop(); + stdout.map(function(i) { if (i) { - reporter.report(JSON.parse(i)); + i = JSON.parse(i); + if (i && i[0] === 'finish') { + callback(i[1]); + } else { + reporter.report(i); + } } }); }) From d53c429abc28650b6747a25f45f4c69bb7139655 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Wed, 3 Aug 2011 18:01:16 +0700 Subject: [PATCH 04/28] [isolate] exec => spawn, stream suite output, fix command line arguments to child process --- bin/vows | 69 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/bin/vows b/bin/vows index 92855a8..e259cc2 100755 --- a/bin/vows +++ b/bin/vows @@ -384,47 +384,62 @@ function runSuites(suites, callback) { function importSuites(files) { msg(options.watcher ? 'watcher' : 'runner', 'loading', files); - var exec = require('child_process').exec; + var spawn = require('child_process').spawn; - function wrapExec(f) { + function cwdname(f) { + return f.replace(process.cwd() + '/', '') + '.js'; + } + + function wrapSpawn(f) { + f = cwdname(f); return function(options, callback) { - var cmd = process.argv.slice(0, 2).concat('--json'); - - exec(cmd.join(' '), function (err, stdout, stderr) { - if (err) { - reporter.report(['error', stderr]); - callback({ - errored: 1, - total: 1 + var args = [process.argv[1], '--json', f], + p = spawn(process.argv[0], args), + result; + + p.on('exit', function(code) { + callback( + (code != 0 || !result) ? + {errored: 1, total: 1} + : + result + ); + }); + + var buffer = []; + p.stdout.on('data', function(data) { + data = data.toString().split(/\n/g); + if (data.length == 1) { + buffer.push(data[0]); + } else { + data[0] = buffer.concat(data[0]).join(''); + buffer = [data.pop()]; + + data.forEach(function(data) { + if (data) { + data = JSON.parse(data); + if (data && data[0] === 'finish') { + result = data[1]; + } else { + reporter.report(data); + } + } }); - return; } + }); - stdout = stdout.split(/\n/g); - - var result = stdout.pop(); - stdout.map(function(i) { - if (i) { - i = JSON.parse(i); - if (i && i[0] === 'finish') { - callback(i[1]); - } else { - reporter.report(i); - } - } - }); - }) + p.stderr.pipe(process.stderr); } } return files.reduce(options.isolate ? function (suites, f) { return suites.concat({ - run: wrapExec(f) + run: wrapSpawn(f) }); } : function (suites, f) { var obj = require(f); return suites.concat(Object.keys(obj).map(function (s) { - obj[s]._filename = f.replace(process.cwd() + '/', '') + '.js'; + obj[s]._filename = cwdname(f); return obj[s]; })); }, []) From 26fc3f776658c8e870489f36ce02c9469ee463e2 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Wed, 3 Aug 2011 20:30:19 +0700 Subject: [PATCH 05/28] [isolate] supress-stdout option and true stream usage in reporters --- bin/vows | 22 +++++++++++++++----- lib/vows/console.js | 2 ++ lib/vows/reporters/dot-matrix.js | 35 ++++++++++++++++---------------- lib/vows/reporters/json.js | 10 +++++++-- lib/vows/reporters/spec.js | 6 ++++-- lib/vows/reporters/watch.js | 5 +++-- 6 files changed, 51 insertions(+), 29 deletions(-) diff --git a/bin/vows b/bin/vows index e259cc2..a4e34dd 100755 --- a/bin/vows +++ b/bin/vows @@ -38,7 +38,7 @@ var vows = require('../lib/vows'); var cutils = require('../lib/vows/console'); var stylize = require('../lib/vows/console').stylize; var _reporter = require('../lib/vows/reporters/dot-matrix'), reporter = { - name: _reporter.name, + name: _reporter.name }; var _coverage; @@ -136,6 +136,9 @@ while (arg = argv.shift()) { case 'w': options.watch = true; break; + case 'supress-stdout': + options.supressStdout = true; + break; case 'isolate': case 'i': options.isolate = true; @@ -159,6 +162,11 @@ while (arg = argv.shift()) { } } +if (options.supressStdout) { + _reporter.setStream && _reporter.setStream(process.stdout); + process.stdout = fs.createWriteStream('/dev/null'); +} + if (options.watch) { options.reporter = reporter = require('../lib/vows/reporters/watch'); } @@ -201,10 +209,14 @@ if (! options.watch) { _reporter.report(data, filename); break; case 'end': - (options.verbose || _reporter.name === 'json') && _reporter.report(data); + (options.verbose || _reporter.name === 'json') && + _reporter.report(data); break; case 'finish': - options.verbose ? _reporter.print('\n') : _reporter.print(' '); + options.verbose ? + _reporter.print('\n') + : + _reporter.print(' '); break; } }; @@ -393,13 +405,13 @@ function importSuites(files) { function wrapSpawn(f) { f = cwdname(f); return function(options, callback) { - var args = [process.argv[1], '--json', f], + var args = [process.argv[1], '--json', '--supress-stdout', f], p = spawn(process.argv[0], args), result; p.on('exit', function(code) { callback( - (code != 0 || !result) ? + !result ? {errored: 1, total: 1} : result diff --git a/lib/vows/console.js b/lib/vows/console.js index 391e6bc..c7b5795 100644 --- a/lib/vows/console.js +++ b/lib/vows/console.js @@ -32,6 +32,8 @@ var $ = this.$ = function (str) { this.puts = function (options) { var stylize = exports.stylize; + options.stream || (options.stream = process.stdout); + return function (args) { args = Array.prototype.slice.call(arguments).map(function (a) { return a.replace(/`([^`]+)`/g, function (_, capture) { return stylize(capture, 'italic') }) diff --git a/lib/vows/reporters/dot-matrix.js b/lib/vows/reporters/dot-matrix.js index b9ddef3..417f204 100644 --- a/lib/vows/reporters/dot-matrix.js +++ b/lib/vows/reporters/dot-matrix.js @@ -1,26 +1,25 @@ - -var sys = require('sys'); - -var options = {}; -var console = require('../../vows/console'); -var spec = require('./spec'); -var stylize = console.stylize, +var options = {}, + console = require('../../vows/console'), + spec = require('./spec'), + stylize = console.stylize, puts = console.puts(options); // // Console reporter // -var stream, messages = [], lastContext; +var messages = [], lastContext; this.name = 'dot-matrix'; +this.setStream = function(s) { + options.stream = s; +}; + this.reset = function () { messages = []; lastContext = null; }; -this.report = function (data, s) { +this.report = function (data) { var event = data[1]; - options.stream = typeof(s) === 'object' ? s : process.stdout; - switch (data[0]) { case 'subject': // messages.push(stylize(event, 'underline') + '\n'); @@ -29,32 +28,32 @@ this.report = function (data, s) { break; case 'vow': if (event.status === 'honored') { - sys.print(stylize('·', 'green')); + puts(stylize('·', 'green')); } else if (event.status === 'pending') { - sys.print(stylize('-', 'cyan')); + puts(stylize('-', 'cyan')); } else { if (lastContext !== event.context) { lastContext = event.context; messages.push(spec.contextText(event.context)); } if (event.status === 'broken') { - sys.print(stylize('✗', 'yellow')); + puts(stylize('✗', 'yellow')); messages.push(spec.vowText(event)); } else if (event.status === 'errored') { - sys.print(stylize('✗', 'red')); + puts(stylize('✗', 'red')); messages.push(spec.vowText(event)); } messages.push(''); } break; case 'end': - sys.print(' '); + puts(' '); break; case 'finish': if (messages.length) { puts('\n\n' + messages.join('\n')); } else { - sys.print('\n'); + puts(''); } puts(console.result(event).join('\n')); break; @@ -65,5 +64,5 @@ this.report = function (data, s) { }; this.print = function (str) { - sys.print(str); + puts(str); }; diff --git a/lib/vows/reporters/json.js b/lib/vows/reporters/json.js index 449a68a..97ad5d4 100644 --- a/lib/vows/reporters/json.js +++ b/lib/vows/reporters/json.js @@ -1,10 +1,16 @@ -var sys = require('sys'); +var options = {}; +var console = require('../../vows/console'); +var puts = console.puts(options); + // // Console JSON reporter // this.name = 'json'; +this.setStream = function(s) { + options.stream = s; +}; this.report = function (obj) { - sys.puts(JSON.stringify(obj)); + puts(JSON.stringify(obj)); }; this.print = function (str) {}; diff --git a/lib/vows/reporters/spec.js b/lib/vows/reporters/spec.js index a7835ae..32ee370 100644 --- a/lib/vows/reporters/spec.js +++ b/lib/vows/reporters/spec.js @@ -9,10 +9,12 @@ var stylize = console.stylize, // this.name = 'spec'; -this.report = function (data, s) { +this.setStream = function(s) { + options.stream = s; +}; +this.report = function (data) { var event = data[1]; - options.stream = typeof(s) === 'object' ? s : process.stdout; buffer = []; switch (data[0]) { diff --git a/lib/vows/reporters/watch.js b/lib/vows/reporters/watch.js index e47e1ad..a09382a 100644 --- a/lib/vows/reporters/watch.js +++ b/lib/vows/reporters/watch.js @@ -11,14 +11,15 @@ var stylize = console.stylize, var lastContext; this.name = 'watch'; +this.setStream = function(s) { + options.stream = s; +}; this.reset = function () { lastContext = null; }; this.report = function (data) { var event = data[1]; - options.stream = process.stdout; - switch (data[0]) { case 'vow': if (['honored', 'pending'].indexOf(event.status) === -1) { From 5c40a46c85e06e1538a9da0798c09f56db99cd6f Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Wed, 3 Aug 2011 20:31:43 +0700 Subject: [PATCH 06/28] [isolate] tests --- test/fixtures/isolate/failing-test.js | 18 ++++ test/fixtures/isolate/log-test.js | 18 ++++ test/fixtures/isolate/passing-test.js | 17 ++++ test/fixtures/isolate/stderr-test.js | 18 ++++ test/isolate-test.js | 140 ++++++++++++++++++++++++++ 5 files changed, 211 insertions(+) create mode 100644 test/fixtures/isolate/failing-test.js create mode 100644 test/fixtures/isolate/log-test.js create mode 100644 test/fixtures/isolate/passing-test.js create mode 100644 test/fixtures/isolate/stderr-test.js create mode 100644 test/isolate-test.js diff --git a/test/fixtures/isolate/failing-test.js b/test/fixtures/isolate/failing-test.js new file mode 100644 index 0000000..3f5046c --- /dev/null +++ b/test/fixtures/isolate/failing-test.js @@ -0,0 +1,18 @@ +var vows = require('../../../lib/vows'), + assert = require('assert'); + +var obvious; +vows.describe('failing').addBatch({ + 'Obvious test': obvious = { + topic: function() { + this.callback(null, false); + }, + 'should work': function(result) { + assert.ok(result); + } + // but it won't + }, + 'Obvious test #2': obvious, + 'Obvious test #3': obvious, + 'Obvious test #4': obvious +}).export(module); diff --git a/test/fixtures/isolate/log-test.js b/test/fixtures/isolate/log-test.js new file mode 100644 index 0000000..7b09b50 --- /dev/null +++ b/test/fixtures/isolate/log-test.js @@ -0,0 +1,18 @@ +var vows = require('../../../lib/vows'), + assert = require('assert'); + +var obvious; +vows.describe('stderr').addBatch({ + 'Obvious test': obvious = { + topic: function() { + this.callback(null, true); + }, + 'should work': function(result) { + console.log('oh no!'); + assert.ok(result); + } + }, + 'Obvious test #2': obvious, + 'Obvious test #3': obvious, + 'Obvious test #4': obvious +}).export(module); diff --git a/test/fixtures/isolate/passing-test.js b/test/fixtures/isolate/passing-test.js new file mode 100644 index 0000000..59f7ffa --- /dev/null +++ b/test/fixtures/isolate/passing-test.js @@ -0,0 +1,17 @@ +var vows = require('../../../lib/vows'), + assert = require('assert'); + +var obvious; +vows.describe('passing').addBatch({ + 'Obvious test': obvious = { + topic: function() { + this.callback(null, true); + }, + 'should work': function(result) { + assert.ok(result); + } + }, + 'Obvious test #2': obvious, + 'Obvious test #3': obvious, + 'Obvious test #4': obvious +}).export(module); diff --git a/test/fixtures/isolate/stderr-test.js b/test/fixtures/isolate/stderr-test.js new file mode 100644 index 0000000..7b1c452 --- /dev/null +++ b/test/fixtures/isolate/stderr-test.js @@ -0,0 +1,18 @@ +var vows = require('../../../lib/vows'), + assert = require('assert'); + +var obvious; +vows.describe('stderr').addBatch({ + 'Obvious test': obvious = { + topic: function() { + this.callback(null, true); + }, + 'should work': function(result) { + console.error('oh no!'); + assert.ok(result); + } + }, + 'Obvious test #2': obvious, + 'Obvious test #3': obvious, + 'Obvious test #4': obvious +}).export(module); diff --git a/test/isolate-test.js b/test/isolate-test.js new file mode 100644 index 0000000..4c0bc25 --- /dev/null +++ b/test/isolate-test.js @@ -0,0 +1,140 @@ +var vows = require('../lib/vows'), + assert = require('assert'), + path = require('path'), + exec = require('child_process').exec; + +function generateTopic(args, file) { + return function() { + var cmd = './bin/vows' + ' -i ' + (args || '') + + ' ./test/fixtures/isolate/' + file, + options = {cwd: path.resolve(__dirname + '/../')}, + callback = this.callback; + + exec(cmd, options, function(err, stdout, stderr) { + callback(null, { + err: err, + stdout: stdout, + stderr: stderr + }); + }); + } +}; + +function assertExecOk(r) { + assert.isNull(r.err); +} + +function assertExecNotOk(r) { + assert.isNotNull(r.err); +} + +function parseResults(stdout) { + return stdout.split(/\n/g).map(function(s) { + if (!s) return; + return JSON.parse(s); + }).filter(function(s) {return s}); +} + +function assertResultTypePresent(results, type) { + assert.ok(results.some(function(result) { + return result[0] == type; + })); +} + +function assertResultsFinish(results, expected) { + var finish = results[results.length - 1]; + assert.equal(finish[0], 'finish'); + + finish = finish[1]; + + Object.keys(expected).forEach(function(key) { + assert.equal(finish[key], expected[key]); + }); +} + +vows.describe('vows/isolate').addBatch({ + 'Running vows with -i flag for test/fixtures/isolate/': { + 'passing-test.js': { + 'with default reporter': { + topic: generateTopic(null, 'passing-test.js'), + 'should be ok': assertExecOk + }, + 'with json reporter': { + topic: generateTopic('--json', 'passing-test.js'), + 'should be ok': assertExecOk, + 'should have correct output': function(r) { + var results = parseResults(r.stdout) + + assertResultTypePresent(results, 'subject'); + assertResultTypePresent(results, 'end'); + + assertResultsFinish(results, { + total: 4, + honored: 4 + }); + } + } + }, + 'failing-test.js': { + 'with json reporter': { + topic: generateTopic('--json', 'failing-test.js'), + 'should be not ok': assertExecNotOk, + 'should have correct output though': function(r) { + var results = parseResults(r.stdout); + + assertResultsFinish(results, { + total: 4, + broken: 4 + }); + } + } + }, + 'stderr-test.js': { + 'with json reporter': { + topic: generateTopic('--json', 'stderr-test.js'), + 'should be ok': assertExecOk, + 'should have stderr': function(r) { + assert.equal(r.stderr, + ['oh no!', 'oh no!', 'oh no!', 'oh no!', ''].join('\n')); + }, + 'should have correct output': function(r) { + var results= parseResults(r.stdout); + + assertResultsFinish(results, { + total: 4, + honored: 4 + }); + } + } + }, + 'log-test.js': { + 'with json reporter': { + topic: generateTopic('--json', 'log-test.js'), + 'should be ok': assertExecOk, + 'should have correct output': function(r) { + var results= parseResults(r.stdout); + + assertResultsFinish(results, { + total: 4, + honored: 4 + }); + } + } + }, + 'all tests (*)': { + 'with json reporter': { + topic: generateTopic('--json', '*'), + 'should be not ok': assertExecNotOk, + 'should have correct output': function(r) { + var results= parseResults(r.stdout); + + assertResultsFinish(results, { + total: 16, + broken: 4, + honored: 12 + }); + } + } + } + } +}).export(module); From 9be20ef03dd67ad3c142b4dd3d6c5d0409db5274 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 5 Aug 2011 13:51:12 +0700 Subject: [PATCH 07/28] [isolate] allow reporters to output raw data --- lib/vows/console.js | 11 +++++++---- lib/vows/reporters/json.js | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/vows/console.js b/lib/vows/console.js index c7b5795..2b80d58 100644 --- a/lib/vows/console.js +++ b/lib/vows/console.js @@ -35,10 +35,13 @@ this.puts = function (options) { options.stream || (options.stream = process.stdout); return function (args) { - args = Array.prototype.slice.call(arguments).map(function (a) { - return a.replace(/`([^`]+)`/g, function (_, capture) { return stylize(capture, 'italic') }) - .replace(/\*([^*]+)\*/g, function (_, capture) { return stylize(capture, 'bold') }); - }); + args = Array.prototype.slice.call(arguments); + if (!options.raw) { + args = args.map(function (a) { + return a.replace(/`([^`]+)`/g, function (_, capture) { return stylize(capture, 'italic') }) + .replace(/\*([^*]+)\*/g, function (_, capture) { return stylize(capture, 'bold') }); + }); + } return options.stream.write(args.join('\n') + '\n'); }; }; diff --git a/lib/vows/reporters/json.js b/lib/vows/reporters/json.js index 97ad5d4..3cf53ef 100644 --- a/lib/vows/reporters/json.js +++ b/lib/vows/reporters/json.js @@ -1,4 +1,4 @@ -var options = {}; +var options = {raw: true}; var console = require('../../vows/console'); var puts = console.puts(options); From dcf502185075cebf3fce9ce016997126aefd44b9 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 5 Aug 2011 14:01:33 +0700 Subject: [PATCH 08/28] [isolate] fixed test fixtures naming --- .../isolate/{failing-test.js => failing.js} | 0 test/fixtures/isolate/{log-test.js => log.js} | 0 .../isolate/{passing-test.js => passing.js} | 0 .../isolate/{stderr-test.js => stderr.js} | 0 test/isolate-test.js | 18 +++++++++--------- 5 files changed, 9 insertions(+), 9 deletions(-) rename test/fixtures/isolate/{failing-test.js => failing.js} (100%) rename test/fixtures/isolate/{log-test.js => log.js} (100%) rename test/fixtures/isolate/{passing-test.js => passing.js} (100%) rename test/fixtures/isolate/{stderr-test.js => stderr.js} (100%) diff --git a/test/fixtures/isolate/failing-test.js b/test/fixtures/isolate/failing.js similarity index 100% rename from test/fixtures/isolate/failing-test.js rename to test/fixtures/isolate/failing.js diff --git a/test/fixtures/isolate/log-test.js b/test/fixtures/isolate/log.js similarity index 100% rename from test/fixtures/isolate/log-test.js rename to test/fixtures/isolate/log.js diff --git a/test/fixtures/isolate/passing-test.js b/test/fixtures/isolate/passing.js similarity index 100% rename from test/fixtures/isolate/passing-test.js rename to test/fixtures/isolate/passing.js diff --git a/test/fixtures/isolate/stderr-test.js b/test/fixtures/isolate/stderr.js similarity index 100% rename from test/fixtures/isolate/stderr-test.js rename to test/fixtures/isolate/stderr.js diff --git a/test/isolate-test.js b/test/isolate-test.js index 4c0bc25..d0990df 100644 --- a/test/isolate-test.js +++ b/test/isolate-test.js @@ -54,13 +54,13 @@ function assertResultsFinish(results, expected) { vows.describe('vows/isolate').addBatch({ 'Running vows with -i flag for test/fixtures/isolate/': { - 'passing-test.js': { + 'passing.js': { 'with default reporter': { - topic: generateTopic(null, 'passing-test.js'), + topic: generateTopic(null, 'passing.js'), 'should be ok': assertExecOk }, 'with json reporter': { - topic: generateTopic('--json', 'passing-test.js'), + topic: generateTopic('--json', 'passing.js'), 'should be ok': assertExecOk, 'should have correct output': function(r) { var results = parseResults(r.stdout) @@ -75,9 +75,9 @@ vows.describe('vows/isolate').addBatch({ } } }, - 'failing-test.js': { + 'failing.js': { 'with json reporter': { - topic: generateTopic('--json', 'failing-test.js'), + topic: generateTopic('--json', 'failing.js'), 'should be not ok': assertExecNotOk, 'should have correct output though': function(r) { var results = parseResults(r.stdout); @@ -89,9 +89,9 @@ vows.describe('vows/isolate').addBatch({ } } }, - 'stderr-test.js': { + 'stderr.js': { 'with json reporter': { - topic: generateTopic('--json', 'stderr-test.js'), + topic: generateTopic('--json', 'stderr.js'), 'should be ok': assertExecOk, 'should have stderr': function(r) { assert.equal(r.stderr, @@ -107,9 +107,9 @@ vows.describe('vows/isolate').addBatch({ } } }, - 'log-test.js': { + 'log.js': { 'with json reporter': { - topic: generateTopic('--json', 'log-test.js'), + topic: generateTopic('--json', 'log.js'), 'should be ok': assertExecOk, 'should have correct output': function(r) { var results= parseResults(r.stdout); From c8ee8156327b7a5a36da48f338f7553e68c5d0ec Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Fri, 5 Aug 2011 14:04:46 +0700 Subject: [PATCH 09/28] [style] respect cloudhead's style --- bin/vows | 8 ++++---- lib/vows/reporters/dot-matrix.js | 2 +- lib/vows/reporters/json.js | 2 +- lib/vows/reporters/spec.js | 2 +- lib/vows/reporters/watch.js | 2 +- test/fixtures/isolate/failing.js | 4 ++-- test/fixtures/isolate/log.js | 4 ++-- test/fixtures/isolate/passing.js | 4 ++-- test/fixtures/isolate/stderr.js | 4 ++-- test/isolate-test.js | 24 ++++++++++++------------ 10 files changed, 28 insertions(+), 28 deletions(-) diff --git a/bin/vows b/bin/vows index a4e34dd..9b9ccf7 100755 --- a/bin/vows +++ b/bin/vows @@ -404,12 +404,12 @@ function importSuites(files) { function wrapSpawn(f) { f = cwdname(f); - return function(options, callback) { + return function (options, callback) { var args = [process.argv[1], '--json', '--supress-stdout', f], p = spawn(process.argv[0], args), result; - p.on('exit', function(code) { + p.on('exit', function (code) { callback( !result ? {errored: 1, total: 1} @@ -419,7 +419,7 @@ function importSuites(files) { }); var buffer = []; - p.stdout.on('data', function(data) { + p.stdout.on('data', function (data) { data = data.toString().split(/\n/g); if (data.length == 1) { buffer.push(data[0]); @@ -427,7 +427,7 @@ function importSuites(files) { data[0] = buffer.concat(data[0]).join(''); buffer = [data.pop()]; - data.forEach(function(data) { + data.forEach(function (data) { if (data) { data = JSON.parse(data); if (data && data[0] === 'finish') { diff --git a/lib/vows/reporters/dot-matrix.js b/lib/vows/reporters/dot-matrix.js index 417f204..0ab36b1 100644 --- a/lib/vows/reporters/dot-matrix.js +++ b/lib/vows/reporters/dot-matrix.js @@ -9,7 +9,7 @@ var options = {}, var messages = [], lastContext; this.name = 'dot-matrix'; -this.setStream = function(s) { +this.setStream = function (s) { options.stream = s; }; diff --git a/lib/vows/reporters/json.js b/lib/vows/reporters/json.js index 3cf53ef..2904a05 100644 --- a/lib/vows/reporters/json.js +++ b/lib/vows/reporters/json.js @@ -6,7 +6,7 @@ var puts = console.puts(options); // Console JSON reporter // this.name = 'json'; -this.setStream = function(s) { +this.setStream = function (s) { options.stream = s; }; this.report = function (obj) { diff --git a/lib/vows/reporters/spec.js b/lib/vows/reporters/spec.js index 32ee370..73f8e74 100644 --- a/lib/vows/reporters/spec.js +++ b/lib/vows/reporters/spec.js @@ -9,7 +9,7 @@ var stylize = console.stylize, // this.name = 'spec'; -this.setStream = function(s) { +this.setStream = function (s) { options.stream = s; }; this.report = function (data) { diff --git a/lib/vows/reporters/watch.js b/lib/vows/reporters/watch.js index a09382a..36ae927 100644 --- a/lib/vows/reporters/watch.js +++ b/lib/vows/reporters/watch.js @@ -11,7 +11,7 @@ var stylize = console.stylize, var lastContext; this.name = 'watch'; -this.setStream = function(s) { +this.setStream = function (s) { options.stream = s; }; this.reset = function () { diff --git a/test/fixtures/isolate/failing.js b/test/fixtures/isolate/failing.js index 3f5046c..7a1865e 100644 --- a/test/fixtures/isolate/failing.js +++ b/test/fixtures/isolate/failing.js @@ -4,10 +4,10 @@ var vows = require('../../../lib/vows'), var obvious; vows.describe('failing').addBatch({ 'Obvious test': obvious = { - topic: function() { + topic: function () { this.callback(null, false); }, - 'should work': function(result) { + 'should work': function (result) { assert.ok(result); } // but it won't diff --git a/test/fixtures/isolate/log.js b/test/fixtures/isolate/log.js index 7b09b50..9828045 100644 --- a/test/fixtures/isolate/log.js +++ b/test/fixtures/isolate/log.js @@ -4,10 +4,10 @@ var vows = require('../../../lib/vows'), var obvious; vows.describe('stderr').addBatch({ 'Obvious test': obvious = { - topic: function() { + topic: function () { this.callback(null, true); }, - 'should work': function(result) { + 'should work': function (result) { console.log('oh no!'); assert.ok(result); } diff --git a/test/fixtures/isolate/passing.js b/test/fixtures/isolate/passing.js index 59f7ffa..7f95730 100644 --- a/test/fixtures/isolate/passing.js +++ b/test/fixtures/isolate/passing.js @@ -4,10 +4,10 @@ var vows = require('../../../lib/vows'), var obvious; vows.describe('passing').addBatch({ 'Obvious test': obvious = { - topic: function() { + topic: function () { this.callback(null, true); }, - 'should work': function(result) { + 'should work': function (result) { assert.ok(result); } }, diff --git a/test/fixtures/isolate/stderr.js b/test/fixtures/isolate/stderr.js index 7b1c452..545ad20 100644 --- a/test/fixtures/isolate/stderr.js +++ b/test/fixtures/isolate/stderr.js @@ -4,10 +4,10 @@ var vows = require('../../../lib/vows'), var obvious; vows.describe('stderr').addBatch({ 'Obvious test': obvious = { - topic: function() { + topic: function () { this.callback(null, true); }, - 'should work': function(result) { + 'should work': function (result) { console.error('oh no!'); assert.ok(result); } diff --git a/test/isolate-test.js b/test/isolate-test.js index d0990df..40f993b 100644 --- a/test/isolate-test.js +++ b/test/isolate-test.js @@ -4,13 +4,13 @@ var vows = require('../lib/vows'), exec = require('child_process').exec; function generateTopic(args, file) { - return function() { + return function () { var cmd = './bin/vows' + ' -i ' + (args || '') + ' ./test/fixtures/isolate/' + file, options = {cwd: path.resolve(__dirname + '/../')}, callback = this.callback; - exec(cmd, options, function(err, stdout, stderr) { + exec(cmd, options, function (err, stdout, stderr) { callback(null, { err: err, stdout: stdout, @@ -29,14 +29,14 @@ function assertExecNotOk(r) { } function parseResults(stdout) { - return stdout.split(/\n/g).map(function(s) { + return stdout.split(/\n/g).map(function (s) { if (!s) return; return JSON.parse(s); - }).filter(function(s) {return s}); + }).filter(function (s) {return s}); } function assertResultTypePresent(results, type) { - assert.ok(results.some(function(result) { + assert.ok(results.some(function (result) { return result[0] == type; })); } @@ -47,7 +47,7 @@ function assertResultsFinish(results, expected) { finish = finish[1]; - Object.keys(expected).forEach(function(key) { + Object.keys(expected).forEach(function (key) { assert.equal(finish[key], expected[key]); }); } @@ -62,7 +62,7 @@ vows.describe('vows/isolate').addBatch({ 'with json reporter': { topic: generateTopic('--json', 'passing.js'), 'should be ok': assertExecOk, - 'should have correct output': function(r) { + 'should have correct output': function (r) { var results = parseResults(r.stdout) assertResultTypePresent(results, 'subject'); @@ -79,7 +79,7 @@ vows.describe('vows/isolate').addBatch({ 'with json reporter': { topic: generateTopic('--json', 'failing.js'), 'should be not ok': assertExecNotOk, - 'should have correct output though': function(r) { + 'should have correct output though': function (r) { var results = parseResults(r.stdout); assertResultsFinish(results, { @@ -93,11 +93,11 @@ vows.describe('vows/isolate').addBatch({ 'with json reporter': { topic: generateTopic('--json', 'stderr.js'), 'should be ok': assertExecOk, - 'should have stderr': function(r) { + 'should have stderr': function (r) { assert.equal(r.stderr, ['oh no!', 'oh no!', 'oh no!', 'oh no!', ''].join('\n')); }, - 'should have correct output': function(r) { + 'should have correct output': function (r) { var results= parseResults(r.stdout); assertResultsFinish(results, { @@ -111,7 +111,7 @@ vows.describe('vows/isolate').addBatch({ 'with json reporter': { topic: generateTopic('--json', 'log.js'), 'should be ok': assertExecOk, - 'should have correct output': function(r) { + 'should have correct output': function (r) { var results= parseResults(r.stdout); assertResultsFinish(results, { @@ -125,7 +125,7 @@ vows.describe('vows/isolate').addBatch({ 'with json reporter': { topic: generateTopic('--json', '*'), 'should be not ok': assertExecNotOk, - 'should have correct output': function(r) { + 'should have correct output': function (r) { var results= parseResults(r.stdout); assertResultsFinish(results, { From 889b748e5bdce9d28226f443faa6494d394450ec Mon Sep 17 00:00:00 2001 From: indexzero Date: Tue, 26 Jul 2011 23:24:00 -0700 Subject: [PATCH 10/28] [bin test] Added additional teardown test. Update bin/vows to support absolute path. #83 --- bin/vows | 4 +++- test/vows-test.js | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/bin/vows b/bin/vows index 9b9ccf7..c6415ba 100755 --- a/bin/vows +++ b/bin/vows @@ -224,7 +224,9 @@ if (! options.watch) { reporter.print = _reporter.print; files = args.map(function (a) { - return path.join(process.cwd(), a.replace(fileExt, '')); + return (!a.match(/^\//)) + ? path.join(process.cwd(), a.replace(fileExt, '')) + : a.replace(fileExt, ''); }); runSuites(importSuites(files), function (results) { diff --git a/test/vows-test.js b/test/vows-test.js index 34f90ae..0568236 100644 --- a/test/vows-test.js +++ b/test/vows-test.js @@ -350,6 +350,11 @@ vows.describe("Vows with teardowns").addBatch({ "And a final vow": function (topic) { assert.isTrue(topic.flag); }, + 'subcontext': { + 'nested': function (_, topic) { + assert.isTrue(topic.flag); + } + }, teardown: function (topic) { topic.flag = false; }, From 33aeb64a0d8f5cf37f2db2b7573914d1e65b117e Mon Sep 17 00:00:00 2001 From: indexzero Date: Fri, 12 Aug 2011 00:46:52 -0400 Subject: [PATCH 11/28] (dist) Version bump. 0.5.10 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 148a5e9..a520fe1 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,11 @@ "url" : "http://vowsjs.org", "keywords" : ["testing", "spec", "test", "BDD"], "author" : "Alexis Sellier ", - "contributors" : [], + "contributors" : [{ name: "Charlie Robbins", email: "charlie.robbins@gmail.com" }], "dependencies" : {"eyes": ">=0.1.6"}, "main" : "./lib/vows", "bin" : { "vows": "./bin/vows" }, "directories" : { "test": "./test", "bin": "./bin" }, - "version" : "0.5.9", + "version" : "0.5.10", "engines" : {"node": ">=0.2.6"} } From 67b7ce797872a380f84c93ac94ab88f09be10c1e Mon Sep 17 00:00:00 2001 From: indexzero Date: Fri, 12 Aug 2011 00:49:13 -0400 Subject: [PATCH 12/28] (minor) Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a520fe1..2ee79e8 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "url" : "http://vowsjs.org", "keywords" : ["testing", "spec", "test", "BDD"], "author" : "Alexis Sellier ", - "contributors" : [{ name: "Charlie Robbins", email: "charlie.robbins@gmail.com" }], + "contributors" : [{ "name": "Charlie Robbins", "email": "charlie.robbins@gmail.com" }], "dependencies" : {"eyes": ">=0.1.6"}, "main" : "./lib/vows", "bin" : { "vows": "./bin/vows" }, From 0d8c406349fa64d546729c1eed6e7e3bc3e66bd7 Mon Sep 17 00:00:00 2001 From: indexzero Date: Fri, 12 Aug 2011 01:47:52 -0400 Subject: [PATCH 13/28] [fix] Dont always append a tailing `\n` to all test output --- lib/vows/console.js | 5 +++-- lib/vows/reporters/dot-matrix.js | 4 ++-- lib/vows/reporters/json.js | 2 +- lib/vows/reporters/spec.js | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/vows/console.js b/lib/vows/console.js index 2b80d58..4a33141 100644 --- a/lib/vows/console.js +++ b/lib/vows/console.js @@ -33,6 +33,7 @@ var $ = this.$ = function (str) { this.puts = function (options) { var stylize = exports.stylize; options.stream || (options.stream = process.stdout); + options.tail = options.tail || ''; return function (args) { args = Array.prototype.slice.call(arguments); @@ -42,7 +43,7 @@ this.puts = function (options) { .replace(/\*([^*]+)\*/g, function (_, capture) { return stylize(capture, 'bold') }); }); } - return options.stream.write(args.join('\n') + '\n'); + return options.stream.write(args.join('\n') + options.tail); }; }; @@ -78,7 +79,7 @@ this.result = function (event) { time = ' (' + event.time.toFixed(3) + 's)'; time = this.stylize(time, 'grey'); } - buffer.push(header + result + time); + buffer.push(header + result + time + '\n'); return buffer; }; diff --git a/lib/vows/reporters/dot-matrix.js b/lib/vows/reporters/dot-matrix.js index 0ab36b1..ae811e8 100644 --- a/lib/vows/reporters/dot-matrix.js +++ b/lib/vows/reporters/dot-matrix.js @@ -1,6 +1,6 @@ -var options = {}, +var options = { tail: '' }, console = require('../../vows/console'), - spec = require('./spec'), + //spec = require('./spec'), stylize = console.stylize, puts = console.puts(options); // diff --git a/lib/vows/reporters/json.js b/lib/vows/reporters/json.js index 2904a05..9f5ac4d 100644 --- a/lib/vows/reporters/json.js +++ b/lib/vows/reporters/json.js @@ -1,4 +1,4 @@ -var options = {raw: true}; +var options = { tail: '\n', raw: true }; var console = require('../../vows/console'); var puts = console.puts(options); diff --git a/lib/vows/reporters/spec.js b/lib/vows/reporters/spec.js index 73f8e74..8f88529 100644 --- a/lib/vows/reporters/spec.js +++ b/lib/vows/reporters/spec.js @@ -1,6 +1,6 @@ var sys = require('sys'); -var options = {}; +var options = { tail: '\n' }; var console = require('../../vows/console'); var stylize = console.stylize, puts = console.puts(options); From a81326827c76bd8559874c82e018922682a1c7e1 Mon Sep 17 00:00:00 2001 From: indexzero Date: Fri, 12 Aug 2011 14:32:50 -0400 Subject: [PATCH 14/28] (fix) Remove unecessary reference to spec in reporters/dot-matrix.js. Fixes #117 --- lib/vows/reporters/dot-matrix.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/vows/reporters/dot-matrix.js b/lib/vows/reporters/dot-matrix.js index ae811e8..9bb3d1e 100644 --- a/lib/vows/reporters/dot-matrix.js +++ b/lib/vows/reporters/dot-matrix.js @@ -1,6 +1,5 @@ var options = { tail: '' }, console = require('../../vows/console'), - //spec = require('./spec'), stylize = console.stylize, puts = console.puts(options); // @@ -34,7 +33,7 @@ this.report = function (data) { } else { if (lastContext !== event.context) { lastContext = event.context; - messages.push(spec.contextText(event.context)); + messages.push(' ' + event.context); } if (event.status === 'broken') { puts(stylize('✗', 'yellow')); From f18b45cacdfe02872e4fa257b19b468b0be62c1d Mon Sep 17 00:00:00 2001 From: indexzero Date: Fri, 12 Aug 2011 16:10:08 -0400 Subject: [PATCH 15/28] (minor) Move .vowsText and .contextText out of reporters/spec into vows/console --- lib/vows/console.js | 32 ++++++++++++++++++++++++++++ lib/vows/reporters/dot-matrix.js | 4 ++-- lib/vows/reporters/spec.js | 36 ++------------------------------ lib/vows/reporters/watch.js | 4 ++-- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/lib/vows/console.js b/lib/vows/console.js index 4a33141..f4e8e29 100644 --- a/lib/vows/console.js +++ b/lib/vows/console.js @@ -97,3 +97,35 @@ this.error = function (obj) { return string; }; + +this.contextText = function (event) { + return ' ' + event; +}; + +this.vowText = function (event) { + var buffer = []; + + buffer.push(' ' + { + honored: ' ✓ ', + broken: ' ✗ ', + errored: ' ✗ ', + pending: ' - ' + }[event.status] + stylize(event.title, ({ + honored: 'green', + broken: 'yellow', + errored: 'red', + pending: 'cyan' + })[event.status])); + + if (event.status === 'broken') { + buffer.push(' » ' + event.exception); + } else if (event.status === 'errored') { + if (event.exception.type === 'promise') { + buffer.push(' » ' + stylize("An unexpected error was caught: " + + stylize(event.exception.error, 'bold'), 'red')); + } else { + buffer.push(' ' + stylize(event.exception, 'red')); + } + } + return buffer.join('\n'); +}; diff --git a/lib/vows/reporters/dot-matrix.js b/lib/vows/reporters/dot-matrix.js index 9bb3d1e..0ecf590 100644 --- a/lib/vows/reporters/dot-matrix.js +++ b/lib/vows/reporters/dot-matrix.js @@ -37,10 +37,10 @@ this.report = function (data) { } if (event.status === 'broken') { puts(stylize('✗', 'yellow')); - messages.push(spec.vowText(event)); + messages.push(console.vowText(event)); } else if (event.status === 'errored') { puts(stylize('✗', 'red')); - messages.push(spec.vowText(event)); + messages.push(console.vowText(event)); } messages.push(''); } diff --git a/lib/vows/reporters/spec.js b/lib/vows/reporters/spec.js index 8f88529..0f91146 100644 --- a/lib/vows/reporters/spec.js +++ b/lib/vows/reporters/spec.js @@ -22,10 +22,10 @@ this.report = function (data) { puts('\n♢ ' + stylize(event, 'bold') + '\n'); break; case 'context': - puts(this.contextText(event)); + puts(console.contextText(event)); break; case 'vow': - puts(this.vowText(event)); + puts(console.vowText(event)); break; case 'end': sys.print('\n'); @@ -39,38 +39,6 @@ this.report = function (data) { } }; -this.contextText = function (event) { - return ' ' + event; -}; - -this.vowText = function (event) { - var buffer = []; - - buffer.push(' ' + { - honored: ' ✓ ', - broken: ' ✗ ', - errored: ' ✗ ', - pending: ' - ' - }[event.status] + stylize(event.title, ({ - honored: 'green', - broken: 'yellow', - errored: 'red', - pending: 'cyan' - })[event.status])); - - if (event.status === 'broken') { - buffer.push(' » ' + event.exception); - } else if (event.status === 'errored') { - if (event.exception.type === 'promise') { - buffer.push(' » ' + stylize("An unexpected error was caught: " + - stylize(event.exception.error, 'bold'), 'red')); - } else { - buffer.push(' ' + stylize(event.exception, 'red')); - } - } - return buffer.join('\n'); -}; - this.print = function (str) { sys.print(str); }; diff --git a/lib/vows/reporters/watch.js b/lib/vows/reporters/watch.js index 36ae927..f172481 100644 --- a/lib/vows/reporters/watch.js +++ b/lib/vows/reporters/watch.js @@ -25,9 +25,9 @@ this.report = function (data) { if (['honored', 'pending'].indexOf(event.status) === -1) { if (lastContext !== event.context) { lastContext = event.context; - puts(spec.contextText(event.context)); + puts(console.contextText(event.context)); } - puts(spec.vowText(event)); + puts(console.vowText(event)); puts(''); } break; From 484b5f418eaa71b71945048d09634faddc930a54 Mon Sep 17 00:00:00 2001 From: indexzero Date: Fri, 12 Aug 2011 19:55:51 -0400 Subject: [PATCH 16/28] [fix] Update references to `stylize` after refactor --- lib/vows/console.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/vows/console.js b/lib/vows/console.js index f4e8e29..cf988dd 100644 --- a/lib/vows/console.js +++ b/lib/vows/console.js @@ -110,7 +110,7 @@ this.vowText = function (event) { broken: ' ✗ ', errored: ' ✗ ', pending: ' - ' - }[event.status] + stylize(event.title, ({ + }[event.status] + this.stylize(event.title, ({ honored: 'green', broken: 'yellow', errored: 'red', @@ -121,10 +121,10 @@ this.vowText = function (event) { buffer.push(' » ' + event.exception); } else if (event.status === 'errored') { if (event.exception.type === 'promise') { - buffer.push(' » ' + stylize("An unexpected error was caught: " + - stylize(event.exception.error, 'bold'), 'red')); + buffer.push(' » ' + this.stylize("An unexpected error was caught: " + + this.stylize(event.exception.error, 'bold'), 'red')); } else { - buffer.push(' ' + stylize(event.exception, 'red')); + buffer.push(' ' + this.stylize(event.exception, 'red')); } } return buffer.join('\n'); From c7f9e3c6b75c61aeacccebe19711f412724d7dfc Mon Sep 17 00:00:00 2001 From: nekaab Date: Fri, 5 Aug 2011 19:36:33 +0200 Subject: [PATCH 17/28] added assert.isNotEmpty and assert.isDefined --- lib/assert/macros.js | 10 ++++++++++ test/assert-test.js | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/assert/macros.js b/lib/assert/macros.js index bdfe7d4..137028e 100644 --- a/lib/assert/macros.js +++ b/lib/assert/macros.js @@ -104,6 +104,11 @@ assert.isEmpty = function (actual, message) { assert.fail(actual, 0, message || "expected {actual} to be empty", "length", assert.isEmpty); } }; +assert.isNotEmpty = function (actual, message) { + if ((isObject(actual) && Object.keys(actual).length === 0) || actual.length === 0) { + assert.fail(actual, 0, message || "expected {actual} to be not empty", "length", assert.isNotEmpty); + } +}; assert.length = function (actual, expected, message) { if (actual.length !== expected) { @@ -152,6 +157,11 @@ assert.isUndefined = function (actual, message) { assert.fail(actual, undefined, message || "expected {actual} to be {expected}", "===", assert.isUndefined); } }; +assert.isDefined = function (actual, message) { + if(actual === undefined) { + assert.fail(actual, 0, message || "expected {actual} to be defined", "===", assert.isDefined); + } +}; assert.isString = function (actual, message) { assertTypeOf(actual, 'string', message || "expected {actual} to be a String", assert.isString); }; diff --git a/test/assert-test.js b/test/assert-test.js index b3aa8e0..76e2d32 100644 --- a/test/assert-test.js +++ b/test/assert-test.js @@ -16,6 +16,10 @@ vows.describe('vows/assert').addBatch({ assert.length("hello world", 11); assert.length([1, 2, 3], 3); }, + "`isDefined`": function (assert) { + assert.isDefined(null); + assertError(assert.isDefined, undefined); + }, "`include`": function (assert) { assert.include("hello world", "world"); assert.include([0, 42, 0], 42); @@ -78,6 +82,10 @@ vows.describe('vows/assert').addBatch({ assert.isUndefined(undefined); assertError(assert.isUndefined, null); }, + "`isDefined`": function (assert) { + assert.isDefined(null); + assertError(assert.isDefined, undefined); + }, "`isNull`": function (assert) { assert.isNull(null); assertError(assert.isNull, 0); @@ -101,6 +109,14 @@ vows.describe('vows/assert').addBatch({ assert.isEmpty({}); assert.isEmpty([]); assert.isEmpty(""); + }, + "`isNotEmpty`": function (assert) { + assert.isNotEmpty({goo:true}); + assert.isNotEmpty([1]); + assert.isNotEmpty(" "); + assertError(assert.isNotEmpty, {}); + assertError(assert.isNotEmpty, []); + assertError(assert.isNotEmpty, ""); } } }).export(module); From 5b2ae847ad003d1b9f0b324212638127ce41eb13 Mon Sep 17 00:00:00 2001 From: indexzero Date: Sat, 20 Aug 2011 23:10:48 -0400 Subject: [PATCH 18/28] (fix) Check topic.constructor to reverse regression introduced by instanceof check --- lib/vows/suite.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vows/suite.js b/lib/vows/suite.js index c6bbd6d..6665ed3 100644 --- a/lib/vows/suite.js +++ b/lib/vows/suite.js @@ -142,7 +142,7 @@ this.Suite.prototype = new(function () { // If the topic doesn't return an event emitter (such as a promise), // we create it ourselves, and emit the value on the next tick. - if (! (topic instanceof events.EventEmitter)) { + if (! (topic && topic.constructor === events.EventEmitter)) { ctx.emitter = new(events.EventEmitter); if (! ctx._callback) { From 3a2f697aba44fd8d7caa742f7bbd5842fa716347 Mon Sep 17 00:00:00 2001 From: Jerry Sievert Date: Wed, 17 Aug 2011 20:20:38 -0700 Subject: [PATCH 19/28] add unified coverage maps, and fix issue when using coverage without instrumentation --- bin/vows | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/bin/vows b/bin/vows index c6415ba..3449709 100755 --- a/bin/vows +++ b/bin/vows @@ -58,6 +58,7 @@ var help = [ " --xunit Use xUnit reporter", " --cover-plain Print plain coverage map if detected", " --cover-html Write coverage map to \"coverage.html\"", + " --cover-json Write unified coverage map to \"coverage.json\"", //" --no-color Don't use terminal colors", " --version Show version", " -h, --help You're staring at it" @@ -128,6 +129,10 @@ while (arg = argv.shift()) { options.coverage = true; _coverage = require('../lib/vows/coverage/report-html'); break; + case 'cover-json': + options.coverage = true; + _coverage = require('../lib/vows/coverage/report-json'); + break; case 'verbose': case 'v': options.verbose = true; @@ -239,8 +244,12 @@ if (! options.watch) { util.print(str.replace(/^\n\n/, '\n')); } }); - if (options.coverage === true && _$jscoverage !== undefined) { - _coverage.report(_$jscoverage); + try { + if (options.coverage === true && _$jscoverage !== undefined) { + _coverage.report(_$jscoverage); + } + } catch (err) { + // ignore the undefined jscoverage } if (process.stdout.write('')) { // Check if stdout is drained process.exit(status); From 3b9acaca741f2be6abdf215a4191a88870e0215d Mon Sep 17 00:00:00 2001 From: Jerry Sievert Date: Wed, 17 Aug 2011 20:21:52 -0700 Subject: [PATCH 20/28] add unified coverage maps, and fix issue when using coverage without instrumentation --- lib/vows/coverage/report-json.js | 54 ++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 lib/vows/coverage/report-json.js diff --git a/lib/vows/coverage/report-json.js b/lib/vows/coverage/report-json.js new file mode 100644 index 0000000..90fea22 --- /dev/null +++ b/lib/vows/coverage/report-json.js @@ -0,0 +1,54 @@ +var sys = require('sys'), + fs = require('fs'), + file = require('./file'); + +this.name = 'coverage-report-json'; + +this.report = function (coverageMap) { + var output = { + meta: { + "generator": "vowsjs", + "generated": new Date().toString(), + "instrumentation": "node-jscoverage", + "file-version": "1.0" + }, + files: [ ], + coverage: [ ] + }; + + + for (var filename in coverageMap) { + if (coverageMap.hasOwnProperty(filename)) { + var data = file.coverage(filename, coverageMap[filename]); + + var coverage = { + file: filename, + coverage: data.coverage.toFixed(2), + hits: data.hits, + misses: data.misses, + sloc: data.sloc, + source: { } + }; + + for (var i = 0; i < data.source.length; i++) { + coverage.source[i + 1] = { + line: data.source[i].line, + coverage: data.source[i].coverage + }; + } + + output.coverage.push(coverage); + + output.files.push(filename); + } + } + + try { + out = fs.openSync("coverage.json", "w"); + fs.writeSync(out, JSON.stringify(output)); + fs.close(out); + } catch (error) { + sys.print("Error: Unable to write to file coverage.json\n"); + return; + } +}; \ No newline at end of file From 0108f1f7a61f63c1b389bc4a3116f4fbcb798b85 Mon Sep 17 00:00:00 2001 From: Ben Taber Date: Wed, 17 Aug 2011 12:25:53 -0600 Subject: [PATCH 21/28] Allow arguments to flow through to callbacks in error conditions. https://gist.github.com/1152218 Topic callbacks should receive all arguments passed in error situations. Currently only the first argument is passed to the callback function regardless of how many arguments are sent. --- lib/vows.js | 2 +- lib/vows/context.js | 2 +- lib/vows/extras.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/vows.js b/lib/vows.js index 0e75cb9..44e5cf2 100644 --- a/lib/vows.js +++ b/lib/vows.js @@ -73,7 +73,7 @@ function addVow(vow) { }).on("error", function (err) { if (vow.callback.length >= 2 || !batch.suite.options.error) { - runTest([err], this.ctx); + runTest(arguments, this.ctx); } else { output('errored', { type: 'promise', error: err.stack || err.message || JSON.stringify(err) }); } diff --git a/lib/vows/context.js b/lib/vows/context.js index 7430747..426bc27 100644 --- a/lib/vows/context.js +++ b/lib/vows/context.js @@ -28,7 +28,7 @@ this.Context = function (vow, ctx, env) { if (typeof(e) === 'boolean' && args.length === 0) { that.emitter.emit.call(that.emitter, 'success', e); } else { - if (e) { that.emitter.emit.call(that.emitter, 'error', e) } + if (e) { that.emitter.emit.apply(that.emitter, ['error', e].concat(args)) } else { that.emitter.emit.apply(that.emitter, ['success'].concat(args)) } } }; diff --git a/lib/vows/extras.js b/lib/vows/extras.js index 3912c52..a90d7a5 100644 --- a/lib/vows/extras.js +++ b/lib/vows/extras.js @@ -13,7 +13,7 @@ this.prepare = function (obj, targets) { args.push(function (err /* [, data] */) { var args = Array.prototype.slice.call(arguments, 1); - if (err) { ee.emit('error', err) } + if (err) { ee.emit.apply(ee, ['error', err].concat(args)) } else { ee.emit.apply(ee, ['success'].concat(args)) } }); fun.apply(obj, args); From 954386c5d833847fb308b595d76156e0d65a92d9 Mon Sep 17 00:00:00 2001 From: indexzero Date: Sat, 20 Aug 2011 23:17:08 -0400 Subject: [PATCH 22/28] (test) Added tests for error pass thru --- test/vows-error-test.js | 51 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 test/vows-error-test.js diff --git a/test/vows-error-test.js b/test/vows-error-test.js new file mode 100644 index 0000000..79afaba --- /dev/null +++ b/test/vows-error-test.js @@ -0,0 +1,51 @@ +var path = require('path'), + events = require('events'), + assert = require('assert'), + fs = require('fs'), + vows = require('../lib/vows'); + +function doSomethingAsync(callback) { + var err = null; + var testValue = 'a'; + + process.nextTick(function() { + callback(err, testValue); + }); +} + +function doSomethingAsyncWithError(callback) { + var err = true; + var testValue = 'a'; + + process.nextTick(function() { + callback(err, testValue); + }); +} + + +vows.describe('vows/error').addBatch({ + 'Generate success response to async function': { + topic: function() { + doSomethingAsync(this.callback) + }, + 'Validate success': function(err, testValue) { + assert.ok(!err); + }, + 'Validate testValue': function(err, testValue) { + assert.equal(testValue, 'a'); + } + }, + + 'Generate error response to async function': { + topic: function() { + doSomethingAsyncWithError(this.callback) + }, + 'Validate error': function(err, testValue) { + assert.ok(err); + }, + 'Validate testValue': function(err, testValue) { + // This assertion fails. It shouldn't. + assert.equal(testValue, 'a'); + } + } +}).export(module) \ No newline at end of file From 3843409171c4718acc6c7837d1011aac83fcf2bd Mon Sep 17 00:00:00 2001 From: indexzero Date: Sat, 20 Aug 2011 23:17:39 -0400 Subject: [PATCH 23/28] (dist) Version bump. 0.5.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ee79e8..154f5cc 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,6 @@ "main" : "./lib/vows", "bin" : { "vows": "./bin/vows" }, "directories" : { "test": "./test", "bin": "./bin" }, - "version" : "0.5.10", + "version" : "0.5.11", "engines" : {"node": ">=0.2.6"} } From 485698d823823b52e7c65ffaf2228ab048360148 Mon Sep 17 00:00:00 2001 From: Alexis Sellier Date: Tue, 30 Aug 2011 19:51:14 -0300 Subject: [PATCH 24/28] (doc) add 'authors' section to README --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 58c8ff5..5ed8b00 100644 --- a/README.md +++ b/README.md @@ -37,3 +37,10 @@ documentation Head over to +authors +------- + +Alexis Sellier <>, Charlie Robbins, + +*...and many others* + From 398adde0b17b369ec85330f6b63e4440c5c1113a Mon Sep 17 00:00:00 2001 From: Henry Chan Date: Wed, 7 Sep 2011 02:45:33 -0700 Subject: [PATCH 25/28] merge to latest --- bin/vows | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/vows b/bin/vows index c155f53..f951c8d 100755 --- a/bin/vows +++ b/bin/vows @@ -272,7 +272,8 @@ if (! options.watch) { process.exit(status); }); } - }); + } + }); }; From 74da6e6ea596cd5d55dd88340ff104cd48b48dd5 Mon Sep 17 00:00:00 2001 From: Henry Chan Date: Wed, 7 Sep 2011 12:41:54 -0700 Subject: [PATCH 26/28] Add emma support --- bin/vows | 5 ++ lib/vows/coverage/report-emma.js | 147 +++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 lib/vows/coverage/report-emma.js diff --git a/bin/vows b/bin/vows index f951c8d..95d8035 100755 --- a/bin/vows +++ b/bin/vows @@ -60,6 +60,7 @@ var help = [ " --cover-plain Print plain coverage map if detected", " --cover-html Write coverage map to \"coverage.html\"", " --cover-json Write unified coverage map to \"coverage.json\"", + " --cover-emma Write unified coverage map to \"coverage.emma\"", //" --no-color Don't use terminal colors", " --version Show version", " -h, --help You're staring at it" @@ -141,6 +142,10 @@ while (arg = argv.shift()) { options.coverage = true; _coverage = require('../lib/vows/coverage/report-json'); break; + case 'cover-emma': + options.coverage = true; + _coverage = require('../lib/vows/coverage/report-emma'); + break; case 'verbose': case 'v': options.verbose = true; diff --git a/lib/vows/coverage/report-emma.js b/lib/vows/coverage/report-emma.js new file mode 100644 index 0000000..84adcc8 --- /dev/null +++ b/lib/vows/coverage/report-emma.js @@ -0,0 +1,147 @@ +var sys = require('sys'), + fs = require('fs'), + file = require('./file'); + +this.name = 'coverage-report-emma'; + +function xmlEnc(value) { + return !value ? value : String(value).replace(/&/g, "&") + .replace(/>/g, ">") + .replace(/'; +} + +function cdata(data) { + return ''; +} + +/** + * coverageMap coverage info for each file + */ +this.report = function (coverageMap) { + var output = { + meta: { + "generator": "vowsjs", + "generated": new Date().toString(), + "instrumentation": "node-jscoverage", + "file-version": "1.0" + }, + files: [ ], + coverage: [ ] + }; + + for (var filename in coverageMap) { + if (coverageMap.hasOwnProperty(filename)) { + // get data for the file + var data = file.coverage(filename, coverageMap[filename]); + + var coverage = { + file: filename, + coverage: data.coverage.toFixed(2), + hits: data.hits, + misses: data.misses, + sloc: data.sloc, + source: { } + }; + + for (var i = 0; i < data.source.length; i++) { + coverage.source[i + 1] = { + line: data.source[i].line, + coverage: data.source[i].coverage + }; + } + + output.coverage.push(coverage); + + output.files.push(filename); + } + } + var totalsloc = 0; + var totalhits = 0; + for ( var i = 0; i < output.coverage.length; i++) { + totalsloc += output.coverage[i].sloc; + totalhits += output.coverage[i].hits; + } + + var buffer = []; + buffer.push(tag('report', {}, false)); + buffer.push(tag('stats', {}, false)); + buffer.push(tag('packages', { value: 1 }, false)); + buffer.push(tag('classes', { value: 1 }, false)); + buffer.push(tag('srcfiles', { value: output.files.length }, false)); + buffer.push(tag('srclines', { value: totalsloc }, false)); + buffer.push(end('stats')); + + buffer.push(tag('data', {}, false)); + // all + buffer.push(tag('all', { name : 'all classes'}, false)); + buffer.push(tag('coverage', { type : 'class, %', value : '100% (1/1)'}, true) ); + buffer.push(tag('coverage', { type : 'method, %', value : '100% (1/1)'}, true) ); + buffer.push(tag('coverage', { type : 'block, %', value : '100% (1/1)'}, true) ); + buffer.push(tag('coverage', { type : 'line, %', value : (totalhits*1.0/totalsloc * 100.0) + '% ('+totalhits+'/'+totalsloc+')'}, true) ); + + // package + buffer.push(tag('package', {name: '{root}'}, false)); + buffer.push(tag('coverage', { type : 'class, %', value : '100% (1/1)'}, true) ); + buffer.push(tag('coverage', { type : 'method, %', value : '100% (1/1)'}, true) ); + buffer.push(tag('coverage', { type : 'block, %', value : '100% (1/1)'}, true) ); + buffer.push(tag('coverage', { type : 'line, %', value : (totalhits*1.0/totalsloc * 100.0) + '% ('+totalhits+'/'+totalsloc+')'}, true) ); + + for ( var i = 0; i < output.coverage.length; i++) { + var sloc = output.coverage[i].sloc; + var hits = output.coverage[i].hits; + var file = output.coverage[i].file; + + buffer.push(tag('srcfile', { name : file }, false) ); + buffer.push(tag('coverage', { type : 'class, %', value : '100% (1/1)'}, true) ); + buffer.push(tag('coverage', { type : 'method, %', value : '100% (1/1)'}, true) ); + buffer.push(tag('coverage', { type : 'block, %', value : '100% (1/1)'}, true) ); + buffer.push(tag('coverage', { type : 'line, %', value : (hits*1.0/sloc * 100.0) + '% ('+hits+'/'+sloc+')'}, true) ); + buffer.push(end('srcfile')); + } + + buffer.push(end('package')); + + buffer.push(end('all')); + buffer.push(end('data')); + + + buffer.push(end('report')); + + buffer.unshift(''); + + try { + out = fs.openSync("coverage.emma", "w"); + fs.writeSync(out, buffer.join('\n')); + fs.close(out); + } catch (error) { + sys.print("Error: Unable to write to file coverage.emma\n"); + return; + } +}; \ No newline at end of file From 0c71eb942cdd44c40b0fd582740706454517b1de Mon Sep 17 00:00:00 2001 From: Henry Chan Date: Wed, 7 Sep 2011 12:57:41 -0700 Subject: [PATCH 27/28] Add emma support --- lib/vows/coverage/report-emma.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/vows/coverage/report-emma.js b/lib/vows/coverage/report-emma.js index 84adcc8..2729252 100644 --- a/lib/vows/coverage/report-emma.js +++ b/lib/vows/coverage/report-emma.js @@ -104,25 +104,25 @@ this.report = function (coverageMap) { buffer.push(tag('coverage', { type : 'class, %', value : '100% (1/1)'}, true) ); buffer.push(tag('coverage', { type : 'method, %', value : '100% (1/1)'}, true) ); buffer.push(tag('coverage', { type : 'block, %', value : '100% (1/1)'}, true) ); - buffer.push(tag('coverage', { type : 'line, %', value : (totalhits*1.0/totalsloc * 100.0) + '% ('+totalhits+'/'+totalsloc+')'}, true) ); + buffer.push(tag('coverage', { type : 'line, %', value : (totalhits*1.0/totalsloc * 100.0).toFixed(2) + '% ('+totalhits+'/'+totalsloc+')'}, true) ); // package buffer.push(tag('package', {name: '{root}'}, false)); buffer.push(tag('coverage', { type : 'class, %', value : '100% (1/1)'}, true) ); buffer.push(tag('coverage', { type : 'method, %', value : '100% (1/1)'}, true) ); buffer.push(tag('coverage', { type : 'block, %', value : '100% (1/1)'}, true) ); - buffer.push(tag('coverage', { type : 'line, %', value : (totalhits*1.0/totalsloc * 100.0) + '% ('+totalhits+'/'+totalsloc+')'}, true) ); + buffer.push(tag('coverage', { type : 'line, %', value : (totalhits*1.0/totalsloc * 100.0).toFixed(2) + '% ('+totalhits+'/'+totalsloc+')'}, true) ); for ( var i = 0; i < output.coverage.length; i++) { var sloc = output.coverage[i].sloc; var hits = output.coverage[i].hits; - var file = output.coverage[i].file; + var filename = output.coverage[i].file; - buffer.push(tag('srcfile', { name : file }, false) ); + buffer.push(tag('srcfile', { name : filename }, false) ); buffer.push(tag('coverage', { type : 'class, %', value : '100% (1/1)'}, true) ); buffer.push(tag('coverage', { type : 'method, %', value : '100% (1/1)'}, true) ); buffer.push(tag('coverage', { type : 'block, %', value : '100% (1/1)'}, true) ); - buffer.push(tag('coverage', { type : 'line, %', value : (hits*1.0/sloc * 100.0) + '% ('+hits+'/'+sloc+')'}, true) ); + buffer.push(tag('coverage', { type : 'line, %', value : (hits*1.0/sloc * 100.0).toFixed(2) + '% ('+hits+'/'+sloc+')'}, true) ); buffer.push(end('srcfile')); } From e9094fe9af107ce4506b8a5a448840054b916ae6 Mon Sep 17 00:00:00 2001 From: Henry Chan Date: Wed, 7 Sep 2011 13:39:04 -0700 Subject: [PATCH 28/28] Add emma support --- lib/vows/coverage/report-emma.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/vows/coverage/report-emma.js b/lib/vows/coverage/report-emma.js index 2729252..01c09fb 100644 --- a/lib/vows/coverage/report-emma.js +++ b/lib/vows/coverage/report-emma.js @@ -92,10 +92,10 @@ this.report = function (coverageMap) { var buffer = []; buffer.push(tag('report', {}, false)); buffer.push(tag('stats', {}, false)); - buffer.push(tag('packages', { value: 1 }, false)); - buffer.push(tag('classes', { value: 1 }, false)); - buffer.push(tag('srcfiles', { value: output.files.length }, false)); - buffer.push(tag('srclines', { value: totalsloc }, false)); + buffer.push(tag('packages', { value: 1 }, true)); + buffer.push(tag('classes', { value: 1 }, true)); + buffer.push(tag('srcfiles', { value: output.files.length }, true)); + buffer.push(tag('srclines', { value: totalsloc }, true)); buffer.push(end('stats')); buffer.push(tag('data', {}, false));