rspec-core 2.8.0 → 2.9.0
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/.document +5 -0
- data/.yardopts +3 -0
- data/Changelog.md +493 -0
- data/README.md +1 -1
- data/features/mock_framework_integration/use_flexmock.feature +2 -2
- data/features/step_definitions/additional_cli_steps.rb +2 -2
- data/features/subject/attribute_of_subject.feature +4 -2
- data/features/subject/explicit_subject.feature +6 -2
- data/features/subject/implicit_receiver.feature +1 -1
- data/features/subject/implicit_subject.feature +40 -7
- data/lib/autotest/rspec2.rb +1 -1
- data/lib/rspec/core/configuration.rb +53 -5
- data/lib/rspec/core/configuration_options.rb +5 -2
- data/lib/rspec/core/drb_options.rb +3 -1
- data/lib/rspec/core/filter_manager.rb +1 -1
- data/lib/rspec/core/formatters/base_text_formatter.rb +1 -5
- data/lib/rspec/core/formatters/documentation_formatter.rb +4 -8
- data/lib/rspec/core/formatters/helpers.rb +15 -0
- data/lib/rspec/core/hooks.rb +3 -1
- data/lib/rspec/core/metadata.rb +6 -11
- data/lib/rspec/core/runner.rb +4 -14
- data/lib/rspec/core/subject.rb +15 -7
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/world.rb +7 -7
- data/lib/rspec/core.rb +1 -1
- data/spec/autotest/rspec_spec.rb +1 -1
- data/spec/rspec/core/configuration_options_spec.rb +8 -5
- data/spec/rspec/core/configuration_spec.rb +38 -10
- data/spec/rspec/core/example_group_spec.rb +16 -0
- data/spec/rspec/core/formatters/documentation_formatter_spec.rb +23 -1
- data/spec/rspec/core/formatters/helpers_spec.rb +20 -0
- data/spec/rspec/core/metadata_spec.rb +3 -4
- data/spec/rspec/core/shared_example_group_spec.rb +2 -2
- data/spec/rspec/core/subject_spec.rb +29 -0
- data/spec/rspec/core/world_spec.rb +11 -1
- metadata +157 -14
- data/lib/rspec/monkey/spork/test_framework/rspec.rb +0 -10
- data/lib/rspec/monkey.rb +0 -1
|
@@ -534,10 +534,26 @@ EOM
|
|
|
534
534
|
# or config files (e.g. `.rspec`).
|
|
535
535
|
#
|
|
536
536
|
# @example
|
|
537
|
-
#
|
|
537
|
+
# # given this declaration
|
|
538
|
+
# describe "something", :foo => 'bar' do
|
|
539
|
+
# # ...
|
|
540
|
+
# end
|
|
541
|
+
#
|
|
542
|
+
# # any of the following will include that group
|
|
543
|
+
# config.filter_run_including :foo => 'bar'
|
|
544
|
+
# config.filter_run_including :foo => /^ba/
|
|
545
|
+
# config.filter_run_including :foo => lambda {|v| v == 'bar'}
|
|
546
|
+
# config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'}
|
|
547
|
+
#
|
|
548
|
+
# # given a proc with an arity of 1, the lambda is passed the value related to the key, e.g.
|
|
549
|
+
# config.filter_run_including :foo => lambda {|v| v == 'bar'}
|
|
550
|
+
#
|
|
551
|
+
# # given a proc with an arity of 2, the lambda is passed the value related to the key,
|
|
552
|
+
# # and the metadata itself e.g.
|
|
553
|
+
# config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'}
|
|
538
554
|
#
|
|
539
555
|
# # with treat_symbols_as_metadata_keys_with_true_values = true
|
|
540
|
-
# filter_run_including :foo #
|
|
556
|
+
# filter_run_including :foo # same as filter_run_including :foo => true
|
|
541
557
|
def filter_run_including(*args)
|
|
542
558
|
filter_manager.include_with_low_priority build_metadata_hash_from(args)
|
|
543
559
|
end
|
|
@@ -576,10 +592,26 @@ EOM
|
|
|
576
592
|
# or config files (e.g. `.rspec`).
|
|
577
593
|
#
|
|
578
594
|
# @example
|
|
579
|
-
#
|
|
595
|
+
# # given this declaration
|
|
596
|
+
# describe "something", :foo => 'bar' do
|
|
597
|
+
# # ...
|
|
598
|
+
# end
|
|
599
|
+
#
|
|
600
|
+
# # any of the following will exclude that group
|
|
601
|
+
# config.filter_run_excluding :foo => 'bar'
|
|
602
|
+
# config.filter_run_excluding :foo => /^ba/
|
|
603
|
+
# config.filter_run_excluding :foo => lambda {|v| v == 'bar'}
|
|
604
|
+
# config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'}
|
|
605
|
+
#
|
|
606
|
+
# # given a proc with an arity of 1, the lambda is passed the value related to the key, e.g.
|
|
607
|
+
# config.filter_run_excluding :foo => lambda {|v| v == 'bar'}
|
|
608
|
+
#
|
|
609
|
+
# # given a proc with an arity of 2, the lambda is passed the value related to the key,
|
|
610
|
+
# # and the metadata itself e.g.
|
|
611
|
+
# config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'}
|
|
580
612
|
#
|
|
581
613
|
# # with treat_symbols_as_metadata_keys_with_true_values = true
|
|
582
|
-
# filter_run_excluding :foo #
|
|
614
|
+
# filter_run_excluding :foo # same as filter_run_excluding :foo => true
|
|
583
615
|
def filter_run_excluding(*args)
|
|
584
616
|
filter_manager.exclude_with_low_priority build_metadata_hash_from(args)
|
|
585
617
|
end
|
|
@@ -677,7 +709,23 @@ EOM
|
|
|
677
709
|
def configure_group(group)
|
|
678
710
|
include_or_extend_modules.each do |include_or_extend, mod, filters|
|
|
679
711
|
next unless filters.empty? || group.any_apply?(filters)
|
|
680
|
-
|
|
712
|
+
send("safe_#{include_or_extend}", mod, group)
|
|
713
|
+
end
|
|
714
|
+
end
|
|
715
|
+
|
|
716
|
+
# @private
|
|
717
|
+
def safe_include(mod, host)
|
|
718
|
+
host.send(:include,mod) unless host < mod
|
|
719
|
+
end
|
|
720
|
+
|
|
721
|
+
# @private
|
|
722
|
+
if RUBY_VERSION.to_f >= 1.9
|
|
723
|
+
def safe_extend(mod, host)
|
|
724
|
+
host.extend(mod) unless (class << host; self; end) < mod
|
|
725
|
+
end
|
|
726
|
+
else
|
|
727
|
+
def safe_extend(mod, host)
|
|
728
|
+
host.extend(mod) unless (class << host; self; end).included_modules.include?(mod)
|
|
681
729
|
end
|
|
682
730
|
end
|
|
683
731
|
|
|
@@ -33,12 +33,15 @@ module RSpec
|
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def filter_manager
|
|
36
|
-
@filter_manager ||=
|
|
36
|
+
@filter_manager ||= RSpec::configuration.filter_manager
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
private
|
|
40
40
|
|
|
41
|
-
NON_FORCED_OPTIONS = [
|
|
41
|
+
NON_FORCED_OPTIONS = [
|
|
42
|
+
:debug, :requires, :libs, :profile, :drb, :files_or_directories_to_run,
|
|
43
|
+
:line_numbers, :full_description, :full_backtrace, :tty
|
|
44
|
+
].to_set
|
|
42
45
|
|
|
43
46
|
def force?(key)
|
|
44
47
|
!NON_FORCED_OPTIONS.include?(key)
|
|
@@ -52,9 +52,11 @@ module RSpec::Core
|
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
|
|
55
|
+
CONDITIONAL_FILTERS = [:if, :unless]
|
|
56
|
+
|
|
55
57
|
def add_filter(argv, name, hash)
|
|
56
58
|
hash.each_pair do |k, v|
|
|
57
|
-
next if
|
|
59
|
+
next if CONDITIONAL_FILTERS.include?(k)
|
|
58
60
|
tag = name == :inclusion ? k.to_s : "~#{k}"
|
|
59
61
|
tag << ":#{v}" if v.is_a?(String)
|
|
60
62
|
argv << "--tag" << tag
|
|
@@ -67,7 +67,7 @@ module RSpec
|
|
|
67
67
|
# @see Configuration#filter_run_excluding
|
|
68
68
|
class FilterManager
|
|
69
69
|
DEFAULT_EXCLUSIONS = {
|
|
70
|
-
:if => lambda { |value
|
|
70
|
+
:if => lambda { |value| !value },
|
|
71
71
|
:unless => lambda { |value| value }
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -35,7 +35,7 @@ module RSpec
|
|
|
35
35
|
super(duration, example_count, failure_count, pending_count)
|
|
36
36
|
# Don't print out profiled info if there are failures, it just clutters the output
|
|
37
37
|
dump_profile if profile_examples? && failure_count == 0
|
|
38
|
-
output.puts "\nFinished in #{
|
|
38
|
+
output.puts "\nFinished in #{format_duration(duration)}\n"
|
|
39
39
|
output.puts colorise_summary(summary_line(example_count, failure_count, pending_count))
|
|
40
40
|
dump_commands_to_rerun_failed_examples
|
|
41
41
|
end
|
|
@@ -142,10 +142,6 @@ module RSpec
|
|
|
142
142
|
|
|
143
143
|
private
|
|
144
144
|
|
|
145
|
-
def pluralize(count, string)
|
|
146
|
-
"#{count} #{string}#{'s' unless count == 1}"
|
|
147
|
-
end
|
|
148
|
-
|
|
149
145
|
def format_caller(caller_info)
|
|
150
146
|
backtrace_line(caller_info.to_s.split(':in `block').first)
|
|
151
147
|
end
|
|
@@ -3,9 +3,7 @@ require 'rspec/core/formatters/base_text_formatter'
|
|
|
3
3
|
module RSpec
|
|
4
4
|
module Core
|
|
5
5
|
module Formatters
|
|
6
|
-
|
|
7
6
|
class DocumentationFormatter < BaseTextFormatter
|
|
8
|
-
|
|
9
7
|
def initialize(output)
|
|
10
8
|
super(output)
|
|
11
9
|
@group_level = 0
|
|
@@ -15,7 +13,7 @@ module RSpec
|
|
|
15
13
|
super(example_group)
|
|
16
14
|
|
|
17
15
|
output.puts if @group_level == 0
|
|
18
|
-
output.puts "#{current_indentation}#{example_group.description}"
|
|
16
|
+
output.puts "#{current_indentation}#{example_group.description.strip}"
|
|
19
17
|
|
|
20
18
|
@group_level += 1
|
|
21
19
|
end
|
|
@@ -40,7 +38,7 @@ module RSpec
|
|
|
40
38
|
end
|
|
41
39
|
|
|
42
40
|
def failure_output(example, exception)
|
|
43
|
-
red("#{current_indentation}#{example.description} (FAILED - #{next_failure_index})")
|
|
41
|
+
red("#{current_indentation}#{example.description.strip} (FAILED - #{next_failure_index})")
|
|
44
42
|
end
|
|
45
43
|
|
|
46
44
|
def next_failure_index
|
|
@@ -49,11 +47,11 @@ module RSpec
|
|
|
49
47
|
end
|
|
50
48
|
|
|
51
49
|
def passed_output(example)
|
|
52
|
-
green("#{current_indentation}#{example.description}")
|
|
50
|
+
green("#{current_indentation}#{example.description.strip}")
|
|
53
51
|
end
|
|
54
52
|
|
|
55
53
|
def pending_output(example, message)
|
|
56
|
-
yellow("#{current_indentation}#{example.description} (PENDING: #{message})")
|
|
54
|
+
yellow("#{current_indentation}#{example.description.strip} (PENDING: #{message})")
|
|
57
55
|
end
|
|
58
56
|
|
|
59
57
|
def current_indentation
|
|
@@ -63,9 +61,7 @@ module RSpec
|
|
|
63
61
|
def example_group_chain
|
|
64
62
|
example_group.ancestors.reverse
|
|
65
63
|
end
|
|
66
|
-
|
|
67
64
|
end
|
|
68
|
-
|
|
69
65
|
end
|
|
70
66
|
end
|
|
71
67
|
end
|
|
@@ -6,6 +6,17 @@ module RSpec
|
|
|
6
6
|
SUB_SECOND_PRECISION = 5
|
|
7
7
|
DEFAULT_PRECISION = 2
|
|
8
8
|
|
|
9
|
+
def format_duration(duration)
|
|
10
|
+
if duration > 60
|
|
11
|
+
minutes = duration.to_i / 60
|
|
12
|
+
seconds = duration - minutes * 60
|
|
13
|
+
|
|
14
|
+
"#{pluralize(minutes, 'minute')} #{format_seconds(seconds)} seconds"
|
|
15
|
+
else
|
|
16
|
+
"#{format_seconds(duration)} seconds"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
9
20
|
def format_seconds(float)
|
|
10
21
|
precision ||= (float < 1) ? SUB_SECOND_PRECISION : DEFAULT_PRECISION
|
|
11
22
|
formatted = sprintf("%.#{precision}f", float)
|
|
@@ -17,6 +28,10 @@ module RSpec
|
|
|
17
28
|
stripped.empty? ? "0" : stripped
|
|
18
29
|
end
|
|
19
30
|
|
|
31
|
+
def pluralize(count, string)
|
|
32
|
+
"#{count} #{string}#{'s' unless count == 1}"
|
|
33
|
+
end
|
|
34
|
+
|
|
20
35
|
end
|
|
21
36
|
|
|
22
37
|
end
|
data/lib/rspec/core/hooks.rb
CHANGED
|
@@ -398,8 +398,10 @@ module RSpec
|
|
|
398
398
|
|
|
399
399
|
private
|
|
400
400
|
|
|
401
|
+
SCOPES = [:each, :all, :suite]
|
|
402
|
+
|
|
401
403
|
def scope_and_options_from(*args)
|
|
402
|
-
scope = if
|
|
404
|
+
scope = if SCOPES.include?(args.first)
|
|
403
405
|
args.shift
|
|
404
406
|
elsif args.any? { |a| a.is_a?(Symbol) }
|
|
405
407
|
raise ArgumentError.new("You must explicitly give a scope (:each, :all, or :suite) when using symbols as metadata for a hook.")
|
data/lib/rspec/core/metadata.rb
CHANGED
|
@@ -102,8 +102,8 @@ module RSpec
|
|
|
102
102
|
|
|
103
103
|
def described_class
|
|
104
104
|
container_stack.each do |g|
|
|
105
|
-
return g[:describes] if g.has_key?(:describes)
|
|
106
105
|
return g[:described_class] if g.has_key?(:described_class)
|
|
106
|
+
return g[:describes] if g.has_key?(:describes)
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
container_stack.reverse.each do |g|
|
|
@@ -174,20 +174,15 @@ module RSpec
|
|
|
174
174
|
return metadata.location_filter_applies?(value) if key == :locations
|
|
175
175
|
return metadata.filters_apply?(key, value) if Hash === value
|
|
176
176
|
|
|
177
|
+
return false unless metadata.has_key?(key)
|
|
178
|
+
|
|
177
179
|
case value
|
|
178
180
|
when Regexp
|
|
179
181
|
metadata[key] =~ value
|
|
180
182
|
when Proc
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
# { } # => run the example
|
|
185
|
-
# { :if => nil } # => exclude the example
|
|
186
|
-
# The value of metadata[:if] is the same in these two cases but
|
|
187
|
-
# they need to be treated differently.
|
|
188
|
-
value.call(metadata[key], metadata) rescue false
|
|
189
|
-
else
|
|
190
|
-
value.call(metadata[key]) rescue false
|
|
183
|
+
case value.arity
|
|
184
|
+
when 1 then value.call(metadata[key])
|
|
185
|
+
when 2 then value.call(metadata[key], metadata)
|
|
191
186
|
end
|
|
192
187
|
else
|
|
193
188
|
metadata[key].to_s == value.to_s
|
data/lib/rspec/core/runner.rb
CHANGED
|
@@ -7,7 +7,7 @@ module RSpec
|
|
|
7
7
|
# Register an at_exit hook that runs the suite.
|
|
8
8
|
def self.autorun
|
|
9
9
|
return if autorun_disabled? || installed_at_exit? || running_in_drb?
|
|
10
|
-
at_exit { exit run(ARGV, $stderr, $stdout).to_i }
|
|
10
|
+
at_exit { exit run(ARGV, $stderr, $stdout).to_i unless $! }
|
|
11
11
|
@installed_at_exit = true
|
|
12
12
|
end
|
|
13
13
|
AT_EXIT_HOOK_BACKTRACE_LINE = "#{__FILE__}:#{__LINE__ - 2}:in `autorun'"
|
|
@@ -60,27 +60,17 @@ module RSpec
|
|
|
60
60
|
|
|
61
61
|
if options.options[:drb]
|
|
62
62
|
begin
|
|
63
|
-
|
|
63
|
+
DRbCommandLine.new(options).run(err, out)
|
|
64
64
|
rescue DRb::DRbConnError
|
|
65
65
|
err.puts "No DRb server is running. Running in local process instead ..."
|
|
66
|
-
|
|
66
|
+
CommandLine.new(options).run(err, out)
|
|
67
67
|
end
|
|
68
68
|
else
|
|
69
|
-
|
|
69
|
+
CommandLine.new(options).run(err, out)
|
|
70
70
|
end
|
|
71
71
|
ensure
|
|
72
72
|
RSpec.reset
|
|
73
73
|
end
|
|
74
|
-
|
|
75
|
-
def self.run_over_drb(options, err, out)
|
|
76
|
-
DRbCommandLine.new(options).run(err, out)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def self.run_in_process(options, err, out)
|
|
80
|
-
CommandLine.new(options, RSpec::configuration, RSpec::world).run(err, out)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
74
|
end
|
|
84
|
-
|
|
85
75
|
end
|
|
86
76
|
end
|
data/lib/rspec/core/subject.rb
CHANGED
|
@@ -67,6 +67,16 @@ module RSpec
|
|
|
67
67
|
end
|
|
68
68
|
rescue LoadError
|
|
69
69
|
end
|
|
70
|
+
|
|
71
|
+
def _attribute_chain(attribute)
|
|
72
|
+
attribute.to_s.split('.')
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def _nested_attribute(subject, attribute)
|
|
76
|
+
_attribute_chain(attribute).inject(subject) do |subject, attr|
|
|
77
|
+
subject.send(attr)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
70
80
|
end
|
|
71
81
|
|
|
72
82
|
module ExampleGroupMethods
|
|
@@ -122,13 +132,11 @@ module RSpec
|
|
|
122
132
|
example do
|
|
123
133
|
self.class.class_eval do
|
|
124
134
|
define_method(:subject) do
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
end
|
|
131
|
-
end
|
|
135
|
+
if defined?(@_subject)
|
|
136
|
+
@_subject
|
|
137
|
+
else
|
|
138
|
+
@_subject = Array === attribute ? super()[*attribute] : _nested_attribute(super(), attribute)
|
|
139
|
+
end
|
|
132
140
|
end
|
|
133
141
|
end
|
|
134
142
|
instance_eval(&block)
|
data/lib/rspec/core/version.rb
CHANGED
data/lib/rspec/core/world.rb
CHANGED
|
@@ -4,12 +4,13 @@ module RSpec
|
|
|
4
4
|
|
|
5
5
|
include RSpec::Core::Hooks
|
|
6
6
|
|
|
7
|
-
attr_reader :example_groups, :
|
|
8
|
-
|
|
7
|
+
attr_reader :example_groups, :shared_example_groups, :filtered_examples
|
|
8
|
+
attr_accessor :wants_to_quit
|
|
9
9
|
|
|
10
10
|
def initialize(configuration=RSpec.configuration)
|
|
11
11
|
@configuration = configuration
|
|
12
12
|
@example_groups = [].extend(Extensions::Ordered)
|
|
13
|
+
@shared_example_groups = {}
|
|
13
14
|
@filtered_examples = Hash.new { |hash,group|
|
|
14
15
|
hash[group] = begin
|
|
15
16
|
examples = group.examples.dup
|
|
@@ -22,6 +23,7 @@ module RSpec
|
|
|
22
23
|
|
|
23
24
|
def reset
|
|
24
25
|
example_groups.clear
|
|
26
|
+
shared_example_groups.clear
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
def filter_manager
|
|
@@ -45,12 +47,10 @@ module RSpec
|
|
|
45
47
|
@configuration.configure_group(group)
|
|
46
48
|
end
|
|
47
49
|
|
|
48
|
-
def shared_example_groups
|
|
49
|
-
@shared_example_groups ||= {}
|
|
50
|
-
end
|
|
51
|
-
|
|
52
50
|
def example_count
|
|
53
|
-
example_groups.collect {|g| g.descendants}.flatten.inject(0)
|
|
51
|
+
example_groups.collect {|g| g.descendants}.flatten.inject(0) do |sum, g|
|
|
52
|
+
sum += g.filtered_examples.size
|
|
53
|
+
end
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
def preceding_declaration_line(filter_line)
|
data/lib/rspec/core.rb
CHANGED
|
@@ -10,6 +10,7 @@ else
|
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
+
require 'set'
|
|
13
14
|
require_rspec 'core/filter_manager'
|
|
14
15
|
require_rspec 'core/dsl'
|
|
15
16
|
require_rspec 'core/extensions'
|
|
@@ -104,4 +105,3 @@ module RSpec
|
|
|
104
105
|
end
|
|
105
106
|
|
|
106
107
|
require_rspec 'core/backward_compatibility'
|
|
107
|
-
require_rspec 'monkey'
|
data/spec/autotest/rspec_spec.rb
CHANGED
|
@@ -30,7 +30,7 @@ describe Autotest::Rspec2 do
|
|
|
30
30
|
|
|
31
31
|
it "makes the appropriate test command" do
|
|
32
32
|
actual_command = rspec_autotest.make_test_cmd(@files_to_test)
|
|
33
|
-
expected_command = /#{ruby_cmd}
|
|
33
|
+
expected_command = /#{ruby_cmd}.*'#{spec_cmd}' (.*)/
|
|
34
34
|
|
|
35
35
|
actual_command.should match(expected_command)
|
|
36
36
|
|
|
@@ -74,13 +74,9 @@ describe RSpec::Core::ConfigurationOptions do
|
|
|
74
74
|
["--pattern", "foo/bar", :pattern, "foo/bar"],
|
|
75
75
|
["--failure-exit-code", "37", :failure_exit_code, 37],
|
|
76
76
|
["--default_path", "behavior", :default_path, "behavior"],
|
|
77
|
-
["--drb", nil, :drb, true],
|
|
78
77
|
["--order", "rand", :order, "rand"],
|
|
79
78
|
["--seed", "37", :order, "rand:37"],
|
|
80
|
-
["--drb-port", "37", :drb_port, 37]
|
|
81
|
-
["--backtrace", nil, :full_backtrace, true],
|
|
82
|
-
["--profile", nil, :profile_examples, true],
|
|
83
|
-
["--tty", nil, :tty, true]
|
|
79
|
+
["--drb-port", "37", :drb_port, 37]
|
|
84
80
|
].each do |cli_option, cli_value, config_key, config_value|
|
|
85
81
|
it "forces #{config_key}" do
|
|
86
82
|
opts = config_options_object(*[cli_option, cli_value].compact)
|
|
@@ -305,6 +301,13 @@ describe RSpec::Core::ConfigurationOptions do
|
|
|
305
301
|
end
|
|
306
302
|
end
|
|
307
303
|
|
|
304
|
+
describe "#filter_manager" do
|
|
305
|
+
it "returns the same object as RSpec::configuration.filter_manager" do
|
|
306
|
+
config_options_object.filter_manager.
|
|
307
|
+
should be(RSpec::configuration.filter_manager)
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
308
311
|
describe "sources: ~/.rspec, ./.rspec, custom, CLI, and SPEC_OPTS" do
|
|
309
312
|
before(:each) do
|
|
310
313
|
FileUtils.mkpath(File.expand_path("~"))
|
|
@@ -713,20 +713,16 @@ module RSpec::Core
|
|
|
713
713
|
end
|
|
714
714
|
|
|
715
715
|
describe "the default :if filter" do
|
|
716
|
-
it "does not exclude a spec with
|
|
717
|
-
config.exclusion_filter[:if].call(
|
|
716
|
+
it "does not exclude a spec with { :if => true } metadata" do
|
|
717
|
+
config.exclusion_filter[:if].call(true).should be_false
|
|
718
718
|
end
|
|
719
719
|
|
|
720
|
-
it "
|
|
721
|
-
config.exclusion_filter[:if].call(
|
|
720
|
+
it "excludes a spec with { :if => false } metadata" do
|
|
721
|
+
config.exclusion_filter[:if].call(false).should be_true
|
|
722
722
|
end
|
|
723
723
|
|
|
724
|
-
it "excludes a spec with
|
|
725
|
-
config.exclusion_filter[:if].call(
|
|
726
|
-
end
|
|
727
|
-
|
|
728
|
-
it "excludes a spec with { :if => nil } metadata" do
|
|
729
|
-
config.exclusion_filter[:if].call(false, {:if => nil}).should be_true
|
|
724
|
+
it "excludes a spec with { :if => nil } metadata" do
|
|
725
|
+
config.exclusion_filter[:if].call(nil).should be_true
|
|
730
726
|
end
|
|
731
727
|
end
|
|
732
728
|
|
|
@@ -1005,6 +1001,38 @@ module RSpec::Core
|
|
|
1005
1001
|
group.included_modules.should include(mod1)
|
|
1006
1002
|
group.included_modules.should include(mod2)
|
|
1007
1003
|
end
|
|
1004
|
+
|
|
1005
|
+
module IncludeOrExtendMeOnce
|
|
1006
|
+
def self.included(host)
|
|
1007
|
+
raise "included again" if host.instance_methods.include?(:foobar)
|
|
1008
|
+
host.class_eval { def foobar; end }
|
|
1009
|
+
end
|
|
1010
|
+
|
|
1011
|
+
def self.extended(host)
|
|
1012
|
+
raise "extended again" if host.respond_to?(:foobar)
|
|
1013
|
+
def host.foobar; end
|
|
1014
|
+
end
|
|
1015
|
+
end
|
|
1016
|
+
|
|
1017
|
+
it "doesn't include a module when already included in ancestor" do
|
|
1018
|
+
config.include(IncludeOrExtendMeOnce, :foo => :bar)
|
|
1019
|
+
|
|
1020
|
+
group = ExampleGroup.describe("group", :foo => :bar)
|
|
1021
|
+
child = group.describe("child")
|
|
1022
|
+
|
|
1023
|
+
config.configure_group(group)
|
|
1024
|
+
config.configure_group(child)
|
|
1025
|
+
end
|
|
1026
|
+
|
|
1027
|
+
it "doesn't extend when ancestor is already extended with same module" do
|
|
1028
|
+
config.extend(IncludeOrExtendMeOnce, :foo => :bar)
|
|
1029
|
+
|
|
1030
|
+
group = ExampleGroup.describe("group", :foo => :bar)
|
|
1031
|
+
child = group.describe("child")
|
|
1032
|
+
|
|
1033
|
+
config.configure_group(group)
|
|
1034
|
+
config.configure_group(child)
|
|
1035
|
+
end
|
|
1008
1036
|
end
|
|
1009
1037
|
|
|
1010
1038
|
describe "#alias_example_to" do
|
|
@@ -293,6 +293,22 @@ module RSpec::Core
|
|
|
293
293
|
group.run.should be_true
|
|
294
294
|
end
|
|
295
295
|
end
|
|
296
|
+
|
|
297
|
+
context "and metadata redefinition after `described_class` call" do
|
|
298
|
+
it "is the redefined level constant" do
|
|
299
|
+
group = ExampleGroup.describe(String) do
|
|
300
|
+
described_class
|
|
301
|
+
metadata[:example_group][:described_class] = Object
|
|
302
|
+
describe :symbol do
|
|
303
|
+
example "described_class is Object" do
|
|
304
|
+
described_class.should eq(Object)
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
group.run.should be_true
|
|
310
|
+
end
|
|
311
|
+
end
|
|
296
312
|
end
|
|
297
313
|
|
|
298
314
|
context "in a nested group" do
|
|
@@ -28,7 +28,6 @@ module RSpec::Core::Formatters
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
it "represents nested group using hierarchy tree" do
|
|
31
|
-
|
|
32
31
|
output = StringIO.new
|
|
33
32
|
RSpec.configuration.stub(:color_enabled?) { false }
|
|
34
33
|
|
|
@@ -60,6 +59,29 @@ root
|
|
|
60
59
|
context 2
|
|
61
60
|
nested example 2.1
|
|
62
61
|
nested example 2.2
|
|
62
|
+
")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "strips whitespace for each row" do
|
|
66
|
+
output = StringIO.new
|
|
67
|
+
RSpec.configuration.stub(:color_enabled?) { false }
|
|
68
|
+
|
|
69
|
+
formatter = RSpec::Core::Formatters::DocumentationFormatter.new(output)
|
|
70
|
+
|
|
71
|
+
group = RSpec::Core::ExampleGroup.describe(" root ")
|
|
72
|
+
context1 = group.describe(" nested ")
|
|
73
|
+
context1.example(" example 1 ") {}
|
|
74
|
+
context1.example(" example 2 ", :pending => true){}
|
|
75
|
+
context1.example(" example 3 ") { fail }
|
|
76
|
+
|
|
77
|
+
group.run(RSpec::Core::Reporter.new(formatter))
|
|
78
|
+
|
|
79
|
+
output.string.should eql("
|
|
80
|
+
root
|
|
81
|
+
nested
|
|
82
|
+
example 1
|
|
83
|
+
example 2 (PENDING: No reason given)
|
|
84
|
+
example 3 (FAILED - 1)
|
|
63
85
|
")
|
|
64
86
|
end
|
|
65
87
|
end
|
|
@@ -4,6 +4,26 @@ require 'rspec/core/formatters/helpers'
|
|
|
4
4
|
describe RSpec::Core::Formatters::Helpers do
|
|
5
5
|
let(:helper) { Object.new.extend(RSpec::Core::Formatters::Helpers) }
|
|
6
6
|
|
|
7
|
+
describe "format duration" do
|
|
8
|
+
context '> 60 and < 120' do
|
|
9
|
+
it "returns 'x minute xx seconds' formatted string" do
|
|
10
|
+
helper.format_duration(70.14).should eq("1 minute 10.14 seconds")
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
context '> 120' do
|
|
15
|
+
it "returns 'x minutes xx seconds' formatted string" do
|
|
16
|
+
helper.format_duration(135.14).should eq("2 minutes 15.14 seconds")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context '< 60' do
|
|
21
|
+
it "returns 'xx seconds' formatted string" do
|
|
22
|
+
helper.format_duration(45.5).should eq("45.5 seconds")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
7
27
|
describe "format seconds" do
|
|
8
28
|
context "sub second times" do
|
|
9
29
|
it "returns 5 digits of precision" do
|
|
@@ -126,10 +126,9 @@ module RSpec
|
|
|
126
126
|
example_metadata.filter_applies?(:if, lambda { |v| !v }).should be_false
|
|
127
127
|
end
|
|
128
128
|
|
|
129
|
-
it "
|
|
130
|
-
|
|
131
|
-
example_metadata.filter_applies?(:
|
|
132
|
-
passed_metadata.should eq(example_metadata)
|
|
129
|
+
it "matches a proc with an arity of 2" do
|
|
130
|
+
example_metadata[:foo] = nil
|
|
131
|
+
example_metadata.filter_applies?(:foo, lambda { |v, m| m == example_metadata }).should be_true
|
|
133
132
|
end
|
|
134
133
|
|
|
135
134
|
context "with an Array" do
|
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
module RSpec::Core
|
|
4
4
|
describe SharedExampleGroup do
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
ExampleModule = Module.new
|
|
7
7
|
ExampleClass = Class.new
|
|
8
8
|
|
|
@@ -19,7 +19,7 @@ module RSpec::Core
|
|
|
19
19
|
group.send(method_name, 'shared group') {}
|
|
20
20
|
end.should raise_error(ArgumentError, "Shared example group 'shared group' already exists")
|
|
21
21
|
end
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
["name", :name, ExampleModule, ExampleClass].each do |object|
|
|
24
24
|
type = object.class.name.downcase
|
|
25
25
|
context "given a #{type}" do
|