rspec-core 3.6.0.beta2 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.
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