[rspec-users] Problems using config.extend(Macro)

Ants Pants antsmailinglist at gmail.com
Tue Jan 10 14:08:35 EST 2012


On 10 January 2012 18:29, David Chelimsky <dchelimsky at gmail.com> wrote:

> On Tue, Jan 10, 2012 at 10:30 AM, Ants Pants <antsmailinglist at gmail.com>
> wrote:
> >
> >
> > On 10 January 2012 14:56, David Chelimsky <dchelimsky at gmail.com> wrote:
> >>
> >> On Jan 10, 2012, at 7:21 AM, Ants Pants wrote:
> >>
> >> > Under Ruby 1.8.7 - Rails 2.3.11 - Rspec 1:
> >> >
> >> > I have model_macros.rb under spec/spec_helpers and it runs
> beautifully.
> >> >
> >> > Dir[File.expand_path(File.join(File.dirname(__FILE__), 'spec_helpers',
> >> > '**', '*.rb'))].each { require f }
> >> > config.extend(ModelMacros, :type => :model)
> >> >
> >> > Exactly the same code under Ruby 1.9.2 - Rails 3.1.3 - Rspec 2 gives
> me
> >> > ... uninitialized constant ModelMacros (NameError)
> >> >
> >> > Dir[Rails.root.join("spec/spec_helpers/**/*.rb")].each {|f| require f}
> >> > config.extend(ModelMacros, :type => :model)
> >> >
> >> > .... which makes sense as it's missing the namespace (but how did it
> run
> >> > under 2.3.11. Is Ruby 1.8.7 more lenient? - I doubt it)
> >>
> >> That would make sense if Rails was autoloading (implicit) this, but it's
> >> not - spec_helper.rb is loading it explicitly. I think the namespace
> thing
> >> is a red herring.
> >>
> >> > So I added the namespace and I got rid of that error
> >> >
> >> > config.extend(SpecHelpers::ModelMacros, :type => :model)
> >> >
> >> > But sadly the methods that are called from within the model specs are
> >> > unable to be found...... Exception encountered: #<NoMethodError:
> undefined
> >> > method `it_should_require_attributes'
> >> >
> >> > This is only solved by including extend SpecHelpers::ModelMacros in
> the
> >> > model spec file. Not what I want.
> >>
> >> Which suggests that the config is being silently ignored, even though
> the
> >> loading is working.
> >>
> >> > Is there something I am missing while migrating all my code? Is there
> >> > some really basic Ruby thing I have forgotten to do to get this module
> >> > included?
> >> >
> >> > I also tried config.include(SpecHelpers::ModelMacros, :type => :model)
> >> > but to no avail.
> >>
> >> That would never have worked under any version because "include" exposes
> >> methods to the example scope, not the group scope:
> >>
> >> describe "something" do
> >>  # methods in modules added using extend are available here
> >>  it "does something" do
> >>    # methods in modules added using include are available here
> >>  end
> >> end
> >>
> >> > Any help would be great, thank you.
> >>
> >> My best guess is that you don't need the namespace, and you should leave
> >> Rails out of loading this. Try this:
> >>
> >>  Dir["spec_helpers/**/*.rb"].each {|f| require f}
> >>  RSpec.configure do |config|
> >>    config.extend(ModelMacros, :type => :model)
> >>  end
> >>
> >> That should work to load the file, since RSpec adds"./spec" to the
> >> $LOAD_PATH.
> >>
> >> If that doesn't work, it might be that ":type => :model" isn't working
> >> correctly, so try "path => /spec\/model/" instead. Please report back
> and
> >> let us know which, if either, works for you.
> >>
> >> HTH,
> >> David
> >> _______________________________________________
> >> rspec-users mailing list
> >> rspec-users at rubyforge.org
> >> http://rubyforge.org/mailman/listinfo/rspec-users
> >
> >
> > Hey David, thanks for the reply.
> >
> > Sadly nothing worked and here are my results
> >
> > With ....
> > Dir["spec_helpers/**/*.rb"].each {|f| puts "loading ... #{f}"; require f}
> >
> > I didn't find any file to load and got the following error....
> >
> > /home/anthony/Development/websites/ruby/GMFT/spec/spec_helper.rb:84:in
> > `block in <top (required)>': uninitialized constant ModelMacros
> (NameError)
> >
> > With ....
> > Dir["spec/spec_helpers/**/*.rb"].each {|f| puts "loading ... #{f}";
> require
> > f}
> >
> > I found a file to load but require couldn't find it ....
> >
> > loading ... spec/spec_helpers/model_macros.rb
> > /home/anthony/.rvm/gems/ruby-1.9.2-p290 at gmft313
> /gems/activesupport-3.1.3/lib/active_support/dependencies.rb:240:in
> > `require': no such file to load -- spec/spec_helpers/model_macros.rb
> > (LoadError)
> >
> > With ....
> > Dir[Rails.root.join("spec/spec_helpers/**/*.rb")].each {|f| puts "loading
> > ... #{f}"; require f}
> >
> > I found a file to load, apparently it loaded it but then the
> > ModelMacros#method could not be found....
> >
> > loading ...
> >
> /home/anthony/Development/websites/ruby/GMFT/spec/spec_helpers/model_macros.rb
> >
> /home/anthony/Development/websites/ruby/GMFT/spec/model/event_group_spec.rb:27:in
> > `block in <top (required)>': undefined method
> `it_should_require_attributes'
> > for #<Class:0xd25d5fc> (NoMethodError
> >
> > I also tried with :path in the third example but nada.
> >
> > I've also tried all of the above running rspec 2.7.0 and rspec-rails
> 2.7.0.
> > No joy.
> >
> > It must be something I'm doing wrong. But what?!!!
>
> What's in model_macros.rb?
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>

David,

I set an instance variable @dut  (domain under test) in a before block in
the spec and use it in the macro. I don't know if this is the best way but
I'm not an expert Ruby programmer.

before(:each) do
   @event_group = Factory.build(:event_group)
   @dut = @event_group
end

## and an example call in the spec
it_should_require_attributes :name, :created_by

Here are just a few methods from the macro .....

module ModelMacros
  ## dut - Domain Under Test
  ## aut - Attribute Under Test

  def it_should_require_attributes(*attrs)
    attrs.each { |attr| it_should_require_attribute(attr) }
  end

  def it_should_not_require_attributes(*attrs)
    attrs.each { |attr| it_should_not_require_attribute(attr) }
  end

  def it_should_require_attribute(aut)
    it "is not valid with missing #{aut}" do
      @dut.send("#{aut}=", nil)
      @dut.should_not be_valid
      @dut.should have(1).error_on(aut.to_sym)
    end
  end

  def it_should_not_require_attribute(aut)
    it "is valid with missing #{aut}" do
      @dut.send("#{aut}=", nil)
      @dut.should be_valid
    end
  end
end

I hope this helps. I'm really racking my brains but I just can't think of
anything.

-ants
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20120110/4eeb7008/attachment-0001.html>


More information about the rspec-users mailing list