jasmine-headless-webkit 0.6.3 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/.gitignore +3 -0
  2. data/Gemfile +3 -1
  3. data/Guardfile +7 -2
  4. data/Rakefile +1 -0
  5. data/bin/jasmine-headless-webkit +15 -2
  6. data/ext/jasmine-webkit-specrunner/ConsoleOutput.cpp +140 -0
  7. data/ext/jasmine-webkit-specrunner/ConsoleOutput.h +38 -0
  8. data/ext/jasmine-webkit-specrunner/ConsoleOutput_test.cpp +129 -0
  9. data/ext/jasmine-webkit-specrunner/ConsoleOutput_test.h +32 -0
  10. data/ext/jasmine-webkit-specrunner/ConsoleOutput_test.pro +7 -0
  11. data/ext/jasmine-webkit-specrunner/Makefile.dummy +5 -0
  12. data/ext/jasmine-webkit-specrunner/{HeadlessSpecRunner/Page.cpp → Page.cpp} +3 -4
  13. data/ext/jasmine-webkit-specrunner/{HeadlessSpecRunner/Page.h → Page.h} +0 -2
  14. data/ext/jasmine-webkit-specrunner/Page_test.cpp +43 -0
  15. data/ext/jasmine-webkit-specrunner/Page_test.h +27 -0
  16. data/ext/jasmine-webkit-specrunner/Page_test.pro +6 -0
  17. data/ext/jasmine-webkit-specrunner/ReportFileOutput.cpp +54 -0
  18. data/ext/jasmine-webkit-specrunner/ReportFileOutput.h +37 -0
  19. data/ext/jasmine-webkit-specrunner/ReportFileOutput_test.cpp +88 -0
  20. data/ext/jasmine-webkit-specrunner/ReportFileOutput_test.h +26 -0
  21. data/ext/jasmine-webkit-specrunner/ReportFileOutput_test.pro +7 -0
  22. data/ext/jasmine-webkit-specrunner/Runner.cpp +211 -0
  23. data/ext/jasmine-webkit-specrunner/Runner.h +66 -0
  24. data/ext/jasmine-webkit-specrunner/common.pri +9 -0
  25. data/ext/jasmine-webkit-specrunner/extconf.rb +3 -1
  26. data/ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner.pro +19 -0
  27. data/ext/jasmine-webkit-specrunner/specrunner.cpp +5 -3
  28. data/ext/jasmine-webkit-specrunner/specrunner.pro +3 -7
  29. data/ext/jasmine-webkit-specrunner/test.pri +3 -0
  30. data/ext/jasmine-webkit-specrunner/test.rb +24 -0
  31. data/jasmine/jasmine.headless-reporter.coffee +47 -15
  32. data/jasmine/jasmine.headless-reporter.js +42 -17
  33. data/jasmine-headless-webkit.gemspec +2 -2
  34. data/js-lib/beautify-html.js +463 -0
  35. data/js-lib/jsDump.js +209 -0
  36. data/lib/jasmine/files_list.rb +35 -64
  37. data/lib/jasmine/headless/cacheable_action.rb +77 -0
  38. data/lib/jasmine/headless/coffee_script_cache.rb +20 -0
  39. data/lib/jasmine/headless/errors.rb +1 -0
  40. data/lib/jasmine/headless/options.rb +14 -2
  41. data/lib/jasmine/headless/railtie.rb +0 -2
  42. data/lib/jasmine/headless/report.rb +76 -0
  43. data/lib/jasmine/headless/report_message/console.rb +20 -0
  44. data/lib/jasmine/headless/report_message/error.rb +20 -0
  45. data/lib/jasmine/headless/report_message/fail.rb +5 -0
  46. data/lib/jasmine/headless/report_message/pass.rb +5 -0
  47. data/lib/jasmine/headless/report_message/spec.rb +30 -0
  48. data/lib/jasmine/headless/report_message/total.rb +31 -0
  49. data/lib/jasmine/headless/report_message.rb +11 -0
  50. data/lib/jasmine/headless/runner.rb +2 -6
  51. data/lib/jasmine/headless/spec_file_analyzer.rb +37 -0
  52. data/lib/jasmine/headless/task.rb +0 -2
  53. data/lib/jasmine/headless/version.rb +5 -0
  54. data/lib/jasmine/template_writer.rb +17 -2
  55. data/lib/jasmine-headless-webkit.rb +15 -2
  56. data/lib/qt/qmake.rb +61 -30
  57. data/script/gemfile +11 -0
  58. data/script/hooks/pre-commit +15 -0
  59. data/script/initialize-environment +35 -0
  60. data/script/install-git-hooks +6 -0
  61. data/spec/bin/jasmine-headless-webkit_spec.rb +10 -0
  62. data/spec/javascripts/jasmine.headless-reporter_spec.coffee +63 -5
  63. data/spec/lib/jasmine/files_list_spec.rb +37 -116
  64. data/spec/lib/jasmine/headless/cacheable_action_spec.rb +89 -0
  65. data/spec/lib/jasmine/headless/coffee_script_cache_spec.rb +21 -0
  66. data/spec/lib/jasmine/headless/options_spec.rb +3 -5
  67. data/spec/lib/jasmine/headless/report_message/spec_spec.rb +20 -0
  68. data/spec/lib/jasmine/headless/report_spec.rb +79 -0
  69. data/spec/lib/jasmine/headless/runner_spec.rb +5 -1
  70. data/spec/lib/jasmine/headless/spec_file_analyzer_spec.rb +57 -0
  71. data/spec/lib/qt/qmake_spec.rb +15 -2
  72. data/spec/spec_helper.rb +35 -22
  73. metadata +109 -19
  74. data/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/ConsoleOutput.cpp +0 -0
  75. data/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/ConsoleOutput.h +0 -0
  76. data/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Runner.cpp +0 -270
  77. data/ext/jasmine-webkit-specrunner/HeadlessSpecRunner/Runner.h +0 -61
  78. data/lib/jasmine-headless-webkit/version.rb +0 -7
@@ -0,0 +1,88 @@
1
+ #include <QtTest/QtTest>
2
+
3
+ #include "ReportFileOutput.h"
4
+ #include "ReportFileOutput_test.h"
5
+
6
+ using namespace std;
7
+
8
+ ReportFileOutputTest::ReportFileOutputTest() : QObject() {}
9
+
10
+ void ReportFileOutputTest::testPassed() {
11
+ stringstream buffer;
12
+ ReportFileOutput output;
13
+
14
+ output.outputIO = &buffer;
15
+ output.passed("test||done||file.js:23");
16
+ QVERIFY(buffer.str() == "PASS||test||done||file.js:23\n");
17
+ QVERIFY(output.successes.size() == 1);
18
+ QVERIFY(output.failures.size() == 0);
19
+ }
20
+
21
+ void ReportFileOutputTest::testFailed() {
22
+ stringstream buffer;
23
+ ReportFileOutput output;
24
+
25
+ output.outputIO = &buffer;
26
+ output.failed("test||done||file.js:23");
27
+ QVERIFY(buffer.str() == "FAIL||test||done||file.js:23\n");
28
+ QVERIFY(output.successes.size() == 0);
29
+ QVERIFY(output.failures.size() == 1);
30
+ }
31
+
32
+ void ReportFileOutputTest::testErrorLog() {
33
+ stringstream buffer;
34
+ ReportFileOutput output;
35
+
36
+ output.outputIO = &buffer;
37
+ output.errorLog("JS Error", 23, "file.js");
38
+ QVERIFY(buffer.str() == "ERROR||JS Error||file.js:23\n");
39
+ }
40
+
41
+ void ReportFileOutputTest::testConsoleLog() {
42
+ stringstream buffer;
43
+ ReportFileOutput output;
44
+
45
+ output.outputIO = &buffer;
46
+ output.consoleLog("Console");
47
+ QVERIFY(buffer.str() == "CONSOLE||Console\n");
48
+ }
49
+
50
+ void ReportFileOutputTest::testStubMethods() {
51
+ stringstream buffer;
52
+ ReportFileOutput output;
53
+
54
+ output.outputIO = &buffer;
55
+ output.internalLog("Internal", "Log");
56
+ output.logSpecFilename("Filename");
57
+ output.logSpecResult("REsult");
58
+ }
59
+
60
+ void ReportFileOutputTest::testReportFailure() {
61
+ stringstream buffer;
62
+ ReportFileOutput output;
63
+
64
+ output.outputIO = &buffer;
65
+ output.reportFailure("5", "2", "1.5");
66
+ QVERIFY(buffer.str() == "TOTAL||5||2||1.5||F\n");
67
+ }
68
+
69
+ void ReportFileOutputTest::testReportSuccess() {
70
+ stringstream buffer;
71
+ ReportFileOutput output;
72
+
73
+ output.outputIO = &buffer;
74
+ output.reportSuccess("5", "0", "1.5");
75
+ QVERIFY(buffer.str() == "TOTAL||5||0||1.5||F\n");
76
+ }
77
+
78
+ void ReportFileOutputTest::testReportSuccessWithJSErrors() {
79
+ stringstream buffer;
80
+ ReportFileOutput output;
81
+
82
+ output.outputIO = &buffer;
83
+ output.reportSuccessWithJSErrors("5", "0", "1.5");
84
+ QVERIFY(buffer.str() == "TOTAL||5||0||1.5||T\n");
85
+ }
86
+
87
+ QTEST_MAIN(ReportFileOutputTest);
88
+
@@ -0,0 +1,26 @@
1
+ #ifndef JHW_TEST_REPORT_FILE_OUTPUT
2
+ #define JHW_TEST_REPORT_FILE_OUTPUT
3
+
4
+ #include <QtTest/QtTest>
5
+ #include <iostream>
6
+ #include <sstream>
7
+ #include <string>
8
+
9
+ #include "ReportFileOutput.h"
10
+
11
+ class ReportFileOutputTest : public QObject {
12
+ Q_OBJECT
13
+ public:
14
+ ReportFileOutputTest();
15
+ private slots:
16
+ void testPassed();
17
+ void testFailed();
18
+ void testErrorLog();
19
+ void testConsoleLog();
20
+ void testStubMethods();
21
+ void testReportFailure();
22
+ void testReportSuccess();
23
+ void testReportSuccessWithJSErrors();
24
+ };
25
+
26
+ #endif
@@ -0,0 +1,7 @@
1
+ include(common.pri)
2
+ include(test.pri)
3
+
4
+ SOURCES += ReportFileOutput_test.cpp
5
+ HEADERS += ReportFileOutput_test.h
6
+
7
+
@@ -0,0 +1,211 @@
1
+ #include <QtGui>
2
+ #include <QtWebKit>
3
+ #include <QFile>
4
+ #include <QTextStream>
5
+ #include <iostream>
6
+ #include <QQueue>
7
+
8
+ #include "Runner.h"
9
+
10
+ using namespace std;
11
+
12
+ Runner::Runner() : QObject()
13
+ , m_runs(0)
14
+ , hasErrors(false)
15
+ , usedConsole(false)
16
+ , isFinished(false)
17
+ , didFail(false)
18
+ {
19
+ m_page.settings()->enablePersistentStorage();
20
+ m_ticker.setInterval(TIMER_TICK);
21
+
22
+ connect(&m_ticker, SIGNAL(timeout()), this, SLOT(timerEvent()));
23
+ connect(&m_page, SIGNAL(loadFinished(bool)), this, SLOT(watch(bool)));
24
+ connect(&m_page, SIGNAL(consoleLog(QString, int, QString)), this, SLOT(errorLog(QString, int, QString)));
25
+ connect(&m_page, SIGNAL(internalLog(QString, QString)), this, SLOT(internalLog(QString, QString)));
26
+ connect(m_page.mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(addJHW()));
27
+ }
28
+
29
+ void Runner::addFile(const QString &spec) {
30
+ runnerFiles.enqueue(spec);
31
+ }
32
+
33
+ void Runner::go()
34
+ {
35
+ m_ticker.stop();
36
+ m_page.setPreferredContentsSize(QSize(1024, 600));
37
+ addJHW();
38
+ loadSpec();
39
+
40
+ m_ticker.start();
41
+ }
42
+ void Runner::addJHW()
43
+ {
44
+ m_page.mainFrame()->addToJavaScriptWindowObject("JHW", this);
45
+ }
46
+
47
+ void Runner::loadSpec()
48
+ {
49
+ m_page.mainFrame()->load(runnerFiles.dequeue());
50
+ m_ticker.start();
51
+ }
52
+
53
+ void Runner::watch(bool ok)
54
+ {
55
+ if (!ok) {
56
+ std::cerr << "Can't load " << qPrintable(m_page.mainFrame()->url().toString()) << ", the file may be broken." << std::endl;
57
+ std::cerr << "Out of curiosity, did your tests try to submit a form and you haven't prevented that?" << std::endl;
58
+ std::cerr << "Try running your tests in your browser with the Jasmine server and see what happens." << std::endl;
59
+ QApplication::instance()->exit(1);
60
+ return;
61
+ }
62
+
63
+ }
64
+
65
+ bool Runner::hasElement(const char *select)
66
+ {
67
+ return !m_page.mainFrame()->findFirstElement(select).isNull();
68
+ }
69
+
70
+ void Runner::setColors(bool colors) {
71
+ consoleOutput.showColors = colors;
72
+ }
73
+
74
+ void Runner::reportFile(const QString &file) {
75
+ reportFileName = file;
76
+ }
77
+
78
+ bool Runner::hasError() {
79
+ return hasErrors;
80
+ }
81
+
82
+ void Runner::timerPause() {
83
+ m_ticker.stop();
84
+ }
85
+
86
+ void Runner::timerDone() {
87
+ m_ticker.start();
88
+ }
89
+
90
+ void Runner::specPassed(const QString &specDetail) {
91
+ consoleOutput.passed(specDetail);
92
+ reportFileOutput.passed(specDetail);
93
+ }
94
+
95
+ void Runner::specFailed(const QString &specDetail) {
96
+ consoleOutput.failed(specDetail);
97
+ reportFileOutput.failed(specDetail);
98
+
99
+ didFail = true;
100
+ failedSpecs.push(specDetail);
101
+ }
102
+
103
+ void Runner::errorLog(const QString &msg, int lineNumber, const QString &sourceID)
104
+ {
105
+ consoleOutput.errorLog(msg, lineNumber, sourceID);
106
+ reportFileOutput.errorLog(msg, lineNumber, sourceID);
107
+
108
+ hasErrors = true;
109
+ m_runs = 0;
110
+ m_ticker.start();
111
+ }
112
+
113
+ void Runner::internalLog(const QString &note, const QString &msg) {
114
+ consoleOutput.internalLog(note, msg);
115
+ reportFileOutput.internalLog(note, msg);
116
+ }
117
+
118
+ void Runner::log(const QString &msg)
119
+ {
120
+ usedConsole = true;
121
+ consoleOutput.consoleLog(msg);
122
+ reportFileOutput.consoleLog(msg);
123
+ }
124
+
125
+ void Runner::leavePageAttempt(const QString &msg)
126
+ {
127
+ consoleOutput.internalLog("error", msg);
128
+ m_page.oneFalseConfirm();
129
+ hasErrors = true;
130
+ }
131
+
132
+ void Runner::printName(const QString &name)
133
+ {
134
+ consoleOutput.logSpecFilename(name);
135
+ }
136
+
137
+ void Runner::printResult(const QString &result)
138
+ {
139
+ consoleOutput.logSpecResult(result);
140
+ }
141
+
142
+ void Runner::finishSuite(const QString &duration, const QString &total, const QString& failed)
143
+ {
144
+ if (didFail) {
145
+ consoleOutput.reportFailure(total, failed, duration);
146
+ reportFileOutput.reportFailure(total, failed, duration);
147
+ } else {
148
+ if (hasErrors) {
149
+ consoleOutput.reportSuccessWithJSErrors(total, failed, duration);
150
+ reportFileOutput.reportSuccessWithJSErrors(total, failed, duration);
151
+ } else {
152
+ consoleOutput.reportSuccess(total, failed, duration);
153
+ reportFileOutput.reportSuccess(total, failed, duration);
154
+ }
155
+ }
156
+
157
+ if (!reportFileName.isEmpty()) {
158
+ QFile outputFile(reportFileName);
159
+ outputFile.open(QIODevice::WriteOnly);
160
+
161
+ QTextStream ts(&outputFile);
162
+
163
+ ts << reportFileOutput.outputIO->str().c_str();
164
+
165
+ outputFile.close();
166
+ }
167
+
168
+ isFinished = true;
169
+ }
170
+
171
+ void Runner::timerEvent()
172
+ {
173
+ ++m_runs;
174
+
175
+ if (hasErrors && m_runs > 2)
176
+ QApplication::instance()->exit(1);
177
+
178
+ if (isFinished) {
179
+ int exitCode = 0;
180
+ if (didFail || hasErrors) {
181
+ exitCode = 1;
182
+ } else {
183
+ if (usedConsole) {
184
+ exitCode = 2;
185
+ }
186
+ }
187
+
188
+ bool runAgain = true;
189
+
190
+ if (runnerFiles.count() == 0) {
191
+ runAgain = false;
192
+ } else {
193
+ if (exitCode == 1) {
194
+ runAgain = false;
195
+ }
196
+ }
197
+
198
+ if (runAgain) {
199
+ isFinished = false;
200
+ loadSpec();
201
+ } else {
202
+ QApplication::instance()->exit(exitCode);
203
+ }
204
+ }
205
+
206
+ if (m_runs > MAX_LOOPS) {
207
+ std::cout << "WARNING: too many runs and the test is still not finished!" << std::endl;
208
+ QApplication::instance()->exit(1);
209
+ }
210
+ }
211
+
@@ -0,0 +1,66 @@
1
+ #ifndef JHW_RUNNER
2
+ #define JHW_RUNNER
3
+
4
+ #include <QtGui>
5
+ #include <QtWebKit>
6
+ #include <QFile>
7
+ #include <QTextStream>
8
+ #include <iostream>
9
+ #include <fstream>
10
+ #include <QQueue>
11
+
12
+ #include "Page.h"
13
+ #include "ConsoleOutput.h"
14
+ #include "ReportFileOutput.h"
15
+
16
+ using namespace std;
17
+
18
+ class Runner: public QObject {
19
+ Q_OBJECT
20
+ public:
21
+ enum { TIMER_TICK = 200, MAX_LOOPS = 25 };
22
+
23
+ Runner();
24
+ void setColors(bool colors);
25
+ void reportFile(const QString &file);
26
+ void addFile(const QString &spec);
27
+ void go();
28
+ public slots:
29
+ void log(const QString &msg);
30
+ bool hasError();
31
+ void leavePageAttempt(const QString &msg);
32
+ void timerPause();
33
+ void timerDone();
34
+ void specPassed(const QString &specDetail);
35
+ void specFailed(const QString &specDetail);
36
+ void printName(const QString &name);
37
+ void printResult(const QString &result);
38
+ void finishSuite(const QString &duration, const QString &total, const QString& failed);
39
+ private slots:
40
+ void watch(bool ok);
41
+ void errorLog(const QString &msg, int lineNumber, const QString &sourceID);
42
+ void internalLog(const QString &note, const QString &msg);
43
+ void addJHW();
44
+ void timerEvent();
45
+ protected:
46
+ bool hasElement(const char *select);
47
+ private:
48
+ Page m_page;
49
+ QTimer m_ticker;
50
+ int m_runs;
51
+ bool hasErrors;
52
+ bool usedConsole;
53
+ bool isFinished;
54
+ bool didFail;
55
+ QQueue<QString> runnerFiles;
56
+ QStack<QString> failedSpecs;
57
+
58
+ ConsoleOutput consoleOutput;
59
+ ReportFileOutput reportFileOutput;
60
+
61
+ QString reportFileName;
62
+
63
+ void loadSpec();
64
+ };
65
+
66
+ #endif
@@ -0,0 +1,9 @@
1
+ TEMPLATE = app
2
+ CONFIG -= app_bundle
3
+ QMAKE_INFO_PLIST = Info.plist
4
+ QMAKESPEC = macx-g++
5
+ QT += network webkit
6
+
7
+ SOURCES = Page.cpp Runner.cpp ConsoleOutput.cpp ReportFileOutput.cpp
8
+ HEADERS = Page.h Runner.h ConsoleOutput.h ReportFileOutput.h
9
+
@@ -4,5 +4,7 @@ $: << File.expand_path("../../../lib", __FILE__)
4
4
 
5
5
  require 'qt/qmake'
6
6
 
7
- Qt::Qmake.make!('jasmine-headless-webkit')
7
+ system %{make clean}
8
+ Qt::Qmake.make!('jasmine-headless-webkit', 'specrunner.pro')
8
9
 
10
+ FileUtils.cp File.expand_path('../Makefile.dummy', __FILE__), File.expand_path('../Makefile', __FILE__)
@@ -0,0 +1,19 @@
1
+ ######################################################################
2
+ # Automatically generated by qmake (2.01a) Tue Aug 2 10:37:48 2011
3
+ ######################################################################
4
+
5
+ TEMPLATE = app
6
+ TARGET =
7
+ DEPENDPATH += . HeadlessSpecRunner Test
8
+ INCLUDEPATH += . HeadlessSpecRunner Test
9
+
10
+ # Input
11
+ HEADERS += HeadlessSpecRunner/ConsoleOutput.h \
12
+ HeadlessSpecRunner/Page.h \
13
+ HeadlessSpecRunner/Runner.h \
14
+ Test/Page_test.h
15
+ SOURCES += specrunner.cpp \
16
+ HeadlessSpecRunner/ConsoleOutput.cpp \
17
+ HeadlessSpecRunner/Page.cpp \
18
+ HeadlessSpecRunner/Runner.cpp \
19
+ Test/Page_test.cpp
@@ -21,8 +21,8 @@
21
21
  THE SOFTWARE.
22
22
  */
23
23
 
24
- #include "HeadlessSpecRunner/Page.h"
25
- #include "HeadlessSpecRunner/Runner.h"
24
+ #include "Page.h"
25
+ #include "Runner.h"
26
26
 
27
27
  #if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
28
28
  #error Use Qt 4.7 or later version
@@ -54,13 +54,15 @@ int main(int argc, char** argv)
54
54
 
55
55
  QApplication app(argc, argv);
56
56
  app.setApplicationName("jasmine-headless-webkit");
57
- HeadlessSpecRunner::Runner runner;
57
+ Runner runner;
58
58
  runner.setColors(showColors);
59
+
59
60
  runner.reportFile(reporter);
60
61
 
61
62
  for (index = optind; index < argc; index++) {
62
63
  runner.addFile(QString::fromLocal8Bit(argv[index]));
63
64
  }
65
+
64
66
  runner.go();
65
67
 
66
68
  return app.exec();
@@ -1,8 +1,4 @@
1
- TEMPLATE = app
2
- CONFIG -= app_bundle
1
+ include(common.pri)
2
+
3
+ SOURCES += specrunner.cpp
3
4
  TARGET = jasmine-webkit-specrunner
4
- SOURCES = HeadlessSpecRunner/Page.cpp HeadlessSpecRunner/Runner.cpp specrunner.cpp
5
- HEADERS = HeadlessSpecRunner/Page.h HeadlessSpecRunner/Runner.h
6
- QT += network webkit
7
- QMAKE_INFO_PLIST = Info.plist
8
- QMAKESPEC = macx-gcc
@@ -0,0 +1,3 @@
1
+ TARGET = jhw-test
2
+ QT += testlib
3
+
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fileutils'
4
+
5
+ system %{make clean}
6
+
7
+ $: << File.expand_path("../../../lib", __FILE__)
8
+ require 'qt/qmake'
9
+
10
+ Dir['*_test.pro'].each do |test|
11
+ FileUtils.rm_f('jhw-test')
12
+
13
+ Qt::Qmake.make!('jasmine-headless-webkit', test)
14
+
15
+ if File.file?('jhw-test')
16
+ system %{./jhw-test}
17
+ if $?.exitstatus != 0
18
+ exit 1
19
+ end
20
+ else
21
+ exit 1
22
+ end
23
+ end
24
+
@@ -1,6 +1,43 @@
1
1
  if !jasmine?
2
2
  throw new Error("jasmine not laoded!")
3
3
 
4
+ # Jasmine extensions
5
+ getSplitName = (parts) ->
6
+ parts.push(String(@description).replace(/[\n\r]/g, ' '))
7
+ parts
8
+
9
+ jasmine.Suite.prototype.getSuiteSplitName = ->
10
+ this.getSplitName(if @parentSuite then @parentSuite.getSuiteSplitName() else [])
11
+
12
+ jasmine.Spec.prototype.getSpecSplitName = ->
13
+ this.getSplitName(@suite.getSuiteSplitName())
14
+
15
+ jasmine.Suite.prototype.getSplitName = getSplitName
16
+ jasmine.Spec.prototype.getSplitName = getSplitName
17
+
18
+ jasmine.Spec.prototype.getJHWSpecInformation = ->
19
+ parts = this.getSpecSplitName()
20
+ specLineInfo = HeadlessReporterResult.findSpecLine(parts)
21
+ if specLineInfo.file
22
+ parts.push("#{specLineInfo.file}:#{specLineInfo.lineNumber}")
23
+ else
24
+ parts.push('')
25
+ parts.join("||")
26
+
27
+ if !jasmine.WaitsBlock.prototype._execute
28
+ jasmine.WaitsBlock.prototype._execute = jasmine.WaitsBlock.prototype.execute
29
+ jasmine.WaitsForBlock.prototype._execute = jasmine.WaitsForBlock.prototype.execute
30
+
31
+ pauseAndRun = (onComplete) ->
32
+ JHW.timerPause()
33
+ this._execute ->
34
+ JHW.timerDone()
35
+ onComplete()
36
+
37
+ jasmine.WaitsBlock.prototype.execute = pauseAndRun
38
+ jasmine.WaitsForBlock.prototype.execute = pauseAndRun
39
+
40
+ # Try to get the line number of a failed spec
4
41
  class window.HeadlessReporterResult
5
42
  constructor: (@name, @splitName) ->
6
43
  @results = []
@@ -8,19 +45,19 @@ class window.HeadlessReporterResult
8
45
  @results.push(message)
9
46
  print: ->
10
47
  output = @name
11
- bestChoice = this._findSpecLine()
48
+ bestChoice = HeadlessReporterResult.findSpecLine(@splitName)
12
49
  output += " (#{bestChoice.file}:#{bestChoice.lineNumber})" if bestChoice.file
13
50
 
14
51
  JHW.printName(output)
15
52
  for result in @results
16
53
  JHW.printResult(result)
17
- _findSpecLine: ->
54
+ @findSpecLine: (splitName) ->
18
55
  bestChoice = { accuracy: 0, file: null, lineNumber: null }
19
56
 
20
57
  for file, lines of HeadlessReporterResult.specLineNumbers
21
58
  index = 0
22
59
  lineNumber = 0
23
- while newLineNumberInfo = lines[@splitName[index]]
60
+ while newLineNumberInfo = lines[splitName[index]]
24
61
  if newLineNumberInfo.length == 0
25
62
  lineNumber = newLineNumberInfo[0]
26
63
  else
@@ -38,16 +75,7 @@ class window.HeadlessReporterResult
38
75
 
39
76
  bestChoice
40
77
 
41
- jasmine.Suite.prototype.getSuiteSplitName = ->
42
- parts = if @parentSuite then @parentSuite.getSuiteSplitName() else []
43
- parts.push(@description)
44
- parts
45
-
46
- jasmine.Spec.prototype.getSpecSplitName = ->
47
- parts = @suite.getSuiteSplitName()
48
- parts.push(@description)
49
- parts
50
-
78
+ # The reporter itself.
51
79
  class jasmine.HeadlessReporter
52
80
  constructor: (@callback = null) ->
53
81
  @results = []
@@ -61,27 +89,31 @@ class jasmine.HeadlessReporter
61
89
 
62
90
  this.callback() if @callback
63
91
  JHW.finishSuite((new Date() - @startTime) / 1000.0, @length, @failedCount)
92
+
64
93
  reportRunnerStarting: (runner) ->
65
94
  @startTime = new Date()
95
+
66
96
  reportSpecResults: (spec) ->
67
97
  return if this.hasError()
68
98
 
69
99
  results = spec.results()
70
100
  @length++
71
101
  if results.passed()
72
- JHW.specPassed()
102
+ JHW.specPassed(spec.getJHWSpecInformation())
73
103
  else
74
- JHW.specFailed(spec.getSpecSplitName().join('||'))
104
+ JHW.specFailed(spec.getJHWSpecInformation())
75
105
  @failedCount++
76
106
  failureResult = new HeadlessReporterResult(spec.getFullName(), spec.getSpecSplitName())
77
107
  for result in results.getItems()
78
108
  if result.type == 'expect' and !result.passed_
79
109
  failureResult.addResult(result.message)
80
110
  @results.push(failureResult)
111
+
81
112
  reportSpecStarting: (spec) ->
82
113
  if this.hasError()
83
114
  spec.finish()
84
115
  spec.suite.finish()
116
+
85
117
  reportSuiteResults: (suite) ->
86
118
  hasError: ->
87
119
  JHW.hasError()