You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
What should happen when you use an anything fuzzy matcher inside a Hash on your specs? #241
I've opened a PR in rspec-support with a hacky fix to the problem you get when you compare an actual hash with a expected hash and they differ, but the expected hash includes some values whose values correspond to the anything matcher.
My PR contains some tests showing the failure and the fix. But the code changes I've made on the rspec differ engine is trivial:
Navigate the expected hash and retrieve all keys you must dig in that hash in order to find values that are anything fuzzy matcher.
Use these keys to fetch the data on the actual hash, and replace the anything values on your expected hash by the values you fetched on the actual hash.
Later, when the diff string is generated, with the morph you made on the expected var on step (2), the diff string will NOT calculate the diff on the key-value pairs you had before the anything fuzzy matcher. The result is you will have a clean diff showing you only the right values that differ and you are interested in.
I'd like to implement this behavior on super_diff, but I know my proposal may be hacky. What are your thoughts about it? Any feedback is appreciated.
I am reading your specs and the source code of super_differ, I'm looking forward to collaborate here or in rspec-support, because diffs is a topic that I found very interesting.
Hi @KarlHeitmann! I've taken a look at your PR over on rspec-support and I think the behavior you demonstrate in the tests there make sense to me. I don't believe that super_diff handles anything yet, but I also think there's a way to implement it here without hacks. I can give you some pointers if you need help.
Hey @mcmire ! Thank you! I'll implement anything handle in your project this week or next week. I took a sneak peak at your tests and understand how you are writing them. I also need to know in which Differ I should implement the anything handle.... I'll explore it the next days in my spare time and I'll let you know how the progress will be going on.
Hey @mcmire ! I wanted to catch up / update my status.
I've read your guides and now I have a slightly better understanding of RSpec. I've noted you wrote some specs about fuzzy finding, but you wrote these examples using the include matcher. I've had problems with the match matcher instead, and that's what I am trying to fix. (eg: expect(actual).to match(expected)). Here is the example I found on the source code: https://github.com/mcmire/super_diff/blob/92253b57854d36bd27fdb3c370fdb45df26c608f/spec/integration/rspec/include_matcher_spec.rb#L266 I wrote a similar example on my local machine, but I'm using match instead of include matcher.
Do you have any tips to debug the source code? Since you are running the examples inside a TestPrograms::Plain class wrapper, it is difficult to put a binding.pry to tinker with the variables and understand what is happening there. I discovered some of your wrapper classes write a temporary file ./tmp/integration_spec.rb that I can run with this command: bin/rspec tmp/integration_spec.rb. This way, it is easier to write a binding.pry statement. Do you also use this method to debug the source code? Or do you have another way / trick to do it?
I understand there are integration tests and unit tests. The integration tests are "end to end", I mean: on one end you've got the input data (ie: the variables you want to diff) and you check the right output data (ie: the diff string) at the other end.
To me, integration tests are great to start looking under the hood of a project. Because there I've got the overview of what is happening. But right now, I am thinking to myself that ~ maybe ~ it is a good idea to tackle this issue by starting with a unit test, because I ~ believe ~ my code change should be small. What do you think? It is a good or bad idea to fix the issue by working on a unit? I think there is a good chance I may be underestimating the issue.
I grepped the source code with: rg TieredLinesFormatter spec/unit/ (TieredLinesFormatter is one of the classes involved with my issue) and found only one relevant match: https://github.com/mcmire/super_diff/blob/92253b57854d36bd27fdb3c370fdb45df26c608f/spec/unit/core/tiered_lines_formatter_spec.rb#L4 , and there is only one test there. I've also grepped to_diff inside the spec/unit/ folder and found no matches at all. What does this result means? My conclusion is that even though #to_diff methods are ~ important ~ and they are defined and used in AbstractDiffer and AbstractOperationTree classes, they don't have any unit test at all either because there is some meta programming going on, or because they involve multiple layers of different classes interacting with each other that it is only worth test the to_diff method with integration. Am I right or wrong with this statement?
Hi @KarlHeitmann , apologies for the long delay! And thanks for your investigation.
Sounds like issue you've found is that when RSpec has found the expected and actual to be different, SuperDiff doesn't fuzzy-match the values in all cases, which produces a misleading diff. This is actually a problem for a lot of RSpec matchers, not just anything. Please let me know if you're still interested in working on a fix and I'll leave it for you. 🙂
Re: test strategy
As you've found, the integration tests are harder to debug, since they capture output and run on generated test files. If you're just trying to identify how RSpec + SuperDiff will work, you can start with a temporary test file (I use spec/scratch_spec.rb) and run it directly with bin/rspec ... or bundle exec appraisal <appraisal_name> rspec .... For the behavior you're testing, you can try something like this out:
require'super_diff/rspec'RSpec.describe'superdiff'doit'does something I expect'doexpect({a: 1}).tomatch({a: anything})endend
From there, once you've identified a spec that tests the exact behaviors you want, you can turn it into an integration test to automate it.
Re: code starting point
I don't believe you'll need to touch the TieredLinesFormatter or anything else in SuperDiff::Core to fix this problem. You should only need to touch these structures:
The operation tree builders, which produce the basis of a diff: a tree of operations that would turn the actual value into the expected value
The differs, which determine which operation tree builder to use given particular expected and actual values
Activity
mcmire commentedon Apr 25, 2024
Hi @KarlHeitmann! I've taken a look at your PR over on
rspec-supportand I think the behavior you demonstrate in the tests there make sense to me. I don't believe thatsuper_diffhandlesanythingyet, but I also think there's a way to implement it here without hacks. I can give you some pointers if you need help.KarlHeitmann commentedon Apr 25, 2024
Hey @mcmire ! Thank you! I'll implement
anythinghandle in your project this week or next week. I took a sneak peak at your tests and understand how you are writing them. I also need to know in which Differ I should implement theanythinghandle.... I'll explore it the next days in my spare time and I'll let you know how the progress will be going on.See you later!
KarlHeitmann commentedon Apr 30, 2024
Hey @mcmire ! I wanted to catch up / update my status.
I've read your guides and now I have a slightly better understanding of RSpec. I've noted you wrote some specs about fuzzy finding, but you wrote these examples using the
includematcher. I've had problems with thematchmatcher instead, and that's what I am trying to fix. (eg:expect(actual).to match(expected)). Here is the example I found on the source code: https://github.com/mcmire/super_diff/blob/92253b57854d36bd27fdb3c370fdb45df26c608f/spec/integration/rspec/include_matcher_spec.rb#L266 I wrote a similar example on my local machine, but I'm usingmatchinstead ofincludematcher.Do you have any tips to debug the source code? Since you are running the examples inside a
TestPrograms::Plainclass wrapper, it is difficult to put abinding.pryto tinker with the variables and understand what is happening there. I discovered some of your wrapper classes write a temporary file./tmp/integration_spec.rbthat I can run with this command:bin/rspec tmp/integration_spec.rb. This way, it is easier to write abinding.prystatement. Do you also use this method to debug the source code? Or do you have another way / trick to do it?I understand there are integration tests and unit tests. The integration tests are "end to end", I mean: on one end you've got the input data (ie: the variables you want to diff) and you check the right output data (ie: the diff string) at the other end.
To me, integration tests are great to start looking under the hood of a project. Because there I've got the overview of what is happening. But right now, I am thinking to myself that ~ maybe ~ it is a good idea to tackle this issue by starting with a unit test, because I ~ believe ~ my code change should be small. What do you think? It is a good or bad idea to fix the issue by working on a unit? I think there is a good chance I may be underestimating the issue.
I grepped the source code with:
rg TieredLinesFormatter spec/unit/(TieredLinesFormatteris one of the classes involved with my issue) and found only one relevant match: https://github.com/mcmire/super_diff/blob/92253b57854d36bd27fdb3c370fdb45df26c608f/spec/unit/core/tiered_lines_formatter_spec.rb#L4 , and there is only one test there. I've also greppedto_diffinside thespec/unit/folder and found no matches at all. What does this result means? My conclusion is that even though#to_diffmethods are ~ important ~ and they are defined and used inAbstractDifferandAbstractOperationTreeclasses, they don't have any unit test at all either because there is some meta programming going on, or because they involve multiple layers of different classes interacting with each other that it is only worth test theto_diffmethod with integration. Am I right or wrong with this statement?jas14 commentedon Dec 5, 2025
Hi @KarlHeitmann , apologies for the long delay! And thanks for your investigation.
Sounds like issue you've found is that when RSpec has found the
expectedandactualto be different, SuperDiff doesn't fuzzy-match the values in all cases, which produces a misleading diff. This is actually a problem for a lot of RSpec matchers, not justanything. Please let me know if you're still interested in working on a fix and I'll leave it for you. 🙂Re: test strategy
As you've found, the integration tests are harder to debug, since they capture output and run on generated test files. If you're just trying to identify how RSpec + SuperDiff will work, you can start with a temporary test file (I use
spec/scratch_spec.rb) and run it directly withbin/rspec ...orbundle exec appraisal <appraisal_name> rspec .... For the behavior you're testing, you can try something like this out:From there, once you've identified a spec that tests the exact behaviors you want, you can turn it into an integration test to automate it.
Re: code starting point
I don't believe you'll need to touch the
TieredLinesFormatteror anything else inSuperDiff::Coreto fix this problem. You should only need to touch these structures:actualvalue into theexpectedvalueexpectedandactualvaluesCheck out
RSpec::Differs::HashIncluding. The structure of that differ will likely inform the solution here!