Comments (9)
Just for the record, since this issue is what I found using "rspec metadata before" search-engine query and since I couldn't find it documented anywhere.
This behaviour can be achieved in a up-to-date rspec version the following way:
before do |example|
example.metadata[:foo] # => true
end
it "should behave", :foo => true do
end
from rspec-core.
Green light! I'd like to have it work through the running_example variable though, not just options, to keep the local namespace uncluttered. Either of these would work for me:
RSpec.configure do |config| config.before :each do Capybara.current_driver = :culerity if running_example[:js] end end RSpec.configure do |config| config.before :each do Capybara.current_driver = :culerity if running_example.options[:js] end end
Separate, but related, what do you think about renaming running_example to example?
from rspec-core.
Yes, makes sense to avoid cluttering the local namespace. Looking at the options:
1: if example[:foo]
2: if example.options[:foo]
3: if running_example[:foo]
4: if running_example.options[:foo]
Option "2" reads nicest to me because it is close to the English "if the example option foo is set". I'll go with that for now.
Will start playing and see if I can knock a patch together before the day is out.
from rspec-core.
Great. Thanks!
from rspec-core.
Ok, have something now. Seeing as you can't attach patches to Github tickets, have pushed a few commits to forks here:
http://github.com/wincent/rspec-core/commits/core-ticket-42
And here:
http://github.com/wincent/rspec-rails/commits/core-ticket-42
Specifically we're talking about these commits:
http://github.com/wincent/rspec-core/commit/99f0428d53b98cee8a60250d1347224f3dbc5697
http://github.com/wincent/rspec-core/commit/2ed401684b68e404d75be051b932d592b260dc00
http://github.com/wincent/rspec-rails/commit/66c5df14c5f7e4d0f8e42f98009837077c680437
http://github.com/wincent/rspec-rails/commit/0c5801a412bfd3abaac5ed7222e4e1d34e4e78e7
The actual changes to the codebase were trivial (20 minutes of coding), but I've had quite a bit of trouble and spent several hours trying to keep the specs and features passing.
One of the problems is that it is quite fiddly if you make a change which requires simultaneous modifications across different repos. For example, the renaming of "running_example" to "example" in rspec-core requires changes in rspec-rails because the latter uses "running_example".
So you make the change in both repos at once, but you get failures in rspec-rails because it is using the system version of rspec-core rather than the local one.
The spec failures can be fixed by tweaking the Gemfile in the generated example Rails app so that it uses the local version of rspec-core instead of some other version that it might pull from elsewhere on the system. (That's what commit 0c5801a412bfd does.)
In this way you can make the change in both rspec-core and rspec-rails at the same time, and all specs keep passing.
The feature failures are another matter entirely. Cucumber insists on using some other version of rspec-core rather than the local one. I've spent hours trying to find out why, but I'm afraid I have to give up.
That in turn means I am not so confident about commit 66c5df14c5f7e. In particular I am not sure about the change to lib/rspec/rails/adapters.rb. I changed the instance variable name from @running_example to @example in the "method_name" method, but I don't even know what that method does, and the specs/features pass irrespective of what the instance variable is called.
So, take a look at the commits and perhaps you can see something that I can't that explains how to get Cucumber to use the right version of rspec-core.
In any case, with these commits we can do stuff like:
RSpec.configure do |config|
config.before :each do
Capybara.current_driver = :celerity if example.options[:js]
end
end
There is one possible further modification that I was playing around with, but it is a bit more invasive so I haven't committed anything yet.
The thing is that in a "before :all" block there is obviously no "running example" at that point, so if the user tries to do something like this they'll bomb out because "example" is nil at this point:
config.before :all do
do_something if example.options[:foo]
end
At that point we're executing within the scope of a RSpec::Core::ExampleGroup class, so if we ask for "example" we hit the "example" accessor and get nil back.
Note:
config.before :all do
# people could do it this way, and it works...
do_something if self.class.metadata[:foo]
# but I expect lots will try "example.options" and fail anyway...
end
The idea I was playing with was in that context, returning a different non-nil object (probably a Metadata subclass) that responds to "options", and would return the user-supplied metadata passed in at the describe-block level. ie:
describe Thing, :js => true do
before :all do
example.options[:js] # => true
end
before :each do
example.options[:foo] # => defined below
end
it "should behave", :foo => true do
end
end
So you could define your metadata at any level, and access it at any level.
Not sure if this is opening up a can of worms, though, cause then we'd have to think about how this metadata should "trickle" down when nesting is involved, e.g:
describe Outer, :foo => 1 do
describe Inner, :bar => 2 do
before :all do
# here should have access to :foo and :bar
end
before :each do
# here should have access to :foo and :bar too
# plus anything set at the "its" level
end
it "should behave", :foo => :override, :baz => 3 do
# here :foo => override, :bar => 2, :baz => 3
end
end
end
from rspec-core.
There's a lot to review in that comment and I'm pressed for time this minute, but re: the name change - we'll want to deprecate running_example as there are other consumers of that method in the wild. So in rspec-core, something like:
def example # code moved from running_example end def running_example RSpec.deprecate("running_example", "example") example end
Then you don't have to worry about the other libs just yet and they can move independently.
from rspec-core.
Ah, yes, good idea. I'd seen the "RSpec.deprecate" in a couple places in the codebase but didn't think to use it.
from rspec-core.
Added the deprecation warning as suggested:
http://github.com/wincent/rspec-core/commit/272c3762fa0af775f0c7d23afffa3196bb7ad81c
from rspec-core.
Merged - thanks!!!!!
from rspec-core.
Related Issues (20)
- Shared contexts/examples files_organization / code_loading HOT 6
- Calling `before` or `after` in an invalid context that will never run should raise an error HOT 3
- RSpec skipping at_exit hooks on force quit HOT 1
- No way to filter tags with and logic HOT 3
- The SPEC environment variable does not support using bracketed example IDs HOT 9
- Guard against name collisions with internals HOT 2
- add :context scope to let method HOT 2
- Add `--only-pending` CLI option which filters to only the pending examples HOT 3
- Requiring rspec before IRB console causes warning HOT 1
- doc_string which is the first argument of example, must be string object HOT 3
- Unclear working of shared_examples inside a context in a shared_context HOT 4
- Define weak/default memoized helpers with `let?` method. HOT 6
- Numbered list of failed specs HOT 2
- Docs are offline HOT 1
- config.include works unpredictably when supplying more than one metadata to filter HOT 4
- Adding ProfileFormatter report to output stream? HOT 2
- SimpleCov execution in rspec-core builds is sneakily broken HOT 6
- Class variable state leaked/persisted between examples HOT 3
- Failed to clone rspec repo on the branch `4-0-dev` HOT 1
- Feature Request: Allow CLI tags option to specify a hash HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rspec-core.