diff --git a/Gemfile b/Gemfile index bfcf6b6..d6151f4 100644 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,6 @@ gem 'guard-coffeescript' gem 'growl' gem 'rake', '0.8.7' gem 'mocha', '0.9.12' -gem 'guard-jasmine-headless-webkit' +gem 'guard-jasmine-headless-webkit', :git => 'git://github.com/johnbintz/guard-jasmine-headless-webkit.git' gem 'facter' diff --git a/ext/jasmine-webkit-specrunner/Runner.cpp b/ext/jasmine-webkit-specrunner/Runner.cpp index a5cd6a7..6c64ad3 100644 --- a/ext/jasmine-webkit-specrunner/Runner.cpp +++ b/ext/jasmine-webkit-specrunner/Runner.cpp @@ -14,8 +14,12 @@ Runner::Runner() : QObject() , hasErrors(false) , usedConsole(false) , isFinished(false) - , didFail(false) { + , didFail(false) + { m_page.settings()->enablePersistentStorage(); + m_ticker.setInterval(TIMER_TICK); + + connect(&m_ticker, SIGNAL(timeout()), this, SLOT(timerEvent())); connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool))); connect(&m_page, SIGNAL(consoleLog(QString, int, QString)), this, SLOT(errorLog(QString, int, QString))); connect(&m_page, SIGNAL(internalLog(QString, QString)), this, SLOT(internalLog(QString, QString))); @@ -32,6 +36,8 @@ void Runner::go() m_page.setPreferredContentsSize(QSize(1024, 600)); addJHW(); loadSpec(); + + m_ticker.start(); } void Runner::addJHW() { @@ -41,7 +47,7 @@ void Runner::addJHW() void Runner::loadSpec() { m_page.mainFrame()->load(runnerFiles.dequeue()); - m_ticker.start(200, this); + m_ticker.start(); } void Runner::watch(bool ok) @@ -54,7 +60,6 @@ void Runner::watch(bool ok) return; } - m_ticker.start(200, this); } bool Runner::hasElement(const char *select) @@ -74,6 +79,14 @@ bool Runner::hasError() { return hasErrors; } +void Runner::timerPause() { + m_ticker.stop(); +} + +void Runner::timerDone() { + m_ticker.start(); +} + void Runner::specPassed(const QString &specDetail) { consoleOutput.passed(specDetail); reportFileOutput.passed(specDetail); @@ -94,7 +107,7 @@ void Runner::errorLog(const QString &msg, int lineNumber, const QString &sourceI hasErrors = true; m_runs = 0; - m_ticker.start(200, this); + m_ticker.start(); } void Runner::internalLog(const QString ¬e, const QString &msg) { @@ -155,13 +168,10 @@ void Runner::finishSuite(const QString &duration, const QString &total, const QS isFinished = true; } -void Runner::timerEvent(QTimerEvent *event) +void Runner::timerEvent() { ++m_runs; - if (event->timerId() != m_ticker.timerId()) - return; - if (hasErrors && m_runs > 2) QApplication::instance()->exit(1); @@ -193,7 +203,7 @@ void Runner::timerEvent(QTimerEvent *event) } } - if (m_runs > 30) { + if (m_runs > MAX_LOOPS) { std::cout << "WARNING: too many runs and the test is still not finished!" << std::endl; QApplication::instance()->exit(1); } diff --git a/ext/jasmine-webkit-specrunner/Runner.h b/ext/jasmine-webkit-specrunner/Runner.h index 8642fdb..96170b9 100644 --- a/ext/jasmine-webkit-specrunner/Runner.h +++ b/ext/jasmine-webkit-specrunner/Runner.h @@ -18,6 +18,8 @@ using namespace std; class Runner: public QObject { Q_OBJECT public: + enum { TIMER_TICK = 200, MAX_LOOPS = 25 }; + Runner(); void setColors(bool colors); void reportFile(const QString &file); @@ -27,6 +29,8 @@ class Runner: public QObject { void log(const QString &msg); bool hasError(); void leavePageAttempt(const QString &msg); + void timerPause(); + void timerDone(); void specPassed(const QString &specDetail); void specFailed(const QString &specDetail); void printName(const QString &name); @@ -37,12 +41,12 @@ class Runner: public QObject { void errorLog(const QString &msg, int lineNumber, const QString &sourceID); void internalLog(const QString ¬e, const QString &msg); void addJHW(); + void timerEvent(); protected: bool hasElement(const char *select); - void timerEvent(QTimerEvent *event); private: Page m_page; - QBasicTimer m_ticker; + QTimer m_ticker; int m_runs; bool hasErrors; bool usedConsole; diff --git a/jasmine/jasmine.headless-reporter.coffee b/jasmine/jasmine.headless-reporter.coffee index f1e8d31..59c56f0 100644 --- a/jasmine/jasmine.headless-reporter.coffee +++ b/jasmine/jasmine.headless-reporter.coffee @@ -1,6 +1,40 @@ if !jasmine? throw new Error("jasmine not laoded!") +# Jasmine extensions +getSplitName = (parts) -> + parts.push(String(@description).replace(/[\n\r]/g, ' ')) + parts + +jasmine.Suite.prototype.getSuiteSplitName = -> + this.getSplitName(if @parentSuite then @parentSuite.getSuiteSplitName() else []) + +jasmine.Spec.prototype.getSpecSplitName = -> + this.getSplitName(@suite.getSuiteSplitName()) + +jasmine.Suite.prototype.getSplitName = getSplitName +jasmine.Spec.prototype.getSplitName = getSplitName + +jasmine.Spec.prototype.getJHWSpecInformation = -> + parts = this.getSpecSplitName() + specLineInfo = HeadlessReporterResult.findSpecLine(parts) + parts.push("#{specLineInfo.file}:#{specLineInfo.lineNumber}") + parts.join("||") + +if !jasmine.WaitsBlock.prototype._execute + jasmine.WaitsBlock.prototype._execute = jasmine.WaitsBlock.prototype.execute + jasmine.WaitsForBlock.prototype._execute = jasmine.WaitsForBlock.prototype.execute + + pauseAndRun = (onComplete) -> + JHW.timerPause() + this._execute -> + JHW.timerDone() + onComplete() + + jasmine.WaitsBlock.prototype.execute = pauseAndRun + jasmine.WaitsForBlock.prototype.execute = pauseAndRun + +# Try to get the line number of a failed spec class window.HeadlessReporterResult constructor: (@name, @splitName) -> @results = [] @@ -38,22 +72,7 @@ class window.HeadlessReporterResult bestChoice -jasmine.Suite.prototype.getSuiteSplitName = -> - parts = if @parentSuite then @parentSuite.getSuiteSplitName() else [] - parts.push(String(@description).replace(/[\n\r]/g, ' ')) - parts - -jasmine.Spec.prototype.getSpecSplitName = -> - parts = @suite.getSuiteSplitName() - parts.push(String(@description).replace(/[\n\r]/g, ' ')) - parts - -jasmine.Spec.prototype.getJHWSpecInformation = -> - parts = this.getSpecSplitName() - specLineInfo = HeadlessReporterResult.findSpecLine(parts) - parts.push("#{specLineInfo.file}:#{specLineInfo.lineNumber}") - parts.join("||") - +# The reporter itself. class jasmine.HeadlessReporter constructor: (@callback = null) -> @results = [] diff --git a/jasmine/jasmine.headless-reporter.js b/jasmine/jasmine.headless-reporter.js index 003924c..17e018c 100644 --- a/jasmine/jasmine.headless-reporter.js +++ b/jasmine/jasmine.headless-reporter.js @@ -1,7 +1,40 @@ (function() { + var getSplitName, pauseAndRun; if (!(typeof jasmine !== "undefined" && jasmine !== null)) { throw new Error("jasmine not laoded!"); } + getSplitName = function(parts) { + parts.push(String(this.description).replace(/[\n\r]/g, ' ')); + return parts; + }; + jasmine.Suite.prototype.getSuiteSplitName = function() { + return this.getSplitName(this.parentSuite ? this.parentSuite.getSuiteSplitName() : []); + }; + jasmine.Spec.prototype.getSpecSplitName = function() { + return this.getSplitName(this.suite.getSuiteSplitName()); + }; + jasmine.Suite.prototype.getSplitName = getSplitName; + jasmine.Spec.prototype.getSplitName = getSplitName; + jasmine.Spec.prototype.getJHWSpecInformation = function() { + var parts, specLineInfo; + parts = this.getSpecSplitName(); + specLineInfo = HeadlessReporterResult.findSpecLine(parts); + parts.push("" + specLineInfo.file + ":" + specLineInfo.lineNumber); + return parts.join("||"); + }; + if (!jasmine.WaitsBlock.prototype._execute) { + jasmine.WaitsBlock.prototype._execute = jasmine.WaitsBlock.prototype.execute; + jasmine.WaitsForBlock.prototype._execute = jasmine.WaitsForBlock.prototype.execute; + pauseAndRun = function(onComplete) { + JHW.timerPause(); + return this._execute(function() { + JHW.timerDone(); + return onComplete(); + }); + }; + jasmine.WaitsBlock.prototype.execute = pauseAndRun; + jasmine.WaitsForBlock.prototype.execute = pauseAndRun; + } window.HeadlessReporterResult = (function() { function HeadlessReporterResult(name, splitName) { this.name = name; @@ -67,25 +100,6 @@ }; return HeadlessReporterResult; })(); - jasmine.Suite.prototype.getSuiteSplitName = function() { - var parts; - parts = this.parentSuite ? this.parentSuite.getSuiteSplitName() : []; - parts.push(String(this.description).replace(/[\n\r]/g, ' ')); - return parts; - }; - jasmine.Spec.prototype.getSpecSplitName = function() { - var parts; - parts = this.suite.getSuiteSplitName(); - parts.push(String(this.description).replace(/[\n\r]/g, ' ')); - return parts; - }; - jasmine.Spec.prototype.getJHWSpecInformation = function() { - var parts, specLineInfo; - parts = this.getSpecSplitName(); - specLineInfo = HeadlessReporterResult.findSpecLine(parts); - parts.push("" + specLineInfo.file + ":" + specLineInfo.lineNumber); - return parts.join("||"); - }; jasmine.HeadlessReporter = (function() { function HeadlessReporter(callback) { this.callback = callback != null ? callback : null; diff --git a/spec/javascripts/jasmine.headless-reporter_spec.coffee b/spec/javascripts/jasmine.headless-reporter_spec.coffee index aa623e2..bd70b45 100644 --- a/spec/javascripts/jasmine.headless-reporter_spec.coffee +++ b/spec/javascripts/jasmine.headless-reporter_spec.coffee @@ -61,3 +61,29 @@ describe 'jasmine.Spec.prototype.getSuiteSplitName', -> spec.description = 1 expect(spec.getSpecSplitName()).toEqual([ "1" ]) +describe 'jasmine.WaitsBlock and jasmine.WaitsForBlock', -> + beforeEach -> + it 'should notify JHW of waiting', -> + waits(5500) + runs -> + expect(true).toEqual(true) + + it 'should notify JHW of waiting for something', -> + value = false + + setTimeout( + -> + value = true + , 5000 + ) + + waitsFor( + -> + value + , "Nope" + 5500 + ) + + runs -> + expect(true).toEqual(true) +