rspec-core 2.0.0.a2 → 2.0.0.a3
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +2 -2
- data/.gitignore +1 -0
- data/README.markdown +18 -4
- data/Rakefile +6 -17
- data/bin/rspec +0 -8
- data/example_specs/failing/README.txt +1 -1
- data/example_specs/failing/spec_helper.rb +7 -2
- data/example_specs/failing/team_spec.rb +0 -1
- data/features/before_and_after_blocks/around.feature +2 -0
- data/features/command_line/example_name_option.feature +54 -0
- data/features/command_line/line_number_appended_to_path.feature +39 -0
- data/features/command_line/line_number_option.feature +40 -0
- data/features/matchers/define_matcher.feature +18 -4
- data/features/matchers/define_matcher_outside_rspec.feature +1 -2
- data/features/mocks/mix_stubs_and_mocks.feature +2 -0
- data/features/subject/explicit_subject.feature +4 -0
- data/features/subject/implicit_subject.feature +4 -0
- data/features/support/env.rb +15 -1
- data/lib/rspec/core.rb +1 -1
- data/lib/rspec/core/command_line_options.rb +9 -0
- data/lib/rspec/core/configuration.rb +18 -8
- data/lib/rspec/core/example.rb +14 -23
- data/lib/rspec/core/example_group.rb +39 -30
- data/lib/rspec/core/formatters/base_formatter.rb +9 -7
- data/lib/rspec/core/formatters/base_text_formatter.rb +2 -2
- data/lib/rspec/core/formatters/documentation_formatter.rb +10 -12
- data/lib/rspec/core/kernel_extensions.rb +2 -2
- data/lib/rspec/core/load_path.rb +1 -2
- data/lib/rspec/core/metadata.rb +65 -27
- data/lib/rspec/core/ruby_project.rb +24 -10
- data/lib/rspec/core/runner.rb +3 -3
- data/lib/rspec/core/{shared_behaviour.rb → shared_example_group.rb} +5 -5
- data/lib/rspec/core/{shared_behaviour_kernel_extensions.rb → shared_example_group_kernel_extensions.rb} +3 -3
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/world.rb +29 -50
- data/rspec-core.gemspec +22 -21
- data/spec/rspec/core/command_line_options_spec.rb +14 -0
- data/spec/rspec/core/configuration_spec.rb +51 -13
- data/spec/rspec/core/example_group_spec.rb +61 -68
- data/spec/rspec/core/example_group_subject_spec.rb +1 -1
- data/spec/rspec/core/example_spec.rb +19 -8
- data/spec/rspec/core/formatters/base_formatter_spec.rb +2 -2
- data/spec/rspec/core/metadata_spec.rb +52 -17
- data/spec/rspec/core/mocha_spec.rb +4 -4
- data/spec/rspec/core/pending_example_spec.rb +19 -0
- data/spec/rspec/core/ruby_project_spec.rb +24 -0
- data/spec/rspec/core/{shared_behaviour_spec.rb → shared_example_group_spec.rb} +31 -31
- data/spec/rspec/core/world_spec.rb +64 -83
- data/spec/spec_helper.rb +19 -30
- metadata +17 -17
- data/features-pending/command_line/line_number_option.feature +0 -56
- data/features-pending/command_line/line_number_option_with_example_with_no_name.feature +0 -22
- data/lib/rspec/core/extensions/instance_exec.rb +0 -31
- data/spec/resources/example_classes.rb +0 -67
- data/spec/rspec/core/resources/example_classes.rb +0 -67
data/lib/rspec/core.rb
CHANGED
@@ -8,7 +8,7 @@ require 'rspec/core/runner'
|
|
8
8
|
require 'rspec/core/example'
|
9
9
|
require 'rspec/core/metadata'
|
10
10
|
require 'rspec/core/kernel_extensions'
|
11
|
-
require 'rspec/core/
|
11
|
+
require 'rspec/core/shared_example_group'
|
12
12
|
require 'rspec/core/example_group_subject'
|
13
13
|
require 'rspec/core/example_group'
|
14
14
|
require 'rspec/core/formatters'
|
@@ -29,6 +29,15 @@ module Rspec
|
|
29
29
|
options[:formatter] = o
|
30
30
|
end
|
31
31
|
|
32
|
+
opts.on('-l', '--line_number [LINE]', 'Specify the line number of a single example to run') do |o|
|
33
|
+
options[:line_number] = o
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on('-e', '--example [PATTERN]', "Run examples whose full descriptions match this pattern",
|
37
|
+
"(PATTERN is compiled into a Ruby regular expression)") do |o|
|
38
|
+
options[:full_description] = /#{o}/
|
39
|
+
end
|
40
|
+
|
32
41
|
opts.on('-p', '--profile', 'Enable profiling of examples with output of the top 10 slowest examples') do |o|
|
33
42
|
options[:profile_examples] = o
|
34
43
|
end
|
@@ -22,7 +22,7 @@ module Rspec
|
|
22
22
|
attr_reader :options
|
23
23
|
|
24
24
|
def initialize
|
25
|
-
@run_all_when_everything_filtered =
|
25
|
+
@run_all_when_everything_filtered = false
|
26
26
|
@advice = {
|
27
27
|
:before => { :each => [], :all => [], :suite => [] },
|
28
28
|
:after => { :each => [], :all => [], :suite => [] }
|
@@ -98,6 +98,14 @@ module Rspec
|
|
98
98
|
def color_enabled?
|
99
99
|
options[:color_enabled]
|
100
100
|
end
|
101
|
+
|
102
|
+
def line_number=(line_number)
|
103
|
+
filter_run :line_number => line_number.to_i
|
104
|
+
end
|
105
|
+
|
106
|
+
def full_description=(description)
|
107
|
+
filter_run :full_description => /#{description}/
|
108
|
+
end
|
101
109
|
|
102
110
|
# Enable profiling of example run - defaults to false
|
103
111
|
def profile_examples
|
@@ -139,7 +147,9 @@ module Rspec
|
|
139
147
|
result += Dir[File.expand_path("#{file}/#{pattern.strip}")]
|
140
148
|
end
|
141
149
|
else
|
142
|
-
|
150
|
+
path, line_number = file.split(':')
|
151
|
+
self.line_number = line_number if line_number
|
152
|
+
result << path
|
143
153
|
end
|
144
154
|
result
|
145
155
|
end
|
@@ -156,7 +166,7 @@ module Rspec
|
|
156
166
|
end
|
157
167
|
|
158
168
|
def filter_run(options={})
|
159
|
-
@filter = options
|
169
|
+
@filter = options unless @filter and @filter[:line_number] || @filter[:full_description]
|
160
170
|
end
|
161
171
|
|
162
172
|
def run_all_when_everything_filtered?
|
@@ -185,8 +195,8 @@ module Rspec
|
|
185
195
|
end
|
186
196
|
|
187
197
|
def find_modules(group)
|
188
|
-
include_or_extend_modules.select do |include_or_extend, mod,
|
189
|
-
|
198
|
+
include_or_extend_modules.select do |include_or_extend, mod, filters|
|
199
|
+
group.all_apply?(filters)
|
190
200
|
end
|
191
201
|
end
|
192
202
|
|
@@ -199,9 +209,9 @@ module Rspec
|
|
199
209
|
end
|
200
210
|
|
201
211
|
def find_advice(desired_advice_type, desired_each_or_all, group)
|
202
|
-
advice[desired_advice_type][desired_each_or_all].select do |
|
203
|
-
|
204
|
-
end.map { |
|
212
|
+
advice[desired_advice_type][desired_each_or_all].select do |filters, block|
|
213
|
+
group.all_apply?(filters)
|
214
|
+
end.map { |filters, block| block }
|
205
215
|
end
|
206
216
|
|
207
217
|
end
|
data/lib/rspec/core/example.rb
CHANGED
@@ -2,25 +2,18 @@ module Rspec
|
|
2
2
|
module Core
|
3
3
|
class Example
|
4
4
|
|
5
|
-
attr_reader :
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
@
|
10
|
-
@metadata
|
11
|
-
@metadata[:execution_result] = {}
|
12
|
-
@metadata[:caller] = options.delete(:caller)
|
13
|
-
if @metadata[:caller]
|
14
|
-
@metadata[:file_path] = @metadata[:caller].split(":")[0].strip
|
15
|
-
@metadata[:line_number] = @metadata[:caller].split(":")[1].to_i
|
16
|
-
end
|
17
|
-
@metadata.update(options)
|
5
|
+
attr_reader :example_group, :metadata, :example_block
|
6
|
+
alias_method :behaviour, :example_group
|
7
|
+
|
8
|
+
def initialize(example_group, desc, options, example_block=nil)
|
9
|
+
@example_group, @options, @example_block = example_group, options, example_block
|
10
|
+
@metadata = @example_group.metadata.for_example(desc, options)
|
18
11
|
end
|
19
12
|
|
20
13
|
def description
|
21
14
|
@metadata[:description]
|
22
15
|
end
|
23
|
-
|
16
|
+
|
24
17
|
def record_results(results={})
|
25
18
|
@metadata[:execution_result].update(results)
|
26
19
|
end
|
@@ -30,7 +23,7 @@ module Rspec
|
|
30
23
|
end
|
31
24
|
|
32
25
|
def file_path
|
33
|
-
@metadata[:file_path] ||
|
26
|
+
@metadata[:file_path] || example_group.file_path
|
34
27
|
end
|
35
28
|
|
36
29
|
def run_started
|
@@ -58,11 +51,11 @@ module Rspec
|
|
58
51
|
|
59
52
|
def run_before_each
|
60
53
|
@example_group_instance._setup_mocks if @example_group_instance.respond_to?(:_setup_mocks)
|
61
|
-
@
|
54
|
+
@example_group.eval_before_eachs(@example_group_instance)
|
62
55
|
end
|
63
56
|
|
64
57
|
def run_after_each
|
65
|
-
@
|
58
|
+
@example_group.eval_after_eachs(@example_group_instance)
|
66
59
|
@example_group_instance._verify_mocks if @example_group_instance.respond_to?(:_verify_mocks)
|
67
60
|
ensure
|
68
61
|
@example_group_instance._teardown_mocks if @example_group_instance.respond_to?(:_teardown_mocks)
|
@@ -86,9 +79,7 @@ module Rspec
|
|
86
79
|
end
|
87
80
|
|
88
81
|
def runnable?
|
89
|
-
![
|
90
|
-
metadata[:disabled] == true,
|
91
|
-
metadata[:pending] == true ].any?
|
82
|
+
!metadata[:pending]
|
92
83
|
end
|
93
84
|
|
94
85
|
def run(example_group_instance)
|
@@ -102,10 +93,10 @@ module Rspec
|
|
102
93
|
|
103
94
|
begin
|
104
95
|
run_before_each
|
105
|
-
if @
|
96
|
+
if @example_group.around_eachs.empty?
|
106
97
|
@example_group_instance.instance_eval(&example_block) if runnable?
|
107
98
|
else
|
108
|
-
@
|
99
|
+
@example_group.around_eachs.first.call(AroundProxy.new(self, &example_block))
|
109
100
|
end
|
110
101
|
rescue Exception => e
|
111
102
|
exception_encountered = e
|
@@ -133,7 +124,7 @@ module Rspec
|
|
133
124
|
end
|
134
125
|
|
135
126
|
def inspect
|
136
|
-
|
127
|
+
@metadata[:full_description]
|
137
128
|
end
|
138
129
|
|
139
130
|
def to_s
|
@@ -13,7 +13,7 @@ module Rspec
|
|
13
13
|
def self.inherited(klass)
|
14
14
|
super
|
15
15
|
Rspec::Core.configuration.autorun!
|
16
|
-
Rspec::Core.world.
|
16
|
+
Rspec::Core.world.example_groups << klass
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.extended_modules #:nodoc:
|
@@ -22,13 +22,16 @@ module Rspec
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.example(desc=nil, options={}, &block)
|
25
|
-
|
25
|
+
options.update(:pending => true) unless block
|
26
|
+
options.update(:caller => caller)
|
27
|
+
examples << Rspec::Core::Example.new(self, desc, options, block)
|
26
28
|
end
|
27
29
|
|
28
30
|
def self.alias_example_to(new_alias, extra_options={})
|
29
31
|
new_alias = <<-END_RUBY
|
30
32
|
def self.#{new_alias}(desc=nil, options={}, &block)
|
31
|
-
updated_options = options.update(:caller => caller
|
33
|
+
updated_options = options.update(:caller => caller)
|
34
|
+
updated_options.update(:pending => true) unless block
|
32
35
|
updated_options.update(#{extra_options.inspect})
|
33
36
|
examples << Rspec::Core::Example.new(self, desc, updated_options, block)
|
34
37
|
end
|
@@ -39,11 +42,10 @@ module Rspec
|
|
39
42
|
alias_example_to :it
|
40
43
|
alias_example_to :specify
|
41
44
|
alias_example_to :focused, :focused => true
|
42
|
-
alias_example_to :disabled, :disabled => true
|
43
45
|
alias_example_to :pending, :pending => true
|
44
46
|
|
45
47
|
def self.it_should_behave_like(*names)
|
46
|
-
Rspec::Core.world.
|
48
|
+
Rspec::Core.world.shared_example_groups.each do |name, block|
|
47
49
|
module_eval(&block) if names.include?(name)
|
48
50
|
end
|
49
51
|
end
|
@@ -73,11 +75,11 @@ module Rspec
|
|
73
75
|
end
|
74
76
|
|
75
77
|
def self.name(friendly=true)
|
76
|
-
friendly ? metadata[:
|
78
|
+
friendly ? metadata[:example_group][:name] : super
|
77
79
|
end
|
78
80
|
|
79
81
|
def self.describes
|
80
|
-
metadata[:
|
82
|
+
metadata[:example_group][:describes]
|
81
83
|
end
|
82
84
|
|
83
85
|
def self.described_class
|
@@ -85,24 +87,24 @@ module Rspec
|
|
85
87
|
end
|
86
88
|
|
87
89
|
def self.description
|
88
|
-
metadata[:
|
90
|
+
metadata[:example_group][:description]
|
89
91
|
end
|
90
92
|
|
91
93
|
def self.file_path
|
92
|
-
metadata[:
|
94
|
+
metadata[:example_group][:file_path]
|
93
95
|
end
|
94
96
|
|
95
|
-
def self.describe(*args, &
|
97
|
+
def self.describe(*args, &example_group_block)
|
96
98
|
raise(ArgumentError, "No arguments given. You must a least supply a type or description") if args.empty?
|
97
|
-
raise(ArgumentError, "You must supply a block when calling describe") if
|
99
|
+
raise(ArgumentError, "You must supply a block when calling describe") if example_group_block.nil?
|
98
100
|
|
99
101
|
# TODO: Pull out the below into a metadata object, that we can defer the subclassing if necessary
|
100
102
|
# describe 'foo', :shared => true will need this to be completed first
|
101
103
|
subclass('NestedLevel') do
|
102
104
|
args << {} unless args.last.is_a?(Hash)
|
103
|
-
args.last.update(:
|
105
|
+
args.last.update(:example_group_block => example_group_block, :caller => caller)
|
104
106
|
set_it_up(*args)
|
105
|
-
module_eval(&
|
107
|
+
module_eval(&example_group_block)
|
106
108
|
end
|
107
109
|
end
|
108
110
|
|
@@ -134,33 +136,33 @@ module Rspec
|
|
134
136
|
@before_all_ivars ||= {}
|
135
137
|
end
|
136
138
|
|
137
|
-
def self.eval_before_alls(
|
138
|
-
superclass.before_all_ivars.each { |ivar, val|
|
139
|
-
Rspec::Core.configuration.find_advice(:before, :all, self).each { |blk|
|
139
|
+
def self.eval_before_alls(running_example_group)
|
140
|
+
superclass.before_all_ivars.each { |ivar, val| running_example_group.instance_variable_set(ivar, val) }
|
141
|
+
Rspec::Core.configuration.find_advice(:before, :all, self).each { |blk| running_example_group.instance_eval(&blk) }
|
140
142
|
|
141
|
-
before_alls.each { |blk|
|
142
|
-
|
143
|
+
before_alls.each { |blk| running_example_group.instance_eval(&blk) }
|
144
|
+
running_example_group.instance_variables.each { |ivar| before_all_ivars[ivar] = running_example_group.instance_variable_get(ivar) }
|
143
145
|
end
|
144
146
|
|
145
|
-
def self.eval_before_eachs(
|
146
|
-
Rspec::Core.configuration.find_advice(:before, :each, self).each { |blk|
|
147
|
-
before_ancestors.each { |ancestor| ancestor.before_eachs.each { |blk|
|
147
|
+
def self.eval_before_eachs(running_example_group)
|
148
|
+
Rspec::Core.configuration.find_advice(:before, :each, self).each { |blk| running_example_group.instance_eval(&blk) }
|
149
|
+
before_ancestors.each { |ancestor| ancestor.before_eachs.each { |blk| running_example_group.instance_eval(&blk) } }
|
148
150
|
end
|
149
151
|
|
150
|
-
def self.eval_after_alls(
|
151
|
-
after_alls.each { |blk|
|
152
|
-
Rspec::Core.configuration.find_advice(:after, :all, self).each { |blk|
|
153
|
-
before_all_ivars.keys.each { |ivar| before_all_ivars[ivar] =
|
152
|
+
def self.eval_after_alls(running_example_group)
|
153
|
+
after_alls.each { |blk| running_example_group.instance_eval(&blk) }
|
154
|
+
Rspec::Core.configuration.find_advice(:after, :all, self).each { |blk| running_example_group.instance_eval(&blk) }
|
155
|
+
before_all_ivars.keys.each { |ivar| before_all_ivars[ivar] = running_example_group.instance_variable_get(ivar) }
|
154
156
|
end
|
155
157
|
|
156
|
-
def self.eval_after_eachs(
|
157
|
-
after_ancestors.each { |ancestor| ancestor.after_eachs.each { |blk|
|
158
|
-
Rspec::Core.configuration.find_advice(:after, :each, self).each { |blk|
|
158
|
+
def self.eval_after_eachs(running_example_group)
|
159
|
+
after_ancestors.each { |ancestor| ancestor.after_eachs.each { |blk| running_example_group.instance_eval(&blk) } }
|
160
|
+
Rspec::Core.configuration.find_advice(:after, :each, self).each { |blk| running_example_group.instance_eval(&blk) }
|
159
161
|
end
|
160
162
|
|
161
163
|
def self.run(reporter)
|
162
164
|
example_world = new
|
163
|
-
reporter.
|
165
|
+
reporter.add_example_group(self)
|
164
166
|
eval_before_alls(example_world)
|
165
167
|
success = run_examples(example_world, reporter)
|
166
168
|
eval_after_alls(example_world)
|
@@ -178,7 +180,6 @@ module Rspec
|
|
178
180
|
end.all?
|
179
181
|
end
|
180
182
|
|
181
|
-
|
182
183
|
def self.subclass(base_name, &body) # :nodoc:
|
183
184
|
@_subclass_count ||= 0
|
184
185
|
@_subclass_count += 1
|
@@ -200,10 +201,18 @@ module Rspec
|
|
200
201
|
end
|
201
202
|
end
|
202
203
|
|
204
|
+
def self.all_apply?(filters)
|
205
|
+
metadata.all_apply?(filters)
|
206
|
+
end
|
207
|
+
|
203
208
|
def assignments
|
204
209
|
@assignments ||= {}
|
205
210
|
end
|
206
211
|
|
212
|
+
def described_class
|
213
|
+
running_example.metadata[:example_group][:describes]
|
214
|
+
end
|
215
|
+
|
207
216
|
def __reset__
|
208
217
|
instance_variables.each { |ivar| remove_instance_variable(ivar) }
|
209
218
|
assignments.clear
|
@@ -5,13 +5,13 @@ module Rspec
|
|
5
5
|
module Formatters
|
6
6
|
|
7
7
|
class BaseFormatter
|
8
|
-
attr_accessor :
|
8
|
+
attr_accessor :example_group
|
9
9
|
attr_reader :example_count, :duration, :examples
|
10
10
|
|
11
11
|
def initialize
|
12
12
|
@example_count = 0
|
13
13
|
@examples = []
|
14
|
-
@
|
14
|
+
@example_group = nil
|
15
15
|
end
|
16
16
|
|
17
17
|
def configuration
|
@@ -43,7 +43,7 @@ module Rspec
|
|
43
43
|
# formatters that need to provide progress on feedback (graphical ones)
|
44
44
|
#
|
45
45
|
# This method will only be invoked once, and the next one to be invoked
|
46
|
-
# is #
|
46
|
+
# is #add_example_group
|
47
47
|
def start(example_count)
|
48
48
|
@example_count = example_count
|
49
49
|
end
|
@@ -52,13 +52,15 @@ module Rspec
|
|
52
52
|
examples << example
|
53
53
|
end
|
54
54
|
|
55
|
-
# This method is invoked at the beginning of the execution of each
|
56
|
-
# +
|
55
|
+
# This method is invoked at the beginning of the execution of each example group.
|
56
|
+
# +example_group+ is the example_group.
|
57
57
|
#
|
58
58
|
# The next method to be invoked after this is #example_failed or #example_finished
|
59
|
-
def
|
60
|
-
@
|
59
|
+
def add_example_group(example_group)
|
60
|
+
@example_group = example_group
|
61
61
|
end
|
62
|
+
|
63
|
+
alias_method :add_example_group, :add_example_group
|
62
64
|
|
63
65
|
# This method is invoked after all of the examples have executed. The next method
|
64
66
|
# to be invoked after this one is #dump_failure (once for each failed example),
|
@@ -79,7 +79,7 @@ module Rspec
|
|
79
79
|
output.puts "Pending:"
|
80
80
|
pending_examples.each do |pending_example, message|
|
81
81
|
output.puts " #{pending_example}"
|
82
|
-
output.puts grey(" # #{format_caller(pending_example.metadata[:
|
82
|
+
output.puts grey(" # #{format_caller(pending_example.metadata[:location])}")
|
83
83
|
end
|
84
84
|
end
|
85
85
|
output.flush
|
@@ -136,4 +136,4 @@ module Rspec
|
|
136
136
|
|
137
137
|
end
|
138
138
|
|
139
|
-
end
|
139
|
+
end
|
@@ -6,28 +6,26 @@ module Rspec
|
|
6
6
|
|
7
7
|
class DocumentationFormatter < BaseTextFormatter
|
8
8
|
|
9
|
-
attr_reader :previous_nested_behaviours
|
10
|
-
|
11
9
|
def initialize
|
12
10
|
super
|
13
|
-
@
|
11
|
+
@previous_nested_example_groups = []
|
14
12
|
end
|
15
13
|
|
16
|
-
def
|
14
|
+
def add_example_group(example_group)
|
17
15
|
super
|
18
16
|
|
19
|
-
|
20
|
-
unless
|
17
|
+
described_example_group_chain.each_with_index do |nested_example_group, i|
|
18
|
+
unless nested_example_group == @previous_nested_example_groups[i]
|
21
19
|
at_root_level = (i == 0)
|
22
|
-
desc_or_name = at_root_level ?
|
20
|
+
desc_or_name = at_root_level ? nested_example_group.name : nested_example_group.description
|
23
21
|
output.puts if at_root_level
|
24
22
|
output.puts "#{' ' * i}#{desc_or_name}"
|
25
23
|
end
|
26
24
|
end
|
27
25
|
|
28
|
-
@
|
26
|
+
@previous_nested_example_groups = described_example_group_chain
|
29
27
|
end
|
30
|
-
|
28
|
+
|
31
29
|
def output_for(example)
|
32
30
|
case example.execution_result[:status]
|
33
31
|
when 'failed'
|
@@ -68,11 +66,11 @@ module Rspec
|
|
68
66
|
end
|
69
67
|
|
70
68
|
def current_indentation
|
71
|
-
' ' *
|
69
|
+
' ' * @previous_nested_example_groups.size
|
72
70
|
end
|
73
71
|
|
74
|
-
def
|
75
|
-
|
72
|
+
def described_example_group_chain
|
73
|
+
example_group.ancestors
|
76
74
|
end
|
77
75
|
|
78
76
|
end
|