rspec-core 2.5.1 → 2.6.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.
Files changed (123) hide show
  1. data/.travis.yml +7 -0
  2. data/Gemfile +12 -14
  3. data/README.md +4 -1
  4. data/Rakefile +29 -12
  5. data/cucumber.yml +1 -1
  6. data/features/.nav +15 -9
  7. data/features/Autotest.md +31 -7
  8. data/features/Changelog.md +46 -3
  9. data/features/Upgrade.md +35 -2
  10. data/features/command_line/README.md +22 -0
  11. data/features/command_line/configure.feature +2 -2
  12. data/features/command_line/example_name_option.feature +10 -10
  13. data/features/command_line/exit_status.feature +4 -4
  14. data/features/command_line/format_option.feature +4 -4
  15. data/features/command_line/line_number_appended_to_path.feature +11 -11
  16. data/features/command_line/line_number_option.feature +2 -2
  17. data/features/command_line/rake_task.feature +3 -3
  18. data/features/command_line/tag.feature +30 -14
  19. data/features/configuration/alias_example_to.feature +48 -0
  20. data/features/configuration/custom_settings.feature +3 -3
  21. data/features/configuration/fail_fast.feature +3 -3
  22. data/features/configuration/read_options_from_file.feature +4 -4
  23. data/features/example_groups/basic_structure.feature +11 -15
  24. data/features/example_groups/shared_context.feature +74 -0
  25. data/features/example_groups/shared_example_group.feature +21 -17
  26. data/features/expectation_framework_integration/configure_expectation_framework.feature +15 -4
  27. data/features/filtering/exclusion_filters.feature +28 -4
  28. data/features/filtering/{implicit_filters.feature → if_and_unless.feature} +9 -7
  29. data/features/filtering/inclusion_filters.feature +26 -3
  30. data/features/filtering/run_all_when_everything_filtered.feature +2 -2
  31. data/features/formatters/custom_formatter.feature +1 -1
  32. data/features/formatters/text_formatter.feature +43 -0
  33. data/features/helper_methods/arbitrary_methods.feature +2 -2
  34. data/features/helper_methods/let.feature +2 -2
  35. data/features/helper_methods/modules.feature +149 -0
  36. data/features/hooks/around_hooks.feature +18 -11
  37. data/features/hooks/before_and_after_hooks.feature +15 -19
  38. data/features/hooks/filtering.feature +160 -124
  39. data/features/metadata/current_example.feature +17 -0
  40. data/features/metadata/described_class.feature +2 -2
  41. data/features/metadata/user_defined.feature +111 -0
  42. data/features/mock_framework_integration/use_any_framework.feature +1 -1
  43. data/features/mock_framework_integration/use_flexmock.feature +83 -10
  44. data/features/mock_framework_integration/use_mocha.feature +84 -10
  45. data/features/mock_framework_integration/use_rr.feature +85 -10
  46. data/features/mock_framework_integration/use_rspec.feature +84 -10
  47. data/features/pending/pending_examples.feature +8 -8
  48. data/features/spec_files/arbitrary_file_suffix.feature +1 -1
  49. data/features/step_definitions/additional_cli_steps.rb +11 -1
  50. data/features/subject/attribute_of_subject.feature +24 -4
  51. data/features/subject/explicit_subject.feature +5 -5
  52. data/features/subject/implicit_receiver.feature +2 -2
  53. data/features/subject/implicit_subject.feature +2 -2
  54. data/features/support/env.rb +6 -1
  55. data/lib/rspec/core/backward_compatibility.rb +12 -2
  56. data/lib/rspec/core/command_line.rb +2 -5
  57. data/lib/rspec/core/configuration.rb +70 -38
  58. data/lib/rspec/core/configuration_options.rb +6 -23
  59. data/lib/rspec/core/drb_command_line.rb +5 -11
  60. data/lib/rspec/core/example.rb +29 -21
  61. data/lib/rspec/core/example_group.rb +40 -8
  62. data/lib/rspec/core/extensions/object.rb +0 -1
  63. data/lib/rspec/core/formatters/base_formatter.rb +6 -0
  64. data/lib/rspec/core/formatters/base_text_formatter.rb +1 -1
  65. data/lib/rspec/core/formatters/helpers.rb +0 -4
  66. data/lib/rspec/core/hooks.rb +14 -4
  67. data/lib/rspec/core/metadata.rb +1 -1
  68. data/lib/rspec/core/metadata_hash_builder.rb +93 -0
  69. data/lib/rspec/core/mocking/with_flexmock.rb +2 -0
  70. data/lib/rspec/core/mocking/with_mocha.rb +2 -0
  71. data/lib/rspec/core/mocking/with_rr.rb +2 -0
  72. data/lib/rspec/core/mocking/with_rspec.rb +3 -1
  73. data/lib/rspec/core/option_parser.rb +9 -2
  74. data/lib/rspec/core/pending.rb +10 -3
  75. data/lib/rspec/core/reporter.rb +2 -2
  76. data/lib/rspec/core/runner.rb +38 -13
  77. data/lib/rspec/core/shared_example_group.rb +18 -4
  78. data/lib/rspec/core/subject.rb +4 -6
  79. data/lib/rspec/core/version.rb +1 -1
  80. data/lib/rspec/core/world.rb +70 -18
  81. data/lib/rspec/core.rb +29 -0
  82. data/lib/rspec/monkey/spork/test_framework/rspec.rb +1 -0
  83. data/rspec-core.gemspec +3 -5
  84. data/spec/autotest/failed_results_re_spec.rb +2 -2
  85. data/spec/rspec/core/command_line_spec.rb +36 -2
  86. data/spec/rspec/core/configuration_spec.rb +150 -70
  87. data/spec/rspec/core/deprecations_spec.rb +21 -0
  88. data/spec/rspec/core/drb_command_line_spec.rb +21 -56
  89. data/spec/rspec/core/example_group_spec.rb +213 -56
  90. data/spec/rspec/core/example_spec.rb +110 -0
  91. data/spec/rspec/core/formatters/base_formatter_spec.rb +23 -2
  92. data/spec/rspec/core/formatters/base_text_formatter_spec.rb +9 -0
  93. data/spec/rspec/core/formatters/helpers_spec.rb +1 -1
  94. data/spec/rspec/core/formatters/html_formatted-1.8.6.html +5 -5
  95. data/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html +8 -10
  96. data/spec/rspec/core/formatters/html_formatted-1.8.7.html +5 -5
  97. data/spec/rspec/core/formatters/html_formatted-1.9.1.html +5 -5
  98. data/spec/rspec/core/formatters/html_formatted-1.9.2.html +5 -5
  99. data/spec/rspec/core/formatters/progress_formatter_spec.rb +0 -1
  100. data/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html +5 -5
  101. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html +8 -10
  102. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html +5 -5
  103. data/spec/rspec/core/formatters/text_mate_formatted-1.9.1.html +5 -5
  104. data/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html +5 -5
  105. data/spec/rspec/core/hooks_spec.rb +86 -0
  106. data/spec/rspec/core/metadata_spec.rb +7 -7
  107. data/spec/rspec/core/option_parser_spec.rb +26 -15
  108. data/spec/rspec/core/pending_example_spec.rb +12 -51
  109. data/spec/rspec/core/reporter_spec.rb +19 -3
  110. data/spec/rspec/core/resources/formatter_specs.rb +7 -1
  111. data/spec/rspec/core/rspec_matchers_spec.rb +45 -0
  112. data/spec/rspec/core/runner_spec.rb +42 -10
  113. data/spec/rspec/core/shared_example_group_spec.rb +57 -21
  114. data/spec/rspec/core/subject_spec.rb +32 -11
  115. data/spec/rspec/core/world_spec.rb +147 -15
  116. data/spec/rspec/core_spec.rb +28 -0
  117. data/spec/spec_helper.rb +22 -2
  118. data/spec/support/matchers.rb +44 -13
  119. data/spec/support/shared_example_groups.rb +41 -0
  120. data/spec/support/spec_files.rb +44 -0
  121. data/spec.txt +1126 -0
  122. metadata +35 -16
  123. data/spec/ruby_forker.rb +0 -13
@@ -21,25 +21,57 @@ module RSpec::Core
21
21
  end
22
22
 
23
23
  describe "#run" do
24
+ let(:err) { StringIO.new }
25
+ let(:out) { StringIO.new }
26
+
27
+ it "resets world and configuration" do
28
+ RSpec.configuration.should_receive(:reset)
29
+ RSpec.world.should_receive(:reset)
30
+ RSpec::Core::Runner.run([], err, out)
31
+ end
32
+
24
33
  context "with --drb or -X" do
25
- before(:each) do
26
- @err = @out = StringIO.new
27
34
 
35
+ before(:each) do
28
36
  @options = RSpec::Core::ConfigurationOptions.new(%w[--drb --drb-port 8181 --color])
29
37
  RSpec::Core::ConfigurationOptions.stub(:new) { @options }
38
+ end
30
39
 
31
- @drb_proxy = double(RSpec::Core::DRbCommandLine, :run => true)
32
- RSpec::Core::DRbCommandLine.stub(:new => @drb_proxy)
40
+ def run_specs
41
+ RSpec::Core::Runner.run(%w[ --drb ], err, out)
33
42
  end
34
43
 
35
- it "builds a DRbCommandLine" do
36
- RSpec::Core::DRbCommandLine.should_receive(:new)
37
- RSpec::Core::Runner.run(%w[ --drb ], @err, @out)
44
+ context 'and a DRb server is running' do
45
+ it "builds a DRbCommandLine and runs the specs" do
46
+ drb_proxy = double(RSpec::Core::DRbCommandLine, :run => true)
47
+ drb_proxy.should_receive(:run).with(err, out)
48
+
49
+ RSpec::Core::DRbCommandLine.should_receive(:new).and_return(drb_proxy)
50
+
51
+ run_specs
52
+ end
38
53
  end
39
54
 
40
- it "runs specs over the proxy" do
41
- @drb_proxy.should_receive(:run).with(@err, @out)
42
- RSpec::Core::Runner.run(%w[ --drb ], @err, @out)
55
+ context 'and a DRb server is not running' do
56
+ before(:each) do
57
+ RSpec::Core::DRbCommandLine.should_receive(:new).and_raise(DRb::DRbConnError)
58
+ end
59
+
60
+ it "outputs a message" do
61
+ err.should_receive(:puts).with(
62
+ "No DRb server is running. Running in local process instead ..."
63
+ )
64
+ run_specs
65
+ end
66
+
67
+ it "builds a CommandLine and runs the specs" do
68
+ process_proxy = double(RSpec::Core::CommandLine, :run => true)
69
+ process_proxy.should_receive(:run).with(err, out)
70
+
71
+ RSpec::Core::CommandLine.should_receive(:new).and_return(process_proxy)
72
+
73
+ run_specs
74
+ end
43
75
  end
44
76
  end
45
77
  end
@@ -6,7 +6,6 @@ module RSpec::Core
6
6
 
7
7
  %w[share_examples_for shared_examples_for].each do |method_name|
8
8
  describe method_name do
9
-
10
9
  it "is exposed to the global namespace" do
11
10
  Kernel.should respond_to(method_name)
12
11
  end
@@ -19,32 +18,49 @@ module RSpec::Core
19
18
  end.should raise_error(ArgumentError, "Shared example group 'shared group' already exists")
20
19
  end
21
20
 
22
- it "captures the given name and block in the Worlds collection of shared example groups" do
23
- implementation = lambda {}
24
- RSpec.world.shared_example_groups.should_receive(:[]=).with(:foo, implementation)
25
- send(method_name, :foo, &implementation)
21
+ context "given a string" do
22
+ it "captures the given string and block in the World's collection of shared example groups" do
23
+ implementation = lambda {}
24
+ RSpec.world.shared_example_groups.should_receive(:[]=).with("name", implementation)
25
+ send(method_name, "name", &implementation)
26
+ end
26
27
  end
27
28
 
28
- end
29
- end
29
+ context "given a symbol" do
30
+ it "captures the given symbol and block in the World's collection of shared example groups" do
31
+ implementation = lambda {}
32
+ RSpec.world.shared_example_groups.should_receive(:[]=).with(:name, implementation)
33
+ send(method_name, :name, &implementation)
34
+ end
35
+ end
30
36
 
31
- describe "#share_as" do
32
- it "is exposed to the global namespace" do
33
- Kernel.should respond_to("share_as")
34
- end
37
+ context "given a hash" do
38
+ it "delegates extend on configuration" do
39
+ implementation = Proc.new { def bar; 'bar'; end }
40
+ send(method_name, :foo => :bar, &implementation)
41
+ a = RSpec.configuration.include_or_extend_modules.first
42
+ a[0].should eq(:extend)
43
+ Class.new.extend(a[1]).new.bar.should eq('bar')
44
+ a[2].should eq(:foo => :bar)
45
+ end
46
+ end
35
47
 
36
- it "adds examples to current example_group using include", :compat => 'rspec-1.2' do
37
- share_as('Cornucopia') do
38
- it "is plentiful" do
39
- 5.should == 4
48
+ context "given a string and a hash" do
49
+ it "captures the given string and block in the World's collection of shared example groups" do
50
+ implementation = lambda {}
51
+ RSpec.world.shared_example_groups.should_receive(:[]=).with("name", implementation)
52
+ send(method_name, "name", :foo => :bar, &implementation)
53
+ end
54
+
55
+ it "delegates extend on configuration" do
56
+ implementation = Proc.new { def bar; 'bar'; end }
57
+ send(method_name, "name", :foo => :bar, &implementation)
58
+ a = RSpec.configuration.include_or_extend_modules.first
59
+ a[0].should eq(:extend)
60
+ Class.new.extend(a[1]).new.bar.should eq('bar')
61
+ a[2].should eq(:foo => :bar)
40
62
  end
41
63
  end
42
- group = ExampleGroup.describe('group') { include Cornucopia }
43
- phantom_group = group.children.first
44
- phantom_group.description.should eql("")
45
- phantom_group.metadata[:shared_group_name].should eql('Cornucopia')
46
- phantom_group.examples.length.should == 1
47
- phantom_group.examples.first.metadata[:description].should == "is plentiful"
48
64
  end
49
65
  end
50
66
 
@@ -148,5 +164,25 @@ module RSpec::Core
148
164
  end.should raise_error(/Could not find shared example group named/)
149
165
  end
150
166
  end
167
+
168
+ describe "#share_as" do
169
+ it "is exposed to the global namespace" do
170
+ Kernel.should respond_to("share_as")
171
+ end
172
+
173
+ it "adds examples to current example_group using include", :compat => 'rspec-1.2' do
174
+ share_as('Cornucopia') do
175
+ it "is plentiful" do
176
+ 5.should == 4
177
+ end
178
+ end
179
+ group = ExampleGroup.describe('group') { include Cornucopia }
180
+ phantom_group = group.children.first
181
+ phantom_group.description.should eql("")
182
+ phantom_group.metadata[:shared_group_name].should eql('Cornucopia')
183
+ phantom_group.examples.length.should == 1
184
+ phantom_group.examples.first.metadata[:description].should == "is plentiful"
185
+ end
186
+ end
151
187
  end
152
188
  end
@@ -3,6 +3,7 @@ require 'spec_helper'
3
3
  module RSpec::Core
4
4
 
5
5
  describe Subject do
6
+ before(:each) { RSpec.configuration.configure_expectation_framework }
6
7
 
7
8
  describe "implicit subject" do
8
9
  describe "with a class" do
@@ -134,27 +135,47 @@ module RSpec::Core
134
135
  its("name.size.class") { should eq(Fixnum) }
135
136
  end
136
137
 
137
- context "when it is a Hash" do
138
+ context "when it responds to #[]" do
138
139
  subject do
139
- { :attribute => 'value',
140
- 'another_attribute' => 'another_value' }
141
- end
142
- its([:attribute]) { should == 'value' }
143
- its([:attribute]) { should_not == 'another_value' }
144
- its([:another_attribute]) { should == 'another_value' }
145
- its([:another_attribute]) { should_not == 'value' }
146
- its(:keys) { should =~ ['another_attribute', :attribute] }
140
+ Class.new do
141
+ def [](*objects)
142
+ objects.map do |object|
143
+ "#{object.class}: #{object.to_s}"
144
+ end.join("; ")
145
+ end
146
+
147
+ def name
148
+ "George"
149
+ end
150
+ end.new
151
+ end
152
+ its([:a]) { should == 'Symbol: a' }
153
+ its(['a']) { should == 'String: a' }
154
+ its([:b, 'c', 4]) { should == 'Symbol: b; String: c; Fixnum: 4' }
155
+ its(:name) { should = "George" }
147
156
  context "when referring to an attribute without the proper array syntax" do
148
157
  context "it raises an error" do
149
- its(:attribute) do
158
+ its(:age) do
150
159
  expect do
151
- should eq('value')
160
+ should eq(64)
152
161
  end.to raise_error(NoMethodError)
153
162
  end
154
163
  end
155
164
  end
156
165
  end
157
166
 
167
+ context "when it does not respond to #[]" do
168
+ subject { Object.new }
169
+
170
+ context "it raises an error" do
171
+ its([:a]) do
172
+ expect do
173
+ should == 'Symbol: a'
174
+ end.to raise_error(NoMethodError)
175
+ end
176
+ end
177
+ end
178
+
158
179
  context "calling and overriding super" do
159
180
  it "calls to the subject defined in the parent group" do
160
181
  group = ExampleGroup.describe(Array) do
@@ -5,8 +5,9 @@ class Foo; end
5
5
 
6
6
  module RSpec::Core
7
7
 
8
- describe World do
9
- let(:world) { RSpec::Core::World.new }
8
+ describe RSpec::Core::World do
9
+ let(:configuration) { RSpec::Core::Configuration.new }
10
+ let(:world) { RSpec::Core::World.new(configuration) }
10
11
 
11
12
  describe "#example_groups" do
12
13
  it "contains all registered example groups" do
@@ -138,7 +139,15 @@ module RSpec::Core
138
139
  let(:group) do
139
140
  RSpec::Core::ExampleGroup.describe("group") do
140
141
 
141
- example("example") {}
142
+ example("example") {}
143
+
144
+ end
145
+ end
146
+
147
+ let(:second_group) do
148
+ RSpec::Core::ExampleGroup.describe("second_group") do
149
+
150
+ example("second_example") {}
142
151
 
143
152
  end
144
153
  end
@@ -146,29 +155,152 @@ module RSpec::Core
146
155
  let(:group_declaration_line) { group.metadata[:example_group][:line_number] }
147
156
  let(:example_declaration_line) { group_declaration_line + 2 }
148
157
 
149
- before { world.register(group) }
158
+ context "with one example" do
159
+ before { world.register(group) }
160
+
161
+ it "returns nil if no example or group precedes the line" do
162
+ world.preceding_declaration_line(group_declaration_line - 1).should be_nil
163
+ end
164
+
165
+ it "returns the argument line number if a group starts on that line" do
166
+ world.preceding_declaration_line(group_declaration_line).should eq(group_declaration_line)
167
+ end
168
+
169
+ it "returns the argument line number if an example starts on that line" do
170
+ world.preceding_declaration_line(example_declaration_line).should eq(example_declaration_line)
171
+ end
172
+
173
+ it "returns line number of a group that immediately precedes the argument line" do
174
+ world.preceding_declaration_line(group_declaration_line + 1).should eq(group_declaration_line)
175
+ end
150
176
 
151
- it "returns nil if no example or group precedes the line" do
152
- world.preceding_declaration_line(group_declaration_line - 1).should be_nil
177
+ it "returns line number of an example that immediately precedes the argument line" do
178
+ world.preceding_declaration_line(example_declaration_line + 1).should eq(example_declaration_line)
179
+ end
153
180
  end
154
181
 
155
- it "returns the argument line number if a group starts on that line" do
156
- world.preceding_declaration_line(group_declaration_line).should eq(group_declaration_line)
182
+ context "with two exaples and the second example is registre first" do
183
+ let(:second_group_declaration_line) { second_group.metadata[:example_group][:line_number] }
184
+
185
+ before do
186
+ world.register(second_group)
187
+ world.register(group)
188
+ end
189
+
190
+ it 'return line number of group if a group start on that line' do
191
+ world.preceding_declaration_line(second_group_declaration_line).should eq(second_group_declaration_line)
192
+ end
157
193
  end
194
+ end
195
+
196
+ describe "#announce_filters" do
197
+ let(:reporter) { double('reporter').as_null_object }
198
+ before { world.stub(:reporter) { reporter } }
199
+
200
+ context "with no examples" do
201
+ before { world.stub(:example_count) { 0 } }
202
+
203
+ context "with no filters" do
204
+ it "announces" do
205
+ reporter.should_receive(:message).
206
+ with("No examples found.")
207
+ world.announce_filters
208
+ end
209
+ end
210
+
211
+ context "with an inclusion filter" do
212
+ it "announces" do
213
+ configuration.inclusion_filter = { :foo => 'bar' }
214
+ reporter.should_receive(:message).
215
+ with("No examples matched #{{ :foo => 'bar' }.inspect}.")
216
+ world.announce_filters
217
+ end
218
+ end
158
219
 
159
- it "returns the argument line number if an example starts on that line" do
160
- world.preceding_declaration_line(example_declaration_line).should eq(example_declaration_line)
220
+ context "with an inclusion filter and run_all_when_everything_filtered" do
221
+ it "announces" do
222
+ configuration.stub(:run_all_when_everything_filtered?) { true }
223
+ configuration.inclusion_filter = { :foo => 'bar' }
224
+ reporter.should_receive(:message).
225
+ with("No examples matched #{{ :foo => 'bar' }.inspect}. Running all.")
226
+ world.announce_filters
227
+ end
228
+ end
229
+
230
+ context "with an exclusion filter" do
231
+ it "announces" do
232
+ configuration.exclusion_filter = { :foo => 'bar' }
233
+ reporter.should_receive(:message).
234
+ with("No examples were matched. Perhaps #{{ :foo => 'bar' }.inspect} is excluding everything?")
235
+ world.announce_filters
236
+ end
237
+ end
161
238
  end
162
239
 
163
- it "returns line number of a group that immediately precedes the argument line" do
164
- world.preceding_declaration_line(group_declaration_line + 1).should eq(group_declaration_line)
240
+ context "with examples" do
241
+ before { world.stub(:example_count) { 1 } }
242
+
243
+ context "with no filters" do
244
+ it "does not announce" do
245
+ reporter.should_not_receive(:message)
246
+ world.announce_filters
247
+ end
248
+ end
165
249
  end
250
+ end
166
251
 
167
- it "returns line number of an example that immediately precedes the argument line" do
168
- world.preceding_declaration_line(example_declaration_line + 1).should eq(example_declaration_line)
252
+ describe "#inclusion_filter" do
253
+ describe "#description" do
254
+ it 'cleans up the description' do
255
+ # check the assumptions of this example
256
+ project_dir = File.expand_path('.')
257
+ lambda { }.inspect.should include(project_dir)
258
+ lambda { }.inspect.should include('0x')
259
+ lambda { }.inspect.should include(' (lambda)') if RUBY_VERSION > '1.9'
260
+
261
+ configuration.filter_run :foo => lambda { }
262
+ world.inclusion_filter.description.should_not include('0x')
263
+ world.inclusion_filter.description.should_not include(project_dir)
264
+ world.inclusion_filter.description.should_not include(' (lambda)')
265
+ end
169
266
  end
170
267
  end
171
268
 
172
- end
269
+ describe "#exclusion_filter" do
270
+ describe "#description" do
271
+ it 'returns `{}` when it only contains the default filters' do
272
+ world.exclusion_filter.description.should == {}.inspect
273
+ end
274
+
275
+ it 'includes other filters' do
276
+ configuration.exclusion_filter[:foo] = :bar
277
+ world.exclusion_filter.description.should == { :foo => :bar }.inspect
278
+ end
173
279
 
280
+ it 'includes an overriden :if filter' do
281
+ configuration.exclusion_filter[:if] = :custom_filter
282
+ world.exclusion_filter.description.should == { :if => :custom_filter }.inspect
283
+ end
284
+
285
+ it 'includes an overriden :unless filter' do
286
+ configuration.exclusion_filter[:unless] = :custom_filter
287
+ world.exclusion_filter.description.should == { :unless => :custom_filter }.inspect
288
+ end
289
+
290
+ it 'cleans up the description' do
291
+ # check the assumptions of this example
292
+ project_dir = File.expand_path('.')
293
+ lambda { }.inspect.should include(project_dir)
294
+ lambda { }.inspect.should include('0x')
295
+ lambda { }.inspect.should include(' (lambda)') if RUBY_VERSION > '1.9'
296
+
297
+ configuration.exclusion_filter[:foo] = lambda { }
298
+ configuration.filter_run_excluding :bar => lambda { }
299
+ world.exclusion_filter.description.should_not include('0x')
300
+ world.exclusion_filter.description.should_not include(project_dir)
301
+ world.exclusion_filter.description.should_not include(' (lambda)')
302
+ end
303
+ end
304
+ end
305
+ end
174
306
  end
@@ -11,6 +11,13 @@ describe RSpec::Core do
11
11
  end
12
12
 
13
13
  describe "#configure" do
14
+ around(:each) do |example|
15
+ RSpec.allowing_configure_warning(&example)
16
+ end
17
+
18
+ before(:each) do
19
+ RSpec.stub(:warn)
20
+ end
14
21
 
15
22
  it "yields the current configuration" do
16
23
  RSpec.configure do |config|
@@ -18,6 +25,27 @@ describe RSpec::Core do
18
25
  end
19
26
  end
20
27
 
28
+ context "when an example group has already been defined" do
29
+ before(:each) do
30
+ RSpec.world.stub(:example_groups).and_return([double.as_null_object])
31
+ end
32
+
33
+ it "prints a deprecation warning" do
34
+ RSpec.should_receive(:warn).with(/configuration should happen before the first example group/)
35
+ RSpec.configure { |c| }
36
+ end
37
+ end
38
+
39
+ context "when no examples have been defined yet" do
40
+ before(:each) do
41
+ RSpec.world.stub(:example_groups).and_return([])
42
+ end
43
+
44
+ it "does not print a deprecation warning" do
45
+ RSpec.should_not_receive(:warn)
46
+ RSpec.configure { |c| }
47
+ end
48
+ end
21
49
  end
22
50
 
23
51
  describe "#world" do
data/spec/spec_helper.rb CHANGED
@@ -15,7 +15,6 @@ def sandboxed(&block)
15
15
  @orig_config = RSpec.configuration
16
16
  @orig_world = RSpec.world
17
17
  new_config = RSpec::Core::Configuration.new
18
- new_config.include(RSpec::Matchers)
19
18
  new_world = RSpec::Core::World.new(new_config)
20
19
  RSpec.instance_variable_set(:@configuration, new_config)
21
20
  RSpec.instance_variable_set(:@world, new_world)
@@ -51,6 +50,27 @@ def in_editor?
51
50
  ENV.has_key?('TM_MODE') || ENV.has_key?('EMACS') || ENV.has_key?('VIM')
52
51
  end
53
52
 
53
+ class << RSpec
54
+ alias_method :original_warn_about_deprecated_configure, :warn_about_deprecated_configure
55
+
56
+ def warn_about_deprecated_configure
57
+ # no-op: in our specs we don't want to see the warning.
58
+ end
59
+
60
+ alias_method :null_warn_about_deprecated_configure, :warn_about_deprecated_configure
61
+
62
+ def allowing_configure_warning
63
+ (class << self; self; end).class_eval do
64
+ alias_method :warn_about_deprecated_configure, :original_warn_about_deprecated_configure
65
+ begin
66
+ yield
67
+ ensure
68
+ alias_method :warn_about_deprecated_configure, :null_warn_about_deprecated_configure
69
+ end
70
+ end
71
+ end
72
+ end
73
+
54
74
  RSpec.configure do |c|
55
75
  c.color_enabled = !in_editor?
56
76
  c.filter_run :focus => true
@@ -58,7 +78,7 @@ RSpec.configure do |c|
58
78
  c.filter_run_excluding :ruby => lambda {|version|
59
79
  case version.to_s
60
80
  when "!jruby"
61
- RUBY_ENGINE != "jruby"
81
+ RUBY_ENGINE == "jruby"
62
82
  when /^> (.*)/
63
83
  !(RUBY_VERSION.to_s > $1)
64
84
  else
@@ -20,25 +20,56 @@ RSpec::Matchers.define :map_specs do |specs|
20
20
  end
21
21
  end
22
22
 
23
- RSpec::Matchers.define :have_interface_for do |method|
24
- match do |object|
25
- @method = method
26
- @object = object
27
- object.respond_to?(method) && actual_arity == @expected_arity
23
+ RSpec::Matchers.define :be_pending_with do |message|
24
+ match do |example|
25
+ example.metadata[:pending] && example.metadata[:execution_result][:pending_message] == message
28
26
  end
29
27
 
30
- chain :with do |arity|
31
- @expected_arity = arity
28
+ failure_message_for_should do |example|
29
+ "expected example to pending with #{message.inspect}, got #{example.metadata[:execution_result][:pending_message].inspect}"
32
30
  end
31
+ end
33
32
 
34
- chain(:argument) {}
35
- chain(:arguments) {}
33
+ RSpec::Matchers.define :fail_with do |exception_klass|
34
+ match do |example|
35
+ failure_reason(example, exception_klass).nil?
36
+ end
36
37
 
37
- failure_message_for_should do
38
- "#{@object} should have method :#{@method} with #{@expected_arity} argument(s), but it had #{actual_arity}"
38
+ failure_message_for_should do |example|
39
+ "expected example to fail with a #{exception_klass} exception, but #{failure_reason(example, exception_klass)}"
40
+ end
41
+
42
+ def failure_reason(example, exception_klass)
43
+ result = example.metadata[:execution_result]
44
+ case
45
+ when example.metadata[:pending] then "was pending"
46
+ when result[:status] != 'failed' then result[:status]
47
+ when !result[:exception].is_a?(exception_klass) then "failed with a #{result[:exception].class}"
48
+ else nil
49
+ end
50
+ end
51
+ end
52
+
53
+ RSpec::Matchers.define :pass do
54
+ match do |example|
55
+ failure_reason(example).nil?
56
+ end
57
+
58
+ failure_message_for_should do |example|
59
+ "expected example to pass, but #{failure_reason(example)}"
39
60
  end
40
61
 
41
- def actual_arity
42
- @object.method(@method).arity
62
+ def failure_reason(example)
63
+ result = example.metadata[:execution_result]
64
+ case
65
+ when example.metadata[:pending] then "was pending"
66
+ when result[:status] != 'passed' then result[:status]
67
+ else nil
68
+ end
43
69
  end
44
70
  end
71
+
72
+ RSpec::Matchers.module_eval do
73
+ alias have_failed_with fail_with
74
+ alias have_passed pass
75
+ end
@@ -0,0 +1,41 @@
1
+ shared_examples_for "metadata hash builder" do
2
+ context "when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true" do
3
+ let(:hash) { metadata_hash(:foo, :bar, :bazz => 23) }
4
+
5
+ before(:each) do
6
+ RSpec.configure { |c| c.treat_symbols_as_metadata_keys_with_true_values = true }
7
+ end
8
+
9
+ it 'treats symbols as metadata keys with a true value' do
10
+ hash[:foo].should == true
11
+ hash[:bar].should == true
12
+ end
13
+
14
+ it 'still processes hash values normally' do
15
+ hash[:bazz].should == 23
16
+ end
17
+ end
18
+
19
+ context "when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false" do
20
+ let(:warning_receiver) { Kernel }
21
+
22
+ before(:each) do
23
+ RSpec.configure { |c| c.treat_symbols_as_metadata_keys_with_true_values = false }
24
+ warning_receiver.stub(:warn)
25
+ end
26
+
27
+ it 'prints a deprecation warning about any symbols given as arguments' do
28
+ warning_receiver.should_receive(:warn).with(/In RSpec 3, these symbols will be treated as metadata keys/)
29
+ metadata_hash(:foo, :bar, :key => 'value')
30
+ end
31
+
32
+ it 'does not treat symbols as metadata keys' do
33
+ metadata_hash(:foo, :bar, :key => 'value').should_not include(:foo, :bar)
34
+ end
35
+
36
+ it 'does not print a warning if there are no symbol arguments' do
37
+ warning_receiver.should_not_receive(:warn)
38
+ metadata_hash(:foo => 23, :bar => 17)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,44 @@
1
+ shared_context "spec files" do
2
+ def failing_spec_filename
3
+ @failing_spec_filename ||= File.expand_path(File.dirname(__FILE__)) + "/_failing_spec.rb"
4
+ end
5
+
6
+ def passing_spec_filename
7
+ @passing_spec_filename ||= File.expand_path(File.dirname(__FILE__)) + "/_passing_spec.rb"
8
+ end
9
+
10
+ def create_passing_spec_file
11
+ File.open(passing_spec_filename, 'w') do |f|
12
+ f.write %q{
13
+ describe "passing spec" do
14
+ it "passes" do
15
+ 1.should eq(1)
16
+ end
17
+ end
18
+ }
19
+ end
20
+ end
21
+
22
+ def create_failing_spec_file
23
+ File.open(failing_spec_filename, 'w') do |f|
24
+ f.write %q{
25
+ describe "failing spec" do
26
+ it "fails" do
27
+ 1.should eq(2)
28
+ end
29
+ end
30
+ }
31
+ end
32
+ end
33
+
34
+ before(:all) do
35
+ create_passing_spec_file
36
+ create_failing_spec_file
37
+ end
38
+
39
+ after(:all) do
40
+ File.delete(passing_spec_filename)
41
+ File.delete(failing_spec_filename)
42
+ end
43
+
44
+ end