From 904be27e42c19a7b3b81cc786edfe9342eec204a Mon Sep 17 00:00:00 2001 From: John Bintz Date: Mon, 29 Aug 2011 13:35:36 -0400 Subject: [PATCH] some more c++ cleanup --- .gitignore | 1 + .../ConsoleOutput.cpp | 36 ++++++++++++++- ext/jasmine-webkit-specrunner/ConsoleOutput.h | 5 +++ .../ConsoleOutput_test.cpp | 42 ++++++++++++++++++ .../ConsoleOutput_test.h | 5 ++- ext/jasmine-webkit-specrunner/Page.cpp | 4 +- ext/jasmine-webkit-specrunner/Runner.cpp | 33 +++----------- ext/jasmine-webkit-specrunner/Runner.h | 1 - ext/jasmine-webkit-specrunner/jhw-test | Bin 71104 -> 0 bytes ext/jasmine-webkit-specrunner/test.rb | 18 +++++--- 10 files changed, 107 insertions(+), 38 deletions(-) delete mode 100755 ext/jasmine-webkit-specrunner/jhw-test diff --git a/.gitignore b/.gitignore index 198d3eb..801dd0a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner moc_*.* .DS_Store hydra-runner.log +jhw-test diff --git a/ext/jasmine-webkit-specrunner/ConsoleOutput.cpp b/ext/jasmine-webkit-specrunner/ConsoleOutput.cpp index edca3ce..f6d9804 100644 --- a/ext/jasmine-webkit-specrunner/ConsoleOutput.cpp +++ b/ext/jasmine-webkit-specrunner/ConsoleOutput.cpp @@ -2,7 +2,8 @@ namespace HeadlessSpecRunner { ConsoleOutput::ConsoleOutput() : QObject(), - showColors(false) { + showColors(false), + consoleLogUsed(false) { outputIO = &std::cout; } @@ -12,6 +13,7 @@ namespace HeadlessSpecRunner { clear(); outputIO->flush(); + consoleLogUsed = false; successes.push(specDetail); } @@ -22,6 +24,7 @@ namespace HeadlessSpecRunner { clear(); outputIO->flush(); + consoleLogUsed = false; failures.push(specDetail); } @@ -44,4 +47,35 @@ namespace HeadlessSpecRunner { *outputIO << qPrintable(sourceID) << ":" << lineNumber << " : " << qPrintable(msg); *outputIO << std::endl; } + + void ConsoleOutput::internalLog(const QString ¬e, 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; + consoleLogUsed = true; + } + + green(); + *outputIO << "[console] "; + if (msg.contains("\n")) + *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(); + } } + diff --git a/ext/jasmine-webkit-specrunner/ConsoleOutput.h b/ext/jasmine-webkit-specrunner/ConsoleOutput.h index 5069e4e..51afb93 100644 --- a/ext/jasmine-webkit-specrunner/ConsoleOutput.h +++ b/ext/jasmine-webkit-specrunner/ConsoleOutput.h @@ -13,10 +13,15 @@ namespace HeadlessSpecRunner { void passed(const QString &specDetail); void failed(const QString &specDetail); void errorLog(const QString &msg, int lineNumber, const QString &sourceID); + void internalLog(const QString ¬e, const QString &msg); + void consoleLog(const QString &msg); + void logSpecFilename(const QString &name); + std::ostream *outputIO; QStack successes; QStack failures; bool showColors; + bool consoleLogUsed; private: void green(); void clear(); diff --git a/ext/jasmine-webkit-specrunner/ConsoleOutput_test.cpp b/ext/jasmine-webkit-specrunner/ConsoleOutput_test.cpp index d99d7a8..e833549 100644 --- a/ext/jasmine-webkit-specrunner/ConsoleOutput_test.cpp +++ b/ext/jasmine-webkit-specrunner/ConsoleOutput_test.cpp @@ -13,22 +13,26 @@ namespace HeadlessSpecRunner { stringstream buffer; HeadlessSpecRunner::ConsoleOutput output; + output.consoleLogUsed = true; output.outputIO = &buffer; output.passed("test"); QVERIFY(buffer.str() == "."); QVERIFY(output.successes.size() == 1); QVERIFY(output.failures.size() == 0); + QVERIFY(output.consoleLogUsed == false); } void ConsoleOutputTest::testFailed() { stringstream buffer; HeadlessSpecRunner::ConsoleOutput output; + output.consoleLogUsed = true; output.outputIO = &buffer; output.failed("test"); QVERIFY(buffer.str() == "F"); QVERIFY(output.successes.size() == 0); QVERIFY(output.failures.size() == 1); + QVERIFY(output.consoleLogUsed == false); } void ConsoleOutputTest::testErrorLog() { @@ -39,6 +43,44 @@ namespace HeadlessSpecRunner { output.errorLog("message", 1, "source"); QVERIFY(buffer.str() == "[error] source:1 : message\n"); } + + void ConsoleOutputTest::testInternalLog() { + stringstream buffer; + HeadlessSpecRunner::ConsoleOutput output; + + output.outputIO = &buffer; + output.internalLog("note", "message"); + QVERIFY(buffer.str() == "[note] message\n"); + } + + void ConsoleOutputTest::testConsoleLog() { + stringstream buffer; + HeadlessSpecRunner::ConsoleOutput output; + + output.consoleLogUsed = false; + output.outputIO = &buffer; + output.consoleLog("log"); + QVERIFY(buffer.str() == "\n[console] log\n"); + } + + void ConsoleOutputTest::testConsoleLogUsed() { + stringstream buffer; + HeadlessSpecRunner::ConsoleOutput output; + + output.consoleLogUsed = true; + output.outputIO = &buffer; + output.consoleLog("log"); + QVERIFY(buffer.str() == "[console] log\n"); + } + + void ConsoleOutputTest::testLogSpecFilename() { + stringstream buffer; + HeadlessSpecRunner::ConsoleOutput output; + + output.outputIO = &buffer; + output.logSpecFilename("whatever"); + QVERIFY(buffer.str() == "\n\nwhatever\n"); + } } QTEST_MAIN(HeadlessSpecRunner::ConsoleOutputTest); diff --git a/ext/jasmine-webkit-specrunner/ConsoleOutput_test.h b/ext/jasmine-webkit-specrunner/ConsoleOutput_test.h index 1537eea..3e13942 100644 --- a/ext/jasmine-webkit-specrunner/ConsoleOutput_test.h +++ b/ext/jasmine-webkit-specrunner/ConsoleOutput_test.h @@ -18,9 +18,12 @@ namespace HeadlessSpecRunner { void testPassed(); void testFailed(); void testErrorLog(); + void testInternalLog(); + void testConsoleLog(); + void testConsoleLogUsed(); + void testLogSpecFilename(); }; } #endif - diff --git a/ext/jasmine-webkit-specrunner/Page.cpp b/ext/jasmine-webkit-specrunner/Page.cpp index 6b9f91e..d277e21 100644 --- a/ext/jasmine-webkit-specrunner/Page.cpp +++ b/ext/jasmine-webkit-specrunner/Page.cpp @@ -11,7 +11,7 @@ namespace HeadlessSpecRunner { emit consoleLog(message, lineNumber, sourceID); } - bool Page::javaScriptConfirm(QWebFrame *frame, const QString &msg) { + 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; @@ -21,7 +21,7 @@ namespace HeadlessSpecRunner { } } - void Page::javaScriptAlert(QWebFrame *frame, const QString &msg) { + void Page::javaScriptAlert(QWebFrame*, const QString &msg) { emit internalLog("alert", msg); } diff --git a/ext/jasmine-webkit-specrunner/Runner.cpp b/ext/jasmine-webkit-specrunner/Runner.cpp index 7330bae..e129505 100644 --- a/ext/jasmine-webkit-specrunner/Runner.cpp +++ b/ext/jasmine-webkit-specrunner/Runner.cpp @@ -14,8 +14,7 @@ namespace HeadlessSpecRunner { , usedConsole(false) , showColors(false) , isFinished(false) - , didFail(false) - , consoleNotUsedThisRun(false) { + , didFail(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))); @@ -100,13 +99,11 @@ namespace HeadlessSpecRunner { void Runner::specPassed() { - consoleNotUsedThisRun = true; consoleOutput.passed(""); } void Runner::specFailed(const QString &specDetail) { - consoleNotUsedThisRun = true; consoleOutput.failed(""); didFail = true; failedSpecs.push(specDetail); @@ -122,45 +119,25 @@ namespace HeadlessSpecRunner { } void Runner::internalLog(const QString ¬e, const QString &msg) { - red(); - std::cout << "[" << qPrintable(note) << "] "; - clear(); - std::cout << qPrintable(msg); - std::cout << std::endl; + consoleOutput.internalLog(note, msg); } 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; + consoleOutput.consoleLog(msg); } void Runner::leavePageAttempt(const QString &msg) { - red(); - std::cout << "[error] "; - clear(); - std::cout << qPrintable(msg) << std::endl; + consoleOutput.internalLog("error", msg); 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(); + consoleOutput.logSpecFilename(name); } void Runner::printResult(const QString &result) diff --git a/ext/jasmine-webkit-specrunner/Runner.h b/ext/jasmine-webkit-specrunner/Runner.h index c00e575..9c76fd0 100644 --- a/ext/jasmine-webkit-specrunner/Runner.h +++ b/ext/jasmine-webkit-specrunner/Runner.h @@ -46,7 +46,6 @@ namespace HeadlessSpecRunner { bool showColors; bool isFinished; bool didFail; - bool consoleNotUsedThisRun; QQueue runnerFiles; QString reportFilename; QStack failedSpecs; diff --git a/ext/jasmine-webkit-specrunner/jhw-test b/ext/jasmine-webkit-specrunner/jhw-test deleted file mode 100755 index 763649ba23d54b8756b9afb697e0f2420e51e09f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 71104 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