rspec-core 3.6.0.beta2 → 3.7.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 (40) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Changelog.md +48 -0
  5. data/lib/rspec/core.rb +1 -1
  6. data/lib/rspec/core/configuration.rb +34 -9
  7. data/lib/rspec/core/configuration_options.rb +2 -0
  8. data/lib/rspec/core/drb.rb +1 -1
  9. data/lib/rspec/core/example.rb +11 -7
  10. data/lib/rspec/core/example_group.rb +3 -2
  11. data/lib/rspec/core/formatters.rb +14 -4
  12. data/lib/rspec/core/formatters/base_formatter.rb +1 -1
  13. data/lib/rspec/core/formatters/base_text_formatter.rb +3 -4
  14. data/lib/rspec/core/formatters/deprecation_formatter.rb +6 -8
  15. data/lib/rspec/core/formatters/documentation_formatter.rb +1 -1
  16. data/lib/rspec/core/formatters/exception_presenter.rb +3 -2
  17. data/lib/rspec/core/formatters/html_printer.rb +3 -1
  18. data/lib/rspec/core/formatters/html_snippet_extractor.rb +4 -2
  19. data/lib/rspec/core/formatters/json_formatter.rb +9 -3
  20. data/lib/rspec/core/formatters/protocol.rb +3 -2
  21. data/lib/rspec/core/formatters/snippet_extractor.rb +1 -3
  22. data/lib/rspec/core/{source → formatters}/syntax_highlighter.rb +1 -1
  23. data/lib/rspec/core/hooks.rb +3 -1
  24. data/lib/rspec/core/memoized_helpers.rb +3 -0
  25. data/lib/rspec/core/metadata_filter.rb +17 -0
  26. data/lib/rspec/core/notifications.rb +20 -13
  27. data/lib/rspec/core/option_parser.rb +1 -1
  28. data/lib/rspec/core/output_wrapper.rb +29 -0
  29. data/lib/rspec/core/project_initializer/spec/spec_helper.rb +0 -3
  30. data/lib/rspec/core/reporter.rb +17 -8
  31. data/lib/rspec/core/set.rb +5 -0
  32. data/lib/rspec/core/shared_example_group.rb +0 -5
  33. data/lib/rspec/core/version.rb +1 -1
  34. data/lib/rspec/core/world.rb +13 -5
  35. metadata +14 -17
  36. metadata.gz.sig +0 -0
  37. data/lib/rspec/core/source.rb +0 -86
  38. data/lib/rspec/core/source/location.rb +0 -13
  39. data/lib/rspec/core/source/node.rb +0 -93
  40. data/lib/rspec/core/source/token.rb +0 -87
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cedf9914463a5f8470ddb33bef491f31615a7b63
4
- data.tar.gz: 8eecab50a480c797c96f53932f955643f23db6eb
3
+ metadata.gz: 0b5c0a6998742c8632fd03444e01f5c63ae7feb1
4
+ data.tar.gz: 28050c825d4aae86612c92b8e6ed6fc6ea843ec4
5
5
  SHA512:
6
- metadata.gz: a162b44414bcbd3ac23ee749f456976c10858bc84b8703a4ef63f370fcf8a691b7366ef8a9d0d2e15f7cecea6f38ce78379da1a25be1f75bf09ea9e913aa4939
7
- data.tar.gz: f9a9b8815b6a42d5da60f033443dbf145b025058a6ec327c8a16fde556c83a753b1ed2bfd54ae85e02772fa54e8d7169c7323e034622b52ffbd9e3eab0826841
6
+ metadata.gz: 3b43ec0a2cd3c5286ca23160861983bc4b66948d1c63449e99ea88dda57329e7091483cb033780d253161fd4b9acc1da7e6d08546e12860864ed018ee2725c65
7
+ data.tar.gz: 6a16b4a35c84eba0dda74004a6cc53b9f9a3e3bc638fb3c30bda49a65230c2296fab5a215a4fb6d42606e99a7f874c3f533181d6eafad45143c3c312f69ebe14
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,51 @@
1
+ ### Development
2
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.7.0...master)
3
+
4
+ ### 3.7.0 / 2017-10-17
5
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0...v3.7.0)
6
+
7
+ Enhancements:
8
+
9
+ * Add `-n` alias for `--next-failure`. (Ian Ker-Seymer, #2434)
10
+ * Improve compatibility with `--enable-frozen-string-literal` option
11
+ on Ruby 2.3+. (Pat Allan, #2425, #2427, #2437)
12
+ * Do not run `:context` hooks for example groups that have been skipped.
13
+ (Devon Estes, #2442)
14
+ * Add `errors_outside_of_examples_count` to the JSON formatter.
15
+ (Takeshi Arabiki, #2448)
16
+
17
+ Bug Fixes:
18
+
19
+ * Improve compatibility with frozen string literal flag. (#2425, Pat Allan)
20
+
21
+ ### 3.6.0 / 2017-05-04
22
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0.beta2...v3.6.0)
23
+
24
+ Enhancements:
25
+
26
+ * Add seed information to JSON formatter output. (#2388, Mitsutaka Mimura)
27
+ * Include example id in the JSON formatter output. (#2369, Xavier Shay)
28
+ * Respect changes to `config.output_stream` after formatters have been
29
+ setup. (#2401, #2419, Ilya Lavrov)
30
+
31
+ Bug Fixes:
32
+
33
+ * Delay formatter loading until the last minute to allow accessing the reporter
34
+ without triggering formatter setup. (Jon Rowe, #2243)
35
+ * Ensure context hook failures running before an example can access the
36
+ reporter. (Jon Jensen, #2387)
37
+ * Multiple fixes to allow using the runner multiple times within the same
38
+ process: `RSpec.clear_examples` resets the formatter and no longer clears
39
+ shared examples, and streams can be used across multiple runs rather than
40
+ being closed after the first. (#2368, Xavier Shay)
41
+ * Prevent unexpected `example_group_finished` notifications causing an error.
42
+ (#2396, VTJamie)
43
+ * Fix bugs where `config.when_first_matching_example_defined` hooks would fire
44
+ multiple times in some cases. (Yuji Nakayama, #2400)
45
+ * Default `last_run_status` to "unknown" when the `status` field in the
46
+ persistence file contains an unrecognized value. (#2360, matrinox)
47
+ * Prevent `let` from defining an `initialize` method. (#2414, Jon Rowe)
48
+
1
49
  ### 3.6.0.beta2 / 2016-12-12
2
50
  [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0.beta1...v3.6.0.beta2)
3
51
 
@@ -69,7 +69,7 @@ module RSpec
69
69
  # same process.
70
70
  def self.clear_examples
71
71
  world.reset
72
- configuration.reporter.reset
72
+ configuration.reset_reporter
73
73
  configuration.start_time = ::RSpec::Core::Time.now
74
74
  configuration.reset_filters
75
75
  end
@@ -1,6 +1,7 @@
1
1
  RSpec::Support.require_rspec_core "backtrace_formatter"
2
2
  RSpec::Support.require_rspec_core "ruby_project"
3
3
  RSpec::Support.require_rspec_core "formatters/deprecation_formatter"
4
+ RSpec::Support.require_rspec_core "output_wrapper"
4
5
 
5
6
  module RSpec
6
7
  module Core
@@ -141,7 +142,7 @@ module RSpec
141
142
 
142
143
  # Determines where deprecation warnings are printed.
143
144
  # Defaults to `$stderr`.
144
- # @return [IO, String] IO to write to or filename to write to
145
+ # @return [IO, String] IO or filename to write to
145
146
  define_reader :deprecation_stream
146
147
 
147
148
  # Determines where deprecation warnings are printed.
@@ -160,7 +161,7 @@ module RSpec
160
161
 
161
162
  # @macro define_reader
162
163
  # The file path to use for persisting example statuses. Necessary for the
163
- # `--only-failures` and `--next-failures` CLI options.
164
+ # `--only-failures` and `--next-failure` CLI options.
164
165
  #
165
166
  # @overload example_status_persistence_file_path
166
167
  # @return [String] the file path
@@ -169,7 +170,7 @@ module RSpec
169
170
  define_reader :example_status_persistence_file_path
170
171
 
171
172
  # Sets the file path to use for persisting example statuses. Necessary for the
172
- # `--only-failures` and `--next-failures` CLI options.
173
+ # `--only-failures` and `--next-failure` CLI options.
173
174
  def example_status_persistence_file_path=(value)
174
175
  @example_status_persistence_file_path = value
175
176
  clear_values_derived_from_example_status_persistence_file_path
@@ -218,7 +219,7 @@ module RSpec
218
219
  define_reader :output_stream
219
220
 
220
221
  # Set the output stream for reporter.
221
- # @attr value [IO] value for output, defaults to $stdout
222
+ # @attr value [IO, String] IO to write to or filename to write to, defaults to $stdout
222
223
  def output_stream=(value)
223
224
  if @reporter && !value.equal?(@output_stream)
224
225
  warn "RSpec's reporter has already been initialized with " \
@@ -227,6 +228,7 @@ module RSpec
227
228
  "it to take effect. (Called from #{CallerFilter.first_non_rspec_line})"
228
229
  else
229
230
  @output_stream = value
231
+ output_wrapper.output = @output_stream
230
232
  end
231
233
  end
232
234
 
@@ -411,6 +413,8 @@ module RSpec
411
413
 
412
414
  # rubocop:disable Metrics/AbcSize
413
415
  # rubocop:disable Metrics/MethodLength
416
+
417
+ # Build an object to store runtime configuration options and set defaults
414
418
  def initialize
415
419
  # rubocop:disable Style/GlobalVars
416
420
  @start_time = $_rspec_core_load_started_at || ::RSpec::Core::Time.now
@@ -480,8 +484,14 @@ module RSpec
480
484
  # @private
481
485
  def reset
482
486
  @spec_files_loaded = false
487
+ reset_reporter
488
+ end
489
+
490
+ # @private
491
+ def reset_reporter
483
492
  @reporter = nil
484
493
  @formatter_loader = nil
494
+ @output_wrapper = nil
485
495
  end
486
496
 
487
497
  # @private
@@ -864,7 +874,7 @@ module RSpec
864
874
  # Adds a formatter to the set RSpec will use for this run.
865
875
  #
866
876
  # @see RSpec::Core::Formatters::Protocol
867
- def add_formatter(formatter, output=output_stream)
877
+ def add_formatter(formatter, output=output_wrapper)
868
878
  formatter_loader.add(formatter, output)
869
879
  end
870
880
  alias_method :formatter=, :add_formatter
@@ -930,7 +940,7 @@ module RSpec
930
940
  @reporter_buffer || @reporter ||=
931
941
  begin
932
942
  @reporter_buffer = DeprecationReporterBuffer.new
933
- formatter_loader.setup_default output_stream, deprecation_stream
943
+ formatter_loader.prepare_default output_wrapper, deprecation_stream
934
944
  @reporter_buffer.play_onto(formatter_loader.reporter)
935
945
  @reporter_buffer = nil
936
946
  formatter_loader.reporter
@@ -974,7 +984,9 @@ module RSpec
974
984
  if (path = example_status_persistence_file_path)
975
985
  begin
976
986
  ExampleStatusPersister.load_from(path).inject(statuses) do |hash, example|
977
- hash[example.fetch(:example_id)] = example.fetch(:status)
987
+ status = example[:status]
988
+ status = UNKNOWN_STATUS unless VALID_STATUSES.include?(status)
989
+ hash[example.fetch(:example_id)] = status
978
990
  hash
979
991
  end
980
992
  rescue SystemCallError => e
@@ -994,6 +1006,15 @@ module RSpec
994
1006
  # @private
995
1007
  FAILED_STATUS = "failed".freeze
996
1008
 
1009
+ # @private
1010
+ PASSED_STATUS = "passed".freeze
1011
+
1012
+ # @private
1013
+ PENDING_STATUS = "pending".freeze
1014
+
1015
+ # @private
1016
+ VALID_STATUSES = [UNKNOWN_STATUS, FAILED_STATUS, PASSED_STATUS, PENDING_STATUS]
1017
+
997
1018
  # @private
998
1019
  def spec_files_with_failures
999
1020
  @spec_files_with_failures ||= last_run_statuses.inject(Set.new) do |files, (id, status)|
@@ -1698,7 +1719,7 @@ module RSpec
1698
1719
  # mocks.patch_marshal_to_support_partial_doubles = false
1699
1720
  # end
1700
1721
  #
1701
- # config.mock_with :rspec do |expectations|
1722
+ # config.expect_with :rspec do |expectations|
1702
1723
  # expectations.syntax = :expect
1703
1724
  # end
1704
1725
  # end
@@ -1761,7 +1782,7 @@ module RSpec
1761
1782
  return unless example_or_group_meta.key?(:example_group)
1762
1783
 
1763
1784
  # Ensure the callback only fires once.
1764
- @derived_metadata_blocks.items_for(specified_meta).delete(callback)
1785
+ @derived_metadata_blocks.delete(callback, specified_meta)
1765
1786
 
1766
1787
  block.call
1767
1788
  end
@@ -2039,6 +2060,10 @@ module RSpec
2039
2060
  )
2040
2061
  end
2041
2062
 
2063
+ def output_wrapper
2064
+ @output_wrapper ||= OutputWrapper.new(output_stream)
2065
+ end
2066
+
2042
2067
  def output_to_tty?(output=output_stream)
2043
2068
  output.respond_to?(:tty?) && output.tty?
2044
2069
  end
@@ -186,8 +186,10 @@ module RSpec
186
186
  def global_options_file
187
187
  File.join(File.expand_path("~"), ".rspec")
188
188
  rescue ArgumentError
189
+ # :nocov:
189
190
  RSpec.warning "Unable to find ~/.rspec because the HOME environment variable is not set"
190
191
  nil
192
+ # :nocov:
191
193
  end
192
194
  end
193
195
  end
@@ -84,7 +84,7 @@ module RSpec
84
84
  def add_filter(argv, name, hash)
85
85
  hash.each_pair do |k, v|
86
86
  next if CONDITIONAL_FILTERS.include?(k)
87
- tag = name == :inclusion ? k.to_s : "~#{k}"
87
+ tag = name == :inclusion ? k.to_s : "~#{k}".dup
88
88
  tag << ":#{v}" if v.is_a?(String)
89
89
  argv << "--tag" << tag
90
90
  end unless hash.empty?
@@ -87,7 +87,7 @@ module RSpec
87
87
  def inspect_output
88
88
  inspect_output = "\"#{description}\""
89
89
  unless metadata[:description].to_s.empty?
90
- inspect_output << " (#{location})"
90
+ inspect_output += " (#{location})"
91
91
  end
92
92
  inspect_output
93
93
  end
@@ -260,7 +260,11 @@ module RSpec
260
260
  'Expected example to fail since it is pending, but it passed.',
261
261
  [location]
262
262
  end
263
- rescue Pending::SkipDeclaredInExample
263
+ rescue Pending::SkipDeclaredInExample => _
264
+ # The "=> _" is normally useless but on JRuby it is a workaround
265
+ # for a bug that prevents us from getting backtraces:
266
+ # https://github.com/jruby/jruby/issues/4467
267
+ #
264
268
  # no-op, required metadata has already been set by the `skip`
265
269
  # method.
266
270
  rescue AllExceptionsExcludingDangerousOnesOnRubiesThatAllowIt => e
@@ -465,22 +469,22 @@ module RSpec
465
469
 
466
470
  if @exception
467
471
  execution_result.exception = @exception
468
- record_finished :failed
472
+ record_finished :failed, reporter
469
473
  reporter.example_failed self
470
474
  false
471
475
  elsif pending_message
472
476
  execution_result.pending_message = pending_message
473
- record_finished :pending
477
+ record_finished :pending, reporter
474
478
  reporter.example_pending self
475
479
  true
476
480
  else
477
- record_finished :passed
481
+ record_finished :passed, reporter
478
482
  reporter.example_passed self
479
483
  true
480
484
  end
481
485
  end
482
486
 
483
- def record_finished(status)
487
+ def record_finished(status, reporter)
484
488
  execution_result.record_finished(status, clock.now)
485
489
  reporter.example_finished(self)
486
490
  end
@@ -519,7 +523,7 @@ module RSpec
519
523
  def assign_generated_description
520
524
  if metadata[:description].empty? && (description = generate_description)
521
525
  metadata[:description] = description
522
- metadata[:full_description] << description
526
+ metadata[:full_description] += description
523
527
  end
524
528
  ensure
525
529
  RSpec::Matchers.clear_generated_description
@@ -3,6 +3,7 @@ RSpec::Support.require_rspec_support 'recursive_const_methods'
3
3
  module RSpec
4
4
  module Core
5
5
  # rubocop:disable Metrics/ClassLength
6
+
6
7
  # ExampleGroup and {Example} are the main structural elements of
7
8
  # rspec-core. Consider this example:
8
9
  #
@@ -838,10 +839,10 @@ module RSpec
838
839
  end
839
840
 
840
841
  def self.base_name_for(group)
841
- return "Anonymous" if group.description.empty?
842
+ return "Anonymous".dup if group.description.empty?
842
843
 
843
844
  # Convert to CamelCase.
844
- name = ' ' << group.description
845
+ name = ' ' + group.description
845
846
  name.gsub!(/[^0-9a-zA-Z]+([0-9a-zA-Z])/) do
846
847
  match = ::Regexp.last_match[1]
847
848
  match.upcase!
@@ -115,6 +115,11 @@ module RSpec::Core::Formatters
115
115
  # @return [String] the default formatter to setup, defaults to `progress`
116
116
  attr_accessor :default_formatter
117
117
 
118
+ # @private
119
+ def prepare_default(output_stream, deprecation_stream)
120
+ reporter.prepare_default(self, output_stream, deprecation_stream)
121
+ end
122
+
118
123
  # @private
119
124
  def setup_default(output_stream, deprecation_stream)
120
125
  add default_formatter, output_stream if @formatters.empty?
@@ -140,7 +145,7 @@ module RSpec::Core::Formatters
140
145
  def add(formatter_to_use, *paths)
141
146
  formatter_class = find_formatter(formatter_to_use)
142
147
 
143
- args = paths.map { |p| p.respond_to?(:puts) ? p : file_at(p) }
148
+ args = paths.map { |p| p.respond_to?(:puts) ? p : open_stream(p) }
144
149
 
145
150
  if !Loader.formatters[formatter_class].nil?
146
151
  formatter = formatter_class.new(*args)
@@ -247,9 +252,14 @@ module RSpec::Core::Formatters
247
252
  word
248
253
  end
249
254
 
250
- def file_at(path)
251
- RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(path))
252
- File.new(path, 'w')
255
+ def open_stream(path_or_wrapper)
256
+ if RSpec::Core::OutputWrapper === path_or_wrapper
257
+ path_or_wrapper.output = open_stream(path_or_wrapper.output)
258
+ path_or_wrapper
259
+ else
260
+ RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(path_or_wrapper))
261
+ File.new(path_or_wrapper, 'w')
262
+ end
253
263
  end
254
264
  end
255
265
  end
@@ -5,7 +5,7 @@ module RSpec
5
5
  module Core
6
6
  module Formatters
7
7
  # RSpec's built-in formatters are all subclasses of
8
- # RSpec::Core::Formatters::BaseTextFormatter.
8
+ # RSpec::Core::Formatters::BaseFormatter.
9
9
  #
10
10
  # @see RSpec::Core::Formatters::BaseTextFormatter
11
11
  # @see RSpec::Core::Reporter
@@ -57,18 +57,17 @@ module RSpec
57
57
 
58
58
  # @api public
59
59
  #
60
- # Invoked at the very end, `close` allows the formatter to clean
61
- # up resources, e.g. open streams, etc.
60
+ # Invoked at the end of a suite run. Allows the formatter to do any
61
+ # tidying up, but be aware that formatter output streams may be used
62
+ # elsewhere so don't actually close them.
62
63
  #
63
64
  # @param _notification [NullNotification] (Ignored)
64
65
  def close(_notification)
65
- return unless IO === output
66
66
  return if output.closed?
67
67
 
68
68
  output.puts
69
69
 
70
70
  output.flush
71
- output.close unless output == $stdout
72
71
  end
73
72
  end
74
73
  end
@@ -59,6 +59,8 @@ module RSpec
59
59
 
60
60
  DEPRECATION_STREAM_NOTICE = "Pass `--deprecation-out` or set " \
61
61
  "`config.deprecation_stream` to a file for full output."
62
+ TOO_MANY_WARNINGS_NOTICE = "Too many similar deprecation messages " \
63
+ "reported, disregarding further reports. #{DEPRECATION_STREAM_NOTICE}"
62
64
 
63
65
  SpecifiedDeprecationMessage = Struct.new(:type) do
64
66
  def initialize(data)
@@ -71,9 +73,7 @@ module RSpec
71
73
  end
72
74
 
73
75
  def too_many_warnings_message
74
- msg = "Too many similar deprecation messages reported, disregarding further reports. "
75
- msg << DEPRECATION_STREAM_NOTICE
76
- msg
76
+ TOO_MANY_WARNINGS_NOTICE
77
77
  end
78
78
 
79
79
  private
@@ -96,16 +96,14 @@ module RSpec
96
96
  end
97
97
 
98
98
  def to_s
99
- msg = "#{@data.deprecated} is deprecated."
99
+ msg = String.new("#{@data.deprecated} is deprecated.")
100
100
  msg << " Use #{@data.replacement} instead." if @data.replacement
101
- msg << " Called from #{@data.call_site}." if @data.call_site
101
+ msg << " Called from #{@data.call_site}." if @data.call_site
102
102
  msg
103
103
  end
104
104
 
105
105
  def too_many_warnings_message
106
- msg = "Too many uses of deprecated '#{type}'. "
107
- msg << DEPRECATION_STREAM_NOTICE
108
- msg
106
+ "Too many uses of deprecated '#{type}'. #{DEPRECATION_STREAM_NOTICE}"
109
107
  end
110
108
  end
111
109
 
@@ -22,7 +22,7 @@ module RSpec
22
22
  end
23
23
 
24
24
  def example_group_finished(_notification)
25
- @group_level -= 1
25
+ @group_level -= 1 if @group_level > 0
26
26
  end
27
27
 
28
28
  def example_passed(passed)
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
  RSpec::Support.require_rspec_core "formatters/console_codes"
3
3
  RSpec::Support.require_rspec_core "formatters/snippet_extractor"
4
+ RSpec::Support.require_rspec_core 'formatters/syntax_highlighter'
4
5
  RSpec::Support.require_rspec_support "encoded_string"
5
6
 
6
7
  module RSpec
@@ -215,7 +216,7 @@ module RSpec
215
216
  file_path, line_number = file_and_line_number[1..2]
216
217
  max_line_count = RSpec.configuration.max_displayed_failure_line_count
217
218
  lines = SnippetExtractor.extract_expression_lines_at(file_path, line_number.to_i, max_line_count)
218
- RSpec.world.source_cache.syntax_highlighter.highlight(lines)
219
+ RSpec.world.syntax_highlighter.highlight(lines)
219
220
  rescue SnippetExtractor::NoSuchFileError
220
221
  ["Unable to find #{file_path} to read failed line"]
221
222
  rescue SnippetExtractor::NoSuchLineError
@@ -279,7 +280,7 @@ module RSpec
279
280
  :description => "#{@example.full_description} FIXED",
280
281
  :message_color => RSpec.configuration.fixed_color,
281
282
  :failure_lines => [
282
- "Expected pending '#{@execution_result.pending_message}' to fail. No Error was raised."
283
+ "Expected pending '#{@execution_result.pending_message}' to fail. No error was raised."
283
284
  ]
284
285
  }
285
286
  elsif @execution_result.status == :pending