diff --git a/DEV-README.md b/DEV-README.md index ff37b60e4..5b61fe016 100644 --- a/DEV-README.md +++ b/DEV-README.md @@ -1,24 +1,32 @@ ## Set up the dev environment - git clone https://github.com/rspec/rspec-expectations.git - cd rspec-expectations - gem install bundler - bundle install +```shell +git clone https://github.com/rspec/rspec-expectations.git +cd rspec-expectations +gem install bundler +bundle install +``` Now you should be able to run any of: - rake - rake spec - rake cucumber +```shell +rake +rake spec +rake cucumber +``` Or, if you prefer to use the rspec and cucumber commands directly, you can either: - bundle exec rspec +```shell +bundle exec rspec +``` Or ... - bundle install --binstubs - bin/rspec +```shell +bundle install --binstubs +bin/rspec +``` ## Customize the dev environment diff --git a/README.md b/README.md index 605c834e2..a649542b0 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,9 @@ If you want to use rspec-expectations with rspec, just install the rspec gem and RubyGems will also install rspec-expectations for you (along with rspec-core and rspec-mocks): - gem install rspec +```shell +gem install rspec +``` Want to run against the `main` branch? You'll need to include the dependent RSpec repos as well. Add the following to your `Gemfile`: @@ -27,7 +29,9 @@ end If you want to use rspec-expectations with another tool, like Test::Unit, Minitest, or Cucumber, you can install it directly: - gem install rspec-expectations +```shell +gem install rspec-expectations +``` ## Contributing @@ -67,8 +71,10 @@ The `describe` and `it` methods come from rspec-core. The `Order`, `LineItem`, expresses an expected outcome. If `order.total == Money.new(5.55, :USD)`, then the example passes. If not, it fails with a message like: - expected: # - got: # +``` + expected: # + got: # +``` ## Built-in matchers diff --git a/features/built_in_matchers/README.md b/features/built_in_matchers/README.md index 686620384..90e9dc37d 100644 --- a/features/built_in_matchers/README.md +++ b/features/built_in_matchers/README.md @@ -8,172 +8,172 @@ respectively on an object. Most matchers can also be accessed using the `(...).s e.g. ```ruby - expect(result).to eq(3) - expect(list).not_to be_empty - pi.should be > 3 +expect(result).to eq(3) +expect(list).not_to be_empty +pi.should be > 3 ``` ## Object identity ```ruby - expect(actual).to be(expected) # passes if actual.equal?(expected) +expect(actual).to be(expected) # passes if actual.equal?(expected) ``` ## Object equivalence ```ruby - expect(actual).to eq(expected) # passes if actual == expected +expect(actual).to eq(expected) # passes if actual == expected ``` ## Optional APIs for identity/equivalence ```ruby - expect(actual).to eql(expected) # passes if actual.eql?(expected) - expect(actual).to equal(expected) # passes if actual.equal?(expected) +expect(actual).to eql(expected) # passes if actual.eql?(expected) +expect(actual).to equal(expected) # passes if actual.equal?(expected) - # NOTE: `expect` does not support `==` matcher. +# NOTE: `expect` does not support `==` matcher. ``` ## Comparisons ```ruby - expect(actual).to be > expected - expect(actual).to be >= expected - expect(actual).to be <= expected - expect(actual).to be < expected - expect(actual).to be_between(minimum, maximum).inclusive - expect(actual).to be_between(minimum, maximum).exclusive - expect(actual).to match(/expression/) - expect(actual).to be_within(delta).of(expected) - expect(actual).to start_with expected - expect(actual).to end_with expected +expect(actual).to be > expected +expect(actual).to be >= expected +expect(actual).to be <= expected +expect(actual).to be < expected +expect(actual).to be_between(minimum, maximum).inclusive +expect(actual).to be_between(minimum, maximum).exclusive +expect(actual).to match(/expression/) +expect(actual).to be_within(delta).of(expected) +expect(actual).to start_with expected +expect(actual).to end_with expected - # NOTE: `expect` does not support `=~` matcher. +# NOTE: `expect` does not support `=~` matcher. ``` ## Types/classes/response ```ruby - expect(actual).to be_instance_of(expected) - expect(actual).to be_kind_of(expected) - expect(actual).to respond_to(expected) +expect(actual).to be_instance_of(expected) +expect(actual).to be_kind_of(expected) +expect(actual).to respond_to(expected) ``` ## Truthiness and existentialism ```ruby - expect(actual).to be_truthy # passes if actual is truthy (not nil or false) - expect(actual).to be true # passes if actual == true - expect(actual).to be_falsey # passes if actual is falsy (nil or false) - expect(actual).to be false # passes if actual == false - expect(actual).to be_nil # passes if actual is nil - expect(actual).to exist # passes if actual.exist? and/or actual.exists? are truthy - expect(actual).to exist(*args) # passes if actual.exist?(*args) and/or actual.exists?(*args) are truthy +expect(actual).to be_truthy # passes if actual is truthy (not nil or false) +expect(actual).to be true # passes if actual == true +expect(actual).to be_falsey # passes if actual is falsy (nil or false) +expect(actual).to be false # passes if actual == false +expect(actual).to be_nil # passes if actual is nil +expect(actual).to exist # passes if actual.exist? and/or actual.exists? are truthy +expect(actual).to exist(*args) # passes if actual.exist?(*args) and/or actual.exists?(*args) are truthy ``` ## Expecting errors ```ruby - expect { ... }.to raise_error - expect { ... }.to raise_error(ErrorClass) - expect { ... }.to raise_error("message") - expect { ... }.to raise_error(ErrorClass, "message") +expect { ... }.to raise_error +expect { ... }.to raise_error(ErrorClass) +expect { ... }.to raise_error("message") +expect { ... }.to raise_error(ErrorClass, "message") ``` ## Expecting throws ```ruby - expect { ... }.to throw_symbol - expect { ... }.to throw_symbol(:symbol) - expect { ... }.to throw_symbol(:symbol, 'value') +expect { ... }.to throw_symbol +expect { ... }.to throw_symbol(:symbol) +expect { ... }.to throw_symbol(:symbol, 'value') ``` ## Predicate matchers ```ruby - expect(actual).to be_xxx # passes if actual.xxx? - expect(actual).to have_xxx(:arg) # passes if actual.has_xxx?(:arg) +expect(actual).to be_xxx # passes if actual.xxx? +expect(actual).to have_xxx(:arg) # passes if actual.has_xxx?(:arg) ``` ### Examples ```ruby - expect([]).to be_empty - expect(:a => 1).to have_key(:a) +expect([]).to be_empty +expect(:a => 1).to have_key(:a) ``` ## Collection membership ```ruby - expect(actual).to include(expected) - expect(array).to match_array(expected_array) - # ...which is the same as: - expect(array).to contain_exactly(individual, elements) +expect(actual).to include(expected) +expect(array).to match_array(expected_array) +# ...which is the same as: +expect(array).to contain_exactly(individual, elements) ``` ### Examples ```ruby - expect([1, 2, 3]).to include(1) - expect([1, 2, 3]).to include(1, 2) - expect(:a => 'b').to include(:a => 'b') - expect("this string").to include("is str") - expect([1, 2, 3]).to contain_exactly(2, 1, 3) - expect([1, 2, 3]).to match_array([3, 2, 1]) +expect([1, 2, 3]).to include(1) +expect([1, 2, 3]).to include(1, 2) +expect(:a => 'b').to include(:a => 'b') +expect("this string").to include("is str") +expect([1, 2, 3]).to contain_exactly(2, 1, 3) +expect([1, 2, 3]).to match_array([3, 2, 1]) ``` ## Ranges (1.9+ only) ```ruby - expect(1..10).to cover(3) +expect(1..10).to cover(3) ``` ## Change observation ```ruby - expect { object.action }.to change(object, :value).from(old).to(new) - expect { object.action }.to change(object, :value).by(delta) - expect { object.action }.to change(object, :value).by_at_least(minimum_delta) - expect { object.action }.to change(object, :value).by_at_most(maximum_delta) +expect { object.action }.to change(object, :value).from(old).to(new) +expect { object.action }.to change(object, :value).by(delta) +expect { object.action }.to change(object, :value).by_at_least(minimum_delta) +expect { object.action }.to change(object, :value).by_at_most(maximum_delta) ``` ### Examples ```ruby - expect { a += 1 }.to change { a }.by(1) - expect { a += 3 }.to change { a }.from(2) - expect { a += 3 }.to change { a }.by_at_least(2) +expect { a += 1 }.to change { a }.by(1) +expect { a += 3 }.to change { a }.from(2) +expect { a += 3 }.to change { a }.by_at_least(2) ``` ## Satisfy ```ruby - expect(actual).to satisfy { |value| value == expected } +expect(actual).to satisfy { |value| value == expected } ``` ## Output capture ```ruby - expect { actual }.to output("some output").to_stdout - expect { actual }.to output("some error").to_stderr +expect { actual }.to output("some output").to_stdout +expect { actual }.to output("some error").to_stderr ``` ## Block expectation ```ruby - expect { |b| object.action(&b) }.to yield_control - expect { |b| object.action(&b) }.to yield_with_no_args # only matches no args - expect { |b| object.action(&b) }.to yield_with_args # matches any args - expect { |b| object.action(&b) }.to yield_successive_args(*args) # matches args against multiple yields +expect { |b| object.action(&b) }.to yield_control +expect { |b| object.action(&b) }.to yield_with_no_args # only matches no args +expect { |b| object.action(&b) }.to yield_with_args # matches any args +expect { |b| object.action(&b) }.to yield_successive_args(*args) # matches args against multiple yields ``` ### Examples ```ruby - expect { |b| User.transaction(&b) }.to yield_control - expect { |b| User.transaction(&b) }.to yield_with_no_args - expect { |b| 5.tap(&b) }.not_to yield_with_no_args # because it yields with `5` - expect { |b| 5.tap(&b) }.to yield_with_args(5) # because 5 == 5 - expect { |b| 5.tap(&b) }.to yield_with_args(Integer) # because Integer === 5 - expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3) +expect { |b| User.transaction(&b) }.to yield_control +expect { |b| User.transaction(&b) }.to yield_with_no_args +expect { |b| 5.tap(&b) }.not_to yield_with_no_args # because it yields with `5` +expect { |b| 5.tap(&b) }.to yield_with_args(5) # because 5 == 5 +expect { |b| 5.tap(&b) }.to yield_with_args(Integer) # because Integer === 5 +expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3) ``` diff --git a/features/built_in_matchers/all.feature b/features/built_in_matchers/all.feature index d2a3103ad..16b840a42 100644 --- a/features/built_in_matchers/all.feature +++ b/features/built_in_matchers/all.feature @@ -3,17 +3,17 @@ Feature: `all` matcher Use the `all` matcher to specify that a collection's objects all pass an expected matcher. This works on any enumerable object. ```ruby - expect([1, 3, 5]).to all( be_odd ) - expect([1, 3, 5]).to all( be_an(Integer) ) - expect([1, 3, 5]).to all( be < 10 ) - expect([1, 3, 4]).to all( be_odd ) # fails + expect([1, 3, 5]).to all( be_odd ) + expect([1, 3, 5]).to all( be_an(Integer) ) + expect([1, 3, 5]).to all( be < 10 ) + expect([1, 3, 4]).to all( be_odd ) # fails ``` The matcher also supports compound matchers: ```ruby - expect([1, 3, 5]).to all( be_odd.and be < 10 ) - expect([1, 4, 21]).to all( be_odd.or be < 10 ) + expect([1, 3, 5]).to all( be_odd.and be < 10 ) + expect([1, 4, 21]).to all( be_odd.or be < 10 ) ``` If you are looking for "any" member of a collection that passes an expectation, look at the `include`-matcher. diff --git a/features/built_in_matchers/be.feature b/features/built_in_matchers/be.feature index ce4ed433b..716622ca1 100644 --- a/features/built_in_matchers/be.feature +++ b/features/built_in_matchers/be.feature @@ -3,10 +3,10 @@ Feature: `be` matchers There are several related "be" matchers: ```ruby - expect(obj).to be_truthy # passes if obj is truthy (not nil or false) - expect(obj).to be_falsey # passes if obj is falsy (nil or false) - expect(obj).to be_nil # passes if obj is nil - expect(obj).to be # passes if obj is truthy (not nil or false) + expect(obj).to be_truthy # passes if obj is truthy (not nil or false) + expect(obj).to be_falsey # passes if obj is falsy (nil or false) + expect(obj).to be_nil # passes if obj is nil + expect(obj).to be # passes if obj is truthy (not nil or false) ``` Scenario: The `be_truthy` matcher diff --git a/features/built_in_matchers/be_within.feature b/features/built_in_matchers/be_within.feature index 9620c17d0..a5270325f 100644 --- a/features/built_in_matchers/be_within.feature +++ b/features/built_in_matchers/be_within.feature @@ -3,18 +3,20 @@ Feature: `be_within` matcher Normal equality expectations do not work well for floating point values. Consider this irb session: - > radius = 3 - => 3 - > area_of_circle = radius * radius * Math::PI - => 28.2743338823081 - > area_of_circle == 28.2743338823081 - => false + ```shell + > radius = 3 + => 3 + > area_of_circle = radius * radius * Math::PI + => 28.2743338823081 + > area_of_circle == 28.2743338823081 + => false + ``` Instead, you should use the `be_within` matcher to check that the value is within a delta of your expected value: ```ruby - expect(area_of_circle).to be_within(0.1).of(28.3) + expect(area_of_circle).to be_within(0.1).of(28.3) ``` Note that the difference between the actual and expected values must be smaller than your diff --git a/features/built_in_matchers/comparisons.feature b/features/built_in_matchers/comparisons.feature index 255a90936..af2753f9f 100644 --- a/features/built_in_matchers/comparisons.feature +++ b/features/built_in_matchers/comparisons.feature @@ -4,10 +4,10 @@ Feature: Comparison matchers can be used for generalized comparison of values. E.g. ```ruby - expect(9).to be > 6 - expect(3).to be <= 3 - expect(1).to be < 6 - expect('a').to be < 'b' + expect(9).to be > 6 + expect(3).to be <= 3 + expect(1).to be < 6 + expect('a').to be < 'b' ``` Scenario: Numeric operator matchers diff --git a/features/built_in_matchers/contain_exactly.feature b/features/built_in_matchers/contain_exactly.feature index 19fcf0374..4ba2e90a8 100644 --- a/features/built_in_matchers/contain_exactly.feature +++ b/features/built_in_matchers/contain_exactly.feature @@ -5,8 +5,8 @@ Feature: `contain_exactly` matcher For example: ```ruby - expect([1, 2, 3]).to contain_exactly(2, 3, 1) # pass - expect([:a, :c, :b]).to contain_exactly(:a, :c ) # fail + expect([1, 2, 3]).to contain_exactly(2, 3, 1) # pass + expect([:a, :c, :b]).to contain_exactly(:a, :c ) # fail ``` This matcher is also available as `match_array`, which expects the expected array to be @@ -14,8 +14,8 @@ Feature: `contain_exactly` matcher could also be written as: ```ruby - expect([1, 2, 3]).to match_array [2, 3, 1] # pass - expect([:a, :c, :b]).to match_array [:a, :c] # fail + expect([1, 2, 3]).to match_array [2, 3, 1] # pass + expect([:a, :c, :b]).to match_array [:a, :c] # fail ``` Scenario: Array is expected to contain every value diff --git a/features/built_in_matchers/cover.feature b/features/built_in_matchers/cover.feature index c0cc40496..d4ef0058c 100644 --- a/features/built_in_matchers/cover.feature +++ b/features/built_in_matchers/cover.feature @@ -6,9 +6,9 @@ Feature: `cover` matcher (such as a `Range`): ```ruby - expect(1..10).to cover(5) - expect(1..10).to cover(4, 6) - expect(1..10).not_to cover(11) + expect(1..10).to cover(5) + expect(1..10).to cover(4, 6) + expect(1..10).not_to cover(11) ``` Scenario: Range usage diff --git a/features/built_in_matchers/end_with.feature b/features/built_in_matchers/end_with.feature index abfc02d3c..688cf4d0e 100644 --- a/features/built_in_matchers/end_with.feature +++ b/features/built_in_matchers/end_with.feature @@ -4,9 +4,9 @@ Feature: `end_with` matcher characters or elements. ```ruby - expect("this string").to end_with "string" - expect("this string").not_to end_with "stringy" - expect([0, 1, 2]).to end_with 1, 2 + expect("this string").to end_with "string" + expect("this string").not_to end_with "stringy" + expect([0, 1, 2]).to end_with 1, 2 ``` Scenario: String usage diff --git a/features/built_in_matchers/equality.feature b/features/built_in_matchers/equality.feature index cd89ac529..513e35d3e 100644 --- a/features/built_in_matchers/equality.feature +++ b/features/built_in_matchers/equality.feature @@ -2,9 +2,11 @@ Feature: Equality matchers Ruby exposes several different methods for handling equality: - a.equal?(b) # object identity - a and b refer to the same object - a.eql?(b) # object equivalence - a and b have the same value - a == b # object equivalence - a and b have the same value with type conversions + ```ruby + a.equal?(b) # object identity - a and b refer to the same object + a.eql?(b) # object equivalence - a and b have the same value + a == b # object equivalence - a and b have the same value with type conversions + ``` Note that these descriptions are guidelines but are not forced by the language. Any object can implement any of these methods with its own semantics. @@ -12,16 +14,16 @@ Feature: Equality matchers rspec-expectations ships with matchers that align with each of these methods: ```ruby - expect(a).to equal(b) # passes if a.equal?(b) - expect(a).to eql(b) # passes if a.eql?(b) - expect(a).to be == b # passes if a == b + expect(a).to equal(b) # passes if a.equal?(b) + expect(a).to eql(b) # passes if a.eql?(b) + expect(a).to be == b # passes if a == b ``` It also ships with two matchers that have more of a DSL feel to them: ```ruby - expect(a).to be(b) # passes if a.equal?(b) - expect(a).to eq(b) # passes if a == b + expect(a).to be(b) # passes if a.equal?(b) + expect(a).to eq(b) # passes if a == b ``` Scenario: Compare using eq (==) diff --git a/features/built_in_matchers/exist.feature b/features/built_in_matchers/exist.feature index e290e7fd6..0df3717e2 100644 --- a/features/built_in_matchers/exist.feature +++ b/features/built_in_matchers/exist.feature @@ -3,7 +3,7 @@ Feature: `exist` matcher The `exist` matcher is used to specify that something exists (as indicated by `#exist?` or `#exists?`): ```ruby - expect(obj).to exist # passes if obj.exist? or obj.exists? + expect(obj).to exist # passes if obj.exist? or obj.exists? ``` Scenario: Basic usage diff --git a/features/built_in_matchers/have_attributes.feature b/features/built_in_matchers/have_attributes.feature index cf30b794d..f088532ed 100644 --- a/features/built_in_matchers/have_attributes.feature +++ b/features/built_in_matchers/have_attributes.feature @@ -3,17 +3,17 @@ Feature: `have_attributes` matcher Use the have_attributes matcher to specify that an object's attributes match the expected attributes: ```ruby - Person = Struct.new(:name, :age) - person = Person.new("Jim", 32) + Person = Struct.new(:name, :age) + person = Person.new("Jim", 32) - expect(person).to have_attributes(:name => "Jim", :age => 32) - expect(person).to have_attributes(:name => a_string_starting_with("J"), :age => (a_value > 30) ) + expect(person).to have_attributes(:name => "Jim", :age => 32) + expect(person).to have_attributes(:name => a_string_starting_with("J"), :age => (a_value > 30) ) ``` The matcher will fail if actual doesn't respond to any of the expected attributes: ```ruby - expect(person).to have_attributes(:name => "Jim", :color => 'red') + expect(person).to have_attributes(:name => "Jim", :color => 'red') ``` Scenario: Basic usage diff --git a/features/built_in_matchers/include.feature b/features/built_in_matchers/include.feature index 3c478df7f..d337b22a9 100644 --- a/features/built_in_matchers/include.feature +++ b/features/built_in_matchers/include.feature @@ -3,32 +3,32 @@ Feature: `include` matcher Use the `include` matcher to specify that a collection includes one or more expected objects. It succeeds if any object of the given collection passes the specified matcher. This works on any object that responds to `#include?` (such as a string or array): ```ruby - expect("a string").to include("a") - expect("a string").to include(/a|str/).twice - expect("a string").to include("str", "g") - expect("a string").not_to include("foo") + expect("a string").to include("a") + expect("a string").to include(/a|str/).twice + expect("a string").to include("str", "g") + expect("a string").not_to include("foo") - expect([1, 2]).to include(1) - expect([1, 2]).to include(1, 2) - expect([1, 2]).to include(a_kind_of(Integer)) - expect([1, 2]).to include(be_odd.and be < 10 ) - expect([1, 2]).to include(be_odd) - expect([1, 2]).to include(be < 10).at_least(2).times - expect([1, 2]).not_to include(17) + expect([1, 2]).to include(1) + expect([1, 2]).to include(1, 2) + expect([1, 2]).to include(a_kind_of(Integer)) + expect([1, 2]).to include(be_odd.and be < 10 ) + expect([1, 2]).to include(be_odd) + expect([1, 2]).to include(be < 10).at_least(2).times + expect([1, 2]).not_to include(17) ``` The matcher also provides flexible handling for hashes: ```ruby - expect(:a => 1, :b => 2).to include(:a) - expect(:a => 1, :b => 2).to include(:a, :b) - expect(:a => 1, :b => 2).to include(:a => 1) - expect(:a => 1, :b => 2).to include(:b => 2, :a => 1) - expect(:a => 1, :b => 2).to include(match(/b/) => 2) - expect(:a => 1, :b => 2).to include(match(/b/) => be_even) - expect(:a => 1, :b => 2).not_to include(:c) - expect(:a => 1, :b => 2).not_to include(:a => 2) - expect(:a => 1, :b => 2).not_to include(:c => 3) + expect(:a => 1, :b => 2).to include(:a) + expect(:a => 1, :b => 2).to include(:a, :b) + expect(:a => 1, :b => 2).to include(:a => 1) + expect(:a => 1, :b => 2).to include(:b => 2, :a => 1) + expect(:a => 1, :b => 2).to include(match(/b/) => 2) + expect(:a => 1, :b => 2).to include(match(/b/) => be_even) + expect(:a => 1, :b => 2).not_to include(:c) + expect(:a => 1, :b => 2).not_to include(:a => 2) + expect(:a => 1, :b => 2).not_to include(:c => 3) ``` Scenario: Array usage diff --git a/features/built_in_matchers/match.feature b/features/built_in_matchers/match.feature index 0cc0756ed..8c2705319 100644 --- a/features/built_in_matchers/match.feature +++ b/features/built_in_matchers/match.feature @@ -4,10 +4,10 @@ Feature: `match` matcher `false` or `nil`) value. `Regexp` and `String` both provide a `#match` method. ```ruby - expect("a string").to match(/str/) # passes - expect("a string").to match(/foo/) # fails - expect(/foo/).to match("food") # passes - expect(/foo/).to match("drinks") # fails + expect("a string").to match(/str/) # passes + expect("a string").to match(/foo/) # fails + expect(/foo/).to match("food") # passes + expect(/foo/).to match("drinks") # fails ``` You can also use this matcher to match nested data structures when composing matchers. diff --git a/features/built_in_matchers/predicates.feature b/features/built_in_matchers/predicates.feature index 2b974d463..0c3b33c5e 100644 --- a/features/built_in_matchers/predicates.feature +++ b/features/built_in_matchers/predicates.feature @@ -3,18 +3,18 @@ Feature: Predicate matchers Ruby objects commonly provide predicate methods: ```ruby - 7.zero? # => false - 0.zero? # => true - [1].empty? # => false - [].empty? # => true - { :a => 5 }.has_key?(:b) # => false - { :b => 5 }.has_key?(:b) # => true + 7.zero? # => false + 0.zero? # => true + [1].empty? # => false + [].empty? # => true + { :a => 5 }.has_key?(:b) # => false + { :b => 5 }.has_key?(:b) # => true ``` You could use a basic equality matcher to set expectations on these: ```ruby - expect(7.zero?).to eq true # fails with "expected true, got false (using ==)" + expect(7.zero?).to eq true # fails with "expected true, got false (using ==)" ``` ...but RSpec provides dynamic predicate matchers that are more readable and provide @@ -24,26 +24,26 @@ Feature: Predicate matchers method with `be_` and remove the question mark. Examples: ```ruby - expect(7).not_to be_zero # calls 7.zero? - expect([]).to be_empty # calls [].empty? - expect(x).to be_multiple_of(3) # calls x.multiple_of?(3) + expect(7).not_to be_zero # calls 7.zero? + expect([]).to be_empty # calls [].empty? + expect(x).to be_multiple_of(3) # calls x.multiple_of?(3) ``` Alternately, for a predicate method that begins with `has_` like `Hash#has_key?`, RSpec allows you to use an alternate form since `be_has_key` makes no sense. ```ruby - expect(hash).to have_key(:foo) # calls hash.has_key?(:foo) - expect(array).not_to have_odd_values # calls array.has_odd_values? + expect(hash).to have_key(:foo) # calls hash.has_key?(:foo) + expect(array).not_to have_odd_values # calls array.has_odd_values? ``` In either case, RSpec provides nice, clear error messages, such as: - `expected zero? to be truthy, got false` + `expected zero? to be truthy, got false` Calling private methods will also fail: - `expected private_method? to return true but it's a private method` + `expected private_method? to return true but it's a private method` Any arguments passed to the matcher will be passed on to the predicate method. diff --git a/features/built_in_matchers/raise_error.feature b/features/built_in_matchers/raise_error.feature index 0d4d74dad..5eb18ad68 100644 --- a/features/built_in_matchers/raise_error.feature +++ b/features/built_in_matchers/raise_error.feature @@ -4,13 +4,13 @@ Feature: `raise_error` matcher basic form passes if any error is thrown: ```ruby - expect { raise StandardError }.to raise_error + expect { raise StandardError }.to raise_error ``` You can use `raise_exception` instead if you prefer that wording: ```ruby - expect { 3 / 0 }.to raise_exception + expect { 3 / 0 }.to raise_exception ``` `raise_error` and `raise_exception` are functionally interchangeable, so use the one that @@ -20,13 +20,13 @@ Feature: `raise_error` matcher error/exception: ```ruby - expect { raise "oops" }.to raise_error - expect { raise "oops" }.to raise_error(RuntimeError) - expect { raise "oops" }.to raise_error("oops") - expect { raise "oops" }.to raise_error(/op/) - expect { raise "oops" }.to raise_error(RuntimeError, "oops") - expect { raise "oops" }.to raise_error(RuntimeError, /op/) - expect { raise "oops" }.to raise_error(an_instance_of(RuntimeError).and having_attributes(message: "oops")) + expect { raise "oops" }.to raise_error + expect { raise "oops" }.to raise_error(RuntimeError) + expect { raise "oops" }.to raise_error("oops") + expect { raise "oops" }.to raise_error(/op/) + expect { raise "oops" }.to raise_error(RuntimeError, "oops") + expect { raise "oops" }.to raise_error(RuntimeError, /op/) + expect { raise "oops" }.to raise_error(an_instance_of(RuntimeError).and having_attributes(message: "oops")) ``` Scenario: Expecting any error diff --git a/features/built_in_matchers/respond_to.feature b/features/built_in_matchers/respond_to.feature index 90484daf5..f3d370743 100644 --- a/features/built_in_matchers/respond_to.feature +++ b/features/built_in_matchers/respond_to.feature @@ -3,33 +3,33 @@ Feature: `respond_to` matcher Use the `respond_to` matcher to specify details of an object's interface. In its most basic form: ```ruby - expect(obj).to respond_to(:foo) # pass if obj.respond_to?(:foo) + expect(obj).to respond_to(:foo) # pass if obj.respond_to?(:foo) ``` You can specify that an object responds to multiple messages in a single statement with multiple arguments passed to the matcher: ```ruby - expect(obj).to respond_to(:foo, :bar) # passes if obj.respond_to?(:foo) && obj.respond_to?(:bar) + expect(obj).to respond_to(:foo, :bar) # passes if obj.respond_to?(:foo) && obj.respond_to?(:bar) ``` If the number of arguments accepted by the method is important to you, you can specify that as well: ```ruby - expect(obj).to respond_to(:foo).with(1).argument - expect(obj).to respond_to(:bar).with(2).arguments - expect(obj).to respond_to(:baz).with(1..2).arguments - expect(obj).to respond_to(:xyz).with_unlimited_arguments + expect(obj).to respond_to(:foo).with(1).argument + expect(obj).to respond_to(:bar).with(2).arguments + expect(obj).to respond_to(:baz).with(1..2).arguments + expect(obj).to respond_to(:xyz).with_unlimited_arguments ``` If your Ruby version supports keyword arguments, you can specify a list of keywords accepted by the method. ```ruby - expect(obj).to respond_to(:foo).with_keywords(:ichi, :ni) - expect(obj).to respond_to(:bar).with(2).arguments.and_keywords(:san, :yon) - expect(obj).to respond_to(:baz).with_arbitrary_keywords + expect(obj).to respond_to(:foo).with_keywords(:ichi, :ni) + expect(obj).to respond_to(:bar).with(2).arguments.and_keywords(:san, :yon) + expect(obj).to respond_to(:baz).with_arbitrary_keywords ``` Note that this matcher relies entirely upon `#respond_to?`. If an object dynamically responds diff --git a/features/built_in_matchers/satisfy.feature b/features/built_in_matchers/satisfy.feature index b7ccacfb8..6aeab01b2 100644 --- a/features/built_in_matchers/satisfy.feature +++ b/features/built_in_matchers/satisfy.feature @@ -4,17 +4,17 @@ Feature: `satisfy` matcher specify. It passes if the block you provide returns true: ```ruby - expect(10).to satisfy { |v| v % 5 == 0 } - expect(7).not_to satisfy { |v| v % 5 == 0 } + expect(10).to satisfy { |v| v % 5 == 0 } + expect(7).not_to satisfy { |v| v % 5 == 0 } ``` The default failure message ("expected [actual] to satisfy block") is not very descriptive or helpful. To add clarification, you can provide your own description as an argument: ```ruby - expect(10).to satisfy("be a multiple of 5") do |v| - v % 5 == 0 - end + expect(10).to satisfy("be a multiple of 5") do |v| + v % 5 == 0 + end ``` @skip-when-ripper-unsupported diff --git a/features/built_in_matchers/start_with.feature b/features/built_in_matchers/start_with.feature index 86c29ff92..cfdcd86f7 100644 --- a/features/built_in_matchers/start_with.feature +++ b/features/built_in_matchers/start_with.feature @@ -4,9 +4,9 @@ Feature: `start_with` matcher characters or elements. ```ruby - expect("this string").to start_with("this") - expect("this string").not_to start_with("that") - expect([0,1,2]).to start_with(0, 1) + expect("this string").to start_with("this") + expect("this string").not_to start_with("that") + expect([0,1,2]).to start_with(0, 1) ``` Scenario: With a string diff --git a/features/built_in_matchers/throw_symbol.feature b/features/built_in_matchers/throw_symbol.feature index c6671c94e..7ded193f5 100644 --- a/features/built_in_matchers/throw_symbol.feature +++ b/features/built_in_matchers/throw_symbol.feature @@ -4,19 +4,19 @@ Feature: `throw_symbol` matcher basic form passes if any symbol is thrown: ```ruby - expect { throw :foo }.to throw_symbol + expect { throw :foo }.to throw_symbol ``` You'll often want to specify that a particular symbol is thrown: ```ruby - expect { throw :foo }.to throw_symbol(:foo) + expect { throw :foo }.to throw_symbol(:foo) ``` If you care about the additional argument given to throw, you can specify that as well: ```ruby - expect { throw :foo, 7 }.to throw_symbol(:foo, 7) + expect { throw :foo, 7 }.to throw_symbol(:foo, 7) ``` Scenario: Basic usage diff --git a/features/built_in_matchers/types.feature b/features/built_in_matchers/types.feature index 841945cc5..bfa086061 100644 --- a/features/built_in_matchers/types.feature +++ b/features/built_in_matchers/types.feature @@ -2,19 +2,19 @@ Feature: Type matchers rspec-expectations includes two matchers to specify types of objects: - * `expect(obj).to be_kind_of(type)`: calls `obj.kind_of?(type)`, which returns true if - type is in obj's class hierarchy or is a module and is included in a class in obj's - class hierarchy. - * `expect(obj).to be_instance_of(type)`: calls `obj.instance_of?(type)`, which returns - true if and only if type if obj's class. + * `expect(obj).to be_kind_of(type)`: calls `obj.kind_of?(type)`, which returns true if + type is in obj's class hierarchy or is a module and is included in a class in obj's + class hierarchy. + * `expect(obj).to be_instance_of(type)`: calls `obj.instance_of?(type)`, which returns + true if and only if type if obj's class. Both of these matchers have aliases: ```ruby - expect(obj).to be_a_kind_of(type) # same as expect(obj).to be_kind_of(type) - expect(obj).to be_a(type) # same as expect(obj).to be_kind_of(type) - expect(obj).to be_an(type) # same as expect(obj).to be_kind_of(type) - expect(obj).to be_an_instance_of(type) # same as expect(obj).to be_instance_of(type) + expect(obj).to be_a_kind_of(type) # same as expect(obj).to be_kind_of(type) + expect(obj).to be_a(type) # same as expect(obj).to be_kind_of(type) + expect(obj).to be_an(type) # same as expect(obj).to be_kind_of(type) + expect(obj).to be_an_instance_of(type) # same as expect(obj).to be_instance_of(type) ``` Scenario: With `be_(a_)kind_of` matcher diff --git a/features/built_in_matchers/yield.feature b/features/built_in_matchers/yield.feature index 67ec15989..78199f41c 100644 --- a/features/built_in_matchers/yield.feature +++ b/features/built_in_matchers/yield.feature @@ -4,13 +4,13 @@ Feature: `yield` matchers how many times it yields, whether or not it yields with arguments, and what those arguments are. - * `yield_control` matches if the method-under-test yields, regardless of whether or not - arguments are yielded. - * `yield_with_args` matches if the method-under-test yields with arguments. If arguments - are provided to this matcher, it will only pass if the actual yielded arguments match the expected ones using `===` or `==`. - * `yield_with_no_args` matches if the method-under-test yields with no arguments. - * `yield_successive_args` is designed for iterators, and will match if the method-under-test - yields the same number of times as arguments passed to this matcher, and all actual yielded arguments match the expected ones using `===` or `==`. + * `yield_control` matches if the method-under-test yields, regardless of whether or not + arguments are yielded. + * `yield_with_args` matches if the method-under-test yields with arguments. If arguments + are provided to this matcher, it will only pass if the actual yielded arguments match the expected ones using `===` or `==`. + * `yield_with_no_args` matches if the method-under-test yields with no arguments. + * `yield_successive_args` is designed for iterators, and will match if the method-under-test + yields the same number of times as arguments passed to this matcher, and all actual yielded arguments match the expected ones using `===` or `==`. Note: your expect block _must_ accept an argument that is then passed on to the method-under-test as a block. This acts as a "probe" that allows the matcher to detect diff --git a/features/custom_matchers/define_matcher.feature b/features/custom_matchers/define_matcher.feature index 47d6352fc..aadb0dced 100644 --- a/features/custom_matchers/define_matcher.feature +++ b/features/custom_matchers/define_matcher.feature @@ -1,6 +1,6 @@ Feature: Defining a custom matcher - rspec-expectations provides a DSL for defining custom matchers. These are often useful for expressing expectations in the domain of your application. + `rspec-expectations` provides a DSL for defining custom matchers. These are often useful for expressing expectations in the domain of your application. Behind the scenes `RSpec::Matchers.define` evaluates the `define` block in the context of a singleton class. If you need to write a more complex matcher and would like to use the `Class`-approach yourself, please head over to our `API`-documentation and read [the docs](http://rspec.info/documentation/latest/rspec-expectations/RSpec/Matchers/MatcherProtocol.html) about the `MatcherProtocol`. diff --git a/features/custom_matchers/define_matcher_outside_rspec.feature b/features/custom_matchers/define_matcher_outside_rspec.feature index 7025283cc..86be88332 100644 --- a/features/custom_matchers/define_matcher_outside_rspec.feature +++ b/features/custom_matchers/define_matcher_outside_rspec.feature @@ -15,7 +15,6 @@ Feature: Defining a matcher outside rspec end class TestMultiples < Minitest::Test - def test_9_should_be_a_multiple_of_3 expect(9).to be_a_multiple_of(3) end @@ -23,7 +22,6 @@ Feature: Defining a matcher outside rspec def test_9_should_be_a_multiple_of_4 expect(9).to be_a_multiple_of(4) end - end """ When I run `ruby test_multiples.rb` diff --git a/features/customized_message.feature b/features/customized_message.feature index d66f9ebce..960dbeb72 100644 --- a/features/customized_message.feature +++ b/features/customized_message.feature @@ -16,7 +16,6 @@ Feature: Customized message end end end - """ When I run `rspec example_spec.rb --format documentation` Then the output should contain "expected empty array, got [1]" @@ -33,7 +32,6 @@ Feature: Customized message end end end - """ When I run `rspec example_spec.rb --format documentation` Then the output should contain "expected empty array, got [1]"