rspec-core 2.10.1 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Changelog.md +35 -2
- data/README.md +14 -13
- data/features/command_line/example_name_option.feature +15 -0
- data/features/helper_methods/modules.feature +3 -3
- data/lib/rspec/core.rb +6 -2
- data/lib/rspec/core/configuration.rb +61 -26
- data/lib/rspec/core/configuration_options.rb +5 -1
- data/lib/rspec/core/deprecation.rb +0 -15
- data/lib/rspec/core/drb_command_line.rb +3 -0
- data/lib/rspec/core/drb_options.rb +3 -1
- data/lib/rspec/core/dsl.rb +4 -2
- data/lib/rspec/core/example.rb +85 -23
- data/lib/rspec/core/example_group.rb +103 -78
- data/lib/rspec/core/hooks.rb +68 -33
- data/lib/rspec/core/let.rb +0 -1
- data/lib/rspec/core/mocking/with_mocha.rb +10 -4
- data/lib/rspec/core/option_parser.rb +3 -2
- data/lib/rspec/core/project_initializer.rb +7 -1
- data/lib/rspec/core/runner.rb +2 -2
- data/lib/rspec/core/shared_context.rb +2 -2
- data/lib/rspec/core/shared_example_group.rb +38 -14
- data/lib/rspec/core/subject.rb +67 -52
- data/lib/rspec/core/version.rb +1 -1
- data/spec/rspec/core/command_line_spec.rb +68 -126
- data/spec/rspec/core/configuration_options_spec.rb +20 -4
- data/spec/rspec/core/configuration_spec.rb +61 -21
- data/spec/rspec/core/drb_command_line_spec.rb +1 -0
- data/spec/rspec/core/drb_options_spec.rb +1 -0
- data/spec/rspec/core/dsl_spec.rb +17 -0
- data/spec/rspec/core/example_group_spec.rb +19 -11
- data/spec/rspec/core/example_spec.rb +34 -0
- data/spec/rspec/core/option_parser_spec.rb +2 -1
- data/spec/rspec/core/shared_example_group_spec.rb +9 -9
- data/spec/rspec/core/subject_spec.rb +14 -0
- data/spec/rspec/core_spec.rb +18 -8
- data/spec/spec_helper.rb +1 -2
- metadata +7 -5
@@ -95,6 +95,22 @@ describe RSpec::Core::ConfigurationOptions, :fakefs do
|
|
95
95
|
config.should_receive(:debug=).with(true)
|
96
96
|
opts.configure(config)
|
97
97
|
end
|
98
|
+
|
99
|
+
it "merges --require specified by multiple configuration sources" do
|
100
|
+
ENV['SPEC_OPTS'] = "--require file_from_env"
|
101
|
+
opts = config_options_object(*%w[--require file_from_opts])
|
102
|
+
config = RSpec::Core::Configuration.new
|
103
|
+
config.should_receive(:requires=).with(["file_from_opts", "file_from_env"])
|
104
|
+
opts.configure(config)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "merges --I specified by multiple configuration sources" do
|
108
|
+
ENV['SPEC_OPTS'] = "-I dir_from_env"
|
109
|
+
opts = config_options_object(*%w[-I dir_from_opts])
|
110
|
+
config = RSpec::Core::Configuration.new
|
111
|
+
config.should_receive(:libs=).with(["dir_from_opts", "dir_from_env"])
|
112
|
+
opts.configure(config)
|
113
|
+
end
|
98
114
|
end
|
99
115
|
|
100
116
|
describe "-c, --color, and --colour" do
|
@@ -170,8 +186,8 @@ describe RSpec::Core::ConfigurationOptions, :fakefs do
|
|
170
186
|
|
171
187
|
describe "--example" do
|
172
188
|
it "sets :full_description" do
|
173
|
-
parse_options('--example','foo').should include(:full_description => /foo/)
|
174
|
-
parse_options('-e','bar').should include(:full_description => /bar/)
|
189
|
+
parse_options('--example','foo').should include(:full_description => [/foo/])
|
190
|
+
parse_options('-e','bar').should include(:full_description => [/bar/])
|
175
191
|
end
|
176
192
|
end
|
177
193
|
|
@@ -321,7 +337,7 @@ describe RSpec::Core::ConfigurationOptions, :fakefs do
|
|
321
337
|
options[:color].should be_true
|
322
338
|
options[:line_numbers].should eq(["37"])
|
323
339
|
options[:debug].should be_true
|
324
|
-
options[:full_description].should eq(/foo\ bar/)
|
340
|
+
options[:full_description].should eq([/foo\ bar/])
|
325
341
|
options[:drb].should be_true
|
326
342
|
end
|
327
343
|
|
@@ -354,7 +370,7 @@ describe RSpec::Core::ConfigurationOptions, :fakefs do
|
|
354
370
|
it "parses -e 'full spec description'" do
|
355
371
|
File.open("./custom.opts", "w") {|f| f << "-e 'The quick brown fox jumps over the lazy dog'"}
|
356
372
|
options = parse_options("-O", "./custom.opts")
|
357
|
-
options[:full_description].should
|
373
|
+
options[:full_description].should eq([/The\ quick\ brown\ fox\ jumps\ over\ the\ lazy\ dog/])
|
358
374
|
end
|
359
375
|
end
|
360
376
|
end
|
@@ -64,10 +64,37 @@ module RSpec::Core
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
+
shared_examples "a configurable framework adapter" do |m|
|
68
|
+
it "yields a config object if the framework_module supports it" do
|
69
|
+
custom_config = Struct.new(:custom_setting).new
|
70
|
+
mod = Module.new
|
71
|
+
mod.stub(:configuration => custom_config)
|
72
|
+
|
73
|
+
config.send m, mod do |mod_config|
|
74
|
+
mod_config.custom_setting = true
|
75
|
+
end
|
76
|
+
|
77
|
+
custom_config.custom_setting.should be_true
|
78
|
+
end
|
79
|
+
|
80
|
+
it "raises if framework module doesn't support configuration" do
|
81
|
+
mod = Module.new
|
82
|
+
|
83
|
+
lambda do
|
84
|
+
config.send m, mod do |mod_config|
|
85
|
+
end
|
86
|
+
end.should raise_error /must respond to `configuration`/
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
67
90
|
describe "#mock_with" do
|
91
|
+
before { config.stub(:require) }
|
92
|
+
|
93
|
+
it_behaves_like "a configurable framework adapter", :mock_with
|
94
|
+
|
68
95
|
[:rspec, :mocha, :rr, :flexmock].each do |framework|
|
69
96
|
context "with #{framework}" do
|
70
|
-
it "requires the adapter for #{framework
|
97
|
+
it "requires the adapter for #{framework}" do
|
71
98
|
config.should_receive(:require).with("rspec/core/mocking/with_#{framework}")
|
72
99
|
config.mock_with framework
|
73
100
|
end
|
@@ -76,7 +103,6 @@ module RSpec::Core
|
|
76
103
|
|
77
104
|
context "with a module" do
|
78
105
|
it "sets the mock_framework_adapter to that module" do
|
79
|
-
config.stub(:require)
|
80
106
|
mod = Module.new
|
81
107
|
config.mock_with mod
|
82
108
|
config.mock_framework.should eq(mod)
|
@@ -89,8 +115,6 @@ module RSpec::Core
|
|
89
115
|
end
|
90
116
|
|
91
117
|
context 'when there are already some example groups defined' do
|
92
|
-
before(:each) { config.stub(:require) }
|
93
|
-
|
94
118
|
it 'raises an error since this setting must be applied before any groups are defined' do
|
95
119
|
RSpec.world.stub(:example_groups).and_return([double.as_null_object])
|
96
120
|
expect {
|
@@ -129,16 +153,14 @@ module RSpec::Core
|
|
129
153
|
end
|
130
154
|
|
131
155
|
describe "#expect_with" do
|
132
|
-
before(:
|
133
|
-
|
134
|
-
|
135
|
-
config.stub(:require)
|
136
|
-
end
|
156
|
+
before { config.stub(:require) }
|
157
|
+
|
158
|
+
it_behaves_like "a configurable framework adapter", :expect_with
|
137
159
|
|
138
160
|
[
|
139
161
|
[:rspec, 'rspec/expectations'],
|
140
162
|
[:stdlib, 'test/unit/assertions']
|
141
|
-
].each do |
|
163
|
+
].each do |framework, required_file|
|
142
164
|
context "with #{framework}" do
|
143
165
|
it "requires #{required_file}" do
|
144
166
|
config.should_receive(:require).with(required_file)
|
@@ -147,6 +169,19 @@ module RSpec::Core
|
|
147
169
|
end
|
148
170
|
end
|
149
171
|
|
172
|
+
it "supports multiple calls" do
|
173
|
+
config.expect_with :rspec
|
174
|
+
config.expect_with :stdlib
|
175
|
+
config.expectation_frameworks.should eq [RSpec::Matchers, Test::Unit::Assertions]
|
176
|
+
end
|
177
|
+
|
178
|
+
it "raises if block given with multiple args" do
|
179
|
+
lambda do
|
180
|
+
config.expect_with :rspec, :stdlib do |mod_config|
|
181
|
+
end
|
182
|
+
end.should raise_error /expect_with only accepts/
|
183
|
+
end
|
184
|
+
|
150
185
|
it "raises ArgumentError if framework is not supported" do
|
151
186
|
expect do
|
152
187
|
config.expect_with :not_supported
|
@@ -178,11 +213,7 @@ module RSpec::Core
|
|
178
213
|
end
|
179
214
|
|
180
215
|
describe "#expecting_with_rspec?" do
|
181
|
-
before(:
|
182
|
-
# prevent minitest assertions from being required and included,
|
183
|
-
# as that causes problems in some of our specs.
|
184
|
-
config.stub(:require)
|
185
|
-
end
|
216
|
+
before { config.stub(:require) }
|
186
217
|
|
187
218
|
it "returns false by default" do
|
188
219
|
config.should_not be_expecting_with_rspec
|
@@ -215,13 +246,13 @@ module RSpec::Core
|
|
215
246
|
config.files_to_run.should eq([ "spec/rspec/core/resources/a_bar.rb"])
|
216
247
|
end
|
217
248
|
|
218
|
-
it "prevents
|
249
|
+
it "prevents repetition of dir when start of the pattern" do
|
219
250
|
config.pattern = "spec/**/a_spec.rb"
|
220
251
|
config.files_or_directories_to_run = "spec"
|
221
252
|
config.files_to_run.should eq(["spec/rspec/core/resources/a_spec.rb"])
|
222
253
|
end
|
223
254
|
|
224
|
-
it "does not prevent
|
255
|
+
it "does not prevent repetition of dir when later of the pattern" do
|
225
256
|
config.pattern = "rspec/**/a_spec.rb"
|
226
257
|
config.files_or_directories_to_run = "spec"
|
227
258
|
config.files_to_run.should eq(["spec/rspec/core/resources/a_spec.rb"])
|
@@ -265,10 +296,14 @@ module RSpec::Core
|
|
265
296
|
config.files_to_run.should eq([ "spec/rspec/core/resources/a_spec.rb"])
|
266
297
|
end
|
267
298
|
|
268
|
-
it "loads files in Windows" do
|
269
|
-
|
270
|
-
config.
|
271
|
-
|
299
|
+
it "loads files in Windows", :if => RSpec.windows_os? do
|
300
|
+
config.files_or_directories_to_run = "C:\\path\\to\\project\\spec\\sub\\foo_spec.rb"
|
301
|
+
config.files_to_run.should eq([ "C:/path/to/project/spec/sub/foo_spec.rb"])
|
302
|
+
end
|
303
|
+
|
304
|
+
it "loads files in Windows when directory is specified", :if => RSpec.windows_os? do
|
305
|
+
config.files_or_directories_to_run = "spec\\rspec\\core\\resources"
|
306
|
+
config.files_to_run.should eq([ "spec/rspec/core/resources/a_spec.rb"])
|
272
307
|
end
|
273
308
|
end
|
274
309
|
|
@@ -376,6 +411,11 @@ module RSpec::Core
|
|
376
411
|
config.filter.should eq({:full_description => /foo/})
|
377
412
|
end
|
378
413
|
|
414
|
+
it "assigns the example names as the filter on description if description is an array" do
|
415
|
+
config.full_description = [ "foo", "bar" ]
|
416
|
+
config.filter.should eq({:full_description => Regexp.union(/foo/, /bar/)})
|
417
|
+
end
|
418
|
+
|
379
419
|
describe "#default_path" do
|
380
420
|
it 'defaults to "spec"' do
|
381
421
|
config.default_path.should eq('spec')
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
main = self
|
4
|
+
describe "The describe method" do
|
5
|
+
it 'is available on the main object' do
|
6
|
+
main.should respond_to(:describe)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'is available on modules (so example groups can be nested inside them)' do
|
10
|
+
Module.new.should respond_to(:describe)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'is not available on other types of objects' do
|
14
|
+
Object.new.should_not respond_to(:describe)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -359,15 +359,14 @@ module RSpec::Core
|
|
359
359
|
|
360
360
|
[:focus, :focused].each do |example_alias|
|
361
361
|
describe "##{example_alias}" do
|
362
|
-
let(:
|
363
|
-
subject { group.send example_alias, "a focused example" }
|
362
|
+
let(:focused_example) { ExampleGroup.describe.send example_alias, "a focused example" }
|
364
363
|
|
365
364
|
it 'defines an example that can be filtered with :focused => true' do
|
366
|
-
|
365
|
+
focused_example.metadata[:focused].should be_true
|
367
366
|
end
|
368
367
|
|
369
368
|
it 'defines an example that can be filtered with :focus => true' do
|
370
|
-
|
369
|
+
focused_example.metadata[:focus].should be_true
|
371
370
|
end
|
372
371
|
end
|
373
372
|
end
|
@@ -866,7 +865,7 @@ module RSpec::Core
|
|
866
865
|
|
867
866
|
context "with all examples passing" do
|
868
867
|
it "returns true" do
|
869
|
-
group = describe("something") do
|
868
|
+
group = RSpec::Core::ExampleGroup.describe("something") do
|
870
869
|
it "does something" do
|
871
870
|
# pass
|
872
871
|
end
|
@@ -883,7 +882,7 @@ module RSpec::Core
|
|
883
882
|
|
884
883
|
context "with top level example failing" do
|
885
884
|
it "returns false" do
|
886
|
-
group = describe("something") do
|
885
|
+
group = RSpec::Core::ExampleGroup.describe("something") do
|
887
886
|
it "does something (wrong - fail)" do
|
888
887
|
raise "fail"
|
889
888
|
end
|
@@ -900,7 +899,7 @@ module RSpec::Core
|
|
900
899
|
|
901
900
|
context "with nested example failing" do
|
902
901
|
it "returns true" do
|
903
|
-
group = describe("something") do
|
902
|
+
group = RSpec::Core::ExampleGroup.describe("something") do
|
904
903
|
it "does something" do
|
905
904
|
# pass
|
906
905
|
end
|
@@ -971,10 +970,19 @@ module RSpec::Core
|
|
971
970
|
eval_count.should eq(1)
|
972
971
|
end
|
973
972
|
|
974
|
-
it "
|
975
|
-
|
976
|
-
|
977
|
-
|
973
|
+
it "evals the block when given" do
|
974
|
+
key = "#{__FILE__}:#{__LINE__}"
|
975
|
+
shared_examples(key) do
|
976
|
+
it("does something") do
|
977
|
+
foo.should eq("bar")
|
978
|
+
end
|
979
|
+
end
|
980
|
+
group = ExampleGroup.describe do
|
981
|
+
send name, key do
|
982
|
+
def foo; "bar"; end
|
983
|
+
end
|
984
|
+
end
|
985
|
+
group.run.should be_true
|
978
986
|
end
|
979
987
|
end
|
980
988
|
end
|
@@ -258,6 +258,40 @@ describe RSpec::Core::Example, :parent_metadata => 'sample' do
|
|
258
258
|
group.run.should be_true
|
259
259
|
end
|
260
260
|
end
|
261
|
+
|
262
|
+
context "when the example and an around hook raise errors" do
|
263
|
+
it "prints the around hook error rather than silencing it" do
|
264
|
+
group = RSpec::Core::ExampleGroup.describe do
|
265
|
+
around(:each) { |e| e.run; raise "around" }
|
266
|
+
example("e") { raise "example" }
|
267
|
+
end
|
268
|
+
|
269
|
+
reported_msg = nil
|
270
|
+
# We can't use should_receive(:message).with(/.../) here,
|
271
|
+
# because if that fails, it would fail within our example-under-test,
|
272
|
+
# and since there's already two errors, it would just be reported again.
|
273
|
+
RSpec.configuration.reporter.stub(:message) { |msg| reported_msg = msg }
|
274
|
+
group.run
|
275
|
+
reported_msg.should =~ /An error occurred in an around.* hook/i
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
context "when the example and an after hook raise errors" do
|
280
|
+
it "prints the after hook error rather than silencing it" do
|
281
|
+
group = RSpec::Core::ExampleGroup.describe do
|
282
|
+
after(:each) { raise "after" }
|
283
|
+
example("e") { raise "example" }
|
284
|
+
end
|
285
|
+
|
286
|
+
reported_msg = nil
|
287
|
+
# We can't use should_receive(:message).with(/.../) here,
|
288
|
+
# because if that fails, it would fail within our example-under-test,
|
289
|
+
# and since there's already two errors, it would just be reported again.
|
290
|
+
RSpec.configuration.reporter.stub(:message) { |msg| reported_msg = msg }
|
291
|
+
group.run
|
292
|
+
reported_msg.should =~ /An error occurred in an after.* hook/i
|
293
|
+
end
|
294
|
+
end
|
261
295
|
end
|
262
296
|
|
263
297
|
describe "#pending" do
|
@@ -68,7 +68,8 @@ module RSpec::Core
|
|
68
68
|
describe option do
|
69
69
|
it "escapes the arg" do
|
70
70
|
options = Parser.parse!([option, "this (and that)"])
|
71
|
-
|
71
|
+
options[:full_description].length.should == 1
|
72
|
+
"this (and that)".should match(options[:full_description].first)
|
72
73
|
end
|
73
74
|
end
|
74
75
|
end
|
@@ -6,17 +6,17 @@ module RSpec::Core
|
|
6
6
|
ExampleModule = Module.new
|
7
7
|
ExampleClass = Class.new
|
8
8
|
|
9
|
-
%w[share_examples_for shared_examples_for].each do |
|
10
|
-
describe
|
9
|
+
%w[share_examples_for shared_examples_for shared_examples shared_context].each do |shared_method_name|
|
10
|
+
describe shared_method_name do
|
11
11
|
it "is exposed to the global namespace" do
|
12
|
-
Kernel.should respond_to(
|
12
|
+
Kernel.should respond_to(shared_method_name)
|
13
13
|
end
|
14
14
|
|
15
15
|
it "raises an ArgumentError when adding a second shared example group with the same name" do
|
16
16
|
group = ExampleGroup.describe('example group')
|
17
|
-
group.send(
|
17
|
+
group.send(shared_method_name, 'shared group') {}
|
18
18
|
lambda do
|
19
|
-
group.send(
|
19
|
+
group.send(shared_method_name, 'shared group') {}
|
20
20
|
end.should raise_error(ArgumentError, "Shared example group 'shared group' already exists")
|
21
21
|
end
|
22
22
|
|
@@ -26,7 +26,7 @@ module RSpec::Core
|
|
26
26
|
it "captures the given #{type} and block in the World's collection of shared example groups" do
|
27
27
|
implementation = lambda {}
|
28
28
|
RSpec.world.shared_example_groups.should_receive(:[]=).with(object, implementation)
|
29
|
-
send(
|
29
|
+
send(shared_method_name, object, &implementation)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -34,7 +34,7 @@ module RSpec::Core
|
|
34
34
|
context "given a hash" do
|
35
35
|
it "delegates extend on configuration" do
|
36
36
|
implementation = Proc.new { def bar; 'bar'; end }
|
37
|
-
send(
|
37
|
+
send(shared_method_name, :foo => :bar, &implementation)
|
38
38
|
a = RSpec.configuration.include_or_extend_modules.first
|
39
39
|
a[0].should eq(:extend)
|
40
40
|
Class.new.extend(a[1]).new.bar.should eq('bar')
|
@@ -46,12 +46,12 @@ module RSpec::Core
|
|
46
46
|
it "captures the given string and block in the World's collection of shared example groups" do
|
47
47
|
implementation = lambda {}
|
48
48
|
RSpec.world.shared_example_groups.should_receive(:[]=).with("name", implementation)
|
49
|
-
send(
|
49
|
+
send(shared_method_name, "name", :foo => :bar, &implementation)
|
50
50
|
end
|
51
51
|
|
52
52
|
it "delegates extend on configuration" do
|
53
53
|
implementation = Proc.new { def bar; 'bar'; end }
|
54
|
-
send(
|
54
|
+
send(shared_method_name, "name", :foo => :bar, &implementation)
|
55
55
|
a = RSpec.configuration.include_or_extend_modules.first
|
56
56
|
a[0].should eq(:extend)
|
57
57
|
Class.new.extend(a[1]).new.bar.should eq('bar')
|
@@ -78,6 +78,20 @@ module RSpec::Core
|
|
78
78
|
doubly_nested_group.subject.call.should eq([4,5,6])
|
79
79
|
end
|
80
80
|
end
|
81
|
+
|
82
|
+
describe "with a name" do
|
83
|
+
it "defines a method that returns the memoized subject" do
|
84
|
+
group = ExampleGroup.describe do
|
85
|
+
subject(:list) { [1,2,3] }
|
86
|
+
example do
|
87
|
+
list.should equal(list)
|
88
|
+
subject.should equal(subject)
|
89
|
+
subject.should equal(list)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
group.run.should be_true
|
93
|
+
end
|
94
|
+
end
|
81
95
|
end
|
82
96
|
|
83
97
|
context "using 'self' as an explicit subject" do
|
data/spec/rspec/core_spec.rb
CHANGED
@@ -1,25 +1,35 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe RSpec
|
4
|
-
|
5
|
-
describe "#configuration" do
|
3
|
+
describe RSpec do
|
4
|
+
describe "::configuration" do
|
6
5
|
it "returns the same object every time" do
|
7
6
|
RSpec.configuration.should equal(RSpec.configuration)
|
8
7
|
end
|
9
8
|
end
|
10
9
|
|
11
|
-
describe "
|
10
|
+
describe "::configure" do
|
12
11
|
it "yields the current configuration" do
|
13
12
|
RSpec.configure do |config|
|
14
|
-
config.should
|
13
|
+
config.should equal(RSpec::configuration)
|
15
14
|
end
|
16
15
|
end
|
17
16
|
end
|
18
17
|
|
19
|
-
describe "
|
20
|
-
it "returns the
|
21
|
-
RSpec.world.should
|
18
|
+
describe "::world" do
|
19
|
+
it "returns the same object every time" do
|
20
|
+
RSpec.world.should equal(RSpec.world)
|
22
21
|
end
|
23
22
|
end
|
24
23
|
|
24
|
+
describe "::reset" do
|
25
|
+
it "resets the configuration and world objects" do
|
26
|
+
config_before_reset = RSpec.configuration
|
27
|
+
world_before_reset = RSpec.world
|
28
|
+
|
29
|
+
RSpec.reset
|
30
|
+
|
31
|
+
RSpec.configuration.should_not equal(config_before_reset)
|
32
|
+
RSpec.world.should_not equal(world_before_reset)
|
33
|
+
end
|
34
|
+
end
|
25
35
|
end
|