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.
Files changed (38) hide show
  1. data/.document +5 -0
  2. data/.yardopts +3 -0
  3. data/Changelog.md +493 -0
  4. data/README.md +1 -1
  5. data/features/mock_framework_integration/use_flexmock.feature +2 -2
  6. data/features/step_definitions/additional_cli_steps.rb +2 -2
  7. data/features/subject/attribute_of_subject.feature +4 -2
  8. data/features/subject/explicit_subject.feature +6 -2
  9. data/features/subject/implicit_receiver.feature +1 -1
  10. data/features/subject/implicit_subject.feature +40 -7
  11. data/lib/autotest/rspec2.rb +1 -1
  12. data/lib/rspec/core/configuration.rb +53 -5
  13. data/lib/rspec/core/configuration_options.rb +5 -2
  14. data/lib/rspec/core/drb_options.rb +3 -1
  15. data/lib/rspec/core/filter_manager.rb +1 -1
  16. data/lib/rspec/core/formatters/base_text_formatter.rb +1 -5
  17. data/lib/rspec/core/formatters/documentation_formatter.rb +4 -8
  18. data/lib/rspec/core/formatters/helpers.rb +15 -0
  19. data/lib/rspec/core/hooks.rb +3 -1
  20. data/lib/rspec/core/metadata.rb +6 -11
  21. data/lib/rspec/core/runner.rb +4 -14
  22. data/lib/rspec/core/subject.rb +15 -7
  23. data/lib/rspec/core/version.rb +1 -1
  24. data/lib/rspec/core/world.rb +7 -7
  25. data/lib/rspec/core.rb +1 -1
  26. data/spec/autotest/rspec_spec.rb +1 -1
  27. data/spec/rspec/core/configuration_options_spec.rb +8 -5
  28. data/spec/rspec/core/configuration_spec.rb +38 -10
  29. data/spec/rspec/core/example_group_spec.rb +16 -0
  30. data/spec/rspec/core/formatters/documentation_formatter_spec.rb +23 -1
  31. data/spec/rspec/core/formatters/helpers_spec.rb +20 -0
  32. data/spec/rspec/core/metadata_spec.rb +3 -4
  33. data/spec/rspec/core/shared_example_group_spec.rb +2 -2
  34. data/spec/rspec/core/subject_spec.rb +29 -0
  35. data/spec/rspec/core/world_spec.rb +11 -1
  36. metadata +157 -14
  37. data/lib/rspec/monkey/spork/test_framework/rspec.rb +0 -10
  38. 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
- # filter_run_including :x => 'y'
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 # results in {:foo => true}
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
- # filter_run_excluding :x => 'y'
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 # results in {:foo => true}
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
- group.send(include_or_extend, mod)
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 ||= FilterManager.new
36
+ @filter_manager ||= RSpec::configuration.filter_manager
37
37
  end
38
38
 
39
39
  private
40
40
 
41
- NON_FORCED_OPTIONS = [:debug, :requires, :libs, :files_or_directories_to_run, :line_numbers, :full_description]
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 [:if,:unless].include?(k)
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, metadata| metadata.has_key?(:if) && !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 #{format_seconds(duration)} seconds\n"
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
@@ -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 [:each, :all, :suite].include?(args.first)
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.")
@@ -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
- if value.arity == 2
182
- # Pass the metadata hash to allow the proc to check if it even has the key.
183
- # This is necessary for the implicit :if exclusion filter:
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
@@ -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
- run_over_drb(options, err, out)
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
- run_in_process(options, err, out)
66
+ CommandLine.new(options).run(err, out)
67
67
  end
68
68
  else
69
- run_in_process(options, err, out)
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
@@ -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
- @_subject ||= if attribute.is_a?(Array)
126
- super()[*attribute]
127
- else
128
- attribute.to_s.split('.').inject(super()) do |target, method|
129
- target.send(method)
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)
@@ -1,7 +1,7 @@
1
1
  module RSpec
2
2
  module Core
3
3
  module Version
4
- STRING = '2.8.0'
4
+ STRING = '2.9.0'
5
5
  end
6
6
  end
7
7
  end
@@ -4,12 +4,13 @@ module RSpec
4
4
 
5
5
  include RSpec::Core::Hooks
6
6
 
7
- attr_reader :example_groups, :filtered_examples, :wants_to_quit
8
- attr_writer :wants_to_quit
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) { |sum, g| sum += g.filtered_examples.size }
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'
@@ -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}.*#{spec_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 no :if metadata" do
717
- config.exclusion_filter[:if].call(nil, {}).should be_false
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 "does not exclude a spec with { :if => true } metadata" do
721
- config.exclusion_filter[:if].call(true, {:if => true}).should be_false
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 { :if => false } metadata" do
725
- config.exclusion_filter[:if].call(false, {:if => false}).should be_true
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 "passes the metadata hash as the second argument if a given proc expects 2 args" do
130
- passed_metadata = nil
131
- example_metadata.filter_applies?(:if, lambda { |v, m| passed_metadata = m })
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