Skip to content

Commit

Permalink
Add new treat_symbols_as_metadata_keys_with_true_values option.
Browse files Browse the repository at this point in the history
  • Loading branch information
myronmarston committed Feb 22, 2011
1 parent ebc4bff commit 2dd6fab
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 1 deletion.
39 changes: 39 additions & 0 deletions features/metadata/user_defined.feature
Expand Up @@ -8,6 +8,17 @@ Feature: User-defined metadata
Metadata defined on an example group is available (and can be overriden)
by any sub-group or from any example in that group or a sub-group.

In addition, there is a configuration option (which will be the default
behavior in RSpec 3) that allows you to specify metadata using just
symbols:

RSpec.configure do |c|
c.treat_symbols_as_metadata_keys_with_true_values = true
end

Each symbol passed as an argument to `describe`, `context` or `it` will
be a key in the metadata hash, with a corresponding value of `true`.

Scenario: define group metadata using a hash
Given a file named "define_group_metadata_with_hash_spec.rb" with:
"""
Expand Down Expand Up @@ -70,3 +81,31 @@ Feature: User-defined metadata
"""
When I run "rspec override_metadata_spec.rb"
Then the examples should all pass

Scenario: less verbose metadata
Given a file named "less_verbose_metadata_spec.rb" with:
"""
RSpec.configure do |c|
c.treat_symbols_as_metadata_keys_with_true_values = true
end
describe "a group with simple metadata", :fast, :simple, :bug => 73 do
it 'has `:fast => true` metadata' do
example.metadata[:fast].should == true
end
it 'has `:simple => true` metadata' do
example.metadata[:simple].should == true
end
it 'can still use a hash for metadata' do
example.metadata[:bug].should == 73
end
it 'can define simple metadata on an example', :special do
example.metadata[:special].should == true
end
end
"""
When I run "rspec less_verbose_metadata_spec.rb"
Then the examples should all pass
1 change: 1 addition & 0 deletions lib/rspec/core.rb
Expand Up @@ -9,6 +9,7 @@
require 'rspec/core/let'
require 'rspec/core/metadata'
require 'rspec/core/pending'
require 'rspec/core/metadata_hash_builder'

require 'rspec/core/world'
require 'rspec/core/configuration'
Expand Down
1 change: 1 addition & 0 deletions lib/rspec/core/configuration.rb
Expand Up @@ -33,6 +33,7 @@ def self.add_setting(name, opts={})
add_setting :include_or_extend_modules
add_setting :backtrace_clean_patterns
add_setting :tty
add_setting :treat_symbols_as_metadata_keys_with_true_values, :default => false

def initialize
@color_enabled = false
Expand Down
7 changes: 6 additions & 1 deletion lib/rspec/core/example_group.rb
Expand Up @@ -8,6 +8,7 @@ class ExampleGroup
include Subject::InstanceMethods
include Let
include Pending
extend MetadataHashBuilder

attr_accessor :example

Expand Down Expand Up @@ -41,7 +42,8 @@ def self.delegate_to_metadata(*names)

def self.define_example_method(name, extra_options={})
module_eval(<<-END_RUBY, __FILE__, __LINE__)
def self.#{name}(desc=nil, options={}, &block)
def self.#{name}(desc=nil, *args, &block)
options = build_metadata_hash_from(args)
options.update(:pending => true) unless block
options.update(#{extra_options.inspect})
examples << RSpec::Core::Example.new(self, desc, options, block)
Expand Down Expand Up @@ -150,6 +152,9 @@ def self.top_level?
end

def self.set_it_up(*args)
symbol_description = args.shift if args.first.is_a?(Symbol)
args << build_metadata_hash_from(args)
args.unshift(symbol_description) if symbol_description
@metadata = RSpec::Core::Metadata.new(superclass_metadata).process(*args)
world.configure_group(self)
end
Expand Down
50 changes: 50 additions & 0 deletions lib/rspec/core/metadata_hash_builder.rb
@@ -0,0 +1,50 @@
module RSpec
module Core
module MetadataHashBuilder
def build_metadata_hash_from(args)
metadata = args.last.is_a?(Hash) ? args.pop : {}

if RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values?
add_symbols_to_hash(metadata, args)
else
warn_about_deprecated_symbol_usage(args)
end

metadata
end

private

def add_symbols_to_hash(hash, args)
while args.last.is_a?(Symbol)
hash.merge!(args.pop => true)
end
end

def warn_about_deprecated_symbol_usage(args)
symbols = args.select { |a| a.is_a?(Symbol) }
return if symbols.empty?

Kernel.warn <<-NOTICE
*****************************************************************
DEPRECATION WARNING: you are using deprecated behaviour that will
be removed from RSpec 3.0.
You have passed symbols (#{symbols.inspect}) as additional
arguments for a doc string.
In RSpec 3.0, these symbols will be treated as metadata keys with
a value of `true`. To get this behavior now (and prevent this
warning), you can set a configuration option:
RSpec.configure do |c|
c.treat_symbols_as_metadata_keys_with_true_values = true
end
*****************************************************************
NOTICE
end
end
end
end
11 changes: 11 additions & 0 deletions spec/rspec/core/configuration_spec.rb
Expand Up @@ -30,6 +30,17 @@ module RSpec::Core
end
end

describe "#treat_symbols_as_metadata_keys_with_true_values?" do
it 'can be set to true' do
config.treat_symbols_as_metadata_keys_with_true_values = true
config.treat_symbols_as_metadata_keys_with_true_values?.should be_true
end

it 'defaults to false' do
config.treat_symbols_as_metadata_keys_with_true_values?.should be_false
end
end

describe "#mock_framework" do
it "defaults to :rspec" do
config.should_receive(:require).with('rspec/core/mocking/with_rspec')
Expand Down
38 changes: 38 additions & 0 deletions spec/rspec/core/example_group_spec.rb
Expand Up @@ -13,6 +13,44 @@ def initialize
module RSpec::Core

describe ExampleGroup do
it_behaves_like "metadata hash builder" do
def metadata_hash(*args)
group = ExampleGroup.describe('example description', *args)
group.metadata
end
end

context 'when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false' do
before(:each) do
RSpec.configure { |c| c.treat_symbols_as_metadata_keys_with_true_values = false }
Kernel.stub(:warn)
end

it 'processes string args as part of the description' do
group = ExampleGroup.describe("some", "separate", "strings")
group.description.should == "some separate strings"
end

it 'processes symbol args as part of the description' do
group = ExampleGroup.describe(:some, :separate, :symbols)
group.description.should == "some separate symbols"
end
end

context 'when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true' do
let(:group) { ExampleGroup.describe(:symbol) }
before(:each) do
RSpec.configure { |c| c.treat_symbols_as_metadata_keys_with_true_values = true }
end

it 'does not treat the first argument as a metadata key even if it is a symbol' do
group.metadata.should_not include(:symbol)
end

it 'treats the first argument as part of the description when it is a symbol' do
group.description.should == "symbol"
end
end

describe "top level group" do
it "runs its children" do
Expand Down
7 changes: 7 additions & 0 deletions spec/rspec/core/example_spec.rb
Expand Up @@ -9,6 +9,13 @@
example_group.example('example description')
end

it_behaves_like "metadata hash builder" do
def metadata_hash(*args)
example = example_group.example('example description', *args)
example.metadata
end
end

describe '#described_class' do
it "returns the class (if any) of the outermost example group" do
described_class.should == RSpec::Core::Example
Expand Down
45 changes: 45 additions & 0 deletions spec/support/shared_example_groups.rb
@@ -0,0 +1,45 @@
shared_examples_for "metadata hash builder" do
context "when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to true" do
let(:hash) { metadata_hash(:foo, :bar, :bazz => 23) }

before(:each) do
RSpec.configure { |c| c.treat_symbols_as_metadata_keys_with_true_values = true }
end

it 'treats symbols as metadata keys with a true value' do
hash[:foo].should == true
hash[:bar].should == true
end

it 'does not treat the first argument as a metadata key' do
hash.should_not include(:group)
end

it 'still processes hash values normally' do
hash[:bazz].should == 23
end
end

context "when RSpec.configuration.treat_symbols_as_metadata_keys_with_true_values is set to false" do
let(:warning_receiver) { Kernel }

before(:each) do
RSpec.configure { |c| c.treat_symbols_as_metadata_keys_with_true_values = false }
warning_receiver.stub(:warn)
end

it 'prints a deprecation warning about any symbols given as arguments' do
warning_receiver.should_receive(:warn).with(/you have passed symbols \(\[:foo, :bar\]\) as additional\s+arguments for a doc string/i)
metadata_hash(:foo, :bar, :key => 'value')
end

it 'does not treat symbols as metadata keys' do
metadata_hash(:foo, :bar, :key => 'value').should_not include(:foo, :bar)
end

it 'does not print a warning if there are no symbol arguments' do
warning_receiver.should_not_receive(:warn)
metadata_hash(:foo => 23, :bar => 17)
end
end
end

0 comments on commit 2dd6fab

Please sign in to comment.