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

Sign up to get free protection for your applications and to get access to all the features.
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