diff --git a/.gitignore b/.gitignore index 801dd0a..b523b09 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ moc_*.* .DS_Store hydra-runner.log jhw-test +.jhw-cache/ diff --git a/Guardfile b/Guardfile index 1488233..1a2ca0d 100644 --- a/Guardfile +++ b/Guardfile @@ -26,7 +26,8 @@ guard 'jasmine-headless-webkit', :all_on_start => false do 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/ReportFileOutput.cpp b/ext/jasmine-webkit-specrunner/ReportFileOutput.cpp index 5093ed1..b215e47 100644 --- a/ext/jasmine-webkit-specrunner/ReportFileOutput.cpp +++ b/ext/jasmine-webkit-specrunner/ReportFileOutput.cpp @@ -1,10 +1,54 @@ #include "ReportFileOutput.h" +using namespace std; + ReportFileOutput::ReportFileOutput() : QObject() { + reset(); +} + +void ReportFileOutput::reset() { + buffer = new stringstream(); + outputIO = buffer; } void ReportFileOutput::passed(const QString &specDetail) { *outputIO << "PASS||" << qPrintable(specDetail) << std::endl; successes.push(specDetail); } + +void ReportFileOutput::failed(const QString &specDetail) { + *outputIO << "FAIL||" << qPrintable(specDetail) << std::endl; + failures.push(specDetail); +} + +void ReportFileOutput::errorLog(const QString &msg, int lineNumber, const QString &sourceID) { + *outputIO << "ERROR||" << qPrintable(msg) << "||" << qPrintable(sourceID) << ":" << lineNumber << std::endl; +} + +void ReportFileOutput::consoleLog(const QString &msg) { + *outputIO << "CONSOLE||" << qPrintable(msg) << std::endl; +} + +void ReportFileOutput::internalLog(const QString &, const QString &) {} +void ReportFileOutput::logSpecFilename(const QString &) {} +void ReportFileOutput::logSpecResult(const QString &) {} + +void ReportFileOutput::reportFailure(const QString &totalTests, const QString &failedTests, const QString &duration) { + reportTotals(totalTests, failedTests, duration, false); +} + +void ReportFileOutput::reportSuccess(const QString &totalTests, const QString &failedTests, const QString &duration) { + reportTotals(totalTests, failedTests, duration, false); +} + +void ReportFileOutput::reportSuccessWithJSErrors(const QString &totalTests, const QString &failedTests, const QString &duration) { + reportTotals(totalTests, failedTests, duration, true); +} + +void ReportFileOutput::reportTotals(const QString &totalTests, const QString &failedTests, const QString &duration, bool hasJavaScriptError) { + *outputIO << "TOTAL||" << qPrintable(totalTests) << "||" << qPrintable(failedTests) << "||" << qPrintable(duration) << "||"; + *outputIO << (hasJavaScriptError ? "T" : "F"); + *outputIO << std::endl; +} + diff --git a/ext/jasmine-webkit-specrunner/ReportFileOutput.h b/ext/jasmine-webkit-specrunner/ReportFileOutput.h index fedf612..30b4f02 100644 --- a/ext/jasmine-webkit-specrunner/ReportFileOutput.h +++ b/ext/jasmine-webkit-specrunner/ReportFileOutput.h @@ -4,6 +4,9 @@ #include #include #include +#include + +using namespace std; class ReportFileOutput : public QObject { public: @@ -21,9 +24,14 @@ class ReportFileOutput : public QObject { 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; + void reset(); + + stringstream *buffer; + stringstream *outputIO; QStack successes; QStack failures; + private: + void reportTotals(const QString &totalTests, const QString &failedTests, const QString &duration, bool hasJavaScriptError); }; #endif diff --git a/ext/jasmine-webkit-specrunner/ReportFileOutput_test.cpp b/ext/jasmine-webkit-specrunner/ReportFileOutput_test.cpp index 5f3fa3d..bc5b9e4 100644 --- a/ext/jasmine-webkit-specrunner/ReportFileOutput_test.cpp +++ b/ext/jasmine-webkit-specrunner/ReportFileOutput_test.cpp @@ -23,11 +23,66 @@ void ReportFileOutputTest::testFailed() { ReportFileOutput output; output.outputIO = &buffer; - output.passed("test||done||file.js:23"); + output.failed("test||done||file.js:23"); QVERIFY(buffer.str() == "FAIL||test||done||file.js:23\n"); QVERIFY(output.successes.size() == 0); QVERIFY(output.failures.size() == 1); } +void ReportFileOutputTest::testErrorLog() { + stringstream buffer; + ReportFileOutput output; + + output.outputIO = &buffer; + output.errorLog("JS Error", 23, "file.js"); + QVERIFY(buffer.str() == "ERROR||JS Error||file.js:23\n"); +} + +void ReportFileOutputTest::testConsoleLog() { + stringstream buffer; + ReportFileOutput output; + + output.outputIO = &buffer; + output.consoleLog("Console"); + QVERIFY(buffer.str() == "CONSOLE||Console\n"); +} + +void ReportFileOutputTest::testStubMethods() { + stringstream buffer; + ReportFileOutput output; + + output.outputIO = &buffer; + output.internalLog("Internal", "Log"); + output.logSpecFilename("Filename"); + output.logSpecResult("REsult"); +} + +void ReportFileOutputTest::testReportFailure() { + stringstream buffer; + ReportFileOutput output; + + output.outputIO = &buffer; + output.reportFailure("5", "2", "1.5"); + QVERIFY(buffer.str() == "TOTAL||5||2||1.5||F\n"); +} + +void ReportFileOutputTest::testReportSuccess() { + stringstream buffer; + ReportFileOutput output; + + output.outputIO = &buffer; + output.reportSuccess("5", "0", "1.5"); + QVERIFY(buffer.str() == "TOTAL||5||0||1.5||F\n"); +} + +void ReportFileOutputTest::testReportSuccessWithJSErrors() { + stringstream buffer; + ReportFileOutput output; + + output.outputIO = &buffer; + output.reportSuccessWithJSErrors("5", "0", "1.5"); + QVERIFY(buffer.str() == "TOTAL||5||0||1.5||T\n"); +} + QTEST_MAIN(ReportFileOutputTest); diff --git a/ext/jasmine-webkit-specrunner/ReportFileOutput_test.h b/ext/jasmine-webkit-specrunner/ReportFileOutput_test.h index 25dee7d..8b46a60 100644 --- a/ext/jasmine-webkit-specrunner/ReportFileOutput_test.h +++ b/ext/jasmine-webkit-specrunner/ReportFileOutput_test.h @@ -15,6 +15,12 @@ class ReportFileOutputTest : public QObject { private slots: void testPassed(); void testFailed(); + void testErrorLog(); + void testConsoleLog(); + void testStubMethods(); + void testReportFailure(); + void testReportSuccess(); + void testReportSuccessWithJSErrors(); }; #endif diff --git a/ext/jasmine-webkit-specrunner/Runner.cpp b/ext/jasmine-webkit-specrunner/Runner.cpp index d633449..a5cd6a7 100644 --- a/ext/jasmine-webkit-specrunner/Runner.cpp +++ b/ext/jasmine-webkit-specrunner/Runner.cpp @@ -7,197 +7,195 @@ #include "Runner.h" - Runner::Runner() : QObject() - , m_runs(0) - , hasErrors(false) - , usedConsole(false) - , isFinished(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))); - 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; +using namespace std; + +Runner::Runner() : QObject() + , m_runs(0) + , hasErrors(false) + , usedConsole(false) + , isFinished(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))); + 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) { + consoleOutput.showColors = colors; +} + +void Runner::reportFile(const QString &file) { + reportFileName = file; +} + +bool Runner::hasError() { + return hasErrors; +} + +void Runner::specPassed(const QString &specDetail) { + consoleOutput.passed(specDetail); + reportFileOutput.passed(specDetail); +} + +void Runner::specFailed(const QString &specDetail) { + consoleOutput.failed(specDetail); + reportFileOutput.failed(specDetail); + + didFail = true; + failedSpecs.push(specDetail); +} + +void Runner::errorLog(const QString &msg, int lineNumber, const QString &sourceID) +{ + consoleOutput.errorLog(msg, lineNumber, sourceID); + reportFileOutput.errorLog(msg, lineNumber, sourceID); + + hasErrors = true; + m_runs = 0; + m_ticker.start(200, this); +} + +void Runner::internalLog(const QString ¬e, const QString &msg) { + consoleOutput.internalLog(note, msg); + reportFileOutput.internalLog(note, msg); +} + +void Runner::log(const QString &msg) +{ + usedConsole = true; + consoleOutput.consoleLog(msg); + reportFileOutput.consoleLog(msg); +} + +void Runner::leavePageAttempt(const QString &msg) +{ + consoleOutput.internalLog("error", msg); + m_page.oneFalseConfirm(); + hasErrors = true; +} + +void Runner::printName(const QString &name) +{ + consoleOutput.logSpecFilename(name); +} + +void Runner::printResult(const QString &result) +{ + consoleOutput.logSpecResult(result); +} + +void Runner::finishSuite(const QString &duration, const QString &total, const QString& failed) +{ + if (didFail) { + consoleOutput.reportFailure(total, failed, duration); + reportFileOutput.reportFailure(total, failed, duration); + } else { + if (hasErrors) { + consoleOutput.reportSuccessWithJSErrors(total, failed, duration); + reportFileOutput.reportSuccessWithJSErrors(total, failed, duration); + } else { + consoleOutput.reportSuccess(total, failed, duration); + reportFileOutput.reportSuccess(total, failed, duration); } - - m_ticker.start(200, this); - } - - bool Runner::hasElement(const char *select) - { - return !m_page.mainFrame()->findFirstElement(select).isNull(); - } - - void Runner::setColors(bool colors) - { - consoleOutput.showColors = colors; } - void Runner::reportFile(const QString &file) - { - reportFilename = file; - } + if (!reportFileName.isEmpty()) { + QFile outputFile(reportFileName); + outputFile.open(QIODevice::WriteOnly); - bool Runner::hasError() { - return hasErrors; - } + QTextStream ts(&outputFile); - void Runner::specPassed() - { - consoleOutput.passed(""); - } + ts << reportFileOutput.outputIO->str().c_str(); - void Runner::specFailed(const QString &specDetail) - { - consoleOutput.failed(""); - didFail = true; - failedSpecs.push(specDetail); + outputFile.close(); } - void Runner::errorLog(const QString &msg, int lineNumber, const QString &sourceID) - { - consoleOutput.errorLog(msg, lineNumber, sourceID); + isFinished = true; +} - hasErrors = true; - m_runs = 0; - m_ticker.start(200, this); - } - - void Runner::internalLog(const QString ¬e, const QString &msg) { - consoleOutput.internalLog(note, msg); - } +void Runner::timerEvent(QTimerEvent *event) +{ + ++m_runs; - void Runner::log(const QString &msg) - { - usedConsole = true; - consoleOutput.consoleLog(msg); - } + if (event->timerId() != m_ticker.timerId()) + return; - void Runner::leavePageAttempt(const QString &msg) - { - consoleOutput.internalLog("error", msg); - m_page.oneFalseConfirm(); - hasErrors = true; - } + if (hasErrors && m_runs > 2) + QApplication::instance()->exit(1); - void Runner::printName(const QString &name) - { - consoleOutput.logSpecFilename(name); - } - - void Runner::printResult(const QString &result) - { - consoleOutput.logSpecResult(result); - } - - void Runner::finishSuite(const QString &duration, const QString &total, const QString& failed) - { - if (didFail) { - consoleOutput.reportFailure(total, failed, duration); + if (isFinished) { + int exitCode = 0; + if (didFail || hasErrors) { + exitCode = 1; } else { - if (hasErrors) { - consoleOutput.reportSuccessWithJSErrors(total, failed, duration); - } else { - consoleOutput.reportSuccess(total, failed, duration); - } - } - - 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(); + if (usedConsole) { + exitCode = 2; } } - isFinished = true; - } - - void Runner::timerEvent(QTimerEvent *event) - { - ++m_runs; + bool runAgain = true; - 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) { + if (runnerFiles.count() == 0) { + runAgain = false; + } else { + if (exitCode == 1) { 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); + 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/Runner.h b/ext/jasmine-webkit-specrunner/Runner.h index bb78b5f..8642fdb 100644 --- a/ext/jasmine-webkit-specrunner/Runner.h +++ b/ext/jasmine-webkit-specrunner/Runner.h @@ -6,53 +6,57 @@ #include #include #include +#include #include #include "Page.h" #include "ConsoleOutput.h" #include "ReportFileOutput.h" - class Runner: public QObject { - Q_OBJECT - public: - Runner(); - void setColors(bool colors); - void reportFile(const QString &file); - void addFile(const QString &spec); - void go(); +using namespace std; + +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); - bool hasError(); - 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); + bool hasError(); + void leavePageAttempt(const QString &msg); + void specPassed(const QString &specDetail); + 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: - Page m_page; - QBasicTimer m_ticker; - int m_runs; - bool hasErrors; - bool usedConsole; - bool isFinished; - bool didFail; - QQueue runnerFiles; - QString reportFilename; - QStack failedSpecs; - - ConsoleOutput consoleOutput; - ReportFileOutput reportFileOutput; - - void loadSpec(); - }; + 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: + Page m_page; + QBasicTimer m_ticker; + int m_runs; + bool hasErrors; + bool usedConsole; + bool isFinished; + bool didFail; + QQueue runnerFiles; + QStack failedSpecs; + + ConsoleOutput consoleOutput; + ReportFileOutput reportFileOutput; + + QString reportFileName; + + void loadSpec(); +}; #endif diff --git a/ext/jasmine-webkit-specrunner/specrunner.cpp b/ext/jasmine-webkit-specrunner/specrunner.cpp index 66dd7a0..b144a30 100644 --- a/ext/jasmine-webkit-specrunner/specrunner.cpp +++ b/ext/jasmine-webkit-specrunner/specrunner.cpp @@ -56,11 +56,13 @@ int main(int argc, char** argv) app.setApplicationName("jasmine-headless-webkit"); Runner runner; runner.setColors(showColors); + runner.reportFile(reporter); for (index = optind; index < argc; index++) { runner.addFile(QString::fromLocal8Bit(argv[index])); } + runner.go(); return app.exec(); diff --git a/jasmine/jasmine.headless-reporter.coffee b/jasmine/jasmine.headless-reporter.coffee index 74517e1..f1e8d31 100644 --- a/jasmine/jasmine.headless-reporter.coffee +++ b/jasmine/jasmine.headless-reporter.coffee @@ -8,19 +8,19 @@ class window.HeadlessReporterResult @results.push(message) print: -> output = @name - bestChoice = this._findSpecLine() + bestChoice = HeadlessReporterResult.findSpecLine(@splitName) output += " (#{bestChoice.file}:#{bestChoice.lineNumber})" if bestChoice.file JHW.printName(output) for result in @results JHW.printResult(result) - _findSpecLine: -> + @findSpecLine: (splitName) -> bestChoice = { accuracy: 0, file: null, lineNumber: null } for file, lines of HeadlessReporterResult.specLineNumbers index = 0 lineNumber = 0 - while newLineNumberInfo = lines[@splitName[index]] + while newLineNumberInfo = lines[splitName[index]] if newLineNumberInfo.length == 0 lineNumber = newLineNumberInfo[0] else @@ -40,14 +40,20 @@ class window.HeadlessReporterResult jasmine.Suite.prototype.getSuiteSplitName = -> parts = if @parentSuite then @parentSuite.getSuiteSplitName() else [] - parts.push(@description) + parts.push(String(@description).replace(/[\n\r]/g, ' ')) parts jasmine.Spec.prototype.getSpecSplitName = -> parts = @suite.getSuiteSplitName() - parts.push(@description) + 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("||") + class jasmine.HeadlessReporter constructor: (@callback = null) -> @results = [] @@ -61,27 +67,31 @@ class jasmine.HeadlessReporter this.callback() if @callback JHW.finishSuite((new Date() - @startTime) / 1000.0, @length, @failedCount) + reportRunnerStarting: (runner) -> @startTime = new Date() + reportSpecResults: (spec) -> return if this.hasError() results = spec.results() @length++ if results.passed() - JHW.specPassed() + JHW.specPassed(spec.getJHWSpecInformation()) else - JHW.specFailed(spec.getSpecSplitName().join('||')) + JHW.specFailed(spec.getJHWSpecInformation()) @failedCount++ failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName()) for result in results.getItems() if result.type == 'expect' and !result.passed_ failureResult.addResult(result.message) @results.push(failureResult) + reportSpecStarting: (spec) -> if this.hasError() spec.finish() spec.suite.finish() + reportSuiteResults: (suite) -> hasError: -> JHW.hasError() diff --git a/jasmine/jasmine.headless-reporter.js b/jasmine/jasmine.headless-reporter.js index 574b632..003924c 100644 --- a/jasmine/jasmine.headless-reporter.js +++ b/jasmine/jasmine.headless-reporter.js @@ -14,7 +14,7 @@ HeadlessReporterResult.prototype.print = function() { var bestChoice, output, result, _i, _len, _ref, _results; output = this.name; - bestChoice = this._findSpecLine(); + bestChoice = HeadlessReporterResult.findSpecLine(this.splitName); if (bestChoice.file) { output += " (" + bestChoice.file + ":" + bestChoice.lineNumber + ")"; } @@ -27,7 +27,7 @@ } return _results; }; - HeadlessReporterResult.prototype._findSpecLine = function() { + HeadlessReporterResult.findSpecLine = function(splitName) { var bestChoice, file, index, lastLine, line, lineNumber, lines, newLineNumberInfo, _i, _len, _ref; bestChoice = { accuracy: 0, @@ -39,7 +39,7 @@ lines = _ref[file]; index = 0; lineNumber = 0; - while (newLineNumberInfo = lines[this.splitName[index]]) { + while (newLineNumberInfo = lines[splitName[index]]) { if (newLineNumberInfo.length === 0) { lineNumber = newLineNumberInfo[0]; } else { @@ -70,15 +70,22 @@ jasmine.Suite.prototype.getSuiteSplitName = function() { var parts; parts = this.parentSuite ? this.parentSuite.getSuiteSplitName() : []; - parts.push(this.description); + parts.push(String(this.description).replace(/[\n\r]/g, ' ')); return parts; }; jasmine.Spec.prototype.getSpecSplitName = function() { var parts; parts = this.suite.getSuiteSplitName(); - parts.push(this.description); + 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; @@ -112,9 +119,9 @@ results = spec.results(); this.length++; if (results.passed()) { - return JHW.specPassed(); + return JHW.specPassed(spec.getJHWSpecInformation()); } else { - JHW.specFailed(spec.getSpecSplitName().join('||')); + JHW.specFailed(spec.getJHWSpecInformation()); this.failedCount++; failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName()); _ref = results.getItems(); diff --git a/spec/javascripts/jasmine.headless-reporter_spec.coffee b/spec/javascripts/jasmine.headless-reporter_spec.coffee index e58b911..aa623e2 100644 --- a/spec/javascripts/jasmine.headless-reporter_spec.coffee +++ b/spec/javascripts/jasmine.headless-reporter_spec.coffee @@ -9,11 +9,8 @@ describe 'HeadlessReporterResult', -> } } it 'should find the best spec lines', -> - result = new HeadlessReporterResult('test', [ 'name', 'of', 'test' ]) - expect(result._findSpecLine().lineNumber).toEqual(3) - - result = new HeadlessReporterResult('test', [ 'other', 'of', 'test' ]) - expect(result._findSpecLine().lineNumber).toEqual(10) + expect(HeadlessReporterResult.findSpecLine([ 'name', 'of', 'test' ]).lineNumber).toEqual(3) + expect(HeadlessReporterResult.findSpecLine([ 'other', 'of', 'test' ]).lineNumber).toEqual(10) describe 'jasmine.HeadlessReporter', -> reporter = null @@ -36,3 +33,31 @@ describe 'jasmine.HeadlessReporter', -> expect(spec.finish).toHaveBeenCalled() expect(suite.finish).toHaveBeenCalled() +describe 'jasmine.Suite.prototype.getSuiteSplitName', -> + it 'should flatten the description', -> + suite = new jasmine.Suite({}); + suite.description = "hello\ngoodbye\n"; + expect(suite.getSuiteSplitName()).toEqual([ "hello goodbye " ]) + + it 'should not fail on missing description', -> + suite = new jasmine.Suite({}); + suite.description = 1; + expect(suite.getSuiteSplitName()).toEqual([ "1" ]) + +describe 'jasmine.Spec.prototype.getSuiteSplitName', -> + it 'should flatten the description', -> + spec = new jasmine.Spec({}, {}); + spec.suite = { + getSuiteSplitName: -> [] + } + spec.description = "hello\ngoodbye\n"; + expect(spec.getSpecSplitName()).toEqual([ "hello goodbye " ]) + + it 'should not fail on missing description', -> + spec = new jasmine.Spec({}, {}); + spec.suite = { + getSuiteSplitName: -> [] + } + spec.description = 1 + expect(spec.getSpecSplitName()).toEqual([ "1" ]) + diff --git a/spec/lib/jasmine/headless/report_spec.rb b/spec/lib/jasmine/headless/report_spec.rb new file mode 100644 index 0000000..f6424f5 --- /dev/null +++ b/spec/lib/jasmine/headless/report_spec.rb @@ -0,0 +1,18 @@ +require 'spec_helper' + +describe Jasmine::Headless::Report do + include FakeFS::SpecHelpers + + describe '.load' do + context 'no file' do + it 'should raise an exception' do + expect { described_class.load(file) }.to raise_error(Errno::ENOENT) + end + end + + context 'file' do + + end + end +end +