rspec-core 2.10.1 → 2.11.0
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/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
|