rspec-core 2.0.0.beta.17 → 2.0.0.beta.18

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 (70) hide show
  1. data/README.markdown +5 -1
  2. data/Rakefile +4 -1
  3. data/Upgrade.markdown +28 -2
  4. data/VERSION +1 -1
  5. data/autotest/discover.rb +1 -1
  6. data/features/command_line/configure.feature +19 -0
  7. data/features/example_groups/shared_example_group.feature +125 -0
  8. data/features/hooks/around_hooks.feature +11 -2
  9. data/features/pending/pending_examples.feature +18 -6
  10. data/lib/autotest/rspec2.rb +1 -1
  11. data/lib/rspec/core.rb +1 -0
  12. data/lib/rspec/core/command_line_configuration.rb +62 -0
  13. data/lib/rspec/core/configuration.rb +39 -12
  14. data/lib/rspec/core/configuration_options.rb +5 -5
  15. data/lib/rspec/core/deprecation.rb +6 -6
  16. data/lib/rspec/core/errors.rb +1 -1
  17. data/lib/rspec/core/example.rb +25 -25
  18. data/lib/rspec/core/example_group.rb +30 -14
  19. data/lib/rspec/core/formatters/base_formatter.rb +25 -25
  20. data/lib/rspec/core/formatters/base_text_formatter.rb +11 -10
  21. data/lib/rspec/core/formatters/documentation_formatter.rb +2 -2
  22. data/lib/rspec/core/formatters/helpers.rb +6 -6
  23. data/lib/rspec/core/formatters/html_formatter.rb +13 -12
  24. data/lib/rspec/core/formatters/progress_formatter.rb +1 -1
  25. data/lib/rspec/core/formatters/snippet_extractor.rb +5 -5
  26. data/lib/rspec/core/hooks.rb +3 -3
  27. data/lib/rspec/core/kernel_extensions.rb +1 -1
  28. data/lib/rspec/core/let.rb +5 -5
  29. data/lib/rspec/core/metadata.rb +2 -2
  30. data/lib/rspec/core/mocking/with_absolutely_nothing.rb +3 -3
  31. data/lib/rspec/core/mocking/with_mocha.rb +5 -5
  32. data/lib/rspec/core/mocking/with_rr.rb +3 -3
  33. data/lib/rspec/core/mocking/with_rspec.rb +3 -3
  34. data/lib/rspec/core/option_parser.rb +8 -4
  35. data/lib/rspec/core/rake_task.rb +5 -0
  36. data/lib/rspec/core/ruby_project.rb +1 -1
  37. data/lib/rspec/core/shared_example_group.rb +2 -2
  38. data/lib/rspec/core/subject.rb +10 -4
  39. data/lib/rspec/core/world.rb +5 -5
  40. data/rspec-core.gemspec +19 -11
  41. data/spec/autotest/rspec_spec.rb +14 -14
  42. data/spec/rspec/core/command_line_configuration_spec.rb +26 -0
  43. data/spec/rspec/core/command_line_spec.rb +5 -5
  44. data/spec/rspec/core/configuration_options_spec.rb +20 -20
  45. data/spec/rspec/core/configuration_spec.rb +10 -10
  46. data/spec/rspec/core/core_spec.rb +8 -8
  47. data/spec/rspec/core/deprecations_spec.rb +2 -2
  48. data/spec/rspec/core/drb_command_line_spec.rb +10 -10
  49. data/spec/rspec/core/example_group_spec.rb +46 -10
  50. data/spec/rspec/core/example_spec.rb +46 -12
  51. data/spec/rspec/core/formatters/base_formatter_spec.rb +2 -46
  52. data/spec/rspec/core/formatters/base_text_formatter_spec.rb +4 -3
  53. data/spec/rspec/core/formatters/documentation_formatter_spec.rb +1 -1
  54. data/spec/rspec/core/formatters/helpers_spec.rb +2 -2
  55. data/spec/rspec/core/formatters/html_formatted-1.8.7.html +1 -1
  56. data/spec/rspec/core/formatters/html_formatted-1.9.1.html +1 -1
  57. data/spec/rspec/core/formatters/html_formatted-1.9.2.html +1 -1
  58. data/spec/rspec/core/formatters/progress_formatter_spec.rb +10 -9
  59. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html +13 -13
  60. data/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html +1 -1
  61. data/spec/rspec/core/let_spec.rb +1 -1
  62. data/spec/rspec/core/metadata_spec.rb +9 -9
  63. data/spec/rspec/core/option_parser_spec.rb +3 -3
  64. data/spec/rspec/core/pending_example_spec.rb +1 -1
  65. data/spec/rspec/core/resources/custom_example_group_runner.rb +1 -1
  66. data/spec/rspec/core/runner_spec.rb +4 -4
  67. data/spec/rspec/core/shared_example_group_spec.rb +66 -162
  68. data/spec/rspec/core/subject_spec.rb +4 -4
  69. data/spec/rspec/core/world_spec.rb +38 -38
  70. metadata +21 -13
@@ -7,13 +7,13 @@ module RSpec
7
7
  class ConfigurationOptions
8
8
  LOCAL_OPTIONS_FILE = ".rspec"
9
9
  GLOBAL_OPTIONS_FILE = File.join(File.expand_path("~"), ".rspec")
10
-
10
+
11
11
  attr_reader :options
12
-
12
+
13
13
  def initialize(args)
14
14
  @args = args
15
15
  end
16
-
16
+
17
17
  def configure(config)
18
18
  keys = options.keys
19
19
  keys.unshift(:requires) if keys.delete(:requires)
@@ -22,7 +22,7 @@ module RSpec
22
22
  config.send("#{key}=", options[key])
23
23
  end
24
24
  end
25
-
25
+
26
26
  def drb_argv
27
27
  argv = []
28
28
  argv << "--color" if options[:color_enabled]
@@ -73,7 +73,7 @@ module RSpec
73
73
  def parse_global_options
74
74
  parse_options_file(GLOBAL_OPTIONS_FILE)
75
75
  end
76
-
76
+
77
77
  def parse_options_file(path)
78
78
  Parser.parse(args_from_options_file(path))
79
79
  end
@@ -1,8 +1,8 @@
1
1
  module RSpec
2
-
2
+
3
3
  class << self
4
4
  def deprecate(method, alternate_method=nil, version=nil)
5
- version_string = version ? "rspec-#{version}" : "a future version of RSpec"
5
+ version_string = version ? "rspec-#{version}" : "a future version of RSpec"
6
6
 
7
7
  message = <<-NOTICE
8
8
 
@@ -30,16 +30,16 @@ ADDITIONAL
30
30
  end
31
31
 
32
32
  class HashWithDeprecationNotice < Hash
33
-
33
+
34
34
  def initialize(method, alternate_method=nil, &block)
35
35
  @method, @alternate_method = method, alternate_method
36
36
  end
37
-
37
+
38
38
  def []=(k,v)
39
39
  RSpec.deprecate(@method, @alternate_method)
40
40
  super
41
41
  end
42
-
42
+
43
43
  end
44
-
44
+
45
45
  end
@@ -5,7 +5,7 @@ module RSpec
5
5
  superclass = ['Test::Unit::AssertionFailedError', '::StandardError'].map do |c|
6
6
  eval(c) rescue nil
7
7
  end.compact.first
8
-
8
+
9
9
  class PendingExampleFixedError < superclass
10
10
  end
11
11
  end
@@ -12,14 +12,11 @@ module RSpec
12
12
 
13
13
  delegate_to_metadata :description, :full_description, :execution_result, :file_path, :pending
14
14
 
15
- alias_method :inspect, :full_description
16
- alias_method :to_s, :full_description
17
-
18
15
  def initialize(example_group_class, desc, options, example_block=nil)
19
16
  @example_group_class, @options, @example_block = example_group_class, options, example_block
20
17
  @metadata = @example_group_class.metadata.for_example(desc, options)
21
18
  @exception = nil
22
- @in_block = false
19
+ @pending_declared_in_example = @in_block = false
23
20
  end
24
21
 
25
22
  def example_group
@@ -35,6 +32,10 @@ module RSpec
35
32
  @in_block
36
33
  end
37
34
 
35
+ def pending?
36
+ !!pending
37
+ end
38
+
38
39
  def run(example_group_instance, reporter)
39
40
  @example_group_instance = example_group_instance
40
41
  @example_group_instance.example = self
@@ -43,21 +44,20 @@ module RSpec
43
44
 
44
45
  begin
45
46
  unless pending
46
- with_around_hooks do
47
- begin
48
- run_before_each
49
- @in_block = true
50
- with_pending_capture &@example_block
51
- rescue Exception => e
52
- set_exception(e)
53
- ensure
54
- @in_block = false
55
- run_after_each
47
+ with_pending_capture do
48
+ with_around_hooks do
49
+ begin
50
+ run_before_each
51
+ @in_block = true
52
+ @example_group_instance.instance_eval(&@example_block)
53
+ rescue Exception => e
54
+ set_exception(e)
55
+ ensure
56
+ @in_block = false
57
+ run_after_each
58
+ end
56
59
  end
57
- # FUCKME (DC): I really want to move the call below to the end of
58
- # the with_around_hooks method, but it adds 4% to the run time.
59
- # Why? (footnote - Dan North made me write this comment)
60
- end.call
60
+ end
61
61
  end
62
62
  rescue Exception => e
63
63
  set_exception(e)
@@ -75,15 +75,15 @@ module RSpec
75
75
 
76
76
  private
77
77
 
78
- def with_pending_capture
78
+ def with_pending_capture(&block)
79
79
  @pending_declared_in_example = catch(:pending_declared_in_example) do
80
- @example_group_instance.instance_eval(&@example_block)
80
+ block.call
81
81
  throw :pending_declared_in_example, false
82
82
  end
83
83
  end
84
84
 
85
85
  def with_around_hooks(&wrapped_example)
86
- @example_group_class.eval_around_eachs(@example_group_instance, wrapped_example)
86
+ @example_group_class.eval_around_eachs(@example_group_instance, wrapped_example).call
87
87
  end
88
88
 
89
89
  def start(reporter)
@@ -117,20 +117,20 @@ module RSpec
117
117
  end
118
118
 
119
119
  def run_before_each
120
- @example_group_instance._setup_mocks if @example_group_instance.respond_to?(:_setup_mocks)
120
+ @example_group_instance.setup_mocks_for_rspec if @example_group_instance.respond_to?(:setup_mocks_for_rspec)
121
121
  @example_group_class.eval_before_eachs(@example_group_instance)
122
122
  end
123
123
 
124
124
  def run_after_each
125
125
  @example_group_class.eval_after_eachs(@example_group_instance)
126
- @example_group_instance._verify_mocks if @example_group_instance.respond_to?(:_verify_mocks)
126
+ @example_group_instance.verify_mocks_for_rspec if @example_group_instance.respond_to?(:verify_mocks_for_rspec)
127
127
  ensure
128
- @example_group_instance._teardown_mocks if @example_group_instance.respond_to?(:_teardown_mocks)
128
+ @example_group_instance.teardown_mocks_for_rspec if @example_group_instance.respond_to?(:teardown_mocks_for_rspec)
129
129
  end
130
130
 
131
131
  def assign_auto_description
132
132
  if description.empty?
133
- metadata[:description] = RSpec::Matchers.generated_description
133
+ metadata[:description] = RSpec::Matchers.generated_description
134
134
  RSpec::Matchers.clear_generated_description
135
135
  end
136
136
  end
@@ -59,16 +59,28 @@ module RSpec
59
59
  alias_example_to :focused, :focused => true
60
60
  alias_example_to :pending, :pending => true
61
61
 
62
- def self.it_should_behave_like(*names)
63
- names.each do |name|
64
- begin
65
- module_eval &RSpec.world.shared_example_groups[name]
66
- rescue ArgumentError
67
- raise "Could not find shared example group named #{name.inspect}"
62
+ def self.define_shared_group_method(new_name, report_label=nil)
63
+ report_label = "it should behave like" unless report_label
64
+ module_eval(<<-END_RUBY, __FILE__, __LINE__)
65
+ def self.#{new_name}(name, &customization_block)
66
+ shared_block = world.shared_example_groups[name]
67
+ raise "Could not find shared example group named \#{name.inspect}" unless shared_block
68
+
69
+ shared_group = describe("#{report_label} \#{name}", &shared_block)
70
+ shared_group.class_eval(&customization_block) if customization_block
71
+ shared_group
68
72
  end
69
- end
73
+ END_RUBY
70
74
  end
71
75
 
76
+ define_shared_group_method :it_should_behave_like
77
+
78
+ class << self
79
+ alias_method :alias_it_should_behave_like_to, :define_shared_group_method
80
+ end
81
+
82
+ alias_it_should_behave_like_to :it_behaves_like, "behaves like"
83
+
72
84
  def self.examples
73
85
  @examples ||= []
74
86
  end
@@ -82,7 +94,7 @@ module RSpec
82
94
  end
83
95
 
84
96
  def self.metadata
85
- @metadata
97
+ @metadata if defined?(@metadata)
86
98
  end
87
99
 
88
100
  def self.superclass_metadata
@@ -111,7 +123,7 @@ module RSpec
111
123
 
112
124
  def self.subclass(parent, args, &example_group_block)
113
125
  subclass = Class.new(parent)
114
- subclass.set_it_up(*args)
126
+ subclass.set_it_up(*args)
115
127
  subclass.module_eval(&example_group_block) if example_group_block
116
128
  subclass
117
129
  end
@@ -128,6 +140,10 @@ module RSpec
128
140
  @_ancestors ||= super().select {|a| a < RSpec::Core::ExampleGroup}
129
141
  end
130
142
 
143
+ def self.top_level?
144
+ ancestors.size == 1
145
+ end
146
+
131
147
  def self.set_it_up(*args)
132
148
  @metadata = RSpec::Core::Metadata.new(superclass_metadata).process(*args)
133
149
 
@@ -143,7 +159,7 @@ module RSpec
143
159
  def self.eval_before_alls(example)
144
160
  return if descendant_filtered_examples.empty?
145
161
  superclass.before_all_ivars.each { |ivar, val| example.instance_variable_set(ivar, val) }
146
- world.run_hook_filtered(:before, :all, self, example)
162
+ world.run_hook_filtered(:before, :all, self, example) if top_level?
147
163
 
148
164
  run_hook!(:before, :all, example)
149
165
  example.instance_variables.each { |ivar| before_all_ivars[ivar] = example.instance_variable_get(ivar) }
@@ -173,13 +189,14 @@ module RSpec
173
189
  def self.eval_after_alls(example)
174
190
  return if descendant_filtered_examples.empty?
175
191
  before_all_ivars.each { |ivar, val| example.instance_variable_set(ivar, val) }
176
- ancestors.each {|ancestor| ancestor.run_hook!(:after, :all, example) }
177
- world.run_hook_filtered(:after, :all, self, example)
192
+ run_hook!(:after, :all, example)
193
+ world.run_hook_filtered(:after, :all, self, example) if top_level?
178
194
  end
179
195
 
180
196
  def self.run(reporter)
197
+ @reporter = reporter
181
198
  example_group_instance = new
182
- reporter.add_example_group(self)
199
+ reporter.example_group_started(self)
183
200
  begin
184
201
  eval_before_alls(example_group_instance)
185
202
  result_for_this_group = run_examples(example_group_instance, reporter)
@@ -248,7 +265,6 @@ module RSpec
248
265
  :extend => extended_modules
249
266
  }
250
267
  end
251
-
252
268
  end
253
269
  end
254
270
  end
@@ -35,9 +35,12 @@ module RSpec
35
35
  start(count)
36
36
  begin
37
37
  yield self
38
- ensure
39
38
  stop
40
- dump(@duration)
39
+ start_dump
40
+ dump_summary(duration, example_count, failure_count, pending_count)
41
+ dump_pending
42
+ dump_failures
43
+ ensure
41
44
  close
42
45
  end
43
46
  end
@@ -47,15 +50,25 @@ module RSpec
47
50
  # they have all been collected. This can be useful for special
48
51
  # formatters that need to provide progress on feedback (graphical ones)
49
52
  #
50
- # This method will only be invoked once, and the next one to be invoked
51
- # is #add_example_group
53
+ # This will only be invoked once, and the next one to be invoked
54
+ # is #example_group_started
52
55
  def start(example_count)
53
- @start = Time.now
54
56
  @example_count = example_count
57
+ @start = Time.now
55
58
  end
56
59
 
57
- def stop
58
- @duration = Time.now - @start
60
+ # This method is invoked at the beginning of the execution of each example group.
61
+ # +example_group+ is the example_group.
62
+ #
63
+ # The next method to be invoked after this is +example_passed+,
64
+ # +example_pending+, or +example_finished+
65
+ def example_group_started(example_group)
66
+ @example_group = example_group
67
+ end
68
+
69
+ def add_example_group(example_group)
70
+ RSpec.deprecate("add_example_group", "example_group_started")
71
+ example_group_started(example_group)
59
72
  end
60
73
 
61
74
  def example_started(example)
@@ -74,26 +87,13 @@ module RSpec
74
87
  def message(message)
75
88
  end
76
89
 
77
- # This method is invoked at the beginning of the execution of each example group.
78
- # +example_group+ is the example_group.
79
- #
80
- # The next method to be invoked after this is +example_passed+,
81
- # +example_pending+, or +example_finished+
82
- def add_example_group(example_group)
83
- @example_group = example_group
84
- end
85
-
86
- def dump(duration)
87
- start_dump(duration)
88
- dump_failures
89
- dump_summary
90
- dump_pending
90
+ def stop
91
+ @duration = Time.now - @start
91
92
  end
92
93
 
93
94
  # This method is invoked after all of the examples have executed. The next method
94
95
  # to be invoked after this one is #dump_failure (once for each failed example),
95
- def start_dump(duration)
96
- @duration = duration
96
+ def start_dump
97
97
  end
98
98
 
99
99
  # Dumps detailed information about each example failure.
@@ -101,7 +101,7 @@ module RSpec
101
101
  end
102
102
 
103
103
  # This method is invoked after the dumping of examples and failures.
104
- def dump_summary
104
+ def dump_summary(duration, example_count, failure_count, pending_count)
105
105
  end
106
106
 
107
107
  # This gets invoked after the summary if option is set to do so.
@@ -118,7 +118,7 @@ module RSpec
118
118
 
119
119
  cleansed = backtrace.select { |line| backtrace_line(line) }
120
120
  # Kick the describe stack info off the list, just keep the line the problem happened on from that file
121
- # cleansed = [cleansed.detect { |line| line.split(':').first == example.metadata[:caller].split(':').first }] if cleansed.size > 1
121
+ # cleansed = [cleansed.detect { |line| line.split(':').first == example.metadata[:caller].split(':').first }] if cleansed.size > 1
122
122
  cleansed.empty? ? backtrace : cleansed
123
123
  end
124
124
 
@@ -14,10 +14,10 @@ module RSpec
14
14
  exception = failed_example.execution_result[:exception_encountered]
15
15
  padding = ' '
16
16
  if exception.is_a?(RSpec::Core::PendingExampleFixedError)
17
- output.puts "#{index.next}) #{failed_example} FIXED"
17
+ output.puts "#{index.next}) #{failed_example.full_description} FIXED"
18
18
  output.puts "#{padding}Expected pending '#{failed_example.metadata[:execution_result][:pending_message]}' to fail. No Error was raised."
19
19
  else
20
- output.puts "#{index.next}) #{failed_example}"
20
+ output.puts "#{index.next}) #{failed_example.full_description}"
21
21
  output.puts "#{padding}Failure/Error: #{read_failed_line(exception, failed_example).strip}"
22
22
  exception.message.split("\n").each do |line|
23
23
  output.puts "#{padding}#{red(line)}"
@@ -28,7 +28,7 @@ module RSpec
28
28
  output.puts grey("#{padding}# #{backtrace_info}")
29
29
  end
30
30
 
31
- output.puts
31
+ output.puts
32
32
  end
33
33
  end
34
34
 
@@ -43,8 +43,8 @@ module RSpec
43
43
  red(summary)
44
44
  end
45
45
  end
46
-
47
- def dump_summary
46
+
47
+ def dump_summary(duration, example_count, failure_count, pending_count)
48
48
  output.puts "\nFinished in #{format_seconds(duration)} seconds\n"
49
49
 
50
50
  output.puts colorise_summary(summary_line(example_count, failure_count, pending_count))
@@ -52,7 +52,7 @@ module RSpec
52
52
  # Don't print out profiled info if there are failures, it just clutters the output
53
53
  if profile_examples? && failure_count == 0
54
54
  sorted_examples = examples.sort_by { |example| example.execution_result[:run_time] }.reverse.first(10)
55
- output.puts "\nTop #{sorted_examples.size} slowest examples:\n"
55
+ output.puts "\nTop #{sorted_examples.size} slowest examples:\n"
56
56
  sorted_examples.each do |example|
57
57
  output.puts " (#{format_seconds(example.execution_result[:run_time])} seconds) #{example}"
58
58
  output.puts grey(" # #{format_caller(example.metadata[:location])}")
@@ -63,7 +63,7 @@ module RSpec
63
63
  def summary_line(example_count, failure_count, pending_count)
64
64
  summary = pluralize(example_count, "example")
65
65
  summary << ", " << pluralize(failure_count, "failure")
66
- summary << ", #{pending_count} pending" if pending_count > 0
66
+ summary << ", #{pending_count} pending" if pending_count > 0
67
67
  summary
68
68
  end
69
69
 
@@ -72,8 +72,9 @@ module RSpec
72
72
  output.puts
73
73
  output.puts "Pending:"
74
74
  pending_examples.each do |pending_example|
75
- output.puts " #{pending_example} (#{pending_example.metadata[:execution_result][:pending_message]})"
76
- output.puts grey(" # #{format_caller(pending_example.metadata[:location])}")
75
+ output.puts yellow(" #{pending_example.full_description}")
76
+ output.puts grey(" # #{pending_example.metadata[:execution_result][:pending_message]}")
77
+ output.puts grey(" # #{format_caller(pending_example.metadata[:location])}")
77
78
  end
78
79
  end
79
80
  end
@@ -127,7 +128,7 @@ module RSpec
127
128
  end
128
129
 
129
130
  def format_caller(caller_info)
130
- caller_info.to_s.split(':in `block').first
131
+ backtrace_line(caller_info.to_s.split(':in `block').first)
131
132
  end
132
133
 
133
134
  end
@@ -9,7 +9,7 @@ module RSpec
9
9
  @previous_nested_example_groups = []
10
10
  end
11
11
 
12
- def add_example_group(example_group)
12
+ def example_group_started(example_group)
13
13
  super
14
14
 
15
15
  example_group_chain.each_with_index do |nested_example_group, i|
@@ -21,7 +21,7 @@ module RSpec
21
21
 
22
22
  @previous_nested_example_groups = example_group_chain
23
23
  end
24
-
24
+
25
25
  def example_passed(example)
26
26
  super
27
27
  output.puts passed_output(example)