Forum: RSpec how can shared examples be shared across gems?

Posted by Lille (Guest)
on 2011-12-11 23:05
(Received via mailing list)
Hi,

I have shared examples in a gem...

some_gem_name/spec/some_gem_name/shared_examples.rb

...where the shared examples are contained in a module, e.g.,

module SharedExamples

   shared_examples_for ...

end

How can I include these shared examples in tests in a different gem
that depends on my some_gem_name, above? Maybe I can refer to the
shared examples in my dependent gem's spec_helper?

Thanks,

Lille
Posted by David Chelimsky (Guest)
on 2011-12-12 15:47
(Received via mailing list)
On Dec 11, 2011, at 4:02 PM, Lille wrote:

>   shared_examples_for ...
>
> end

How does this even work? shared_examples_for is not defined in Module, 
so unless you're leaving something important out, that should raise an 
error.

> How can I include these shared examples in tests in a different gem
> that depends on my some_gem_name, above? Maybe I can refer to the
> shared examples in my dependent gem's spec_helper?

There are two ways you can do this:

shared_examples "stuff" do
  before { ... }
  let(:name) { value }
  it "does something" do
    # ..
  end
end

As long as this file is required somewhere (only once, please) you can 
use those examples in your gem or any other gem:

describe Something do
  it_behaves_like "stuff"
end

You can also define a module:

module SharedExamples
  extend RSpec::Core::SharedContext
  before { ... }
  let(:name) { value }
  it "does something" do
    # ..
  end
end

Now you can do a standard Ruby include

describe Something do
  include SharedExamples
end


see 
https://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples
see 
http://rubydoc.info/github/rspec/rspec-core/master/RSpec/Core/SharedContext

HTH,
David
Posted by Lille (Guest)
on 2011-12-14 02:04
(Received via mailing list)
Thank you.

Here is what I did to conform my gem spec to the conventions suggested
at 
https://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples...

my spec/spec_helper.rb...

$LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
# Dir["spec/support/**/*.rb"].each {|f| require f} # this did not
work...

require 'rubygems'
require 'rum_92265'
require 'rspec'
require 'rspec/autorun'
require 'support/shared_examples' # this did

now, at the top of in lib/rum_92265.rb...

require "rum_92265/version"
require File.dirname(__FILE__) + "/../spec/support/shared_examples.rb"

finally, here are the top lines of the spec/support/
shared_sample.rb...

extend RSpec::Core::SharedContext

shared_examples_for "Rum92265::A3::PartB" do

...

Anyway, I hadn't seen any gems with shared example groups exposed, so
this was the best I could come up with -- it worked. It seems weird to
require shared_samples.rb from the lib directory, but I couldn't see
where else -- gemspec, for example? -- to require it.

Lille
Posted by David Chelimsky (Guest)
on 2011-12-14 05:33
(Received via mailing list)
On Dec 13, 2011, at 6:30 PM, Lille wrote:

I moved your post to the bottom. Please read 
http://idallen.com/topposting.html and please bottom post or inline post 
so readers can more easily follow the thread.

>>
>>> shared examples in my dependent gem's spec_helper?
>>
>>   before { ... }
>> end
>>
>> seehttps://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared...
>> seehttp://rubydoc.info/github/rspec/rspec-core/master/RSpec/Core/SharedC...
>>
>> HTH,
>> David

> Thank you.
>
> Here is what I did to conform my gem spec to the conventions suggested
> at 
https://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples...
>
> my spec/spec_helper.rb...
>
> $LOAD_PATH.unshift(File.dirname(__FILE__))
> $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))

You don't need to modify the ^^ LOAD_PATH ^^ here - it's already done 
for you by RSpec.

> # Dir["spec/support/**/*.rb"].each {|f| require f} # this did not work...

I'm assuming you're using Ruby 1.9, which does not include "." on the 
LOAD_PATH (which is assumed by Dir["spec/support/**/*.rb"]). Either of 
these would work:

Dir["./spec/support/**/*.rb"].each {|f| require f}
Dir["support/**/*.rb"].each {|f| require f}

I'll update the docs on relishapp.com accordingly.

> require File.dirname(__FILE__) + "/../spec/support/shared_examples.rb"
This ^^ is going to get you into trouble because Ruby doesn't see 
/path/to/x/../spec/support/shared_examples.rb and 
/path/to/spec/support/shared_examples.rb as the same path (even though 
they end at the same file). This means that your users will likely end 
up requiring shared_examples.rb twice, which makes bad things happen.

I'd recommend modifying and relying on the LOAD_PATH instead. More 
below.

>
> finally, here are the top lines of the spec/support/
> shared_sample.rb...
>
> extend RSpec::Core::SharedContext
>
> shared_examples_for "Rum92265::A3::PartB" do

You don't need both "extend RSpec::Core::SharedContext" and 
"shared_examples_for". Just one or the other.

> Anyway, I hadn't seen any gems with shared example groups exposed, so
> this was the best I could come up with -- it worked. It seems weird to
> require shared_samples.rb from the lib directory, but I couldn't see
> where else -- gemspec, for example? -- to require it.
>
> Lille

If the idea here is to expose shared_examples to users of your gem, I'd 
actually store them under lib. Something like:

lib/rum_92265/spec_support.rb # requires 
rum_92265/spec_support/shared_examples.rb
lib/rum_92265/spec_support/shared_examples.rb

Now you can require 'rum_92265/spec_support' in your own 
spec/spec_helper.rb, and you can tell your users to do the same.

HTH,
David
Posted by Lille (Guest)
on 2011-12-16 02:29
(Received via mailing list)
> > Here is what I did to conform my gem spec to the conventions suggested
> > athttps://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared......
>
> > my spec/spec_helper.rb...
>
> > $LOAD_PATH.unshift(File.dirname(__FILE__))
> > $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
>
> You don't need to modify the ^^ LOAD_PATH ^^ here - it's already done for you by 
RSpec.

OK - I made this change, thanks...

> > finally, here are the top lines of the spec/support/
> > shared_sample.rb...
>
> > extend RSpec::Core::SharedContext
>
> > shared_examples_for "Rum92265::A3::PartB" do
>
> You don't need both "extend RSpec::Core::SharedContext" and 
"shared_examples_for". Just one or the other.

...and made this change...

> If the idea here is to expose shared_examples to users of your gem, I'd actually 
store them under lib. Something like:
>
> lib/rum_92265/spec_support.rb # requires 
rum_92265/spec_support/shared_examples.rb
> lib/rum_92265/spec_support/shared_examples.rb
>
> Now you can require 'rum_92265/spec_support' in your own spec/spec_helper.rb, 
and you can tell your users to do the same.

...finally, I did this, too. These steps added up to a successful
result for me.

Thank you very much for your detailed and helpful response.

Lille
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.