rspec-core 2.0.0.beta.19 → 2.0.0.beta.20

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 (50) hide show
  1. data/.gitignore +1 -0
  2. data/Upgrade.markdown +6 -0
  3. data/VERSION +1 -1
  4. data/features/example_groups/shared_example_group.feature +44 -7
  5. data/features/filtering/exclusion_filters.feature +79 -0
  6. data/features/filtering/inclusion_filters.feature +1 -1
  7. data/features/hooks/around_hooks.feature +28 -1
  8. data/features/pending/pending_examples.feature +2 -4
  9. data/features/spec_files/arbitrary_file_suffix.feature +13 -0
  10. data/lib/autotest/rspec2.rb +17 -17
  11. data/lib/rspec/core.rb +2 -2
  12. data/lib/rspec/core/command_line.rb +2 -1
  13. data/lib/rspec/core/configuration.rb +23 -9
  14. data/lib/rspec/core/deprecation.rb +1 -1
  15. data/lib/rspec/core/example_group.rb +11 -28
  16. data/lib/rspec/core/extensions.rb +4 -0
  17. data/lib/rspec/core/extensions/instance_eval_with_args.rb +39 -0
  18. data/lib/rspec/core/{kernel_extensions.rb → extensions/kernel.rb} +0 -0
  19. data/lib/rspec/core/extensions/module_eval_with_args.rb +54 -0
  20. data/lib/rspec/core/{object_extensions.rb → extensions/object.rb} +3 -1
  21. data/lib/rspec/core/formatters/base_formatter.rb +20 -43
  22. data/lib/rspec/core/formatters/base_text_formatter.rb +13 -10
  23. data/lib/rspec/core/formatters/documentation_formatter.rb +4 -4
  24. data/lib/rspec/core/formatters/html_formatter.rb +4 -4
  25. data/lib/rspec/core/formatters/progress_formatter.rb +4 -4
  26. data/lib/rspec/core/rake_task.rb +1 -1
  27. data/lib/rspec/core/reporter.rb +65 -0
  28. data/lib/rspec/core/subject.rb +1 -1
  29. data/lib/rspec/core/world.rb +11 -3
  30. data/rspec-core.gemspec +26 -14
  31. data/spec/autotest/failed_results_re_spec.rb +14 -23
  32. data/spec/autotest/rspec_spec.rb +1 -1
  33. data/spec/rspec/core/configuration_spec.rb +74 -9
  34. data/spec/rspec/core/drb_command_line_spec.rb +2 -2
  35. data/spec/rspec/core/example_group_spec.rb +13 -7
  36. data/spec/rspec/core/example_spec.rb +4 -4
  37. data/spec/rspec/core/formatters/html_formatted-1.8.6.html +280 -0
  38. data/spec/rspec/core/formatters/html_formatter_spec.rb +5 -3
  39. data/spec/rspec/core/formatters/progress_formatter_spec.rb +3 -3
  40. data/spec/rspec/core/formatters/snippet_extractor_spec.rb +2 -2
  41. data/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html +280 -0
  42. data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +5 -3
  43. data/spec/rspec/core/hooks_filtering_spec.rb +104 -0
  44. data/spec/rspec/core/reporter_spec.rb +34 -0
  45. data/spec/rspec/core/shared_example_group_spec.rb +22 -2
  46. data/spec/rspec/core/world_spec.rb +10 -8
  47. data/spec/rspec/{core/core_spec.rb → core_spec.rb} +0 -0
  48. data/spec/ruby_forker.rb +1 -1
  49. data/spec/spec_helper.rb +2 -2
  50. metadata +39 -33
@@ -0,0 +1,4 @@
1
+ require 'rspec/core/extensions/object'
2
+ require 'rspec/core/extensions/kernel'
3
+ require 'rspec/core/extensions/instance_eval_with_args'
4
+ require 'rspec/core/extensions/module_eval_with_args'
@@ -0,0 +1,39 @@
1
+ module RSpec
2
+ module Core
3
+ module Extensions
4
+ module InstanceEvalWithArgs
5
+ # based on Bounded Spec InstanceExec (Mauricio Fernandez)
6
+ # http://eigenclass.org/hiki/bounded+space+instance_exec
7
+ # - uses singleton_class instead of global InstanceExecHelper module
8
+ # - this keeps it scoped to classes/modules that include this module
9
+ # - only necessary for ruby 1.8.6
10
+ def instance_eval_with_args(*args, &block)
11
+ return instance_exec(*args, &block) if respond_to?(:instance_exec)
12
+
13
+ # If there are no args and the block doesn't expect any, there's no
14
+ # need to fake instance_exec with our hack below.
15
+ # Notes:
16
+ # * lambda { }.arity # => -1
17
+ # * lambda { || }.arity # => 0
18
+ # * lambda { |*a| }.arity # -1
19
+ return instance_eval(&block) if block.arity < 1 && args.size.zero?
20
+
21
+ singleton_class = (class << self; self; end)
22
+ begin
23
+ orig_critical, Thread.critical = Thread.critical, true
24
+ n = 0
25
+ n += 1 while respond_to?(method_name="__instance_exec#{n}")
26
+ singleton_class.module_eval{ define_method(method_name, &block) }
27
+ ensure
28
+ Thread.critical = orig_critical
29
+ end
30
+ begin
31
+ return send(method_name, *args)
32
+ ensure
33
+ singleton_class.module_eval{ remove_method(method_name) } rescue nil
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,54 @@
1
+ module RSpec
2
+ module Core
3
+ module Extensions
4
+ module ModuleEvalWithArgs
5
+ include InstanceEvalWithArgs
6
+
7
+ def module_eval_with_args(*args, &block)
8
+ # ruby > 1.8.6
9
+ return module_exec(*args, &block) if respond_to?(:module_exec)
10
+
11
+ # If there are no args and the block doesn't expect any, there's no
12
+ # need to fake module_exec with our hack below.
13
+ # Notes:
14
+ # * lambda { }.arity # => -1
15
+ # * lambda { || }.arity # => 0
16
+ # * lambda { |*a| }.arity # -1
17
+ return module_eval(&block) if block.arity < 1 && args.size.zero?
18
+
19
+ instance_eval_with_args(*args, &block)
20
+
21
+ # The only difference between instance_eval and module_eval is static method defs.
22
+ # * `def foo` in instance_eval defines a singleton method on the instance
23
+ # * `def foo` in class/module_eval defines an instance method for the class/module
24
+ # Here we deal with this difference by defining instance methods on the
25
+ # class/module and removing the singleton definitions.
26
+ singleton_class = class << self; self; end
27
+ extract_static_instance_method_defs_from(block).each do |m_name, m_def|
28
+ define_method(m_name, &m_def)
29
+ singleton_class.send(:remove_method, m_name)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def extract_static_instance_method_defs_from(block)
36
+ klass = Class.new do
37
+ # swallow any missing class method errors;
38
+ # we only care to capture the raw method definitions here.
39
+ def self.method_missing(*a); end
40
+
41
+ # skip any dynamic method definitions
42
+ def self.define_method(*a); end
43
+
44
+ # run the block so our instance methods get defined
45
+ class_eval(&block)
46
+ end
47
+
48
+ instance = klass.new
49
+ klass.instance_methods(false).inject({}) { |h, m| h[m] = instance.method(m); h }
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -12,4 +12,6 @@ module RSpec
12
12
  end
13
13
  end
14
14
 
15
- include RSpec::Core::ObjectExtensions
15
+ class Object
16
+ include RSpec::Core::ObjectExtensions
17
+ end
@@ -5,47 +5,19 @@ module RSpec
5
5
  class BaseFormatter
6
6
  include Helpers
7
7
  attr_accessor :example_group
8
- attr_reader :example_count, :duration, :examples, :output
8
+ attr_reader :duration, :examples, :output
9
+ attr_reader :example_count, :pending_count, :failure_count
10
+ attr_reader :failed_examples, :pending_examples
9
11
 
10
12
  def initialize(output)
11
13
  @output = output
12
- @example_count = 0
14
+ @example_count = @pending_count = @failure_count = 0
13
15
  @examples = []
16
+ @failed_examples = []
17
+ @pending_examples = []
14
18
  @example_group = nil
15
19
  end
16
20
 
17
- def pending_examples
18
- @pending_examples ||= ::RSpec.world.find(examples, :execution_result => { :status => 'pending' })
19
- end
20
-
21
- def pending_count
22
- pending_examples.size
23
- end
24
-
25
- def failed_examples
26
- @failed_examples ||= ::RSpec.world.find(examples, :execution_result => { :status => 'failed' })
27
- end
28
-
29
- def failure_count
30
- failed_examples.size
31
- end
32
-
33
- def report(count)
34
- sync_output do
35
- start(count)
36
- begin
37
- yield self
38
- stop
39
- start_dump
40
- dump_summary(duration, example_count, failure_count, pending_count)
41
- dump_pending
42
- dump_failures
43
- ensure
44
- close
45
- end
46
- end
47
- end
48
-
49
21
  # This method is invoked before any examples are run, right after
50
22
  # they have all been collected. This can be useful for special
51
23
  # formatters that need to provide progress on feedback (graphical ones)
@@ -53,8 +25,8 @@ module RSpec
53
25
  # This will only be invoked once, and the next one to be invoked
54
26
  # is #example_group_started
55
27
  def start(example_count)
28
+ start_sync_output
56
29
  @example_count = example_count
57
- @start = Time.now
58
30
  end
59
31
 
60
32
  # This method is invoked at the beginning of the execution of each example group.
@@ -79,16 +51,17 @@ module RSpec
79
51
  end
80
52
 
81
53
  def example_pending(example)
54
+ @pending_examples << example
82
55
  end
83
56
 
84
57
  def example_failed(example)
58
+ @failed_examples << example
85
59
  end
86
60
 
87
61
  def message(message)
88
62
  end
89
63
 
90
64
  def stop
91
- @duration = Time.now - @start
92
65
  end
93
66
 
94
67
  # This method is invoked after all of the examples have executed. The next method
@@ -102,6 +75,10 @@ module RSpec
102
75
 
103
76
  # This method is invoked after the dumping of examples and failures.
104
77
  def dump_summary(duration, example_count, failure_count, pending_count)
78
+ @duration = duration
79
+ @example_count = example_count
80
+ @failure_count = failure_count
81
+ @pending_count = pending_count
105
82
  end
106
83
 
107
84
  # This gets invoked after the summary if option is set to do so.
@@ -110,6 +87,7 @@ module RSpec
110
87
 
111
88
  # This method is invoked at the very end. Allows the formatter to clean up, like closing open streams.
112
89
  def close
90
+ restore_sync_output
113
91
  end
114
92
 
115
93
  def format_backtrace(backtrace, example)
@@ -150,13 +128,12 @@ module RSpec
150
128
  end
151
129
  end
152
130
 
153
- def sync_output
154
- begin
155
- old_sync, output.sync = output.sync, true if output_supports_sync
156
- yield
157
- ensure
158
- output.sync = old_sync if output_supports_sync and !output.closed?
159
- end
131
+ def start_sync_output
132
+ @old_sync, output.sync = output.sync, true if output_supports_sync
133
+ end
134
+
135
+ def restore_sync_output
136
+ output.sync = @old_sync if output_supports_sync and !output.closed?
160
137
  end
161
138
 
162
139
  def output_supports_sync
@@ -9,26 +9,28 @@ module RSpec
9
9
  end
10
10
 
11
11
  def dump_failures
12
+ return if failed_examples.empty?
12
13
  output.puts
13
- failed_examples.each_with_index do |failed_example, index|
14
- exception = failed_example.execution_result[:exception_encountered]
15
- padding = ' '
14
+ output.puts "Failures:"
15
+ failed_examples.each_with_index do |example, index|
16
+ output.puts if index > 0
17
+ exception = example.execution_result[:exception_encountered]
18
+ short_padding = ' '
19
+ padding = ' '
16
20
  if exception.is_a?(RSpec::Core::PendingExampleFixedError)
17
- output.puts "#{index.next}) #{failed_example.full_description} FIXED"
18
- output.puts "#{padding}Expected pending '#{failed_example.metadata[:execution_result][:pending_message]}' to fail. No Error was raised."
21
+ output.puts "#{short_padding}#{index.next}) #{example.full_description} FIXED"
22
+ output.puts "#{padding}Expected pending '#{example.metadata[:execution_result][:pending_message]}' to fail. No Error was raised."
19
23
  else
20
- output.puts "#{index.next}) #{failed_example.full_description}"
21
- output.puts "#{padding}Failure/Error: #{read_failed_line(exception, failed_example).strip}"
24
+ output.puts "#{short_padding}#{index.next}) #{example.full_description}"
25
+ output.puts "#{padding}Failure/Error: #{read_failed_line(exception, example).strip}"
22
26
  exception.message.split("\n").each do |line|
23
27
  output.puts "#{padding}#{red(line)}"
24
28
  end
25
29
  end
26
30
 
27
- format_backtrace(exception.backtrace, failed_example).each do |backtrace_info|
31
+ format_backtrace(exception.backtrace, example).each do |backtrace_info|
28
32
  output.puts grey("#{padding}# #{backtrace_info}")
29
33
  end
30
-
31
- output.puts
32
34
  end
33
35
  end
34
36
 
@@ -45,6 +47,7 @@ module RSpec
45
47
  end
46
48
 
47
49
  def dump_summary(duration, example_count, failure_count, pending_count)
50
+ super(duration, example_count, failure_count, pending_count)
48
51
  output.puts "\nFinished in #{format_seconds(duration)} seconds\n"
49
52
 
50
53
  output.puts colorise_summary(summary_line(example_count, failure_count, pending_count))
@@ -10,7 +10,7 @@ module RSpec
10
10
  end
11
11
 
12
12
  def example_group_started(example_group)
13
- super
13
+ super(example_group)
14
14
 
15
15
  example_group_chain.each_with_index do |nested_example_group, i|
16
16
  unless nested_example_group == @previous_nested_example_groups[i]
@@ -23,17 +23,17 @@ module RSpec
23
23
  end
24
24
 
25
25
  def example_passed(example)
26
- super
26
+ super(example)
27
27
  output.puts passed_output(example)
28
28
  end
29
29
 
30
30
  def example_pending(example)
31
- super
31
+ super(example)
32
32
  output.puts pending_output(example, example.execution_result[:pending_message])
33
33
  end
34
34
 
35
35
  def example_failed(example)
36
- super
36
+ super(example)
37
37
  output.puts failure_output(example, example.execution_result[:exception_encountered])
38
38
  end
39
39
 
@@ -15,7 +15,7 @@ module RSpec
15
15
  end
16
16
 
17
17
  def initialize(output)
18
- super
18
+ super(output)
19
19
  @example_group_number = 0
20
20
  @example_number = 0
21
21
  @header_red = nil
@@ -32,14 +32,14 @@ module RSpec
32
32
  end
33
33
 
34
34
  def start(example_count)
35
- super
35
+ super(example_count)
36
36
  @output.puts html_header
37
37
  @output.puts report_header
38
38
  @output.flush
39
39
  end
40
40
 
41
41
  def example_group_started(example_group)
42
- super
42
+ super(example_group)
43
43
  @example_group_red = false
44
44
  @example_group_number += 1
45
45
  unless example_group_number == 1
@@ -59,7 +59,7 @@ module RSpec
59
59
  end
60
60
 
61
61
  def example_started(example)
62
- super
62
+ super(example)
63
63
  @example_number += 1
64
64
  end
65
65
 
@@ -5,22 +5,22 @@ module RSpec
5
5
  class ProgressFormatter < BaseTextFormatter
6
6
 
7
7
  def example_passed(example)
8
- super
8
+ super(example)
9
9
  output.print green('.')
10
10
  end
11
11
 
12
12
  def example_pending(example)
13
- super
13
+ super(example)
14
14
  output.print yellow('*')
15
15
  end
16
16
 
17
17
  def example_failed(example)
18
- super
18
+ super(example)
19
19
  output.print red('F')
20
20
  end
21
21
 
22
22
  def start_dump
23
- super
23
+ super()
24
24
  output.puts
25
25
  end
26
26
 
@@ -67,7 +67,7 @@ module RSpec
67
67
  puts "No examples matching #{pattern} could be found"
68
68
  else
69
69
  puts spec_command.inspect if verbose
70
- unless system(spec_command)
70
+ unless ruby("-S #{spec_command}")
71
71
  STDERR.puts failure_message if failure_message
72
72
  raise("#{spec_command} failed") if fail_on_error
73
73
  end
@@ -0,0 +1,65 @@
1
+ module RSpec::Core
2
+ class Reporter
3
+ def initialize(*formatters)
4
+ @formatters = formatters
5
+ @failure_count = @pending_count = 0
6
+ end
7
+
8
+ def report(count)
9
+ start(count)
10
+ begin
11
+ yield self
12
+ stop
13
+ notify :start_dump
14
+ notify :dump_pending
15
+ notify :dump_failures
16
+ notify :dump_summary, @duration, @example_count, @failure_count, @pending_count
17
+ ensure
18
+ notify :close
19
+ end
20
+ end
21
+
22
+ def start(example_count)
23
+ @example_count = example_count
24
+ @start = Time.now
25
+ notify :start, example_count
26
+ end
27
+
28
+ def message(message)
29
+ notify :message, message
30
+ end
31
+
32
+ def example_group_started(group)
33
+ notify :example_group_started, group
34
+ end
35
+
36
+ def example_started(example)
37
+ notify :example_started, example
38
+ end
39
+
40
+ def example_passed(example)
41
+ notify :example_passed, example
42
+ end
43
+
44
+ def example_failed(example)
45
+ @failure_count += 1
46
+ notify :example_failed, example
47
+ end
48
+
49
+ def example_pending(example)
50
+ @pending_count += 1
51
+ notify :example_pending, example
52
+ end
53
+
54
+ def stop
55
+ @duration = Time.now - @start
56
+ notify :stop
57
+ end
58
+
59
+ def notify(method, *args, &block)
60
+ @formatters.each do |formatter|
61
+ formatter.send method, *args, &block
62
+ end
63
+ end
64
+ end
65
+ end
@@ -99,7 +99,7 @@ module RSpec
99
99
  example do
100
100
  self.class.class_eval do
101
101
  define_method(:subject) do
102
- attribute.to_s.split('.').inject(super) do |target, method|
102
+ attribute.to_s.split('.').inject(super()) do |target, method|
103
103
  target.send(method)
104
104
  end
105
105
  end