0.01
No commit activity in last 3 years
No release in over 3 years
This gem is here to help DRYing your tests cases by giving a better "shared_examples".
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies
 Project Readme

RspecInContext

Gem Version Codacy Badge Test and Release badge

This gem is here to help you write better shared_examples in Rspec.

Ever been bothered by the fact that they don't really behave like methods and that you can't pass it a block ? There you go: rspec_in_context

Installation

Add this line to your application's Gemfile:

gem 'rspec_in_context'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rspec_in_context

Usage

Add this into Rspec

You must require the gem on top of your spec_helper:

require 'rspec_in_context'

Then include it into Rspec:

RSpec.configure do |config|
  [...]
  
  config.include RspecInContext
end

Define a new in_context

You can define in_context block that are reusable almost anywhere. They completely look like normal Rspec.

Inside a Rspec block (scoped)
# A in_context can be named with a symbol or a string
define_context :context_name do
  it 'works' do
    expect(true).to be_truthy
  end
end

Those in_context will be scoped to their current describe/context block.

Outside a Rspec block (globally)

Outside of a test you have to use RSpec.define_context. Those in_context will be defined globally in your tests.

Use the context

Anywhere in your test description, use a in_context block to use a predefined in_context.

Important: in_context are scoped to their current describe/context block. If you need globally defined context see RSpec.define_context

# A in_context can be named with a symbol or a string
RSpec.define_context :context_name do
  it 'works' do
    expect(true).to be_truthy
  end
end

[...]
Rspec.describe MyClass do
  in_context :context_name # => will execute the 'it works' test here
end

Things to know

Inside block execution

  • You can chose exactly where your inside test will be used: By using execute_tests in your define context, the test passed when you use the context will be executed here
define_context :context_name do
  it 'works' do
    expect(true).to be_truthy
  end
  context "in this context pomme exists" do
    let(:pomme) { "abcd" }
    
    execute_tests
  end
end

[...]

in_context :context_name do
  it 'will be executed at execute_tests place' do
    expect(pomme).to eq("abcd") # => true
  end
end
  • You can add variable instantiation relative to your test where you exactly want:

instanciate_context is an alias of execute_tests so you can't use both. But it let you describe what the block will do better.

Variable usage

  • You can use variable in the in_context definition
define_context :context_name do |name|
  it 'works' do
    expect(true).to be_truthy
  end
  context "in this context #{name} exists" do
    let(name) { "abcd" }
    
    execute_tests
  end
end

[...]

in_context :context_name, :poire do
  it 'the right variable will exists' do
    expect(poire).to eq("abcd") # => true
  end
end

Scoping

  • In_contexts can be scope inside one another
define_context :context_name do |name|
  it 'works' do
    expect(true).to be_truthy
  end
  context "in this context #{name} exists" do
    let(name) { "abcd" }
    
    execute_tests
  end
end

define_context "second in_context" do
  context 'and tree also' do
    let(:tree) { 'abcd' }

    it 'will scope correctly' do
      expect(tree).to eq(poire)
    end
  end
end

[...]

in_context :context_name, :poire do
  it 'the right variable will exists' do
    expect(poire).to eq("abcd") # => true
  end

  in_context "second in_context" # => will work
end
  • in_context are bound to their current scope

Namespacing

  • You can add a namespace to a in_context definition
define_context "this is a namespaced context", namespace: "namespace name"

Or

define_context "this is a namespaced context", ns: "namespace name"

Or

RSpec.define_context "this is a namespaced context", ns: "namespace name"
  • When you want to use a namespaced in_context, you have two choice:

Ignore any namespace and it will try to find a corresponding in_context in any_namespace (the ones defined without namespace have the priority);

define_context "namespaced context", ns: "namespace name" do
  [...]
end

in_context "namespaced context"

Pass a namespace and it will look only in this context.

define_context "namespaced context", ns: "namespace name" do
  [...]
end

in_context "namespaced context", namespace: "namespace name"
in_context "namespaced context", ns: "namespace name"

Making in_context adverstise itself

The fact that a in_context block is used inside the test is silent and invisible by default. in_context will still wrap its own execution inside a anonymous context.

But, there's some case where it helps to make the in_context to wrap its execution in a named context block. For example:

define_context "with my_var defined" do
  before do
    described_class.set_my_var(true)
  end

  it "works"
end

define_context "without my_var defined" do
  it "doesn't work"
end

RSpec.describe MyNiceClass do
  in_context "with my_var defined"
  in_context "without my_var defined"
end

Using a rspec -f doc will only print "MyNiceClass works" and "MyNiceClass doesn't work" which is not really a good documentation.

So, you can define a context specifying it not to be silent or to print_context. For example :

define_context "with my_var defined", silent: false do
  before do
    described_class.set_my_var(true)
  end

  it "works"
end

define_context "without my_var defined", print_context: true do
  it "doesn't work"
end

RSpec.describe MyNiceClass do
  in_context "with my_var defined"
  in_context "without my_var defined"
end

Will print "MyNiceClass with my_var defined works" and "MyNiceClass without my_var defined doesn't work". Which is valid and readable documentation.

Development

After checking out the repo, run bin/setup to install dependencies. You can also run bin/console for an interactive prompt that will allow you to experiment.

After setuping the repo, you should run overcommit --install to install the different hooks.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/denispasin/rspec_in_context.