Skip to content

Commit

Permalink
fixup! Suggest a replacement for unstrict predicate matchers
Browse files Browse the repository at this point in the history
We could suggest `expect(subject.predicate?).to eq("bar")`, but it will
make the spec too specific.
  • Loading branch information
pirj committed Jul 24, 2021
1 parent 7d6ff58 commit 4fd9b36
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 12 deletions.
3 changes: 2 additions & 1 deletion lib/rspec/matchers/built_in/has.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ def predicate_matches?(value=true)
predicate_actual = predicate_result
if value == !!predicate_actual && value != predicate_actual
RSpec.deprecate(
"`#{predicate_method_name}` returned neither `true` nor `false`, but rather `#{predicate_actual.inspect}`")
"`#{predicate_method_name}` returned neither `true` nor `false`, but rather `#{predicate_actual.inspect}`",
:replacement => "`expect(subject.#{predicate_method_name}).to #{value ? "be_truthy" : "be_falsey"}`")
end
value == !!predicate_actual
end
Expand Down
21 changes: 16 additions & 5 deletions spec/rspec/matchers/built_in/be_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,22 @@
}.to fail_with("expected `#{actual.inspect}.happy?` to be truthy, got false")
end

it "prints a deprecation warning" do
expect(RSpec).
to receive(:deprecate).
with("`infinite?` returned neither `true` nor `false`, but rather `-1`")
expect(-Float::INFINITY).to be_infinite
context "when the predicate neither returns true or false" do
it "prints a deprecation warning when actual is truthy" do
expect(RSpec).
to receive(:deprecate).
with("`infinite?` returned neither `true` nor `false`, but rather `-1`",
:replacement => "`expect(subject.infinite?).to be_truthy`")
expect(-Float::INFINITY).to be_infinite
end

it "prints a deprecation warning when actual is truthy" do
expect(RSpec).
to receive(:deprecate).
with("`infinite?` returned neither `true` nor `false`, but rather `nil`",
:replacement => "`expect(subject.infinite?).to be_falsey`")
expect(1).to_not be_infinite
end
end
end

Expand Down
24 changes: 18 additions & 6 deletions spec/rspec/matchers/built_in/has_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,24 @@ def o.has_sym?(sym); sym == :foo; end
expect(actual).not_to have_foo
end

it "prints a deprecation warning" do
expect(RSpec).
to receive(:deprecate).
with("`has_foo?` returned neither `true` nor `false`, but rather `nil`")
actual = double("actual", :has_foo? => nil)
expect(actual).not_to have_foo
context "when the predicate neither returns true or false" do
it "prints a deprecation warning when actual is falsey" do
expect(RSpec).
to receive(:deprecate).
with("`has_foo?` returned neither `true` nor `false`, but rather `nil`",
:replacement => "`expect(subject.has_foo?).to be_falsey`")
actual = double("actual", :has_foo? => nil)
expect(actual).not_to have_foo
end

it "prints a deprecation warning when actual is truthy" do
expect(RSpec).
to receive(:deprecate).
with('`has_foo?` returned neither `true` nor `false`, but rather `"bar"`',
:replacement => "`expect(subject.has_foo?).to be_truthy`")
actual = double("actual", :has_foo? => "bar")
expect(actual).to have_foo
end
end
end

Expand Down

0 comments on commit 4fd9b36

Please sign in to comment.