Permalink
Browse files

Merge pull request #5 from gtramontina/master

An XUnit formatter implementation
  • Loading branch information...
2 parents 4f1c767 + f0188fe commit 2f4415300cb01d4b2e97adc5c9d1c23f1f3c029a @marcinbunsch marcinbunsch committed Jun 23, 2011
@@ -0,0 +1,95 @@
+var sys = require('sys');
+
+exports.formatter = {
+ specStart: function(spec) {
+ spec.duration = Number(new Date);
+ },
+
+ reportSpecResults: function(spec) {
+ spec.duration = (Number(new Date) - spec.duration);
+ },
+
+ finish: function(result, runner) {
+ sys.puts(tag('testsuite', {
+ name: 'Jasmine Tests',
+ tests: result.total,
+ failures: result.failed,
+ skip: result.pending,
+ timestamp: (new Date).toUTCString(),
+ time: result.duration / 1000
+ }, false));
+ runner.suites().forEach(handleSuite);
+ sys.puts(end('testsuite'));
+ }
+};
+
+function handleSuite(suite) {
+ suite.specs().forEach(handleSpec);
+}
+
+function handleSpec(spec) {
+ var r = extractResult(spec);
+ var attributes = {
+ classname: spec.suite.getFullName(),
+ name: spec.description,
+ time: spec.duration / 1000
+ };
+
+ var reason = r.pending? pendingSpecTag(spec) : r.fail? failedSpecTag(spec) : '';
+ var specTag = reason?
+ tag('testcase', attributes, false, reason) :
+ tag('testcase', attributes, true)
+
+ sys.puts(specTag);
+}
+
+function pendingSpecTag(spec) {
+ return tag('skipped', { message: encode(spec.results().getItems()[0].trace.message) }, true);
+}
+
+function failedSpecTag(spec) {
+ var reason = spec.results().getItems()[0];
+ var attributes = { message: encode(reason.message) };
+ reason.trace.type && (attributes.type = reason.trace.type)
+ return tag('failure', attributes, false, cdata(reason.trace.stack));
+}
+
+function extractResult(spec) {
+ var pending = false
+ spec.results().getItems().forEach(function(item) {
+ pending = item.pending || false;
+ });
+ return { pending: pending, fail: spec.results().failedCount > 0 };
+}
+
+function encode(value) {
+ return !value ? value :
+ String(value)
+ .replace(/&/g, '&')
+ .replace(/>/g, '>')
+ .replace(/</g, '&lt;')
+ .replace(/"/g, '&quot;')
+ .replace(/\u001b\[\d{1,2}m/g, '');
+}
+
+function tag(name, attribs, single, content) {
+ var tag;
+ var end = single ? ' />' : '>'
+ var strAttr = [];
+ for (var attr in attribs) {
+ attribs.hasOwnProperty(attr) && strAttr.push(attr + '="' + encode(attribs[attr]) + '"');
+ }
+
+ tag = '<' + name + (strAttr.length? ' ' + strAttr.join(' ') : '' ) + end
+ tag = content? (tag + content + '</' + name + end) : tag
+ return tag;
+}
+
+function end(name) {
+ return '</' + name + '>';
+}
+
+function cdata(data) {
+ return '<![CDATA[' + encode(data) + ']]>';
+}
+
@@ -3,7 +3,7 @@ describe('jessie.finder', function() {
var finder = new (require('jessie/finder').finder)()
it("should find files if only dir is specified", function() {
- finder.find(['spec']).length.should_be(12)
+ finder.find(['spec']).length.should_be(13)
})
it("should find coffee script files", function() {
@@ -23,15 +23,16 @@ describe('jessie.finder', function() {
})
it('leaves non-relative paths alone', function() {
- finder.find([path.resolve('spec')]).length.should_be(12)
+ finder.find([path.resolve('spec')]).length.should_be(13)
});
it("should find files if only files are specified", function() {
finder.find(['spec/jessie/finder_spec.js', 'spec/jessie/sugar_spec.js']).length.should_be(2)
})
it("should find files if both dirs and files are specified", function() {
- finder.find(['spec/jessie/formatters', 'spec/jessie/finder_spec.js']).length.should_be(3)
+ finder.find(['spec/jessie/formatters', 'spec/jessie/finder_spec.js']).length.should_be(4)
})
})
+
@@ -1,10 +1,10 @@
describe('formatters', function() {
var reporter = new (require('jessie/reporter')).reporter('nested')
-
+
describe('nested formatter', function() {
-
+
describe('single spec', function() {
-
+
it("should use the green spec description to render a successful spec", function() {
capture = require('helpers/stdout').capture(function() {
reporter.formatter.spec({fail: false}, {description: 'my spec'})
@@ -23,7 +23,7 @@ describe('formatters', function() {
reporter.formatter.depth = original_depth
})
- it("should use the yello spec description to render a pending spec", function() {
+ it("should use the yellow spec description to render a pending spec", function() {
var original_depth = reporter.formatter.depth
capture = require('helpers/stdout').capture(function() {
reporter.formatter.spec({pending: true}, {description: 'my spec'})
@@ -32,7 +32,7 @@ describe('formatters', function() {
capture.output().should_match(/\033\[33m/) // yellow
reporter.formatter.depth = original_depth
})
-
+
it("should render the spec with appropriate spacing on the left", function() {
var original_depth = reporter.formatter.depth
reporter.formatter.depth = 1
@@ -49,25 +49,25 @@ describe('formatters', function() {
capture.output().should_match(/^ {4}/)
reporter.formatter.depth = original_depth
})
-
+
})
-
+
describe('single suite', function() {
it("should render the suite name", function() {
var original_depth = reporter.formatter.depth
-
+
capture = require('helpers/stdout').capture(function() {
reporter.formatter.suiteStart({description: 'my suite'})
})
capture.output().should_match('my suite')
reporter.formatter.depth = original_depth
-
- })
+
+ })
it("should render the suite name with appropriate spacing on the left", function() {
var original_depth = reporter.formatter.depth
-
+
reporter.formatter.depth = 1
capture = require('helpers/stdout').capture(function() {
reporter.formatter.suiteStart({description: 'my suite'})
@@ -78,7 +78,7 @@ describe('formatters', function() {
reporter.formatter.depth.should_be(2)
reporter.formatter.suite()
reporter.formatter.depth.should_be(1)
-
+
reporter.formatter.depth = 2
capture = require('helpers/stdout').capture(function() {
reporter.formatter.suiteStart({description: 'my suite'})
@@ -91,39 +91,39 @@ describe('formatters', function() {
it("should increase depth when starting a suite", function() {
var original_depth = reporter.formatter.depth
-
+
reporter.formatter.depth = 1
capture = require('helpers/stdout').capture(function() {
reporter.formatter.suiteStart({description: 'my suite'})
})
-
+
reporter.formatter.depth.should_be(2)
reporter.formatter.depth = original_depth
-
+
})
-
+
it("should decrease depth when ending a suite", function() {
var original_depth = reporter.formatter.depth
-
+
reporter.formatter.depth = 2
reporter.formatter.suite()
reporter.formatter.depth.should_be(1)
-
+
reporter.formatter.depth = original_depth
-
+
})
-
+
})
-
+
describe('summary', function() {
var result = {duration: 15, failed: 1, total: 2}
result.failures= [{
description: 'it should print errors',
message: 'Expected A to be B',
stacktrace: ['Expected A to be B', 'file.js:23:2', 'another_file.js:30:11']
}]
-
+
it("should properly render a summary", function() {
capture = require('helpers/stdout').capture(function() {
reporter.formatter.finish(result)
@@ -135,17 +135,17 @@ describe('formatters', function() {
capture.output().should_match('Expected A to be B')
capture.output().should_match('file.js:23:2')
capture.output().should_match('another_file.js:30:11')
-
+
})
-
+
it("should properly render a summary with pending and failing specs", function() {
var result = {duration: 15, failed: 1, total: 3, pending: 1}
result.failures= [{
description: 'it should print errors',
message: 'Expected A to be B',
stacktrace: ['Expected A to be B', 'file.js:23:2', 'another_file.js:30:11']
}]
-
+
capture = require('helpers/stdout').capture(function() {
reporter.formatter.finish(result)
})
@@ -156,7 +156,7 @@ describe('formatters', function() {
capture.output().should_match('it should print errors')
capture.output().should_match('Expected A to be B')
capture.output().should_match('file.js:23:2')
- capture.output().should_match('another_file.js:30:11')
+ capture.output().should_match('another_file.js:30:11')
})
it("should properly render a summary with pending and failing specs", function() {
@@ -166,7 +166,7 @@ describe('formatters', function() {
message: 'Expected A to be B',
stacktrace: ['Expected A to be B', 'file.js:23:2', 'another_file.js:30:11']
}]
-
+
capture = require('helpers/stdout').capture(function() {
reporter.formatter.finish(result)
})
@@ -177,11 +177,12 @@ describe('formatters', function() {
capture.output().should_match('it should print errors')
capture.output().should_match('Expected A to be B')
capture.output().should_match('file.js:23:2')
- capture.output().should_match('another_file.js:30:11')
+ capture.output().should_match('another_file.js:30:11')
})
-
-
+
+
})
})
-
-})
+
+})
+
Oops, something went wrong.

0 comments on commit 2f44153

Please sign in to comment.