rspec-core 2.5.1 → 2.6.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 (123) hide show
  1. data/.travis.yml +7 -0
  2. data/Gemfile +12 -14
  3. data/README.md +4 -1
  4. data/Rakefile +29 -12
  5. data/cucumber.yml +1 -1
  6. data/features/.nav +15 -9
  7. data/features/Autotest.md +31 -7
  8. data/features/Changelog.md +46 -3
  9. data/features/Upgrade.md +35 -2
  10. data/features/command_line/README.md +22 -0
  11. data/features/command_line/configure.feature +2 -2
  12. data/features/command_line/example_name_option.feature +10 -10
  13. data/features/command_line/exit_status.feature +4 -4
  14. data/features/command_line/format_option.feature +4 -4
  15. data/features/command_line/line_number_appended_to_path.feature +11 -11
  16. data/features/command_line/line_number_option.feature +2 -2
  17. data/features/command_line/rake_task.feature +3 -3
  18. data/features/command_line/tag.feature +30 -14
  19. data/features/configuration/alias_example_to.feature +48 -0
  20. data/features/configuration/custom_settings.feature +3 -3
  21. data/features/configuration/fail_fast.feature +3 -3
  22. data/features/configuration/read_options_from_file.feature +4 -4
  23. data/features/example_groups/basic_structure.feature +11 -15
  24. data/features/example_groups/shared_context.feature +74 -0
  25. data/features/example_groups/shared_example_group.feature +21 -17
  26. data/features/expectation_framework_integration/configure_expectation_framework.feature +15 -4
  27. data/features/filtering/exclusion_filters.feature +28 -4
  28. data/features/filtering/{implicit_filters.feature → if_and_unless.feature} +9 -7
  29. data/features/filtering/inclusion_filters.feature +26 -3
  30. data/features/filtering/run_all_when_everything_filtered.feature +2 -2
  31. data/features/formatters/custom_formatter.feature +1 -1
  32. data/features/formatters/text_formatter.feature +43 -0
  33. data/features/helper_methods/arbitrary_methods.feature +2 -2
  34. data/features/helper_methods/let.feature +2 -2
  35. data/features/helper_methods/modules.feature +149 -0
  36. data/features/hooks/around_hooks.feature +18 -11
  37. data/features/hooks/before_and_after_hooks.feature +15 -19
  38. data/features/hooks/filtering.feature +160 -124
  39. data/features/metadata/current_example.feature +17 -0
  40. data/features/metadata/described_class.feature +2 -2
  41. data/features/metadata/user_defined.feature +111 -0
  42. data/features/mock_framework_integration/use_any_framework.feature +1 -1
  43. data/features/mock_framework_integration/use_flexmock.feature +83 -10
  44. data/features/mock_framework_integration/use_mocha.feature +84 -10
  45. data/features/mock_framework_integration/use_rr.feature +85 -10
  46. data/features/mock_framework_integration/use_rspec.feature +84 -10
  47. data/features/pending/pending_examples.feature +8 -8
  48. data/features/spec_files/arbitrary_file_suffix.feature +1 -1
  49. data/features/step_definitions/additional_cli_steps.rb +11 -1
  50. data/features/subject/attribute_of_subject.feature +24 -4
  51. data/features/subject/explicit_subject.feature +5 -5
  52. data/features/subject/implicit_receiver.feature +2 -2
  53. data/features/subject/implicit_subject.feature +2 -2
  54. data/features/support/env.rb +6 -1
  55. data/lib/rspec/core/backward_compatibility.rb +12 -2
  56. data/lib/rspec/core/command_line.rb +2 -5
  57. data/lib/rspec/core/configuration.rb +70 -38
  58. data/lib/rspec/core/configuration_options.rb +6 -23
  59. data/lib/rspec/core/drb_command_line.rb +5 -11
  60. data/lib/rspec/core/example.rb +29 -21
  61. data/lib/rspec/core/example_group.rb +40 -8
  62. data/lib/rspec/core/extensions/object.rb +0 -1
  63. data/lib/rspec/core/formatters/base_formatter.rb +6 -0
  64. data/lib/rspec/core/formatters/base_text_formatter.rb +1 -1
  65. data/lib/rspec/core/formatters/helpers.rb +0 -4
  66. data/lib/rspec/core/hooks.rb +14 -4
  67. data/lib/rspec/core/metadata.rb +1 -1
  68. data/lib/rspec/core/metadata_hash_builder.rb +93 -0
  69. data/lib/rspec/core/mocking/with_flexmock.rb +2 -0
  70. data/lib/rspec/core/mocking/with_mocha.rb +2 -0
  71. data/lib/rspec/core/mocking/with_rr.rb +2 -0
  72. data/lib/rspec/core/mocking/with_rspec.rb +3 -1
  73. data/lib/rspec/core/option_parser.rb +9 -2
  74. data/lib/rspec/core/pending.rb +10 -3
  75. data/lib/rspec/core/reporter.rb +2 -2
  76. data/lib/rspec/core/runner.rb +38 -13
  77. data/lib/rspec/core/shared_example_group.rb +18 -4
  78. data/lib/rspec/core/subject.rb +4 -6
  79. data/lib/rspec/core/version.rb +1 -1
  80. data/lib/rspec/core/world.rb +70 -18
  81. data/lib/rspec/core.rb +29 -0
  82. data/lib/rspec/monkey/spork/test_framework/rspec.rb +1 -0
  83. data/rspec-core.gemspec +3 -5
  84. data/spec/autotest/failed_results_re_spec.rb +2 -2
  85. data/spec/rspec/core/command_line_spec.rb +36 -2
  86. data/spec/rspec/core/configuration_spec.rb +150 -70
  87. data/spec/rspec/core/deprecations_spec.rb +21 -0
  88. data/spec/rspec/core/drb_command_line_spec.rb +21 -56
  89. data/spec/rspec/core/example_group_spec.rb +213 -56
  90. data/spec/rspec/core/example_spec.rb +110 -0
  91. data/spec/rspec/core/formatters/base_formatter_spec.rb +23 -2
  92. data/spec/rspec/core/formatters/base_text_formatter_spec.rb +9 -0
  93. data/spec/rspec/core/formatters/helpers_spec.rb +1 -1
  94. data/spec/rspec/core/formatters/html_formatted-1.8.6.html +5 -5
  95. data/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html +8 -10
  96. data/spec/rspec/core/formatters/html_formatted-1.8.7.html +5 -5
  97. data/spec/rspec/core/formatters/html_formatted-1.9.1.html +5 -5
  98. data/spec/rspec/core/formatters/html_formatted-1.9.2.html +5 -5
  99. data/spec/rspec/core/formatters/progress_formatter_spec.rb +0 -1
  100. data/spec/rspec/core/formatters/text_mate_formatted-1.8.6.html +5 -5
  101. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html +8 -10
  102. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html +5 -5
  103. data/spec/rspec/core/formatters/text_mate_formatted-1.9.1.html +5 -5
  104. data/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html +5 -5
  105. data/spec/rspec/core/hooks_spec.rb +86 -0
  106. data/spec/rspec/core/metadata_spec.rb +7 -7
  107. data/spec/rspec/core/option_parser_spec.rb +26 -15
  108. data/spec/rspec/core/pending_example_spec.rb +12 -51
  109. data/spec/rspec/core/reporter_spec.rb +19 -3
  110. data/spec/rspec/core/resources/formatter_specs.rb +7 -1
  111. data/spec/rspec/core/rspec_matchers_spec.rb +45 -0
  112. data/spec/rspec/core/runner_spec.rb +42 -10
  113. data/spec/rspec/core/shared_example_group_spec.rb +57 -21
  114. data/spec/rspec/core/subject_spec.rb +32 -11
  115. data/spec/rspec/core/world_spec.rb +147 -15
  116. data/spec/rspec/core_spec.rb +28 -0
  117. data/spec/spec_helper.rb +22 -2
  118. data/spec/support/matchers.rb +44 -13
  119. data/spec/support/shared_example_groups.rb +41 -0
  120. data/spec/support/spec_files.rb +44 -0
  121. data/spec.txt +1126 -0
  122. metadata +35 -16
  123. data/spec/ruby_forker.rb +0 -13
@@ -0,0 +1,93 @@
1
+ module RSpec
2
+ module Core
3
+ module MetadataHashBuilder
4
+ module Common
5
+ def build_metadata_hash_from(args)
6
+ metadata = args.last.is_a?(Hash) ? args.pop : {}
7
+
8
+ if RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values?
9
+ add_symbols_to_hash(metadata, args)
10
+ else
11
+ warn_about_symbol_usage(args)
12
+ end
13
+
14
+ metadata
15
+ end
16
+
17
+ private
18
+
19
+ def add_symbols_to_hash(hash, args)
20
+ while args.last.is_a?(Symbol)
21
+ hash[args.pop] = true
22
+ end
23
+ end
24
+
25
+ def warn_about_symbol_usage(args)
26
+ symbols = args.select { |a| a.is_a?(Symbol) }
27
+ return if symbols.empty?
28
+ Kernel.warn symbol_metadata_warning(symbols)
29
+ end
30
+ end
31
+
32
+ module WithConfigWarning
33
+ include Common
34
+
35
+ private
36
+
37
+ def symbol_metadata_warning(symbols)
38
+ <<-NOTICE
39
+
40
+ *****************************************************************
41
+ WARNING: You have passed symbols (#{symbols.inspect}) as metadata
42
+ arguments to a configuration option.
43
+
44
+ In RSpec 3, these symbols will be treated as metadata keys with
45
+ a value of `true`. To get this behavior now (and prevent this
46
+ warning), you can set a configuration option:
47
+
48
+ RSpec.configure do |c|
49
+ c.treat_symbols_as_metadata_keys_with_true_values = true
50
+ end
51
+
52
+ Note that this config setting should go before your other config
53
+ settings so that they can use symbols as metadata.
54
+ *****************************************************************
55
+
56
+ NOTICE
57
+ end
58
+ end
59
+
60
+ module WithDeprecationWarning
61
+ include Common
62
+
63
+ private
64
+
65
+ def symbol_metadata_warning(symbols)
66
+ <<-NOTICE
67
+
68
+ *****************************************************************
69
+ DEPRECATION WARNING: you are using deprecated behaviour that will
70
+ be removed from RSpec 3.
71
+
72
+ You have passed symbols (#{symbols.inspect}) as additional
73
+ arguments for a doc string.
74
+
75
+ In RSpec 3, these symbols will be treated as metadata keys with
76
+ a value of `true`. To get this behavior now (and prevent this
77
+ warning), you can set a configuration option:
78
+
79
+ RSpec.configure do |c|
80
+ c.treat_symbols_as_metadata_keys_with_true_values = true
81
+ end
82
+
83
+ Alternately, if your intention is to use the symbol as part of the
84
+ doc string (i.e. to specify a method name), you can change it to
85
+ a string such as "#method_name" to remove this warning.
86
+ *****************************************************************
87
+
88
+ NOTICE
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -8,6 +8,8 @@ require 'flexmock/rspec'
8
8
  module RSpec
9
9
  module Core
10
10
  module MockFrameworkAdapter
11
+
12
+ def self.framework_name; :flexmock end
11
13
 
12
14
  include FlexMock::MockContainer
13
15
  def setup_mocks_for_rspec
@@ -4,6 +4,8 @@ require 'mocha/object'
4
4
  module RSpec
5
5
  module Core
6
6
  module MockFrameworkAdapter
7
+
8
+ def self.framework_name; :mocha end
7
9
 
8
10
  # Mocha::Standalone was deprecated as of Mocha 0.9.7.
9
11
  begin
@@ -5,6 +5,8 @@ RSpec.configuration.backtrace_clean_patterns.push(RR::Errors::BACKTRACE_IDENTIFI
5
5
  module RSpec
6
6
  module Core
7
7
  module MockFrameworkAdapter
8
+
9
+ def self.framework_name; :rr end
8
10
 
9
11
  include RR::Extensions::InstanceMethods
10
12
 
@@ -3,7 +3,9 @@ require 'rspec/mocks'
3
3
  module RSpec
4
4
  module Core
5
5
  module MockFrameworkAdapter
6
-
6
+
7
+ def self.framework_name; :rspec end
8
+
7
9
  def setup_mocks_for_rspec
8
10
  RSpec::Mocks::setup(self)
9
11
  end
@@ -1,3 +1,6 @@
1
+ # http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html
2
+ require 'optparse'
3
+
1
4
  module RSpec::Core
2
5
  class Parser
3
6
  def self.parse!(args)
@@ -33,13 +36,13 @@ module RSpec::Core
33
36
  options[:color_enabled] = o
34
37
  end
35
38
 
36
- parser.on('-d', '--debug', 'Enable debugging') do |o|
39
+ parser.on('-d', '--debugger', 'Enable debugging') do |o|
37
40
  options[:debug] = true
38
41
  end
39
42
 
40
43
  parser.on('-e', '--example PATTERN', "Run examples whose full descriptions match this pattern",
41
44
  "(PATTERN is compiled into a Ruby regular expression)") do |o|
42
- options[:full_description] = /#{o}/
45
+ options[:full_description] = Regexp.compile(Regexp.escape(o))
43
46
  end
44
47
 
45
48
  parser.on('-f', '--format FORMATTER', 'Choose a formatter',
@@ -83,6 +86,10 @@ module RSpec::Core
83
86
  options[:profile_examples] = o
84
87
  end
85
88
 
89
+ parser.on('-P', '--pattern PATTERN', 'Load files those matching this pattern. Default is "spec/**/*_spec.rb"') do |o|
90
+ options[:pattern] = o
91
+ end
92
+
86
93
  parser.on('-r', '--require PATH', 'Require a file') do |path|
87
94
  options[:requires] ||= []
88
95
  options[:requires] << path
@@ -1,6 +1,8 @@
1
1
  module RSpec
2
2
  module Core
3
3
  module Pending
4
+ class PendingDeclaredInExample < StandardError; end
5
+
4
6
  DEFAULT_MESSAGE = 'No reason given'
5
7
 
6
8
  def pending(*args)
@@ -17,13 +19,18 @@ module RSpec
17
19
  example.metadata[:execution_result][:pending_message] = message
18
20
  if block_given?
19
21
  begin
20
- result = yield
22
+ result = begin
23
+ yield
24
+ example.example_group_instance.instance_eval { verify_mocks_for_rspec }
25
+ end
21
26
  example.metadata[:pending] = false
22
- rescue Exception => e
27
+ rescue Exception
28
+ ensure
29
+ teardown_mocks_for_rspec
23
30
  end
24
31
  raise RSpec::Core::PendingExampleFixedError.new if result
25
32
  end
26
- throw :pending_declared_in_example, message
33
+ raise PendingDeclaredInExample.new(message)
27
34
  end
28
35
  end
29
36
  end
@@ -39,11 +39,11 @@ module RSpec::Core
39
39
  end
40
40
 
41
41
  def example_group_started(group)
42
- notify :example_group_started, group
42
+ notify :example_group_started, group unless group.descendant_filtered_examples.empty?
43
43
  end
44
44
 
45
45
  def example_group_finished(group)
46
- notify :example_group_finished, group
46
+ notify :example_group_finished, group unless group.descendant_filtered_examples.empty?
47
47
  end
48
48
 
49
49
  def example_started(example)
@@ -4,30 +4,32 @@ module RSpec
4
4
  module Core
5
5
  class Runner
6
6
 
7
+ # Register an at_exit hook that runs the suite.
7
8
  def self.autorun
8
9
  return if autorun_disabled? || installed_at_exit? || running_in_drb?
9
10
  @installed_at_exit = true
10
- at_exit { run(ARGV, $stderr, $stdout) ? exit(0) : exit(1) }
11
- end
12
-
13
- def self.autorun_disabled?
14
- @autorun_disabled ||= false
11
+ at_exit { exit(run(ARGV, $stderr, $stdout)) }
15
12
  end
13
+ AT_EXIT_HOOK_BACKTRACE_LINE = "#{__FILE__}:#{__LINE__ - 2}:in `autorun'"
16
14
 
17
15
  def self.disable_autorun!
18
16
  @autorun_disabled = true
19
17
  end
20
18
 
21
- def self.installed_at_exit?
19
+ def self.autorun_disabled? # :nodoc:
20
+ @autorun_disabled ||= false
21
+ end
22
+
23
+ def self.installed_at_exit? # :nodoc:
22
24
  @installed_at_exit ||= false
23
25
  end
24
26
 
25
- def self.running_in_drb?
26
- (DRb.current_server rescue false) &&
27
+ def self.running_in_drb? # :nodoc:
28
+ (DRb.current_server rescue false) &&
27
29
  DRb.current_server.uri =~ /druby\:\/\/127.0.0.1\:/
28
30
  end
29
31
 
30
- def self.trap_interrupt
32
+ def self.trap_interrupt # :nodoc:
31
33
  trap('INT') do
32
34
  exit!(1) if RSpec.wants_to_quit
33
35
  RSpec.wants_to_quit = true
@@ -35,23 +37,46 @@ module RSpec
35
37
  end
36
38
  end
37
39
 
38
- def self.run(args, err, out)
40
+ # Run a suite of RSpec examples.
41
+ #
42
+ # This is used internally by RSpec to run a suite, but is available
43
+ # for use by any other automation tool.
44
+ #
45
+ # If you want to run this multiple times in the same process, and you
46
+ # want files like spec_helper.rb to be reloaded, be sure to load `load`
47
+ # instead of `require`.
48
+ #
49
+ # ==== Parameters
50
+ # * +args+ - an array of command-line-supported arguments
51
+ # * +err+ - error stream (Default: $stderr)
52
+ # * +out+ - output stream (Default: $stdout)
53
+ #
54
+ # ==== Returns
55
+ # * +Fixnum+ - exit status code (0/1)
56
+ def self.run(args, err=$stderr, out=$stdout)
39
57
  trap_interrupt
40
58
  options = ConfigurationOptions.new(args)
41
59
  options.parse_options
42
60
 
43
61
  if options.options[:drb]
44
- run_over_drb(options, err, out) || run_in_process(options, err, out)
62
+ begin
63
+ run_over_drb(options, err, out)
64
+ rescue DRb::DRbConnError
65
+ err.puts "No DRb server is running. Running in local process instead ..."
66
+ run_in_process(options, err, out)
67
+ end
45
68
  else
46
69
  run_in_process(options, err, out)
47
70
  end
71
+ ensure
72
+ RSpec.reset
48
73
  end
49
74
 
50
- def self.run_over_drb(options, err, out)
75
+ def self.run_over_drb(options, err, out) # :nodoc:
51
76
  DRbCommandLine.new(options).run(err, out)
52
77
  end
53
78
 
54
- def self.run_in_process(options, err, out)
79
+ def self.run_in_process(options, err, out) # :nodoc:
55
80
  CommandLine.new(options, RSpec::configuration, RSpec::world).run(err, out)
56
81
  end
57
82
 
@@ -2,12 +2,26 @@ module RSpec
2
2
  module Core
3
3
  module SharedExampleGroup
4
4
 
5
- def share_examples_for(name, &block)
6
- ensure_shared_example_group_name_not_taken(name)
7
- RSpec.world.shared_example_groups[name] = block
5
+ def shared_context(*args, &block)
6
+ if String === args.first || Symbol === args.first
7
+ name = args.shift
8
+ ensure_shared_example_group_name_not_taken(name)
9
+ RSpec.world.shared_example_groups[name] = block
10
+ end
11
+
12
+ unless args.empty?
13
+ mod = Module.new
14
+ (class << mod; self; end).send(:define_method, :extended) do |host|
15
+ host.class_eval(&block)
16
+ end
17
+ RSpec.configuration.extend(mod, *args)
18
+ else
19
+ end
8
20
  end
9
21
 
10
- alias :shared_examples_for :share_examples_for
22
+ alias :shared_examples :shared_context
23
+ alias :share_examples_for :shared_context
24
+ alias :shared_examples_for :shared_context
11
25
 
12
26
  def share_as(name, &block)
13
27
  if Object.const_defined?(name)
@@ -1,5 +1,3 @@
1
- require 'ostruct'
2
-
3
1
  module RSpec
4
2
  module Core
5
3
  module Subject
@@ -108,14 +106,14 @@ module RSpec
108
106
  #
109
107
  # describe "a configuration Hash" do
110
108
  # subject do
111
- # { :max_users => 3,
109
+ # { :max_users => 3,
112
110
  # 'admin' => :all_permissions }
113
111
  # end
114
112
  #
115
113
  # its([:max_users]) { should == 3 }
116
114
  # its(['admin']) { should == :all_permissions }
117
115
  #
118
- # # You can still access to its regular methods this way:
116
+ # # You can still access to its regular methods this way:
119
117
  # its(:keys) { should include(:max_users) }
120
118
  # its(:count) { should == 2 }
121
119
  # end
@@ -124,8 +122,8 @@ module RSpec
124
122
  example do
125
123
  self.class.class_eval do
126
124
  define_method(:subject) do
127
- @_subject ||= if super().is_a?(Hash) && attribute.is_a?(Array)
128
- OpenStruct.new(super()).send(attribute.first)
125
+ @_subject ||= if attribute.is_a?(Array)
126
+ super()[*attribute]
129
127
  else
130
128
  attribute.to_s.split('.').inject(super()) do |target, method|
131
129
  target.send(method)
@@ -1,7 +1,7 @@
1
1
  module RSpec # :nodoc:
2
2
  module Core # :nodoc:
3
3
  module Version # :nodoc:
4
- STRING = '2.5.1'
4
+ STRING = '2.6.0'
5
5
  end
6
6
  end
7
7
  end
@@ -2,6 +2,29 @@ module RSpec
2
2
  module Core
3
3
  class World
4
4
 
5
+ module Describable
6
+ PROC_HEX_NUMBER = /0x[0-9a-f]+@/
7
+ PROJECT_DIR = File.expand_path('.')
8
+
9
+ def description
10
+ reject { |k, v| RSpec::Core::Configuration::CONDITIONAL_FILTERS[k] == v }.inspect.gsub(PROC_HEX_NUMBER, '').gsub(PROJECT_DIR, '.').gsub(' (lambda)','')
11
+ end
12
+
13
+ def empty_without_conditional_filters?
14
+ reject { |k, v| RSpec::Core::Configuration::CONDITIONAL_FILTERS[k] == v }.empty?
15
+ end
16
+
17
+ def reject
18
+ super rescue {}
19
+ end
20
+
21
+ def empty?
22
+ super rescue false
23
+ end
24
+ end
25
+
26
+ include RSpec::Core::Hooks
27
+
5
28
  attr_reader :example_groups, :filtered_examples, :wants_to_quit
6
29
  attr_writer :wants_to_quit
7
30
 
@@ -18,17 +41,21 @@ module RSpec
18
41
  }
19
42
  end
20
43
 
44
+ def reset
45
+ example_groups.clear
46
+ end
47
+
21
48
  def register(example_group)
22
49
  example_groups << example_group
23
50
  example_group
24
51
  end
25
52
 
26
53
  def inclusion_filter
27
- @configuration.filter
54
+ @configuration.inclusion_filter.extend(Describable)
28
55
  end
29
56
 
30
57
  def exclusion_filter
31
- @configuration.exclusion_filter
58
+ @configuration.exclusion_filter.extend(Describable)
32
59
  end
33
60
 
34
61
  def configure_group(group)
@@ -54,32 +81,57 @@ module RSpec
54
81
  end
55
82
 
56
83
  def preceding_declaration_line(filter_line)
57
- declaration_line_numbers.inject(nil) do |highest_prior_declaration_line, line|
84
+ declaration_line_numbers.sort.inject(nil) do |highest_prior_declaration_line, line|
58
85
  line <= filter_line ? line : highest_prior_declaration_line
59
86
  end
60
87
  end
61
88
 
62
- def announce_inclusion_filter
63
- if inclusion_filter
64
- if @configuration.run_all_when_everything_filtered? && RSpec.world.example_count.zero?
65
- @configuration.reporter.message "No examples were matched by #{inclusion_filter.inspect}, running all"
66
- @configuration.clear_inclusion_filter
67
- filtered_examples.clear
68
- else
69
- @configuration.reporter.message "Run filtered using #{inclusion_filter.inspect}"
89
+ def reporter
90
+ @configuration.reporter
91
+ end
92
+
93
+ def announce_filters
94
+ filter_announcements = []
95
+
96
+ if @configuration.run_all_when_everything_filtered? && example_count.zero?
97
+ reporter.message( "No examples matched #{inclusion_filter.description}. Running all.")
98
+ filtered_examples.clear
99
+ @configuration.clear_inclusion_filter
100
+ end
101
+
102
+ announce_inclusion_filter filter_announcements
103
+ announce_exclusion_filter filter_announcements
104
+
105
+ if example_count.zero?
106
+ example_groups.clear
107
+ if filter_announcements.empty?
108
+ reporter.message("No examples found.")
109
+ elsif inclusion_filter
110
+ message = "No examples matched #{inclusion_filter.description}."
111
+ if @configuration.run_all_when_everything_filtered?
112
+ message << " Running all."
113
+ end
114
+ reporter.message(message)
115
+ elsif exclusion_filter
116
+ reporter.message(
117
+ "No examples were matched. Perhaps #{exclusion_filter.description} is excluding everything?")
70
118
  end
119
+ elsif !filter_announcements.empty?
120
+ reporter.message("Run filtered #{filter_announcements.join(', ')}")
71
121
  end
72
122
  end
73
-
74
- def announce_exclusion_filter
75
- if exclusion_filter && RSpec.world.example_count.zero?
76
- @configuration.reporter.message(
77
- "No examples were matched. Perhaps #{exclusion_filter.inspect} is excluding everything?")
78
- example_groups.clear
123
+
124
+ def announce_inclusion_filter(announcements)
125
+ if inclusion_filter
126
+ announcements << "including #{inclusion_filter.description}"
79
127
  end
80
128
  end
81
129
 
82
- include RSpec::Core::Hooks
130
+ def announce_exclusion_filter(announcements)
131
+ unless exclusion_filter.empty_without_conditional_filters?
132
+ announcements << "excluding #{exclusion_filter.description}"
133
+ end
134
+ end
83
135
 
84
136
  def find_hook(hook, scope, group, example = nil)
85
137
  @configuration.find_hook(hook, scope, group, example)
data/lib/rspec/core.rb CHANGED
@@ -4,6 +4,7 @@ require 'rspec/core/deprecation'
4
4
  require 'rspec/core/backward_compatibility'
5
5
  require 'rspec/core/reporter'
6
6
 
7
+ require 'rspec/core/metadata_hash_builder'
7
8
  require 'rspec/core/hooks'
8
9
  require 'rspec/core/subject'
9
10
  require 'rspec/core/let'
@@ -48,17 +49,45 @@ module RSpec
48
49
  @world ||= RSpec::Core::World.new
49
50
  end
50
51
 
52
+ # Used internally to ensure examples get reloaded between multiple runs in
53
+ # the same process.
54
+ def self.reset
55
+ world.reset
56
+ configuration.reset
57
+ end
58
+
51
59
  def self.configuration
52
60
  @configuration ||= RSpec::Core::Configuration.new
53
61
  end
54
62
 
55
63
  def self.configure
64
+ warn_about_deprecated_configure if RSpec.world.example_groups.any?
56
65
  yield configuration if block_given?
57
66
  end
58
67
 
59
68
  def self.clear_remaining_example_groups
60
69
  world.example_groups.clear
61
70
  end
71
+
72
+ private
73
+
74
+ def self.warn_about_deprecated_configure
75
+ warn <<-NOTICE
76
+
77
+ *****************************************************************
78
+ DEPRECATION WARNING: you are using deprecated behaviour that will
79
+ be removed from RSpec 3.
80
+
81
+ You have set some configuration options after an example group has
82
+ already been defined. In RSpec 3, this will not be allowed. All
83
+ configuration should happen before the first example group is
84
+ defined. The configuration is happening at:
85
+
86
+ #{caller[1]}
87
+ *****************************************************************
88
+
89
+ NOTICE
90
+ end
62
91
  end
63
92
 
64
93
  require 'rspec/core/backward_compatibility'
@@ -1,3 +1,4 @@
1
+ # TODO (2011-05-08) - remove this as soon as spork 0.9.0 is released
1
2
  if defined?(Spork::TestFramework::RSpec)
2
3
  class Spork::TestFramework::RSpec < Spork::TestFramework
3
4
  def run_tests(argv, err, out)
data/rspec-core.gemspec CHANGED
@@ -7,14 +7,12 @@ Gem::Specification.new do |s|
7
7
  s.version = RSpec::Core::Version::STRING
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Chad Humphries", "David Chelimsky"]
10
- s.email = "dchelimsky@gmail.com;chad.humphries@gmail.com"
11
- s.homepage = "http://github.com/rspec/rspec-core"
10
+ s.email = "rspec-users@rubyforge.org;"
11
+ s.homepage = "http://github.com/rspec"
12
12
  s.summary = "rspec-core-#{RSpec::Core::Version::STRING}"
13
- s.description = "RSpec runner and example groups"
13
+ s.description = "BDD for Ruby. RSpec runner and example groups."
14
14
 
15
- s.rubygems_version = "1.3.7"
16
15
  s.rubyforge_project = "rspec"
17
- s.default_executable = "rspec"
18
16
 
19
17
  s.files = `git ls-files`.split("\n")
20
18
  s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
@@ -19,7 +19,7 @@ describe "failed_results_re for autotest" do
19
19
  it "matches a failure" do
20
20
  re = Autotest::Rspec2.new.failed_results_re
21
21
  example_output.should =~ re
22
- example_output[re, 2].should == __FILE__.sub(File.expand_path('.'),'.')
22
+ example_output.should include(__FILE__.sub(File.expand_path('.'),'.'))
23
23
  end
24
24
  end
25
25
 
@@ -31,7 +31,7 @@ describe "failed_results_re for autotest" do
31
31
  it "matches a failure" do
32
32
  re = Autotest::Rspec2.new.failed_results_re
33
33
  example_output.should =~ re
34
- example_output[re, 2].should == __FILE__.sub(File.expand_path('.'),'.')
34
+ example_output.should include(__FILE__.sub(File.expand_path('.'),'.'))
35
35
  end
36
36
  end
37
37
  end
@@ -4,6 +4,42 @@ require 'tmpdir'
4
4
 
5
5
  module RSpec::Core
6
6
  describe CommandLine do
7
+
8
+ describe "#run" do
9
+ include_context "spec files"
10
+
11
+ let(:out) { StringIO.new }
12
+ let(:err) { StringIO.new }
13
+
14
+ def config_options(argv=[])
15
+ options = RSpec::Core::ConfigurationOptions.new(argv)
16
+ options.parse_options
17
+ options
18
+ end
19
+
20
+ def command_line(args)
21
+ RSpec::Core::CommandLine.new(config_options(args))
22
+ end
23
+
24
+ def config_options(argv=[])
25
+ options = RSpec::Core::ConfigurationOptions.new(argv)
26
+ options.parse_options
27
+ options
28
+ end
29
+
30
+ it "returns 0 if spec passes" do
31
+ err, out = StringIO.new, StringIO.new
32
+ result = command_line([passing_spec_filename]).run(err, out)
33
+ result.should be(0)
34
+ end
35
+
36
+ it "returns 1 if spec passes" do
37
+ err, out = StringIO.new, StringIO.new
38
+ result = command_line([failing_spec_filename]).run(err, out)
39
+ result.should be(1)
40
+ end
41
+ end
42
+
7
43
  context "given an Array of options" do
8
44
  it "assigns ConfigurationOptions built from Array to @options" do
9
45
  config_options = ConfigurationOptions.new(%w[--color])
@@ -50,8 +86,6 @@ module RSpec::Core
50
86
  config.stub(:run_hook)
51
87
 
52
88
  config.should_receive(:load_spec_files)
53
- config.should_receive(:configure_mock_framework)
54
- config.should_receive(:configure_expectation_framework)
55
89
 
56
90
  world.should_receive(:announce_inclusion_filter)
57
91
  world.should_receive(:announce_exclusion_filter)