new reporter, attempt 1

This commit is contained in:
John Bintz 2011-05-12 17:02:11 -04:00
parent 97ba0b329b
commit 16a7507f55
6 changed files with 214 additions and 50 deletions

View File

@ -63,6 +63,7 @@ end
puts "Running Jasmine specs..." puts "Running Jasmine specs..."
files = %w{jasmine jasmine-html}.collect { |name| File.join(Jasmine.root, "lib/#{name}.js") } files = %w{jasmine jasmine-html}.collect { |name| File.join(Jasmine.root, "lib/#{name}.js") }
files << File.join(gem_dir, 'jasmine/jasmine.headless-reporter.js')
files += [ [ 'src_files', 'src_dir' ], [ 'stylesheets', 'src_dir' ], [ 'helpers', 'spec_dir' ], [ 'spec_files', 'spec_dir' ] ].collect do |searches, root| files += [ [ 'src_files', 'src_dir' ], [ 'stylesheets', 'src_dir' ], [ 'helpers', 'spec_dir' ], [ 'spec_files', 'spec_dir' ] ].collect do |searches, root|
data[searches] ||= DEFAULTS[searches] data[searches] ||= DEFAULTS[searches]

18
coffee.watchr Normal file
View File

@ -0,0 +1,18 @@
require 'coffee-script'
FILE = 'jasmine/jasmine.headless-reporter.coffee' if !self.class.const_defined?(:FILE)
TARGET = FILE.gsub('.coffee', '.js') if !self.class.const_defined?(:TARGET)
watch(FILE) { coffee }
def coffee
begin
File.open(TARGET, 'w') { |fh| fh.print CoffeeScript.compile File.open(FILE) }
puts "Wrote #{TARGET}"
rescue Exception => e
puts e.message
end
end
coffee

View File

@ -66,7 +66,11 @@ public:
void setColors(bool colors); void setColors(bool colors);
public slots: public slots:
void log(const QString &msg); void log(const QString &msg);
void specLog(int indent, const QString &msg, const QString &clazz); void specPassed();
void specFailed();
void printName(const QString &name);
void printResult(const QString &result);
void finishSuite(const QString &duration, const QString &total, const QString& failed);
private slots: private slots:
void watch(bool ok); void watch(bool ok);
void errorLog(const QString &msg, int lineNumber, const QString &sourceID); void errorLog(const QString &msg, int lineNumber, const QString &sourceID);
@ -81,6 +85,8 @@ private:
bool hasErrors; bool hasErrors;
bool usedConsole; bool usedConsole;
bool showColors; bool showColors;
bool isFinished;
bool didFail;
void red(); void red();
void green(); void green();
@ -94,6 +100,8 @@ HeadlessSpecRunner::HeadlessSpecRunner()
, hasErrors(false) , hasErrors(false)
, usedConsole(false) , usedConsole(false)
, showColors(false) , showColors(false)
, isFinished(false)
, didFail(false)
{ {
m_page.settings()->enablePersistentStorage(); m_page.settings()->enablePersistentStorage();
connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool))); connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool)));
@ -104,7 +112,7 @@ HeadlessSpecRunner::HeadlessSpecRunner()
void HeadlessSpecRunner::load(const QString &spec) void HeadlessSpecRunner::load(const QString &spec)
{ {
m_ticker.stop(); m_ticker.stop();
m_page.mainFrame()->addToJavaScriptWindowObject("debug", this); m_page.mainFrame()->addToJavaScriptWindowObject("JHW", this);
m_page.mainFrame()->load(spec); m_page.mainFrame()->load(spec);
m_page.setPreferredContentsSize(QSize(1024, 600)); m_page.setPreferredContentsSize(QSize(1024, 600));
} }
@ -152,6 +160,23 @@ void HeadlessSpecRunner::clear()
if (showColors) std::cout << "\033[m"; if (showColors) std::cout << "\033[m";
} }
void HeadlessSpecRunner::specPassed()
{
green();
std::cout << '.';
clear();
fflush(stdout);
}
void HeadlessSpecRunner::specFailed()
{
didFail = true;
red();
std::cout << 'F';
clear();
fflush(stdout);
}
void HeadlessSpecRunner::errorLog(const QString &msg, int lineNumber, const QString &sourceID) void HeadlessSpecRunner::errorLog(const QString &msg, int lineNumber, const QString &sourceID)
{ {
red(); red();
@ -183,33 +208,37 @@ void HeadlessSpecRunner::log(const QString &msg)
std::cout << std::endl; std::cout << std::endl;
} }
void HeadlessSpecRunner::specLog(int indent, const QString &msg, const QString &clazz) void HeadlessSpecRunner::printName(const QString &name)
{ {
for (int i = 0; i < indent; ++i) std::cout << std::endl << std::endl;
std::cout << " ";
if ( clazz.endsWith("fail") ) {
red(); red();
} else { std::cout << qPrintable(name) << std::endl;
yellow();
}
std::cout << qPrintable(msg);
clear(); clear();
std::cout << std::endl;
} }
#define DUMP_MSG "(function(n, i) { \ void HeadlessSpecRunner::printResult(const QString &result)
if (n.toString() === '[object NodeList]') { \ {
for (var c = 0; c < n.length; ++c) arguments.callee(n[c], i); return \ red();
}\ std::cout << " " << qPrintable(result) << std::endl;
if (n.className === 'description' || n.className == 'resultMessage fail') {\ clear();
debug.specLog(i, n.textContent, n.className);\ }
}\
var e = n.firstElementChild;\ void HeadlessSpecRunner::finishSuite(const QString &duration, const QString &total, const QString& failed)
while (e) {\ {
arguments.callee(e, i + 1); e = e.nextElementSibling; \ std::cout << std::endl;
}\ if (didFail) {
n.className = '';\ red();
})(document.getElementsByClassName('suite failed'), 0);" std::cout << "FAIL: ";
} else {
green();
std::cout << "PASS: ";
}
std::cout << qPrintable(total) << " tests, " << qPrintable(failed) << " failures, " << qPrintable(duration) << " secs." << std::endl;
clear();
isFinished = true;
}
void HeadlessSpecRunner::timerEvent(QTimerEvent *event) void HeadlessSpecRunner::timerEvent(QTimerEvent *event)
{ {
@ -222,28 +251,17 @@ void HeadlessSpecRunner::timerEvent(QTimerEvent *event)
QApplication::instance()->exit(1); QApplication::instance()->exit(1);
if (!hasErrors) { if (!hasErrors) {
if (!hasElement(".jasmine_reporter") && !hasElement(".runner.running")) if (isFinished) {
return; int exitCode = 0;
if (didFail) {
if (hasElement(".runner.passed")) { exitCode = 1;
QWebElement desc = m_page.mainFrame()->findFirstElement(".description"); } else {
green(); if (usedConsole) {
std::cout << "PASS: " << qPrintable(desc.toPlainText()); exitCode = 2;
clear(); }
std::cout << std::endl;
QApplication::instance()->exit(usedConsole ? 2 : 0);
return;
} }
if (hasElement(".runner.failed")) { QApplication::instance()->exit(exitCode);
QWebElement desc = m_page.mainFrame()->findFirstElement(".description");
red();
std::cout << "FAIL: " << qPrintable(desc.toPlainText());
clear();
std::cout << std::endl;
m_page.mainFrame()->evaluateJavaScript(DUMP_MSG);
QApplication::instance()->exit(1);
return;
} }
if (m_runs > 30) { if (m_runs > 30) {

View File

@ -0,0 +1,45 @@
if !jasmine?
throw new Exception("jasmine not laoded!")
class HeadlessReporterResult
constructor: (name) ->
@name = name
@results = []
print: ->
JHW.printName(@name)
for result in @results
do (result) =>
JHW.printResult(result)
class jasmine.HeadlessReporter
constructor: ->
@results = []
@failedCount = 0
@totalDuration = 0.0
@length = 0
reportRunnerResults: (runner) ->
for result in @results
do (result) =>
result.print()
JHW.finishSuite(@totalDuration, @length, @failedCount)
reportRunnerStarting: (runner) ->
reportSpecResults: (spec) ->
if spec.results().passed()
JHW.specPassed()
else
JHW.specFailed()
failureResult = new HeadlessReporterResult(spec.getFullName())
for result in spec.results().getItems()
do (result) =>
if result.type == 'expect' and !result.passed_
@failedCount += 1
failureResult.results.push(result.message)
@results.push(failureResult)
reportSpecStarting: (spec) ->
# something here
reportSuiteResults: (suite) ->
suite.startTime ?= new Date()
@totalDuration += (new Date() - suite.startTime) / 1000.0;
@length += suite.specs().length

View File

@ -0,0 +1,81 @@
(function() {
var HeadlessReporterResult;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
if (!(typeof jasmine !== "undefined" && jasmine !== null)) {
throw new Exception("jasmine not laoded!");
}
HeadlessReporterResult = (function() {
function HeadlessReporterResult(name) {
this.name = name;
this.results = [];
}
HeadlessReporterResult.prototype.print = function() {
var result, _i, _len, _ref, _results;
JHW.printName(this.name);
_ref = this.results;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
result = _ref[_i];
_results.push(__bind(function(result) {
return JHW.printResult(result);
}, this)(result));
}
return _results;
};
return HeadlessReporterResult;
})();
jasmine.HeadlessReporter = (function() {
function HeadlessReporter() {
this.results = [];
this.failedCount = 0;
this.totalDuration = 0.0;
this.length = 0;
}
HeadlessReporter.prototype.reportRunnerResults = function(runner) {
var result, _fn, _i, _len, _ref;
_ref = this.results;
_fn = __bind(function(result) {
return result.print();
}, this);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
result = _ref[_i];
_fn(result);
}
return JHW.finishSuite(this.totalDuration, this.length, this.failedCount);
};
HeadlessReporter.prototype.reportRunnerStarting = function(runner) {};
HeadlessReporter.prototype.reportSpecResults = function(spec) {
var failureResult, result, _fn, _i, _len, _ref;
if (spec.results().passed()) {
return JHW.specPassed();
} else {
JHW.specFailed();
failureResult = new HeadlessReporterResult(spec.getFullName());
_ref = spec.results().getItems();
_fn = __bind(function(result) {
if (result.type === 'expect' && !result.passed_) {
this.failedCount += 1;
return failureResult.results.push(result.message);
}
}, this);
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
result = _ref[_i];
_fn(result);
}
return this.results.push(failureResult);
}
};
HeadlessReporter.prototype.reportSpecStarting = function(spec) {};
HeadlessReporter.prototype.reportSuiteResults = function(suite) {
var _ref;
if ((_ref = suite.startTime) != null) {
_ref;
} else {
suite.startTime = new Date();
};
this.totalDuration += (new Date() - suite.startTime) / 1000.0;
return this.length += suite.specs().length;
};
return HeadlessReporter;
})();
}).call(this);

View File

@ -35,14 +35,15 @@ module Jasmine
<head> <head>
<title>Jasmine Test Runner</title> <title>Jasmine Test Runner</title>
<script type="text/javascript"> <script type="text/javascript">
window.console = { log: function(data) { debug.log(JSON.stringify(data)); } }; window.console = { log: function(data) { JHW.log(JSON.stringify(data)); } };
</script> </script>
#{files.join("\n")} #{files.join("\n")}
</head> </head>
<body> <body>
<script type="text/javascript"> <script type="text/javascript">
jasmine.getEnv().addReporter(new jasmine.TrivialReporter()); //jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
jasmine.getEnv().addReporter(new jasmine.HeadlessReporter());
jasmine.getEnv().execute(); jasmine.getEnv().execute();
</script> </script>