From 60713fc88fd92c050586b3bb3e4ad954f2ff968a Mon Sep 17 00:00:00 2001 From: John Bintz Date: Mon, 1 Aug 2011 13:09:08 -0400 Subject: [PATCH] start c++ cleanup --- .gitignore | 3 + Guardfile | 2 +- .../HeadlessSpecRunner/ConsoleOutput.cpp | 0 .../HeadlessSpecRunner/ConsoleOutput.h | 0 .../HeadlessSpecRunner/Page.cpp | 30 ++ .../HeadlessSpecRunner/Page.h | 25 + .../HeadlessSpecRunner/Runner.cpp | 266 ++++++++++ .../HeadlessSpecRunner/Runner.h | 60 +++ ext/jasmine-webkit-specrunner/extconf.rb | 2 + ext/jasmine-webkit-specrunner/specrunner.cpp | 455 ++---------------- ext/jasmine-webkit-specrunner/specrunner.pro | 3 +- 11 files changed, 436 insertions(+), 410 deletions(-) create mode 100644 ext/jasmine-webkit-specrunner/HeadlessSpecRunner/ConsoleOutput.cpp create mode 100644 ext/jasmine-webkit-specrunner/HeadlessSpecRunner/ConsoleOutput.h create mode 100644 ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Page.cpp create mode 100644 ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Page.h create mode 100644 ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Runner.cpp create mode 100644 ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Runner.h diff --git a/.gitignore b/.gitignore index 78852f2..2c8800d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ Makefile specrunner.moc specrunner.o ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner +*.o +moc_*.* + diff --git a/Guardfile b/Guardfile index 0db8fe8..f0c26ca 100644 --- a/Guardfile +++ b/Guardfile @@ -4,7 +4,7 @@ # guard 'shell' do - watch(%r{ext/jasmine-webkit-specrunner/specrunner.cpp}) { compile } + watch(%r{ext/jasmine-webkit-specrunner/.*\.(cpp|h)}) { compile } end # A sample Guardfile # More info at https://github.com/guard/guard#readme diff --git a/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/ConsoleOutput.cpp b/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/ConsoleOutput.cpp new file mode 100644 index 0000000..e69de29 diff --git a/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/ConsoleOutput.h b/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/ConsoleOutput.h new file mode 100644 index 0000000..e69de29 diff --git a/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Page.cpp b/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Page.cpp new file mode 100644 index 0000000..aab256e --- /dev/null +++ b/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Page.cpp @@ -0,0 +1,30 @@ +#include +#include + +#include "Page.h" + +namespace HeadlessSpecRunner { + Page::Page() : QWebPage(), confirmResult(true) {} + + void Page::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) { + emit consoleLog(message, lineNumber, sourceID); + } + + bool Page::javaScriptConfirm(QWebFrame *frame, const QString &msg) { + 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 *frame, const QString &msg) { + emit internalLog("alert", msg); + } + + void Page::oneFalseConfirm() { + confirmResult = false; + } +} diff --git a/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Page.h b/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Page.h new file mode 100644 index 0000000..4c7e151 --- /dev/null +++ b/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Page.h @@ -0,0 +1,25 @@ +#ifndef JHW_PAGE +#define JHW_PAGE + +#include +#include + +namespace HeadlessSpecRunner { + 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; + }; +} + +#endif diff --git a/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Runner.cpp b/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Runner.cpp new file mode 100644 index 0000000..2ec04d1 --- /dev/null +++ b/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Runner.cpp @@ -0,0 +1,266 @@ +#include +#include +#include +#include +#include +#include + +#include "Runner.h" + +namespace HeadlessSpecRunner { + Runner::Runner() : QObject() + , m_runs(0) + , hasErrors(false) + , usedConsole(false) + , showColors(false) + , isFinished(false) + , didFail(false) + , consoleNotUsedThisRun(false) { + m_page.settings()->enablePersistentStorage(); + 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.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJHW())); + } + + void Runner::addFile(const QString &spec) { + runnerFiles.enqueue(spec); + } + + void Runner::go() + { + m_ticker.stop(); + m_page.setPreferredContentsSize(QSize(1024, 600)); + addJHW(); + loadSpec(); + } + void Runner::addJHW() + { + m_page.mainFrame()->addToJavaScriptWindowObject("JHW", this); + } + + void Runner::loadSpec() + { + m_page.mainFrame()->load(runnerFiles.dequeue()); + m_ticker.start(200, this); + } + + 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; + std::cerr << "Try running your tests in your browser with the Jasmine server and see what happens." << std::endl; + QApplication::instance()->exit(1); + return; + } + + m_ticker.start(200, this); + } + + bool Runner::hasElement(const char *select) + { + return !m_page.mainFrame()->findFirstElement(select).isNull(); + } + + void Runner::setColors(bool colors) + { + showColors = colors; + } + + void Runner::reportFile(const QString &file) + { + reportFilename = file; + } + + void Runner::red() + { + if (showColors) std::cout << "\033[0;31m"; + } + + void Runner::green() + { + if (showColors) std::cout << "\033[0;32m"; + } + + void Runner::yellow() + { + if (showColors) std::cout << "\033[0;33m"; + } + + void Runner::clear() + { + if (showColors) std::cout << "\033[m"; + } + + void Runner::specPassed() + { + consoleNotUsedThisRun = true; + green(); + std::cout << '.'; + clear(); + fflush(stdout); + } + + void Runner::specFailed(const QString &specDetail) + { + consoleNotUsedThisRun = true; + didFail = true; + red(); + std::cout << 'F'; + failedSpecs.push(specDetail); + clear(); + fflush(stdout); + } + + void Runner::errorLog(const QString &msg, int lineNumber, const QString &sourceID) + { + red(); + std::cout << "[error] "; + clear(); + std::cout << qPrintable(sourceID) << ":" << lineNumber << " : " << qPrintable(msg); + std::cout << std::endl; + + hasErrors = true; + m_runs = 0; + m_ticker.start(200, this); + } + + void Runner::internalLog(const QString ¬e, const QString &msg) { + red(); + std::cout << "[" << qPrintable(note) << "] "; + clear(); + std::cout << qPrintable(msg); + std::cout << std::endl; + } + + void Runner::log(const QString &msg) + { + usedConsole = true; + green(); + if (consoleNotUsedThisRun) { + std::cout << std::endl; + consoleNotUsedThisRun = false; + } + std::cout << "[console] "; + clear(); + if (msg.contains("\n")) + std::cout << std::endl; + std::cout << qPrintable(msg); + std::cout << std::endl; + } + + void Runner::leavePageAttempt(const QString &msg) + { + red(); + std::cout << "[error] "; + clear(); + std::cout << qPrintable(msg) << std::endl; + m_page.oneFalseConfirm(); + hasErrors = true; + } + + void Runner::printName(const QString &name) + { + std::cout << std::endl << std::endl; + red(); + std::cout << qPrintable(name) << std::endl; + clear(); + } + + void Runner::printResult(const QString &result) + { + red(); + std::cout << " " << qPrintable(result) << std::endl; + clear(); + } + + void Runner::finishSuite(const QString &duration, const QString &total, const QString& failed) + { + std::cout << std::endl; + if (didFail) { + red(); + std::cout << "FAIL: "; + } else { + green(); + std::cout << "PASS"; + + if (hasErrors) { + std::cout << " with JS errors"; + } + + std::cout << ": "; + } + + std::cout << qPrintable(total) << " tests, " << qPrintable(failed) << " failures, " << qPrintable(duration) << " secs."; + clear(); + std::cout << std::endl; + + if (!reportFilename.isEmpty()) { + QFile reportFH(reportFilename); + + if (reportFH.open(QFile::WriteOnly)) { + QTextStream report(&reportFH); + report << qPrintable(total) << "/" << qPrintable(failed) << "/"; + report << (usedConsole ? "T" : "F"); + report << "/" << qPrintable(duration) << "\n"; + + QString failedSpec; + + while (!failedSpecs.isEmpty()) { + failedSpec = failedSpecs.pop(); + report << qPrintable(failedSpec) << "\n"; + } + + reportFH.close(); + } + } + + isFinished = true; + } + + void Runner::timerEvent(QTimerEvent *event) + { + ++m_runs; + + if (event->timerId() != m_ticker.timerId()) + return; + + if (hasErrors && m_runs > 2) + QApplication::instance()->exit(1); + + if (isFinished) { + int exitCode = 0; + if (didFail || hasErrors) { + exitCode = 1; + } else { + if (usedConsole) { + exitCode = 2; + } + } + + bool runAgain = true; + + if (runnerFiles.count() == 0) { + runAgain = false; + } else { + if (exitCode == 1) { + runAgain = false; + } + } + + if (runAgain) { + isFinished = false; + loadSpec(); + } else { + QApplication::instance()->exit(exitCode); + } + } + + if (m_runs > 30) { + 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/HeadlessSpecRunner/Runner.h b/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Runner.h new file mode 100644 index 0000000..46d3bf7 --- /dev/null +++ b/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Runner.h @@ -0,0 +1,60 @@ +#ifndef JHW_RUNNER +#define JHW_RUNNER + +#include +#include +#include +#include +#include +#include + +#include "Page.h" + +namespace HeadlessSpecRunner { + class Runner: public QObject { + Q_OBJECT + public: + Runner(); + void setColors(bool colors); + void reportFile(const QString &file); + void addFile(const QString &spec); + void go(); + public slots: + void log(const QString &msg); + void leavePageAttempt(const QString &msg); + void specPassed(); + void specFailed(const QString &specDetail); + void printName(const QString &name); + void printResult(const QString &result); + void finishSuite(const QString &duration, const QString &total, const QString& failed); + 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(); + protected: + bool hasElement(const char *select); + void timerEvent(QTimerEvent *event); + private: + HeadlessSpecRunner::Page m_page; + QBasicTimer m_ticker; + int m_runs; + bool hasErrors; + bool usedConsole; + bool showColors; + bool isFinished; + bool didFail; + bool consoleNotUsedThisRun; + QQueue runnerFiles; + QString reportFilename; + QStack failedSpecs; + + void red(); + void green(); + void yellow(); + void clear(); + void loadSpec(); + }; +} + +#endif diff --git a/ext/jasmine-webkit-specrunner/extconf.rb b/ext/jasmine-webkit-specrunner/extconf.rb index 6cb0252..df888d3 100644 --- a/ext/jasmine-webkit-specrunner/extconf.rb +++ b/ext/jasmine-webkit-specrunner/extconf.rb @@ -1,3 +1,5 @@ +require 'fileutils' + $: << File.expand_path("../../../lib", __FILE__) require 'qt/qmake' diff --git a/ext/jasmine-webkit-specrunner/specrunner.cpp b/ext/jasmine-webkit-specrunner/specrunner.cpp index d6b0c3c..4827ac9 100644 --- a/ext/jasmine-webkit-specrunner/specrunner.cpp +++ b/ext/jasmine-webkit-specrunner/specrunner.cpp @@ -1,429 +1,68 @@ /* - Copyright (c) 2010 Sencha Inc. - Copyright (c) 2011 John Bintz + Copyright (c) 2010 Sencha Inc. + Copyright (c) 2011 John Bintz - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - */ + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ -#include -#include -#include -#include -#include -#include +#include "HeadlessSpecRunner/Page.h" +#include "HeadlessSpecRunner/Runner.h" #if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) #error Use Qt 4.7 or later version #endif -class HeadlessSpecRunnerPage: public QWebPage -{ - Q_OBJECT -public: - HeadlessSpecRunnerPage(); - 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; -}; - -HeadlessSpecRunnerPage::HeadlessSpecRunnerPage() - : QWebPage() - , confirmResult(true) -{ - -} - -void HeadlessSpecRunnerPage::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) -{ - emit consoleLog(message, lineNumber, sourceID); -} - -bool HeadlessSpecRunnerPage::javaScriptConfirm(QWebFrame *frame, const QString &msg) -{ - 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 HeadlessSpecRunnerPage::javaScriptAlert(QWebFrame *frame, const QString &msg) -{ - emit internalLog("alert", msg); -} - -void HeadlessSpecRunnerPage::oneFalseConfirm() -{ - confirmResult = false; -} - -class HeadlessSpecRunner: public QObject -{ - Q_OBJECT -public: - HeadlessSpecRunner(); - void setColors(bool colors); - void reportFile(const QString &file); - void addFile(const QString &spec); - void go(); -public slots: - void log(const QString &msg); - void leavePageAttempt(const QString &msg); - void specPassed(); - void specFailed(const QString &specDetail); - void printName(const QString &name); - void printResult(const QString &result); - void finishSuite(const QString &duration, const QString &total, const QString& failed); -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(); -protected: - bool hasElement(const char *select); - void timerEvent(QTimerEvent *event); -private: - HeadlessSpecRunnerPage m_page; - QBasicTimer m_ticker; - int m_runs; - bool hasErrors; - bool usedConsole; - bool showColors; - bool isFinished; - bool didFail; - bool consoleNotUsedThisRun; - QQueue runnerFiles; - QString reportFilename; - QStack failedSpecs; - - void red(); - void green(); - void yellow(); - void clear(); - void loadSpec(); -}; - -HeadlessSpecRunner::HeadlessSpecRunner() - : QObject() - , m_runs(0) - , hasErrors(false) - , usedConsole(false) - , showColors(false) - , isFinished(false) - , didFail(false) - , consoleNotUsedThisRun(false) -{ - m_page.settings()->enablePersistentStorage(); - 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.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJHW())); -} - -void HeadlessSpecRunner::addFile(const QString &spec) -{ - runnerFiles.enqueue(spec); -} - -void HeadlessSpecRunner::go() -{ - m_ticker.stop(); - m_page.setPreferredContentsSize(QSize(1024, 600)); - addJHW(); - loadSpec(); -} -void HeadlessSpecRunner::addJHW() -{ - m_page.mainFrame()->addToJavaScriptWindowObject("JHW", this); -} - -void HeadlessSpecRunner::loadSpec() -{ - m_page.mainFrame()->load(runnerFiles.dequeue()); - m_ticker.start(200, this); -} - -void HeadlessSpecRunner::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; - std::cerr << "Try running your tests in your browser with the Jasmine server and see what happens." << std::endl; - QApplication::instance()->exit(1); - return; - } - - m_ticker.start(200, this); -} - -bool HeadlessSpecRunner::hasElement(const char *select) -{ - return !m_page.mainFrame()->findFirstElement(select).isNull(); -} - -void HeadlessSpecRunner::setColors(bool colors) -{ - showColors = colors; -} - -void HeadlessSpecRunner::reportFile(const QString &file) -{ - reportFilename = file; -} - -void HeadlessSpecRunner::red() -{ - if (showColors) std::cout << "\033[0;31m"; -} - -void HeadlessSpecRunner::green() -{ - if (showColors) std::cout << "\033[0;32m"; -} - -void HeadlessSpecRunner::yellow() -{ - if (showColors) std::cout << "\033[0;33m"; -} - -void HeadlessSpecRunner::clear() -{ - if (showColors) std::cout << "\033[m"; -} - -void HeadlessSpecRunner::specPassed() -{ - consoleNotUsedThisRun = true; - green(); - std::cout << '.'; - clear(); - fflush(stdout); -} - -void HeadlessSpecRunner::specFailed(const QString &specDetail) -{ - consoleNotUsedThisRun = true; - didFail = true; - red(); - std::cout << 'F'; - failedSpecs.push(specDetail); - clear(); - fflush(stdout); -} - -void HeadlessSpecRunner::errorLog(const QString &msg, int lineNumber, const QString &sourceID) -{ - red(); - std::cout << "[error] "; - clear(); - std::cout << qPrintable(sourceID) << ":" << lineNumber << " : " << qPrintable(msg); - std::cout << std::endl; - - hasErrors = true; - m_runs = 0; - m_ticker.start(200, this); -} - -void HeadlessSpecRunner::internalLog(const QString ¬e, const QString &msg) { - red(); - std::cout << "[" << qPrintable(note) << "] "; - clear(); - std::cout << qPrintable(msg); - std::cout << std::endl; -} - -void HeadlessSpecRunner::log(const QString &msg) -{ - usedConsole = true; - green(); - if (consoleNotUsedThisRun) { - std::cout << std::endl; - consoleNotUsedThisRun = false; - } - std::cout << "[console] "; - clear(); - if (msg.contains("\n")) - std::cout << std::endl; - std::cout << qPrintable(msg); - std::cout << std::endl; -} - -void HeadlessSpecRunner::leavePageAttempt(const QString &msg) -{ - red(); - std::cout << "[error] "; - clear(); - std::cout << qPrintable(msg) << std::endl; - m_page.oneFalseConfirm(); - hasErrors = true; -} - -void HeadlessSpecRunner::printName(const QString &name) -{ - std::cout << std::endl << std::endl; - red(); - std::cout << qPrintable(name) << std::endl; - clear(); -} - -void HeadlessSpecRunner::printResult(const QString &result) -{ - red(); - std::cout << " " << qPrintable(result) << std::endl; - clear(); -} - -void HeadlessSpecRunner::finishSuite(const QString &duration, const QString &total, const QString& failed) -{ - std::cout << std::endl; - if (didFail) { - red(); - std::cout << "FAIL: "; - } else { - green(); - std::cout << "PASS"; - - if (hasErrors) { - std::cout << " with JS errors"; - } - - std::cout << ": "; - } - - std::cout << qPrintable(total) << " tests, " << qPrintable(failed) << " failures, " << qPrintable(duration) << " secs."; - clear(); - std::cout << std::endl; - - if (!reportFilename.isEmpty()) { - QFile reportFH(reportFilename); - - if (reportFH.open(QFile::WriteOnly)) { - QTextStream report(&reportFH); - report << qPrintable(total) << "/" << qPrintable(failed) << "/"; - report << (usedConsole ? "T" : "F"); - report << "/" << qPrintable(duration) << "\n"; - - QString failedSpec; - - while (!failedSpecs.isEmpty()) { - failedSpec = failedSpecs.pop(); - report << qPrintable(failedSpec) << "\n"; - } - - reportFH.close(); - } - } - - isFinished = true; -} - -void HeadlessSpecRunner::timerEvent(QTimerEvent *event) -{ - ++m_runs; - - if (event->timerId() != m_ticker.timerId()) - return; - - if (hasErrors && m_runs > 2) - QApplication::instance()->exit(1); - - if (isFinished) { - int exitCode = 0; - if (didFail || hasErrors) { - exitCode = 1; - } else { - if (usedConsole) { - exitCode = 2; - } - } - - bool runAgain = true; - - if (runnerFiles.count() == 0) { - runAgain = false; - } else { - if (exitCode == 1) { - runAgain = false; - } - } - - if (runAgain) { - isFinished = false; - loadSpec(); - } else { - QApplication::instance()->exit(exitCode); - } - } - - if (m_runs > 30) { - std::cout << "WARNING: too many runs and the test is still not finished!" << std::endl; - QApplication::instance()->exit(1); - } -} - -#include "specrunner.moc" - int main(int argc, char** argv) { - char *reporter = NULL; - char showColors = false; + char *reporter = NULL; + char showColors = false; - int c, index; + int c, index; - while ((c = getopt(argc, argv, "cr:")) != -1) { - switch(c) { - case 'c': - showColors = true; - break; - case 'r': - reporter = optarg; - break; - } + while ((c = getopt(argc, argv, "cr:")) != -1) { + switch(c) { + case 'c': + showColors = true; + break; + case 'r': + reporter = optarg; + break; } + } - if (optind == argc) { - std::cerr << "Run Jasmine's SpecRunner headlessly" << std::endl << std::endl; - std::cerr << " specrunner [-c] [-r ] specrunner.html ..." << std::endl; - return 1; - } + if (optind == argc) { + std::cerr << "Run Jasmine's SpecRunner headlessly" << std::endl << std::endl; + std::cerr << " specrunner [-c] [-r ] specrunner.html ..." << std::endl; + return 1; + } - QApplication app(argc, argv); - app.setApplicationName("jasmine-headless-webkit"); - HeadlessSpecRunner runner; - runner.setColors(showColors); - runner.reportFile(reporter); + QApplication app(argc, argv); + app.setApplicationName("jasmine-headless-webkit"); + HeadlessSpecRunner::Runner runner; + runner.setColors(showColors); + runner.reportFile(reporter); - for (index = optind; index < argc; index++) { - runner.addFile(QString::fromLocal8Bit(argv[index])); - } - runner.go(); + for (index = optind; index < argc; index++) { + runner.addFile(QString::fromLocal8Bit(argv[index])); + } + runner.go(); - return app.exec(); + return app.exec(); } - diff --git a/ext/jasmine-webkit-specrunner/specrunner.pro b/ext/jasmine-webkit-specrunner/specrunner.pro index 78cddcb..43201b9 100644 --- a/ext/jasmine-webkit-specrunner/specrunner.pro +++ b/ext/jasmine-webkit-specrunner/specrunner.pro @@ -1,7 +1,8 @@ TEMPLATE = app CONFIG -= app_bundle TARGET = jasmine-webkit-specrunner -SOURCES = specrunner.cpp +SOURCES = HeadlessSpecRunner/Page.cpp HeadlessSpecRunner/Runner.cpp specrunner.cpp +HEADERS = HeadlessSpecRunner/Page.h HeadlessSpecRunner/Runner.h QT += network webkit QMAKE_INFO_PLIST = Info.plist QMAKESPEC = macx-gcc