rspec-core 3.5.0.beta3 → 3.5.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eb7575d0b8b74488fe65c38a1309ed0e81fb553b
4
- data.tar.gz: bd6fccb0c6652936a44cd8159e328f581af3c72e
3
+ metadata.gz: 869c418b1e6c72f2af99494959561aad32116de1
4
+ data.tar.gz: 112822b696a2ad0b8679a0a59d5fd411d528acaf
5
5
  SHA512:
6
- metadata.gz: e036ab4dc99141921ab013f94cc58434b5e16ec3e58a0675cfbaa44a7236b676f16eb81f6e7b02ed211f229298350170ca5c97903c8d84046a548280cae4f926
7
- data.tar.gz: f55ba181425dd3c264d4a16983718140e43469a28c25300a077858a528d3403d39fad355fde0ca7a8c4156f1a7be41cd846bd4b3c9efc664873bc72dbd25ddc3
6
+ metadata.gz: 1fbe6dc5949d8a192d76ee6f27ad90f1166e557c70a2d3ac9c898e4b700f60778234cd672a2de14bdb0304a11c5918527bd21935a315ba94c84916bb2b418445
7
+ data.tar.gz: 4354f81e094d54d517a46c738001c5f7f77f8d55e1e4f2a2d229a5f260aece474720f6f9a07fdc1015f57fbd89ca93e0ceef2d5d88e34d7d86afc33a94b2f1cf
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,16 +1,43 @@
1
- ### Development
2
- [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0.beta1...master)
1
+ ### 3.5 Development
2
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0.beta4...master)
3
+
4
+ ### 3.5.0.beta4 / 2016-06-05
5
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0.beta3...v3.5.0.beta4)
6
+
7
+ Enhancements:
8
+
9
+ * Filter out bundler stackframes from backtraces by default, since
10
+ Bundler 1.12 now includes its own frames in stack traces produced
11
+ by using `bundle exec`. (Myron Marston, #2240)
12
+ * HTML Formatter uses exception presenter to get failure message
13
+ for consistency with other formatters. (@mrageh, #2222)
14
+ * Load spec files in the order of the directories or files passed
15
+ at the command line, making it easy to make some specs run before
16
+ others in a one-off manner. For example, `rspec spec/unit
17
+ spec/acceptance --order defined` will run unit specs before acceptance
18
+ specs. (Myron Marston, #2253)
19
+ * Add new `config.include_context` API for configuring global or
20
+ filtered inclusion of shared contexts in example groups.
21
+ (Myron Marston, #2256)
22
+ * Add new `config.shared_context_metadata_behavior = :apply_to_host_groups`
23
+ option, which causes shared context metadata to be inherited by the
24
+ metadata hash of all host groups and examples instead of configuring
25
+ implicit auto-inclusion based on the passed metadata. (Myron Marston, #2256)
26
+
27
+ Bug Fixes:
28
+
29
+ * Fix `--bisect` so it works on large spec suites that were previously triggering
30
+ "Argument list too long errors" due to all the spec locations being passed as
31
+ CLI args. (Matt Jones, #2223).
32
+ * Fix deprecated `:example_group`-based filtering so that it properly
33
+ applies to matching example groups. (Myron Marston, #2234)
34
+ * Fix `NoMethodError` caused by Java backtraces on JRuby. (Michele Piccirillo, #2244)
35
+
36
+ ### 3.5.0.beta3 / 2016-04-02
37
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0.beta2...v3.5.0.beta3)
3
38
 
4
39
  Enhancements:
5
40
 
6
- * Remove unneeded `:execution_result` example groups metadata, saving a
7
- bit of memory. (Myron Marston, #2172)
8
- * Apply hooks registered with `config` to previously defined groups.
9
- (Myron Marston, #2189)
10
- * `RSpec::Core::Configuration#reporter` is now public API under semver.
11
- (Jon Rowe, #2193)
12
- * Add new `config.when_first_matching_example_defined` hook. (Myron
13
- Marston, #2175)
14
41
  * Add new `config.filter_run_when_matching` API, intended to replace
15
42
  the combination of `config.filter_run` and
16
43
  `config.run_all_when_everything_filtered` (Myron Marston, #2206)
@@ -23,8 +50,32 @@ Bug Fixes:
23
50
  ending with `end`-only line can be extracted properly.
24
51
  (Yuji Nakayama, #2215)
25
52
 
53
+ ### 3.5.0.beta2 / 2016-03-10
54
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.5.0.beta1...v3.5.0.beta2)
55
+
56
+ Enhancements:
57
+
58
+ * Remove unneeded `:execution_result` example group metadata, saving a
59
+ bit of memory. (Myron Marston, #2172)
60
+ * Apply hooks registered with `config` to previously defined groups.
61
+ (Myron Marston, #2189)
62
+ * `RSpec::Core::Configuration#reporter` is now public API under SemVer.
63
+ (Jon Rowe, #2193)
64
+ * Add new `config.when_first_matching_example_defined` hook. (Myron
65
+ Marston, #2175)
66
+
26
67
  ### 3.5.0.beta1 / 2016-02-06
27
- [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.3...v3.5.0.beta1)
68
+ [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.4...v3.5.0.beta1)
69
+
70
+ Enhancements:
71
+
72
+ * Add `RSpec::Core::ExampleGroup.currently_executing_a_context_hook?`,
73
+ primarily for use by rspec-rails. (Sam Phippen, #2131)
74
+
75
+ Bug Fixes:
76
+
77
+ * Ensure `MultipleExceptionError` does not contain a recursive reference
78
+ to itself. (Sam Phippen, #2133)
28
79
 
29
80
  ### 3.4.4 / 2016-03-09
30
81
  [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.3...v3.4.4)
@@ -39,7 +90,7 @@ Bug Fixes:
39
90
 
40
91
  Bug Fixes:
41
92
 
42
- * Prevent a `TypeError` from occuring when running via the rake task when
93
+ * Prevent a `TypeError` from occurring when running via the rake task when
43
94
  Ruby crashes. (Patrik Wenger, #2161)
44
95
  * Only consider example and group declaration lines from a specific file
45
96
  when applying line number filtering, instead of considering all
@@ -47,6 +98,8 @@ Bug Fixes:
47
98
  * Fix failure snippet extraction so that snippets that contain `do-end` style
48
99
  block and end with `end`-only line can be extracted properly.
49
100
  (Yuji Nakayama, #2173)
101
+ * Prevent infinite recursion when an exception is caused by itself.
102
+ (Jon Rowe, #2128)
50
103
 
51
104
  ### 3.4.2 / 2016-01-26
52
105
  [Full Changelog](http://github.com/rspec/rspec-core/compare/v3.4.1...v3.4.2)
@@ -8,7 +8,7 @@ module RSpec
8
8
  def initialize
9
9
  @full_backtrace = false
10
10
 
11
- patterns = %w[ /lib\d*/ruby/ bin/ exe/rspec ]
11
+ patterns = %w[ /lib\d*/ruby/ bin/ exe/rspec /lib/bundler/ /exe/bundle: ]
12
12
  patterns << "org/jruby/" if RUBY_PLATFORM == 'java'
13
13
  patterns.map! { |s| Regexp.new(s.gsub("/", File::SEPARATOR)) }
14
14
 
@@ -27,6 +27,7 @@ module RSpec
27
27
 
28
28
  parts << "--format" << "bisect"
29
29
  parts << "--drb-port" << @server.drb_port
30
+
30
31
  parts.concat reusable_cli_options
31
32
  parts.concat locations.map { |l| open3_safe_escape(l) }
32
33
 
@@ -60,9 +61,9 @@ module RSpec
60
61
  alias open3_safe_escape escape
61
62
  end
62
63
 
63
- def run_locations(locations, *capture_args)
64
+ def run_locations(*capture_args)
64
65
  @server.capture_run_results(*capture_args) do
65
- run_command command_for(locations)
66
+ run_command command_for([])
66
67
  end
67
68
  end
68
69
 
@@ -20,8 +20,9 @@ module RSpec
20
20
  server.stop
21
21
  end
22
22
 
23
- def capture_run_results(expected_failures=[])
23
+ def capture_run_results(files_or_directories_to_run=[], expected_failures=[])
24
24
  self.expected_failures = expected_failures
25
+ self.files_or_directories_to_run = files_or_directories_to_run
25
26
  self.latest_run_results = nil
26
27
  run_output = yield
27
28
  latest_run_results || raise_bisect_failed(run_output)
@@ -49,6 +50,9 @@ module RSpec
49
50
  # Set via DRb by the BisectFormatter with the results of the run.
50
51
  attr_accessor :latest_run_results
51
52
 
53
+ # Fetched via DRb to tell clients which files to run
54
+ attr_accessor :files_or_directories_to_run
55
+
52
56
  private
53
57
 
54
58
  def raise_bisect_failed(run_output)
@@ -327,6 +327,59 @@ module RSpec
327
327
  )
328
328
  end
329
329
 
330
+ # @macro define_reader
331
+ # Configures how RSpec treats metadata passed as part of a shared example
332
+ # group definition. For example, given this shared example group definition:
333
+ #
334
+ # RSpec.shared_context "uses DB", :db => true do
335
+ # around(:example) do |ex|
336
+ # MyORM.transaction(:rollback => true, &ex)
337
+ # end
338
+ # end
339
+ #
340
+ # ...there are two ways RSpec can treat the `:db => true` metadata, each
341
+ # of which has a corresponding config option:
342
+ #
343
+ # 1. `:trigger_inclusion`: this shared context will be implicitly included
344
+ # in any groups (or examples) that have `:db => true` metadata.
345
+ # 2. `:apply_to_host_groups`: the metadata will be inherited by the metadata
346
+ # hash of all host groups and examples.
347
+ #
348
+ # `:trigger_inclusion` is the legacy behavior from before RSpec 3.5 but should
349
+ # be considered deprecated. Instead, you can explicitly include a group with
350
+ # `include_context`:
351
+ #
352
+ # RSpec.describe "My model" do
353
+ # include_context "uses DB"
354
+ # end
355
+ #
356
+ # ...or you can configure RSpec to include the context based on matching metadata
357
+ # using an API that mirrors configured module inclusion:
358
+ #
359
+ # RSpec.configure do |rspec|
360
+ # rspec.include_context "uses DB", :db => true
361
+ # end
362
+ #
363
+ # `:apply_to_host_groups` is a new feature of RSpec 3.5 and will be the only
364
+ # supported behavior in RSpec 4.
365
+ #
366
+ # @overload shared_context_metadata_behavior
367
+ # @return [:trigger_inclusion, :apply_to_host_groups] the configured behavior
368
+ # @overload shared_context_metadata_behavior=(value)
369
+ # @param value [:trigger_inclusion, :apply_to_host_groups] sets the configured behavior
370
+ define_reader :shared_context_metadata_behavior
371
+ # @see shared_context_metadata_behavior
372
+ def shared_context_metadata_behavior=(value)
373
+ case value
374
+ when :trigger_inclusion, :apply_to_host_groups
375
+ @shared_context_metadata_behavior = value
376
+ else
377
+ raise ArgumentError, "Cannot set `RSpec.configuration." \
378
+ "shared_context_metadata_behavior` to `#{value.inspect}`. Only " \
379
+ "`:trigger_inclusion` and `:apply_to_host_groups` are valid values."
380
+ end
381
+ end
382
+
330
383
  # Record the start time of the spec suite to measure load time.
331
384
  add_setting :start_time
332
385
 
@@ -352,6 +405,7 @@ module RSpec
352
405
  attr_reader :backtrace_formatter, :ordering_manager, :loaded_spec_files
353
406
 
354
407
  # rubocop:disable Metrics/AbcSize
408
+ # rubocop:disable Metrics/MethodLength
355
409
  def initialize
356
410
  # rubocop:disable Style/GlobalVars
357
411
  @start_time = $_rspec_core_load_started_at || ::RSpec::Core::Time.now
@@ -398,9 +452,11 @@ module RSpec
398
452
  @threadsafe = true
399
453
  @max_displayed_failure_line_count = 10
400
454
  @world = World::Null
455
+ @shared_context_metadata_behavior = :trigger_inclusion
401
456
 
402
457
  define_built_in_hooks
403
458
  end
459
+ # rubocop:enable Metrics/MethodLength
404
460
  # rubocop:enable Metrics/AbcSize
405
461
 
406
462
  # @private
@@ -1153,7 +1209,7 @@ module RSpec
1153
1209
  # end
1154
1210
  #
1155
1211
  # RSpec.configure do |config|
1156
- # config.include(UserHelpers) # included in all modules
1212
+ # config.include(UserHelpers) # included in all groups
1157
1213
  # config.include(AuthenticationHelpers, :type => :request)
1158
1214
  # end
1159
1215
  #
@@ -1172,12 +1228,55 @@ module RSpec
1172
1228
  # example has a singleton example group containing just the one
1173
1229
  # example.
1174
1230
  #
1231
+ # @see #include_context
1175
1232
  # @see #extend
1176
1233
  # @see #prepend
1177
1234
  def include(mod, *filters)
1178
- meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
1179
- @include_modules.append(mod, meta)
1180
- on_existing_matching_groups(meta) { |group| safe_include(mod, group) }
1235
+ define_mixed_in_module(mod, filters, @include_modules, :include) do |group|
1236
+ safe_include(mod, group)
1237
+ end
1238
+ end
1239
+
1240
+ # Tells RSpec to include the named shared example group in example groups.
1241
+ # Use `filters` to constrain the groups or examples in which to include
1242
+ # the example group.
1243
+ #
1244
+ # @example
1245
+ #
1246
+ # RSpec.shared_context "example users" do
1247
+ # let(:admin_user) { create_user(:admin) }
1248
+ # let(:guest_user) { create_user(:guest) }
1249
+ # end
1250
+ #
1251
+ # RSpec.configure do |config|
1252
+ # config.include_context "example users", :type => :request
1253
+ # end
1254
+ #
1255
+ # RSpec.describe "The admin page", :type => :request do
1256
+ # it "can be viewed by admins" do
1257
+ # login_with admin_user
1258
+ # get "/admin"
1259
+ # expect(response).to be_ok
1260
+ # end
1261
+ #
1262
+ # it "cannot be viewed by guests" do
1263
+ # login_with guest_user
1264
+ # get "/admin"
1265
+ # expect(response).to be_forbidden
1266
+ # end
1267
+ # end
1268
+ #
1269
+ # @note Filtered context inclusions can also be applied to
1270
+ # individual examples that have matching metadata. Just like
1271
+ # Ruby's object model is that every object has a singleton class
1272
+ # which has only a single instance, RSpec's model is that every
1273
+ # example has a singleton example group containing just the one
1274
+ # example.
1275
+ #
1276
+ # @see #include
1277
+ def include_context(shared_group_name, *filters)
1278
+ shared_module = world.shared_example_group_registry.find([:main], shared_group_name)
1279
+ include shared_module, *filters
1181
1280
  end
1182
1281
 
1183
1282
  # Tells RSpec to extend example groups with `mod`. Methods defined in
@@ -1211,9 +1310,9 @@ module RSpec
1211
1310
  # @see #include
1212
1311
  # @see #prepend
1213
1312
  def extend(mod, *filters)
1214
- meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
1215
- @extend_modules.append(mod, meta)
1216
- on_existing_matching_groups(meta) { |group| safe_extend(mod, group) }
1313
+ define_mixed_in_module(mod, filters, @extend_modules, :extend) do |group|
1314
+ safe_extend(mod, group)
1315
+ end
1217
1316
  end
1218
1317
 
1219
1318
  if RSpec::Support::RubyFeatures.module_prepends_supported?
@@ -1250,9 +1349,9 @@ module RSpec
1250
1349
  # @see #include
1251
1350
  # @see #extend
1252
1351
  def prepend(mod, *filters)
1253
- meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
1254
- @prepend_modules.append(mod, meta)
1255
- on_existing_matching_groups(meta) { |group| safe_prepend(mod, group) }
1352
+ define_mixed_in_module(mod, filters, @prepend_modules, :prepend) do |group|
1353
+ safe_prepend(mod, group)
1354
+ end
1256
1355
  end
1257
1356
  end
1258
1357
 
@@ -1261,6 +1360,8 @@ module RSpec
1261
1360
  # Used internally to extend a group with modules using `include`, `prepend` and/or
1262
1361
  # `extend`.
1263
1362
  def configure_group(group)
1363
+ group.hooks.register_globals(group, hooks)
1364
+
1264
1365
  configure_group_with group, @include_modules, :safe_include
1265
1366
  configure_group_with group, @extend_modules, :safe_extend
1266
1367
  configure_group_with group, @prepend_modules, :safe_prepend
@@ -1270,7 +1371,8 @@ module RSpec
1270
1371
  #
1271
1372
  # Used internally to extend the singleton class of a single example's
1272
1373
  # example group instance with modules using `include` and/or `extend`.
1273
- def configure_example(example)
1374
+ def configure_example(example, example_hooks)
1375
+ example_hooks.register_global_singleton_context_hooks(example, hooks)
1274
1376
  singleton_group = example.example_group_instance.singleton_class
1275
1377
 
1276
1378
  # We replace the metadata so that SharedExampleGroupModule#included
@@ -1389,8 +1491,12 @@ module RSpec
1389
1491
 
1390
1492
  # @macro delegate_to_ordering_manager
1391
1493
  #
1392
- # Sets the default global order and, if order is `'rand:<seed>'`, also
1393
- # sets the seed.
1494
+ # Sets the default global ordering strategy. By default this can be one
1495
+ # of `:defined`, `:random`, but is customizable through the
1496
+ # `register_ordering` API. If order is set to `'rand:<seed>'`,
1497
+ # the seed will also be set.
1498
+ #
1499
+ # @see #register_ordering
1394
1500
  delegate_to_ordering_manager :order=
1395
1501
 
1396
1502
  # @macro delegate_to_ordering_manager
@@ -1412,13 +1518,32 @@ module RSpec
1412
1518
  # end
1413
1519
  # end
1414
1520
  #
1415
- # describe MyClass, :order => :reverse do
1521
+ # RSpec.describe 'MyClass', :order => :reverse do
1416
1522
  # # ...
1417
1523
  # end
1418
1524
  #
1419
1525
  # @note Pass the symbol `:global` to set the ordering strategy that
1420
1526
  # will be used to order the top-level example groups and any example
1421
1527
  # groups that do not have declared `:order` metadata.
1528
+ #
1529
+ # @example
1530
+ # RSpec.configure do |rspec|
1531
+ # rspec.register_ordering :global do |examples|
1532
+ # acceptance, other = examples.partition do |example|
1533
+ # example.metadata[:type] == :acceptance
1534
+ # end
1535
+ # other + acceptance
1536
+ # end
1537
+ # end
1538
+ #
1539
+ # RSpec.describe 'MyClass', :type => :acceptance do
1540
+ # # will run last
1541
+ # end
1542
+ #
1543
+ # RSpec.describe 'MyClass' do
1544
+ # # will run first
1545
+ # end
1546
+ #
1422
1547
  delegate_to_ordering_manager :register_ordering
1423
1548
 
1424
1549
  # @private
@@ -1759,7 +1884,7 @@ module RSpec
1759
1884
  files = FlatMap.flat_map(paths_to_check(paths)) do |path|
1760
1885
  path = path.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
1761
1886
  File.directory?(path) ? gather_directories(path) : extract_location(path)
1762
- end.sort.uniq
1887
+ end.uniq
1763
1888
 
1764
1889
  return files unless only_failures?
1765
1890
  relative_files = files.map { |f| Metadata.relative_path(File.expand_path f) }
@@ -1779,11 +1904,12 @@ module RSpec
1779
1904
  def gather_directories(path)
1780
1905
  include_files = get_matching_files(path, pattern)
1781
1906
  exclude_files = get_matching_files(path, exclude_pattern)
1782
- (include_files - exclude_files).sort.uniq
1907
+ (include_files - exclude_files).uniq
1783
1908
  end
1784
1909
 
1785
1910
  def get_matching_files(path, pattern)
1786
- Dir[file_glob_from(path, pattern)].map { |file| File.expand_path(file) }
1911
+ raw_files = Dir[file_glob_from(path, pattern)]
1912
+ raw_files.map { |file| File.expand_path(file) }.sort
1787
1913
  end
1788
1914
 
1789
1915
  def file_glob_from(path, pattern)
@@ -1823,7 +1949,7 @@ module RSpec
1823
1949
  end
1824
1950
 
1825
1951
  return [] if path == default_path
1826
- path
1952
+ File.expand_path(path)
1827
1953
  end
1828
1954
 
1829
1955
  def command
@@ -1932,6 +2058,16 @@ module RSpec
1932
2058
  end
1933
2059
  # :nocov:
1934
2060
  end
2061
+
2062
+ def define_mixed_in_module(mod, filters, mod_list, config_method, &block)
2063
+ unless Module === mod
2064
+ raise TypeError, "`RSpec.configuration.#{config_method}` expects a module but got: #{mod.inspect}"
2065
+ end
2066
+
2067
+ meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
2068
+ mod_list.append(mod, meta)
2069
+ on_existing_matching_groups(meta, &block)
2070
+ end
1935
2071
  end
1936
2072
  # rubocop:enable Metrics/ClassLength
1937
2073
  end
@@ -142,6 +142,13 @@ module RSpec
142
142
  new_metadata, new_metadata[:block])
143
143
  end
144
144
 
145
+ # @private
146
+ def update_inherited_metadata(updates)
147
+ metadata.update(updates) do |_key, existing_example_value, _new_inherited_value|
148
+ existing_example_value
149
+ end
150
+ end
151
+
145
152
  # @attr_reader
146
153
  #
147
154
  # Returns the first exception raised in the context of running this
@@ -229,8 +236,7 @@ module RSpec
229
236
  def run(example_group_instance, reporter)
230
237
  @example_group_instance = example_group_instance
231
238
  @reporter = reporter
232
- hooks.register_global_singleton_context_hooks(self, RSpec.configuration.hooks)
233
- RSpec.configuration.configure_example(self)
239
+ RSpec.configuration.configure_example(self, hooks)
234
240
  RSpec.current_example = self
235
241
 
236
242
  start(reporter)
@@ -33,6 +33,8 @@ module RSpec
33
33
  include Pending
34
34
  extend SharedExampleGroup
35
35
 
36
+ # Define a singleton method for the singleton class (remove the method if
37
+ # it's already been defined).
36
38
  # @private
37
39
  def self.idempotently_define_singleton_method(name, &definition)
38
40
  (class << self; self; end).module_exec do
@@ -362,16 +364,16 @@ module RSpec
362
364
 
363
365
  # @private
364
366
  def self.find_and_eval_shared(label, name, inclusion_location, *args, &customization_block)
365
- shared_block = RSpec.world.shared_example_group_registry.find(parent_groups, name)
367
+ shared_module = RSpec.world.shared_example_group_registry.find(parent_groups, name)
366
368
 
367
- unless shared_block
369
+ unless shared_module
368
370
  raise ArgumentError, "Could not find shared #{label} #{name.inspect}"
369
371
  end
370
372
 
371
- SharedExampleGroupInclusionStackFrame.with_frame(name, Metadata.relative_path(inclusion_location)) do
372
- module_exec(*args, &shared_block)
373
- module_exec(&customization_block) if customization_block
374
- end
373
+ shared_module.include_in(
374
+ self, Metadata.relative_path(inclusion_location),
375
+ args, customization_block
376
+ )
375
377
  end
376
378
 
377
379
  # @!endgroup
@@ -424,7 +426,6 @@ module RSpec
424
426
 
425
427
  @currently_executing_a_context_hook = false
426
428
 
427
- hooks.register_globals(self, RSpec.configuration.hooks)
428
429
  RSpec.configuration.configure_group(self)
429
430
  end
430
431
 
@@ -688,6 +689,17 @@ module RSpec
688
689
  # :nocov:
689
690
  end
690
691
 
692
+ # @private
693
+ def self.update_inherited_metadata(updates)
694
+ metadata.update(updates) do |_key, existing_group_value, _new_inherited_value|
695
+ existing_group_value
696
+ end
697
+
698
+ RSpec.configuration.configure_group(self)
699
+ examples.each { |ex| ex.update_inherited_metadata(updates) }
700
+ children.each { |group| group.update_inherited_metadata(updates) }
701
+ end
702
+
691
703
  # Raised when an RSpec API is called in the wrong scope, such as `before`
692
704
  # being called from within an example rather than from within an example
693
705
  # group block.
@@ -16,12 +16,13 @@ module RSpec
16
16
  :example_failed, :example_passed, :example_pending
17
17
 
18
18
  def initialize(_output)
19
- port = RSpec.configuration.drb_port
20
- drb_uri = "druby://localhost:#{port}"
21
- @all_example_ids = []
19
+ port = RSpec.configuration.drb_port
20
+ drb_uri = "druby://localhost:#{port}"
21
+ @all_example_ids = []
22
22
  @failed_example_ids = []
23
- @bisect_server = DRbObject.new_with_uri(drb_uri)
23
+ @bisect_server = DRbObject.new_with_uri(drb_uri)
24
24
  @remaining_failures = []
25
+ RSpec.configuration.files_or_directories_to_run = @bisect_server.files_or_directories_to_run
25
26
  end
26
27
 
27
28
  def start(_notification)
@@ -34,8 +34,7 @@ module RSpec
34
34
  end
35
35
 
36
36
  def example_failed(failure)
37
- output.puts failure_output(failure.example,
38
- failure.example.execution_result.exception)
37
+ output.puts failure_output(failure.example)
39
38
  end
40
39
 
41
40
  private
@@ -50,7 +49,7 @@ module RSpec
50
49
  :pending)
51
50
  end
52
51
 
53
- def failure_output(example, _exception)
52
+ def failure_output(example)
54
53
  ConsoleCodes.wrap("#{current_indentation}#{example.description.strip} " \
55
54
  "(FAILED - #{next_failure_index})",
56
55
  :failure)
@@ -204,7 +204,13 @@ module RSpec
204
204
  return ["Unable to find matching line from backtrace"]
205
205
  end
206
206
 
207
- file_path, line_number = matching_line.match(/(.+?):(\d+)(|:\d+)/)[1..2]
207
+ file_and_line_number = matching_line.match(/(.+?):(\d+)(|:\d+)/)
208
+
209
+ unless file_and_line_number
210
+ return ["Unable to infer file and line number from backtrace"]
211
+ end
212
+
213
+ file_path, line_number = file_and_line_number[1..2]
208
214
  max_line_count = RSpec.configuration.max_displayed_failure_line_count
209
215
  lines = SnippetExtractor.extract_expression_lines_at(file_path, line_number.to_i, max_line_count)
210
216
  RSpec.world.source_cache.syntax_highlighter.highlight(lines)
@@ -71,7 +71,7 @@ module RSpec
71
71
  exception = failure.exception
72
72
  exception_details = if exception
73
73
  {
74
- :message => exception.message,
74
+ :message => failure.message_lines.join("\n"),
75
75
  :backtrace => failure.formatted_backtrace.join("\n")
76
76
  }
77
77
  end
@@ -34,6 +34,14 @@ module RSpec
34
34
  end
35
35
  end
36
36
 
37
+ # @private
38
+ def silence_metadata_example_group_deprecations
39
+ RSpec::Support.thread_local_data[:silence_metadata_example_group_deprecations] = true
40
+ yield
41
+ ensure
42
+ RSpec::Support.thread_local_data.delete(:silence_metadata_example_group_deprecations)
43
+ end
44
+
37
45
  private
38
46
 
39
47
  def filter_applies_to_any_value?(key, value, metadata)
@@ -72,13 +80,6 @@ module RSpec
72
80
  return false unless Hash === subhash || HashImitatable === subhash
73
81
  value.all? { |k, v| filter_applies?(k, v, subhash) }
74
82
  end
75
-
76
- def silence_metadata_example_group_deprecations
77
- RSpec::Support.thread_local_data[:silence_metadata_example_group_deprecations] = true
78
- yield
79
- ensure
80
- RSpec::Support.thread_local_data.delete(:silence_metadata_example_group_deprecations)
81
- end
82
83
  end
83
84
  end
84
85
 
@@ -202,9 +203,20 @@ module RSpec
202
203
  end
203
204
 
204
205
  def applicable_metadata_from(metadata)
205
- @applicable_keys.inject({}) do |hash, key|
206
- hash[key] = metadata[key] if metadata.key?(key)
207
- hash
206
+ MetadataFilter.silence_metadata_example_group_deprecations do
207
+ @applicable_keys.inject({}) do |hash, key|
208
+ # :example_group is treated special here because...
209
+ # - In RSpec 2, example groups had an `:example_group` key
210
+ # - In RSpec 3, that key is deprecated (it was confusing!).
211
+ # - The key is not technically present in an example group metadata hash
212
+ # (and thus would fail the `metadata.key?(key)` check) but a value
213
+ # is provided when accessed via the hash's `default_proc`
214
+ # - Thus, for backwards compatibility, we have to explicitly check
215
+ # for `:example_group` here if it is one of the keys being used to
216
+ # filter.
217
+ hash[key] = metadata[key] if metadata.key?(key) || key == :example_group
218
+ hash
219
+ end
208
220
  end
209
221
  end
210
222
 
@@ -40,6 +40,13 @@ RSpec.configure do |config|
40
40
  mocks.verify_partial_doubles = true
41
41
  end
42
42
 
43
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
44
+ # have no way to turn it off -- the option exists only for backwards
45
+ # compatibility in RSpec 3). It causes shared context metadata to be
46
+ # inherited by the metadata hash of host groups and examples, rather than
47
+ # triggering implicit auto-inclusion in groups with matching metadata.
48
+ config.shared_context_metadata_behavior = :apply_to_host_groups
49
+
43
50
  # The settings below are suggested to provide a good initial experience
44
51
  # with RSpec, but feel free to customize to your heart's content.
45
52
  =begin
@@ -5,9 +5,13 @@ module RSpec
5
5
  # eval'd when the `SharedExampleGroupModule` instance is included in an example
6
6
  # group.
7
7
  class SharedExampleGroupModule < Module
8
- def initialize(description, definition)
8
+ # @private
9
+ attr_reader :definition
10
+
11
+ def initialize(description, definition, metadata)
9
12
  @description = description
10
13
  @definition = definition
14
+ @metadata = metadata
11
15
  end
12
16
 
13
17
  # Provides a human-readable representation of this module.
@@ -21,8 +25,16 @@ module RSpec
21
25
  # including example group.
22
26
  def included(klass)
23
27
  inclusion_line = klass.metadata[:location]
28
+ include_in klass, inclusion_line, [], nil
29
+ end
30
+
31
+ # @private
32
+ def include_in(klass, inclusion_line, args, customization_block)
33
+ klass.update_inherited_metadata(@metadata) unless @metadata.empty?
34
+
24
35
  SharedExampleGroupInclusionStackFrame.with_frame(@description, inclusion_line) do
25
- klass.class_exec(&@definition)
36
+ klass.class_exec(*args, &@definition)
37
+ klass.class_exec(&customization_block) if customization_block
26
38
  end
27
39
  end
28
40
  end
@@ -141,17 +153,21 @@ module RSpec
141
153
  # @private
142
154
  class Registry
143
155
  def add(context, name, *metadata_args, &block)
144
- ensure_block_has_source_location(block) { CallerFilter.first_non_rspec_line }
156
+ if RSpec.configuration.shared_context_metadata_behavior == :trigger_inclusion
157
+ return legacy_add(context, name, *metadata_args, &block)
158
+ end
145
159
 
146
- if valid_name?(name)
147
- warn_if_key_taken context, name, block
148
- shared_example_groups[context][name] = block
149
- else
150
- metadata_args.unshift name
160
+ unless valid_name?(name)
161
+ raise ArgumentError, "Shared example group names can only be a string, " \
162
+ "symbol or module but got: #{name.inspect}"
151
163
  end
152
164
 
153
- return if metadata_args.empty?
154
- RSpec.configuration.include SharedExampleGroupModule.new(name, block), *metadata_args
165
+ ensure_block_has_source_location(block) { CallerFilter.first_non_rspec_line }
166
+ warn_if_key_taken context, name, block
167
+
168
+ metadata = Metadata.build_hash_from(metadata_args)
169
+ shared_module = SharedExampleGroupModule.new(name, block, metadata)
170
+ shared_example_groups[context][name] = shared_module
155
171
  end
156
172
 
157
173
  def find(lookup_contexts, name)
@@ -165,6 +181,25 @@ module RSpec
165
181
 
166
182
  private
167
183
 
184
+ # TODO: remove this in RSpec 4. This exists only to support
185
+ # `config.shared_context_metadata_behavior == :trigger_inclusion`,
186
+ # the legacy behavior of shared context metadata, which we do
187
+ # not want to support in RSpec 4.
188
+ def legacy_add(context, name, *metadata_args, &block)
189
+ ensure_block_has_source_location(block) { CallerFilter.first_non_rspec_line }
190
+ shared_module = SharedExampleGroupModule.new(name, block, {})
191
+
192
+ if valid_name?(name)
193
+ warn_if_key_taken context, name, block
194
+ shared_example_groups[context][name] = shared_module
195
+ else
196
+ metadata_args.unshift name
197
+ end
198
+
199
+ return if metadata_args.empty?
200
+ RSpec.configuration.include shared_module, *metadata_args
201
+ end
202
+
168
203
  def shared_example_groups
169
204
  @shared_example_groups ||= Hash.new { |hash, context| hash[context] = {} }
170
205
  end
@@ -177,13 +212,13 @@ module RSpec
177
212
  end
178
213
 
179
214
  def warn_if_key_taken(context, key, new_block)
180
- existing_block = shared_example_groups[context][key]
215
+ existing_module = shared_example_groups[context][key]
181
216
 
182
- return unless existing_block
217
+ return unless existing_module
183
218
 
184
219
  RSpec.warn_with <<-WARNING.gsub(/^ +\|/, ''), :call_site => nil
185
220
  |WARNING: Shared example group '#{key}' has been previously defined at:
186
- | #{formatted_location existing_block}
221
+ | #{formatted_location existing_module.definition}
187
222
  |...and you are now defining it at:
188
223
  | #{formatted_location new_block}
189
224
  |The new definition will overwrite the original one.
@@ -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.5.0.beta3'
6
+ STRING = '3.5.0.beta4'
7
7
  end
8
8
  end
9
9
  end
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.5.0.beta3
4
+ version: 3.5.0.beta4
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: 2016-04-02 00:00:00.000000000 Z
49
+ date: 2016-06-05 00:00:00.000000000 Z
50
50
  dependencies:
51
51
  - !ruby/object:Gem::Dependency
52
52
  name: rspec-support
@@ -54,14 +54,14 @@ dependencies:
54
54
  requirements:
55
55
  - - '='
56
56
  - !ruby/object:Gem::Version
57
- version: 3.5.0.beta3
57
+ version: 3.5.0.beta4
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.5.0.beta3
64
+ version: 3.5.0.beta4
65
65
  - !ruby/object:Gem::Dependency
66
66
  name: cucumber
67
67
  requirement: !ruby/object:Gem::Requirement
@@ -279,9 +279,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
279
279
  version: 1.3.1
280
280
  requirements: []
281
281
  rubyforge_project:
282
- rubygems_version: 2.4.5.1
282
+ rubygems_version: 2.5.1
283
283
  signing_key:
284
284
  specification_version: 4
285
- summary: rspec-core-3.5.0.beta3
285
+ summary: rspec-core-3.5.0.beta4
286
286
  test_files: []
287
287
  has_rdoc:
metadata.gz.sig CHANGED
Binary file