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.
- data/.gitignore +1 -0
- data/Upgrade.markdown +6 -0
- data/VERSION +1 -1
- data/features/example_groups/shared_example_group.feature +44 -7
- data/features/filtering/exclusion_filters.feature +79 -0
- data/features/filtering/inclusion_filters.feature +1 -1
- data/features/hooks/around_hooks.feature +28 -1
- data/features/pending/pending_examples.feature +2 -4
- data/features/spec_files/arbitrary_file_suffix.feature +13 -0
- data/lib/autotest/rspec2.rb +17 -17
- data/lib/rspec/core.rb +2 -2
- data/lib/rspec/core/command_line.rb +2 -1
- data/lib/rspec/core/configuration.rb +23 -9
- data/lib/rspec/core/deprecation.rb +1 -1
- data/lib/rspec/core/example_group.rb +11 -28
- data/lib/rspec/core/extensions.rb +4 -0
- data/lib/rspec/core/extensions/instance_eval_with_args.rb +39 -0
- data/lib/rspec/core/{kernel_extensions.rb → extensions/kernel.rb} +0 -0
- data/lib/rspec/core/extensions/module_eval_with_args.rb +54 -0
- data/lib/rspec/core/{object_extensions.rb → extensions/object.rb} +3 -1
- data/lib/rspec/core/formatters/base_formatter.rb +20 -43
- data/lib/rspec/core/formatters/base_text_formatter.rb +13 -10
- data/lib/rspec/core/formatters/documentation_formatter.rb +4 -4
- data/lib/rspec/core/formatters/html_formatter.rb +4 -4
- data/lib/rspec/core/formatters/progress_formatter.rb +4 -4
- data/lib/rspec/core/rake_task.rb +1 -1
- data/lib/rspec/core/reporter.rb +65 -0
- data/lib/rspec/core/subject.rb +1 -1
- data/lib/rspec/core/world.rb +11 -3
- data/rspec-core.gemspec +26 -14
- data/spec/autotest/failed_results_re_spec.rb +14 -23
- data/spec/autotest/rspec_spec.rb +1 -1
- data/spec/rspec/core/configuration_spec.rb +74 -9
- data/spec/rspec/core/drb_command_line_spec.rb +2 -2
- data/spec/rspec/core/example_group_spec.rb +13 -7
- data/spec/rspec/core/example_spec.rb +4 -4
- data/spec/rspec/core/formatters/html_formatted-1.8.6.html +280 -0
- data/spec/rspec/core/formatters/html_formatter_spec.rb +5 -3
- data/spec/rspec/core/formatters/progress_formatter_spec.rb +3 -3
- data/spec/rspec/core/formatters/snippet_extractor_spec.rb +2 -2
- data/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html +280 -0
- data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +5 -3
- data/spec/rspec/core/hooks_filtering_spec.rb +104 -0
- data/spec/rspec/core/reporter_spec.rb +34 -0
- data/spec/rspec/core/shared_example_group_spec.rb +22 -2
- data/spec/rspec/core/world_spec.rb +10 -8
- data/spec/rspec/{core/core_spec.rb → core_spec.rb} +0 -0
- data/spec/ruby_forker.rb +1 -1
- data/spec/spec_helper.rb +2 -2
- metadata +39 -33
@@ -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
|
File without changes
|
@@ -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
|
@@ -5,47 +5,19 @@ module RSpec
|
|
5
5
|
class BaseFormatter
|
6
6
|
include Helpers
|
7
7
|
attr_accessor :example_group
|
8
|
-
attr_reader :
|
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
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
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}) #{
|
18
|
-
output.puts "#{padding}Expected pending '#{
|
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}) #{
|
21
|
-
output.puts "#{padding}Failure/Error: #{read_failed_line(exception,
|
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,
|
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
|
|
data/lib/rspec/core/rake_task.rb
CHANGED
@@ -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
|
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
|
data/lib/rspec/core/subject.rb
CHANGED
@@ -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
|