rspec-core 3.7.0 → 3.8.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. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Changelog.md +36 -2
  4. data/README.md +1 -1
  5. data/lib/rspec/core/bisect/coordinator.rb +26 -30
  6. data/lib/rspec/core/bisect/example_minimizer.rb +12 -8
  7. data/lib/rspec/core/bisect/fork_runner.rb +134 -0
  8. data/lib/rspec/core/bisect/server.rb +4 -13
  9. data/lib/rspec/core/bisect/{runner.rb → shell_command.rb} +27 -70
  10. data/lib/rspec/core/bisect/shell_runner.rb +73 -0
  11. data/lib/rspec/core/bisect/utilities.rb +58 -0
  12. data/lib/rspec/core/configuration.rb +163 -53
  13. data/lib/rspec/core/configuration_options.rb +41 -4
  14. data/lib/rspec/core/example.rb +4 -4
  15. data/lib/rspec/core/example_group.rb +1 -0
  16. data/lib/rspec/core/formatters/base_bisect_formatter.rb +45 -0
  17. data/lib/rspec/core/formatters/bisect_drb_formatter.rb +29 -0
  18. data/lib/rspec/core/formatters/bisect_progress_formatter.rb +29 -16
  19. data/lib/rspec/core/formatters/deprecation_formatter.rb +3 -1
  20. data/lib/rspec/core/formatters/exception_presenter.rb +1 -0
  21. data/lib/rspec/core/formatters/html_printer.rb +0 -2
  22. data/lib/rspec/core/formatters/protocol.rb +17 -17
  23. data/lib/rspec/core/formatters/syntax_highlighter.rb +19 -19
  24. data/lib/rspec/core/formatters.rb +10 -6
  25. data/lib/rspec/core/hooks.rb +1 -3
  26. data/lib/rspec/core/invocations.rb +8 -6
  27. data/lib/rspec/core/memoized_helpers.rb +2 -2
  28. data/lib/rspec/core/profiler.rb +3 -1
  29. data/lib/rspec/core/reporter.rb +3 -6
  30. data/lib/rspec/core/runner.rb +20 -14
  31. data/lib/rspec/core/shared_example_group.rb +1 -3
  32. data/lib/rspec/core/shell_escape.rb +2 -2
  33. data/lib/rspec/core/version.rb +1 -1
  34. data/lib/rspec/core/world.rb +11 -0
  35. data.tar.gz.sig +0 -0
  36. metadata +12 -9
  37. metadata.gz.sig +0 -0
  38. data/lib/rspec/core/formatters/bisect_formatter.rb +0 -69
@@ -0,0 +1,29 @@
1
+ require 'drb/drb'
2
+ RSpec::Support.require_rspec_core "formatters/base_bisect_formatter"
3
+
4
+ module RSpec
5
+ module Core
6
+ module Formatters
7
+ # Used by `--bisect`. When it shells out and runs a portion of the suite, it uses
8
+ # this formatter as a means to have the status reported back to it, via DRb.
9
+ #
10
+ # Note that since DRb calls carry considerable overhead compared to normal
11
+ # method calls, we try to minimize the number of DRb calls for perf reasons,
12
+ # opting to communicate only at the start and the end of the run, rather than
13
+ # after each example.
14
+ # @private
15
+ class BisectDRbFormatter < BaseBisectFormatter
16
+ def initialize(_output)
17
+ drb_uri = "druby://localhost:#{RSpec.configuration.drb_port}"
18
+ @bisect_server = DRbObject.new_with_uri(drb_uri)
19
+ RSpec.configuration.files_or_directories_to_run = @bisect_server.files_or_directories_to_run
20
+ super(Set.new(@bisect_server.expected_failures))
21
+ end
22
+
23
+ def notify_results(results)
24
+ @bisect_server.latest_run_results = results
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -6,19 +6,14 @@ module RSpec
6
6
  # @private
7
7
  # Produces progress output while bisecting.
8
8
  class BisectProgressFormatter < BaseTextFormatter
9
- # We've named all events with a `bisect_` prefix to prevent naming collisions.
10
- Formatters.register self, :bisect_starting, :bisect_original_run_complete,
11
- :bisect_round_started, :bisect_individual_run_complete,
12
- :bisect_complete, :bisect_repro_command,
13
- :bisect_failed, :bisect_aborted,
14
- :bisect_round_ignoring_ids, :bisect_round_detected_multiple_culprits,
15
- :bisect_dependency_check_started, :bisect_dependency_check_passed,
16
- :bisect_dependency_check_failed
9
+ def initialize(output, bisect_runner)
10
+ super(output)
11
+ @bisect_runner = bisect_runner
12
+ end
17
13
 
18
14
  def bisect_starting(notification)
19
15
  @round_count = 0
20
- options = notification.original_cli_args.join(' ')
21
- output.puts "Bisect started using options: #{options.inspect}"
16
+ output.puts bisect_started_message(notification)
22
17
  output.print "Running suite to find failures..."
23
18
  end
24
19
 
@@ -40,6 +35,16 @@ module RSpec
40
35
 
41
36
  def bisect_dependency_check_failed(_notification)
42
37
  output.puts " failure(s) do not require any non-failures to run first"
38
+
39
+ if @bisect_runner == :fork
40
+ output.puts
41
+ output.puts "=" * 80
42
+ output.puts "NOTE: this bisect run used `config.bisect_runner = :fork`, which generally"
43
+ output.puts "provides significantly faster bisection runs than the old shell-based runner,"
44
+ output.puts "but may inaccurately report that no non-failures are required. If this result"
45
+ output.puts "is unexpected, consider setting `config.bisect_runner = :shell` and trying again."
46
+ output.puts "=" * 80
47
+ end
43
48
  end
44
49
 
45
50
  def bisect_round_started(notification, include_trailing_space=true)
@@ -85,16 +90,20 @@ module RSpec
85
90
  output.puts "\n\nBisect aborted!"
86
91
  output.puts "\nThe most minimal reproduction command discovered so far is:\n #{notification.repro}"
87
92
  end
93
+
94
+ private
95
+
96
+ def bisect_started_message(notification)
97
+ options = notification.original_cli_args.join(' ')
98
+ "Bisect started using options: #{options.inspect}"
99
+ end
88
100
  end
89
101
 
90
102
  # @private
91
- # Produces detailed debug output while bisecting. Used when
92
- # bisect is performed while the `DEBUG_RSPEC_BISECT` ENV var is used.
93
- # Designed to provide details for us when we need to troubleshoot bisect bugs.
103
+ # Produces detailed debug output while bisecting. Used when bisect is
104
+ # performed with `--bisect=verbose`. Designed to provide details for
105
+ # us when we need to troubleshoot bisect bugs.
94
106
  class BisectDebugFormatter < BisectProgressFormatter
95
- Formatters.register self, :bisect_original_run_complete, :bisect_individual_run_start,
96
- :bisect_individual_run_complete, :bisect_round_ignoring_ids
97
-
98
107
  def bisect_original_run_complete(notification)
99
108
  output.puts " (#{Helpers.format_duration(notification.duration)})"
100
109
 
@@ -138,6 +147,10 @@ module RSpec
138
147
  formatted_ids = organized_ids.map { |id| " - #{id}" }.join("\n")
139
148
  "#{description} (#{ids.size}):\n#{formatted_ids}"
140
149
  end
150
+
151
+ def bisect_started_message(notification)
152
+ "#{super} and bisect runner: #{notification.bisect_runner.inspect}"
153
+ end
141
154
  end
142
155
  end
143
156
  end
@@ -62,6 +62,7 @@ module RSpec
62
62
  TOO_MANY_WARNINGS_NOTICE = "Too many similar deprecation messages " \
63
63
  "reported, disregarding further reports. #{DEPRECATION_STREAM_NOTICE}"
64
64
 
65
+ # @private
65
66
  SpecifiedDeprecationMessage = Struct.new(:type) do
66
67
  def initialize(data)
67
68
  @message = data.message
@@ -80,7 +81,7 @@ module RSpec
80
81
 
81
82
  def output_formatted(str)
82
83
  return str unless str.lines.count > 1
83
- separator = "#{'-' * 80}"
84
+ separator = '-' * 80
84
85
  "#{separator}\n#{str.chomp}\n#{separator}"
85
86
  end
86
87
 
@@ -89,6 +90,7 @@ module RSpec
89
90
  end
90
91
  end
91
92
 
93
+ # @private
92
94
  GeneratedDeprecationMessage = Struct.new(:type) do
93
95
  def initialize(data)
94
96
  @data = data
@@ -379,6 +379,7 @@ module RSpec
379
379
  parent_bt[index] != child_bt[index]
380
380
  end
381
381
 
382
+ return child if index_before_first_common_frame.nil?
382
383
  return child if index_before_first_common_frame == -1
383
384
 
384
385
  child = child.dup
@@ -115,7 +115,6 @@ module RSpec
115
115
  "style=\"margin-left: #{(number_of_parents - 1) * 15}px;\""
116
116
  end
117
117
 
118
- # rubocop:disable LineLength
119
118
  REPORT_HEADER = <<-EOF
120
119
  <div class="rspec-report">
121
120
 
@@ -139,7 +138,6 @@ module RSpec
139
138
 
140
139
  <div class="results">
141
140
  EOF
142
- # rubocop:enable LineLength
143
141
 
144
142
  GLOBAL_SCRIPTS = <<-EOF
145
143
 
@@ -17,12 +17,12 @@ module RSpec
17
17
  # @see RSpec::Core::Formatters::BaseTextFormatter
18
18
  # @see RSpec::Core::Reporter
19
19
  class Protocol
20
- # @method initialize
20
+ # @method initialize(output)
21
21
  # @api public
22
22
  #
23
23
  # @param output [IO] the formatter output
24
24
 
25
- # @method start
25
+ # @method start(notification)
26
26
  # @api public
27
27
  # @group Suite Notifications
28
28
  #
@@ -35,7 +35,7 @@ module RSpec
35
35
  #
36
36
  # @param notification [Notifications::StartNotification]
37
37
 
38
- # @method example_group_started
38
+ # @method example_group_started(notification)
39
39
  # @api public
40
40
  # @group Group Notifications
41
41
  #
@@ -48,7 +48,7 @@ module RSpec
48
48
  # @param notification [Notifications::GroupNotification] containing example_group
49
49
  # subclass of {ExampleGroup}
50
50
 
51
- # @method example_group_finished
51
+ # @method example_group_finished(notification)
52
52
  # @api public
53
53
  # @group Group Notifications
54
54
  #
@@ -57,7 +57,7 @@ module RSpec
57
57
  # @param notification [Notifications::GroupNotification] containing example_group
58
58
  # subclass of {ExampleGroup}
59
59
 
60
- # @method example_started
60
+ # @method example_started(notification)
61
61
  # @api public
62
62
  # @group Example Notifications
63
63
  #
@@ -66,7 +66,7 @@ module RSpec
66
66
  # @param notification [Notifications::ExampleNotification] containing example subclass
67
67
  # of {Example}
68
68
 
69
- # @method example_finished
69
+ # @method example_finished(notification)
70
70
  # @api public
71
71
  # @group Example Notifications
72
72
  #
@@ -75,7 +75,7 @@ module RSpec
75
75
  # @param notification [Notifications::ExampleNotification] containing example subclass
76
76
  # of {Example}
77
77
 
78
- # @method example_passed
78
+ # @method example_passed(notification)
79
79
  # @api public
80
80
  # @group Example Notifications
81
81
  #
@@ -84,7 +84,7 @@ module RSpec
84
84
  # @param notification [Notifications::ExampleNotification] containing example subclass
85
85
  # of {Example}
86
86
 
87
- # @method example_pending
87
+ # @method example_pending(notification)
88
88
  # @api public
89
89
  # @group Example Notifications
90
90
  #
@@ -93,7 +93,7 @@ module RSpec
93
93
  # @param notification [Notifications::ExampleNotification] containing example subclass
94
94
  # of {Example}
95
95
 
96
- # @method example_failed
96
+ # @method example_failed(notification)
97
97
  # @api public
98
98
  # @group Example Notifications
99
99
  #
@@ -102,7 +102,7 @@ module RSpec
102
102
  # @param notification [Notifications::ExampleNotification] containing example subclass
103
103
  # of {Example}
104
104
 
105
- # @method message
105
+ # @method message(notification)
106
106
  # @api public
107
107
  # @group Suite Notifications
108
108
  #
@@ -110,7 +110,7 @@ module RSpec
110
110
  #
111
111
  # @param notification [Notifications::MessageNotification] containing message
112
112
 
113
- # @method stop
113
+ # @method stop(notification)
114
114
  # @api public
115
115
  # @group Suite Notifications
116
116
  #
@@ -119,7 +119,7 @@ module RSpec
119
119
  #
120
120
  # @param notification [Notifications::NullNotification]
121
121
 
122
- # @method start_dump
122
+ # @method start_dump(notification)
123
123
  # @api public
124
124
  # @group Suite Notifications
125
125
  #
@@ -130,7 +130,7 @@ module RSpec
130
130
  #
131
131
  # @param notification [Notifications::NullNotification]
132
132
 
133
- # @method dump_failures
133
+ # @method dump_failures(notification)
134
134
  # @api public
135
135
  # @group Suite Notifications
136
136
  #
@@ -138,7 +138,7 @@ module RSpec
138
138
  #
139
139
  # @param notification [Notifications::NullNotification]
140
140
 
141
- # @method dump_summary
141
+ # @method dump_summary(summary)
142
142
  # @api public
143
143
  # @group Suite Notifications
144
144
  #
@@ -148,7 +148,7 @@ module RSpec
148
148
  # @param summary [Notifications::SummaryNotification] containing duration,
149
149
  # example_count, failure_count and pending_count
150
150
 
151
- # @method dump_profile
151
+ # @method dump_profile(profile)
152
152
  # @api public
153
153
  # @group Suite Notifications
154
154
  #
@@ -158,7 +158,7 @@ module RSpec
158
158
  # @param profile [Notifications::ProfileNotification] containing duration,
159
159
  # slowest_examples and slowest_example_groups
160
160
 
161
- # @method dump_pending
161
+ # @method dump_pending(notification)
162
162
  # @api public
163
163
  # @group Suite Notifications
164
164
  #
@@ -167,7 +167,7 @@ module RSpec
167
167
  #
168
168
  # @param notification [Notifications::NullNotification]
169
169
 
170
- # @method close
170
+ # @method close(notification)
171
171
  # @api public
172
172
  # @group Suite Notifications
173
173
  #
@@ -13,6 +13,25 @@ module RSpec
13
13
  implementation.highlight_syntax(lines)
14
14
  end
15
15
 
16
+ # rubocop:disable Lint/RescueException
17
+ # rubocop:disable Lint/HandleExceptions
18
+ def self.attempt_to_add_rspec_terms_to_coderay_keywords
19
+ CodeRay::Scanners::Ruby::Patterns::IDENT_KIND.add(%w[
20
+ describe context
21
+ it specify
22
+ before after around
23
+ let subject
24
+ expect allow
25
+ ], :keyword)
26
+ rescue Exception
27
+ # Mutating CodeRay's contants like this is not a public API
28
+ # and might not always work. If we cannot add our keywords
29
+ # to CodeRay it is not a big deal and not worth raising an
30
+ # error over, so we ignore it.
31
+ end
32
+ # rubocop:enable Lint/HandleExceptions
33
+ # rubocop:enable Lint/RescueException
34
+
16
35
  private
17
36
 
18
37
  if RSpec::Support::OS.windows?
@@ -38,25 +57,6 @@ module RSpec
38
57
  end
39
58
  end
40
59
 
41
- # rubocop:disable Lint/RescueException
42
- # rubocop:disable Lint/HandleExceptions
43
- def self.attempt_to_add_rspec_terms_to_coderay_keywords
44
- CodeRay::Scanners::Ruby::Patterns::IDENT_KIND.add(%w[
45
- describe context
46
- it specify
47
- before after around
48
- let subject
49
- expect allow
50
- ], :keyword)
51
- rescue Exception
52
- # Mutating CodeRay's contants like this is not a public API
53
- # and might not always work. If we cannot add our keywords
54
- # to CodeRay it is not a big deal and not worth raising an
55
- # error over, so we ignore it.
56
- end
57
- # rubocop:enable Lint/HandleExceptions
58
- # rubocop:enable Lint/RescueException
59
-
60
60
  # @private
61
61
  module CodeRayImplementation
62
62
  RESET_CODE = "\e[0m"
@@ -72,7 +72,7 @@ module RSpec::Core::Formatters
72
72
  autoload :ProgressFormatter, 'rspec/core/formatters/progress_formatter'
73
73
  autoload :ProfileFormatter, 'rspec/core/formatters/profile_formatter'
74
74
  autoload :JsonFormatter, 'rspec/core/formatters/json_formatter'
75
- autoload :BisectFormatter, 'rspec/core/formatters/bisect_formatter'
75
+ autoload :BisectDRbFormatter, 'rspec/core/formatters/bisect_drb_formatter'
76
76
  autoload :ExceptionPresenter, 'rspec/core/formatters/exception_presenter'
77
77
 
78
78
  # Register the formatter class
@@ -133,9 +133,6 @@ module RSpec::Core::Formatters
133
133
  end
134
134
 
135
135
  return unless RSpec.configuration.profile_examples?
136
-
137
- @reporter.setup_profiler
138
-
139
136
  return if existing_formatter_implements?(:dump_profile)
140
137
 
141
138
  add RSpec::Core::Formatters::ProfileFormatter, output_stream
@@ -143,6 +140,13 @@ module RSpec::Core::Formatters
143
140
 
144
141
  # @private
145
142
  def add(formatter_to_use, *paths)
143
+ # If a formatter instance was passed, we can register it directly,
144
+ # with no need for any of the further processing that happens below.
145
+ if Loader.formatters.key?(formatter_to_use.class)
146
+ register formatter_to_use, notifications_for(formatter_to_use.class)
147
+ return
148
+ end
149
+
146
150
  formatter_class = find_formatter(formatter_to_use)
147
151
 
148
152
  args = paths.map { |p| p.respond_to?(:puts) ? p : open_stream(p) }
@@ -206,8 +210,8 @@ module RSpec::Core::Formatters
206
210
  ProgressFormatter
207
211
  when 'j', 'json'
208
212
  JsonFormatter
209
- when 'bisect'
210
- BisectFormatter
213
+ when 'bisect-drb'
214
+ BisectDRbFormatter
211
215
  end
212
216
  end
213
217
 
@@ -322,7 +322,7 @@ module RSpec
322
322
  # end
323
323
  #
324
324
  # The yielded example aliases `run` with `call`, which lets you treat it
325
- # like a `Proc`. This is especially handy when working with libaries
325
+ # like a `Proc`. This is especially handy when working with libraries
326
326
  # that manage their own setup and teardown using a block or proc syntax,
327
327
  # e.g.
328
328
  #
@@ -339,8 +339,6 @@ module RSpec
339
339
  @hooks ||= HookCollections.new(self, FilterableItemRepository::UpdateOptimized)
340
340
  end
341
341
 
342
- private
343
-
344
342
  # @private
345
343
  Hook = Struct.new(:block, :options)
346
344
 
@@ -26,21 +26,23 @@ module RSpec
26
26
 
27
27
  # @private
28
28
  class Bisect
29
- def call(options, _err, _out)
29
+ def call(options, err, out)
30
30
  RSpec::Support.require_rspec_core "bisect/coordinator"
31
+ runner = Runner.new(options).tap { |r| r.configure(err, out) }
32
+ formatter = bisect_formatter_klass_for(options.options[:bisect]).new(
33
+ out, runner.configuration.bisect_runner
34
+ )
31
35
 
32
36
  success = RSpec::Core::Bisect::Coordinator.bisect_with(
33
- options.args,
34
- RSpec.configuration,
35
- bisect_formatter_for(options.options[:bisect])
37
+ runner, options.args, formatter
36
38
  )
37
39
 
38
40
  success ? 0 : 1
39
41
  end
40
42
 
41
- private
43
+ private
42
44
 
43
- def bisect_formatter_for(argument)
45
+ def bisect_formatter_klass_for(argument)
44
46
  return Formatters::BisectDebugFormatter if argument == "verbose"
45
47
  Formatters::BisectProgressFormatter
46
48
  end
@@ -483,9 +483,9 @@ EOS
483
483
  def self.module_for(example_group)
484
484
  get_constant_or_yield(example_group, :LetDefinitions) do
485
485
  mod = Module.new do
486
- include Module.new {
486
+ include(Module.new {
487
487
  example_group.const_set(:NamedSubjectPreventSuper, self)
488
- }
488
+ })
489
489
  end
490
490
 
491
491
  example_group.const_set(:LetDefinitions, mod)
@@ -20,7 +20,9 @@ module RSpec
20
20
  def example_group_finished(notification)
21
21
  return unless notification.group.top_level?
22
22
 
23
- @example_groups[notification.group][:total_time] = Time.now - @example_groups[notification.group][:start]
23
+ group = @example_groups[notification.group]
24
+ return unless group.key?(:start)
25
+ group[:total_time] = Time.now - group[:start]
24
26
  end
25
27
 
26
28
  def example_started(notification)
@@ -21,17 +21,12 @@ module RSpec::Core
21
21
  @non_example_exception_count = 0
22
22
  @setup_default = lambda {}
23
23
  @setup = false
24
+ @profiler = nil
24
25
  end
25
26
 
26
27
  # @private
27
28
  attr_reader :examples, :failed_examples, :pending_examples
28
29
 
29
- # @private
30
- def setup_profiler
31
- @profiler = Profiler.new
32
- register_listener @profiler, *Profiler::NOTIFICATIONS
33
- end
34
-
35
30
  # Registers a listener to a list of notifications. The reporter will send
36
31
  # notification of events to all registered listeners.
37
32
  #
@@ -231,6 +226,8 @@ module RSpec::Core
231
226
  return if @setup
232
227
 
233
228
  @setup_default.call
229
+ @profiler = Profiler.new
230
+ register_listener @profiler, *Profiler::NOTIFICATIONS
234
231
  @setup = true
235
232
  end
236
233
 
@@ -94,9 +94,7 @@ module RSpec
94
94
  # @param err [IO] error stream
95
95
  # @param out [IO] output stream
96
96
  def setup(err, out)
97
- @configuration.error_stream = err
98
- @configuration.output_stream = out if @configuration.output_stream == $stdout
99
- @options.configure(@configuration)
97
+ configure(err, out)
100
98
  @configuration.load_spec_files
101
99
  @world.announce_filters
102
100
  end
@@ -122,17 +120,11 @@ module RSpec
122
120
  success ? 0 : @configuration.failure_exit_code
123
121
  end
124
122
 
125
- private
126
-
127
- def persist_example_statuses
128
- return unless (path = @configuration.example_status_persistence_file_path)
129
-
130
- ExampleStatusPersister.persist(@world.all_examples, path)
131
- rescue SystemCallError => e
132
- RSpec.warning "Could not write example statuses to #{path} (configured as " \
133
- "`config.example_status_persistence_file_path`) due to a " \
134
- "system error: #{e.inspect}. Please check that the config " \
135
- "option is set to an accessible, valid file path", :call_site => nil
123
+ # @private
124
+ def configure(err, out)
125
+ @configuration.error_stream = err
126
+ @configuration.output_stream = out if @configuration.output_stream == $stdout
127
+ @options.configure(@configuration)
136
128
  end
137
129
 
138
130
  # @private
@@ -188,6 +180,20 @@ module RSpec
188
180
  $stderr.puts "\nRSpec is shutting down and will print the summary report... Interrupt again to force quit."
189
181
  end
190
182
  end
183
+
184
+ private
185
+
186
+ def persist_example_statuses
187
+ return if @configuration.dry_run
188
+ return unless (path = @configuration.example_status_persistence_file_path)
189
+
190
+ ExampleStatusPersister.persist(@world.all_examples, path)
191
+ rescue SystemCallError => e
192
+ RSpec.warning "Could not write example statuses to #{path} (configured as " \
193
+ "`config.example_status_persistence_file_path`) due to a " \
194
+ "system error: #{e.inspect}. Please check that the config " \
195
+ "option is set to an accessible, valid file path", :call_site => nil
196
+ end
191
197
  end
192
198
  end
193
199
  end
@@ -103,7 +103,6 @@ module RSpec
103
103
  # Shared examples top level DSL.
104
104
  module TopLevelDSL
105
105
  # @private
106
- # rubocop:disable Lint/NestedMethodDefinition
107
106
  def self.definitions
108
107
  proc do
109
108
  def shared_examples(name, *args, &block)
@@ -113,7 +112,6 @@ module RSpec
113
112
  alias shared_examples_for shared_examples
114
113
  end
115
114
  end
116
- # rubocop:enable Lint/NestedMethodDefinition
117
115
 
118
116
  # @private
119
117
  def self.exposed_globally?
@@ -259,7 +257,7 @@ module RSpec
259
257
  # :nocov:
260
258
  def ensure_block_has_source_location(block)
261
259
  source_location = yield.split(':')
262
- block.extend Module.new { define_method(:source_location) { source_location } }
260
+ block.extend(Module.new { define_method(:source_location) { source_location } })
263
261
  end
264
262
  # :nocov:
265
263
  end
@@ -6,7 +6,7 @@ module RSpec
6
6
  module_function
7
7
 
8
8
  def quote(argument)
9
- "'#{argument.gsub("'", "\\\\'")}'"
9
+ "'#{argument.to_s.gsub("'", "\\\\'")}'"
10
10
  end
11
11
 
12
12
  if RSpec::Support::OS.windows?
@@ -17,7 +17,7 @@ module RSpec
17
17
  require 'shellwords'
18
18
 
19
19
  def escape(shell_command)
20
- shell_command.shellescape
20
+ Shellwords.escape(shell_command.to_s)
21
21
  end
22
22
  end
23
23
 
@@ -3,7 +3,7 @@ module RSpec
3
3
  # Version information for RSpec Core.
4
4
  module Version
5
5
  # Current version of RSpec Core, in semantic versioning format.
6
- STRING = '3.7.0'
6
+ STRING = '3.8.0'
7
7
  end
8
8
  end
9
9
  end
@@ -21,6 +21,17 @@ module RSpec
21
21
  configuration.world = self
22
22
  @example_groups = []
23
23
  @example_group_counts_by_spec_file = Hash.new(0)
24
+ prepare_example_filtering
25
+ end
26
+
27
+ # @api public
28
+ #
29
+ # Prepares filters so that they apply to example groups when they run.
30
+ #
31
+ # This is a separate method so that filters can be modified/replaced and
32
+ # examples refiltered during a process's lifetime, which can be useful for
33
+ # a custom runner.
34
+ def prepare_example_filtering
24
35
  @filtered_examples = Hash.new do |hash, group|
25
36
  hash[group] = filter_manager.prune(group.examples)
26
37
  end
data.tar.gz.sig CHANGED
Binary file