Skip to content
This repository
tree: 1e241a50eb
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 205 lines (174 sloc) 6.419 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
Feature: shared examples

Shared examples let you describe behaviour of types or modules. When
declared, a shared group's content is stored. It is only realized in the
context of another example group, which provides any context the shared group
needs to run.

A shared group is included in another group using any of:
include_examples "name" # include the examples in the current context
it_behaves_like "name" # include the examples in a nested context
it_should_behave_like "name" # include the examples in a nested context

WARNING: Files containing shared groups must be loaded before the files that
use them. While there are conventions to handle this, RSpec does _not_ do
anything special (like autoload). Doing so would require a strict naming
convention for files that would break existing suites.

CONVENTIONS:

1. The simplest approach is to require files with shared examples explicitly
from the files that use them. Keep in mind that RSpec adds the `spec`
directory to the `LOAD_PATH`, so you can say `require
'shared_examples_for_widgets'` to require a file at
`#{PROJECT_ROOT}/spec/shared_examples_for_widgets.rb`.

2. Put files containing shared examples in `spec/support/` and require files
in that directory from `spec/spec_helper.rb`:

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

This is included in the generated `spec/spec_helper.rb` file in
`rspec-rails`

3. When all of the groups that include the shared group, just declare
the shared group in the same file.

Scenario: shared examples group included in two groups in one file
Given a file named "collection_spec.rb" with:
"""
require "set"

shared_examples "a collection" do
let(:collection) { described_class.new([7, 2, 4]) }

context "initialized with 3 items" do
it "says it has three items" do
collection.size.should eq(3)
end
end

describe "#include?" do
context "with an an item that is in the collection" do
it "returns true" do
collection.include?(7).should be_true
end
end

context "with an an item that is not in the collection" do
it "returns false" do
collection.include?(9).should be_false
end
end
end
end

describe Array do
it_behaves_like "a collection"
end

describe Set do
it_behaves_like "a collection"
end
"""
When I run `rspec collection_spec.rb --format documentation`
Then the examples should all pass
And the output should contain:
"""
Array
behaves like a collection
initialized with 3 items
says it has three items
#include?
with an an item that is in the collection
returns true
with an an item that is not in the collection
returns false

Set
behaves like a collection
initialized with 3 items
says it has three items
#include?
with an an item that is in the collection
returns true
with an an item that is not in the collection
returns false
"""

Scenario: Providing context to a shared group using a block
Given a file named "shared_example_group_spec.rb" with:
"""
require "set"

shared_examples "a collection object" do
describe "<<" do
it "adds objects to the end of the collection" do
collection << 1
collection << 2
collection.to_a.should eq([1,2])
end
end
end

describe Array do
it_behaves_like "a collection object" do
let(:collection) { Array.new }
end
end

describe Set do
it_behaves_like "a collection object" do
let(:collection) { Set.new }
end
end
"""
When I run `rspec shared_example_group_spec.rb --format documentation`
Then the examples should all pass
And the output should contain:
"""
Array
behaves like a collection object
<<
adds objects to the end of the collection

Set
behaves like a collection object
<<
adds objects to the end of the collection
"""

Scenario: Passing parameters to a shared example group
Given a file named "shared_example_group_params_spec.rb" with:
"""
shared_examples "a measurable object" do |measurement, measurement_methods|
measurement_methods.each do |measurement_method|
it "should return #{measurement} from ##{measurement_method}" do
subject.send(measurement_method).should == measurement
end
end
end

describe Array, "with 3 items" do
subject { [1, 2, 3] }
it_should_behave_like "a measurable object", 3, [:size, :length]
end

describe String, "of 6 characters" do
subject { "FooBar" }
it_should_behave_like "a measurable object", 6, [:size, :length]
end
"""
When I run `rspec shared_example_group_params_spec.rb --format documentation`
Then the examples should all pass
And the output should contain:
"""
Array with 3 items
it should behave like a measurable object
should return 3 from #size
should return 3 from #length

String of 6 characters
it should behave like a measurable object
should return 6 from #size
should return 6 from #length
"""

Scenario: Aliasing "it_should_behave_like" to "it_has_behavior"
Given a file named "shared_example_group_spec.rb" with:
"""
RSpec.configure do |c|
c.alias_it_should_behave_like_to :it_has_behavior, 'has behavior:'
end

shared_examples 'sortability' do
it 'responds to <=>' do
sortable.should respond_to(:<=>)
end
end

describe String do
it_has_behavior 'sortability' do
let(:sortable) { 'sample string' }
end
end
"""
When I run `rspec shared_example_group_spec.rb --format documentation`
Then the examples should all pass
And the output should contain:
"""
String
has behavior: sortability
responds to <=>
"""
Something went wrong with that request. Please try again.