guard-jasmine 1.0.4 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|