merge in the new file handle approach, try it and let me know where it breaks
This commit is contained in:
commit
c7ce823409
@ -3,6 +3,8 @@
|
|||||||
# watch('file/path') { `command(s)` }
|
# watch('file/path') { `command(s)` }
|
||||||
#
|
#
|
||||||
|
|
||||||
|
guard 'coffeescript', :input => 'vendor/assets/coffeescripts', :output => 'vendor/assets/javascripts'
|
||||||
|
|
||||||
guard 'shell' do
|
guard 'shell' do
|
||||||
watch(%r{ext/jasmine-webkit-specrunner/.*\.(cpp|h|pro|pri)}) { |m|
|
watch(%r{ext/jasmine-webkit-specrunner/.*\.(cpp|h|pro|pri)}) { |m|
|
||||||
if !m[0]['moc_']
|
if !m[0]['moc_']
|
||||||
@ -27,9 +29,8 @@ end
|
|||||||
|
|
||||||
def compile
|
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 test.rb && ruby extconf.rb}
|
system %{cd ext/jasmine-webkit-specrunner && ruby extconf.rb}
|
||||||
end
|
end
|
||||||
|
|
||||||
compile
|
compile
|
||||||
|
|
||||||
guard 'coffeescript', :input => 'jasmine'
|
|
||||||
|
@ -18,7 +18,6 @@ begin
|
|||||||
files_list = Jasmine::FilesList.new(:config => runner.jasmine_config)
|
files_list = Jasmine::FilesList.new(:config => runner.jasmine_config)
|
||||||
files_list.files.each { |file| puts file }
|
files_list.files.each { |file| puts file }
|
||||||
else
|
else
|
||||||
puts "Running Jasmine specs...".color(:white)
|
|
||||||
exit runner.run
|
exit runner.run
|
||||||
end
|
end
|
||||||
rescue CoffeeScript::CompilationError
|
rescue CoffeeScript::CompilationError
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
bundle exec rake
|
|
||||||
if [ $? -ne 0 ]; then exit 1; fi
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
for i in $PWD/dev-bin/hooks/*; do
|
|
||||||
ln -sf $i .git/hooks/${i##*/}
|
|
||||||
done
|
|
||||||
|
|
@ -1,149 +0,0 @@
|
|||||||
#include "ConsoleOutput.h"
|
|
||||||
|
|
||||||
ConsoleOutput::ConsoleOutput() : QObject(),
|
|
||||||
showColors(false),
|
|
||||||
consoleLogUsed(false) {
|
|
||||||
outputIO = &std::cout;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutput::passed(const QString &specDetail) {
|
|
||||||
green();
|
|
||||||
*outputIO << '.';
|
|
||||||
clear();
|
|
||||||
outputIO->flush();
|
|
||||||
|
|
||||||
consoleLogUsed = false;
|
|
||||||
successes.push(specDetail);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutput::failed(const QString &specDetail) {
|
|
||||||
red();
|
|
||||||
*outputIO << 'F';
|
|
||||||
clear();
|
|
||||||
outputIO->flush();
|
|
||||||
|
|
||||||
consoleLogUsed = false;
|
|
||||||
failures.push(specDetail);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutput::green() {
|
|
||||||
if (showColors) std::cout << "\033[0;32m";
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutput::clear() {
|
|
||||||
if (showColors) std::cout << "\033[m";
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutput::red() {
|
|
||||||
if (showColors) std::cout << "\033[0;31m";
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutput::yellow()
|
|
||||||
{
|
|
||||||
if (showColors) std::cout << "\033[0;33m";
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutput::errorLog(const QString &msg, int lineNumber, const QString &sourceID) {
|
|
||||||
red();
|
|
||||||
*outputIO << "[error] ";
|
|
||||||
clear();
|
|
||||||
*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();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutput::logSpecResult(const QString &result) {
|
|
||||||
QStringList lines = result.split("\n");
|
|
||||||
QStringListIterator linesIterator(lines);
|
|
||||||
|
|
||||||
red();
|
|
||||||
while (linesIterator.hasNext()) {
|
|
||||||
QString line = linesIterator.next();
|
|
||||||
if (!linesIterator.hasNext())
|
|
||||||
yellow();
|
|
||||||
*outputIO << " " << qPrintable(line) << 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";
|
|
||||||
}
|
|
||||||
|
|
||||||
*outputIO << ", ";
|
|
||||||
|
|
||||||
*outputIO << qPrintable(failedTests) << " ";
|
|
||||||
if (failedTests == "1") {
|
|
||||||
*outputIO << "failure";
|
|
||||||
} else {
|
|
||||||
*outputIO << "failures";
|
|
||||||
}
|
|
||||||
|
|
||||||
*outputIO << ", ";
|
|
||||||
|
|
||||||
*outputIO << qPrintable(duration) << " ";
|
|
||||||
if (duration == "1") {
|
|
||||||
*outputIO << "sec.";
|
|
||||||
} else {
|
|
||||||
*outputIO << "secs.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
#ifndef JHW_CONSOLE_OUTPUT
|
|
||||||
#define JHW_CONSOLE_OUTPUT
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <iostream>
|
|
||||||
#include <QStack>
|
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
class ConsoleOutput : public QObject {
|
|
||||||
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 ¬e, 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;
|
|
||||||
|
|
||||||
bool showColors;
|
|
||||||
bool consoleLogUsed;
|
|
||||||
private:
|
|
||||||
void green();
|
|
||||||
void clear();
|
|
||||||
void red();
|
|
||||||
void yellow();
|
|
||||||
void formatTestResults(const QString &totalTests, const QString &failedTests, const QString &duration);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,129 +0,0 @@
|
|||||||
#include <QtTest/QtTest>
|
|
||||||
|
|
||||||
#include "ConsoleOutput.h"
|
|
||||||
#include "ConsoleOutput_test.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
ConsoleOutputTest::ConsoleOutputTest() : QObject() {}
|
|
||||||
|
|
||||||
void ConsoleOutputTest::testPassed() {
|
|
||||||
stringstream buffer;
|
|
||||||
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;
|
|
||||||
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() {
|
|
||||||
stringstream buffer;
|
|
||||||
ConsoleOutput output;
|
|
||||||
|
|
||||||
output.outputIO = &buffer;
|
|
||||||
output.errorLog("message", 1, "source");
|
|
||||||
QVERIFY(buffer.str() == "[error] source:1 : message\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutputTest::testInternalLog() {
|
|
||||||
stringstream buffer;
|
|
||||||
ConsoleOutput output;
|
|
||||||
|
|
||||||
output.outputIO = &buffer;
|
|
||||||
output.internalLog("note", "message");
|
|
||||||
QVERIFY(buffer.str() == "[note] message\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutputTest::testConsoleLog() {
|
|
||||||
stringstream buffer;
|
|
||||||
ConsoleOutput output;
|
|
||||||
|
|
||||||
output.consoleLogUsed = false;
|
|
||||||
output.outputIO = &buffer;
|
|
||||||
output.consoleLog("log");
|
|
||||||
QVERIFY(buffer.str() == "\n[console] log\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutputTest::testConsoleLogUsed() {
|
|
||||||
stringstream buffer;
|
|
||||||
ConsoleOutput output;
|
|
||||||
|
|
||||||
output.consoleLogUsed = true;
|
|
||||||
output.outputIO = &buffer;
|
|
||||||
output.consoleLog("log");
|
|
||||||
QVERIFY(buffer.str() == "[console] log\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutputTest::testLogSpecFilename() {
|
|
||||||
stringstream buffer;
|
|
||||||
ConsoleOutput output;
|
|
||||||
|
|
||||||
output.outputIO = &buffer;
|
|
||||||
output.logSpecFilename("whatever");
|
|
||||||
QVERIFY(buffer.str() == "\n\nwhatever\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutputTest::testLogSpecResult() {
|
|
||||||
stringstream buffer;
|
|
||||||
ConsoleOutput output;
|
|
||||||
|
|
||||||
output.outputIO = &buffer;
|
|
||||||
output.logSpecResult("whatever");
|
|
||||||
QVERIFY(buffer.str() == " whatever\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutputTest::testReportResultsFailedSingular() {
|
|
||||||
stringstream buffer;
|
|
||||||
ConsoleOutput output;
|
|
||||||
|
|
||||||
output.outputIO = &buffer;
|
|
||||||
output.reportFailure("1", "1", "1");
|
|
||||||
QVERIFY(buffer.str() == "\nFAIL: 1 test, 1 failure, 1 sec.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutputTest::testReportResultsFailedPlural() {
|
|
||||||
stringstream buffer;
|
|
||||||
ConsoleOutput output;
|
|
||||||
|
|
||||||
output.outputIO = &buffer;
|
|
||||||
output.reportFailure("2", "2", "2");
|
|
||||||
QVERIFY(buffer.str() == "\nFAIL: 2 tests, 2 failures, 2 secs.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutputTest::testReportResultsSucceeded() {
|
|
||||||
stringstream buffer;
|
|
||||||
ConsoleOutput output;
|
|
||||||
|
|
||||||
output.outputIO = &buffer;
|
|
||||||
output.reportSuccess("2", "2", "2");
|
|
||||||
QVERIFY(buffer.str() == "\nPASS: 2 tests, 2 failures, 2 secs.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConsoleOutputTest::testReportResultsSucceededWithJSErrors() {
|
|
||||||
stringstream buffer;
|
|
||||||
ConsoleOutput output;
|
|
||||||
|
|
||||||
output.outputIO = &buffer;
|
|
||||||
output.reportSuccessWithJSErrors("2", "2", "2");
|
|
||||||
QVERIFY(buffer.str() == "\nPASS with JS errors: 2 tests, 2 failures, 2 secs.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
QTEST_MAIN(ConsoleOutputTest);
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
#ifndef JHW_TEST_CONSOLE_OUTPUT
|
|
||||||
#define JHW_TEST_CONSOLE_OUTPUT
|
|
||||||
|
|
||||||
#include <QtTest/QtTest>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "ConsoleOutput.h"
|
|
||||||
|
|
||||||
class ConsoleOutputTest : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
ConsoleOutputTest();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void testPassed();
|
|
||||||
void testFailed();
|
|
||||||
void testErrorLog();
|
|
||||||
void testInternalLog();
|
|
||||||
void testConsoleLog();
|
|
||||||
void testConsoleLogUsed();
|
|
||||||
void testLogSpecFilename();
|
|
||||||
void testLogSpecResult();
|
|
||||||
|
|
||||||
void testReportResultsFailedSingular();
|
|
||||||
void testReportResultsFailedPlural();
|
|
||||||
void testReportResultsSucceeded();
|
|
||||||
void testReportResultsSucceededWithJSErrors();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,7 +0,0 @@
|
|||||||
include(common.pri)
|
|
||||||
include(test.pri)
|
|
||||||
|
|
||||||
SOURCES += ConsoleOutput_test.cpp
|
|
||||||
HEADERS += ConsoleOutput_test.h
|
|
||||||
|
|
||||||
|
|
@ -4,26 +4,13 @@
|
|||||||
|
|
||||||
#include "Page.h"
|
#include "Page.h"
|
||||||
|
|
||||||
Page::Page() : QWebPage(), confirmResult(true) {}
|
Page::Page() : QWebPage() {}
|
||||||
|
|
||||||
void Page::javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID) {
|
void Page::javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID) {
|
||||||
emit consoleLog(message, lineNumber, sourceID);
|
emit handleError(message, lineNumber, sourceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Page::javaScriptAlert(QWebFrame *, const QString &) {}
|
||||||
bool Page::javaScriptConfirm(QWebFrame *, const QString &) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Page::javaScriptAlert(QWebFrame*, const QString &msg) {
|
|
||||||
emit internalLog("alert", msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Page::oneFalseConfirm() {
|
|
||||||
confirmResult = false;
|
|
||||||
}
|
|
||||||
|
@ -8,16 +8,12 @@
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Page();
|
Page();
|
||||||
void oneFalseConfirm();
|
|
||||||
signals:
|
|
||||||
void consoleLog(const QString &msg, int lineNumber, const QString &sourceID);
|
|
||||||
void internalLog(const QString ¬e, const QString &msg);
|
|
||||||
protected:
|
protected:
|
||||||
void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID);
|
void javaScriptConsoleMessage(const QString & message, int lineNumber, const QString & sourceID);
|
||||||
bool javaScriptConfirm(QWebFrame *frame, const QString &msg);
|
void javaScriptAlert(QWebFrame *, const QString &);
|
||||||
void javaScriptAlert(QWebFrame *frame, const QString &msg);
|
bool javaScriptConfirm(QWebFrame *, const QString &);
|
||||||
private:
|
signals:
|
||||||
bool confirmResult;
|
void handleError(const QString & message, int lineNumber, const QString & sourceID);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
#include <QtTest/QtTest>
|
|
||||||
|
|
||||||
#include "Page.h"
|
|
||||||
#include "Page_test.h"
|
|
||||||
|
|
||||||
PageTest::PageTest() : QObject(), internalLogCalled(false) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void PageTest::internalLog(const QString &, const QString &) {
|
|
||||||
internalLogCalled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PageTest::consoleLog(const QString &, int, const QString &) {
|
|
||||||
consoleLogCalled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PageTest::testJavaScriptConfirmWithLog() {
|
|
||||||
connect(&page, SIGNAL(internalLog(QString, QString)), this, SLOT(internalLog(QString, QString)));
|
|
||||||
internalLogCalled = false;
|
|
||||||
|
|
||||||
page.mainFrame()->setHtml("<script>confirm('test')</script>");
|
|
||||||
QVERIFY(internalLogCalled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PageTest::testJavaScriptConfirmWithoutLog() {
|
|
||||||
connect(&page, SIGNAL(internalLog(QString, QString)), this, SLOT(internalLog(QString, QString)));
|
|
||||||
internalLogCalled = false;
|
|
||||||
|
|
||||||
page.oneFalseConfirm();
|
|
||||||
page.mainFrame()->setHtml("<script>confirm('test')</script>");
|
|
||||||
QVERIFY(!internalLogCalled);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PageTest::testJavaScriptConsoleMessage() {
|
|
||||||
connect(&page, SIGNAL(consoleLog(QString, int, QString)), this, SLOT(consoleLog(QString, int, QString)));
|
|
||||||
consoleLogCalled = false;
|
|
||||||
|
|
||||||
page.mainFrame()->setHtml("<script>cats();</script>");
|
|
||||||
QVERIFY(consoleLogCalled);
|
|
||||||
}
|
|
||||||
|
|
||||||
QTEST_MAIN(PageTest);
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
|||||||
#ifndef JHW_TEST_PAGE
|
|
||||||
#define JHW_TEST_PAGE
|
|
||||||
|
|
||||||
#include <QtTest/QtTest>
|
|
||||||
|
|
||||||
#include "Page.h"
|
|
||||||
|
|
||||||
class PageTest : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
PageTest();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool internalLogCalled;
|
|
||||||
bool consoleLogCalled;
|
|
||||||
Page page;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void internalLog(const QString ¬e, const QString &msg);
|
|
||||||
void consoleLog(const QString &message, int lineNumber, const QString &source);
|
|
||||||
void testJavaScriptConfirmWithLog();
|
|
||||||
void testJavaScriptConfirmWithoutLog();
|
|
||||||
void testJavaScriptConsoleMessage();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
|||||||
include(common.pri)
|
|
||||||
include(test.pri)
|
|
||||||
|
|
||||||
SOURCES += Page_test.cpp
|
|
||||||
HEADERS += Page_test.h
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
|||||||
#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;
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
|||||||
#ifndef JHW_REPORT_FILE_OUTPUT
|
|
||||||
#define JHW_REPORT_FILE_OUTPUT
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <iostream>
|
|
||||||
#include <QStack>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
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 ¬e, 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);
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
stringstream *buffer;
|
|
||||||
stringstream *outputIO;
|
|
||||||
QStack<QString> successes;
|
|
||||||
QStack<QString> failures;
|
|
||||||
private:
|
|
||||||
void reportTotals(const QString &totalTests, const QString &failedTests, const QString &duration, bool hasJavaScriptError);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,88 +0,0 @@
|
|||||||
#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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReportFileOutputTest::testFailed() {
|
|
||||||
stringstream buffer;
|
|
||||||
ReportFileOutput output;
|
|
||||||
|
|
||||||
output.outputIO = &buffer;
|
|
||||||
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);
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
|||||||
#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();
|
|
||||||
void testFailed();
|
|
||||||
void testErrorLog();
|
|
||||||
void testConsoleLog();
|
|
||||||
void testStubMethods();
|
|
||||||
void testReportFailure();
|
|
||||||
void testReportSuccess();
|
|
||||||
void testReportSuccessWithJSErrors();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,7 +0,0 @@
|
|||||||
include(common.pri)
|
|
||||||
include(test.pri)
|
|
||||||
|
|
||||||
SOURCES += ReportFileOutput_test.cpp
|
|
||||||
HEADERS += ReportFileOutput_test.h
|
|
||||||
|
|
||||||
|
|
@ -3,181 +3,153 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
|
|
||||||
#include "Runner.h"
|
#include "Runner.h"
|
||||||
|
#include "Page.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Runner::Runner() : QObject()
|
Runner::Runner() : QObject()
|
||||||
, m_runs(0)
|
, runs(0)
|
||||||
, hasErrors(false)
|
, hasErrors(false)
|
||||||
|
, _hasSpecFailure(false)
|
||||||
, usedConsole(false)
|
, usedConsole(false)
|
||||||
, isFinished(false)
|
, isFinished(false)
|
||||||
, didFail(false)
|
, useColors(false)
|
||||||
{
|
{
|
||||||
m_page.settings()->enablePersistentStorage();
|
page.settings()->enablePersistentStorage();
|
||||||
m_ticker.setInterval(TIMER_TICK);
|
ticker.setInterval(TIMER_TICK);
|
||||||
|
|
||||||
connect(&m_ticker, SIGNAL(timeout()), this, SLOT(timerEvent()));
|
connect(&ticker, SIGNAL(timeout()), this, SLOT(timerEvent()));
|
||||||
connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool)));
|
connect(&page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool)));
|
||||||
connect(&m_page, SIGNAL(consoleLog(QString, int, QString)), this, SLOT(errorLog(QString, int, QString)));
|
connect(&page, SIGNAL(handleError(const QString &, int, const QString &)), this, SLOT(handleError(const QString &, int, const QString &)));
|
||||||
connect(&m_page, SIGNAL(internalLog(QString, QString)), this, SLOT(internalLog(QString, QString)));
|
connect(page.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJHW()));
|
||||||
connect(m_page.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJHW()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::addFile(const QString &spec) {
|
void Runner::addFile(const QString &spec) {
|
||||||
runnerFiles.enqueue(spec);
|
runnerFiles.enqueue(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::go()
|
void Runner::go() {
|
||||||
{
|
ticker.stop();
|
||||||
m_ticker.stop();
|
page.setPreferredContentsSize(QSize(1024, 600));
|
||||||
m_page.setPreferredContentsSize(QSize(1024, 600));
|
|
||||||
addJHW();
|
addJHW();
|
||||||
loadSpec();
|
|
||||||
|
|
||||||
m_ticker.start();
|
loadSpec();
|
||||||
}
|
}
|
||||||
void Runner::addJHW()
|
void Runner::addJHW() {
|
||||||
{
|
page.mainFrame()->addToJavaScriptWindowObject("JHW", this);
|
||||||
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;");
|
||||||
|
|
||||||
|
page.mainFrame()->evaluateJavaScript(command);
|
||||||
|
|
||||||
|
hasErrors = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::loadSpec()
|
void Runner::loadSpec()
|
||||||
{
|
{
|
||||||
m_page.mainFrame()->load(runnerFiles.dequeue());
|
if (reportFileName.isEmpty()) {
|
||||||
m_ticker.start();
|
outputFile = 0;
|
||||||
|
ts = 0;
|
||||||
|
} else {
|
||||||
|
outputFile = new QFile(reportFileName);
|
||||||
|
outputFile->open(QIODevice::WriteOnly);
|
||||||
|
|
||||||
|
ts = new QTextStream(outputFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::watch(bool ok)
|
page.mainFrame()->load(runnerFiles.dequeue());
|
||||||
{
|
ticker.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Runner::watch(bool ok) {
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
std::cerr << "Can't load " << qPrintable(m_page.mainFrame()->url().toString()) << ", the file may be broken." << std::endl;
|
std::cerr << "Can't load " << qPrintable(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 << "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;
|
std::cerr << "Try running your tests in your browser with the Jasmine server and see what happens." << std::endl;
|
||||||
QApplication::instance()->exit(1);
|
QApplication::instance()->exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
page.mainFrame()->evaluateJavaScript(QString("JHW._setColors(") + (useColors ? QString("true") : QString("false")) + QString("); false;"));
|
||||||
|
|
||||||
bool Runner::hasElement(const char *select)
|
|
||||||
{
|
|
||||||
return !m_page.mainFrame()->findFirstElement(select).isNull();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::setColors(bool colors) {
|
void Runner::setColors(bool colors) {
|
||||||
consoleOutput.showColors = colors;
|
useColors = colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Runner::hasUsedConsole() {
|
||||||
|
usedConsole = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Runner::hasError() {
|
||||||
|
hasErrors = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Runner::hasSpecFailure() {
|
||||||
|
_hasSpecFailure = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::reportFile(const QString &file) {
|
void Runner::reportFile(const QString &file) {
|
||||||
reportFileName = file;
|
reportFileName = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Runner::hasError() {
|
|
||||||
return hasErrors;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Runner::timerPause() {
|
void Runner::timerPause() {
|
||||||
m_ticker.stop();
|
ticker.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::timerDone() {
|
void Runner::timerDone() {
|
||||||
m_ticker.start();
|
ticker.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::specPassed(const QString &specDetail) {
|
void Runner::print(const QString &fh, const QString &content) {
|
||||||
consoleOutput.passed(specDetail);
|
if (fh == "stdout") {
|
||||||
reportFileOutput.passed(specDetail);
|
std::cout << qPrintable(content);
|
||||||
|
std::cout.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::specFailed(const QString &specDetail) {
|
if (fh == "stderr") {
|
||||||
consoleOutput.failed(specDetail);
|
std::cerr << qPrintable(content);
|
||||||
reportFileOutput.failed(specDetail);
|
std::cerr.flush();
|
||||||
|
|
||||||
didFail = true;
|
|
||||||
failedSpecs.push(specDetail);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::errorLog(const QString &msg, int lineNumber, const QString &sourceID)
|
if (fh == "report" && outputFile) {
|
||||||
{
|
*ts << qPrintable(content);
|
||||||
consoleOutput.errorLog(msg, lineNumber, sourceID);
|
ts->flush();
|
||||||
reportFileOutput.errorLog(msg, lineNumber, sourceID);
|
|
||||||
|
|
||||||
hasErrors = true;
|
|
||||||
m_runs = 0;
|
|
||||||
m_ticker.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!reportFileName.isEmpty()) {
|
void Runner::finishSuite() {
|
||||||
QFile outputFile(reportFileName);
|
|
||||||
outputFile.open(QIODevice::WriteOnly);
|
|
||||||
|
|
||||||
QTextStream ts(&outputFile);
|
|
||||||
|
|
||||||
ts << reportFileOutput.outputIO->str().c_str();
|
|
||||||
|
|
||||||
outputFile.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
isFinished = true;
|
isFinished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runner::timerEvent()
|
void Runner::timerEvent() {
|
||||||
{
|
++runs;
|
||||||
++m_runs;
|
|
||||||
|
|
||||||
if (hasErrors && m_runs > 2)
|
if (hasErrors && runs > 2)
|
||||||
QApplication::instance()->exit(1);
|
QApplication::instance()->exit(1);
|
||||||
|
|
||||||
if (isFinished) {
|
if (isFinished) {
|
||||||
|
if (outputFile) {
|
||||||
|
outputFile->close();
|
||||||
|
}
|
||||||
|
|
||||||
int exitCode = 0;
|
int exitCode = 0;
|
||||||
if (didFail || hasErrors) {
|
if (_hasSpecFailure || hasErrors) {
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
} else {
|
} else {
|
||||||
if (usedConsole) {
|
if (usedConsole) {
|
||||||
@ -203,8 +175,8 @@ void Runner::timerEvent()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_runs > MAX_LOOPS) {
|
if (runs > MAX_LOOPS) {
|
||||||
std::cout << "WARNING: too many runs and the test is still not finished!" << std::endl;
|
std::cerr << "WARNING: too many runs and the test is still not finished!" << std::endl;
|
||||||
QApplication::instance()->exit(1);
|
QApplication::instance()->exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,57 +10,53 @@
|
|||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
|
|
||||||
#include "Page.h"
|
#include "Page.h"
|
||||||
#include "ConsoleOutput.h"
|
|
||||||
#include "ReportFileOutput.h"
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class Runner: public QObject {
|
class Runner: public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum { TIMER_TICK = 200, MAX_LOOPS = 25 };
|
enum { TIMER_TICK = 200, MAX_LOOPS = 50 };
|
||||||
|
|
||||||
Runner();
|
Runner();
|
||||||
void setColors(bool colors);
|
void setColors(bool colors);
|
||||||
void reportFile(const QString &file);
|
void reportFile(const QString &file);
|
||||||
void addFile(const QString &spec);
|
void addFile(const QString &spec);
|
||||||
void go();
|
void go();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void log(const QString &msg);
|
|
||||||
bool hasError();
|
|
||||||
void leavePageAttempt(const QString &msg);
|
|
||||||
void timerPause();
|
void timerPause();
|
||||||
void timerDone();
|
void timerDone();
|
||||||
void specPassed(const QString &specDetail);
|
void hasUsedConsole();
|
||||||
void specFailed(const QString &specDetail);
|
void hasError();
|
||||||
void printName(const QString &name);
|
void hasSpecFailure();
|
||||||
void printResult(const QString &result);
|
void print(const QString &fh, const QString &content);
|
||||||
void finishSuite(const QString &duration, const QString &total, const QString& failed);
|
void finishSuite();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void watch(bool ok);
|
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 addJHW();
|
||||||
void timerEvent();
|
void timerEvent();
|
||||||
protected:
|
void handleError(const QString & message, int lineNumber, const QString & sourceID);
|
||||||
bool hasElement(const char *select);
|
|
||||||
private:
|
private:
|
||||||
Page m_page;
|
Page page;
|
||||||
QTimer m_ticker;
|
QTimer ticker;
|
||||||
int m_runs;
|
int runs;
|
||||||
bool hasErrors;
|
bool hasErrors;
|
||||||
|
bool _hasSpecFailure;
|
||||||
bool usedConsole;
|
bool usedConsole;
|
||||||
bool isFinished;
|
bool isFinished;
|
||||||
bool didFail;
|
bool useColors;
|
||||||
QQueue<QString> runnerFiles;
|
|
||||||
QStack<QString> failedSpecs;
|
|
||||||
|
|
||||||
ConsoleOutput consoleOutput;
|
QQueue<QString> runnerFiles;
|
||||||
ReportFileOutput reportFileOutput;
|
|
||||||
|
|
||||||
QString reportFileName;
|
QString reportFileName;
|
||||||
|
|
||||||
void loadSpec();
|
void loadSpec();
|
||||||
|
|
||||||
|
QFile *outputFile;
|
||||||
|
QTextStream *ts;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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 ReportFileOutput.cpp
|
SOURCES = Page.cpp Runner.cpp
|
||||||
HEADERS = Page.h Runner.h ConsoleOutput.h ReportFileOutput.h
|
HEADERS = Page.h Runner.h
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Page.h"
|
|
||||||
#include "Runner.h"
|
#include "Runner.h"
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
|
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
|
||||||
|
@ -2,3 +2,4 @@ include(common.pri)
|
|||||||
|
|
||||||
SOURCES += specrunner.cpp
|
SOURCES += specrunner.cpp
|
||||||
TARGET = jasmine-webkit-specrunner
|
TARGET = jasmine-webkit-specrunner
|
||||||
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
TARGET = jhw-test
|
|
||||||
QT += testlib
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
#!/usr/bin/env ruby
|
|
||||||
|
|
||||||
require 'fileutils'
|
|
||||||
|
|
||||||
system %{make clean}
|
|
||||||
|
|
||||||
$: << File.expand_path("../../../lib", __FILE__)
|
|
||||||
require 'qt/qmake'
|
|
||||||
|
|
||||||
result = 0
|
|
||||||
|
|
||||||
Dir['*_test.pro'].each do |test|
|
|
||||||
FileUtils.rm_f('jhw-test')
|
|
||||||
|
|
||||||
Qt::Qmake.make!('jasmine-headless-webkit', test)
|
|
||||||
|
|
||||||
if File.file?('jhw-test')
|
|
||||||
system %{./jhw-test}
|
|
||||||
if $?.exitstatus != 0
|
|
||||||
result = 1
|
|
||||||
break
|
|
||||||
end
|
|
||||||
else
|
|
||||||
result = 1
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Qt::Qmake.make!('jasmine-headless-webkit', 'specrunner.pro')
|
|
||||||
|
|
||||||
exit result
|
|
@ -1,231 +0,0 @@
|
|||||||
(function() {
|
|
||||||
var getSplitName, pauseAndRun;
|
|
||||||
if (!(typeof jasmine !== "undefined" && jasmine !== null)) {
|
|
||||||
throw new Error("jasmine not laoded!");
|
|
||||||
}
|
|
||||||
if (window.JHW) {
|
|
||||||
getSplitName = function(parts) {
|
|
||||||
parts.push(String(this.description).replace(/[\n\r]/g, ' '));
|
|
||||||
return parts;
|
|
||||||
};
|
|
||||||
jasmine.Suite.prototype.getSuiteSplitName = function() {
|
|
||||||
return this.getSplitName(this.parentSuite ? this.parentSuite.getSuiteSplitName() : []);
|
|
||||||
};
|
|
||||||
jasmine.Spec.prototype.getSpecSplitName = function() {
|
|
||||||
return this.getSplitName(this.suite.getSuiteSplitName());
|
|
||||||
};
|
|
||||||
jasmine.Suite.prototype.getSplitName = getSplitName;
|
|
||||||
jasmine.Spec.prototype.getSplitName = getSplitName;
|
|
||||||
jasmine.Spec.prototype.getJHWSpecInformation = function() {
|
|
||||||
var parts, specLineInfo;
|
|
||||||
parts = this.getSpecSplitName();
|
|
||||||
specLineInfo = HeadlessReporterResult.findSpecLine(parts);
|
|
||||||
if (specLineInfo.file) {
|
|
||||||
parts.push("" + specLineInfo.file + ":" + specLineInfo.lineNumber);
|
|
||||||
} else {
|
|
||||||
parts.push('');
|
|
||||||
}
|
|
||||||
return parts.join("||");
|
|
||||||
};
|
|
||||||
jasmine.Spec.prototype.fail = function(e) {
|
|
||||||
var expectationResult, filename, realFilename;
|
|
||||||
if (e && e.sourceURL && window.CoffeeScriptToFilename) {
|
|
||||||
filename = e.sourceURL.split('/').pop();
|
|
||||||
if (realFilename = window.CoffeeScriptToFilename[filename]) {
|
|
||||||
e = {
|
|
||||||
name: e.name,
|
|
||||||
message: e.message,
|
|
||||||
lineNumber: "~" + String(e.line),
|
|
||||||
sourceURL: realFilename
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expectationResult = new jasmine.ExpectationResult({
|
|
||||||
passed: false,
|
|
||||||
message: e ? jasmine.util.formatException(e) : 'Exception',
|
|
||||||
trace: {
|
|
||||||
stack: e.stack
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return this.results_.addResult(expectationResult);
|
|
||||||
};
|
|
||||||
jasmine.NestedResults.isValidSpecLine = function(line) {
|
|
||||||
return line.match(/^\s*expect/) !== null || line.match(/^\s*return\s*expect/) !== null;
|
|
||||||
};
|
|
||||||
jasmine.NestedResults.parseFunction = function(func) {
|
|
||||||
var line, lineCount, lines, _i, _len, _ref;
|
|
||||||
lines = [];
|
|
||||||
lineCount = 0;
|
|
||||||
_ref = func.split("\n");
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
line = _ref[_i];
|
|
||||||
if (jasmine.NestedResults.isValidSpecLine(line)) {
|
|
||||||
line = line.replace(/^\s*/, '').replace(/\s*$/, '').replace(/^return\s*/, '');
|
|
||||||
lines.push([line, lineCount]);
|
|
||||||
}
|
|
||||||
lineCount += 1;
|
|
||||||
}
|
|
||||||
return lines;
|
|
||||||
};
|
|
||||||
jasmine.NestedResults.parseAndStore = function(func) {
|
|
||||||
if (!jasmine.NestedResults.ParsedFunctions[func]) {
|
|
||||||
jasmine.NestedResults.ParsedFunctions[func] = jasmine.NestedResults.parseFunction(func);
|
|
||||||
}
|
|
||||||
return jasmine.NestedResults.ParsedFunctions[func];
|
|
||||||
};
|
|
||||||
jasmine.NestedResults.ParsedFunctions = [];
|
|
||||||
if (!jasmine.WaitsBlock.prototype._execute) {
|
|
||||||
jasmine.WaitsBlock.prototype._execute = jasmine.WaitsBlock.prototype.execute;
|
|
||||||
jasmine.WaitsForBlock.prototype._execute = jasmine.WaitsForBlock.prototype.execute;
|
|
||||||
pauseAndRun = function(onComplete) {
|
|
||||||
JHW.timerPause();
|
|
||||||
return this._execute(function() {
|
|
||||||
JHW.timerDone();
|
|
||||||
return onComplete();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
jasmine.WaitsBlock.prototype.execute = pauseAndRun;
|
|
||||||
jasmine.WaitsForBlock.prototype.execute = pauseAndRun;
|
|
||||||
jasmine.NestedResults.prototype.addResult_ = jasmine.NestedResults.prototype.addResult;
|
|
||||||
jasmine.NestedResults.prototype.addResult = function(result) {
|
|
||||||
result.expectations = [];
|
|
||||||
result.expectations = jasmine.NestedResults.parseAndStore(arguments.callee.caller.caller.caller.toString());
|
|
||||||
return this.addResult_(result);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
window.HeadlessReporterResult = (function() {
|
|
||||||
function HeadlessReporterResult(name, splitName) {
|
|
||||||
this.name = name;
|
|
||||||
this.splitName = splitName;
|
|
||||||
this.results = [];
|
|
||||||
}
|
|
||||||
HeadlessReporterResult.prototype.addResult = function(message) {
|
|
||||||
return this.results.push(message);
|
|
||||||
};
|
|
||||||
HeadlessReporterResult.prototype.print = function() {
|
|
||||||
var bestChoice, output, result, _i, _len, _ref, _results;
|
|
||||||
output = this.name;
|
|
||||||
bestChoice = HeadlessReporterResult.findSpecLine(this.splitName);
|
|
||||||
if (bestChoice.file) {
|
|
||||||
output += " (" + bestChoice.file + ":" + bestChoice.lineNumber + ")";
|
|
||||||
}
|
|
||||||
JHW.printName(output);
|
|
||||||
_ref = this.results;
|
|
||||||
_results = [];
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
result = _ref[_i];
|
|
||||||
output = result.message;
|
|
||||||
if (result.lineNumber) {
|
|
||||||
output += " (line ~" + (bestChoice.lineNumber + result.lineNumber) + ")\n " + result.line;
|
|
||||||
}
|
|
||||||
_results.push(JHW.printResult(output));
|
|
||||||
}
|
|
||||||
return _results;
|
|
||||||
};
|
|
||||||
HeadlessReporterResult.findSpecLine = function(splitName) {
|
|
||||||
var bestChoice, file, index, lastLine, line, lineNumber, lines, newLineNumberInfo, _i, _len, _ref;
|
|
||||||
bestChoice = {
|
|
||||||
accuracy: 0,
|
|
||||||
file: null,
|
|
||||||
lineNumber: null
|
|
||||||
};
|
|
||||||
_ref = HeadlessReporterResult.specLineNumbers;
|
|
||||||
for (file in _ref) {
|
|
||||||
lines = _ref[file];
|
|
||||||
index = 0;
|
|
||||||
lineNumber = 0;
|
|
||||||
while (newLineNumberInfo = lines[splitName[index]]) {
|
|
||||||
if (newLineNumberInfo.length === 0) {
|
|
||||||
lineNumber = newLineNumberInfo[0];
|
|
||||||
} else {
|
|
||||||
lastLine = null;
|
|
||||||
for (_i = 0, _len = newLineNumberInfo.length; _i < _len; _i++) {
|
|
||||||
line = newLineNumberInfo[_i];
|
|
||||||
lastLine = line;
|
|
||||||
if (line > lineNumber) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lineNumber = lastLine;
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
if (index > bestChoice.accuracy) {
|
|
||||||
bestChoice = {
|
|
||||||
accuracy: index,
|
|
||||||
file: file,
|
|
||||||
lineNumber: lineNumber
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bestChoice;
|
|
||||||
};
|
|
||||||
return HeadlessReporterResult;
|
|
||||||
})();
|
|
||||||
jasmine.HeadlessReporter = (function() {
|
|
||||||
function HeadlessReporter(callback) {
|
|
||||||
this.callback = callback != null ? callback : null;
|
|
||||||
this.results = [];
|
|
||||||
this.failedCount = 0;
|
|
||||||
this.length = 0;
|
|
||||||
}
|
|
||||||
HeadlessReporter.prototype.reportRunnerResults = function(runner) {
|
|
||||||
var result, _i, _len, _ref;
|
|
||||||
if (this.hasError()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_ref = this.results;
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
result = _ref[_i];
|
|
||||||
result.print();
|
|
||||||
}
|
|
||||||
if (this.callback) {
|
|
||||||
this.callback();
|
|
||||||
}
|
|
||||||
return JHW.finishSuite((new Date() - this.startTime) / 1000.0, this.length, this.failedCount);
|
|
||||||
};
|
|
||||||
HeadlessReporter.prototype.reportRunnerStarting = function(runner) {
|
|
||||||
return this.startTime = new Date();
|
|
||||||
};
|
|
||||||
HeadlessReporter.prototype.reportSpecResults = function(spec) {
|
|
||||||
var failureResult, foundLine, result, results, testCount, _i, _len, _ref;
|
|
||||||
if (this.hasError()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
results = spec.results();
|
|
||||||
this.length++;
|
|
||||||
if (results.passed()) {
|
|
||||||
return JHW.specPassed(spec.getJHWSpecInformation());
|
|
||||||
} else {
|
|
||||||
JHW.specFailed(spec.getJHWSpecInformation());
|
|
||||||
this.failedCount++;
|
|
||||||
failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName());
|
|
||||||
testCount = 1;
|
|
||||||
_ref = results.getItems();
|
|
||||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
|
||||||
result = _ref[_i];
|
|
||||||
if (result.type === 'expect' && !result.passed_) {
|
|
||||||
if (foundLine = result.expectations[testCount - 1]) {
|
|
||||||
result.line = foundLine[0], result.lineNumber = foundLine[1];
|
|
||||||
}
|
|
||||||
failureResult.addResult(result);
|
|
||||||
}
|
|
||||||
testCount += 1;
|
|
||||||
}
|
|
||||||
return this.results.push(failureResult);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
HeadlessReporter.prototype.reportSpecStarting = function(spec) {
|
|
||||||
if (this.hasError()) {
|
|
||||||
spec.finish();
|
|
||||||
return spec.suite.finish();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
HeadlessReporter.prototype.reportSuiteResults = function(suite) {};
|
|
||||||
HeadlessReporter.prototype.hasError = function() {
|
|
||||||
return JHW.hasError();
|
|
||||||
};
|
|
||||||
return HeadlessReporter;
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
}).call(this);
|
|
@ -6,14 +6,30 @@ module Jasmine
|
|||||||
class FilesList
|
class FilesList
|
||||||
attr_reader :files, :spec_files, :filtered_files, :spec_outside_scope
|
attr_reader :files, :spec_files, :filtered_files, :spec_outside_scope
|
||||||
|
|
||||||
|
class << self
|
||||||
|
def find_vendored_asset_paths(*names)
|
||||||
|
require 'rubygems'
|
||||||
|
|
||||||
|
raise StandardError.new("A newer version of Rubygems is required to use vendored assets. Please upgrade.") if !Gem::Specification.respond_to?(:map)
|
||||||
|
all_spec_files.find_all do |file|
|
||||||
|
names.any? { |name| file["/#{name}.js"] }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def all_spec_files
|
||||||
|
@all_spec_files ||= Gem::Specification.map { |spec| spec.files.find_all { |file|
|
||||||
|
file["vendor/assets/javascripts"]
|
||||||
|
}.compact.collect { |file| File.join(spec.gem_dir, file) } }.flatten
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
DEFAULT_FILES = [
|
DEFAULT_FILES = [
|
||||||
File.join(Jasmine::Core.path, "jasmine.js"),
|
File.join(Jasmine::Core.path, "jasmine.js"),
|
||||||
File.join(Jasmine::Core.path, "jasmine-html.js"),
|
File.join(Jasmine::Core.path, "jasmine-html.js"),
|
||||||
File.join(Jasmine::Core.path, "jasmine.css"),
|
File.join(Jasmine::Core.path, "jasmine.css")
|
||||||
Jasmine::Headless.root.join('jasmine/jasmine.headless-reporter.js').to_s,
|
] + %w{jasmine-extensions intense headless_reporter_result jasmine.HeadlessConsoleReporter jsDump beautify-html}.collect { |name|
|
||||||
Jasmine::Headless.root.join('js-lib/jsDump.js').to_s,
|
Jasmine::Headless.root.join("vendor/assets/javascripts/#{name}.js").to_s
|
||||||
Jasmine::Headless.root.join('js-lib/beautify-html.js').to_s
|
}
|
||||||
]
|
|
||||||
|
|
||||||
PLEASE_WAIT_IM_WORKING_TIME = 2
|
PLEASE_WAIT_IM_WORKING_TIME = 2
|
||||||
|
|
||||||
@ -72,13 +88,10 @@ module Jasmine
|
|||||||
cache = Jasmine::Headless::CoffeeScriptCache.new(file)
|
cache = Jasmine::Headless::CoffeeScriptCache.new(file)
|
||||||
source = cache.handle
|
source = cache.handle
|
||||||
if cache.cached?
|
if cache.cached?
|
||||||
%{
|
%{<script type="text/javascript" src="#{cache.cache_file}"></script>
|
||||||
<script type="text/javascript" src="#{cache.cache_file}"></script>S
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.CoffeeScriptToFilename = window.CoffeeScriptToFilename || {};
|
window.CSTF['#{File.split(cache.cache_file).last}'] = '#{file}';
|
||||||
window.CoffeeScriptToFilename['#{File.split(cache.cache_file).last}'] = '#{file}';
|
</script>}
|
||||||
</script>
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
%{<script type="text/javascript">#{source}</script>}
|
%{<script type="text/javascript">#{source}</script>}
|
||||||
end
|
end
|
||||||
@ -158,19 +171,6 @@ module Jasmine
|
|||||||
def expanded_dir(path)
|
def expanded_dir(path)
|
||||||
Dir[path].collect { |file| File.expand_path(file) }
|
Dir[path].collect { |file| File.expand_path(file) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find_vendored_asset_path(name)
|
|
||||||
require 'rubygems'
|
|
||||||
|
|
||||||
raise StandardError.new("A newer version of Rubygems is required to use vendored assets. Please upgrade.") if !Gem::Specification.respond_to?(:map)
|
|
||||||
all_spec_files.find_all { |file| file["vendor/assets/javascripts/#{name}.js"] }
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.all_spec_files
|
|
||||||
@all_spec_files ||= Gem::Specification.map { |spec| spec.files.find_all { |file|
|
|
||||||
file["vendor/assets/javascripts"]
|
|
||||||
}.compact.collect { |file| File.join(spec.gem_dir, file) } }.flatten
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ module Jasmine::Headless
|
|||||||
|
|
||||||
class << self
|
class << self
|
||||||
def root
|
def root
|
||||||
@root ||= Pathname.new(File.expand_path('../../..', __FILE__))
|
@root ||= Pathname(File.expand_path('../../..', __FILE__))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
module Jasmine
|
module Jasmine
|
||||||
module Headless
|
module Headless
|
||||||
VERSION = "0.7.3.1"
|
VERSION = "0.8.0"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -39,11 +39,7 @@ module Qt
|
|||||||
|
|
||||||
system command(project_file)
|
system command(project_file)
|
||||||
|
|
||||||
system %{make #{make_options}}
|
system %{make}
|
||||||
end
|
|
||||||
|
|
||||||
def make_options
|
|
||||||
""
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -3,47 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
|
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
|
||||||
<title>Jasmine Test Runner - Generated by jasmine-headless-webkit</title>
|
<title>Jasmine Test Runner - Generated by jasmine-headless-webkit</title>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript" src="<%= Jasmine::Headless.root.join('vendor/assets/javascripts/prolog.js') %>"></script>
|
||||||
if (window.JHW) {
|
|
||||||
window.console = { log: function(data) {
|
|
||||||
if (typeof(jQuery) !== 'undefined' && data instanceof jQuery) {
|
|
||||||
JHW.log(style_html($("<div />").append(data).html(), { indent_size: 2 }));
|
|
||||||
} else {
|
|
||||||
var usejsDump = true;
|
|
||||||
try {
|
|
||||||
if (typeof data.toJSON == 'function') {
|
|
||||||
JHW.log("JSON: " + JSON.stringify(data, null, 2));
|
|
||||||
usejsDump = false;
|
|
||||||
}
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
if (usejsDump) {
|
|
||||||
var dump = jsDump.doParse(data);
|
|
||||||
if (dump.indexOf("\\n") == -1) {
|
|
||||||
JHW.log(dump);
|
|
||||||
} else {
|
|
||||||
JHW.log("jsDump: " + dump);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, pp: function(data) {
|
|
||||||
JHW.log(jasmine ? jasmine.pp(data) : JSON.stringify(data));
|
|
||||||
}, peek: function(data) {
|
|
||||||
console.log(data);
|
|
||||||
return data;
|
|
||||||
} };
|
|
||||||
|
|
||||||
window.onbeforeunload = function(e) {
|
|
||||||
JHW.leavePageAttempt('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";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<%= files.join("\n") %>
|
<%= files.join("\n") %>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
if (window.JHW) { HeadlessReporterResult.specLineNumbers = <%= MultiJson.encode(spec_lines) %>; }
|
if (window.JHW) { HeadlessReporterResult.specLineNumbers = <%= MultiJson.encode(spec_lines) %>; }
|
||||||
@ -51,14 +11,17 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
jasmine.getEnv().console = {
|
||||||
|
log: function(msg) { JHW.stdout.puts(msg) }
|
||||||
|
}
|
||||||
|
|
||||||
window._onload = window.onload
|
window._onload = window.onload
|
||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
if (window._onload) { window._onload() }
|
if (window._onload) { window._onload() }
|
||||||
|
|
||||||
if (window.JHW) {
|
if (window.JHW) {
|
||||||
jasmine.getEnv().addReporter(new jasmine.HeadlessReporter(function() {
|
jasmine.getEnv().addReporter(new jasmine.HeadlessConsoleReporter());
|
||||||
window.onbeforeunload = null;
|
|
||||||
}));
|
|
||||||
} else {
|
} else {
|
||||||
jasmine.getEnv().addReporter(new jasmine.HtmlReporter());
|
jasmine.getEnv().addReporter(new jasmine.HtmlReporter());
|
||||||
}
|
}
|
||||||
|
14
spec/javascripts/headless_reporter_result_spec.coffee
Normal file
14
spec/javascripts/headless_reporter_result_spec.coffee
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
describe 'HeadlessReporterResult', ->
|
||||||
|
result = null
|
||||||
|
name = "name"
|
||||||
|
splitName = "splitName"
|
||||||
|
message = 'message'
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
result = new HeadlessReporterResult(name, splitName)
|
||||||
|
|
||||||
|
describe '#addResult', ->
|
||||||
|
it 'should add a message', ->
|
||||||
|
result.addResult(message)
|
||||||
|
|
||||||
|
expect(result.results).toEqual([ message ])
|
@ -12,11 +12,11 @@ describe 'HeadlessReporterResult', ->
|
|||||||
expect(HeadlessReporterResult.findSpecLine([ 'name', 'of', 'test' ]).lineNumber).toEqual(3)
|
expect(HeadlessReporterResult.findSpecLine([ 'name', 'of', 'test' ]).lineNumber).toEqual(3)
|
||||||
expect(HeadlessReporterResult.findSpecLine([ 'other', 'of', 'test' ]).lineNumber).toEqual(10)
|
expect(HeadlessReporterResult.findSpecLine([ 'other', 'of', 'test' ]).lineNumber).toEqual(10)
|
||||||
|
|
||||||
describe 'jasmine.HeadlessReporter', ->
|
describe 'jasmine.HeadlessConsoleReporter', ->
|
||||||
reporter = null
|
reporter = null
|
||||||
|
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
reporter = new jasmine.HeadlessReporter()
|
reporter = new jasmine.HeadlessConsoleReporter()
|
||||||
|
|
||||||
it 'should stop running specs if there are errors reported', ->
|
it 'should stop running specs if there are errors reported', ->
|
||||||
# otherwise it gets really confusing!
|
# otherwise it gets really confusing!
|
@ -1,4 +1,4 @@
|
|||||||
src_files: [ 'jasmine/*.coffee' ]
|
src_files: [ 'vendor/assets/coffeescripts/*.coffee' ]
|
||||||
spec_files: [ 'spec/javascripts/*_spec.coffee' ]
|
spec_files: [ 'spec/javascripts/*_spec.coffee' ]
|
||||||
src_dir: .
|
src_dir: .
|
||||||
spec_dir: .
|
spec_dir: .
|
||||||
|
@ -14,9 +14,12 @@ describe Jasmine::FilesList do
|
|||||||
File.join(Jasmine::Core.path, "jasmine.js"),
|
File.join(Jasmine::Core.path, "jasmine.js"),
|
||||||
File.join(Jasmine::Core.path, "jasmine-html.js"),
|
File.join(Jasmine::Core.path, "jasmine-html.js"),
|
||||||
File.join(Jasmine::Core.path, "jasmine.css"),
|
File.join(Jasmine::Core.path, "jasmine.css"),
|
||||||
File.expand_path('jasmine/jasmine.headless-reporter.js'),
|
File.expand_path('vendor/assets/javascripts/jasmine-extensions.js'),
|
||||||
File.expand_path('js-lib/jsDump.js'),
|
File.expand_path('vendor/assets/javascripts/intense.js'),
|
||||||
File.expand_path('js-lib/beautify-html.js'),
|
File.expand_path('vendor/assets/javascripts/headless_reporter_result.js'),
|
||||||
|
File.expand_path('vendor/assets/javascripts/jasmine.HeadlessConsoleReporter.js'),
|
||||||
|
File.expand_path('vendor/assets/javascripts/jsDump.js'),
|
||||||
|
File.expand_path('vendor/assets/javascripts/beautify-html.js'),
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -138,11 +138,5 @@ describe Qt::Qmake do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '.make_options' do
|
|
||||||
subject { Qt::Qmake.make_options }
|
|
||||||
|
|
||||||
it { should == "" }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
46
vendor/assets/coffeescripts/headless_reporter_result.coffee
vendored
Normal file
46
vendor/assets/coffeescripts/headless_reporter_result.coffee
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Try to get the line number of a failed spec
|
||||||
|
class window.HeadlessReporterResult
|
||||||
|
constructor: (@name, @splitName) ->
|
||||||
|
@results = []
|
||||||
|
|
||||||
|
addResult: (message) ->
|
||||||
|
@results.push(message)
|
||||||
|
|
||||||
|
print: ->
|
||||||
|
output = @name.foreground('red')
|
||||||
|
bestChoice = HeadlessReporterResult.findSpecLine(@splitName)
|
||||||
|
output += " (#{bestChoice.file}:#{bestChoice.lineNumber})".foreground('blue') if bestChoice.file
|
||||||
|
|
||||||
|
JHW.stdout.puts "\n\n#{output}"
|
||||||
|
for result in @results
|
||||||
|
output = result.message.foreground('red')
|
||||||
|
if result.lineNumber
|
||||||
|
output += " (line ~#{bestChoice.lineNumber + result.lineNumber})".foreground('red').bright()
|
||||||
|
JHW.stdout.puts(" " + output)
|
||||||
|
|
||||||
|
if result.line?
|
||||||
|
JHW.stdout.puts(" #{result.line}".foreground('yellow'))
|
||||||
|
|
||||||
|
@findSpecLine: (splitName) ->
|
||||||
|
bestChoice = { accuracy: 0, file: null, lineNumber: null }
|
||||||
|
|
||||||
|
for file, lines of HeadlessReporterResult.specLineNumbers
|
||||||
|
index = 0
|
||||||
|
lineNumber = 0
|
||||||
|
while newLineNumberInfo = lines[splitName[index]]
|
||||||
|
if newLineNumberInfo.length == 0
|
||||||
|
lineNumber = newLineNumberInfo[0]
|
||||||
|
else
|
||||||
|
lastLine = null
|
||||||
|
for line in newLineNumberInfo
|
||||||
|
lastLine = line
|
||||||
|
break if line > lineNumber
|
||||||
|
|
||||||
|
lineNumber = lastLine
|
||||||
|
|
||||||
|
index++
|
||||||
|
|
||||||
|
if index > bestChoice.accuracy
|
||||||
|
bestChoice = { accuracy: index, file: file, lineNumber: lineNumber }
|
||||||
|
|
||||||
|
bestChoice
|
27
vendor/assets/coffeescripts/intense.coffee
vendored
Normal file
27
vendor/assets/coffeescripts/intense.coffee
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
window.Intense = {
|
||||||
|
colors:
|
||||||
|
black: 0
|
||||||
|
red: 1
|
||||||
|
green: 2
|
||||||
|
yellow: 3
|
||||||
|
blue: 4
|
||||||
|
magenta: 5
|
||||||
|
cyan: 6
|
||||||
|
white: 7
|
||||||
|
methods:
|
||||||
|
foreground: (color) ->
|
||||||
|
if Intense.useColors
|
||||||
|
"\033[3#{Intense.colors[color]}m#{this}\033[0m"
|
||||||
|
else
|
||||||
|
this
|
||||||
|
bright: ->
|
||||||
|
if Intense.useColors
|
||||||
|
"\033[1m#{this}\033[0m"
|
||||||
|
else
|
||||||
|
this
|
||||||
|
useColors: true
|
||||||
|
}
|
||||||
|
|
||||||
|
for method, code of Intense.methods
|
||||||
|
String.prototype[method] = code
|
||||||
|
|
@ -84,92 +84,3 @@ if window.JHW
|
|||||||
result.expectations = jasmine.NestedResults.parseAndStore(arguments.callee.caller.caller.caller.toString())
|
result.expectations = jasmine.NestedResults.parseAndStore(arguments.callee.caller.caller.caller.toString())
|
||||||
|
|
||||||
this.addResult_(result)
|
this.addResult_(result)
|
||||||
|
|
||||||
# Try to get the line number of a failed spec
|
|
||||||
class window.HeadlessReporterResult
|
|
||||||
constructor: (@name, @splitName) ->
|
|
||||||
@results = []
|
|
||||||
addResult: (message) ->
|
|
||||||
@results.push(message)
|
|
||||||
print: ->
|
|
||||||
output = @name
|
|
||||||
bestChoice = HeadlessReporterResult.findSpecLine(@splitName)
|
|
||||||
output += " (#{bestChoice.file}:#{bestChoice.lineNumber})" if bestChoice.file
|
|
||||||
|
|
||||||
JHW.printName(output)
|
|
||||||
for result in @results
|
|
||||||
output = result.message
|
|
||||||
if result.lineNumber
|
|
||||||
output += " (line ~#{bestChoice.lineNumber + result.lineNumber})\n #{result.line}"
|
|
||||||
JHW.printResult(output)
|
|
||||||
@findSpecLine: (splitName) ->
|
|
||||||
bestChoice = { accuracy: 0, file: null, lineNumber: null }
|
|
||||||
|
|
||||||
for file, lines of HeadlessReporterResult.specLineNumbers
|
|
||||||
index = 0
|
|
||||||
lineNumber = 0
|
|
||||||
while newLineNumberInfo = lines[splitName[index]]
|
|
||||||
if newLineNumberInfo.length == 0
|
|
||||||
lineNumber = newLineNumberInfo[0]
|
|
||||||
else
|
|
||||||
lastLine = null
|
|
||||||
for line in newLineNumberInfo
|
|
||||||
lastLine = line
|
|
||||||
break if line > lineNumber
|
|
||||||
|
|
||||||
lineNumber = lastLine
|
|
||||||
|
|
||||||
index++
|
|
||||||
|
|
||||||
if index > bestChoice.accuracy
|
|
||||||
bestChoice = { accuracy: index, file: file, lineNumber: lineNumber }
|
|
||||||
|
|
||||||
bestChoice
|
|
||||||
|
|
||||||
# The reporter itself.
|
|
||||||
class jasmine.HeadlessReporter
|
|
||||||
constructor: (@callback = null) ->
|
|
||||||
@results = []
|
|
||||||
@failedCount = 0
|
|
||||||
@length = 0
|
|
||||||
reportRunnerResults: (runner) ->
|
|
||||||
return if this.hasError()
|
|
||||||
|
|
||||||
for result in @results
|
|
||||||
result.print()
|
|
||||||
|
|
||||||
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(spec.getJHWSpecInformation())
|
|
||||||
else
|
|
||||||
JHW.specFailed(spec.getJHWSpecInformation())
|
|
||||||
@failedCount++
|
|
||||||
failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName())
|
|
||||||
testCount = 1
|
|
||||||
for result in results.getItems()
|
|
||||||
if result.type == 'expect' and !result.passed_
|
|
||||||
if foundLine = result.expectations[testCount - 1]
|
|
||||||
[ result.line, result.lineNumber ] = foundLine
|
|
||||||
failureResult.addResult(result)
|
|
||||||
testCount += 1
|
|
||||||
@results.push(failureResult)
|
|
||||||
|
|
||||||
reportSpecStarting: (spec) ->
|
|
||||||
if this.hasError()
|
|
||||||
spec.finish()
|
|
||||||
spec.suite.finish()
|
|
||||||
|
|
||||||
reportSuiteResults: (suite) ->
|
|
||||||
hasError: ->
|
|
||||||
JHW.hasError()
|
|
||||||
|
|
85
vendor/assets/coffeescripts/jasmine.HeadlessConsoleReporter.coffee
vendored
Normal file
85
vendor/assets/coffeescripts/jasmine.HeadlessConsoleReporter.coffee
vendored
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
if !jasmine?
|
||||||
|
throw new Error("jasmine not loaded!")
|
||||||
|
|
||||||
|
class jasmine.HeadlessConsoleReporter
|
||||||
|
constructor: (@callback = null) ->
|
||||||
|
@results = []
|
||||||
|
@failedCount = 0
|
||||||
|
@length = 0
|
||||||
|
|
||||||
|
reportRunnerResults: (runner) ->
|
||||||
|
return if this.hasError()
|
||||||
|
|
||||||
|
runtime = (new Date() - @startTime) / 1000.0
|
||||||
|
|
||||||
|
JHW.stdout.print("\n")
|
||||||
|
|
||||||
|
resultLine = this._formatResultLine(runtime)
|
||||||
|
|
||||||
|
if @failedCount == 0
|
||||||
|
JHW.stdout.puts("PASS: #{resultLine}".foreground('green'))
|
||||||
|
else
|
||||||
|
JHW.stdout.puts("FAIL: #{resultLine}".foreground('red'))
|
||||||
|
JHW.hasSpecFailure()
|
||||||
|
|
||||||
|
output = "TOTAL||#{@length}||#{@failedCount}||#{runtime}||#{if JHW._hasErrors then "T" else "F"}"
|
||||||
|
|
||||||
|
JHW.report.puts(output)
|
||||||
|
result.print() for result in @results
|
||||||
|
|
||||||
|
if window.JHW
|
||||||
|
window.onbeforeunload = null
|
||||||
|
|
||||||
|
JHW.finishSuite()
|
||||||
|
|
||||||
|
reportRunnerStarting: (runner) ->
|
||||||
|
@startTime = new Date()
|
||||||
|
JHW.stdout.puts("\nRunning Jasmine specs...".bright())
|
||||||
|
|
||||||
|
reportSpecResults: (spec) ->
|
||||||
|
return if this.hasError()
|
||||||
|
|
||||||
|
results = spec.results()
|
||||||
|
|
||||||
|
@length++
|
||||||
|
if results.passed()
|
||||||
|
JHW.stdout.print('.'.foreground('green'))
|
||||||
|
JHW.report.puts("PASS||" + spec.getJHWSpecInformation())
|
||||||
|
else
|
||||||
|
JHW.stdout.print('F'.foreground('red'))
|
||||||
|
JHW.report.puts("FAIL||" + spec.getJHWSpecInformation())
|
||||||
|
|
||||||
|
@failedCount++
|
||||||
|
failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName())
|
||||||
|
testCount = 1
|
||||||
|
|
||||||
|
for result in results.getItems()
|
||||||
|
if result.type == 'expect' and !result.passed_
|
||||||
|
if foundLine = result.expectations[testCount - 1]
|
||||||
|
[ result.line, result.lineNumber ] = foundLine
|
||||||
|
failureResult.addResult(result)
|
||||||
|
testCount += 1
|
||||||
|
@results.push(failureResult)
|
||||||
|
|
||||||
|
reportSpecStarting: (spec) ->
|
||||||
|
if this.hasError()
|
||||||
|
spec.finish()
|
||||||
|
spec.suite.finish()
|
||||||
|
|
||||||
|
reportSuiteResults: (suite) ->
|
||||||
|
hasError: ->
|
||||||
|
JHW._hasErrors
|
||||||
|
|
||||||
|
_formatResultLine: (runtime) ->
|
||||||
|
line = []
|
||||||
|
line.push(@length)
|
||||||
|
line.push((if @length == 1 then "test" else "tests") + ',')
|
||||||
|
|
||||||
|
line.push(@failedCount)
|
||||||
|
line.push((if @failedCount == 1 then "failure" else "failures") + ',')
|
||||||
|
|
||||||
|
line.push(runtime)
|
||||||
|
line.push((if runtime == 1.0 then "sec" else "secs") + '.')
|
||||||
|
|
||||||
|
line.join(' ')
|
||||||
|
|
73
vendor/assets/coffeescripts/prolog.coffee
vendored
Normal file
73
vendor/assets/coffeescripts/prolog.coffee
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
if window.JHW
|
||||||
|
window.console =
|
||||||
|
log: (data) ->
|
||||||
|
if typeof(jQuery) != 'undefined' && data instanceof jQuery
|
||||||
|
JHW.log(style_html($("<div />").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
|
||||||
|
JHW.log(dump)
|
||||||
|
else
|
||||||
|
JHW.log("jsDump: #{dump}")
|
||||||
|
|
||||||
|
pp: (data) ->
|
||||||
|
JHW.log(if jasmine then jasmine.pp(data) else console.log(data))
|
||||||
|
|
||||||
|
peek: (data) ->
|
||||||
|
console.log(data)
|
||||||
|
data
|
||||||
|
|
||||||
|
window.onbeforeunload = (e) ->
|
||||||
|
e = e || window.event
|
||||||
|
|
||||||
|
JHW.hasError()
|
||||||
|
JHW.stdout.puts('The code tried to leave the test page. Check for unhandled form submits and link clicks.')
|
||||||
|
|
||||||
|
if e
|
||||||
|
e.returnValue = 'string'
|
||||||
|
|
||||||
|
return 'string'
|
||||||
|
|
||||||
|
window.confirm = (message) ->
|
||||||
|
JHW.stderr.puts("#{"[confirm]".foreground('red')} jasmine-headless-webkit can't handle confirm() yet! You should mock window.confirm. Returning true.")
|
||||||
|
true
|
||||||
|
|
||||||
|
window.alert = (message) ->
|
||||||
|
JHW.stderr.puts("[alert] ".foreground('red') + message)
|
||||||
|
|
||||||
|
JHW._hasErrors = false
|
||||||
|
JHW._handleError = (message, lineNumber, sourceURL) ->
|
||||||
|
JHW.stderr.puts(message)
|
||||||
|
JHW._hasErrors = true
|
||||||
|
false
|
||||||
|
|
||||||
|
JHW._setColors = (useColors) ->
|
||||||
|
Intense.useColors = useColors
|
||||||
|
|
||||||
|
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._usedConsole = false
|
||||||
|
|
||||||
|
JHW.log = (msg) ->
|
||||||
|
JHW.hasUsedConsole()
|
||||||
|
JHW.report.puts("CONSOLE||#{msg}")
|
||||||
|
JHW._usedConsole = true
|
||||||
|
JHW.stdout.puts(msg)
|
||||||
|
|
||||||
|
window.CoffeeScriptToFilename = {}
|
||||||
|
window.CSTF = window.CoffeeScriptToFilename
|
||||||
|
|
72
vendor/assets/javascripts/headless_reporter_result.js
vendored
Normal file
72
vendor/assets/javascripts/headless_reporter_result.js
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
(function() {
|
||||||
|
window.HeadlessReporterResult = (function() {
|
||||||
|
function HeadlessReporterResult(name, splitName) {
|
||||||
|
this.name = name;
|
||||||
|
this.splitName = splitName;
|
||||||
|
this.results = [];
|
||||||
|
}
|
||||||
|
HeadlessReporterResult.prototype.addResult = function(message) {
|
||||||
|
return this.results.push(message);
|
||||||
|
};
|
||||||
|
HeadlessReporterResult.prototype.print = function() {
|
||||||
|
var bestChoice, output, result, _i, _len, _ref, _results;
|
||||||
|
output = this.name.foreground('red');
|
||||||
|
bestChoice = HeadlessReporterResult.findSpecLine(this.splitName);
|
||||||
|
if (bestChoice.file) {
|
||||||
|
output += (" (" + bestChoice.file + ":" + bestChoice.lineNumber + ")").foreground('blue');
|
||||||
|
}
|
||||||
|
JHW.stdout.puts("\n\n" + output);
|
||||||
|
_ref = this.results;
|
||||||
|
_results = [];
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
result = _ref[_i];
|
||||||
|
output = result.message.foreground('red');
|
||||||
|
if (result.lineNumber) {
|
||||||
|
output += (" (line ~" + (bestChoice.lineNumber + result.lineNumber) + ")").foreground('red').bright();
|
||||||
|
}
|
||||||
|
JHW.stdout.puts(" " + output);
|
||||||
|
_results.push(result.line != null ? JHW.stdout.puts((" " + result.line).foreground('yellow')) : void 0);
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
};
|
||||||
|
HeadlessReporterResult.findSpecLine = function(splitName) {
|
||||||
|
var bestChoice, file, index, lastLine, line, lineNumber, lines, newLineNumberInfo, _i, _len, _ref;
|
||||||
|
bestChoice = {
|
||||||
|
accuracy: 0,
|
||||||
|
file: null,
|
||||||
|
lineNumber: null
|
||||||
|
};
|
||||||
|
_ref = HeadlessReporterResult.specLineNumbers;
|
||||||
|
for (file in _ref) {
|
||||||
|
lines = _ref[file];
|
||||||
|
index = 0;
|
||||||
|
lineNumber = 0;
|
||||||
|
while (newLineNumberInfo = lines[splitName[index]]) {
|
||||||
|
if (newLineNumberInfo.length === 0) {
|
||||||
|
lineNumber = newLineNumberInfo[0];
|
||||||
|
} else {
|
||||||
|
lastLine = null;
|
||||||
|
for (_i = 0, _len = newLineNumberInfo.length; _i < _len; _i++) {
|
||||||
|
line = newLineNumberInfo[_i];
|
||||||
|
lastLine = line;
|
||||||
|
if (line > lineNumber) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lineNumber = lastLine;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
if (index > bestChoice.accuracy) {
|
||||||
|
bestChoice = {
|
||||||
|
accuracy: index,
|
||||||
|
file: file,
|
||||||
|
lineNumber: lineNumber
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bestChoice;
|
||||||
|
};
|
||||||
|
return HeadlessReporterResult;
|
||||||
|
})();
|
||||||
|
}).call(this);
|
37
vendor/assets/javascripts/intense.js
vendored
Normal file
37
vendor/assets/javascripts/intense.js
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
(function() {
|
||||||
|
var code, method, _ref;
|
||||||
|
window.Intense = {
|
||||||
|
colors: {
|
||||||
|
black: 0,
|
||||||
|
red: 1,
|
||||||
|
green: 2,
|
||||||
|
yellow: 3,
|
||||||
|
blue: 4,
|
||||||
|
magenta: 5,
|
||||||
|
cyan: 6,
|
||||||
|
white: 7
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
foreground: function(color) {
|
||||||
|
if (Intense.useColors) {
|
||||||
|
return "\033[3" + Intense.colors[color] + "m" + this + "\033[0m";
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bright: function() {
|
||||||
|
if (Intense.useColors) {
|
||||||
|
return "\033[1m" + this + "\033[0m";
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
useColors: true
|
||||||
|
};
|
||||||
|
_ref = Intense.methods;
|
||||||
|
for (method in _ref) {
|
||||||
|
code = _ref[method];
|
||||||
|
String.prototype[method] = code;
|
||||||
|
}
|
||||||
|
}).call(this);
|
97
vendor/assets/javascripts/jasmine-extensions.js
vendored
Normal file
97
vendor/assets/javascripts/jasmine-extensions.js
vendored
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
(function() {
|
||||||
|
var getSplitName, pauseAndRun;
|
||||||
|
if (!(typeof jasmine !== "undefined" && jasmine !== null)) {
|
||||||
|
throw new Error("jasmine not laoded!");
|
||||||
|
}
|
||||||
|
if (window.JHW) {
|
||||||
|
getSplitName = function(parts) {
|
||||||
|
parts.push(String(this.description).replace(/[\n\r]/g, ' '));
|
||||||
|
return parts;
|
||||||
|
};
|
||||||
|
jasmine.Suite.prototype.getSuiteSplitName = function() {
|
||||||
|
return this.getSplitName(this.parentSuite ? this.parentSuite.getSuiteSplitName() : []);
|
||||||
|
};
|
||||||
|
jasmine.Spec.prototype.getSpecSplitName = function() {
|
||||||
|
return this.getSplitName(this.suite.getSuiteSplitName());
|
||||||
|
};
|
||||||
|
jasmine.Suite.prototype.getSplitName = getSplitName;
|
||||||
|
jasmine.Spec.prototype.getSplitName = getSplitName;
|
||||||
|
jasmine.Spec.prototype.getJHWSpecInformation = function() {
|
||||||
|
var parts, specLineInfo;
|
||||||
|
parts = this.getSpecSplitName();
|
||||||
|
specLineInfo = HeadlessReporterResult.findSpecLine(parts);
|
||||||
|
if (specLineInfo.file) {
|
||||||
|
parts.push("" + specLineInfo.file + ":" + specLineInfo.lineNumber);
|
||||||
|
} else {
|
||||||
|
parts.push('');
|
||||||
|
}
|
||||||
|
return parts.join("||");
|
||||||
|
};
|
||||||
|
jasmine.Spec.prototype.fail = function(e) {
|
||||||
|
var expectationResult, filename, realFilename;
|
||||||
|
if (e && e.sourceURL && window.CoffeeScriptToFilename) {
|
||||||
|
filename = e.sourceURL.split('/').pop();
|
||||||
|
if (realFilename = window.CoffeeScriptToFilename[filename]) {
|
||||||
|
e = {
|
||||||
|
name: e.name,
|
||||||
|
message: e.message,
|
||||||
|
lineNumber: "~" + String(e.line),
|
||||||
|
sourceURL: realFilename
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expectationResult = new jasmine.ExpectationResult({
|
||||||
|
passed: false,
|
||||||
|
message: e ? jasmine.util.formatException(e) : 'Exception',
|
||||||
|
trace: {
|
||||||
|
stack: e.stack
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return this.results_.addResult(expectationResult);
|
||||||
|
};
|
||||||
|
jasmine.NestedResults.isValidSpecLine = function(line) {
|
||||||
|
return line.match(/^\s*expect/) !== null || line.match(/^\s*return\s*expect/) !== null;
|
||||||
|
};
|
||||||
|
jasmine.NestedResults.parseFunction = function(func) {
|
||||||
|
var line, lineCount, lines, _i, _len, _ref;
|
||||||
|
lines = [];
|
||||||
|
lineCount = 0;
|
||||||
|
_ref = func.split("\n");
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
line = _ref[_i];
|
||||||
|
if (jasmine.NestedResults.isValidSpecLine(line)) {
|
||||||
|
line = line.replace(/^\s*/, '').replace(/\s*$/, '').replace(/^return\s*/, '');
|
||||||
|
lines.push([line, lineCount]);
|
||||||
|
}
|
||||||
|
lineCount += 1;
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
};
|
||||||
|
jasmine.NestedResults.parseAndStore = function(func) {
|
||||||
|
if (!jasmine.NestedResults.ParsedFunctions[func]) {
|
||||||
|
jasmine.NestedResults.ParsedFunctions[func] = jasmine.NestedResults.parseFunction(func);
|
||||||
|
}
|
||||||
|
return jasmine.NestedResults.ParsedFunctions[func];
|
||||||
|
};
|
||||||
|
jasmine.NestedResults.ParsedFunctions = [];
|
||||||
|
if (!jasmine.WaitsBlock.prototype._execute) {
|
||||||
|
jasmine.WaitsBlock.prototype._execute = jasmine.WaitsBlock.prototype.execute;
|
||||||
|
jasmine.WaitsForBlock.prototype._execute = jasmine.WaitsForBlock.prototype.execute;
|
||||||
|
pauseAndRun = function(onComplete) {
|
||||||
|
JHW.timerPause();
|
||||||
|
return this._execute(function() {
|
||||||
|
JHW.timerDone();
|
||||||
|
return onComplete();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
jasmine.WaitsBlock.prototype.execute = pauseAndRun;
|
||||||
|
jasmine.WaitsForBlock.prototype.execute = pauseAndRun;
|
||||||
|
jasmine.NestedResults.prototype.addResult_ = jasmine.NestedResults.prototype.addResult;
|
||||||
|
jasmine.NestedResults.prototype.addResult = function(result) {
|
||||||
|
result.expectations = [];
|
||||||
|
result.expectations = jasmine.NestedResults.parseAndStore(arguments.callee.caller.caller.caller.toString());
|
||||||
|
return this.addResult_(result);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).call(this);
|
95
vendor/assets/javascripts/jasmine.HeadlessConsoleReporter.js
vendored
Normal file
95
vendor/assets/javascripts/jasmine.HeadlessConsoleReporter.js
vendored
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
(function() {
|
||||||
|
if (!(typeof jasmine !== "undefined" && jasmine !== null)) {
|
||||||
|
throw new Error("jasmine not loaded!");
|
||||||
|
}
|
||||||
|
jasmine.HeadlessConsoleReporter = (function() {
|
||||||
|
function HeadlessConsoleReporter(callback) {
|
||||||
|
this.callback = callback != null ? callback : null;
|
||||||
|
this.results = [];
|
||||||
|
this.failedCount = 0;
|
||||||
|
this.length = 0;
|
||||||
|
}
|
||||||
|
HeadlessConsoleReporter.prototype.reportRunnerResults = function(runner) {
|
||||||
|
var output, result, resultLine, runtime, _i, _len, _ref;
|
||||||
|
if (this.hasError()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
runtime = (new Date() - this.startTime) / 1000.0;
|
||||||
|
JHW.stdout.print("\n");
|
||||||
|
resultLine = this._formatResultLine(runtime);
|
||||||
|
if (this.failedCount === 0) {
|
||||||
|
JHW.stdout.puts(("PASS: " + resultLine).foreground('green'));
|
||||||
|
} else {
|
||||||
|
JHW.stdout.puts(("FAIL: " + resultLine).foreground('red'));
|
||||||
|
JHW.hasSpecFailure();
|
||||||
|
}
|
||||||
|
output = "TOTAL||" + this.length + "||" + this.failedCount + "||" + runtime + "||" + (JHW._hasErrors ? "T" : "F");
|
||||||
|
JHW.report.puts(output);
|
||||||
|
_ref = this.results;
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
result = _ref[_i];
|
||||||
|
result.print();
|
||||||
|
}
|
||||||
|
if (window.JHW) {
|
||||||
|
window.onbeforeunload = null;
|
||||||
|
}
|
||||||
|
return JHW.finishSuite();
|
||||||
|
};
|
||||||
|
HeadlessConsoleReporter.prototype.reportRunnerStarting = function(runner) {
|
||||||
|
this.startTime = new Date();
|
||||||
|
return JHW.stdout.puts("\nRunning Jasmine specs...".bright());
|
||||||
|
};
|
||||||
|
HeadlessConsoleReporter.prototype.reportSpecResults = function(spec) {
|
||||||
|
var failureResult, foundLine, result, results, testCount, _i, _len, _ref;
|
||||||
|
if (this.hasError()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
results = spec.results();
|
||||||
|
this.length++;
|
||||||
|
if (results.passed()) {
|
||||||
|
JHW.stdout.print('.'.foreground('green'));
|
||||||
|
return JHW.report.puts("PASS||" + spec.getJHWSpecInformation());
|
||||||
|
} else {
|
||||||
|
JHW.stdout.print('F'.foreground('red'));
|
||||||
|
JHW.report.puts("FAIL||" + spec.getJHWSpecInformation());
|
||||||
|
this.failedCount++;
|
||||||
|
failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName());
|
||||||
|
testCount = 1;
|
||||||
|
_ref = results.getItems();
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
result = _ref[_i];
|
||||||
|
if (result.type === 'expect' && !result.passed_) {
|
||||||
|
if (foundLine = result.expectations[testCount - 1]) {
|
||||||
|
result.line = foundLine[0], result.lineNumber = foundLine[1];
|
||||||
|
}
|
||||||
|
failureResult.addResult(result);
|
||||||
|
}
|
||||||
|
testCount += 1;
|
||||||
|
}
|
||||||
|
return this.results.push(failureResult);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
HeadlessConsoleReporter.prototype.reportSpecStarting = function(spec) {
|
||||||
|
if (this.hasError()) {
|
||||||
|
spec.finish();
|
||||||
|
return spec.suite.finish();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
HeadlessConsoleReporter.prototype.reportSuiteResults = function(suite) {};
|
||||||
|
HeadlessConsoleReporter.prototype.hasError = function() {
|
||||||
|
return JHW._hasErrors;
|
||||||
|
};
|
||||||
|
HeadlessConsoleReporter.prototype._formatResultLine = function(runtime) {
|
||||||
|
var line;
|
||||||
|
line = [];
|
||||||
|
line.push(this.length);
|
||||||
|
line.push((this.length === 1 ? "test" : "tests") + ',');
|
||||||
|
line.push(this.failedCount);
|
||||||
|
line.push((this.failedCount === 1 ? "failure" : "failures") + ',');
|
||||||
|
line.push(runtime);
|
||||||
|
line.push((runtime === 1.0 ? "sec" : "secs") + '.');
|
||||||
|
return line.join(' ');
|
||||||
|
};
|
||||||
|
return HeadlessConsoleReporter;
|
||||||
|
})();
|
||||||
|
}).call(this);
|
89
vendor/assets/javascripts/prolog.js
vendored
Normal file
89
vendor/assets/javascripts/prolog.js
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
(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($("<div />").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) {
|
||||||
|
e = e || window.event;
|
||||||
|
JHW.hasError();
|
||||||
|
JHW.stdout.puts('The code tried to leave the test page. Check for unhandled form submits and link clicks.');
|
||||||
|
if (e) {
|
||||||
|
e.returnValue = 'string';
|
||||||
|
}
|
||||||
|
return 'string';
|
||||||
|
};
|
||||||
|
window.confirm = function(message) {
|
||||||
|
JHW.stderr.puts("" + ("[confirm]".foreground('red')) + " 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("[alert] ".foreground('red') + message);
|
||||||
|
};
|
||||||
|
JHW._hasErrors = false;
|
||||||
|
JHW._handleError = function(message, lineNumber, sourceURL) {
|
||||||
|
JHW.stderr.puts(message);
|
||||||
|
JHW._hasErrors = true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
JHW._setColors = function(useColors) {
|
||||||
|
return Intense.useColors = useColors;
|
||||||
|
};
|
||||||
|
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._usedConsole = false;
|
||||||
|
JHW.log = function(msg) {
|
||||||
|
JHW.hasUsedConsole();
|
||||||
|
JHW.report.puts("CONSOLE||" + msg);
|
||||||
|
JHW._usedConsole = true;
|
||||||
|
return JHW.stdout.puts(msg);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
window.CoffeeScriptToFilename = {};
|
||||||
|
window.CSTF = window.CoffeeScriptToFilename;
|
||||||
|
}).call(this);
|
Loading…
Reference in New Issue
Block a user