guard-jasmine 1.0.4 → 1.1.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 +18 -5
- data/lib/guard/jasmine.rb +2 -0
- data/lib/guard/jasmine/cli.rb +7 -0
- data/lib/guard/jasmine/phantomjs/guard-jasmine.coffee +18 -25
- data/lib/guard/jasmine/phantomjs/lib/reporter.js +5 -2
- data/lib/guard/jasmine/phantomjs/lib/result.js +120 -0
- data/lib/guard/jasmine/phantomjs/src/console.coffee +1 -1
- data/lib/guard/jasmine/phantomjs/src/reporter.coffee +3 -1
- data/lib/guard/jasmine/phantomjs/src/result.coffee +79 -0
- data/lib/guard/jasmine/phantomjs/test/console_spec.coffee +1 -1
- data/lib/guard/jasmine/phantomjs/test/result_spec.coffee +311 -0
- data/lib/guard/jasmine/runner.rb +37 -11
- data/lib/guard/jasmine/version.rb +1 -1
- metadata +97 -29
data/README.md
CHANGED
@@ -314,9 +314,6 @@ The spec runner options configures the behavior driven development (or BDD) cycl
|
|
314
314
|
:all_on_start => false # Run all suites on start.
|
315
315
|
# default: true
|
316
316
|
|
317
|
-
:all_on_start => false # Run all suites on start.
|
318
|
-
# default: true
|
319
|
-
|
320
317
|
:keep_failed => false # Keep failed suites and add them to the next run again.
|
321
318
|
# default: true
|
322
319
|
|
@@ -351,6 +348,10 @@ be shown in the console:
|
|
351
348
|
:console => :always # Console.log output options,
|
352
349
|
# either :always, :never or :failure
|
353
350
|
# default: :failure
|
351
|
+
|
352
|
+
:errors => :always # Error output options,
|
353
|
+
# either :always, :never or :failure
|
354
|
+
# default: :failure
|
354
355
|
```
|
355
356
|
|
356
357
|
With the option set to `:always`, the specdoc is shown with and without errors in your spec, whereas on with the option
|
@@ -359,6 +360,10 @@ set to `:never`, there is no output at all, instead just a summary of the spec r
|
|
359
360
|
|
360
361
|
When `:focus` is enabled, only the failing specs are shown in the specdoc when at least one spec is failing.
|
361
362
|
|
363
|
+
The `:errors` option is partially working when using at least PhantomJS version 1.5. Please see
|
364
|
+
[Issue #166](http://code.google.com/p/phantomjs/issues/detail?id=166) for the actual status of retreiving the JavaScript
|
365
|
+
stack trace.
|
366
|
+
|
362
367
|
<a name="console-logs" />
|
363
368
|
#### Console logs
|
364
369
|
|
@@ -454,6 +459,9 @@ Options:
|
|
454
459
|
-c, [--console=CONSOLE] # Whether to show console.log statements in the spec runner,
|
455
460
|
# either `always`, `never` or `failure`
|
456
461
|
# Default: failure
|
462
|
+
-x, [--errors=ERRORS] # Whether to show errors in the spec runner,
|
463
|
+
# either `always`, `never` or `failure`
|
464
|
+
# Default: failure
|
457
465
|
-e, [--server-env=SERVER_ENV] # The server environment to use, for example `development`, `test`
|
458
466
|
# Default: test
|
459
467
|
|
@@ -504,12 +512,17 @@ script: 'bundle exec guard-jasmine'
|
|
504
512
|
|
505
513
|
You can also run your Guard::Jasmine specs after your specs that are ran with `rake` by using `after_script`:
|
506
514
|
|
515
|
+
```yaml
|
516
|
+
script: 'rake spec'
|
517
|
+
after_script: 'bundle exec guard-jasmine'
|
518
|
+
```
|
519
|
+
|
520
|
+
When using a PhantomJS version prior to 1.5, you need to start `xvfb` before running the specs:
|
521
|
+
|
507
522
|
```yaml
|
508
523
|
before_script:
|
509
524
|
- "export DISPLAY=:99.0"
|
510
525
|
- "sh -e /etc/init.d/xvfb start"
|
511
|
-
script: 'rake spec'
|
512
|
-
after_script: 'bundle exec guard-jasmine'
|
513
526
|
```
|
514
527
|
|
515
528
|
## Alternatives
|
data/lib/guard/jasmine.rb
CHANGED
@@ -36,6 +36,7 @@ module Guard
|
|
36
36
|
:max_error_notify => 3,
|
37
37
|
:specdoc => :failure,
|
38
38
|
:console => :failure,
|
39
|
+
:errors => :failure,
|
39
40
|
:focus => true
|
40
41
|
}
|
41
42
|
|
@@ -59,6 +60,7 @@ module Guard
|
|
59
60
|
# @option options [Boolean] :all_after_pass run all suites after a suite has passed again after failing
|
60
61
|
# @option options [Symbol] :specdoc options for the specdoc output, either :always, :never or :failure
|
61
62
|
# @option options [Symbol] :console options for the console.log output, either :always, :never or :failure
|
63
|
+
# @option options [Symbol] :errors options for the errors output, either :always, :never or :failure
|
62
64
|
# @option options [Symbol] :focus options for focus on failures in the specdoc
|
63
65
|
#
|
64
66
|
def initialize(watchers = [], options = { })
|
data/lib/guard/jasmine/cli.rb
CHANGED
@@ -57,6 +57,12 @@ module Guard
|
|
57
57
|
:default => 'failure',
|
58
58
|
:desc => 'Whether to show console.log statements in the spec runner, either `always`, `never` or `failure`'
|
59
59
|
|
60
|
+
method_option :errors,
|
61
|
+
:type => :string,
|
62
|
+
:aliases => '-x',
|
63
|
+
:default => 'failure',
|
64
|
+
:desc => 'Whether to show errors in the spec runner, either `always`, `never` or `failure`'
|
65
|
+
|
60
66
|
method_option :server_env,
|
61
67
|
:type => :string,
|
62
68
|
:aliases => '-e',
|
@@ -85,6 +91,7 @@ module Guard
|
|
85
91
|
runner[:server_env] = options.server_env
|
86
92
|
runner[:spec_dir] = options.spec_dir
|
87
93
|
runner[:console] = [:always, :never, :failure].include?(options.console.to_sym) ? options.console.to_sym : :failure
|
94
|
+
runner[:errors] = [:always, :never, :failure].include?(options.errors.to_sym) ? options.errors.to_sym : :failure
|
88
95
|
runner[:server] = options.server.to_sym
|
89
96
|
|
90
97
|
runner[:notification] = false
|
@@ -1,9 +1,15 @@
|
|
1
1
|
# This file is the script that runs within PhantomJS, requests the Jasmine specs
|
2
2
|
# and waits until they are ready.
|
3
|
+
phantom.injectJs 'lib/result.js'
|
3
4
|
|
4
5
|
# Set default values
|
5
|
-
|
6
|
-
|
6
|
+
options =
|
7
|
+
url: phantom.args[0] || 'http://127.0.0.1:3000/jasmine'
|
8
|
+
timeout: parseInt(phantom.args[1] || 5000)
|
9
|
+
specdoc: phantom.args[2] || 'failure'
|
10
|
+
focus: /true/i.test phantom.args[3]
|
11
|
+
console: phantom.args[4] || 'failure'
|
12
|
+
errors: phantom.args[5] || 'failure'
|
7
13
|
|
8
14
|
# Create the web page.
|
9
15
|
#
|
@@ -13,22 +19,14 @@ page = require('webpage').create()
|
|
13
19
|
#
|
14
20
|
currentSpecId = -1
|
15
21
|
logs = {}
|
22
|
+
errors = {}
|
16
23
|
|
17
|
-
#
|
24
|
+
# Catch JavaScript errors
|
18
25
|
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
arguments.callee(s) if s
|
24
|
-
|
25
|
-
for spec in suite.specs
|
26
|
-
id = Number(spec['id'])
|
27
|
-
spec['logs'] = logs[id] if logs[id] && logs[id].length isnt 0
|
28
|
-
delete spec['id']
|
29
|
-
|
30
|
-
delete suite['id']
|
31
|
-
delete suite['parent']
|
26
|
+
page.onError = (msg, trace) ->
|
27
|
+
if currentSpecId && currentSpecId isnt -1
|
28
|
+
errors[currentSpecId] ||= []
|
29
|
+
errors[currentSpecId].push({ msg: msg, trace: trace })
|
32
30
|
|
33
31
|
# Capture console.log output to add it to
|
34
32
|
# the result when specs have finished.
|
@@ -36,12 +34,7 @@ page.addLogs = (suite) ->
|
|
36
34
|
page.onConsoleMessage = (msg, line, source) ->
|
37
35
|
if /^RUNNER_END$/.test(msg)
|
38
36
|
result = page.evaluate -> window.reporter.runnerResult
|
39
|
-
|
40
|
-
for suite in result.suites
|
41
|
-
page.addLogs(suite)
|
42
|
-
|
43
|
-
console.log JSON.stringify(result)
|
44
|
-
|
37
|
+
console.log JSON.stringify(new Result(result, logs, errors, options).process())
|
45
38
|
page.evaluate -> window.resultReceived = true
|
46
39
|
|
47
40
|
else if /^SPEC_START: (\d+)$/.test(msg)
|
@@ -66,16 +59,16 @@ page.onInitialized = ->
|
|
66
59
|
|
67
60
|
# Open web page and run the Jasmine test runner
|
68
61
|
#
|
69
|
-
page.open url, (status) ->
|
62
|
+
page.open options.url, (status) ->
|
70
63
|
# Avoid that a failed iframe load breaks the runner, see https://github.com/netzpirat/guard-jasmine/pull/19
|
71
64
|
page.onLoadFinished = ->
|
72
65
|
|
73
66
|
if status isnt 'success'
|
74
|
-
console.log JSON.stringify({ error: "Unable to access Jasmine specs at #{ url }" })
|
67
|
+
console.log JSON.stringify({ error: "Unable to access Jasmine specs at #{ options.url }" })
|
75
68
|
phantom.exit()
|
76
69
|
else
|
77
70
|
done = -> phantom.exit()
|
78
|
-
waitFor specsReady, done, timeout
|
71
|
+
waitFor specsReady, done, options.timeout
|
79
72
|
|
80
73
|
# Test if the specs have finished.
|
81
74
|
#
|
@@ -76,7 +76,7 @@
|
|
76
76
|
};
|
77
77
|
|
78
78
|
ConsoleReporter.prototype.reportRunnerResults = function(runner) {
|
79
|
-
var runtime;
|
79
|
+
var end, runtime;
|
80
80
|
runtime = (new Date().getTime() - this.startTime) / 1000;
|
81
81
|
this.runnerResult['passed'] = runner.results().failedCount === 0;
|
82
82
|
this.runnerResult['stats'] = {
|
@@ -84,7 +84,10 @@
|
|
84
84
|
failures: runner.results().failedCount,
|
85
85
|
time: runtime
|
86
86
|
};
|
87
|
-
|
87
|
+
end = function() {
|
88
|
+
return console.log("RUNNER_END");
|
89
|
+
};
|
90
|
+
return setTimeout(end, 10);
|
88
91
|
};
|
89
92
|
|
90
93
|
ConsoleReporter.prototype.reportRunnerStarting = function(runner) {
|
@@ -0,0 +1,120 @@
|
|
1
|
+
(function() {
|
2
|
+
var Result;
|
3
|
+
|
4
|
+
Result = (function() {
|
5
|
+
|
6
|
+
function Result(result, logs, errors, options) {
|
7
|
+
this.result = result;
|
8
|
+
this.logs = logs != null ? logs : {};
|
9
|
+
this.errors = errors != null ? errors : {};
|
10
|
+
this.options = options != null ? options : {};
|
11
|
+
}
|
12
|
+
|
13
|
+
Result.prototype.addLogs = function(suite) {
|
14
|
+
var id, s, spec;
|
15
|
+
suite.suites = (function() {
|
16
|
+
var _i, _len, _ref, _results;
|
17
|
+
_ref = suite.suites;
|
18
|
+
_results = [];
|
19
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
20
|
+
s = _ref[_i];
|
21
|
+
_results.push(this.addLogs(s));
|
22
|
+
}
|
23
|
+
return _results;
|
24
|
+
}).call(this);
|
25
|
+
if (suite.specs) {
|
26
|
+
suite.specs = (function() {
|
27
|
+
var _i, _len, _ref, _results;
|
28
|
+
_ref = suite.specs;
|
29
|
+
_results = [];
|
30
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
31
|
+
spec = _ref[_i];
|
32
|
+
if (this.options.console === 'always' || (this.options.console === 'failure' && !spec.passed)) {
|
33
|
+
id = Number(spec['id']);
|
34
|
+
if (this.logs[id] && this.logs[id].length !== 0) {
|
35
|
+
spec.logs = this.logs[id];
|
36
|
+
}
|
37
|
+
}
|
38
|
+
_results.push(spec);
|
39
|
+
}
|
40
|
+
return _results;
|
41
|
+
}).call(this);
|
42
|
+
}
|
43
|
+
return suite;
|
44
|
+
};
|
45
|
+
|
46
|
+
Result.prototype.addErrors = function(suite) {
|
47
|
+
var id, s, spec;
|
48
|
+
suite.suites = (function() {
|
49
|
+
var _i, _len, _ref, _results;
|
50
|
+
_ref = suite.suites;
|
51
|
+
_results = [];
|
52
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
53
|
+
s = _ref[_i];
|
54
|
+
_results.push(this.addErrors(s));
|
55
|
+
}
|
56
|
+
return _results;
|
57
|
+
}).call(this);
|
58
|
+
if (suite.specs) {
|
59
|
+
suite.specs = (function() {
|
60
|
+
var _i, _len, _ref, _results;
|
61
|
+
_ref = suite.specs;
|
62
|
+
_results = [];
|
63
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
64
|
+
spec = _ref[_i];
|
65
|
+
if (this.options.errors === 'always' || (this.options.errors === 'failure' && !spec.passed)) {
|
66
|
+
id = Number(spec['id']);
|
67
|
+
if (this.errors[id] && this.errors[id].length !== 0) {
|
68
|
+
spec.errors = this.errors[id];
|
69
|
+
}
|
70
|
+
}
|
71
|
+
_results.push(spec);
|
72
|
+
}
|
73
|
+
return _results;
|
74
|
+
}).call(this);
|
75
|
+
}
|
76
|
+
return suite;
|
77
|
+
};
|
78
|
+
|
79
|
+
Result.prototype.cleanResult = function(suite) {
|
80
|
+
var s, spec, _i, _len, _ref;
|
81
|
+
suite.suites = (function() {
|
82
|
+
var _i, _len, _ref, _results;
|
83
|
+
_ref = suite.suites;
|
84
|
+
_results = [];
|
85
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
86
|
+
s = _ref[_i];
|
87
|
+
_results.push(this.cleanResult(s));
|
88
|
+
}
|
89
|
+
return _results;
|
90
|
+
}).call(this);
|
91
|
+
if (suite.specs) {
|
92
|
+
_ref = suite.specs;
|
93
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
94
|
+
spec = _ref[_i];
|
95
|
+
delete spec['id'];
|
96
|
+
}
|
97
|
+
}
|
98
|
+
delete suite['id'];
|
99
|
+
delete suite['parent'];
|
100
|
+
return suite;
|
101
|
+
};
|
102
|
+
|
103
|
+
Result.prototype.process = function() {
|
104
|
+
if (this.options.console !== 'never') this.addLogs(this.result);
|
105
|
+
if (this.options.errors !== 'never') this.addErrors(this.result);
|
106
|
+
this.cleanResult(this.result);
|
107
|
+
return this.result;
|
108
|
+
};
|
109
|
+
|
110
|
+
return Result;
|
111
|
+
|
112
|
+
})();
|
113
|
+
|
114
|
+
if (typeof module !== 'undefined' && module.exports) {
|
115
|
+
if (module) module.exports = Result;
|
116
|
+
} else {
|
117
|
+
if (window) window.Result = Result;
|
118
|
+
}
|
119
|
+
|
120
|
+
}).call(this);
|
@@ -87,7 +87,9 @@ class ConsoleReporter
|
|
87
87
|
time: runtime
|
88
88
|
}
|
89
89
|
|
90
|
-
|
90
|
+
# Delay the end runner message, so that logs and errors can be retreived in between
|
91
|
+
end = -> console.log "RUNNER_END"
|
92
|
+
setTimeout end, 10
|
91
93
|
|
92
94
|
# Report the start of the runner
|
93
95
|
#
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Combines various information into the final result set
|
2
|
+
# that will be outputted to the console.
|
3
|
+
#
|
4
|
+
class Result
|
5
|
+
|
6
|
+
# Construct the result parser
|
7
|
+
#
|
8
|
+
constructor: (@result, @logs = {}, @errors = {}, @options = {}) ->
|
9
|
+
|
10
|
+
# Add captured log statements to the result
|
11
|
+
#
|
12
|
+
# @param [Object] suite the suite result
|
13
|
+
# @return [Object] the suite
|
14
|
+
#
|
15
|
+
addLogs: (suite) ->
|
16
|
+
suite.suites = for s in suite.suites
|
17
|
+
@addLogs(s)
|
18
|
+
|
19
|
+
if suite.specs
|
20
|
+
suite.specs = for spec in suite.specs
|
21
|
+
if @options.console is 'always' || (@options.console is 'failure' && !spec.passed)
|
22
|
+
id = Number(spec['id'])
|
23
|
+
spec.logs = @logs[id] if @logs[id] && @logs[id].length isnt 0
|
24
|
+
|
25
|
+
spec
|
26
|
+
|
27
|
+
suite
|
28
|
+
|
29
|
+
# Add captured errors to the result
|
30
|
+
#
|
31
|
+
# @param [Object] suite the suite result
|
32
|
+
# @return [Object] the suite
|
33
|
+
#
|
34
|
+
addErrors: (suite) ->
|
35
|
+
suite.suites = for s in suite.suites
|
36
|
+
@addErrors(s)
|
37
|
+
|
38
|
+
if suite.specs
|
39
|
+
suite.specs = for spec in suite.specs
|
40
|
+
if @options.errors is 'always' || (@options.errors is 'failure' && !spec.passed)
|
41
|
+
id = Number(spec['id'])
|
42
|
+
spec.errors = @errors[id] if @errors[id] && @errors[id].length isnt 0
|
43
|
+
|
44
|
+
spec
|
45
|
+
|
46
|
+
suite
|
47
|
+
|
48
|
+
# Clean unnecessary properties from the result
|
49
|
+
#
|
50
|
+
# @param [Object] suite the suite result
|
51
|
+
# @return [Object] the cleaned suite
|
52
|
+
#
|
53
|
+
cleanResult: (suite) ->
|
54
|
+
suite.suites = for s in suite.suites
|
55
|
+
@cleanResult(s)
|
56
|
+
|
57
|
+
if suite.specs
|
58
|
+
delete spec['id'] for spec in suite.specs
|
59
|
+
|
60
|
+
delete suite['id']
|
61
|
+
delete suite['parent']
|
62
|
+
|
63
|
+
suite
|
64
|
+
|
65
|
+
# Writes the result output to the console.
|
66
|
+
#
|
67
|
+
# @return [Object] the Jasmine result
|
68
|
+
#
|
69
|
+
process: ->
|
70
|
+
@addLogs(@result) if @options.console isnt 'never'
|
71
|
+
@addErrors(@result) if @options.errors isnt 'never'
|
72
|
+
@cleanResult(@result)
|
73
|
+
|
74
|
+
@result
|
75
|
+
|
76
|
+
if typeof module isnt 'undefined' and module.exports
|
77
|
+
module.exports = Result if module
|
78
|
+
else
|
79
|
+
window.Result = Result if window
|
@@ -0,0 +1,311 @@
|
|
1
|
+
sinon = require 'sinon'
|
2
|
+
{expect} = require 'chai'
|
3
|
+
|
4
|
+
Result = require '../src/result'
|
5
|
+
|
6
|
+
describe 'Result', ->
|
7
|
+
beforeEach ->
|
8
|
+
@logObj =
|
9
|
+
0: ['Log 1', 'Another Log']
|
10
|
+
1: ['Log 2']
|
11
|
+
3: ['Log 4', 'more Logs']
|
12
|
+
|
13
|
+
@errorsObj =
|
14
|
+
1: [{ msg: 'Failure 1', trace: { file: 'a file' }}]
|
15
|
+
2: [{ msg: 'Failure 2', trace: { file: 'another file' }}]
|
16
|
+
3: [{ msg: 'Failure 3', trace: { file: 'file' }}]
|
17
|
+
|
18
|
+
@resultObj =
|
19
|
+
passed: false
|
20
|
+
stats:
|
21
|
+
failures: 1
|
22
|
+
specs: 4
|
23
|
+
time: 0.10
|
24
|
+
specs: [
|
25
|
+
{
|
26
|
+
description: "Spec 1"
|
27
|
+
id: 0
|
28
|
+
passed: true
|
29
|
+
}
|
30
|
+
]
|
31
|
+
suites: [
|
32
|
+
{
|
33
|
+
description: "Suite 1"
|
34
|
+
id: 0
|
35
|
+
passed: true
|
36
|
+
specs: [
|
37
|
+
{
|
38
|
+
description: "Spec 2"
|
39
|
+
id: 1
|
40
|
+
passed: true
|
41
|
+
}
|
42
|
+
{
|
43
|
+
description: "Spec 3"
|
44
|
+
id: 2
|
45
|
+
passed: true
|
46
|
+
}
|
47
|
+
]
|
48
|
+
suites: [
|
49
|
+
description: "Suite 2"
|
50
|
+
id: 1
|
51
|
+
passed: false
|
52
|
+
specs: [
|
53
|
+
{
|
54
|
+
description: "Spec 4"
|
55
|
+
id: 3
|
56
|
+
passed: false
|
57
|
+
}
|
58
|
+
]
|
59
|
+
suites: []
|
60
|
+
]
|
61
|
+
}
|
62
|
+
]
|
63
|
+
|
64
|
+
describe '#prepare', ->
|
65
|
+
describe 'when console and errors are :never', ->
|
66
|
+
beforeEach ->
|
67
|
+
@result = new Result(@resultObj, @logObj, @errorsObj, { console: 'never', errors: 'never' }).process()
|
68
|
+
|
69
|
+
it 'does not add the log and error statements to the specs', ->
|
70
|
+
expected = {
|
71
|
+
passed: false
|
72
|
+
stats:
|
73
|
+
failures: 1
|
74
|
+
specs: 4
|
75
|
+
time: 0.10
|
76
|
+
specs: [
|
77
|
+
{
|
78
|
+
description: "Spec 1"
|
79
|
+
passed: true
|
80
|
+
}
|
81
|
+
]
|
82
|
+
suites: [
|
83
|
+
{
|
84
|
+
description: "Suite 1"
|
85
|
+
passed: true
|
86
|
+
specs: [
|
87
|
+
{
|
88
|
+
description: "Spec 2"
|
89
|
+
passed: true
|
90
|
+
}
|
91
|
+
{
|
92
|
+
description: "Spec 3"
|
93
|
+
passed: true
|
94
|
+
}
|
95
|
+
]
|
96
|
+
suites: [
|
97
|
+
description: "Suite 2"
|
98
|
+
passed: false
|
99
|
+
specs: [
|
100
|
+
{
|
101
|
+
description: "Spec 4"
|
102
|
+
passed: false
|
103
|
+
}
|
104
|
+
]
|
105
|
+
suites: []
|
106
|
+
]
|
107
|
+
}
|
108
|
+
]
|
109
|
+
}
|
110
|
+
|
111
|
+
expect(@result).to.eql expected
|
112
|
+
|
113
|
+
describe 'when console is :always', ->
|
114
|
+
beforeEach ->
|
115
|
+
@result = new Result(@resultObj, @logObj, @errorsObj, { console: 'always', errors: 'never' }).process()
|
116
|
+
|
117
|
+
it 'does add all the log statements to the specs', ->
|
118
|
+
expected = {
|
119
|
+
passed: false
|
120
|
+
stats:
|
121
|
+
failures: 1
|
122
|
+
specs: 4
|
123
|
+
time: 0.10
|
124
|
+
specs: [
|
125
|
+
{
|
126
|
+
description: "Spec 1"
|
127
|
+
passed: true
|
128
|
+
logs: ['Log 1', 'Another Log']
|
129
|
+
}
|
130
|
+
]
|
131
|
+
suites: [
|
132
|
+
{
|
133
|
+
description: "Suite 1"
|
134
|
+
passed: true
|
135
|
+
specs: [
|
136
|
+
{
|
137
|
+
description: "Spec 2"
|
138
|
+
passed: true
|
139
|
+
logs: ['Log 2']
|
140
|
+
}
|
141
|
+
{
|
142
|
+
description: "Spec 3"
|
143
|
+
passed: true
|
144
|
+
}
|
145
|
+
]
|
146
|
+
suites: [
|
147
|
+
description: "Suite 2"
|
148
|
+
passed: false
|
149
|
+
specs: [
|
150
|
+
{
|
151
|
+
description: "Spec 4"
|
152
|
+
passed: false
|
153
|
+
logs: ['Log 4', 'more Logs']
|
154
|
+
}
|
155
|
+
]
|
156
|
+
suites: []
|
157
|
+
]
|
158
|
+
}
|
159
|
+
]
|
160
|
+
}
|
161
|
+
|
162
|
+
expect(@result).to.eql expected
|
163
|
+
|
164
|
+
describe 'when console is :failure', ->
|
165
|
+
beforeEach ->
|
166
|
+
@result = new Result(@resultObj, @logObj, @errorsObj, { console: 'failure', errors: 'never' }).process()
|
167
|
+
|
168
|
+
it 'does add the log statements to the failing specs', ->
|
169
|
+
expected = {
|
170
|
+
passed: false
|
171
|
+
stats:
|
172
|
+
failures: 1
|
173
|
+
specs: 4
|
174
|
+
time: 0.10
|
175
|
+
specs: [
|
176
|
+
{
|
177
|
+
description: "Spec 1"
|
178
|
+
passed: true
|
179
|
+
}
|
180
|
+
]
|
181
|
+
suites: [
|
182
|
+
{
|
183
|
+
description: "Suite 1"
|
184
|
+
passed: true
|
185
|
+
specs: [
|
186
|
+
{
|
187
|
+
description: "Spec 2"
|
188
|
+
passed: true
|
189
|
+
}
|
190
|
+
{
|
191
|
+
description: "Spec 3"
|
192
|
+
passed: true
|
193
|
+
}
|
194
|
+
]
|
195
|
+
suites: [
|
196
|
+
description: "Suite 2"
|
197
|
+
passed: false
|
198
|
+
specs: [
|
199
|
+
{
|
200
|
+
description: "Spec 4"
|
201
|
+
passed: false
|
202
|
+
logs: ['Log 4', 'more Logs']
|
203
|
+
}
|
204
|
+
]
|
205
|
+
suites: []
|
206
|
+
]
|
207
|
+
}
|
208
|
+
]
|
209
|
+
}
|
210
|
+
|
211
|
+
expect(@result).to.eql expected
|
212
|
+
|
213
|
+
describe 'when errors is :always', ->
|
214
|
+
beforeEach ->
|
215
|
+
@result = new Result(@resultObj, @logObj, @errorsObj, { console: 'never', errors: 'always' }).process()
|
216
|
+
|
217
|
+
it 'does add all the log statements to the specs', ->
|
218
|
+
expected = {
|
219
|
+
passed: false
|
220
|
+
stats:
|
221
|
+
failures: 1
|
222
|
+
specs: 4
|
223
|
+
time: 0.10
|
224
|
+
specs: [
|
225
|
+
{
|
226
|
+
description: "Spec 1"
|
227
|
+
passed: true
|
228
|
+
}
|
229
|
+
]
|
230
|
+
suites: [
|
231
|
+
{
|
232
|
+
description: "Suite 1"
|
233
|
+
passed: true
|
234
|
+
specs: [
|
235
|
+
{
|
236
|
+
description: "Spec 2"
|
237
|
+
passed: true
|
238
|
+
errors: [{ msg: 'Failure 1', trace: { file: 'a file' }}]
|
239
|
+
}
|
240
|
+
{
|
241
|
+
description: "Spec 3"
|
242
|
+
passed: true
|
243
|
+
errors: [{ msg: 'Failure 2', trace: { file: 'another file' }}]
|
244
|
+
}
|
245
|
+
]
|
246
|
+
suites: [
|
247
|
+
description: "Suite 2"
|
248
|
+
passed: false
|
249
|
+
specs: [
|
250
|
+
{
|
251
|
+
description: "Spec 4"
|
252
|
+
passed: false
|
253
|
+
errors: [{ msg: 'Failure 3', trace: { file: 'file' }}]
|
254
|
+
}
|
255
|
+
]
|
256
|
+
suites: []
|
257
|
+
]
|
258
|
+
}
|
259
|
+
]
|
260
|
+
}
|
261
|
+
|
262
|
+
expect(@result).to.eql expected
|
263
|
+
|
264
|
+
describe 'when errors is :failure', ->
|
265
|
+
beforeEach ->
|
266
|
+
@result = new Result(@resultObj, @logObj, @errorsObj, { console: 'never', errors: 'failure' }).process()
|
267
|
+
|
268
|
+
it 'does add the log statements to the failing specs', ->
|
269
|
+
expected = {
|
270
|
+
passed: false
|
271
|
+
stats:
|
272
|
+
failures: 1
|
273
|
+
specs: 4
|
274
|
+
time: 0.10
|
275
|
+
specs: [
|
276
|
+
{
|
277
|
+
description: "Spec 1"
|
278
|
+
passed: true
|
279
|
+
}
|
280
|
+
]
|
281
|
+
suites: [
|
282
|
+
{
|
283
|
+
description: "Suite 1"
|
284
|
+
passed: true
|
285
|
+
specs: [
|
286
|
+
{
|
287
|
+
description: "Spec 2"
|
288
|
+
passed: true
|
289
|
+
}
|
290
|
+
{
|
291
|
+
description: "Spec 3"
|
292
|
+
passed: true
|
293
|
+
}
|
294
|
+
]
|
295
|
+
suites: [
|
296
|
+
description: "Suite 2"
|
297
|
+
passed: false
|
298
|
+
specs: [
|
299
|
+
{
|
300
|
+
description: "Spec 4"
|
301
|
+
passed: false
|
302
|
+
errors: [{ msg: 'Failure 3', trace: { file: 'file' }}]
|
303
|
+
}
|
304
|
+
]
|
305
|
+
suites: []
|
306
|
+
]
|
307
|
+
}
|
308
|
+
]
|
309
|
+
}
|
310
|
+
|
311
|
+
expect(@result).to.eql expected
|
data/lib/guard/jasmine/runner.rb
CHANGED
@@ -87,7 +87,7 @@ module Guard
|
|
87
87
|
def run_jasmine_spec(file, options)
|
88
88
|
suite = jasmine_suite(file, options)
|
89
89
|
Formatter.info("Run Jasmine suite at #{ suite }")
|
90
|
-
IO.popen("#{ phantomjs_command(options) } \"#{ suite }\" #{ options[:timeout] }")
|
90
|
+
IO.popen("#{ phantomjs_command(options) } \"#{ suite }\" #{ options[:timeout] } #{ options[:specdoc] } #{ options[:focus] } #{ options[:console] } #{ options[:errors] }")
|
91
91
|
end
|
92
92
|
|
93
93
|
# Get the PhantomJS binary and script to execute.
|
@@ -205,24 +205,30 @@ module Guard
|
|
205
205
|
# @option options [Boolean] :hide_success hide success message notification
|
206
206
|
#
|
207
207
|
def notify_spec_result(result, options)
|
208
|
-
specs
|
209
|
-
failures
|
210
|
-
time
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
208
|
+
specs = result['stats']['specs']
|
209
|
+
failures = result['stats']['failures']
|
210
|
+
time = result['stats']['time']
|
211
|
+
specs_plural = specs == 1 ? '' : 's'
|
212
|
+
failures_plural = failures == 1 ? '' : 's'
|
213
|
+
|
214
|
+
Formatter.info("\nFinished in #{ time } seconds")
|
215
|
+
|
216
|
+
message = "#{ specs } spec#{ specs_plural }, #{ failures } failure#{ failures_plural }"
|
217
|
+
full_message = "#{ message }\nin #{ time } seconds"
|
218
|
+
passed = failures == 0
|
219
|
+
|
216
220
|
if passed
|
217
221
|
report_specdoc(result, passed, options) if options[:specdoc] == :always
|
218
222
|
Formatter.success(message)
|
219
|
-
Formatter.notify(
|
223
|
+
Formatter.notify(full_message, :title => 'Jasmine suite passed') if options[:notification] && !options[:hide_success]
|
220
224
|
else
|
221
225
|
report_specdoc(result, passed, options) if options[:specdoc] != :never
|
222
226
|
Formatter.error(message)
|
223
227
|
notify_errors(result, options)
|
224
|
-
Formatter.notify(
|
228
|
+
Formatter.notify(full_message, :title => 'Jasmine suite failed', :image => :failed, :priority => 2) if options[:notification]
|
225
229
|
end
|
230
|
+
|
231
|
+
Formatter.info("Done.\n")
|
226
232
|
end
|
227
233
|
|
228
234
|
# Specdoc like formatting of the result.
|
@@ -261,6 +267,7 @@ module Guard
|
|
261
267
|
spec['messages'].each do |message|
|
262
268
|
Formatter.spec_failed(indent(" ➤ #{ format_message(message, false) }", level))
|
263
269
|
end
|
270
|
+
report_specdoc_errors(spec, options, level)
|
264
271
|
report_specdoc_logs(spec, options, level)
|
265
272
|
end
|
266
273
|
end
|
@@ -285,6 +292,25 @@ module Guard
|
|
285
292
|
end
|
286
293
|
end
|
287
294
|
|
295
|
+
# Shows the errors for a given spec.
|
296
|
+
#
|
297
|
+
# @param [Hash] spec the spec result
|
298
|
+
# @param [Hash] options the options
|
299
|
+
# @option options [Symbol] :errors options for the errors output, either :always, :never or :failure
|
300
|
+
# @param [Number] level the indention level
|
301
|
+
#
|
302
|
+
def report_specdoc_errors(spec, options, level)
|
303
|
+
if spec['errors'] && (options[:errors] == :always || (options[:errors] == :failure && !spec['passed']))
|
304
|
+
spec['errors'].each do |error|
|
305
|
+
if error['trace']
|
306
|
+
Formatter.spec_failed(indent(" ➜ Exception: #{ error['msg'] } in #{ error['trace']['file'] } on line #{ error['trace']['line'] }", level))
|
307
|
+
else
|
308
|
+
Formatter.spec_failed(indent(" ➜ Exception: #{ error['msg'] }", level))
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
288
314
|
# Indent a message.
|
289
315
|
#
|
290
316
|
# @param [String] message the message
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: guard-jasmine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-03-
|
12
|
+
date: 2012-03-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: guard
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: 0.8.3
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.8.3
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: multi_json
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: childprocess
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: '0'
|
44
54
|
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: thor
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,10 +69,15 @@ dependencies:
|
|
54
69
|
version: '0'
|
55
70
|
type: :runtime
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: bundler
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ! '>='
|
@@ -65,10 +85,15 @@ dependencies:
|
|
65
85
|
version: '0'
|
66
86
|
type: :development
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
69
94
|
- !ruby/object:Gem::Dependency
|
70
95
|
name: guard-rspec
|
71
|
-
requirement:
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
72
97
|
none: false
|
73
98
|
requirements:
|
74
99
|
- - ! '>='
|
@@ -76,10 +101,15 @@ dependencies:
|
|
76
101
|
version: '0'
|
77
102
|
type: :development
|
78
103
|
prerelease: false
|
79
|
-
version_requirements:
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
80
110
|
- !ruby/object:Gem::Dependency
|
81
111
|
name: guard-coffeescript
|
82
|
-
requirement:
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
83
113
|
none: false
|
84
114
|
requirements:
|
85
115
|
- - ! '>='
|
@@ -87,10 +117,15 @@ dependencies:
|
|
87
117
|
version: '0'
|
88
118
|
type: :development
|
89
119
|
prerelease: false
|
90
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
91
126
|
- !ruby/object:Gem::Dependency
|
92
127
|
name: guard-shell
|
93
|
-
requirement:
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
94
129
|
none: false
|
95
130
|
requirements:
|
96
131
|
- - ! '>='
|
@@ -98,10 +133,15 @@ dependencies:
|
|
98
133
|
version: '0'
|
99
134
|
type: :development
|
100
135
|
prerelease: false
|
101
|
-
version_requirements:
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
102
142
|
- !ruby/object:Gem::Dependency
|
103
143
|
name: rspec
|
104
|
-
requirement:
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
105
145
|
none: false
|
106
146
|
requirements:
|
107
147
|
- - ! '>='
|
@@ -109,10 +149,15 @@ dependencies:
|
|
109
149
|
version: '0'
|
110
150
|
type: :development
|
111
151
|
prerelease: false
|
112
|
-
version_requirements:
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
113
158
|
- !ruby/object:Gem::Dependency
|
114
159
|
name: yard
|
115
|
-
requirement:
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
116
161
|
none: false
|
117
162
|
requirements:
|
118
163
|
- - ! '>='
|
@@ -120,10 +165,15 @@ dependencies:
|
|
120
165
|
version: '0'
|
121
166
|
type: :development
|
122
167
|
prerelease: false
|
123
|
-
version_requirements:
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
124
174
|
- !ruby/object:Gem::Dependency
|
125
175
|
name: redcarpet
|
126
|
-
requirement:
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
127
177
|
none: false
|
128
178
|
requirements:
|
129
179
|
- - ! '>='
|
@@ -131,10 +181,15 @@ dependencies:
|
|
131
181
|
version: '0'
|
132
182
|
type: :development
|
133
183
|
prerelease: false
|
134
|
-
version_requirements:
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
135
190
|
- !ruby/object:Gem::Dependency
|
136
191
|
name: pry
|
137
|
-
requirement:
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
138
193
|
none: false
|
139
194
|
requirements:
|
140
195
|
- - ! '>='
|
@@ -142,10 +197,15 @@ dependencies:
|
|
142
197
|
version: '0'
|
143
198
|
type: :development
|
144
199
|
prerelease: false
|
145
|
-
version_requirements:
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
146
206
|
- !ruby/object:Gem::Dependency
|
147
207
|
name: yajl-ruby
|
148
|
-
requirement:
|
208
|
+
requirement: !ruby/object:Gem::Requirement
|
149
209
|
none: false
|
150
210
|
requirements:
|
151
211
|
- - ! '>='
|
@@ -153,7 +213,12 @@ dependencies:
|
|
153
213
|
version: '0'
|
154
214
|
type: :development
|
155
215
|
prerelease: false
|
156
|
-
version_requirements:
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
217
|
+
none: false
|
218
|
+
requirements:
|
219
|
+
- - ! '>='
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: '0'
|
157
222
|
description: Guard::Jasmine automatically tests your Jasmine specs on PhantomJS
|
158
223
|
email:
|
159
224
|
- michi@netzpiraten.ch
|
@@ -171,10 +236,13 @@ files:
|
|
171
236
|
- lib/guard/jasmine/phantomjs/guard-jasmine.coffee
|
172
237
|
- lib/guard/jasmine/phantomjs/lib/console.js
|
173
238
|
- lib/guard/jasmine/phantomjs/lib/reporter.js
|
239
|
+
- lib/guard/jasmine/phantomjs/lib/result.js
|
174
240
|
- lib/guard/jasmine/phantomjs/src/console.coffee
|
175
241
|
- lib/guard/jasmine/phantomjs/src/reporter.coffee
|
242
|
+
- lib/guard/jasmine/phantomjs/src/result.coffee
|
176
243
|
- lib/guard/jasmine/phantomjs/test/console_spec.coffee
|
177
244
|
- lib/guard/jasmine/phantomjs/test/reporter_spec.coffee
|
245
|
+
- lib/guard/jasmine/phantomjs/test/result_spec.coffee
|
178
246
|
- lib/guard/jasmine/runner.rb
|
179
247
|
- lib/guard/jasmine/server.rb
|
180
248
|
- lib/guard/jasmine/task.rb
|
@@ -204,7 +272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
204
272
|
version: 1.3.6
|
205
273
|
requirements: []
|
206
274
|
rubyforge_project: guard-jasmine
|
207
|
-
rubygems_version: 1.8.
|
275
|
+
rubygems_version: 1.8.19
|
208
276
|
signing_key:
|
209
277
|
specification_version: 3
|
210
278
|
summary: Guard gem for headless testing with Jasmine
|