rspec-core 3.5.1 → 3.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 (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Changelog.md +101 -2
  4. data/lib/rspec/core/bisect/server.rb +6 -1
  5. data/lib/rspec/core/configuration.rb +110 -26
  6. data/lib/rspec/core/configuration_options.rb +2 -0
  7. data/lib/rspec/core/drb.rb +2 -0
  8. data/lib/rspec/core/example.rb +18 -12
  9. data/lib/rspec/core/example_group.rb +16 -6
  10. data/lib/rspec/core/formatters/base_text_formatter.rb +3 -5
  11. data/lib/rspec/core/formatters/console_codes.rb +7 -4
  12. data/lib/rspec/core/formatters/documentation_formatter.rb +2 -1
  13. data/lib/rspec/core/formatters/exception_presenter.rb +10 -4
  14. data/lib/rspec/core/formatters/html_formatter.rb +4 -2
  15. data/lib/rspec/core/formatters/html_snippet_extractor.rb +2 -0
  16. data/lib/rspec/core/formatters/json_formatter.rb +7 -2
  17. data/lib/rspec/core/formatters/progress_formatter.rb +1 -0
  18. data/lib/rspec/core/formatters/protocol.rb +26 -25
  19. data/lib/rspec/core/formatters/snippet_extractor.rb +1 -3
  20. data/lib/rspec/core/{source → formatters}/syntax_highlighter.rb +21 -1
  21. data/lib/rspec/core/formatters.rb +15 -5
  22. data/lib/rspec/core/hooks.rb +1 -8
  23. data/lib/rspec/core/invocations.rb +22 -4
  24. data/lib/rspec/core/memoized_helpers.rb +3 -0
  25. data/lib/rspec/core/metadata.rb +1 -0
  26. data/lib/rspec/core/metadata_filter.rb +29 -17
  27. data/lib/rspec/core/notifications.rb +20 -5
  28. data/lib/rspec/core/option_parser.rb +32 -12
  29. data/lib/rspec/core/output_wrapper.rb +29 -0
  30. data/lib/rspec/core/project_initializer/.rspec +0 -1
  31. data/lib/rspec/core/project_initializer/spec/spec_helper.rb +1 -4
  32. data/lib/rspec/core/rake_task.rb +1 -0
  33. data/lib/rspec/core/reporter.rb +33 -9
  34. data/lib/rspec/core/runner.rb +10 -3
  35. data/lib/rspec/core/set.rb +5 -0
  36. data/lib/rspec/core/shared_example_group.rb +39 -15
  37. data/lib/rspec/core/version.rb +1 -1
  38. data/lib/rspec/core/world.rb +23 -5
  39. data/lib/rspec/core.rb +2 -1
  40. data.tar.gz.sig +0 -0
  41. metadata +8 -11
  42. metadata.gz.sig +2 -4
  43. data/lib/rspec/core/source/location.rb +0 -13
  44. data/lib/rspec/core/source/node.rb +0 -93
  45. data/lib/rspec/core/source/token.rb +0 -87
  46. data/lib/rspec/core/source.rb +0 -86
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8edadb66ad16d53a8e8b9c24bcb0d6e0d0cf60a4
4
- data.tar.gz: 482215825781fdb27385c38e782ae15eea0d4340
3
+ metadata.gz: 33bf2ee1c5d02653b19cece430ba75ac28668df0
4
+ data.tar.gz: 5c3e3a2f628543125d4bc02ffff6ee05135e4d1e
5
5
  SHA512:
6
- metadata.gz: 033297ca6896a612fda69a3a7c4f60b98dac28da47312c866a0c1bbfcf799163393b9520f4e158f48d7bdf5b0d8d21dd65091f79779e9fe4e0e0530913588079
7
- data.tar.gz: 290acfab949ab5e5bf54b6cb67d298c232e03c3c00155a18754e327d79aa68d0bf8f210db2ee1f6aea2fc9b7271dd518cd08ee606c31a8f66035b4eee92b6e0f
6
+ metadata.gz: ca2f7dea70f81dad661b79e61b7b4142989368fddca025d8741a97d5d36037bf598c4dff28a37c4a25bc5116520aa49ace6fbd4cc16b1f7b49bc8f5ef1956435
7
+ data.tar.gz: 8d104339ba402be5aec231e5d16e6fcad61cd9b81554593f71f87393b0638f6be590fdbdab06c54b1f981ef9f576eff8db302e32026d8ecabaebb9710d219ba9
checksums.yaml.gz.sig CHANGED
Binary file
data/Changelog.md CHANGED
@@ -1,3 +1,102 @@
1
+ ### 3.6.0 / 2017-05-04
2
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0.beta2...v3.6.0)
3
+
4
+ Enhancements:
5
+
6
+ * Add seed information to JSON formatter output. (#2388, Mitsutaka Mimura)
7
+ * Include example id in the JSON formatter output. (#2369, Xavier Shay)
8
+ * Respect changes to `config.output_stream` after formatters have been
9
+ setup. (#2401, #2419, Ilya Lavrov)
10
+
11
+ Bug Fixes:
12
+
13
+ * Delay formatter loading until the last minute to allow accessing the reporter
14
+ without triggering formatter setup. (Jon Rowe, #2243)
15
+ * Ensure context hook failures running before an example can access the
16
+ reporter. (Jon Jensen, #2387)
17
+ * Multiple fixes to allow using the runner multiple times within the same
18
+ process: `RSpec.clear_examples` resets the formatter and no longer clears
19
+ shared examples, and streams can be used across multiple runs rather than
20
+ being closed after the first. (#2368, Xavier Shay)
21
+ * Prevent unexpected `example_group_finished` notifications causing an error.
22
+ (#2396, VTJamie)
23
+ * Fix bugs where `config.when_first_matching_example_defined` hooks would fire
24
+ multiple times in some cases. (Yuji Nakayama, #2400)
25
+ * Default `last_run_status` to "unknown" when the `status` field in the
26
+ persistence file contains an unrecognized value. (#2360, matrinox)
27
+ * Prevent `let` from defining an `initialize` method. (#2414, Jon Rowe)
28
+
29
+ ### 3.6.0.beta2 / 2016-12-12
30
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.6.0.beta1...v3.6.0.beta2)
31
+
32
+ Enhancements:
33
+
34
+ * Include count of errors occurring outside examples in default summaries.
35
+ (#2351, Jon Rowe)
36
+ * Warn when including shared example groups recursively. (#2356, Jon Rowe)
37
+ * Improve failure snippet syntax highlighting with CodeRay to highlight
38
+ RSpec "keywords" like `expect`. (#2358, Myron Marston)
39
+
40
+ ### 3.6.0.beta1 / 2016-10-09
41
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.4...v3.6.0.beta1)
42
+
43
+ Enhancements:
44
+
45
+ * Warn when duplicate shared examples definitions are loaded due to being
46
+ defined in files matching the spec pattern (e.g. `_spec.rb`) (#2278, Devon Estes)
47
+ * Improve metadata filtering so that it can match against any object
48
+ that implements `===` instead of treating regular expressions as
49
+ special. (Myron Marston, #2294)
50
+ * Improve `rspec -v` so that it prints out the versions of each part of
51
+ RSpec to prevent confusion. (Myron Marston, #2304)
52
+ * Add `config.fail_if_no_examples` option which causes RSpec to fail if
53
+ no examples are found. (Ewa Czechowska, #2302)
54
+ * Nicely format errors encountered while loading spec files.
55
+ (Myron Marston, #2323)
56
+ * Improve the API for enabling and disabling color output (Josh
57
+ Justice, #2321):
58
+ * Automatically enable color if the output is a TTY, since color is
59
+ nearly always desirable if the output can handle it.
60
+ * Introduce new CLI flag to force color on (`--force-color`), even
61
+ if the output is not a TTY. `--no-color` continues to work as well.
62
+ * Introduce `config.color_mode` for configuring the color from Ruby.
63
+ `:automatic` is the default and will produce color if the output is
64
+ a TTY. `:on` forces it on and `:off` forces it off.
65
+
66
+ ### 3.5.4 / 2016-09-30
67
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.3...v3.5.4)
68
+
69
+ Bug Fixes:
70
+
71
+ * Remove accumulated `ExampleGroup` constants when reseting RSpec,
72
+ preventing a memory leak. (TravisSpangle, #2328)
73
+
74
+ ### 3.5.3 / 2016-09-02
75
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.2...v3.5.3)
76
+
77
+ Bug Fixes:
78
+
79
+ * When applying shared group metadata to a host group, overwrite
80
+ conflicting keys if the value in the host group was inherited from
81
+ a parent group instead of being specified at that level.
82
+ (Myron Marston, #2307)
83
+ * Handle errors in `:suite` hooks and provide the same nicely formatted
84
+ output as errors that happen in examples. (Myron Marston, #2316)
85
+ * Set the exit status to non-zero when an error occurs in an
86
+ `after(:context)` hook. (Myron Marston, #2320)
87
+
88
+ ### 3.5.2 / 2016-07-28
89
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.1...v3.5.2)
90
+
91
+ Bug Fixes:
92
+
93
+ * Wait to report `example_finished` until the example's `execution_result`
94
+ has been completely filled in. (Myron Marston, #2291)
95
+ * Make sure example block is still available when using `duplicate_with`
96
+ to clone examples. (bootstraponline, #2298)
97
+ * Don't include the default `--pattern` in the Rake task when
98
+ `rspec_opts` specifies its own. (Jon Rowe, #2305)
99
+
1
100
  ### 3.5.1 / 2016-07-06
2
101
  [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0...v3.5.1)
3
102
 
@@ -1829,7 +1928,7 @@ project's root directory or in your home directory:
1829
1928
 
1830
1929
  require "autotest/bundler"
1831
1930
 
1832
- Now you can just type 'autotest' on the commmand line and it will work as you expect.
1931
+ Now you can just type 'autotest' on the command line and it will work as you expect.
1833
1932
 
1834
1933
  If you don't want 'bundle exec', there is nothing you have to do.
1835
1934
 
@@ -2017,7 +2116,7 @@ Bug fixes
2017
2116
  Enhancements
2018
2117
 
2019
2118
  * implicitly require unknown formatters so you don't have to require the file
2020
- explicitly on the commmand line (Michael Grosser)
2119
+ explicitly on the command line (Michael Grosser)
2021
2120
  * add --out/-o option to assign output target
2022
2121
  * added fail_fast configuration option to abort on first failure
2023
2122
  * support a Hash subject (its([:key]) { should == value }) (Josep M. Bach)
@@ -25,7 +25,12 @@ module RSpec
25
25
  self.files_or_directories_to_run = files_or_directories_to_run
26
26
  self.latest_run_results = nil
27
27
  run_output = yield
28
- latest_run_results || raise_bisect_failed(run_output)
28
+
29
+ if latest_run_results.nil? || latest_run_results.all_example_ids.empty?
30
+ raise_bisect_failed(run_output)
31
+ end
32
+
33
+ latest_run_results
29
34
  end
30
35
 
31
36
  def start
@@ -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.
@@ -199,6 +200,10 @@ module RSpec
199
200
  # The exit code to return if there are any failures (default: 1).
200
201
  add_setting :failure_exit_code
201
202
 
203
+ # @macro add_setting
204
+ # Whether or not to fail when there are no RSpec examples (default: false).
205
+ add_setting :fail_if_no_examples
206
+
202
207
  # @macro define_reader
203
208
  # Indicates files configured to be required.
204
209
  define_reader :requires
@@ -214,7 +219,7 @@ module RSpec
214
219
  define_reader :output_stream
215
220
 
216
221
  # Set the output stream for reporter.
217
- # @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
218
223
  def output_stream=(value)
219
224
  if @reporter && !value.equal?(@output_stream)
220
225
  warn "RSpec's reporter has already been initialized with " \
@@ -223,6 +228,7 @@ module RSpec
223
228
  "it to take effect. (Called from #{CallerFilter.first_non_rspec_line})"
224
229
  else
225
230
  @output_stream = value
231
+ output_wrapper.output = @output_stream
226
232
  end
227
233
  end
228
234
 
@@ -394,6 +400,7 @@ module RSpec
394
400
  add_setting :max_displayed_failure_line_count
395
401
 
396
402
  # @private
403
+ # @deprecated Use {#color_mode} = :on, instead of {#color} with {#tty}
397
404
  add_setting :tty
398
405
  # @private
399
406
  attr_writer :files_to_run
@@ -422,9 +429,11 @@ module RSpec
422
429
  @files_or_directories_to_run = []
423
430
  @loaded_spec_files = Set.new
424
431
  @color = false
432
+ @color_mode = :automatic
425
433
  @pattern = '**{,/*/**}/*_spec.rb'
426
434
  @exclude_pattern = ''
427
435
  @failure_exit_code = 1
436
+ @fail_if_no_examples = false
428
437
  @spec_files_loaded = false
429
438
 
430
439
  @backtrace_formatter = BacktraceFormatter.new
@@ -473,8 +482,14 @@ module RSpec
473
482
  # @private
474
483
  def reset
475
484
  @spec_files_loaded = false
485
+ reset_reporter
486
+ end
487
+
488
+ # @private
489
+ def reset_reporter
476
490
  @reporter = nil
477
491
  @formatter_loader = nil
492
+ @output_wrapper = nil
478
493
  end
479
494
 
480
495
  # @private
@@ -773,24 +788,54 @@ module RSpec
773
788
  @backtrace_formatter.full_backtrace = true_or_false
774
789
  end
775
790
 
776
- # Returns the configuration option for color, but should not
777
- # be used to check if color is supported.
791
+ # Enables color output if the output is a TTY. As of RSpec 3.6, this is
792
+ # the default behavior and this option is retained only for backwards
793
+ # compatibility.
778
794
  #
795
+ # @deprecated No longer recommended because of complex behavior. Instead,
796
+ # rely on the fact that TTYs will display color by default, or set
797
+ # {#color_mode} to :on to display color on a non-TTY output.
798
+ # @see color_mode
779
799
  # @see color_enabled?
780
800
  # @return [Boolean]
781
801
  def color
782
802
  value_for(:color) { @color }
783
803
  end
784
804
 
805
+ # The mode for determining whether to display output in color. One of:
806
+ #
807
+ # - :automatic - the output will be in color if the output is a TTY (the
808
+ # default)
809
+ # - :on - the output will be in color, whether or not the output is a TTY
810
+ # - :off - the output will not be in color
811
+ #
812
+ # @see color_enabled?
813
+ # @return [Boolean]
814
+ def color_mode
815
+ value_for(:color_mode) { @color_mode }
816
+ end
817
+
785
818
  # Check if color is enabled for a particular output.
786
819
  # @param output [IO] an output stream to use, defaults to the current
787
820
  # `output_stream`
788
821
  # @return [Boolean]
789
822
  def color_enabled?(output=output_stream)
790
- output_to_tty?(output) && color
823
+ case color_mode
824
+ when :on then true
825
+ when :off then false
826
+ else # automatic
827
+ output_to_tty?(output) || (color && tty?)
828
+ end
791
829
  end
792
830
 
831
+ # Set the color mode.
832
+ attr_writer :color_mode
833
+
793
834
  # Toggle output color.
835
+ #
836
+ # @deprecated No longer recommended because of complex behavior. Instead,
837
+ # rely on the fact that TTYs will display color by default, or set
838
+ # {:color_mode} to :on to display color on a non-TTY output.
794
839
  attr_writer :color
795
840
 
796
841
  # @private
@@ -813,19 +858,22 @@ module RSpec
813
858
  end
814
859
 
815
860
  # @overload add_formatter(formatter)
861
+ # @overload add_formatter(formatter, output)
816
862
  #
817
- # Adds a formatter to the formatters collection. `formatter` can be a
818
- # string representing any of the built-in formatters (see
819
- # `built_in_formatter`), or a custom formatter class.
863
+ # @param formatter [Class, String] formatter to use. Can be any of the
864
+ # string values supported from the CLI (`p`/`progress`,
865
+ # `d`/`doc`/`documentation`, `h`/`html`, or `j`/`json`) or any
866
+ # class that implements the formatter protocol and has registered
867
+ # itself with RSpec as a formatter.
868
+ # @param output [String, IO] where the formatter will write its output.
869
+ # Can be an IO object or a string path to a file. If not provided,
870
+ # the configured `output_stream` (`$stdout`, by default) will be used.
820
871
  #
821
- # ### Note
872
+ # Adds a formatter to the set RSpec will use for this run.
822
873
  #
823
- # For internal purposes, `add_formatter` also accepts the name of a class
824
- # and paths to use for output streams, but you should consider that a
825
- # private api that may change at any time without notice.
826
- def add_formatter(formatter_to_use, *paths)
827
- paths << output_stream if paths.empty?
828
- formatter_loader.add formatter_to_use, *paths
874
+ # @see RSpec::Core::Formatters::Protocol
875
+ def add_formatter(formatter, output=output_wrapper)
876
+ formatter_loader.add(formatter, output)
829
877
  end
830
878
  alias_method :formatter=, :add_formatter
831
879
 
@@ -890,7 +938,7 @@ module RSpec
890
938
  @reporter_buffer || @reporter ||=
891
939
  begin
892
940
  @reporter_buffer = DeprecationReporterBuffer.new
893
- formatter_loader.setup_default output_stream, deprecation_stream
941
+ formatter_loader.prepare_default output_wrapper, deprecation_stream
894
942
  @reporter_buffer.play_onto(formatter_loader.reporter)
895
943
  @reporter_buffer = nil
896
944
  formatter_loader.reporter
@@ -934,7 +982,9 @@ module RSpec
934
982
  if (path = example_status_persistence_file_path)
935
983
  begin
936
984
  ExampleStatusPersister.load_from(path).inject(statuses) do |hash, example|
937
- hash[example.fetch(:example_id)] = example.fetch(:status)
985
+ status = example[:status]
986
+ status = UNKNOWN_STATUS unless VALID_STATUSES.include?(status)
987
+ hash[example.fetch(:example_id)] = status
938
988
  hash
939
989
  end
940
990
  rescue SystemCallError => e
@@ -954,6 +1004,15 @@ module RSpec
954
1004
  # @private
955
1005
  FAILED_STATUS = "failed".freeze
956
1006
 
1007
+ # @private
1008
+ PASSED_STATUS = "passed".freeze
1009
+
1010
+ # @private
1011
+ PENDING_STATUS = "pending".freeze
1012
+
1013
+ # @private
1014
+ VALID_STATUSES = [UNKNOWN_STATUS, FAILED_STATUS, PASSED_STATUS, PENDING_STATUS]
1015
+
957
1016
  # @private
958
1017
  def spec_files_with_failures
959
1018
  @spec_files_with_failures ||= last_run_statuses.inject(Set.new) do |files, (id, status)|
@@ -1432,7 +1491,7 @@ module RSpec
1432
1491
 
1433
1492
  files_to_run.uniq.each do |f|
1434
1493
  file = File.expand_path(f)
1435
- load file
1494
+ load_spec_file_handling_errors(file)
1436
1495
  loaded_spec_files << file
1437
1496
  end
1438
1497
 
@@ -1658,7 +1717,7 @@ module RSpec
1658
1717
  # mocks.patch_marshal_to_support_partial_doubles = false
1659
1718
  # end
1660
1719
  #
1661
- # config.mock_with :rspec do |expectations|
1720
+ # config.expect_with :rspec do |expectations|
1662
1721
  # expectations.syntax = :expect
1663
1722
  # end
1664
1723
  # end
@@ -1721,7 +1780,7 @@ module RSpec
1721
1780
  return unless example_or_group_meta.key?(:example_group)
1722
1781
 
1723
1782
  # Ensure the callback only fires once.
1724
- @derived_metadata_blocks.items_for(specified_meta).delete(callback)
1783
+ @derived_metadata_blocks.delete(callback, specified_meta)
1725
1784
 
1726
1785
  block.call
1727
1786
  end
@@ -1830,12 +1889,11 @@ module RSpec
1830
1889
  def with_suite_hooks
1831
1890
  return yield if dry_run?
1832
1891
 
1833
- hook_context = SuiteHookContext.new
1834
1892
  begin
1835
- run_hooks_with(@before_suite_hooks, hook_context)
1893
+ run_suite_hooks("a `before(:suite)` hook", @before_suite_hooks)
1836
1894
  yield
1837
1895
  ensure
1838
- run_hooks_with(@after_suite_hooks, hook_context)
1896
+ run_suite_hooks("an `after(:suite)` hook", @after_suite_hooks)
1839
1897
  end
1840
1898
  end
1841
1899
 
@@ -1860,6 +1918,14 @@ module RSpec
1860
1918
 
1861
1919
  private
1862
1920
 
1921
+ def load_spec_file_handling_errors(file)
1922
+ load file
1923
+ rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex
1924
+ relative_file = Metadata.relative_path(file)
1925
+ reporter.notify_non_example_exception(ex, "An error occurred while loading #{relative_file}.")
1926
+ RSpec.world.wants_to_quit = true
1927
+ end
1928
+
1863
1929
  def handle_suite_hook(scope, meta)
1864
1930
  return nil unless scope == :suite
1865
1931
 
@@ -1875,8 +1941,22 @@ module RSpec
1875
1941
  yield
1876
1942
  end
1877
1943
 
1878
- def run_hooks_with(hooks, hook_context)
1879
- hooks.each { |h| h.run(hook_context) }
1944
+ def run_suite_hooks(hook_description, hooks)
1945
+ context = SuiteHookContext.new(hook_description, reporter)
1946
+
1947
+ hooks.each do |hook|
1948
+ begin
1949
+ hook.run(context)
1950
+ rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex
1951
+ context.set_exception(ex)
1952
+
1953
+ # Do not run subsequent `before` hooks if one fails.
1954
+ # But for `after` hooks, we run them all so that all
1955
+ # cleanup bits get a chance to complete, minimizing the
1956
+ # chance that resources get left behind.
1957
+ break if hooks.equal?(@before_suite_hooks)
1958
+ end
1959
+ end
1880
1960
  end
1881
1961
 
1882
1962
  def get_files_to_run(paths)
@@ -1978,8 +2058,12 @@ module RSpec
1978
2058
  )
1979
2059
  end
1980
2060
 
2061
+ def output_wrapper
2062
+ @output_wrapper ||= OutputWrapper.new(output_stream)
2063
+ end
2064
+
1981
2065
  def output_to_tty?(output=output_stream)
1982
- tty? || (output.respond_to?(:tty?) && output.tty?)
2066
+ output.respond_to?(:tty?) && output.tty?
1983
2067
  end
1984
2068
 
1985
2069
  def conditionally_disable_mocks_monkey_patching
@@ -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
@@ -41,6 +41,8 @@ module RSpec
41
41
  def options
42
42
  argv = []
43
43
  argv << "--color" if @submitted_options[:color]
44
+ argv << "--force-color" if @submitted_options[:color_mode] == :on
45
+ argv << "--no-color" if @submitted_options[:color_mode] == :off
44
46
  argv << "--profile" if @submitted_options[:profile_examples]
45
47
  argv << "--backtrace" if @submitted_options[:full_backtrace]
46
48
  argv << "--tty" if @submitted_options[:tty]
@@ -138,8 +138,10 @@ module RSpec
138
138
 
139
139
  # don't clone the example group because the new example
140
140
  # must belong to the same example group (not a clone).
141
+ #
142
+ # block is nil in new_metadata so we have to get it from metadata.
141
143
  Example.new(example_group, description.clone,
142
- new_metadata, new_metadata[:block])
144
+ new_metadata, metadata[:block])
143
145
  end
144
146
 
145
147
  # @private
@@ -258,7 +260,11 @@ module RSpec
258
260
  'Expected example to fail since it is pending, but it passed.',
259
261
  [location]
260
262
  end
261
- 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
+ #
262
268
  # no-op, required metadata has already been set by the `skip`
263
269
  # method.
264
270
  rescue AllExceptionsExcludingDangerousOnesOnRubiesThatAllowIt => e
@@ -461,26 +467,26 @@ module RSpec
461
467
  def finish(reporter)
462
468
  pending_message = execution_result.pending_message
463
469
 
464
- reporter.example_finished(self)
465
470
  if @exception
466
- record_finished :failed
467
471
  execution_result.exception = @exception
472
+ record_finished :failed, reporter
468
473
  reporter.example_failed self
469
474
  false
470
475
  elsif pending_message
471
- record_finished :pending
472
476
  execution_result.pending_message = pending_message
477
+ record_finished :pending, reporter
473
478
  reporter.example_pending self
474
479
  true
475
480
  else
476
- record_finished :passed
481
+ record_finished :passed, reporter
477
482
  reporter.example_passed self
478
483
  true
479
484
  end
480
485
  end
481
486
 
482
- def record_finished(status)
487
+ def record_finished(status, reporter)
483
488
  execution_result.record_finished(status, clock.now)
489
+ reporter.example_finished(self)
484
490
  end
485
491
 
486
492
  def run_before_example
@@ -630,16 +636,16 @@ module RSpec
630
636
  # @private
631
637
  # Provides an execution context for before/after :suite hooks.
632
638
  class SuiteHookContext < Example
633
- def initialize
634
- super(AnonymousExampleGroup, "", {})
639
+ def initialize(hook_description, reporter)
640
+ super(AnonymousExampleGroup, hook_description, {})
635
641
  @example_group_instance = AnonymousExampleGroup.new
642
+ @reporter = reporter
636
643
  end
637
644
 
638
645
  # rubocop:disable Style/AccessorMethodName
639
-
640
- # To ensure we don't silence errors.
641
646
  def set_exception(exception)
642
- raise exception
647
+ reporter.notify_non_example_exception(exception, "An error occurred in #{description}.")
648
+ RSpec.world.wants_to_quit = true
643
649
  end
644
650
  # rubocop:enable Style/AccessorMethodName
645
651
  end
@@ -415,10 +415,10 @@ module RSpec
415
415
  # not be applied where they should.
416
416
  registration_collection << self
417
417
 
418
- user_metadata = Metadata.build_hash_from(args)
418
+ @user_metadata = Metadata.build_hash_from(args)
419
419
 
420
420
  @metadata = Metadata::ExampleGroupHash.create(
421
- superclass_metadata, user_metadata,
421
+ superclass_metadata, @user_metadata,
422
422
  superclass.method(:next_runnable_index_for),
423
423
  description, *args, &example_group_block
424
424
  )
@@ -705,8 +705,8 @@ module RSpec
705
705
 
706
706
  # @private
707
707
  def self.update_inherited_metadata(updates)
708
- metadata.update(updates) do |_key, existing_group_value, _new_inherited_value|
709
- existing_group_value
708
+ metadata.update(updates) do |key, existing_group_value, new_inherited_value|
709
+ @user_metadata.key?(key) ? existing_group_value : new_inherited_value
710
710
  end
711
711
 
712
712
  RSpec.configuration.configure_group(self)
@@ -793,8 +793,12 @@ module RSpec
793
793
  # @private
794
794
  def self.with_frame(name, location)
795
795
  current_stack = shared_example_group_inclusions
796
- current_stack << new(name, location)
797
- yield
796
+ if current_stack.any? { |frame| frame.shared_group_name == name }
797
+ raise ArgumentError, "can't include shared examples recursively"
798
+ else
799
+ current_stack << new(name, location)
800
+ yield
801
+ end
798
802
  ensure
799
803
  current_stack.pop
800
804
  end
@@ -827,6 +831,12 @@ module RSpec
827
831
  const_scope
828
832
  end
829
833
 
834
+ def self.remove_all_constants
835
+ constants.each do |constant|
836
+ __send__(:remove_const, constant)
837
+ end
838
+ end
839
+
830
840
  def self.base_name_for(group)
831
841
  return "Anonymous" if group.description.empty?
832
842
 
@@ -1,5 +1,4 @@
1
1
  RSpec::Support.require_rspec_core "formatters/base_formatter"
2
- RSpec::Support.require_rspec_core "formatters/console_codes"
3
2
 
4
3
  module RSpec
5
4
  module Core
@@ -58,18 +57,17 @@ module RSpec
58
57
 
59
58
  # @api public
60
59
  #
61
- # Invoked at the very end, `close` allows the formatter to clean
62
- # 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.
63
63
  #
64
64
  # @param _notification [NullNotification] (Ignored)
65
65
  def close(_notification)
66
- return unless IO === output
67
66
  return if output.closed?
68
67
 
69
68
  output.puts
70
69
 
71
70
  output.flush
72
- output.close unless output == $stdout
73
71
  end
74
72
  end
75
73
  end
@@ -23,9 +23,12 @@ module RSpec
23
23
  module_function
24
24
 
25
25
  # @private
26
- CONFIG_COLORS_TO_METHODS = Configuration.instance_methods.grep(/_color\z/).inject({}) do |hash, method|
27
- hash[method.to_s.sub(/_color\z/, '').to_sym] = method
28
- hash
26
+ def config_colors_to_methods
27
+ @config_colors_to_methods ||=
28
+ Configuration.instance_methods.grep(/_color\z/).inject({}) do |hash, method|
29
+ hash[method.to_s.sub(/_color\z/, '').to_sym] = method
30
+ hash
31
+ end
29
32
  end
30
33
 
31
34
  # Fetches the correct code for the supplied symbol, or checks
@@ -34,7 +37,7 @@ module RSpec
34
37
  # @param code_or_symbol [Symbol, Fixnum] Symbol or code to check
35
38
  # @return [Fixnum] a console code
36
39
  def console_code_for(code_or_symbol)
37
- if (config_method = CONFIG_COLORS_TO_METHODS[code_or_symbol])
40
+ if (config_method = config_colors_to_methods[code_or_symbol])
38
41
  console_code_for RSpec.configuration.__send__(config_method)
39
42
  elsif VT100_CODE_VALUES.key?(code_or_symbol)
40
43
  code_or_symbol
@@ -1,4 +1,5 @@
1
1
  RSpec::Support.require_rspec_core "formatters/base_text_formatter"
2
+ RSpec::Support.require_rspec_core "formatters/console_codes"
2
3
 
3
4
  module RSpec
4
5
  module Core
@@ -21,7 +22,7 @@ module RSpec
21
22
  end
22
23
 
23
24
  def example_group_finished(_notification)
24
- @group_level -= 1
25
+ @group_level -= 1 if @group_level > 0
25
26
  end
26
27
 
27
28
  def example_passed(passed)