diff --git a/Guardfile b/Guardfile index 38e4233..1a2ca0d 100644 --- a/Guardfile +++ b/Guardfile @@ -27,7 +27,7 @@ end def compile #system %{cd ext/jasmine-webkit-specrunner && ruby test.rb && ruby extconf.rb} - system %{cd ext/jasmine-webkit-specrunner && ruby test.rb && ruby extconf.rb} + system %{cd ext/jasmine-webkit-specrunner && ruby extconf.rb} end compile diff --git a/ext/jasmine-webkit-specrunner/Page.cpp b/ext/jasmine-webkit-specrunner/Page.cpp index caba8e5..0c6103b 100644 --- a/ext/jasmine-webkit-specrunner/Page.cpp +++ b/ext/jasmine-webkit-specrunner/Page.cpp @@ -4,27 +4,8 @@ #include "Page.h" -Page::Page() : QWebPage(), confirmResult(true) {} +Page::Page() : QWebPage() {} -void Page::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) { - emit consoleLog(message, lineNumber, sourceID); +void Page::javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID) { + emit handleError(message, lineNumber, sourceID); } - -bool Page::javaScriptConfirm(QWebFrame*, const QString&) { - if (confirmResult) { - emit internalLog("TODO", "jasmine-headless-webkit can't handle confirm() yet! You should mock window.confirm for now. Returning true."); - return true; - } else { - confirmResult = true; - return false; - } -} - -void Page::javaScriptAlert(QWebFrame*, const QString &msg) { - emit internalLog("alert", msg); -} - -void Page::oneFalseConfirm() { - confirmResult = false; -} - diff --git a/ext/jasmine-webkit-specrunner/Page.h b/ext/jasmine-webkit-specrunner/Page.h index 01963c4..227ea1a 100644 --- a/ext/jasmine-webkit-specrunner/Page.h +++ b/ext/jasmine-webkit-specrunner/Page.h @@ -4,20 +4,14 @@ #include #include - class Page: public QWebPage { - Q_OBJECT - public: - Page(); - void oneFalseConfirm(); - signals: - void consoleLog(const QString &msg, int lineNumber, const QString &sourceID); - void internalLog(const QString ¬e, const QString &msg); - protected: - void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID); - bool javaScriptConfirm(QWebFrame *frame, const QString &msg); - void javaScriptAlert(QWebFrame *frame, const QString &msg); - private: - bool confirmResult; - }; +class Page: public QWebPage { + Q_OBJECT + public: + Page(); + protected: + void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID); + signals: + void handleError(const QString & message, int lineNumber, const QString & sourceID); +}; #endif diff --git a/ext/jasmine-webkit-specrunner/Runner.cpp b/ext/jasmine-webkit-specrunner/Runner.cpp index 985f54d..bf32dc2 100644 --- a/ext/jasmine-webkit-specrunner/Runner.cpp +++ b/ext/jasmine-webkit-specrunner/Runner.cpp @@ -3,9 +3,11 @@ #include #include #include +#include #include #include "Runner.h" +#include "Page.h" using namespace std; @@ -15,14 +17,14 @@ Runner::Runner() : QObject() , usedConsole(false) , isFinished(false) , didFail(false) + , useColors(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))); + connect(&m_page, SIGNAL(handleError(const QString &, int, const QString &)), this, SLOT(handleError(const QString &, int, const QString &))); connect(m_page.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJHW())); } @@ -30,24 +32,40 @@ void Runner::addFile(const QString &spec) { runnerFiles.enqueue(spec); } -void Runner::go() -{ +void Runner::go() { m_ticker.stop(); m_page.setPreferredContentsSize(QSize(1024, 600)); addJHW(); loadSpec(); - - m_ticker.start(); } -void Runner::addJHW() -{ +void Runner::addJHW() { m_page.mainFrame()->addToJavaScriptWindowObject("JHW", this); } +void Runner::handleError(const QString &message, int lineNumber, const QString &sourceID) { + QString messageEscaped = QString(message); + QString sourceIDEscaped = QString(sourceID); + + messageEscaped.replace(QString("\""), QString("\\\"")); + sourceIDEscaped.replace(QString("\""), QString("\\\"")); + + std::stringstream ss; + ss << lineNumber; + + QString command("JHW._handleError(\"" + messageEscaped + "\", " + QString(ss.str().c_str()) + ", \"" + sourceIDEscaped + "\"); false;"); + + m_page.mainFrame()->evaluateJavaScript(command); + + hasErrors = true; +} + void Runner::loadSpec() { - if (!reportFileName.isEmpty()) { + if (reportFileName.isEmpty()) { + outputFile = 0; + ts = 0; + } else { outputFile = new QFile(reportFileName); outputFile->open(QIODevice::WriteOnly); @@ -58,8 +76,7 @@ void Runner::loadSpec() m_ticker.start(); } -void Runner::watch(bool ok) -{ +void Runner::watch(bool ok) { if (!ok) { std::cerr << "Can't load " << qPrintable(m_page.mainFrame()->url().toString()) << ", the file may be broken." << std::endl; std::cerr << "Out of curiosity, did your tests try to submit a form and you haven't prevented that?" << std::endl; @@ -67,13 +84,12 @@ void Runner::watch(bool ok) QApplication::instance()->exit(1); return; } -} -bool Runner::hasElement(const char *select) { - return !m_page.mainFrame()->findFirstElement(select).isNull(); + m_page.mainFrame()->evaluateJavaScript(QString("JHW._setColors(") + (useColors ? QString("true") : QString("false")) + QString("); false;")); } void Runner::setColors(bool colors) { + useColors = colors; } void Runner::reportFile(const QString &file) { @@ -99,27 +115,12 @@ void Runner::print(const QString &fh, const QString &content) { std::cerr.flush(); } - if (fh == "report") { + if (fh == "report" && outputFile) { *ts << qPrintable(content); ts->flush(); } } -void Runner::errorLog(const QString &msg, int lineNumber, const QString &sourceID) -{ - hasErrors = true; - m_runs = 0; - m_ticker.start(); -} - -void Runner::internalLog(const QString ¬e, const QString &msg) {} - -void Runner::leavePageAttempt(const QString &msg) -{ - m_page.oneFalseConfirm(); - hasErrors = true; -} - void Runner::finishSuite() { isFinished = true; } @@ -131,7 +132,9 @@ void Runner::timerEvent() { QApplication::instance()->exit(1); if (isFinished) { - outputFile->close(); + if (outputFile) { + outputFile->close(); + } int exitCode = 0; if (didFail || hasErrors) { diff --git a/ext/jasmine-webkit-specrunner/Runner.h b/ext/jasmine-webkit-specrunner/Runner.h index a93ae2f..5b0f2eb 100644 --- a/ext/jasmine-webkit-specrunner/Runner.h +++ b/ext/jasmine-webkit-specrunner/Runner.h @@ -10,15 +10,13 @@ #include #include "Page.h" -#include "ConsoleOutput.h" -#include "ReportFileOutput.h" using namespace std; class Runner: public QObject { Q_OBJECT public: - enum { TIMER_TICK = 200, MAX_LOOPS = 25 }; + enum { TIMER_TICK = 200, MAX_LOOPS = 50 }; Runner(); void setColors(bool colors); @@ -26,7 +24,6 @@ class Runner: public QObject { void addFile(const QString &spec); void go(); public slots: - void leavePageAttempt(const QString &msg); void timerPause(); void timerDone(); @@ -35,10 +32,9 @@ class Runner: public QObject { void finishSuite(); private slots: void watch(bool ok); - void errorLog(const QString &msg, int lineNumber, const QString &sourceID); - void internalLog(const QString ¬e, const QString &msg); void addJHW(); void timerEvent(); + void handleError(const QString & message, int lineNumber, const QString & sourceID); protected: bool hasElement(const char *select); private: @@ -49,6 +45,8 @@ class Runner: public QObject { bool usedConsole; bool isFinished; bool didFail; + bool useColors; + QQueue runnerFiles; QStack failedSpecs; diff --git a/ext/jasmine-webkit-specrunner/Page_test.cpp b/ext/jasmine-webkit-specrunner/_old/Page_test.cpp similarity index 100% rename from ext/jasmine-webkit-specrunner/Page_test.cpp rename to ext/jasmine-webkit-specrunner/_old/Page_test.cpp diff --git a/ext/jasmine-webkit-specrunner/Page_test.h b/ext/jasmine-webkit-specrunner/_old/Page_test.h similarity index 100% rename from ext/jasmine-webkit-specrunner/Page_test.h rename to ext/jasmine-webkit-specrunner/_old/Page_test.h diff --git a/ext/jasmine-webkit-specrunner/Page_test.pro b/ext/jasmine-webkit-specrunner/_old/Page_test.pro similarity index 100% rename from ext/jasmine-webkit-specrunner/Page_test.pro rename to ext/jasmine-webkit-specrunner/_old/Page_test.pro diff --git a/ext/jasmine-webkit-specrunner/common.pri b/ext/jasmine-webkit-specrunner/common.pri index 7fdf73b..0320485 100644 --- a/ext/jasmine-webkit-specrunner/common.pri +++ b/ext/jasmine-webkit-specrunner/common.pri @@ -4,6 +4,6 @@ QMAKE_INFO_PLIST = Info.plist QMAKESPEC = macx-g++ QT += network webkit -SOURCES = Page.cpp Runner.cpp ConsoleOutput.cpp ReportFileOutput.cpp -HEADERS = Page.h Runner.h ConsoleOutput.h ReportFileOutput.h +SOURCES = Page.cpp Runner.cpp +HEADERS = Page.h Runner.h diff --git a/ext/jasmine-webkit-specrunner/specrunner.cpp b/ext/jasmine-webkit-specrunner/specrunner.cpp index b144a30..c0e969f 100644 --- a/ext/jasmine-webkit-specrunner/specrunner.cpp +++ b/ext/jasmine-webkit-specrunner/specrunner.cpp @@ -21,7 +21,6 @@ THE SOFTWARE. */ -#include "Page.h" #include "Runner.h" #if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) diff --git a/ext/jasmine-webkit-specrunner/specrunner.pro b/ext/jasmine-webkit-specrunner/specrunner.pro index 820c444..1157ea4 100644 --- a/ext/jasmine-webkit-specrunner/specrunner.pro +++ b/ext/jasmine-webkit-specrunner/specrunner.pro @@ -2,3 +2,4 @@ include(common.pri) SOURCES += specrunner.cpp TARGET = jasmine-webkit-specrunner + diff --git a/jasmine/intense.coffee b/jasmine/intense.coffee index ddbcff0..f24d136 100644 --- a/jasmine/intense.coffee +++ b/jasmine/intense.coffee @@ -10,9 +10,16 @@ window.Intense = { white: 7 methods: foreground: (color) -> - "\033[3#{Intense.colors[color]}m#{this}\033[0m" + if Intense.useColors + "\033[3#{Intense.colors[color]}m#{this}\033[0m" + else + this bright: -> - "\033[1m#{this}\033[0m" + if Intense.useColors + "\033[1m#{this}\033[0m" + else + this + useColors: true } for method, code of Intense.methods diff --git a/jasmine/intense.js b/jasmine/intense.js index a393ca1..2e5fffd 100644 --- a/jasmine/intense.js +++ b/jasmine/intense.js @@ -13,12 +13,21 @@ }, methods: { foreground: function(color) { - return "\033[3" + Intense.colors[color] + "m" + this + "\033[0m"; + if (Intense.useColors) { + return "\033[3" + Intense.colors[color] + "m" + this + "\033[0m"; + } else { + return this; + } }, bright: function() { - return "\033[1m" + this + "\033[0m"; + if (Intense.useColors) { + return "\033[1m" + this + "\033[0m"; + } else { + return this; + } } - } + }, + useColors: true }; _ref = Intense.methods; for (method in _ref) { diff --git a/jasmine/jasmine.headless-reporter.coffee b/jasmine/jasmine.headless-reporter.coffee index d0a86be..22fd83f 100644 --- a/jasmine/jasmine.headless-reporter.coffee +++ b/jasmine/jasmine.headless-reporter.coffee @@ -61,7 +61,7 @@ class jasmine.HeadlessReporter reportSuiteResults: (suite) -> hasError: -> - @_hasError == true + JHW._hasErrors _formatResultLine: (runtime) -> line = [] diff --git a/jasmine/jasmine.headless-reporter.js b/jasmine/jasmine.headless-reporter.js index 5209696..1adb21a 100644 --- a/jasmine/jasmine.headless-reporter.js +++ b/jasmine/jasmine.headless-reporter.js @@ -75,7 +75,7 @@ }; HeadlessReporter.prototype.reportSuiteResults = function(suite) {}; HeadlessReporter.prototype.hasError = function() { - return this._hasError === true; + return JHW._hasErrors; }; HeadlessReporter.prototype._formatResultLine = function(runtime) { var line; diff --git a/jasmine/prolog.coffee b/jasmine/prolog.coffee index ee21d7c..837a564 100644 --- a/jasmine/prolog.coffee +++ b/jasmine/prolog.coffee @@ -41,14 +41,23 @@ if window.JHW window.alert = (message) -> JHW.stderr.puts(message) - JHW.error = (message, sourceUrl, lineNumber) -> + JHW._hasErrors = false + JHW._handleError = (message, lineNumber, sourceURL) -> + JHW.stderr.puts(message) + JHW._hasErrors = true + false - for handle in [ 'stdout', 'stderr', 'report' ] + JHW._setColors = (what) -> + Intense.useColors = what + + createHandle = (handle) -> JHW[handle] = print: (content) -> JHW.print(handle, content) puts: (content) -> JHW.print(handle, content + "\n") + createHandle(handle) for handle in [ 'stdout', 'stderr', 'report' ] + JHW.log = (msg) -> JHW.usedConsole() JHW.stdout.puts(msg) diff --git a/jasmine/prolog.js b/jasmine/prolog.js index f5e757a..e480a96 100644 --- a/jasmine/prolog.js +++ b/jasmine/prolog.js @@ -1,3 +1,83 @@ (function() { + var createHandle, handle, _i, _len, _ref; + if (window.JHW) { + window.console = { + log: function(data) { + var dump, useJsDump; + if (typeof jQuery !== 'undefined' && data instanceof jQuery) { + return JHW.log(style_html($("
").append(data).html(), { + indent_size: 2 + })); + } else { + useJsDump = true; + try { + if (typeof data.toJSON === 'function') { + JHW.log("JSON: " + (JSON.stringify(data, null, 2))); + useJsDump = false; + } + } catch (e) { + } + if (useJsDump) { + dump = jsDump.doParse(data); + if (dump.indexOf("\n") === -1) { + return JHW.log(dump); + } else { + return JHW.log("jsDump: " + dump); + } + } + } + }, + pp: function(data) { + return JHW.log(jasmine ? jasmine.pp(data) : console.log(data)); + }, + peek: function(data) { + console.log(data); + return data; + } + }; + window.onbeforeunload = function(e) { + JHW.leavePageAttempt(); + JHW.stderr.puts('The code tried to leave the test page. Check for unhandled form submits and link clicks.'); + if (e = e || window.event) { + e.returnValue = "leaving"; + } + return "leaving"; + }; + window.confirm = function(message) { + JHW.stderr.puts("jasmine-headless-webkit can't handle confirm() yet! You should mock window.confirm. Returning true."); + return true; + }; + window.alert = function(message) { + return JHW.stderr.puts(message); + }; + JHW._hasErrors = false; + JHW._handleError = function(message, lineNumber, sourceURL) { + JHW.stderr.puts(message); + JHW._hasErrors = true; + return false; + }; + JHW._setColors = function(what) { + return Intense.useColors = what; + }; + createHandle = function(handle) { + return JHW[handle] = { + print: function(content) { + return JHW.print(handle, content); + }, + puts: function(content) { + return JHW.print(handle, content + "\n"); + } + }; + }; + _ref = ['stdout', 'stderr', 'report']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + handle = _ref[_i]; + createHandle(handle); + } + JHW.log = function(msg) { + JHW.usedConsole(); + return JHW.stdout.puts(msg); + }; + } }).call(this);