starting work on report file output

This commit is contained in:
John Bintz 2011-08-30 15:59:09 -04:00
parent 0c368ec9f2
commit 3fdc69cfdd
17 changed files with 267 additions and 199 deletions

View File

@ -1,142 +1,140 @@
#include "ConsoleOutput.h" #include "ConsoleOutput.h"
namespace HeadlessSpecRunner { ConsoleOutput::ConsoleOutput() : QObject(),
ConsoleOutput::ConsoleOutput() : QObject(),
showColors(false), showColors(false),
consoleLogUsed(false) { consoleLogUsed(false) {
outputIO = &std::cout; outputIO = &std::cout;
} }
void ConsoleOutput::passed(const QString &specDetail) { void ConsoleOutput::passed(const QString &specDetail) {
green(); green();
*outputIO << '.'; *outputIO << '.';
clear(); clear();
outputIO->flush(); outputIO->flush();
consoleLogUsed = false; consoleLogUsed = false;
successes.push(specDetail); successes.push(specDetail);
} }
void ConsoleOutput::failed(const QString &specDetail) { void ConsoleOutput::failed(const QString &specDetail) {
red(); red();
*outputIO << 'F'; *outputIO << 'F';
clear(); clear();
outputIO->flush(); outputIO->flush();
consoleLogUsed = false; consoleLogUsed = false;
failures.push(specDetail); failures.push(specDetail);
} }
void ConsoleOutput::green() { void ConsoleOutput::green() {
if (showColors) std::cout << "\033[0;32m"; if (showColors) std::cout << "\033[0;32m";
} }
void ConsoleOutput::clear() { void ConsoleOutput::clear() {
if (showColors) std::cout << "\033[m"; if (showColors) std::cout << "\033[m";
} }
void ConsoleOutput::red() { void ConsoleOutput::red() {
if (showColors) std::cout << "\033[0;31m"; if (showColors) std::cout << "\033[0;31m";
} }
void ConsoleOutput::yellow() void ConsoleOutput::yellow()
{ {
if (showColors) std::cout << "\033[0;33m"; if (showColors) std::cout << "\033[0;33m";
} }
void ConsoleOutput::errorLog(const QString &msg, int lineNumber, const QString &sourceID) { void ConsoleOutput::errorLog(const QString &msg, int lineNumber, const QString &sourceID) {
red(); red();
*outputIO << "[error] "; *outputIO << "[error] ";
clear(); clear();
*outputIO << qPrintable(sourceID) << ":" << lineNumber << " : " << qPrintable(msg); *outputIO << qPrintable(sourceID) << ":" << lineNumber << " : " << qPrintable(msg);
*outputIO << std::endl;
}
void ConsoleOutput::internalLog(const QString &note, const QString &msg) {
red();
*outputIO << "[" << qPrintable(note) << "] ";
clear();
*outputIO << qPrintable(msg);
*outputIO << std::endl;
}
void ConsoleOutput::consoleLog(const QString &msg) {
if (!consoleLogUsed) {
*outputIO << std::endl; *outputIO << std::endl;
consoleLogUsed = true;
} }
void ConsoleOutput::internalLog(const QString &note, const QString &msg) { green();
red(); *outputIO << "[console] ";
*outputIO << "[" << qPrintable(note) << "] "; if (msg.contains("\n"))
clear();
*outputIO << qPrintable(msg);
*outputIO << std::endl; *outputIO << std::endl;
clear();
*outputIO << qPrintable(msg);
*outputIO << std::endl;
}
void ConsoleOutput::logSpecFilename(const QString &name) {
*outputIO << std::endl << std::endl;
red();
*outputIO << qPrintable(name) << std::endl;
clear();
}
void ConsoleOutput::logSpecResult(const QString &result) {
red();
*outputIO << " " << qPrintable(result) << std::endl;
clear();
}
void ConsoleOutput::reportFailure(const QString &totalTests, const QString &failedTests, const QString &duration) {
red();
*outputIO << std::endl << "FAIL: ";
formatTestResults(totalTests, failedTests, duration);
*outputIO << std::endl;
clear();
}
void ConsoleOutput::reportSuccess(const QString &totalTests, const QString &failedTests, const QString &duration) {
green();
*outputIO << std::endl << "PASS: ";
formatTestResults(totalTests, failedTests, duration);
*outputIO << std::endl;
clear();
}
void ConsoleOutput::reportSuccessWithJSErrors(const QString &totalTests, const QString &failedTests, const QString &duration) {
yellow();
*outputIO << std::endl << "PASS with JS errors: ";
formatTestResults(totalTests, failedTests, duration);
*outputIO << std::endl;
clear();
}
void ConsoleOutput::formatTestResults(const QString &totalTests, const QString &failedTests, const QString &duration) {
*outputIO << qPrintable(totalTests) << " ";
if (totalTests == "1") {
*outputIO << "test";
} else {
*outputIO << "tests";
} }
void ConsoleOutput::consoleLog(const QString &msg) { *outputIO << ", ";
if (!consoleLogUsed) {
*outputIO << std::endl;
consoleLogUsed = true;
}
green(); *outputIO << qPrintable(failedTests) << " ";
*outputIO << "[console] "; if (failedTests == "1") {
if (msg.contains("\n")) *outputIO << "failure";
*outputIO << std::endl; } else {
clear(); *outputIO << "failures";
*outputIO << qPrintable(msg);
*outputIO << std::endl;
} }
void ConsoleOutput::logSpecFilename(const QString &name) { *outputIO << ", ";
*outputIO << std::endl << std::endl;
red();
*outputIO << qPrintable(name) << std::endl;
clear();
}
void ConsoleOutput::logSpecResult(const QString &result) { *outputIO << qPrintable(duration) << " ";
red(); if (duration == "1") {
*outputIO << " " << qPrintable(result) << std::endl; *outputIO << "sec.";
clear(); } else {
} *outputIO << "secs.";
void ConsoleOutput::reportFailure(const QString &totalTests, const QString &failedTests, const QString &duration) {
red();
*outputIO << std::endl << "FAIL: ";
formatTestResults(totalTests, failedTests, duration);
*outputIO << std::endl;
clear();
}
void ConsoleOutput::reportSuccess(const QString &totalTests, const QString &failedTests, const QString &duration) {
green();
*outputIO << std::endl << "PASS: ";
formatTestResults(totalTests, failedTests, duration);
*outputIO << std::endl;
clear();
}
void ConsoleOutput::reportSuccessWithJSErrors(const QString &totalTests, const QString &failedTests, const QString &duration) {
yellow();
*outputIO << std::endl << "PASS with JS errors: ";
formatTestResults(totalTests, failedTests, duration);
*outputIO << std::endl;
clear();
}
void ConsoleOutput::formatTestResults(const QString &totalTests, const QString &failedTests, const QString &duration) {
*outputIO << qPrintable(totalTests) << " ";
if (totalTests == "1") {
*outputIO << "test";
} else {
*outputIO << "tests";
}
*outputIO << ", ";
*outputIO << qPrintable(failedTests) << " ";
if (failedTests == "1") {
*outputIO << "failure";
} else {
*outputIO << "failures";
}
*outputIO << ", ";
*outputIO << qPrintable(duration) << " ";
if (duration == "1") {
*outputIO << "sec.";
} else {
*outputIO << "secs.";
}
} }
} }

View File

@ -5,35 +5,34 @@
#include <iostream> #include <iostream>
#include <QStack> #include <QStack>
namespace HeadlessSpecRunner { class ConsoleOutput : public QObject {
class ConsoleOutput : public QObject { public:
Q_OBJECT ConsoleOutput();
public:
ConsoleOutput();
void passed(const QString &specDetail);
void failed(const QString &specDetail);
void errorLog(const QString &msg, int lineNumber, const QString &sourceID);
void internalLog(const QString &note, const QString &msg);
void consoleLog(const QString &msg);
void logSpecFilename(const QString &name);
void logSpecResult(const QString &result);
void reportFailure(const QString &totalTests, const QString &failedTests, const QString &duration); void passed(const QString &specDetail);
void reportSuccess(const QString &totalTests, const QString &failedTests, const QString &duration); void failed(const QString &specDetail);
void reportSuccessWithJSErrors(const QString &totalTests, const QString &failedTests, const QString &duration); void errorLog(const QString &msg, int lineNumber, const QString &sourceID);
void internalLog(const QString &note, const QString &msg);
void consoleLog(const QString &msg);
void logSpecFilename(const QString &name);
void logSpecResult(const QString &result);
std::ostream *outputIO; void reportFailure(const QString &totalTests, const QString &failedTests, const QString &duration);
QStack<QString> successes; void reportSuccess(const QString &totalTests, const QString &failedTests, const QString &duration);
QStack<QString> failures; void reportSuccessWithJSErrors(const QString &totalTests, const QString &failedTests, const QString &duration);
bool showColors;
bool consoleLogUsed; std::ostream *outputIO;
private: QStack<QString> successes;
void green(); QStack<QString> failures;
void clear();
void red(); bool showColors;
void yellow(); bool consoleLogUsed;
void formatTestResults(const QString &totalTests, const QString &failedTests, const QString &duration); private:
}; void green();
} void clear();
void red();
void yellow();
void formatTestResults(const QString &totalTests, const QString &failedTests, const QString &duration);
};
#endif #endif

View File

@ -5,13 +5,11 @@
using namespace std; using namespace std;
namespace HeadlessSpecRunner { ConsoleOutputTest::ConsoleOutputTest() : QObject() {}
ConsoleOutputTest::ConsoleOutputTest() : QObject() {
}
void ConsoleOutputTest::testPassed() { void ConsoleOutputTest::testPassed() {
stringstream buffer; stringstream buffer;
HeadlessSpecRunner::ConsoleOutput output; ConsoleOutput output;
output.consoleLogUsed = true; output.consoleLogUsed = true;
output.outputIO = &buffer; output.outputIO = &buffer;
@ -24,7 +22,7 @@ namespace HeadlessSpecRunner {
void ConsoleOutputTest::testFailed() { void ConsoleOutputTest::testFailed() {
stringstream buffer; stringstream buffer;
HeadlessSpecRunner::ConsoleOutput output; ConsoleOutput output;
output.consoleLogUsed = true; output.consoleLogUsed = true;
output.outputIO = &buffer; output.outputIO = &buffer;
@ -37,7 +35,7 @@ namespace HeadlessSpecRunner {
void ConsoleOutputTest::testErrorLog() { void ConsoleOutputTest::testErrorLog() {
stringstream buffer; stringstream buffer;
HeadlessSpecRunner::ConsoleOutput output; ConsoleOutput output;
output.outputIO = &buffer; output.outputIO = &buffer;
output.errorLog("message", 1, "source"); output.errorLog("message", 1, "source");
@ -46,7 +44,7 @@ namespace HeadlessSpecRunner {
void ConsoleOutputTest::testInternalLog() { void ConsoleOutputTest::testInternalLog() {
stringstream buffer; stringstream buffer;
HeadlessSpecRunner::ConsoleOutput output; ConsoleOutput output;
output.outputIO = &buffer; output.outputIO = &buffer;
output.internalLog("note", "message"); output.internalLog("note", "message");
@ -55,7 +53,7 @@ namespace HeadlessSpecRunner {
void ConsoleOutputTest::testConsoleLog() { void ConsoleOutputTest::testConsoleLog() {
stringstream buffer; stringstream buffer;
HeadlessSpecRunner::ConsoleOutput output; ConsoleOutput output;
output.consoleLogUsed = false; output.consoleLogUsed = false;
output.outputIO = &buffer; output.outputIO = &buffer;
@ -65,7 +63,7 @@ namespace HeadlessSpecRunner {
void ConsoleOutputTest::testConsoleLogUsed() { void ConsoleOutputTest::testConsoleLogUsed() {
stringstream buffer; stringstream buffer;
HeadlessSpecRunner::ConsoleOutput output; ConsoleOutput output;
output.consoleLogUsed = true; output.consoleLogUsed = true;
output.outputIO = &buffer; output.outputIO = &buffer;
@ -75,7 +73,7 @@ namespace HeadlessSpecRunner {
void ConsoleOutputTest::testLogSpecFilename() { void ConsoleOutputTest::testLogSpecFilename() {
stringstream buffer; stringstream buffer;
HeadlessSpecRunner::ConsoleOutput output; ConsoleOutput output;
output.outputIO = &buffer; output.outputIO = &buffer;
output.logSpecFilename("whatever"); output.logSpecFilename("whatever");
@ -84,7 +82,7 @@ namespace HeadlessSpecRunner {
void ConsoleOutputTest::testLogSpecResult() { void ConsoleOutputTest::testLogSpecResult() {
stringstream buffer; stringstream buffer;
HeadlessSpecRunner::ConsoleOutput output; ConsoleOutput output;
output.outputIO = &buffer; output.outputIO = &buffer;
output.logSpecResult("whatever"); output.logSpecResult("whatever");
@ -93,7 +91,7 @@ namespace HeadlessSpecRunner {
void ConsoleOutputTest::testReportResultsFailedSingular() { void ConsoleOutputTest::testReportResultsFailedSingular() {
stringstream buffer; stringstream buffer;
HeadlessSpecRunner::ConsoleOutput output; ConsoleOutput output;
output.outputIO = &buffer; output.outputIO = &buffer;
output.reportFailure("1", "1", "1"); output.reportFailure("1", "1", "1");
@ -102,7 +100,7 @@ namespace HeadlessSpecRunner {
void ConsoleOutputTest::testReportResultsFailedPlural() { void ConsoleOutputTest::testReportResultsFailedPlural() {
stringstream buffer; stringstream buffer;
HeadlessSpecRunner::ConsoleOutput output; ConsoleOutput output;
output.outputIO = &buffer; output.outputIO = &buffer;
output.reportFailure("2", "2", "2"); output.reportFailure("2", "2", "2");
@ -111,7 +109,7 @@ namespace HeadlessSpecRunner {
void ConsoleOutputTest::testReportResultsSucceeded() { void ConsoleOutputTest::testReportResultsSucceeded() {
stringstream buffer; stringstream buffer;
HeadlessSpecRunner::ConsoleOutput output; ConsoleOutput output;
output.outputIO = &buffer; output.outputIO = &buffer;
output.reportSuccess("2", "2", "2"); output.reportSuccess("2", "2", "2");
@ -120,13 +118,12 @@ namespace HeadlessSpecRunner {
void ConsoleOutputTest::testReportResultsSucceededWithJSErrors() { void ConsoleOutputTest::testReportResultsSucceededWithJSErrors() {
stringstream buffer; stringstream buffer;
HeadlessSpecRunner::ConsoleOutput output; ConsoleOutput output;
output.outputIO = &buffer; output.outputIO = &buffer;
output.reportSuccessWithJSErrors("2", "2", "2"); output.reportSuccessWithJSErrors("2", "2", "2");
QVERIFY(buffer.str() == "\nPASS with JS errors: 2 tests, 2 failures, 2 secs.\n"); QVERIFY(buffer.str() == "\nPASS with JS errors: 2 tests, 2 failures, 2 secs.\n");
} }
}
QTEST_MAIN(HeadlessSpecRunner::ConsoleOutputTest); QTEST_MAIN(ConsoleOutputTest);

View File

@ -1,5 +1,5 @@
#ifndef JHW_TEST_PAGE #ifndef JHW_TEST_CONSOLE_OUTPUT
#define JHW_TEST_PAGE #define JHW_TEST_CONSOLE_OUTPUT
#include <QtTest/QtTest> #include <QtTest/QtTest>
#include <iostream> #include <iostream>
@ -8,28 +8,25 @@
#include "ConsoleOutput.h" #include "ConsoleOutput.h"
namespace HeadlessSpecRunner { class ConsoleOutputTest : public QObject {
class ConsoleOutputTest : public QObject { Q_OBJECT
Q_OBJECT public:
public: ConsoleOutputTest();
ConsoleOutputTest();
private slots: private slots:
void testPassed(); void testPassed();
void testFailed(); void testFailed();
void testErrorLog(); void testErrorLog();
void testInternalLog(); void testInternalLog();
void testConsoleLog(); void testConsoleLog();
void testConsoleLogUsed(); void testConsoleLogUsed();
void testLogSpecFilename(); void testLogSpecFilename();
void testLogSpecResult(); void testLogSpecResult();
void testReportResultsFailedSingular(); void testReportResultsFailedSingular();
void testReportResultsFailedPlural(); void testReportResultsFailedPlural();
void testReportResultsSucceeded(); void testReportResultsSucceeded();
void testReportResultsSucceededWithJSErrors(); void testReportResultsSucceededWithJSErrors();
}; };
}
#endif #endif

View File

@ -4,7 +4,6 @@
#include "Page.h" #include "Page.h"
namespace HeadlessSpecRunner {
Page::Page() : QWebPage(), confirmResult(true) {} Page::Page() : QWebPage(), confirmResult(true) {}
void Page::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) { void Page::javaScriptConsoleMessage(const QString &message, int lineNumber, const QString &sourceID) {
@ -28,4 +27,3 @@ namespace HeadlessSpecRunner {
void Page::oneFalseConfirm() { void Page::oneFalseConfirm() {
confirmResult = false; confirmResult = false;
} }
}

View File

@ -4,7 +4,6 @@
#include <QtGui> #include <QtGui>
#include <QtWebKit> #include <QtWebKit>
namespace HeadlessSpecRunner {
class Page: public QWebPage { class Page: public QWebPage {
Q_OBJECT Q_OBJECT
public: public:
@ -20,6 +19,5 @@ namespace HeadlessSpecRunner {
private: private:
bool confirmResult; bool confirmResult;
}; };
}
#endif #endif

View File

@ -3,7 +3,6 @@
#include "Page.h" #include "Page.h"
#include "Page_test.h" #include "Page_test.h"
namespace HeadlessSpecRunner {
PageTest::PageTest() : QObject(), internalLogCalled(false) { PageTest::PageTest() : QObject(), internalLogCalled(false) {
} }
@ -39,7 +38,6 @@ namespace HeadlessSpecRunner {
page.mainFrame()->setHtml("<script>cats();</script>"); page.mainFrame()->setHtml("<script>cats();</script>");
QVERIFY(consoleLogCalled); QVERIFY(consoleLogCalled);
} }
}
QTEST_MAIN(HeadlessSpecRunner::PageTest); QTEST_MAIN(PageTest);

View File

@ -5,7 +5,6 @@
#include "Page.h" #include "Page.h"
namespace HeadlessSpecRunner {
class PageTest : public QObject { class PageTest : public QObject {
Q_OBJECT Q_OBJECT
public: public:
@ -14,7 +13,7 @@ namespace HeadlessSpecRunner {
private: private:
bool internalLogCalled; bool internalLogCalled;
bool consoleLogCalled; bool consoleLogCalled;
HeadlessSpecRunner::Page page; Page page;
private slots: private slots:
void internalLog(const QString &note, const QString &msg); void internalLog(const QString &note, const QString &msg);
@ -23,7 +22,6 @@ namespace HeadlessSpecRunner {
void testJavaScriptConfirmWithoutLog(); void testJavaScriptConfirmWithoutLog();
void testJavaScriptConsoleMessage(); void testJavaScriptConsoleMessage();
}; };
}
#endif #endif

View File

@ -0,0 +1,10 @@
#include "ReportFileOutput.h"
ReportFileOutput::ReportFileOutput() : QObject() {
}
void ReportFileOutput::passed(const QString &specDetail) {
*outputIO << "PASS||" << qPrintable(specDetail) << std::endl;
successes.push(specDetail);
}

View File

@ -0,0 +1,29 @@
#ifndef JHW_REPORT_FILE_OUTPUT
#define JHW_REPORT_FILE_OUTPUT
#include <QObject>
#include <iostream>
#include <QStack>
class ReportFileOutput : public QObject {
public:
ReportFileOutput();
void passed(const QString &specDetail);
void failed(const QString &specDetail);
void errorLog(const QString &msg, int lineNumber, const QString &sourceID);
void internalLog(const QString &note, const QString &msg);
void consoleLog(const QString &msg);
void logSpecFilename(const QString &name);
void logSpecResult(const QString &result);
void reportFailure(const QString &totalTests, const QString &failedTests, const QString &duration);
void reportSuccess(const QString &totalTests, const QString &failedTests, const QString &duration);
void reportSuccessWithJSErrors(const QString &totalTests, const QString &failedTests, const QString &duration);
std::ostream *outputIO;
QStack<QString> successes;
QStack<QString> failures;
};
#endif

View File

@ -0,0 +1,22 @@
#include <QtTest/QtTest>
#include "ReportFileOutput.h"
#include "ReportFileOutput_test.h"
using namespace std;
ReportFileOutputTest::ReportFileOutputTest() : QObject() {}
void ReportFileOutputTest::testPassed() {
stringstream buffer;
ReportFileOutput output;
output.outputIO = &buffer;
output.passed("test||done||file.js:23");
QVERIFY(buffer.str() == "PASS||test||done||file.js:23\n");
QVERIFY(output.successes.size() == 1);
QVERIFY(output.failures.size() == 0);
}
QTEST_MAIN(ReportFileOutputTest);

View File

@ -0,0 +1,19 @@
#ifndef JHW_TEST_REPORT_FILE_OUTPUT
#define JHW_TEST_REPORT_FILE_OUTPUT
#include <QtTest/QtTest>
#include <iostream>
#include <sstream>
#include <string>
#include "ReportFileOutput.h"
class ReportFileOutputTest : public QObject {
Q_OBJECT
public:
ReportFileOutputTest();
private slots:
void testPassed();
};
#endif

View File

@ -0,0 +1,7 @@
include(common.pri)
include(test.pri)
SOURCES += ReportFileOutput_test.cpp
HEADERS += ReportFileOutput_test.h

View File

@ -7,7 +7,6 @@
#include "Runner.h" #include "Runner.h"
namespace HeadlessSpecRunner {
Runner::Runner() : QObject() Runner::Runner() : QObject()
, m_runs(0) , m_runs(0)
, hasErrors(false) , hasErrors(false)
@ -201,5 +200,4 @@ namespace HeadlessSpecRunner {
QApplication::instance()->exit(1); QApplication::instance()->exit(1);
} }
} }
}

View File

@ -10,8 +10,8 @@
#include "Page.h" #include "Page.h"
#include "ConsoleOutput.h" #include "ConsoleOutput.h"
#include "ReportFileOutput.h"
namespace HeadlessSpecRunner {
class Runner: public QObject { class Runner: public QObject {
Q_OBJECT Q_OBJECT
public: public:
@ -38,7 +38,7 @@ namespace HeadlessSpecRunner {
bool hasElement(const char *select); bool hasElement(const char *select);
void timerEvent(QTimerEvent *event); void timerEvent(QTimerEvent *event);
private: private:
HeadlessSpecRunner::Page m_page; Page m_page;
QBasicTimer m_ticker; QBasicTimer m_ticker;
int m_runs; int m_runs;
bool hasErrors; bool hasErrors;
@ -49,10 +49,10 @@ namespace HeadlessSpecRunner {
QString reportFilename; QString reportFilename;
QStack<QString> failedSpecs; QStack<QString> failedSpecs;
HeadlessSpecRunner::ConsoleOutput consoleOutput; ConsoleOutput consoleOutput;
ReportFileOutput reportFileOutput;
void loadSpec(); void loadSpec();
}; };
}
#endif #endif

View File

@ -4,6 +4,6 @@ QMAKE_INFO_PLIST = Info.plist
QMAKESPEC = macx-g++ QMAKESPEC = macx-g++
QT += network webkit QT += network webkit
SOURCES = Page.cpp Runner.cpp ConsoleOutput.cpp SOURCES = Page.cpp Runner.cpp ConsoleOutput.cpp ReportFileOutput.cpp
HEADERS = Page.h Runner.h ConsoleOutput.h HEADERS = Page.h Runner.h ConsoleOutput.h ReportFileOutput.h

View File

@ -54,7 +54,7 @@ int main(int argc, char** argv)
QApplication app(argc, argv); QApplication app(argc, argv);
app.setApplicationName("jasmine-headless-webkit"); app.setApplicationName("jasmine-headless-webkit");
HeadlessSpecRunner::Runner runner; Runner runner;
runner.setColors(showColors); runner.setColors(showColors);
runner.reportFile(reporter); runner.reportFile(reporter);