rspec-core 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/Gemfile +16 -11
  2. data/History.markdown +22 -0
  3. data/License.txt +2 -1
  4. data/{README.markdown → README.md} +11 -3
  5. data/Rakefile +1 -0
  6. data/Upgrade.markdown +35 -2
  7. data/features/hooks/around_hooks.feature +18 -2
  8. data/lib/rspec/core/configuration.rb +38 -36
  9. data/lib/rspec/core/configuration_options.rb +2 -1
  10. data/lib/rspec/core/deprecation.rb +1 -1
  11. data/lib/rspec/core/example.rb +19 -9
  12. data/lib/rspec/core/example_group.rb +14 -26
  13. data/lib/rspec/core/extensions/kernel.rb +23 -3
  14. data/lib/rspec/core/formatters/base_text_formatter.rb +43 -30
  15. data/lib/rspec/core/formatters/documentation_formatter.rb +1 -1
  16. data/lib/rspec/core/formatters/html_formatter.rb +10 -8
  17. data/lib/rspec/core/hooks.rb +2 -2
  18. data/lib/rspec/core/metadata.rb +46 -34
  19. data/lib/rspec/core/option_parser.rb +2 -2
  20. data/lib/rspec/core/rake_task.rb +1 -1
  21. data/lib/rspec/core/ruby_project.rb +2 -2
  22. data/lib/rspec/core/runner.rb +2 -2
  23. data/lib/rspec/core/subject.rb +4 -3
  24. data/lib/rspec/core/version.rb +1 -1
  25. data/rspec-core.gemspec +1 -1
  26. data/spec/rspec/core/configuration_options_spec.rb +7 -5
  27. data/spec/rspec/core/configuration_spec.rb +58 -69
  28. data/spec/rspec/core/example_group_spec.rb +22 -7
  29. data/spec/rspec/core/example_spec.rb +1 -1
  30. data/spec/rspec/core/formatters/documentation_formatter_spec.rb +2 -2
  31. data/spec/rspec/core/kernel_extensions_spec.rb +6 -3
  32. data/spec/rspec/core/metadata_spec.rb +13 -0
  33. data/spec/rspec/core/pending_example_spec.rb +1 -1
  34. data/spec/rspec/core/rake_task_spec.rb +2 -3
  35. data/spec/spec_helper.rb +1 -0
  36. metadata +9 -11
  37. data/.treasure_map.rb +0 -23
  38. data/specs.watchr +0 -58
@@ -1,5 +1,25 @@
1
1
  module Kernel
2
- def debugger(*args)
3
- RSpec.configuration.error_stream.puts "debugger statement ignored, use -d or --debug option to enable debugging\n#{caller(0)[1]}"
4
- end unless respond_to?(:debugger)
2
+
3
+ private
4
+
5
+ def method_missing(m, *a)
6
+ if m.to_s == 'debugger'
7
+ begin
8
+ require 'ruby-debug'
9
+ debugger
10
+ rescue LoadError => e
11
+ warn <<-EOM
12
+ #{'*'*50}
13
+ The debugger statement on the following line was ignored:
14
+
15
+ #{caller(0).detect {|l| l !~ /method_missing/}}
16
+
17
+ To use the debugger statement, you must install ruby-debug.
18
+ #{'*'*50}
19
+ EOM
20
+ end
21
+ else
22
+ super
23
+ end
24
+ end
5
25
  end
@@ -15,32 +15,9 @@ module RSpec
15
15
  output.puts
16
16
  output.puts "Failures:"
17
17
  failed_examples.each_with_index do |example, index|
18
- output.puts if index > 0
19
- exception = example.execution_result[:exception_encountered]
20
- short_padding = ' '
21
- padding = ' '
22
- if exception.is_a?(RSpec::Core::PendingExampleFixedError)
23
- output.puts "#{short_padding}#{index.next}) #{example.full_description} FIXED"
24
- output.puts "#{padding}Expected pending '#{example.metadata[:execution_result][:pending_message]}' to fail. No Error was raised."
25
- else
26
- output.puts "#{short_padding}#{index.next}) #{example.full_description}"
27
- output.puts "#{padding}#{red("Failure/Error:")} #{red(read_failed_line(exception, example).strip)}"
28
- exception.message.split("\n").each do |line|
29
- output.puts "#{padding}#{red(line)}"
30
- end
31
-
32
- example.example_group.ancestors.push(example.example_group).each do |group|
33
- if group.metadata[:shared_group_name]
34
- output.puts "#{padding}Shared Example Group: \"#{group.metadata[:shared_group_name]}\" called from " +
35
- "#{backtrace_line(group.metadata[:example_group][:location])}"
36
- break
37
- end
38
- end
39
- end
40
-
41
- format_backtrace(exception.backtrace, example).each do |backtrace_info|
42
- output.puts grey("#{padding}# #{backtrace_info}")
43
- end
18
+ output.puts
19
+ dump_pending_example_fixed(example, index) || dump_failure(example, index)
20
+ dump_backtrace(example)
44
21
  end
45
22
  end
46
23
 
@@ -69,7 +46,7 @@ module RSpec
69
46
  output.puts "\nTop #{sorted_examples.size} slowest examples:\n"
70
47
  sorted_examples.each do |example|
71
48
  output.puts " #{example.full_description}"
72
- output.puts grey(" #{red(format_seconds(example.execution_result[:run_time]))} #{red("seconds")} #{format_caller(example.metadata[:location])}")
49
+ output.puts grey(" #{red(format_seconds(example.execution_result[:run_time]))} #{red("seconds")} #{format_caller(example.location)}")
73
50
  end
74
51
  end
75
52
 
@@ -86,8 +63,8 @@ module RSpec
86
63
  output.puts "Pending:"
87
64
  pending_examples.each do |pending_example|
88
65
  output.puts yellow(" #{pending_example.full_description}")
89
- output.puts grey(" # #{pending_example.metadata[:execution_result][:pending_message]}")
90
- output.puts grey(" # #{format_caller(pending_example.metadata[:location])}")
66
+ output.puts grey(" # #{pending_example.execution_result[:pending_message]}")
67
+ output.puts grey(" # #{format_caller(pending_example.location)}")
91
68
  end
92
69
  end
93
70
  end
@@ -134,6 +111,14 @@ module RSpec
134
111
  color(text, "\e[90m")
135
112
  end
136
113
 
114
+ def short_padding
115
+ ' '
116
+ end
117
+
118
+ def long_padding
119
+ ' '
120
+ end
121
+
137
122
  private
138
123
 
139
124
  def pluralize(count, string)
@@ -144,8 +129,36 @@ module RSpec
144
129
  backtrace_line(caller_info.to_s.split(':in `block').first)
145
130
  end
146
131
 
147
- end
132
+ def dump_backtrace(example)
133
+ format_backtrace(example.execution_result[:exception].backtrace, example).each do |backtrace_info|
134
+ output.puts grey("#{long_padding}# #{backtrace_info}")
135
+ end
136
+ end
137
+
138
+ def dump_pending_example_fixed(example, index)
139
+ if RSpec::Core::PendingExampleFixedError === example.execution_result[:exception]
140
+ output.puts "#{short_padding}#{index.next}) #{example.full_description} FIXED"
141
+ output.puts blue("#{long_padding}Expected pending '#{example.metadata[:execution_result][:pending_message]}' to fail. No Error was raised.")
142
+ true
143
+ end
144
+ end
145
+
146
+ def dump_failure(example, index)
147
+ exception = example.execution_result[:exception]
148
+ output.puts "#{short_padding}#{index.next}) #{example.full_description}"
149
+ output.puts "#{long_padding}#{red("Failure/Error:")} #{red(read_failed_line(exception, example).strip)}"
150
+ exception.message.split("\n").each { |line| output.puts "#{long_padding}#{red(line)}" }
148
151
 
152
+ example.example_group.ancestors.push(example.example_group).each do |group|
153
+ if group.metadata[:shared_group_name]
154
+ output.puts "#{long_padding}Shared Example Group: \"#{group.metadata[:shared_group_name]}\" called from " +
155
+ "#{backtrace_line(group.metadata[:example_group][:location])}"
156
+ break
157
+ end
158
+ end
159
+ end
160
+
161
+ end
149
162
  end
150
163
  end
151
164
  end
@@ -36,7 +36,7 @@ module RSpec
36
36
 
37
37
  def example_failed(example)
38
38
  super(example)
39
- output.puts failure_output(example, example.execution_result[:exception_encountered])
39
+ output.puts failure_output(example, example.execution_result[:exception])
40
40
  end
41
41
 
42
42
  def failure_output(example, exception)
@@ -7,13 +7,6 @@ module RSpec
7
7
  class HtmlFormatter < BaseTextFormatter
8
8
  include ERB::Util # for the #h method
9
9
 
10
- def method_missing(m, *a, &b)
11
- # no-op
12
- end
13
-
14
- def message(message)
15
- end
16
-
17
10
  def initialize(output)
18
11
  super(output)
19
12
  @example_group_number = 0
@@ -21,6 +14,15 @@ module RSpec
21
14
  @header_red = nil
22
15
  end
23
16
 
17
+ private
18
+ def method_missing(m, *a, &b)
19
+ # no-op
20
+ end
21
+
22
+ public
23
+ def message(message)
24
+ end
25
+
24
26
  # The number of the currently running example_group
25
27
  def example_group_number
26
28
  @example_group_number
@@ -71,7 +73,7 @@ module RSpec
71
73
 
72
74
  def example_failed(example)
73
75
  counter = 0
74
- exception = example.metadata[:execution_result][:exception_encountered]
76
+ exception = example.metadata[:execution_result][:exception]
75
77
  extra = extra_failure_content(exception)
76
78
  failure_style = 'failed'
77
79
  failure_style = RSpec::Core::PendingExampleFixedError === exception ? 'pending_fixed' : 'failed'
@@ -57,7 +57,7 @@ module RSpec
57
57
 
58
58
  class BeforeHooks < HookCollection
59
59
  def run_all(example_group_instance)
60
- each {|h| h.run_in(example_group_instance) }
60
+ each {|h| h.run_in(example_group_instance) } unless empty?
61
61
  end
62
62
 
63
63
  def run_all!(example_group_instance)
@@ -67,7 +67,7 @@ module RSpec
67
67
 
68
68
  class AfterHooks < HookCollection
69
69
  def run_all(example_group_instance)
70
- reverse.each {|h| h.run_in(example_group_instance) }
70
+ reverse.each {|h| h.run_in(example_group_instance) } unless empty?
71
71
  end
72
72
 
73
73
  def run_all!(example_group_instance)
@@ -2,14 +2,46 @@ module RSpec
2
2
  module Core
3
3
  class Metadata < Hash
4
4
 
5
+ module LocationKeys
6
+ def [](key)
7
+ return super if has_key?(key)
8
+ case key
9
+ when :location
10
+ store(:location, location)
11
+ when :file_path, :line_number
12
+ file_path, line_number = file_and_line_number
13
+ store(:file_path, file_path)
14
+ store(:line_number, line_number)
15
+ self[key]
16
+ else
17
+ super
18
+ end
19
+ end
20
+
21
+ def location
22
+ "#{self[:file_path]}:#{self[:line_number]}"
23
+ end
24
+
25
+ def file_and_line_number
26
+ first_caller_from_outside_rspec =~ /(.+?):(\d+)(|:\d+)/
27
+ return [$1, $2.to_i]
28
+ end
29
+
30
+ def first_caller_from_outside_rspec
31
+ self[:caller].detect {|l| l !~ /\/lib\/rspec\/core/}
32
+ end
33
+ end
34
+
5
35
  def initialize(superclass_metadata=nil)
6
36
  @superclass_metadata = superclass_metadata
7
37
  if @superclass_metadata
8
38
  update(@superclass_metadata)
9
39
  example_group = {:example_group => @superclass_metadata[:example_group]}
40
+ else
41
+ example_group = {}
10
42
  end
11
43
 
12
- store(:example_group, example_group || {})
44
+ store(:example_group, example_group.extend(LocationKeys))
13
45
  yield self if block_given?
14
46
  end
15
47
 
@@ -27,13 +59,11 @@ module RSpec
27
59
  user_metadata = args.last.is_a?(Hash) ? args.pop : {}
28
60
  ensure_valid_keys(user_metadata)
29
61
 
30
- self[:example_group][:describes] = described_class_from(*args)
31
- self[:example_group][:description] = description_from(*args)
32
- self[:example_group][:full_description] = full_description_from(*args)
33
-
34
- self[:example_group][:block] = user_metadata.delete(:example_group_block)
35
- self[:example_group][:file_path], self[:example_group][:line_number] = file_and_line_number_from(user_metadata.delete(:caller) || caller)
36
- self[:example_group][:location] = location_from(self[:example_group])
62
+ self[:example_group].store(:caller, user_metadata.delete(:caller) || caller)
63
+ self[:example_group].store(:describes, described_class_from(*args))
64
+ self[:example_group].store(:description, description_from(*args))
65
+ self[:example_group].store(:full_description, full_description_from(*args))
66
+ self[:example_group].store(:block, user_metadata.delete(:example_group_block))
37
67
 
38
68
  update(user_metadata)
39
69
  end
@@ -60,17 +90,16 @@ EOM
60
90
  end
61
91
  end
62
92
 
63
- def for_example(description, options)
64
- dup.configure_for_example(description,options)
93
+ def for_example(description, user_metadata)
94
+ dup.extend(LocationKeys).configure_for_example(description, user_metadata)
65
95
  end
66
96
 
67
- def configure_for_example(description, options)
97
+ def configure_for_example(description, user_metadata)
68
98
  store(:description, description.to_s)
69
99
  store(:full_description, "#{self[:example_group][:full_description]} #{self[:description]}")
70
100
  store(:execution_result, {})
71
- self[:file_path], self[:line_number] = file_and_line_number_from(options.delete(:caller) || caller)
72
- self[:location] = location_from(self)
73
- update(options)
101
+ store(:caller, user_metadata.delete(:caller) || caller)
102
+ update(user_metadata)
74
103
  end
75
104
 
76
105
  def apply?(predicate, filters)
@@ -88,8 +117,7 @@ EOM
88
117
  end
89
118
  end
90
119
 
91
- def apply_condition(key, value, metadata=nil)
92
- metadata ||= self
120
+ def apply_condition(key, value, metadata=self)
93
121
  case value
94
122
  when Hash
95
123
  value.all? { |k, v| apply_condition(k, v, metadata[key]) }
@@ -150,26 +178,10 @@ EOM
150
178
  end
151
179
 
152
180
  def described_class_from(*args)
153
- if args.first.is_a?(String) || args.first.is_a?(Symbol)
154
- superclass_metadata[:example_group][:describes]
155
- else
156
- args.first
181
+ superclass_metadata[:example_group][:describes] || begin
182
+ args.first unless args.first.is_a?(String) || args.first.is_a?(Symbol)
157
183
  end
158
184
  end
159
-
160
- def file_and_line_number_from(list)
161
- entry = first_caller_from_outside_rspec_from_caller(list)
162
- entry =~ /(.+?):(\d+)(|:\d+)/
163
- return [$1, $2.to_i]
164
- end
165
-
166
- def first_caller_from_outside_rspec_from_caller(list)
167
- list.detect {|l| l !~ /\/lib\/rspec\/core/}
168
- end
169
-
170
- def location_from(metadata)
171
- "#{metadata[:file_path]}:#{metadata[:line_number]}"
172
- end
173
185
  end
174
186
  end
175
187
  end
@@ -96,8 +96,8 @@ module RSpec::Core
96
96
  options[:drb_port] = o.to_i
97
97
  end
98
98
 
99
- parser.on('--autotest') do |o|
100
- options[:autotest] = true
99
+ parser.on('--tty') do |o|
100
+ options[:tty] = true
101
101
  end
102
102
 
103
103
  parser.on('--fail-fast', 'Use the fail_fast option to tell RSpec to abort the run on first failure.') do |o|
@@ -161,7 +161,7 @@ module RSpec
161
161
  cmd_parts << "bundle exec" if gemfile? unless skip_bundler
162
162
  cmd_parts << runner
163
163
  if rcov
164
- cmd_parts << ["-Ispec", "-Ilib", rcov_opts]
164
+ cmd_parts << ["-Ispec:lib", rcov_opts]
165
165
  else
166
166
  cmd_parts << rspec_opts
167
167
  end
@@ -27,9 +27,9 @@ module RSpec
27
27
  ascend_until {|path| File.exists?(File.join(path, dir))}
28
28
  end
29
29
 
30
- def ascend_until(&block) # :nodoc:
30
+ def ascend_until # :nodoc:
31
31
  Pathname(File.expand_path('.')).ascend do |path|
32
- return path if block.call(path)
32
+ return path if yield(path)
33
33
  end
34
34
  end
35
35
 
@@ -23,8 +23,8 @@ module RSpec
23
23
  end
24
24
 
25
25
  def self.running_in_drb?
26
- (DRb.current_server rescue false) &&
27
- !!((DRb.current_server.uri) =~ /druby\:\/\/127.0.0.1\:/)
26
+ (DRb.current_server rescue false) &&
27
+ DRb.current_server.uri =~ /druby\:\/\/127.0.0.1\:/
28
28
  end
29
29
 
30
30
  def self.trap_interrupt
@@ -88,9 +88,10 @@ module RSpec
88
88
  # onto the subject in an expression.
89
89
  #
90
90
  # describe Person do
91
- # let(:person) do
92
- # person = Person.new
93
- # person.phone_numbers << "555-1212"
91
+ # subject do
92
+ # Person.new.tap do |person|
93
+ # person.phone_numbers << "555-1212"
94
+ # end
94
95
  # end
95
96
  #
96
97
  # its("phone_numbers.first") { should == "555-1212" }
@@ -1,7 +1,7 @@
1
1
  module RSpec # :nodoc:
2
2
  module Core # :nodoc:
3
3
  module Version # :nodoc:
4
- STRING = '2.1.0'
4
+ STRING = '2.2.0'
5
5
  end
6
6
  end
7
7
  end
data/rspec-core.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.files = `git ls-files`.split("\n")
20
20
  s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
21
21
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
- s.extra_rdoc_files = [ "README.markdown" ]
22
+ s.extra_rdoc_files = [ "README.md" ]
23
23
  s.rdoc_options = ["--charset=UTF-8"]
24
24
  s.require_path = "lib"
25
25
 
@@ -165,13 +165,11 @@ describe RSpec::Core::ConfigurationOptions do
165
165
  end
166
166
  end
167
167
 
168
- it "sends all the arguments other than --drb back to the parser after parsing options" do
168
+ it "does not send --drb back to the parser after parsing options" do
169
169
  config_options_object("--drb", "--color").drb_argv.should_not include("--drb")
170
170
  end
171
171
  end
172
172
 
173
-
174
- # TODO #drb_argv may not be the best name
175
173
  # TODO ensure all options are output
176
174
  # TODO check if we need to spec that the short options are "expanded" ("-v" becomes "--version" currently)
177
175
  describe "#drb_argv" do
@@ -180,6 +178,10 @@ describe RSpec::Core::ConfigurationOptions do
180
178
  config_options_object(*%w[ a --drb b --color c ]).drb_argv.should =~ %w[ --color a b c ]
181
179
  end
182
180
 
181
+ it "includes --fail-fast" do
182
+ config_options_object(*%w[--fail-fast]).drb_argv.should include("--fail-fast")
183
+ end
184
+
183
185
  context "--drb specified in ARGV" do
184
186
  it "renders all the original arguments except --drb" do
185
187
  config_options_object(*%w[ --drb --color --format s --line_number 1 --example pattern --profile --backtrace -I path/a -I path/b --require path/c --require path/d]).
@@ -191,8 +193,8 @@ describe RSpec::Core::ConfigurationOptions do
191
193
  it "renders all the original arguments except --drb" do
192
194
  File.stub(:exist?) { true }
193
195
  IO.stub(:read) { "--drb --color" }
194
- config_options_object(*%w[ --autotest --format s --line_number 1 --example pattern --profile --backtrace ]).
195
- drb_argv.should eq(%w[ --color --profile --backtrace --autotest --format s --line_number 1 --example pattern ])
196
+ config_options_object(*%w[ --tty --format s --line_number 1 --example pattern --profile --backtrace ]).
197
+ drb_argv.should eq(%w[ --color --profile --backtrace --tty --format s --line_number 1 --example pattern ])
196
198
  end
197
199
  end
198
200