rspec/rspec-core — pull request #1376 by myronmarston (2014-03-10 03:11:54+00:00)
Title: [WIP] Redesign metadata

I've been making good progress on the metadata redesign we discussed in #1231, first in [a spike](https://github.com/rspec/rspec-core/compare/refactor-metadata-spike) and now I'm doing a more careful, surgical refactoring in this PR. I've run into a couple related issues that I'm not sure what to do about so I figured I'd open this PR to get the discussion rolling.

* Currently we [raise an error](https://github.com/rspec/rspec-core/blob/v3.0.0.beta2/lib/rspec/core/metadata.rb#L270-L299) if the user supplies a value for any of the reserved keys that RSpec is responsible for computing. Should we continue to do this? Now that we are moving these keys off of the root hash and onto a nested object exposed from the `:rspec` key, there isn't a direct conflict. The hash can be `{ :file_path => "some/path.rb", :rspec => object_containing_file_path }`. However, I worry that it could be confusing to allow users to specify values for these keys (especially when combined with some of the filtering complexities outlined below...).
* Filtering based on the computed keys is made more complicated/confusing by the direction we are going. Currently, you can do something like `config.before(:each, :file_path => %r{spec/unit}) { ... }` to define a global before hook that runs before all specs in the `spec/unit` directory. This made perfect sense before since the individual examples had a `:file_path` entry in their metadata. Now it'll be exposed off the `:rspec` object. Should we therefore require this to be `config.before(:each, :rspec => { :file_path => %r{spec/unit} }) { ... }` to match the nested structure? Given that `:rspec` doesn't refer to a hash this might be confusing. Here's an alternate solution I'm considering (which has the nice side benefit of being more backwards compatible): run the filtering against a hash that contains the user metadata merged with the properties exposed off of `:rspec` so that when the filtering runs, `:file_path` is treated as a top-level metadata attribute.
* Deprecations: should we deprecate the old APIs in 2.99 or in 3.0? Having 3.0 have a clean slate is appealing, but this metadata stuff is used by a number of extensions, and our general policy has been to retain deprecated support in 3.0 for things extensions are using (e.g. the formatter protocol and matcher protocol). For now I'm going to proceed with adding the deprecations to 3.0 as I go along because it'll be easiest to implement, and even if we wind up putting it in 2.99 only, it'll provide us something to work off of.

/cc @avdi @xaviershay @samphippen @soulcutter @JonRowe @alindeman