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.
- 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
|