rspec-core 3.10.2 → 3.12.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c462ef57abbfae97ff1b4fa21937c229704f11d76d98f9d364cac49845421ad
4
- data.tar.gz: 96a6cff188d2268a7c3ee96a64d5d12bbc3fca390e821b1f155d7e963745ea79
3
+ metadata.gz: f573a79d2311b74b6d9cdf7f8694856d70aa84037566289b6834c6ca710ecfd0
4
+ data.tar.gz: 9ec85ab6c34cf92e45404985f5578241b7a54ebb48a2a13d182493ce9ff31b71
5
5
  SHA512:
6
- metadata.gz: 62f270716ca47f5ee3388a95f89d71d4b0e9bdf0fd1f7c6806332af2a9191028c6694b38e9792e8ad1c791fb277161b29ba4f92486303eaf6c2b986ae7616b3b
7
- data.tar.gz: 5eaf0e7f745c9885d9fba59bf26303588632a4294ea004131bca55496121a60185154848492e5b31eafc9186f19c7903365da829fbcf8334f043ad707263076c
6
+ metadata.gz: f03be116127209918f11a49536975a5f584185d6b4dd72fb845a8eb270ff0da131ed729a86dc7c8b0205b7d7e6f3a922ff8e01f3118e7a3bfd017d2cdaeea966
7
+ data.tar.gz: 24bebf24323887a2534c5fdecdcfdd4c269e10947464cab62ed4f702bd025dd4ea2f9f6725c89d2e9b096f9a5424895f80aac6b250113aabff6f92c1662aeed9
checksums.yaml.gz.sig CHANGED
Binary file
data/Changelog.md CHANGED
@@ -1,5 +1,23 @@
1
1
  ### Development
2
- [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.10.2...3-10-maintenance)
2
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.12.0...3-12-maintenance)
3
+
4
+ ### 3.12.0 / 2022-10-26
5
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.11.0...v3.12.0)
6
+
7
+ * No changes, released to support other gems.
8
+
9
+ ### 3.11.0 / 2022-02-09
10
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.10.2...v3.11.0)
11
+
12
+ Enhancements:
13
+
14
+ * Improve pluralisation of words ending with `s` (like process). (Joshua Pinter, #2779)
15
+ * Add ordering by file modification time (most recent first). (Matheus Richard, #2778)
16
+ * Add `to_s` to reserved names for #let and #subject. (Nick Flückiger, #2886)
17
+ * Introduce `RSpec.current_scope` to expose the current scope in which
18
+ RSpec is executing. e.g. `:before_example_hook`, `:example` etc. (@odinhb, #2895)
19
+ * Add named bold colours as options for custom colours. (#2913, #2914)
20
+ * Warn when (but not prevent) a `SystemExit` occurs. (Jared Beck, #2926)
3
21
 
4
22
  ### 3.10.2 / 2022-01-27
5
23
  [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.10.1...v3.10.2)
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # rspec-core [![Build Status](https://github.com/rspec/rspec-core/workflows/RSpec%20CI/badge.svg?branch=3-10-maintenance)](https://github.com/rspec/rspec-core/actions) [![Code Climate](https://codeclimate.com/github/rspec/rspec-core.svg)](https://codeclimate.com/github/rspec/rspec-core)
1
+ # rspec-core [![Build Status](https://github.com/rspec/rspec-core/workflows/RSpec%20CI/badge.svg)](https://github.com/rspec/rspec-core/actions) [![Code Climate](https://codeclimate.com/github/rspec/rspec-core.svg)](https://codeclimate.com/github/rspec/rspec-core)
2
2
 
3
3
  rspec-core provides the structure for writing executable examples of how your
4
4
  code should behave, and an `rspec` command with tools to constrain which
@@ -502,7 +502,8 @@ module RSpec
502
502
  # @private
503
503
  attr_reader :backtrace_formatter, :ordering_manager, :loaded_spec_files
504
504
 
505
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
505
+ # rubocop:disable Metrics/AbcSize
506
+ # rubocop:disable Metrics/MethodLength
506
507
 
507
508
  # Build an object to store runtime configuration options and set defaults
508
509
  def initialize
@@ -561,7 +562,8 @@ module RSpec
561
562
 
562
563
  define_built_in_hooks
563
564
  end
564
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
565
+ # rubocop:enable Metrics/AbcSize
566
+ # rubocop:enable Metrics/MethodLength
565
567
 
566
568
  # @private
567
569
  #
@@ -2063,10 +2065,13 @@ module RSpec
2063
2065
  return yield if dry_run?
2064
2066
 
2065
2067
  begin
2068
+ RSpec.current_scope = :before_suite_hook
2066
2069
  run_suite_hooks("a `before(:suite)` hook", @before_suite_hooks)
2067
2070
  yield
2068
2071
  ensure
2072
+ RSpec.current_scope = :after_suite_hook
2069
2073
  run_suite_hooks("an `after(:suite)` hook", @after_suite_hooks)
2074
+ RSpec.current_scope = :suite
2070
2075
  end
2071
2076
  end
2072
2077
 
@@ -2119,6 +2124,14 @@ module RSpec
2119
2124
  relative_file = Metadata.relative_path(file)
2120
2125
  reporter.notify_non_example_exception(ex, "An error occurred while loading #{relative_file}.")
2121
2126
  RSpec.world.wants_to_quit = true
2127
+ rescue SystemExit => ex
2128
+ relative_file = Metadata.relative_path(file)
2129
+ reporter.notify_non_example_exception(
2130
+ ex,
2131
+ "While loading #{relative_file} an `exit` / `raise SystemExit` occurred, RSpec will now quit."
2132
+ )
2133
+ RSpec.world.rspec_is_quitting = true
2134
+ raise ex
2122
2135
  end
2123
2136
 
2124
2137
  def handle_suite_hook(scope, meta)
@@ -259,6 +259,7 @@ module RSpec
259
259
  with_around_and_singleton_context_hooks do
260
260
  begin
261
261
  run_before_example
262
+ RSpec.current_scope = :example
262
263
  @example_group_instance.instance_exec(self, &@example_block)
263
264
 
264
265
  if pending?
@@ -278,6 +279,7 @@ module RSpec
278
279
  rescue AllExceptionsExcludingDangerousOnesOnRubiesThatAllowIt => e
279
280
  set_exception(e)
280
281
  ensure
282
+ RSpec.current_scope = :after_example_hook
281
283
  run_after_example
282
284
  end
283
285
  end
@@ -462,6 +464,7 @@ module RSpec
462
464
  end
463
465
 
464
466
  def with_around_example_hooks
467
+ RSpec.current_scope = :before_example_hook
465
468
  hooks.run(:around, :example, self) { yield }
466
469
  rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e
467
470
  set_exception(e)
@@ -602,6 +602,7 @@ module RSpec
602
602
 
603
603
  should_run_context_hooks = descendant_filtered_examples.any?
604
604
  begin
605
+ RSpec.current_scope = :before_context_hook
605
606
  run_before_context_hooks(new('before(:context) hook')) if should_run_context_hooks
606
607
  result_for_this_group = run_examples(reporter)
607
608
  results_for_descendants = ordering_strategy.order(children).map { |child| child.run(reporter) }.all?
@@ -614,6 +615,7 @@ module RSpec
614
615
  RSpec.world.wants_to_quit = true if reporter.fail_fast_limit_met?
615
616
  false
616
617
  ensure
618
+ RSpec.current_scope = :after_context_hook
617
619
  run_after_context_hooks(new('after(:context) hook')) if should_run_context_hooks
618
620
  reporter.example_group_finished(self)
619
621
  end
@@ -7,15 +7,23 @@ module RSpec
7
7
  # @private
8
8
  VT100_CODES =
9
9
  {
10
- :black => 30,
11
- :red => 31,
12
- :green => 32,
13
- :yellow => 33,
14
- :blue => 34,
15
- :magenta => 35,
16
- :cyan => 36,
17
- :white => 37,
18
- :bold => 1,
10
+ :black => 30,
11
+ :red => 31,
12
+ :green => 32,
13
+ :yellow => 33,
14
+ :blue => 34,
15
+ :magenta => 35,
16
+ :cyan => 36,
17
+ :white => 37,
18
+ :bold_black => '1;30',
19
+ :bold_red => '1;31',
20
+ :bold_green => '1;32',
21
+ :bold_yellow => '1;33',
22
+ :bold_blue => '1;34',
23
+ :bold_magenta => '1;35',
24
+ :bold_cyan => '1;36',
25
+ :bold_white => '1;37',
26
+ :bold => 1,
19
27
  }
20
28
  # @private
21
29
  VT100_CODE_VALUES = VT100_CODES.invert
@@ -242,6 +242,10 @@ module RSpec
242
242
  line_regex = RSpec.configuration.in_project_source_dir_regex
243
243
  loaded_spec_files = RSpec.configuration.loaded_spec_files
244
244
 
245
+ exception_backtrace.reject! do |line|
246
+ line.start_with?("<internal:")
247
+ end
248
+
245
249
  exception_backtrace.find do |line|
246
250
  next unless (line_path = line[/(.+?):(\d+)(|:\d+)/, 1])
247
251
  path = File.expand_path(line_path)
@@ -86,7 +86,15 @@ module RSpec
86
86
  # @param string [String] word to be pluralized
87
87
  # @return [String] pluralized word
88
88
  def self.pluralize(count, string)
89
- "#{count} #{string}#{'s' unless count.to_f == 1}"
89
+ pluralized_string = if count.to_f == 1
90
+ string
91
+ elsif string.end_with?('s') # e.g. "process"
92
+ "#{string}es" # e.g. "processes"
93
+ else
94
+ "#{string}s"
95
+ end
96
+
97
+ "#{count} #{pluralized_string}"
90
98
  end
91
99
 
92
100
  # @api private
@@ -33,10 +33,8 @@ module RSpec
33
33
  "<span class='duration'>#{formatted_run_time}s</span></dd>"
34
34
  end
35
35
 
36
- # rubocop:disable Metrics/ParameterLists
37
36
  def print_example_failed(pending_fixed, description, run_time, failure_id,
38
37
  exception, extra_content)
39
- # rubocop:enable Metrics/ParameterLists
40
38
  formatted_run_time = "%.5f" % run_time
41
39
 
42
40
  @output.puts " <dd class=\"example #{pending_fixed ? 'pending_fixed' : 'failed'}\">"
@@ -215,7 +213,7 @@ function assign_display_style_for_group(classname, display_flag, subgroup_flag)
215
213
  }
216
214
  }
217
215
  EOF
218
- # rubocop:enable LineLength
216
+ # rubocop:enable Layout/LineLength
219
217
 
220
218
  GLOBAL_STYLES = <<-EOF
221
219
  #rspec-header {
@@ -78,6 +78,7 @@ module RSpec
78
78
  # @note If you are using RSpec's newer expect-based syntax you may
79
79
  # want to use `is_expected.to` instead of `should`.
80
80
  def should(matcher=nil, message=nil)
81
+ enforce_value_expectation(matcher, 'should')
81
82
  RSpec::Expectations::PositiveExpectationHandler.handle_matcher(subject, matcher, message)
82
83
  end
83
84
 
@@ -97,6 +98,7 @@ module RSpec
97
98
  # @note If you are using RSpec's newer expect-based syntax you may
98
99
  # want to use `is_expected.to_not` instead of `should_not`.
99
100
  def should_not(matcher=nil, message=nil)
101
+ enforce_value_expectation(matcher, 'should_not')
100
102
  RSpec::Expectations::NegativeExpectationHandler.handle_matcher(subject, matcher, message)
101
103
  end
102
104
 
@@ -144,6 +146,26 @@ module RSpec
144
146
  end
145
147
  end
146
148
 
149
+ # @private
150
+ def enforce_value_expectation(matcher, method_name)
151
+ return if matcher_supports_value_expectations?(matcher)
152
+
153
+ RSpec.deprecate(
154
+ "#{method_name} #{RSpec::Support::ObjectFormatter.format(matcher)}",
155
+ :message =>
156
+ "The implicit block expectation syntax is deprecated, you should pass " \
157
+ "a block to `expect` to use the provided block expectation matcher " \
158
+ "(#{RSpec::Support::ObjectFormatter.format(matcher)}), " \
159
+ "or the matcher must implement `supports_value_expectations?`."
160
+ )
161
+ end
162
+
163
+ def matcher_supports_value_expectations?(matcher)
164
+ matcher.supports_value_expectations?
165
+ rescue
166
+ true
167
+ end
168
+
147
169
  # @private
148
170
  class ThreadsafeMemoized
149
171
  def initialize
@@ -285,9 +307,13 @@ EOS
285
307
  # We have to pass the block directly to `define_method` to
286
308
  # allow it to use method constructs like `super` and `return`.
287
309
  raise "#let or #subject called without a block" if block.nil?
288
- raise(
289
- "#let or #subject called with a reserved name #initialize"
290
- ) if :initialize == name
310
+
311
+ # A list of reserved words that can't be used as a name for a memoized helper
312
+ # Matches for both symbols and passed strings
313
+ if [:initialize, :to_s].include?(name.to_sym)
314
+ raise ArgumentError, "#let or #subject called with reserved name `#{name}`"
315
+ end
316
+
291
317
  our_module = MemoizedHelpers.module_for(self)
292
318
 
293
319
  # If we have a module clash in our helper module
@@ -32,11 +32,10 @@ module RSpec::Core
32
32
 
33
33
  private
34
34
 
35
- # rubocop:disable MethodLength
36
35
  # rubocop:disable Metrics/AbcSize
37
- # rubocop:disable CyclomaticComplexity
38
- # rubocop:disable PerceivedComplexity
39
- # rubocop:disable Metrics/BlockLength
36
+ # rubocop:disable Metrics/MethodLength
37
+ # rubocop:disable Metrics/CyclomaticComplexity
38
+ # rubocop:disable Metrics/PerceivedComplexity
40
39
  def parser(options)
41
40
  OptionParser.new do |parser|
42
41
  parser.summary_width = 34
@@ -58,10 +57,11 @@ module RSpec::Core
58
57
  end
59
58
 
60
59
  parser.on('--order TYPE[:SEED]', 'Run examples by the specified order type.',
61
- ' [defined] examples and groups are run in the order they are defined',
62
- ' [rand] randomize the order of groups and examples',
63
- ' [random] alias for rand',
64
- ' [random:SEED] e.g. --order random:123') do |o|
60
+ ' [defined] examples and groups are run in the order they are defined',
61
+ ' [rand] randomize the order of groups and examples',
62
+ ' [random] alias for rand',
63
+ ' [random:SEED] e.g. --order random:123',
64
+ ' [recently-modified] run the most recently modified files first') do |o|
65
65
  options[:order] = o
66
66
  end
67
67
 
@@ -302,11 +302,10 @@ FILTERING
302
302
  end
303
303
  end
304
304
  end
305
- # rubocop:enable Metrics/BlockLength
306
305
  # rubocop:enable Metrics/AbcSize
307
- # rubocop:enable MethodLength
308
- # rubocop:enable CyclomaticComplexity
309
- # rubocop:enable PerceivedComplexity
306
+ # rubocop:enable Metrics/MethodLength
307
+ # rubocop:enable Metrics/CyclomaticComplexity
308
+ # rubocop:enable Metrics/PerceivedComplexity
310
309
 
311
310
  def add_tag_filter(options, filter_type, tag_name, value=true)
312
311
  (options[filter_type] ||= {})[tag_name] = value
@@ -58,6 +58,14 @@ module RSpec
58
58
  MAX_32_BIT = 4_294_967_295
59
59
  end
60
60
 
61
+ # @private
62
+ # Orders items by modification time (most recent modified first).
63
+ class RecentlyModified
64
+ def order(list)
65
+ list.sort_by { |item| -File.mtime(item.metadata[:absolute_file_path]).to_i }
66
+ end
67
+ end
68
+
61
69
  # @private
62
70
  # Orders items based on a custom block.
63
71
  class Custom
@@ -77,7 +85,8 @@ module RSpec
77
85
  @configuration = configuration
78
86
  @strategies = {}
79
87
 
80
- register(:random, Random.new(configuration))
88
+ register(:random, Random.new(configuration))
89
+ register(:recently_modified, RecentlyModified.new)
81
90
 
82
91
  identity = Identity.new
83
92
  register(:defined, identity)
@@ -132,6 +141,8 @@ module RSpec
132
141
  :random
133
142
  elsif order == 'defined'
134
143
  :defined
144
+ elsif order == 'recently-modified'
145
+ :recently_modified
135
146
  end
136
147
 
137
148
  register_ordering(:global, ordering_registry.fetch(ordering_name)) if ordering_name
@@ -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.10.2'
6
+ STRING = '3.12.0'
7
7
  end
8
8
  end
9
9
  end
@@ -10,6 +10,13 @@ module RSpec
10
10
  # Used internally to determine what to do when a SIGINT is received.
11
11
  attr_accessor :wants_to_quit
12
12
 
13
+ # Used internally to signify that a SystemExit occurred in
14
+ # `Configuration#load_file_handling_errors`, and thus examples cannot
15
+ # be counted accurately. Specifically, we cannot accurately report
16
+ # "No examples found".
17
+ # @private
18
+ attr_accessor :rspec_is_quitting
19
+
13
20
  # Used internally to signal that a failure outside of an example
14
21
  # has occurred, and that therefore the exit status should indicate
15
22
  # the run failed.
@@ -18,6 +25,7 @@ module RSpec
18
25
 
19
26
  def initialize(configuration=RSpec.configuration)
20
27
  @wants_to_quit = false
28
+ @rspec_is_quitting = false
21
29
  @configuration = configuration
22
30
  configuration.world = self
23
31
  @example_groups = []
@@ -184,10 +192,12 @@ module RSpec
184
192
  return unless example_count.zero?
185
193
 
186
194
  example_groups.clear
187
- if filter_manager.empty?
188
- report_filter_message("No examples found.")
189
- elsif exclusion_filter.empty? || inclusion_filter.empty?
190
- report_filter_message(everything_filtered_message)
195
+ unless rspec_is_quitting
196
+ if filter_manager.empty?
197
+ report_filter_message("No examples found.")
198
+ elsif exclusion_filter.empty? || inclusion_filter.empty?
199
+ report_filter_message(everything_filtered_message)
200
+ end
191
201
  end
192
202
  end
193
203
 
data/lib/rspec/core.rb CHANGED
@@ -129,6 +129,32 @@ module RSpec
129
129
  RSpec::Support.thread_local_data[:current_example] = example
130
130
  end
131
131
 
132
+ # Set the current scope rspec is executing in
133
+ # @api private
134
+ def self.current_scope=(scope)
135
+ RSpec::Support.thread_local_data[:current_scope] = scope
136
+ end
137
+ RSpec.current_scope = :suite
138
+
139
+ # Get the current RSpec execution scope
140
+ #
141
+ # Returns (in order of lifecycle):
142
+ # * `:suite` as an initial value, this is outside of the test lifecycle.
143
+ # * `:before_suite_hook` during `before(:suite)` hooks.
144
+ # * `:before_context_hook` during `before(:context)` hooks.
145
+ # * `:before_example_hook` during `before(:example)` hooks and `around(:example)` before `example.run`.
146
+ # * `:example` within the example run.
147
+ # * `:after_example_hook` during `after(:example)` hooks and `around(:example)` after `example.run`.
148
+ # * `:after_context_hook` during `after(:context)` hooks.
149
+ # * `:after_suite_hook` during `after(:suite)` hooks.
150
+ # * `:suite` as a final value, again this is outside of the test lifecycle.
151
+ #
152
+ # Reminder, `:context` hooks have `:all` alias and `:example` hooks have `:each` alias.
153
+ # @return [Symbol]
154
+ def self.current_scope
155
+ RSpec::Support.thread_local_data[:current_scope]
156
+ end
157
+
132
158
  # @private
133
159
  # Internal container for global non-configuration data.
134
160
  def self.world
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.10.2
4
+ version: 3.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Baker
@@ -46,7 +46,7 @@ cert_chain:
46
46
  ZsVDj6a7lH3cNqtWXZxrb2wO38qV5AkYj8SQK7Hj3/Yui9myUX3crr+PdetazSqQ
47
47
  F3MdtaDehhjC
48
48
  -----END CERTIFICATE-----
49
- date: 2022-01-27 00:00:00.000000000 Z
49
+ date: 2022-10-26 00:00:00.000000000 Z
50
50
  dependencies:
51
51
  - !ruby/object:Gem::Dependency
52
52
  name: rspec-support
@@ -54,26 +54,26 @@ dependencies:
54
54
  requirements:
55
55
  - - "~>"
56
56
  - !ruby/object:Gem::Version
57
- version: 3.10.0
57
+ version: 3.12.0
58
58
  type: :runtime
59
59
  prerelease: false
60
60
  version_requirements: !ruby/object:Gem::Requirement
61
61
  requirements:
62
62
  - - "~>"
63
63
  - !ruby/object:Gem::Version
64
- version: 3.10.0
64
+ version: 3.12.0
65
65
  - !ruby/object:Gem::Dependency
66
66
  name: cucumber
67
67
  requirement: !ruby/object:Gem::Requirement
68
68
  requirements:
69
- - - "~>"
69
+ - - ">="
70
70
  - !ruby/object:Gem::Version
71
71
  version: '1.3'
72
72
  type: :development
73
73
  prerelease: false
74
74
  version_requirements: !ruby/object:Gem::Requirement
75
75
  requirements:
76
- - - "~>"
76
+ - - ">="
77
77
  - !ruby/object:Gem::Version
78
78
  version: '1.3'
79
79
  - !ruby/object:Gem::Dependency
@@ -267,7 +267,7 @@ licenses:
267
267
  - MIT
268
268
  metadata:
269
269
  bug_tracker_uri: https://github.com/rspec/rspec-core/issues
270
- changelog_uri: https://github.com/rspec/rspec-core/blob/v3.10.2/Changelog.md
270
+ changelog_uri: https://github.com/rspec/rspec-core/blob/v3.12.0/Changelog.md
271
271
  documentation_uri: https://rspec.info/documentation/
272
272
  mailing_list_uri: https://groups.google.com/forum/#!forum/rspec
273
273
  source_code_uri: https://github.com/rspec/rspec-core
@@ -290,5 +290,5 @@ requirements: []
290
290
  rubygems_version: 3.3.3
291
291
  signing_key:
292
292
  specification_version: 4
293
- summary: rspec-core-3.10.2
293
+ summary: rspec-core-3.12.0
294
294
  test_files: []
metadata.gz.sig CHANGED
Binary file