guard-rspectacle 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +27 -12
- data/lib/guard/rspectacle.rb +10 -21
- data/lib/guard/rspectacle/notifier.rb +8 -10
- data/lib/guard/rspectacle/runner.rb +29 -28
- data/lib/guard/rspectacle/version.rb +1 -1
- metadata +14 -14
data/README.md
CHANGED
@@ -7,9 +7,12 @@ Tested on MRI Ruby 1.8.7, 1.9.2, 1.9.3, REE and the latest versions of JRuby & R
|
|
7
7
|
If you have any questions please join us on our [Google group](http://groups.google.com/group/guard-dev) or on `#guard`
|
8
8
|
(irc.freenode.net).
|
9
9
|
|
10
|
-
##
|
10
|
+
## How it works
|
11
11
|
|
12
|
-
|
12
|
+
The idea is that Guard starts the Rails environment, reloads changed Ruby files and starts the RSpec runner embedded in
|
13
|
+
the current process. **Please be sure to [understand the limitation](#reloading) of this approach.**
|
14
|
+
|
15
|
+
If you want to use a safer approach to run your specs, try [guard-rspec](https://github.com/guard/guard-rspec).
|
13
16
|
|
14
17
|
## Install
|
15
18
|
|
@@ -17,13 +20,25 @@ If you have any questions please join us on our [Google group](http://groups.goo
|
|
17
20
|
|
18
21
|
Please be sure to have [Guard](https://github.com/guard/guard) installed.
|
19
22
|
|
20
|
-
Add it to your `Gemfile
|
23
|
+
Add it to your `Gemfile`:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
group :development
|
27
|
+
gem 'guard-rspectacle'
|
28
|
+
end
|
29
|
+
```
|
21
30
|
|
22
|
-
|
31
|
+
and install it by running Bundler:
|
23
32
|
|
24
|
-
|
33
|
+
```bash
|
34
|
+
$ bundle
|
35
|
+
```
|
25
36
|
|
26
|
-
|
37
|
+
Add the guard definition to your `Guardfile` by running this command:
|
38
|
+
|
39
|
+
```bash
|
40
|
+
$ guard init rspectacle
|
41
|
+
```
|
27
42
|
|
28
43
|
## Usage
|
29
44
|
|
@@ -57,7 +72,7 @@ end
|
|
57
72
|
|
58
73
|
## Options
|
59
74
|
|
60
|
-
There are many options that can customize Guard::
|
75
|
+
There are many options that can customize Guard::RSpectacle to your needs. Options are simply supplied as hash when
|
61
76
|
defining the Guard in your `Guardfile`:
|
62
77
|
|
63
78
|
```ruby
|
@@ -68,13 +83,15 @@ end
|
|
68
83
|
|
69
84
|
### General options
|
70
85
|
|
71
|
-
The general options configures the environment that is needed to run Guard::
|
86
|
+
The general options configures the environment that is needed to run Guard::RSpectacle and RSpec:
|
72
87
|
|
73
88
|
```ruby
|
74
89
|
:cli => '--tag @focus' # RSpec CLI options
|
75
90
|
# default: ''
|
76
91
|
```
|
77
92
|
|
93
|
+
Spork is not needed (and supported), thus the `--drb` flag will be removed from the `:cli` options.
|
94
|
+
|
78
95
|
### Spec runner options
|
79
96
|
|
80
97
|
The spec runner options configures the behavior driven development (or BDD) cycle:
|
@@ -86,9 +103,6 @@ The spec runner options configures the behavior driven development (or BDD) cycl
|
|
86
103
|
:keep_failed => false # Keep failed examples and add them to the next run again.
|
87
104
|
# default: true
|
88
105
|
|
89
|
-
:keep_pending => false # Keep pending examples and add them to the next run again.
|
90
|
-
# default: true
|
91
|
-
|
92
106
|
:all_after_pass => false # Run all specs after all examples have passed again after failing.
|
93
107
|
# default: true
|
94
108
|
```
|
@@ -105,6 +119,7 @@ These options affects what system notifications (growl, libnotify or notifu) are
|
|
105
119
|
# default: false
|
106
120
|
```
|
107
121
|
|
122
|
+
<a name="reloading"/>
|
108
123
|
## Important note on reloading
|
109
124
|
|
110
125
|
The ability to run specs immediately comes at a cost:
|
@@ -141,7 +156,7 @@ easily (suggest if you know how?). So just keep in mind: **you are monkey-patchi
|
|
141
156
|
|
142
157
|
## Alternatives
|
143
158
|
|
144
|
-
Please have a look at the rock solid [guard-rspec](https://github.com/guard/guard-rspec). Guard::
|
159
|
+
Please have a look at the rock solid [guard-rspec](https://github.com/guard/guard-rspec). Guard::RSpectacle uses it
|
145
160
|
for continuous testing.
|
146
161
|
|
147
162
|
## Issues
|
data/lib/guard/rspectacle.rb
CHANGED
@@ -16,7 +16,7 @@ module Guard
|
|
16
16
|
autoload :Reloader, 'guard/rspectacle/reloader'
|
17
17
|
autoload :Notifier, 'guard/rspectacle/notifier'
|
18
18
|
|
19
|
-
attr_accessor :last_run_passed, :
|
19
|
+
attr_accessor :last_run_passed, :rerun_specs
|
20
20
|
|
21
21
|
DEFAULT_OPTIONS = {
|
22
22
|
:cli => '',
|
@@ -24,7 +24,6 @@ module Guard
|
|
24
24
|
:hide_success => false,
|
25
25
|
:all_on_start => true,
|
26
26
|
:keep_failed => true,
|
27
|
-
:keep_pending => true,
|
28
27
|
:all_after_pass => true,
|
29
28
|
}
|
30
29
|
|
@@ -37,7 +36,6 @@ module Guard
|
|
37
36
|
# @option options [Boolean] :hide_success hide success message notification
|
38
37
|
# @option options [Boolean] :all_on_start Run all specs on start
|
39
38
|
# @option options [Boolean] :keep_failed keep failed examples and add them to the next run again
|
40
|
-
# @option options [Boolean] :keep_pending keep pending examples and add them to the next run again
|
41
39
|
# @option options [Boolean] :all_after_pass run all specs after all examples have passed again after failing
|
42
40
|
#
|
43
41
|
def initialize(watchers = [], options = {})
|
@@ -46,7 +44,7 @@ module Guard
|
|
46
44
|
super(watchers, options)
|
47
45
|
|
48
46
|
self.last_run_passed = true
|
49
|
-
self.
|
47
|
+
self.rerun_specs = []
|
50
48
|
end
|
51
49
|
|
52
50
|
# Gets called once when Guard starts.
|
@@ -69,7 +67,7 @@ module Guard
|
|
69
67
|
Dir.glob('**/*.rb').each { |file| Reloader.reload_file(file) }
|
70
68
|
|
71
69
|
self.last_run_passed = true
|
72
|
-
self.
|
70
|
+
self.rerun_specs = []
|
73
71
|
end
|
74
72
|
|
75
73
|
# Gets called when all specs should be run.
|
@@ -77,14 +75,9 @@ module Guard
|
|
77
75
|
# @raise [:task_has_failed] when run_on_change has failed
|
78
76
|
#
|
79
77
|
def run_all
|
80
|
-
passed, failed_examples, passed_examples
|
81
|
-
|
82
|
-
if options[:keep_pending]
|
83
|
-
self.rerun_examples = failed_examples + pending_examples
|
84
|
-
else
|
85
|
-
self.rerun_examples = failed_examples
|
86
|
-
end
|
78
|
+
passed, failed_examples, passed_examples = Runner.run(['spec'], options.merge({ :message => 'Run all specs'}))
|
87
79
|
|
80
|
+
self.rerun_specs = failed_examples
|
88
81
|
self.last_run_passed = passed
|
89
82
|
|
90
83
|
throw :task_has_failed unless passed
|
@@ -99,22 +92,18 @@ module Guard
|
|
99
92
|
specs = Inspector.clean(paths)
|
100
93
|
return false if specs.empty?
|
101
94
|
|
102
|
-
specs += self.
|
95
|
+
specs += self.rerun_specs if options[:keep_failed]
|
103
96
|
|
104
97
|
# RSpec reloads the files, so reload only non spec files
|
105
98
|
(paths - specs).each { |path| Reloader.reload_file(path) }
|
106
99
|
|
107
|
-
passed, failed_examples, passed_examples
|
108
|
-
|
109
|
-
if options[:keep_pending]
|
110
|
-
self.rerun_examples += failed_examples + pending_examples
|
111
|
-
else
|
112
|
-
self.rerun_examples += failed_examples
|
113
|
-
end
|
100
|
+
passed, failed_examples, passed_examples = Runner.run(specs, options)
|
114
101
|
|
115
|
-
self.
|
102
|
+
self.rerun_specs += failed_examples
|
103
|
+
self.rerun_specs -= passed_examples
|
116
104
|
|
117
105
|
run_all if passed && !self.last_run_passed && options[:all_after_pass]
|
106
|
+
|
118
107
|
self.last_run_passed = passed
|
119
108
|
|
120
109
|
throw :task_has_failed unless passed
|
@@ -13,9 +13,8 @@ module Guard
|
|
13
13
|
attr_accessor :example_count
|
14
14
|
attr_accessor :failure_count
|
15
15
|
attr_accessor :pending_count
|
16
|
-
attr_accessor :
|
17
|
-
attr_accessor :
|
18
|
-
attr_accessor :passed_examples
|
16
|
+
attr_accessor :failed_specs
|
17
|
+
attr_accessor :passed_specs
|
19
18
|
end
|
20
19
|
|
21
20
|
def initialize(output)
|
@@ -28,13 +27,12 @@ module Guard
|
|
28
27
|
end
|
29
28
|
|
30
29
|
def dump_summary(duration, example_count, failure_count, pending_count)
|
31
|
-
::Guard::RSpectacle::Notifier.duration
|
32
|
-
::Guard::RSpectacle::Notifier.example_count
|
33
|
-
::Guard::RSpectacle::Notifier.failure_count
|
34
|
-
::Guard::RSpectacle::Notifier.pending_count
|
35
|
-
::Guard::RSpectacle::Notifier.
|
36
|
-
::Guard::RSpectacle::Notifier.
|
37
|
-
::Guard::RSpectacle::Notifier.passed_examples = @passed_examples.map { |example| example.location }
|
30
|
+
::Guard::RSpectacle::Notifier.duration = duration
|
31
|
+
::Guard::RSpectacle::Notifier.example_count = example_count
|
32
|
+
::Guard::RSpectacle::Notifier.failure_count = failure_count
|
33
|
+
::Guard::RSpectacle::Notifier.pending_count = pending_count
|
34
|
+
::Guard::RSpectacle::Notifier.failed_specs = @failed_examples.map { |example| example.file_path }.uniq
|
35
|
+
::Guard::RSpectacle::Notifier.passed_specs = @passed_examples.map { |example| example.file_path }.uniq
|
38
36
|
end
|
39
37
|
|
40
38
|
end
|
@@ -17,65 +17,66 @@ module Guard
|
|
17
17
|
# - https://github.com/rspec/rspec-core/blob/master/lib/rspec/core/runner.rb
|
18
18
|
# - https://github.com/rspec/rspec-core/blob/master/spec/rspec/core/configuration_options_spec.rb
|
19
19
|
#
|
20
|
-
# @param [Array<String>]
|
20
|
+
# @param [Array<String>] examples the specs to run
|
21
21
|
# @param [Hash] options the options
|
22
22
|
# @option options [String] :cli the RSpec CLI options
|
23
23
|
# @option options [Boolean] :notification show notifications
|
24
24
|
# @option options [Boolean] :hide_success hide success message notification
|
25
25
|
# @param [IO] err the error stream
|
26
26
|
# @param [IO] out the output stream
|
27
|
-
# @return [Array] the spec result: status,
|
27
|
+
# @return [Array] the spec result: status, failed_specs, passed_specs
|
28
28
|
#
|
29
|
-
def run(
|
29
|
+
def run(examples, options, err=$stderr, out=$stdout)
|
30
|
+
message = options[:message] || "Run #{ examples.join(' ') }"
|
31
|
+
::Guard::UI.info(message, :reset => true)
|
32
|
+
|
30
33
|
rspec_options = options[:cli].to_s.split
|
31
34
|
rspec_options.delete('--drb')
|
32
|
-
rspec_options
|
35
|
+
rspec_options.delete('-X')
|
36
|
+
rspec_options += rspectacular_options + examples
|
33
37
|
|
34
38
|
begin
|
35
|
-
|
39
|
+
status = ::RSpec::Core::Runner.run(rspec_options, err, out)
|
36
40
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
pending_count = ::Guard::RSpectacle::Notifier.pending_count || -1
|
41
|
+
passed = status == 0
|
42
|
+
failed_specs = ::Guard::RSpectacle::Notifier.failed_specs || []
|
43
|
+
passed_specs = ::Guard::RSpectacle::Notifier.passed_specs || []
|
44
|
+
duration = ::Guard::RSpectacle::Notifier.duration || 0.0
|
45
|
+
example_count = ::Guard::RSpectacle::Notifier.example_count || -1
|
46
|
+
failure_count = ::Guard::RSpectacle::Notifier.failure_count || -1
|
47
|
+
pending_count = ::Guard::RSpectacle::Notifier.pending_count || -1
|
45
48
|
|
46
|
-
|
49
|
+
if options[:notification]
|
47
50
|
|
48
|
-
|
51
|
+
message = " #{ example_count } example#{ example_count == 1 ? '' : 's' }"
|
49
52
|
message << ", #{ failure_count } failure#{ failure_count == 1 ? '' : 's' }"
|
50
53
|
message << " (#{ pending_count } pending)" if pending_count > 0
|
51
54
|
message << "\nin #{ round(duration) } seconds"
|
52
55
|
|
53
|
-
if failure_count
|
54
|
-
::Guard::RSpectacle::Formatter.notify(::Guard::RSpectacle::Humanity.
|
56
|
+
if failure_count > 0
|
57
|
+
::Guard::RSpectacle::Formatter.notify(::Guard::RSpectacle::Humanity.failure + message,
|
55
58
|
:title => 'RSpec results',
|
56
|
-
:image => :
|
57
|
-
:priority => 2)
|
58
|
-
|
59
|
-
elsif failure_count == 0 && pending_count > 0
|
59
|
+
:image => :failed,
|
60
|
+
:priority => -2)
|
61
|
+
elsif pending_count > 0
|
60
62
|
::Guard::RSpectacle::Formatter.notify(::Guard::RSpectacle::Humanity.pending + message,
|
61
63
|
:title => 'RSpec results',
|
62
64
|
:image => :pending,
|
63
65
|
:priority => -1)
|
64
|
-
|
65
66
|
else
|
66
|
-
::Guard::RSpectacle::Formatter.notify(::Guard::RSpectacle::Humanity.
|
67
|
+
::Guard::RSpectacle::Formatter.notify(::Guard::RSpectacle::Humanity.success + message,
|
67
68
|
:title => 'RSpec results',
|
68
|
-
:image => :
|
69
|
-
:priority =>
|
69
|
+
:image => :success,
|
70
|
+
:priority => 2) if !options[:hide_success]
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
73
|
-
[passed, relative(
|
74
|
+
[passed, relative(failed_specs), relative(passed_specs)]
|
74
75
|
|
75
76
|
rescue Exception => e
|
76
77
|
::Guard::RSpectacle::Formatter.error("Error running specs: #{ e.message }")
|
77
78
|
|
78
|
-
[false, [], []
|
79
|
+
[false, [], []]
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
@@ -84,7 +85,7 @@ module Guard
|
|
84
85
|
# Make all the paths relative to the current working
|
85
86
|
# directory (the project dir).
|
86
87
|
#
|
87
|
-
# @
|
88
|
+
# @param [Array<String>] the absolute paths
|
88
89
|
# @return [Array<String>] the relative paths
|
89
90
|
#
|
90
91
|
def relative(paths)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: guard-rspectacle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.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-01-
|
12
|
+
date: 2012-01-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: guard
|
16
|
-
requirement: &
|
16
|
+
requirement: &70275000328420 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0.8'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70275000328420
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &70275000327960 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 2.8.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70275000327960
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: bundler
|
38
|
-
requirement: &
|
38
|
+
requirement: &70275000327480 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '1.0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70275000327480
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: guard-rspec
|
49
|
-
requirement: &
|
49
|
+
requirement: &70275000327020 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0.6'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70275000327020
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: yard
|
60
|
-
requirement: &
|
60
|
+
requirement: &70275000326640 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70275000326640
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: kramdown
|
71
|
-
requirement: &
|
71
|
+
requirement: &70275000326160 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70275000326160
|
80
80
|
description: Guard::RSpectacle automatically tests your code with RSpec
|
81
81
|
email:
|
82
82
|
- michi@netzpiraten.ch
|