rspec-core 2.0.0.beta.12 → 2.0.0.beta.13
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/.gitignore +1 -0
- data/Gemfile +14 -0
- data/Rakefile +15 -12
- data/VERSION +1 -1
- data/features/command_line/example_name_option.feature +17 -3
- data/features/command_line/exit_status.feature +49 -0
- data/features/hooks/before_and_after_hooks.feature +51 -19
- data/features/hooks/halt.feature +1 -1
- data/features/support/env.rb +5 -3
- data/lib/rspec/core/command_line.rb +14 -5
- data/lib/rspec/core/configuration.rb +14 -24
- data/lib/rspec/core/configuration_options.rb +13 -8
- data/lib/rspec/core/drb_command_line.rb +2 -3
- data/lib/rspec/core/example.rb +5 -5
- data/lib/rspec/core/example_group.rb +23 -25
- data/lib/rspec/core/formatters/base_text_formatter.rb +13 -4
- data/lib/rspec/core/hooks.rb +57 -24
- data/lib/rspec/core/metadata.rb +1 -1
- data/lib/rspec/core/pending.rb +3 -3
- data/lib/rspec/core/rake_task.rb +48 -11
- data/lib/rspec/core/runner.rb +19 -8
- data/lib/rspec/core/subject.rb +3 -3
- data/lib/rspec/core/world.rb +3 -7
- data/rspec-core.gemspec +16 -12
- data/spec/rspec/core/command_line_spec.rb +72 -0
- data/spec/rspec/core/configuration_options_spec.rb +12 -3
- data/spec/rspec/core/configuration_spec.rb +6 -1
- data/spec/rspec/core/deprecations_spec.rb +19 -0
- data/spec/rspec/core/drb_command_line_spec.rb +1 -1
- data/spec/rspec/core/example_group_spec.rb +120 -12
- data/spec/rspec/core/example_spec.rb +27 -17
- data/spec/rspec/core/formatters/base_text_formatter_spec.rb +23 -0
- data/spec/rspec/core/metadata_spec.rb +32 -0
- data/spec/rspec/core/runner_spec.rb +2 -1
- data/spec/rspec/core/shared_example_group_spec.rb +1 -1
- data/spec/spec_helper.rb +49 -51
- data/specs.watchr +1 -1
- metadata +31 -27
data/lib/rspec/core/example.rb
CHANGED
@@ -2,7 +2,7 @@ module RSpec
|
|
2
2
|
module Core
|
3
3
|
class Example
|
4
4
|
|
5
|
-
attr_reader :metadata, :example_block
|
5
|
+
attr_reader :metadata, :example_block, :options
|
6
6
|
|
7
7
|
def self.delegate_to_metadata(*keys)
|
8
8
|
keys.each do |key|
|
@@ -33,7 +33,7 @@ module RSpec
|
|
33
33
|
def run(example_group_instance, reporter)
|
34
34
|
@in_block = false
|
35
35
|
@example_group_instance = example_group_instance
|
36
|
-
@example_group_instance.
|
36
|
+
@example_group_instance.example = self
|
37
37
|
|
38
38
|
run_started
|
39
39
|
|
@@ -43,10 +43,10 @@ module RSpec
|
|
43
43
|
run_before_each
|
44
44
|
pending_declared_in_example = catch(:pending_declared_in_example) do
|
45
45
|
@in_block = true
|
46
|
-
if @example_group_class.
|
46
|
+
if @example_group_class.hooks[:around][:each].empty?
|
47
47
|
@example_group_instance.instance_eval(&example_block) unless pending
|
48
48
|
else
|
49
|
-
@example_group_class.
|
49
|
+
@example_group_class.hooks[:around][:each].first.call(AroundProxy.new(self, &example_block))
|
50
50
|
end
|
51
51
|
throw :pending_declared_in_example, false
|
52
52
|
end
|
@@ -62,7 +62,7 @@ module RSpec
|
|
62
62
|
rescue Exception => e
|
63
63
|
exception ||= e
|
64
64
|
ensure
|
65
|
-
@example_group_instance.
|
65
|
+
@example_group_instance.example = nil
|
66
66
|
end
|
67
67
|
|
68
68
|
if exception
|
@@ -6,7 +6,12 @@ module RSpec
|
|
6
6
|
include Let
|
7
7
|
include Pending
|
8
8
|
|
9
|
-
attr_accessor :
|
9
|
+
attr_accessor :example
|
10
|
+
|
11
|
+
def running_example
|
12
|
+
RSpec.deprecate('running_example', 'example')
|
13
|
+
example
|
14
|
+
end
|
10
15
|
|
11
16
|
def self.world
|
12
17
|
RSpec.world
|
@@ -135,36 +140,30 @@ module RSpec
|
|
135
140
|
@before_all_ivars ||= {}
|
136
141
|
end
|
137
142
|
|
138
|
-
def self.eval_before_alls(
|
143
|
+
def self.eval_before_alls(example)
|
139
144
|
return if descendant_filtered_examples.empty?
|
140
|
-
superclass.before_all_ivars.each { |ivar, val|
|
141
|
-
world.
|
145
|
+
superclass.before_all_ivars.each { |ivar, val| example.instance_variable_set(ivar, val) }
|
146
|
+
world.run_hook_filtered(:before, :all, self, example)
|
142
147
|
|
143
|
-
|
144
|
-
|
145
|
-
end
|
146
|
-
running_example.instance_variables.each { |ivar| before_all_ivars[ivar] = running_example.instance_variable_get(ivar) }
|
148
|
+
run_hook!(:before, :all, example, :reverse => true)
|
149
|
+
example.instance_variables.each { |ivar| before_all_ivars[ivar] = example.instance_variable_get(ivar) }
|
147
150
|
end
|
148
151
|
|
149
|
-
def self.eval_before_eachs(
|
150
|
-
world.
|
151
|
-
ancestors.reverse.each { |ancestor| ancestor.
|
152
|
+
def self.eval_before_eachs(example)
|
153
|
+
world.run_hook_filtered(:before, :each, self, example)
|
154
|
+
ancestors.reverse.each { |ancestor| ancestor.run_hook(:before, :each, example) }
|
152
155
|
end
|
153
156
|
|
154
|
-
def self.eval_after_eachs(
|
155
|
-
ancestors.each { |ancestor| ancestor.
|
156
|
-
world.
|
157
|
+
def self.eval_after_eachs(example)
|
158
|
+
ancestors.each { |ancestor| ancestor.run_hook(:after, :each, example, :reverse => true) }
|
159
|
+
world.run_hook_filtered(:after, :each, self, example)
|
157
160
|
end
|
158
161
|
|
159
|
-
def self.eval_after_alls(
|
162
|
+
def self.eval_after_alls(example)
|
160
163
|
return if descendant_filtered_examples.empty?
|
161
|
-
before_all_ivars.each { |ivar, val|
|
162
|
-
ancestors.each
|
163
|
-
|
164
|
-
running_example.instance_eval &ancestor.after_alls.pop
|
165
|
-
end
|
166
|
-
end
|
167
|
-
world.run_hook(:after, :all, self, running_example)
|
164
|
+
before_all_ivars.each { |ivar, val| example.instance_variable_set(ivar, val) }
|
165
|
+
ancestors.each {|ancestor| ancestor.run_hook!(:after, :all, example) }
|
166
|
+
world.run_hook_filtered(:after, :all, self, example)
|
168
167
|
end
|
169
168
|
|
170
169
|
def self.run(reporter)
|
@@ -172,9 +171,8 @@ module RSpec
|
|
172
171
|
reporter.add_example_group(self)
|
173
172
|
begin
|
174
173
|
eval_before_alls(example_group_instance)
|
175
|
-
|
176
|
-
|
177
|
-
result_for_this_group && (children.empty? ? true : results_for_descendants)
|
174
|
+
run_examples(example_group_instance, reporter) &&
|
175
|
+
children.map {|child| child.run(reporter)}.all?
|
178
176
|
ensure
|
179
177
|
eval_after_alls(example_group_instance)
|
180
178
|
end
|
@@ -38,12 +38,10 @@ module RSpec
|
|
38
38
|
def dump_summary
|
39
39
|
failure_count = failed_examples.size
|
40
40
|
pending_count = pending_examples.size
|
41
|
-
|
42
41
|
|
43
|
-
|
42
|
+
output.puts "\nFinished in #{format_seconds(duration)} seconds\n"
|
44
43
|
|
45
|
-
summary =
|
46
|
-
summary << ", #{pending_count} pending" if pending_count > 0
|
44
|
+
summary = summary_line(example_count, failure_count, pending_count)
|
47
45
|
|
48
46
|
if failure_count == 0
|
49
47
|
if pending_count > 0
|
@@ -68,6 +66,17 @@ module RSpec
|
|
68
66
|
output.flush
|
69
67
|
end
|
70
68
|
|
69
|
+
def summary_line(example_count, failure_count, pending_count)
|
70
|
+
summary = pluralize(example_count, "example")
|
71
|
+
summary << ", " << pluralize(failure_count, "failure")
|
72
|
+
summary << ", #{pending_count} pending" if pending_count > 0
|
73
|
+
summary
|
74
|
+
end
|
75
|
+
|
76
|
+
def pluralize(count, string)
|
77
|
+
"#{count} #{string}#{'s' unless count == 1}"
|
78
|
+
end
|
79
|
+
|
71
80
|
def format_caller(caller_info)
|
72
81
|
caller_info.to_s.split(':in `block').first
|
73
82
|
end
|
data/lib/rspec/core/hooks.rb
CHANGED
@@ -1,49 +1,82 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Core
|
3
3
|
module Hooks
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
class Hook
|
5
|
+
attr_reader :options
|
6
|
+
|
7
|
+
def initialize(options, block)
|
8
|
+
@options = options
|
9
|
+
@block = block
|
10
|
+
end
|
11
|
+
|
12
|
+
def options_apply?(group)
|
13
|
+
!group || group.all_apply?(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
@block.call
|
18
|
+
end
|
7
19
|
|
8
|
-
|
9
|
-
|
20
|
+
def to_proc
|
21
|
+
@block
|
22
|
+
end
|
10
23
|
end
|
11
24
|
|
12
|
-
def
|
13
|
-
@
|
25
|
+
def hooks
|
26
|
+
@hooks ||= {
|
27
|
+
:around => { :each => [] },
|
28
|
+
:before => { :each => [], :all => [], :suite => [] },
|
29
|
+
:after => { :each => [], :all => [], :suite => [] }
|
30
|
+
}
|
14
31
|
end
|
15
32
|
|
16
|
-
def
|
17
|
-
|
33
|
+
def before(scope=:each, options={}, &block)
|
34
|
+
hooks[:before][scope] << Hook.new(options, block)
|
18
35
|
end
|
19
36
|
|
20
|
-
def
|
21
|
-
|
37
|
+
def after(scope=:each, options={}, &block)
|
38
|
+
hooks[:after][scope] << Hook.new(options, block)
|
22
39
|
end
|
23
40
|
|
24
|
-
def
|
25
|
-
|
41
|
+
def around(scope=:each, &block)
|
42
|
+
RSpec::deprecate("around", "before and after")
|
43
|
+
hooks[:around][scope] << block
|
26
44
|
end
|
27
45
|
|
28
|
-
|
29
|
-
|
46
|
+
# Runs all of the blocks stored with the hook in the context of the
|
47
|
+
# example. If no example is provided, just calls the hook directly.
|
48
|
+
def run_hook(hook, scope, example=nil, options={})
|
49
|
+
if options[:reverse]
|
50
|
+
hooks[hook][scope].reverse.each &run_hook_in(example)
|
51
|
+
else
|
52
|
+
hooks[hook][scope].each &run_hook_in(example)
|
53
|
+
end
|
30
54
|
end
|
31
55
|
|
32
|
-
|
33
|
-
|
56
|
+
# Just like run_hook, except it removes the blocks as it evalutes them,
|
57
|
+
# ensuring that they will only be run once.
|
58
|
+
def run_hook!(hook, scope, example, options={})
|
59
|
+
until hooks[hook][scope].empty?
|
60
|
+
if options[:reverse]
|
61
|
+
example.instance_eval &hooks[hook][scope].shift
|
62
|
+
else
|
63
|
+
example.instance_eval &hooks[hook][scope].pop
|
64
|
+
end
|
65
|
+
end
|
34
66
|
end
|
35
67
|
|
36
|
-
def
|
37
|
-
|
68
|
+
def run_hook_filtered(hook, scope, group, example)
|
69
|
+
find_hook(hook, scope, group).each &run_hook_in(example)
|
38
70
|
end
|
39
71
|
|
40
|
-
def
|
41
|
-
|
72
|
+
def find_hook(hook, scope, group)
|
73
|
+
hooks[hook][scope].select {|hook| hook.options_apply?(group)}
|
42
74
|
end
|
43
75
|
|
44
|
-
|
45
|
-
|
46
|
-
|
76
|
+
private
|
77
|
+
|
78
|
+
def run_hook_in(example)
|
79
|
+
lambda {|hook| example ? example.instance_eval(&hook) : hook.call}
|
47
80
|
end
|
48
81
|
end
|
49
82
|
end
|
data/lib/rspec/core/metadata.rb
CHANGED
data/lib/rspec/core/pending.rb
CHANGED
@@ -2,12 +2,12 @@ module RSpec
|
|
2
2
|
module Core
|
3
3
|
module Pending
|
4
4
|
def pending(message = 'No reason given')
|
5
|
-
|
6
|
-
|
5
|
+
example.metadata[:pending] = true
|
6
|
+
example.metadata[:execution_result][:pending_message] = message
|
7
7
|
if block_given?
|
8
8
|
begin
|
9
9
|
result = yield
|
10
|
-
|
10
|
+
example.metadata[:pending] = false
|
11
11
|
rescue Exception => e
|
12
12
|
end
|
13
13
|
raise RSpec::Core::PendingExampleFixedError.new if result
|
data/lib/rspec/core/rake_task.rb
CHANGED
@@ -35,16 +35,20 @@ module RSpec
|
|
35
35
|
# Use rcov for code coverage? defaults to false
|
36
36
|
attr_accessor :rcov
|
37
37
|
|
38
|
+
# Path to rcov. You can set this to 'bundle exec rcov' if you bundle rcov.
|
39
|
+
attr_accessor :rcov_path
|
40
|
+
|
38
41
|
# The options to pass to rcov. Defaults to blank
|
39
42
|
attr_accessor :rcov_opts
|
40
43
|
|
41
44
|
def initialize(*args)
|
42
45
|
@name = args.shift || :spec
|
43
|
-
@pattern, @rcov_opts, @ruby_opts = nil, nil, nil
|
46
|
+
@pattern, @rcov_path, @rcov_opts, @ruby_opts = nil, nil, nil, nil
|
44
47
|
@warning, @rcov = false, false
|
45
48
|
@fail_on_error = true
|
46
49
|
|
47
50
|
yield self if block_given?
|
51
|
+
@rcov_path ||= 'rcov'
|
48
52
|
@pattern ||= './spec/**/*_spec.rb'
|
49
53
|
define
|
50
54
|
end
|
@@ -58,18 +62,30 @@ module RSpec
|
|
58
62
|
if files_to_run.empty?
|
59
63
|
puts "No examples matching #{pattern} could be found"
|
60
64
|
else
|
61
|
-
cmd_parts = [
|
62
|
-
cmd_parts += rcov ? [rcov_opts] : [ruby_opts]
|
63
|
-
cmd_parts << '-Ilib'
|
64
|
-
cmd_parts << '-Ispec'
|
65
|
+
cmd_parts = [ '-Ilib', '-Ispec' ]
|
65
66
|
cmd_parts << "-w" if warning
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
67
|
+
|
68
|
+
if rcov
|
69
|
+
command_to_run = rcov_command(cmd_parts)
|
70
|
+
command_to_run.inspect if verbose
|
71
|
+
|
72
|
+
unless system(command_to_run)
|
73
|
+
STDERR.puts failure_message if failure_message
|
74
|
+
raise("#{command_to_run} failed") if fail_on_error
|
75
|
+
end
|
76
|
+
else
|
77
|
+
cmd_parts.concat(files_to_run)
|
78
|
+
puts cmd.inspect if verbose
|
79
|
+
|
80
|
+
require 'rspec/core'
|
81
|
+
RSpec::Core::Runner.disable_at_exit_hook!
|
82
|
+
|
83
|
+
unless RSpec::Core::Runner.run(cmd_parts, $stderr, $stdout)
|
84
|
+
STDERR.puts failure_message if failure_message
|
85
|
+
raise("RSpec::Core::Runner.run with args #{cmd_parts.inspect} failed") if fail_on_error
|
86
|
+
end
|
72
87
|
end
|
88
|
+
|
73
89
|
end
|
74
90
|
end
|
75
91
|
end
|
@@ -81,6 +97,27 @@ module RSpec
|
|
81
97
|
FileList[ pattern ].to_a
|
82
98
|
end
|
83
99
|
|
100
|
+
private
|
101
|
+
|
102
|
+
def rcov_command(cmd_parts)
|
103
|
+
cmd_parts.unshift runner_options
|
104
|
+
cmd_parts.unshift runner
|
105
|
+
cmd_parts.unshift bundler
|
106
|
+
cmd_parts += files_to_run.map { |fn| %["#{fn}"] }
|
107
|
+
cmd_parts.join(" ")
|
108
|
+
end
|
109
|
+
|
110
|
+
def runner
|
111
|
+
rcov ? rcov_path : RUBY
|
112
|
+
end
|
113
|
+
|
114
|
+
def runner_options
|
115
|
+
rcov ? [rcov_opts] : [ruby_opts]
|
116
|
+
end
|
117
|
+
|
118
|
+
def bundler
|
119
|
+
File.exist?("./Gemfile") ? "bundle exec " : ""
|
120
|
+
end
|
84
121
|
end
|
85
122
|
|
86
123
|
end
|
data/lib/rspec/core/runner.rb
CHANGED
@@ -4,12 +4,20 @@ module RSpec
|
|
4
4
|
module Core
|
5
5
|
class Runner
|
6
6
|
|
7
|
+
def self.at_exit_hook_disabled?
|
8
|
+
@no_at_exit_hook ||= false
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.disable_at_exit_hook!
|
12
|
+
@no_at_exit_hook = true
|
13
|
+
end
|
14
|
+
|
7
15
|
def self.installed_at_exit?
|
8
16
|
@installed_at_exit ||= false
|
9
17
|
end
|
10
18
|
|
11
19
|
def self.autorun
|
12
|
-
return if installed_at_exit? || running_in_drb?
|
20
|
+
return if at_exit_hook_disabled? || installed_at_exit? || running_in_drb?
|
13
21
|
@installed_at_exit = true
|
14
22
|
at_exit { run(ARGV, $stderr, $stdout) ? exit(0) : exit(1) }
|
15
23
|
end
|
@@ -20,19 +28,22 @@ module RSpec
|
|
20
28
|
end
|
21
29
|
|
22
30
|
def self.run(args, err, out)
|
23
|
-
|
24
|
-
|
31
|
+
options = ConfigurationOptions.new(args)
|
32
|
+
options.parse_options
|
33
|
+
|
34
|
+
if options.options[:drb]
|
35
|
+
run_over_drb(options, err, out) || run_in_process(options, err, out)
|
25
36
|
else
|
26
|
-
run_in_process(
|
37
|
+
run_in_process(options, err, out)
|
27
38
|
end
|
28
39
|
end
|
29
40
|
|
30
|
-
def self.run_over_drb(
|
31
|
-
DRbCommandLine.new(
|
41
|
+
def self.run_over_drb(options, err, out)
|
42
|
+
DRbCommandLine.new(options).run(err, out)
|
32
43
|
end
|
33
44
|
|
34
|
-
def self.run_in_process(
|
35
|
-
CommandLine.new(
|
45
|
+
def self.run_in_process(options, err, out)
|
46
|
+
CommandLine.new(options).run(err, out)
|
36
47
|
end
|
37
48
|
|
38
49
|
end
|
data/lib/rspec/core/subject.rb
CHANGED
@@ -80,12 +80,12 @@ module RSpec
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def attribute_of_subject
|
83
|
-
original_subject.send(
|
83
|
+
original_subject.send(example.description) if using_attribute?
|
84
84
|
end
|
85
85
|
|
86
86
|
def using_attribute?
|
87
|
-
|
88
|
-
|
87
|
+
example.in_block? &&
|
88
|
+
example.metadata[:attribute_of_subject]
|
89
89
|
end
|
90
90
|
|
91
91
|
end
|
data/lib/rspec/core/world.rb
CHANGED
@@ -67,15 +67,11 @@ module RSpec
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
70
|
-
|
71
|
-
|
72
|
-
find_hook(hook, scope, group).each { |blk| example.instance_eval(&blk) }
|
73
|
-
end
|
70
|
+
|
71
|
+
include RSpec::Core::Hooks
|
74
72
|
|
75
73
|
def find_hook(hook, scope, group)
|
76
|
-
RSpec.configuration.
|
77
|
-
group.all_apply?(filters)
|
78
|
-
end.map { |filters, block| block }
|
74
|
+
RSpec.configuration.find_hook(hook, scope, group)
|
79
75
|
end
|
80
76
|
|
81
77
|
private
|