rspec-core 2.5.2 → 2.6.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. data/.travis.yml +7 -0
  2. data/Gemfile +10 -13
  3. data/README.md +4 -1
  4. data/Rakefile +29 -12
  5. data/cucumber.yml +1 -1
  6. data/features/.nav +10 -4
  7. data/features/Autotest.md +31 -7
  8. data/features/Changelog.md +36 -6
  9. data/features/command_line/configure.feature +2 -2
  10. data/features/command_line/example_name_option.feature +10 -10
  11. data/features/command_line/exit_status.feature +4 -4
  12. data/features/command_line/format_option.feature +4 -4
  13. data/features/command_line/line_number_appended_to_path.feature +11 -11
  14. data/features/command_line/line_number_option.feature +2 -2
  15. data/features/command_line/rake_task.feature +3 -3
  16. data/features/command_line/tag.feature +26 -10
  17. data/features/configuration/alias_example_to.feature +48 -0
  18. data/features/configuration/custom_settings.feature +3 -3
  19. data/features/configuration/fail_fast.feature +3 -3
  20. data/features/configuration/read_options_from_file.feature +4 -4
  21. data/features/example_groups/basic_structure.feature +11 -15
  22. data/features/example_groups/shared_context.feature +74 -0
  23. data/features/example_groups/shared_example_group.feature +21 -17
  24. data/features/expectation_framework_integration/configure_expectation_framework.feature +15 -4
  25. data/features/filtering/exclusion_filters.feature +28 -4
  26. data/features/filtering/{implicit_filters.feature → if_and_unless.feature} +9 -7
  27. data/features/filtering/inclusion_filters.feature +26 -3
  28. data/features/filtering/run_all_when_everything_filtered.feature +1 -1
  29. data/features/formatters/custom_formatter.feature +1 -1
  30. data/features/formatters/text_formatter.feature +45 -0
  31. data/features/helper_methods/arbitrary_methods.feature +2 -2
  32. data/features/helper_methods/let.feature +2 -2
  33. data/features/helper_methods/modules.feature +149 -0
  34. data/features/hooks/around_hooks.feature +11 -11
  35. data/features/hooks/before_and_after_hooks.feature +15 -19
  36. data/features/hooks/filtering.feature +160 -124
  37. data/features/metadata/current_example.feature +17 -0
  38. data/features/metadata/described_class.feature +2 -2
  39. data/features/metadata/user_defined.feature +111 -0
  40. data/features/mock_framework_integration/use_any_framework.feature +1 -1
  41. data/features/mock_framework_integration/use_flexmock.feature +83 -10
  42. data/features/mock_framework_integration/use_mocha.feature +84 -10
  43. data/features/mock_framework_integration/use_rr.feature +85 -10
  44. data/features/mock_framework_integration/use_rspec.feature +84 -10
  45. data/features/pending/pending_examples.feature +8 -8
  46. data/features/spec_files/arbitrary_file_suffix.feature +1 -1
  47. data/features/step_definitions/additional_cli_steps.rb +11 -1
  48. data/features/subject/attribute_of_subject.feature +24 -4
  49. data/features/subject/explicit_subject.feature +5 -5
  50. data/features/subject/implicit_receiver.feature +2 -2
  51. data/features/subject/implicit_subject.feature +2 -2
  52. data/features/support/env.rb +6 -1
  53. data/lib/rspec/core.rb +22 -0
  54. data/lib/rspec/core/backward_compatibility.rb +12 -2
  55. data/lib/rspec/core/command_line.rb +1 -4
  56. data/lib/rspec/core/configuration.rb +25 -17
  57. data/lib/rspec/core/configuration_options.rb +6 -23
  58. data/lib/rspec/core/drb_command_line.rb +5 -11
  59. data/lib/rspec/core/example.rb +29 -21
  60. data/lib/rspec/core/example_group.rb +36 -4
  61. data/lib/rspec/core/formatters/base_formatter.rb +6 -0
  62. data/lib/rspec/core/formatters/base_text_formatter.rb +1 -1
  63. data/lib/rspec/core/formatters/helpers.rb +0 -4
  64. data/lib/rspec/core/hooks.rb +14 -4
  65. data/lib/rspec/core/metadata.rb +1 -1
  66. data/lib/rspec/core/metadata_hash_builder.rb +93 -0
  67. data/lib/rspec/core/mocking/with_flexmock.rb +2 -0
  68. data/lib/rspec/core/mocking/with_mocha.rb +2 -0
  69. data/lib/rspec/core/mocking/with_rr.rb +2 -0
  70. data/lib/rspec/core/mocking/with_rspec.rb +3 -1
  71. data/lib/rspec/core/option_parser.rb +5 -2
  72. data/lib/rspec/core/pending.rb +10 -3
  73. data/lib/rspec/core/reporter.rb +2 -2
  74. data/lib/rspec/core/runner.rb +7 -1
  75. data/lib/rspec/core/shared_example_group.rb +18 -4
  76. data/lib/rspec/core/subject.rb +4 -6
  77. data/lib/rspec/core/version.rb +1 -1
  78. data/lib/rspec/core/world.rb +16 -4
  79. data/rspec-core.gemspec +4 -3
  80. data/spec.txt +1126 -0
  81. data/spec/autotest/failed_results_re_spec.rb +2 -2
  82. data/spec/rspec/core/command_line_spec.rb +0 -2
  83. data/spec/rspec/core/configuration_spec.rb +84 -1
  84. data/spec/rspec/core/deprecations_spec.rb +21 -0
  85. data/spec/rspec/core/drb_command_line_spec.rb +3 -11
  86. data/spec/rspec/core/example_group_spec.rb +213 -56
  87. data/spec/rspec/core/example_spec.rb +110 -0
  88. data/spec/rspec/core/formatters/base_formatter_spec.rb +23 -2
  89. data/spec/rspec/core/formatters/base_text_formatter_spec.rb +9 -0
  90. data/spec/rspec/core/formatters/helpers_spec.rb +1 -1
  91. data/spec/rspec/core/formatters/html_formatted-1.8.6.html +5 -5
  92. data/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html +8 -10
  93. data/spec/rspec/core/formatters/html_formatted-1.8.7.html +5 -5
  94. data/spec/rspec/core/formatters/html_formatted-1.9.1.html +5 -5
  95. data/spec/rspec/core/formatters/html_formatted-1.9.2.html +5 -5
  96. data/spec/rspec/core/formatters/progress_formatter_spec.rb +0 -1
  97. data/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html +5 -5
  98. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html +8 -10
  99. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html +5 -5
  100. data/spec/rspec/core/formatters/text_mate_formatted-1.9.1.html +5 -5
  101. data/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html +5 -5
  102. data/spec/rspec/core/hooks_spec.rb +86 -0
  103. data/spec/rspec/core/metadata_spec.rb +7 -7
  104. data/spec/rspec/core/option_parser_spec.rb +8 -0
  105. data/spec/rspec/core/pending_example_spec.rb +12 -51
  106. data/spec/rspec/core/reporter_spec.rb +19 -3
  107. data/spec/rspec/core/resources/formatter_specs.rb +7 -1
  108. data/spec/rspec/core/rspec_matchers_spec.rb +45 -0
  109. data/spec/rspec/core/runner_spec.rb +35 -10
  110. data/spec/rspec/core/shared_example_group_spec.rb +57 -21
  111. data/spec/rspec/core/subject_spec.rb +32 -11
  112. data/spec/rspec/core/world_spec.rb +38 -15
  113. data/spec/rspec/core_spec.rb +28 -0
  114. data/spec/spec_helper.rb +22 -2
  115. data/spec/support/matchers.rb +44 -13
  116. data/spec/support/shared_example_groups.rb +41 -0
  117. metadata +39 -16
@@ -240,13 +240,13 @@ module RSpec
240
240
 
241
241
  %w[# . ::].each do |char|
242
242
  context "with a nested description starting with #{char}" do
243
- it "removes the space" do
244
- parent = Metadata.new
245
- parent.process("Object")
246
- child = Metadata.new(parent)
247
- child.process("#{char}method")
248
- child[:example_group][:full_description].should eq("Object#{char}method")
249
- end
243
+ it "removes the space" do
244
+ parent = Metadata.new
245
+ parent.process("Object")
246
+ child = Metadata.new(parent)
247
+ child.process("#{char}method")
248
+ child[:example_group][:full_description].should eq("Object#{char}method")
249
+ end
250
250
  end
251
251
  end
252
252
  end
@@ -71,5 +71,13 @@ module RSpec::Core
71
71
  end
72
72
  end
73
73
  end
74
+
75
+ describe "--example" do
76
+ it "escapes the arg" do
77
+ options = Parser.parse!(["--example", "this (and that)"])
78
+ "this (and that)".should match(options[:full_description])
79
+ end
80
+ end
81
+
74
82
  end
75
83
  end
@@ -1,54 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- RSpec::Matchers.define :be_pending_with do |message|
4
- match do |example|
5
- example.metadata[:pending] && example.metadata[:execution_result][:pending_message] == message
6
- end
7
-
8
- failure_message_for_should do |example|
9
- "expected example to pending with #{message.inspect}, got #{example.metadata[:execution_result][:pending_message].inspect}"
10
- end
11
- end
12
-
13
- RSpec::Matchers.define :fail_with do |exception_klass|
14
- match do |example|
15
- failure_reason(example, exception_klass).nil?
16
- end
17
-
18
- failure_message_for_should do |example|
19
- "expected example to fail with a #{exception_klass} exception, but #{failure_reason(example, exception_klass)}"
20
- end
21
-
22
- def failure_reason(example, exception_klass)
23
- result = example.metadata[:execution_result]
24
- case
25
- when example.metadata[:pending] then "was pending"
26
- when result[:status] != 'failed' then result[:status]
27
- when !result[:exception].is_a?(exception_klass) then "failed with a #{result[:exception].class}"
28
- else nil
29
- end
30
- end
31
- end
32
-
33
- RSpec::Matchers.define :pass do
34
- match do |example|
35
- failure_reason(example).nil?
36
- end
37
-
38
- failure_message_for_should do |example|
39
- "expected example to pass, but #{failure_reason(example)}"
40
- end
41
-
42
- def failure_reason(example)
43
- result = example.metadata[:execution_result]
44
- case
45
- when example.metadata[:pending] then "was pending"
46
- when result[:status] != 'passed' then result[:status]
47
- else nil
48
- end
49
- end
50
- end
51
-
52
3
  describe "an example" do
53
4
  context "with no block" do
54
5
  it "is listed as pending with 'Not Yet Implemented'" do
@@ -121,10 +72,10 @@ describe "an example" do
121
72
  end
122
73
 
123
74
  context "with a block" do
124
- def run_example(*pending_args)
75
+ def run_example(*pending_args, &block)
125
76
  group = RSpec::Core::ExampleGroup.describe('group') do
126
77
  it "does something" do
127
- pending(*pending_args) { yield }
78
+ pending(*pending_args) { block.call if block }
128
79
  end
129
80
  end
130
81
  example = group.examples.first
@@ -182,6 +133,16 @@ describe "an example" do
182
133
  end
183
134
  end
184
135
 
136
+ context "that fails due to a failed message expectation" do
137
+ def run_example(*pending_args)
138
+ super(*pending_args) { "foo".should_receive(:bar) }
139
+ end
140
+
141
+ it "passes" do
142
+ run_example("just because").should be_pending
143
+ end
144
+ end
145
+
185
146
  context "that passes" do
186
147
  def run_example(*pending_args)
187
148
  super(*pending_args) { 3.should == 3 }
@@ -30,13 +30,17 @@ module RSpec::Core
30
30
  it "passes example_group_started and example_group_finished messages to that formatter in that order" do
31
31
  order = []
32
32
 
33
- formatter = stub("formatter")
33
+ formatter = stub("formatter").as_null_object
34
34
  formatter.stub(:example_group_started) { |group| order << "Started: #{group.description}" }
35
35
  formatter.stub(:example_group_finished) { |group| order << "Finished: #{group.description}" }
36
36
 
37
37
  group = ExampleGroup.describe("root")
38
- group.describe("context 1")
39
- group.describe("context 2")
38
+ group.describe("context 1") do
39
+ example("ignore") {}
40
+ end
41
+ group.describe("context 2") do
42
+ example("ignore") {}
43
+ end
40
44
 
41
45
  group.run(Reporter.new(formatter))
42
46
 
@@ -51,6 +55,18 @@ module RSpec::Core
51
55
  end
52
56
  end
53
57
 
58
+ context "given an example group with no examples" do
59
+ it "does not pass example_group_started or example_group_finished to formatter" do
60
+ formatter = stub("formatter").as_null_object
61
+ formatter.should_not_receive(:example_group_started)
62
+ formatter.should_not_receive(:example_group_finished)
63
+
64
+ group = ExampleGroup.describe("root")
65
+
66
+ group.run(Reporter.new(formatter))
67
+ end
68
+ end
69
+
54
70
  context "given multiple formatters" do
55
71
  it "passes messages to all formatters" do
56
72
  formatters = [double("formatter"), double("formatter")]
@@ -48,7 +48,13 @@ describe "a failing spec with odd backtraces" do
48
48
  ["/foo.html.erb:1:in `<main>': foo (RuntimeError)",
49
49
  " from /lib/ruby/1.9.1/erb.rb:753:in `eval'"]
50
50
  end
51
-
51
+
52
+ def e.message
53
+ # Redefining message steps around this behaviour
54
+ # on JRuby: http://jira.codehaus.org/browse/JRUBY-5637
55
+ self.class.name
56
+ end
57
+
52
58
  raise e
53
59
  end
54
60
  end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ module RSpec::Matchers
4
+ def __method_with_super
5
+ super
6
+ end
7
+
8
+ module ModThatIncludesMatchers
9
+ include RSpec::Matchers
10
+ end
11
+
12
+ RSpec.configure do |c|
13
+ c.include RSpec::Matchers, :include_rspec_matchers => true
14
+ c.include ModThatIncludesMatchers, :include_mod_that_includes_rspec_matchers => true
15
+ end
16
+
17
+ describe self do
18
+ shared_examples_for "a normal module with a method that supers" do
19
+ it "raises the expected error (and not SystemStackError)" do
20
+ expect { __method_with_super }.to raise_error(NoMethodError) # there is no __method_with_super in an ancestor
21
+ end
22
+ end
23
+
24
+ it_behaves_like "a normal module with a method that supers"
25
+
26
+ context "when RSpec::Matchers has been included in an example group" do
27
+ include RSpec::Matchers
28
+ it_behaves_like "a normal module with a method that supers"
29
+ end
30
+
31
+ context "when a module that includes RSpec::Matchers has been included in an example group" do
32
+ include RSpec::Matchers::ModThatIncludesMatchers
33
+ it_behaves_like "a normal module with a method that supers"
34
+ end
35
+
36
+ context "when RSpec::Matchers is included via configuration", :include_rspec_matchers => true do
37
+ it_behaves_like "a normal module with a method that supers"
38
+ end
39
+
40
+ context "when RSpec::Matchers is included in a module that is included via configuration", :include_mod_that_includes_rspec_matchers => true do
41
+ it_behaves_like "a normal module with a method that supers"
42
+ end
43
+ end
44
+ end
45
+
@@ -22,24 +22,49 @@ module RSpec::Core
22
22
 
23
23
  describe "#run" do
24
24
  context "with --drb or -X" do
25
- before(:each) do
26
- @err = @out = StringIO.new
25
+ let(:err) { StringIO.new }
26
+ let(:out) { StringIO.new }
27
27
 
28
+ before(:each) do
28
29
  @options = RSpec::Core::ConfigurationOptions.new(%w[--drb --drb-port 8181 --color])
29
30
  RSpec::Core::ConfigurationOptions.stub(:new) { @options }
31
+ end
30
32
 
31
- @drb_proxy = double(RSpec::Core::DRbCommandLine, :run => true)
32
- RSpec::Core::DRbCommandLine.stub(:new => @drb_proxy)
33
+ def run_specs
34
+ RSpec::Core::Runner.run(%w[ --drb ], err, out)
33
35
  end
34
36
 
35
- it "builds a DRbCommandLine" do
36
- RSpec::Core::DRbCommandLine.should_receive(:new)
37
- RSpec::Core::Runner.run(%w[ --drb ], @err, @out)
37
+ context 'and a DRb server is running' do
38
+ it "builds a DRbCommandLine and runs the specs" do
39
+ drb_proxy = double(RSpec::Core::DRbCommandLine, :run => true)
40
+ drb_proxy.should_receive(:run).with(err, out)
41
+
42
+ RSpec::Core::DRbCommandLine.should_receive(:new).and_return(drb_proxy)
43
+
44
+ run_specs
45
+ end
38
46
  end
39
47
 
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)
48
+ context 'and a DRb server is not running' do
49
+ before(:each) do
50
+ RSpec::Core::DRbCommandLine.should_receive(:new).and_raise(DRb::DRbConnError)
51
+ end
52
+
53
+ it "outputs a message" do
54
+ err.should_receive(:puts).with(
55
+ "No DRb server is running. Running in local process instead ..."
56
+ )
57
+ run_specs
58
+ end
59
+
60
+ it "builds a CommandLine and runs the specs" do
61
+ process_proxy = double(RSpec::Core::CommandLine, :run => true)
62
+ process_proxy.should_receive(:run).with(err, out)
63
+
64
+ RSpec::Core::CommandLine.should_receive(:new).and_return(process_proxy)
65
+
66
+ run_specs
67
+ end
43
68
  end
44
69
  end
45
70
  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