When I run rspec spec/path_to_some_file_spec.rb
and I have made a typo I get a load error that repeats the incorrect path to the file and a stack trace. Is there any interest in me (or someone else) doing pull request for a feature like 'did_you_mean' in ruby. This way, the error would be something like
cannot load file 'spec/path_to_some_filexxx_spec.rb'. Did you mean one of the following:
spec/path_to_some_file_spec.rb
spec/path_to_some_other_file_spec.rb
Then instead of scanning the line I typed in to find the typo. I can just copy and paste the correct alternative?
@obromios this issue would be better placed on https://github.com/rspec/rspec-core, would you mind closing and refiling there?
No need to close, theres a magic transfer issue command :)
I'd say theres interest, but it would depend on the implementation.
We're not interested in adding new dependencies to outside libraries, and such a feature would have to work cross platform, and not introduce too much overhead for normal paths. If you'd like to have a go I'll glad help with feedback.
Thanks Jon, I will do some research on what is possible give those constraints. What platforms would you require it to work on?
I notice that Dir["spec/**/*.rb"]
in the console seems to list all files in all subdirectories of spec. Is this going to be platform independent?
If Dir["spec/**/*.rb"]
is platform independent, then I would propose an algorithm that would measure the Levenshtein distance of the input path to all known spec files and output a small number of the closest matches. This search would only be triggered if there was an incorrect input so should have not impact on normal operation of rspec
. The algorithm for the Levenshtein algorithm is simple for the basic case, so would not need an extra gem. My guess is that the search will be very fast for normal size projects but could become lengthy if the project had a ridiculous number of spec files. Is that an issue?
If you think this all make sense, then please point me to the code which processes the error when the input file is not found. I would be proposing to make a small change to that code and adding in a class for doing the distance measurement processing. Also does rspec keep an internal representation of Dir["spec/**/*.rb"]
already?
It's all in lib/rspec/core/configuration.rb
but there won't be an internal representation of any folder other than what we're told to load, you'll need to check the default logic for how we load things and use the existing code for "no file specified".
Thank you, I will start work on it.
Just a quick update. I have a first cut working and I am finding it useful. For the next few weeks I will tidy it up and tune it by using it in my own workflow. I will then do a pull request so it can be reviewed.
Great!
The algorithm for the Levenshtein algorithm is simple for the basic case, so would not need an extra gem.
What about using built-it did_you_mean
?
UPD: sorry, accidentally submitted the comment before finished it.
did_you_mean
gem (which is a part of Ruby since 2.3) provides an API to generate suggestions from the custom _dictionary_.
So, it could be something like:
# given the incorrect_path
path = Pathname.new(incorrect_path)
spell_checker = DidYouMean::SpellChecker.new(dictionary: Dir["#{path.dirname}/*.rb}"])
spell_checker.correct(path.basename) # => suggestion
Fantastic, if we could define an integration for that checks thats available then uses it that would be ideal. Its even automatically required by Ruby so we should be able to gate this on a simple defined?
check for older rubies. (I'm ok with this not working on rubies that don't support it).
Its even automatically required by Ruby so we should be able to gate this on a simple
defined?
check for older rubies.
Yeah, defined?
should work.
It would probably make sense to wrap it into our own class/module to hide the checks, e.g. like here:
https://github.com/palkan/action_policy/blob/master/lib/action_policy/utils/suggest_message.rb
(NOTE: this check only make suggestions work in Ruby 2.4+, 'cause Ruby 2.3 had a different API, more on that could be found in this gem https://github.com/zverok/did_you).
See ~#2061~ #2601
Using the DidYouMean api seems a good idea. I will try it out. I do not understand the reference to #2061?
Conversation! Er but I meant #2601
I am now using the DidYouMean SpellChecker api in #2601, and it appears to work well. It certainly simplifies the code and is also faster. Thank you palkan.
Closing because https://github.com/rspec/rspec-core/pull/2601 has been merged
Most helpful comment
I am now using the DidYouMean SpellChecker api in #2601, and it appears to work well. It certainly simplifies the code and is also faster. Thank you palkan.