Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail Include matcher when comparing String with non-String #1449

Closed
wants to merge 1 commit into from

Conversation

naveg
Copy link

@naveg naveg commented Feb 1, 2024

If the actual is a String and the expected is not, a TypeError occurs
when we try to call actual.include?, becuase this method expects
a String when called on a String.

If the actual is a String and the expected is not, then the match
can't possibly succeed and we can return early.

If the actual is a String and the expected is not, a `TypeError` occurs
when we try to call `actual.include?`, becuase this method expects
a String when called on a String.

If the actual is a `String` and the expected is not, then the match
can't possibly succeed and we can return early.
naveg added a commit to naveg/rspec-rails that referenced this pull request Feb 2, 2024
In rspec/rspec-expectations#1449, the `Include`
matcher is fixed so that it doesn't raise an error when types don't
match. Instead, the actual and expected will be deemed to not match.
@naveg
Copy link
Author

naveg commented Feb 2, 2024

@pirj the build appears to be failing because tests that are part of rspec-rails are documenting the error that this PR fixes

we probably also want rspec/rspec-rails#2728, but I'm not sure how to best sync up the two changes

Copy link
Member

@pirj pirj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!
Let's safeguard rspec-rails's suite from failures, and this is good to merge.

Copy link
Member

@JonRowe JonRowe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking the time to submit this but I'm leaning towards closing this, Ruby already fails this test for us with a helpful type error, so actually this removes information from the failure, additionally if someone were to monkey patch or refine String to allow include? to match against other things this would break that...

(Requesting changes to block merging here until I'm convinced)

@naveg
Copy link
Author

naveg commented Feb 5, 2024

@JonRowe just invert the matcher to see why this is a bug in rspec:

expect("foo").not_to include({:bar => "baz"})

I think this example should pass, but it currently explodes with an error.

@JonRowe
Copy link
Member

JonRowe commented Feb 5, 2024

I'd actually expect an error, you're matching two incompatible objects its actually a false positive for that to pass... imagine a scenario where you're gating on using the include? call, you write a test to assert that some input would cause your code to reject it and your example passes, but in production it would raise

@JonRowe
Copy link
Member

JonRowe commented Feb 5, 2024

Thank you for the example, its actually pushed me over the fence; I'm going to close this because the false positive of this passing a negation is too much of a behaviour change, your example should fail because a production usage of that would cause an exception.

@JonRowe JonRowe closed this Feb 5, 2024
@naveg
Copy link
Author

naveg commented Feb 5, 2024

@JonRowe I disagree, but it's your call. We'll just have to work around this behavior in our tests.

Ruby is dynamically typed, and checking for inclusion in a test does not imply that we test for inclusion in production code. We are simply asserting something about the shape of the value.

Here's another example that also explodes with the same error:

expect(["foo", {:bar => "baz"}]).to include(a_hash_including({:bar => "baz"}))

@JonRowe
Copy link
Member

JonRowe commented Feb 5, 2024

I respect your different opinion but I have to think of everyones usage and in particular the potential for the harm a false positive causes vs having to catch the error explicitly, I can appreciate its annoying to have to assert on an error vs to_not include but its explicit vs silent; In general we don't prevent Ruby errors from happening because we want to respect Ruby idioms.

Once again I thank you for taking the time to contribute and discuss this and I'm sorry we can't include this on this occasion.

@naveg naveg deleted the include-string branch February 5, 2024 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants