On Dec 4, 2011, at 6:15 PM, Gordon wrote:
=> :bar"
expect { help }.to raise_error(NameError)
end
end
------------- Extract end ---------------
Question: Why is the example expected to fail (ie.
raise_error(NameError))
when the meta data matches and it’s expected to pass?
In Ruby, when we include modules in classes, their methods are available
in instances of those classes.
module Helper
def help
:available
end
end
class Foo
include Helper
end
foo = Foo.new
foo.help # => :available
We can also make the same methods available by extending an instance of
a class.
class Bar
end
bar = Bar.new
bar.extend(Helper)
bar.help # => :available
Now the tricky part is that classes are objects as well - instances of
the Class class. This means that when you extend a class, its methods
are available as class methods, not as instance methods:
class Baz
extend Helper
end
Baz.help # => :available
Baz.new.help # => ERROR!!!
In RSpec, an example group is a class, whereas an example is
(effectively) an instance of that class. This is not 100% accurate, but
let’s go with that metaphor for the moment. When you say “config.include
SomeModule”, it gets included into example groups, making its methods
available within examples (instances of the group). When you say
“config.extend SomeModule”, it extends the example group, making its
methods available within at the group level, but not within the
examples.
In the scenario you cite, the module is used to extend the example group
matching :foo => :bar (the first group), so it is available at the group
level, as demonstrated by puts "In a matching group, help is #{help}"
printing out “In a matching group, help is available”, but is not
available in the other group, as demonstrated by puts "In a non-matching group, help is #{help rescue 'not available'}"
printing
out “In a non-matching group, help is not available”, and it is not
available to examples (instances) in either group, as demonstrated by
expect { help }.to raise_error(NameError)
passing in both examples.
HTH,
David