guard-jasmine 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +13 -18
- data/lib/guard/jasmine.rb +91 -9
- data/lib/guard/jasmine/formatter.rb +18 -0
- data/lib/guard/jasmine/phantomjs/run-jasmine.coffee +73 -67
- data/lib/guard/jasmine/runner.rb +46 -23
- data/lib/guard/jasmine/version.rb +1 -1
- metadata +3 -3
data/README.md
CHANGED
@@ -135,6 +135,12 @@ There following options can be passed to Guard::Jasmine:
|
|
135
135
|
:all_on_start => false # Run all specs on start.
|
136
136
|
# default: true
|
137
137
|
|
138
|
+
:keep_failed => false # Keep failed specs and add them the next run again.
|
139
|
+
# default: true
|
140
|
+
|
141
|
+
:all_after_pass => false # Run all specs after a single spec has passed.
|
142
|
+
# default: true
|
143
|
+
|
138
144
|
:notifications => false # Show success and error messages.
|
139
145
|
# default: true
|
140
146
|
|
@@ -144,7 +150,7 @@ There following options can be passed to Guard::Jasmine:
|
|
144
150
|
|
145
151
|
## Alternatives
|
146
152
|
|
147
|
-
* [guard-jasmine-headless-webkit][], a Guard for [jasmine-headless-webkit][], but doesn't run
|
153
|
+
* [guard-jasmine-headless-webkit][], a Guard for [jasmine-headless-webkit][], but doesn't run on JRuby.
|
148
154
|
* [Evergreen][], runs CoffeeScript specs headless, but has no
|
149
155
|
continuous testing support.
|
150
156
|
* [Jezebel][] a Node.js REPL and continuous test runner for [Jessie][], a Node runner for Jasmine, but has no full
|
@@ -168,26 +174,17 @@ For questions please join us on our [Google group](http://groups.google.com/grou
|
|
168
174
|
|
169
175
|
## Acknowledgment
|
170
176
|
|
171
|
-
[Ariya Hidayat][] for [PhantomJS][], a powerfull headless WebKit browser.
|
172
|
-
|
173
|
-
[
|
174
|
-
|
175
|
-
[Pivotal Labs][] for their beautiful [Jasmine][] BDD testing framework that makes JavaScript testing fun.
|
176
|
-
|
177
|
-
[Jeremy Ashkenas][] for [CoffeeScript][], that little language that compiles into JavaScript and makes me enjoy the
|
177
|
+
- [Ariya Hidayat][] for [PhantomJS][], a powerfull headless WebKit browser.
|
178
|
+
- [Brad Phelan][] for [Jasminerice][], an elegant solution for [Jasmine][] in the Rails 3.1 asset pipeline.
|
179
|
+
- [Pivotal Labs][] for their beautiful [Jasmine][] BDD testing framework that makes JavaScript testing fun.
|
180
|
+
- [Jeremy Ashkenas][] for [CoffeeScript][], that little language that compiles into JavaScript and makes me enjoy the
|
178
181
|
frontend.
|
179
|
-
|
180
|
-
The [Guard Team][] for giving us such a nice piece of software that is so easy to extend, one *has* to make a plugin
|
182
|
+
- The [Guard Team][] for giving us such a nice piece of software that is so easy to extend, one *has* to make a plugin
|
181
183
|
for it!
|
182
|
-
|
183
|
-
All the authors of the numerous [Guards][] available for making the Guard ecosystem so much growing and comprehensive.
|
184
|
+
- All the authors of the numerous [Guards][] available for making the Guard ecosystem so much growing and comprehensive.
|
184
185
|
|
185
186
|
## License
|
186
187
|
|
187
|
-
The Jasmine PhantomJS runner file [run-jasmine.coffee][] from [Roejames12][] is licensed under the BSD license.
|
188
|
-
|
189
|
-
The Guard::Jasmine itself is released under:
|
190
|
-
|
191
188
|
(The MIT License)
|
192
189
|
|
193
190
|
Copyright (c) 2011 Michael Kessler
|
@@ -218,8 +215,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
218
215
|
[PhantomJS]: http://www.phantomjs.org/
|
219
216
|
[the PhantomJS download section]: http://code.google.com/p/phantomjs/downloads/list
|
220
217
|
[PhantomJS build instructions]: http://code.google.com/p/phantomjs/wiki/BuildInstructions
|
221
|
-
[Roejames12]: https://github.com/Roejames12
|
222
|
-
[run-jasmine.coffee]: https://github.com/ariya/phantomjs/blob/master/examples/run-jasmine.coffee
|
223
218
|
[Brad Phelan]: http://twitter.com/#!/bradgonesurfing
|
224
219
|
[Jasminerice]: https://github.com/bradphelan/jasminerice
|
225
220
|
[Pivotal Labs]: http://pivotallabs.com/
|
data/lib/guard/jasmine.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'guard'
|
2
2
|
require 'guard/guard'
|
3
3
|
require 'guard/watcher'
|
4
|
+
require 'net/http'
|
4
5
|
|
5
6
|
module Guard
|
6
7
|
|
@@ -13,6 +14,8 @@ module Guard
|
|
13
14
|
autoload :Inspector, 'guard/jasmine/inspector'
|
14
15
|
autoload :Runner, 'guard/jasmine/runner'
|
15
16
|
|
17
|
+
attr_accessor :last_run_failed, :last_failed_paths
|
18
|
+
|
16
19
|
# Initialize Guard::Jasmine.
|
17
20
|
#
|
18
21
|
# @param [Array<Guard::Watcher>] watchers the watchers in the Guard block
|
@@ -22,17 +25,24 @@ module Guard
|
|
22
25
|
# @option options [Boolean] :notification show notifications
|
23
26
|
# @option options [Boolean] :hide_success hide success message notification
|
24
27
|
# @option options [Boolean] :all_on_start run all suites on start
|
28
|
+
# @option options [Boolean] :keep_failed keep failed specs and add them the next run again
|
29
|
+
# @option options [Boolean] :all_after_pass run all specs after a single spec has passed
|
25
30
|
#
|
26
31
|
def initialize(watchers = [], options = { })
|
27
32
|
defaults = {
|
28
|
-
:jasmine_url
|
29
|
-
:phantomjs_bin
|
30
|
-
:notification
|
31
|
-
:hide_success
|
32
|
-
:all_on_start
|
33
|
+
:jasmine_url => 'http://localhost:3000/jasmine',
|
34
|
+
:phantomjs_bin => '/usr/local/bin/phantomjs',
|
35
|
+
:notification => true,
|
36
|
+
:hide_success => false,
|
37
|
+
:all_on_start => true,
|
38
|
+
:keep_failed => true,
|
39
|
+
:all_after_pass => true
|
33
40
|
}
|
34
41
|
|
35
42
|
super(watchers, defaults.merge(options))
|
43
|
+
|
44
|
+
self.last_run_failed = false
|
45
|
+
self.last_failed_paths = []
|
36
46
|
end
|
37
47
|
|
38
48
|
# Gets called once when Guard starts.
|
@@ -40,7 +50,20 @@ module Guard
|
|
40
50
|
# @return [Boolean] when the start was successful
|
41
51
|
#
|
42
52
|
def start
|
43
|
-
|
53
|
+
if jasmine_runner_available?(options[:jasmine_url])
|
54
|
+
run_all if options[:all_on_start]
|
55
|
+
end
|
56
|
+
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
60
|
+
# Gets called when the Guard should reload itself.
|
61
|
+
#
|
62
|
+
# @return [Boolean] when the reload was successful
|
63
|
+
#
|
64
|
+
def reload
|
65
|
+
self.last_run_failed = false
|
66
|
+
self.last_failed_paths = []
|
44
67
|
|
45
68
|
true
|
46
69
|
end
|
@@ -50,7 +73,12 @@ module Guard
|
|
50
73
|
# @return [Boolean] when running all specs was successful
|
51
74
|
#
|
52
75
|
def run_all
|
53
|
-
Runner.run(['spec/javascripts'], options)
|
76
|
+
passed, failed_specs = Runner.run(['spec/javascripts'], options)
|
77
|
+
|
78
|
+
self.last_failed_paths = failed_specs
|
79
|
+
self.last_run_failed = !passed
|
80
|
+
|
81
|
+
passed
|
54
82
|
end
|
55
83
|
|
56
84
|
# Gets called when watched paths and files have changes.
|
@@ -59,9 +87,63 @@ module Guard
|
|
59
87
|
# @return [Boolean] when running the changed specs was successful
|
60
88
|
#
|
61
89
|
def run_on_change(paths)
|
62
|
-
|
90
|
+
paths += self.last_failed_paths if options[:keep_failed]
|
91
|
+
|
92
|
+
passed, failed_specs = Runner.run(Inspector.clean(paths), options)
|
63
93
|
|
64
|
-
|
94
|
+
if passed
|
95
|
+
self.last_failed_paths = self.last_failed_paths - paths
|
96
|
+
run_all if self.last_run_failed && options[:all_after_pass]
|
97
|
+
else
|
98
|
+
self.last_failed_paths = self.last_failed_paths + failed_specs
|
99
|
+
end
|
100
|
+
|
101
|
+
self.last_run_failed = !passed
|
102
|
+
|
103
|
+
passed
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
# Verifies if the Jasmine test runner is available.
|
109
|
+
#
|
110
|
+
# @param [String] url the location of the test runner
|
111
|
+
# @return [Boolean] when the runner is available
|
112
|
+
#
|
113
|
+
def jasmine_runner_available?(url)
|
114
|
+
url = URI.parse(url)
|
115
|
+
|
116
|
+
begin
|
117
|
+
Net::HTTP.start(url.host, url.port) do |http|
|
118
|
+
response = http.request(Net::HTTP::Head.new(url.path))
|
119
|
+
|
120
|
+
if response.code.to_i == 200
|
121
|
+
Formatter.info("Jasmine test runner is available at #{ url }")
|
122
|
+
else
|
123
|
+
notify_jasmine_runner_failure(url) if options[:notification]
|
124
|
+
end
|
125
|
+
|
126
|
+
response.code.to_i == 200
|
127
|
+
end
|
128
|
+
|
129
|
+
rescue Errno::ECONNREFUSED => e
|
130
|
+
notify_jasmine_runner_failure(url)
|
131
|
+
|
132
|
+
false
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Notify that the Jasmine runner is not available.
|
137
|
+
#
|
138
|
+
# @param [String] url the url of the Jasmine runner
|
139
|
+
#
|
140
|
+
def notify_jasmine_runner_failure(url)
|
141
|
+
message = "Jasmine test runner not available at #{ url }"
|
142
|
+
Formatter.error(message)
|
143
|
+
Formatter.notify(message,
|
144
|
+
:title => 'Jasmine test runner not available',
|
145
|
+
:image => :failed,
|
146
|
+
:priority => 2)
|
65
147
|
end
|
66
148
|
|
67
149
|
end
|
@@ -48,6 +48,24 @@ module Guard
|
|
48
48
|
::Guard::UI.info(color(message, ';32'), options)
|
49
49
|
end
|
50
50
|
|
51
|
+
# Print a red spec failed message to the console.
|
52
|
+
#
|
53
|
+
# @param [String] message the message to print
|
54
|
+
# @param [Hash] options the output options
|
55
|
+
#
|
56
|
+
def spec_failed(message, options = { })
|
57
|
+
::Guard::UI.info(color(message, ';31'), options)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Print a red spec failed message to the console.
|
61
|
+
#
|
62
|
+
# @param [String] message the message to print
|
63
|
+
# @param [Hash] options the output options
|
64
|
+
#
|
65
|
+
def suite_name(message, options = { })
|
66
|
+
::Guard::UI.info(color(message, ';33'), options)
|
67
|
+
end
|
68
|
+
|
51
69
|
# Outputs a system notification.
|
52
70
|
#
|
53
71
|
# @param [String] message the message to print
|
@@ -1,29 +1,85 @@
|
|
1
|
+
# This file is the script that runs within PhantomJS and requests the Jasmine specs,
|
2
|
+
# waits until they are ready, extracts the result form the dom and outputs a JSON
|
3
|
+
# structure that is the parsed by Guard::Jasmine.
|
4
|
+
#
|
5
|
+
# This scripts needs the TrivialReporter to report the results.
|
6
|
+
#
|
7
|
+
# This file is inspired by the Jasmine runner that comes with the PhantomJS examples:
|
8
|
+
# https://github.com/ariya/phantomjs/blob/master/examples/run-jasmine.coffee, by https://github.com/Roejames12
|
9
|
+
#
|
10
|
+
# This file is licensed under the BSD license.
|
11
|
+
|
1
12
|
# Wait until the test condition is true or a timeout occurs.
|
2
13
|
#
|
3
|
-
# @param [Function]
|
4
|
-
# @param [Function]
|
5
|
-
# @param [Number]
|
14
|
+
# @param [Function] condition the condition that evaluates to a boolean
|
15
|
+
# @param [Function] ready the action when the condition is fulfilled
|
16
|
+
# @param [Number] timeout the max amount of time to wait
|
6
17
|
#
|
7
|
-
waitFor = (
|
18
|
+
waitFor = (condition, ready, timeout = 3000) ->
|
8
19
|
start = new Date().getTime()
|
9
|
-
condition = false
|
10
20
|
wait = ->
|
11
|
-
if
|
12
|
-
|
21
|
+
if new Date().getTime() - start > timeout
|
22
|
+
console.log JSON.stringify({ error: "Timeout requesting Jasmine test runner!" })
|
23
|
+
phantom.exit(1)
|
13
24
|
else
|
14
|
-
if
|
15
|
-
|
16
|
-
phantom.exit(1)
|
17
|
-
else
|
18
|
-
if typeof onReady is 'string' then eval onReady else onReady()
|
25
|
+
if condition()
|
26
|
+
ready()
|
19
27
|
clearInterval interval
|
20
28
|
|
21
29
|
interval = setInterval wait, 100
|
22
30
|
|
31
|
+
# Test if the specs have finished.
|
32
|
+
#
|
33
|
+
specsReady = ->
|
34
|
+
page.evaluate -> if document.body.querySelector('.finished-at') then true else false
|
35
|
+
|
36
|
+
# Extract the data from a Jasmine TrivialReporter generated DOM
|
37
|
+
#
|
38
|
+
extractResult = ->
|
39
|
+
page.evaluate ->
|
40
|
+
stats = /(\d+) specs, (\d+) failures? in (\d+.\d+)s/.exec document.body.querySelector('.description').innerText
|
41
|
+
|
42
|
+
result = {
|
43
|
+
passed: true
|
44
|
+
stats: {
|
45
|
+
specs: parseInt stats[1]
|
46
|
+
failures: parseInt stats[2]
|
47
|
+
time: parseFloat stats[3]
|
48
|
+
}
|
49
|
+
suites: []
|
50
|
+
}
|
51
|
+
|
52
|
+
for suite in document.body.querySelectorAll('div.jasmine_reporter > div.suite')
|
53
|
+
description = suite.querySelector('a.description')
|
54
|
+
|
55
|
+
suite_ = {
|
56
|
+
description: description.innerText
|
57
|
+
specs: []
|
58
|
+
}
|
59
|
+
|
60
|
+
for spec in suite.querySelectorAll('div.spec')
|
61
|
+
passed = spec.getAttribute('class').indexOf('passed') isnt -1
|
62
|
+
result['passed'] = false if not passed
|
63
|
+
|
64
|
+
spec_ = {
|
65
|
+
description: spec.querySelector('a.description').getAttribute 'title'
|
66
|
+
passed: passed
|
67
|
+
}
|
68
|
+
|
69
|
+
spec_['error_message'] = spec.querySelector('div.resultMessage').innerText if not passed
|
70
|
+
|
71
|
+
suite_['specs'].push spec_
|
72
|
+
|
73
|
+
result['suites'].push suite_
|
74
|
+
|
75
|
+
console.log "JSON_RESULT: #{ JSON.stringify(result, undefined, 2) }"
|
76
|
+
|
77
|
+
phantom.exit()
|
78
|
+
|
23
79
|
# Check arguments of the script.
|
24
80
|
#
|
25
81
|
if phantom.args.length isnt 1
|
26
|
-
console.log JSON.stringify
|
82
|
+
console.log JSON.stringify({ error: "Wrong usage of PhantomJS script!" })
|
27
83
|
phantom.exit()
|
28
84
|
else
|
29
85
|
url = phantom.args[0]
|
@@ -31,66 +87,16 @@ else
|
|
31
87
|
page = new WebPage()
|
32
88
|
|
33
89
|
# Output the Jasmine test runner result as JSON object.
|
34
|
-
# Ignore all other calls to console.log
|
90
|
+
# Ignore all other calls to console.log that may come from the specs.
|
35
91
|
#
|
36
92
|
page.onConsoleMessage = (msg) ->
|
37
|
-
console.log(RegExp.$1) if /^
|
93
|
+
console.log(RegExp.$1) if /^JSON_RESULT: ([\s\S]*)$/.test(msg)
|
38
94
|
|
39
95
|
# Open web page and run the Jasmine test runner
|
40
96
|
#
|
41
97
|
page.open url, (status) ->
|
42
|
-
|
43
98
|
if status isnt 'success'
|
44
|
-
|
45
|
-
console.log "JasmineResult: #{ JSON.stringify { error: "Unable to access Jasmine specs at #{ url }" } }"
|
99
|
+
console.log "JSON_RESULT: #{ JSON.stringify({ error: "Unable to access Jasmine specs at #{ url }" }) }"
|
46
100
|
phantom.exit()
|
47
|
-
|
48
101
|
else
|
49
|
-
|
50
|
-
waitFor ->
|
51
|
-
page.evaluate ->
|
52
|
-
if document.body.querySelector '.finished-at' then true else false
|
53
|
-
, ->
|
54
|
-
# Jasmine test runner has finished, extract the result from the DOM
|
55
|
-
page.evaluate ->
|
56
|
-
|
57
|
-
# JSON response to Guard::Jasmine
|
58
|
-
result = {
|
59
|
-
suites: []
|
60
|
-
}
|
61
|
-
|
62
|
-
# Extract runner stats from the HTML
|
63
|
-
stats = /(\d+) specs, (\d+) failures? in (\d+.\d+)s/.exec document.body.querySelector('.description').innerText
|
64
|
-
|
65
|
-
# Add stats to the result
|
66
|
-
result['stats'] = {
|
67
|
-
specs: parseInt stats[1]
|
68
|
-
failures: parseInt stats[2]
|
69
|
-
time: parseFloat stats[3]
|
70
|
-
}
|
71
|
-
|
72
|
-
# Extract failed suites
|
73
|
-
for failedSuite in document.body.querySelectorAll 'div.jasmine_reporter > div.suite.failed'
|
74
|
-
description = failedSuite.querySelector('a.description')
|
75
|
-
|
76
|
-
# Add suite information to the result
|
77
|
-
suite = {
|
78
|
-
description: description.innerText
|
79
|
-
filter: description.getAttribute('href')
|
80
|
-
specs: []
|
81
|
-
}
|
82
|
-
|
83
|
-
# Collect information about each **failing** spec
|
84
|
-
for failedSpec in failedSuite.querySelectorAll 'div.spec.failed'
|
85
|
-
spec = {
|
86
|
-
description: failedSpec.querySelector('a.description').getAttribute 'title'
|
87
|
-
error_message: failedSpec.querySelector('div.messages div.resultMessage').innerText
|
88
|
-
}
|
89
|
-
suite['specs'].push spec
|
90
|
-
|
91
|
-
result['suites'].push suite
|
92
|
-
|
93
|
-
# Write result as JSON string that is parsed by Guard::Jasmine
|
94
|
-
console.log "JasmineResult: #{ JSON.stringify result, undefined, 2 }"
|
95
|
-
|
96
|
-
phantom.exit()
|
102
|
+
waitFor specsReady, extractResult
|
data/lib/guard/jasmine/runner.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
1
3
|
require 'multi_json'
|
2
4
|
|
3
5
|
module Guard
|
@@ -18,30 +20,50 @@ module Guard
|
|
18
20
|
# @option options [String] :phantomjs_bin the location of the PhantomJS binary
|
19
21
|
# @option options [Boolean] :notification show notifications
|
20
22
|
# @option options [Boolean] :hide_success hide success message notification
|
21
|
-
# @return [Array<
|
23
|
+
# @return [Boolean, Array<String>] the status of the run and the failed files
|
22
24
|
#
|
23
25
|
def run(paths, options = { })
|
24
|
-
return false if paths.empty?
|
26
|
+
return [false, []] if paths.empty?
|
25
27
|
|
26
28
|
message = options[:message] || (paths == ['spec/javascripts'] ? 'Run all specs' : "Run specs #{ paths.join(' ') }")
|
27
29
|
UI.info message, :reset => true
|
28
30
|
|
29
|
-
paths.inject([]) do |results, file|
|
30
|
-
results << evaluate_result(run_jasmine_spec(file, options), options)
|
31
|
+
results = paths.inject([]) do |results, file|
|
32
|
+
results << evaluate_result(run_jasmine_spec(file, options), file, options)
|
31
33
|
|
32
34
|
results
|
33
35
|
end.compact
|
36
|
+
|
37
|
+
[response_status_for(results), failed_paths_from(results)]
|
34
38
|
end
|
35
39
|
|
36
40
|
private
|
37
41
|
|
42
|
+
# Returns the failed spec file names.
|
43
|
+
#
|
44
|
+
# @param [Array<Object>] results the spec runner results
|
45
|
+
# @return [Array<String>] the list of failed spec files
|
46
|
+
#
|
47
|
+
def failed_paths_from(results)
|
48
|
+
results.map { |r| !r['passed'] ? r['file']: nil }.compact
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the response status for the given result set.
|
52
|
+
#
|
53
|
+
# @param [Array<Object>] results the spec runner results
|
54
|
+
# @return [Boolean] whether it has passed or not
|
55
|
+
#
|
56
|
+
def response_status_for(results)
|
57
|
+
results.none? { |r| r.has_key?('error') || !r['passed'] }
|
58
|
+
end
|
59
|
+
|
38
60
|
# Run the Jasmine spec by executing the PhantomJS script.
|
39
61
|
#
|
40
62
|
# @param [String] path the path of the spec
|
41
63
|
#
|
42
64
|
def run_jasmine_spec(file, options)
|
43
65
|
suite = jasmine_suite(file, options)
|
44
|
-
Formatter.info("Run Jasmine tests
|
66
|
+
Formatter.info("Run Jasmine tests at #{ suite }")
|
45
67
|
IO.popen(phantomjs_command(options) + ' ' + suite)
|
46
68
|
end
|
47
69
|
|
@@ -101,16 +123,18 @@ module Guard
|
|
101
123
|
# actions.
|
102
124
|
#
|
103
125
|
# @param [String] output the JSON output the spec run
|
126
|
+
# @param [String] file the file name of the spec
|
104
127
|
# @param [Hash] options the options for the execution
|
105
128
|
# @return [Hash] the suite result
|
106
129
|
#
|
107
|
-
def evaluate_result(output, options)
|
130
|
+
def evaluate_result(output, file, options)
|
108
131
|
result = MultiJson.decode(output.read)
|
109
132
|
output.close
|
110
133
|
|
111
134
|
if result['error']
|
112
135
|
notify_runtime_error(result, options)
|
113
136
|
else
|
137
|
+
result['file'] = file
|
114
138
|
notify_spec_result(result, options)
|
115
139
|
end
|
116
140
|
|
@@ -144,39 +168,38 @@ module Guard
|
|
144
168
|
time = result['stats']['time']
|
145
169
|
plural = failures == 1 ? '' : 's'
|
146
170
|
|
147
|
-
message = "
|
171
|
+
message = "#{ specs } specs, #{ failures } failure#{ plural }\nin #{ time } seconds"
|
148
172
|
|
149
173
|
if failures != 0
|
150
|
-
|
174
|
+
notify_specdoc(result, message, options)
|
151
175
|
else
|
152
176
|
Formatter.success(message)
|
153
|
-
Formatter.notify(message, :title => 'Jasmine
|
177
|
+
Formatter.notify(message, :title => 'Jasmine specs passed') if options[:notification] && !options[:hide_success]
|
154
178
|
end
|
155
179
|
end
|
156
180
|
|
157
|
-
#
|
158
|
-
# error messages into a single notification.
|
181
|
+
# Specdoc like formatting of the result.
|
159
182
|
#
|
160
183
|
# @param [Hash] result the suite result
|
161
184
|
# @param [String] stats the status information
|
162
|
-
# @
|
163
|
-
# @option options [Boolean] :notification show notifications
|
185
|
+
# @option options [Boolean] :hide_success hide success message notification
|
164
186
|
#
|
165
|
-
def
|
166
|
-
|
187
|
+
def notify_specdoc(result, stats, options)
|
188
|
+
result['suites'].each do |suite|
|
189
|
+
Formatter.suite_name("➥ #{ suite['description'] }")
|
190
|
+
|
167
191
|
suite['specs'].each do |spec|
|
168
|
-
|
192
|
+
if spec['passed']
|
193
|
+
Formatter.success(" ✔ #{ spec['description'] }") if !options[:hide_success]
|
194
|
+
else
|
195
|
+
Formatter.spec_failed(" ✘ #{ spec['description'] } ➤ #{ spec['error_message'] }")
|
196
|
+
Formatter.notify(stats, :title => "#{ spec['description'] }: #{ spec['error_message'] }", :image => :failed, :priority => 2) if options[:notification]
|
197
|
+
end
|
169
198
|
end
|
170
|
-
|
171
|
-
messages
|
172
199
|
end
|
173
200
|
|
174
|
-
|
175
|
-
|
176
|
-
Formatter.error(messages)
|
177
|
-
Formatter.notify(messages, :title => 'Jasmine results', :image => :failed, :priority => 2) if options[:notification]
|
201
|
+
Formatter.info(stats)
|
178
202
|
end
|
179
|
-
|
180
203
|
end
|
181
204
|
end
|
182
205
|
end
|