diff --git a/lib/rspec/matchers/built_in/have.rb b/lib/rspec/matchers/built_in/have.rb index b7ab6eab3..234c3e9d9 100644 --- a/lib/rspec/matchers/built_in/have.rb +++ b/lib/rspec/matchers/built_in/have.rb @@ -143,9 +143,21 @@ def print_deprecation_message(query_method) deprecation_message = "the rspec-collection_matchers gem " deprecation_message << "or replace your expectation with something like " - deprecation_message << "`expect(#{cardinality_expression(query_method)}).#{expectation_format_method} #{matcher_expression}`" + deprecation_message << "`expect(#{cardinality_expression(query_method)}).#{expectation_format_method} #{suggested_matcher_expression}`" - RSpec.deprecate("`#{matcher_method}`", :replacement => deprecation_message) + RSpec.deprecate("`#{expectation_expression(query_method)}`", :replacement => deprecation_message) + end + + def expectation_expression(query_method) + if @negative_expectation + RSpec::Expectations::Syntax.negative_expression('your_object', original_matcher_expression) + else + RSpec::Expectations::Syntax.positive_expression('your_object', original_matcher_expression) + end + end + + def original_matcher_expression + "#{matcher_method}(#{@expected}).#{@collection_name}" end def expectation_format_method @@ -162,15 +174,15 @@ def cardinality_expression(query_method) expression << String(query_method) end - def matcher_expression - send("matcher_expression_for_#{@relativity}") + def suggested_matcher_expression + send("suggested_matcher_expression_for_#{@relativity}") end - def matcher_expression_for_exactly + def suggested_matcher_expression_for_exactly "eq(#{@expected})" end - def matcher_expression_for_at_most + def suggested_matcher_expression_for_at_most if @negative_expectation "be > #{@expected}" else @@ -178,7 +190,7 @@ def matcher_expression_for_at_most end end - def matcher_expression_for_at_least + def suggested_matcher_expression_for_at_least if @negative_expectation "be < #{@expected}" else diff --git a/spec/rspec/matchers/have_spec.rb b/spec/rspec/matchers/have_spec.rb index 5fe8c8b3f..07b16aab9 100644 --- a/spec/rspec/matchers/have_spec.rb +++ b/spec/rspec/matchers/have_spec.rb @@ -464,21 +464,25 @@ def array.send; :sent; end context "when the target is a collection" do it "prints a specific message for the positive expectation format" do + expectation_expression = "expect(your_object).to have(3).items" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.size).to eq(3)`" - expect(RSpec).to receive(:deprecate).with("`have`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) expect([1, 2, 3]).to have(3).items end it "prints a specific message for the negative expectation format" do + expectation_expression = "expect(your_object).not_to have(4).items" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.size).to_not eq(4)`" - expect(RSpec).to receive(:deprecate).with("`have`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) expect([1, 2, 3]).to_not have(4).items end @@ -494,22 +498,26 @@ def initialize(words) end it "prints a specific message for the positive expectation format" do + expectation_expression = "expect(your_object).to have(3).words" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.words.size).to eq(3)`" - expect(RSpec).to receive(:deprecate).with("`have`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) target = BagOfWords.new(%w[foo bar baz]) expect(target).to have(3).words end it "prints a specific message for the negative expectation format" do + expectation_expression = "expect(your_object).not_to have(4).words" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.words.size).to_not eq(4)`" - expect(RSpec).to receive(:deprecate).with("`have`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) target = BagOfWords.new(%w[foo bar baz]) expect(target).to_not have(4).words @@ -519,22 +527,28 @@ def initialize(words) context "when the target is an enumerator" do it "prints a specific message for the positive expectation format" do target = %w[a b c].to_enum(:each) + + expectation_expression = "expect(your_object).to have(3).letters" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.count).to eq(3)`" - expect(RSpec).to receive(:deprecate).with("`have`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) expect(target).to have(3).letters end it "prints a specific message for the negative expectation format" do target = %w[a b c].to_enum(:each) + + expectation_expression = "expect(your_object).not_to have(4).letters" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.count).to_not eq(4)`" - expect(RSpec).to receive(:deprecate).with("`have`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) expect(target).to_not have(4).letters end @@ -552,21 +566,25 @@ def initialize(words) context "when the target is a collection" do it "prints a specific message for the positive expectation format" do + expectation_expression = "expect(your_object).to have_at_most(3).items" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.size).to be <= 3`" - expect(RSpec).to receive(:deprecate).with("`have_at_most`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) expect([1, 2, 3]).to have_at_most(3).items end it "prints a specific message for the negative expectation format" do + expectation_expression = "expect(your_object).not_to have_at_most(2).items" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.size).to be > 2`" - expect(RSpec).to receive(:deprecate).with("`have_at_most`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) expect([1, 2, 3]).to_not have_at_most(2).items end @@ -582,22 +600,26 @@ def initialize(words) end it "prints a specific message for the positive expectation format" do + expectation_expression = "expect(your_object).to have_at_most(3).words" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.words.size).to be <= 3`" - expect(RSpec).to receive(:deprecate).with("`have_at_most`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) target = BagOfWords.new(%w[foo bar baz]) expect(target).to have_at_most(3).words end it "prints a specific message for the negative expectation format" do + expectation_expression = "expect(your_object).not_to have_at_most(2).words" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.words.size).to be > 2`" - expect(RSpec).to receive(:deprecate).with("`have_at_most`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) target = BagOfWords.new(%w[foo bar baz]) expect(target).to_not have_at_most(2).words @@ -607,22 +629,28 @@ def initialize(words) context "when the target is an enumerator" do it "prints a specific message for the positive expectation format" do target = %w[a b c].to_enum(:each) + + expectation_expression = "expect(your_object).to have_at_most(3).letters" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.count).to be <= 3`" - expect(RSpec).to receive(:deprecate).with("`have_at_most`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) expect(target).to have_at_most(3).letters end it "prints a specific message for the negative expectation format" do target = %w[a b c].to_enum(:each) + + expectation_expression = "expect(your_object).not_to have_at_most(2).letters" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.count).to be > 2`" - expect(RSpec).to receive(:deprecate).with("`have_at_most`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) expect(target).to_not have_at_most(2).letters end @@ -640,21 +668,25 @@ def initialize(words) context "when the target is a collection" do it "prints a specific message for the positive expectation format" do + expectation_expression = "expect(your_object).to have_at_least(3).items" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.size).to be >= 3`" - expect(RSpec).to receive(:deprecate).with("`have_at_least`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) expect([1, 2, 3]).to have_at_least(3).items end it "prints a specific message for the negative expectation format" do + expectation_expression = "expect(your_object).not_to have_at_least(4).items" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.size).to be < 4`" - expect(RSpec).to receive(:deprecate).with("`have_at_least`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) expect([1, 2, 3]).to_not have_at_least(4).items end @@ -670,22 +702,26 @@ def initialize(words) end it "prints a specific message for the positive expectation format" do + expectation_expression = "expect(your_object).to have_at_least(3).words" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.words.size).to be >= 3`" - expect(RSpec).to receive(:deprecate).with("`have_at_least`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) target = BagOfWords.new(%w[foo bar baz]) expect(target).to have_at_least(3).words end it "prints a specific message for the negative expectation format" do + expectation_expression = "expect(your_object).not_to have_at_least(4).words" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.words.size).to be < 4`" - expect(RSpec).to receive(:deprecate).with("`have_at_least`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) target = BagOfWords.new(%w[foo bar baz]) expect(target).to_not have_at_least(4).words @@ -695,22 +731,28 @@ def initialize(words) context "when the target is an enumerator" do it "prints a specific message for the positive expectation format" do target = %w[a b c].to_enum(:each) + + expectation_expression = "expect(your_object).to have_at_least(3).letters" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.count).to be >= 3`" - expect(RSpec).to receive(:deprecate).with("`have_at_least`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) expect(target).to have_at_least(3).letters end it "prints a specific message for the negative expectation format" do target = %w[a b c].to_enum(:each) + + expectation_expression = "expect(your_object).not_to have_at_least(4).letters" + message = "the rspec-collection_matchers gem " + "or replace your expectation with something like " + "`expect(your_object.count).to be < 4`" - expect(RSpec).to receive(:deprecate).with("`have_at_least`", :replacement => message) + expect(RSpec).to receive(:deprecate).with("`#{expectation_expression}`", :replacement => message) expect(target).to_not have_at_least(4).letters end