Add Rspec included modules support#13
Conversation
62ef359 to
b984303
Compare
|
As another side note - this branch is full of test/debug code, which I'm using for testing this on the spec of this project (not working lmao) Also, to get ANYTHING working for this, I had to set my solargraph's exclude to be |
b984303 to
9ffb93e
Compare
|
Looks like I got it working, except for spec |
bb61da0 to
55a2596
Compare
|
After hours of deep solargraph diving, I realized I had a bad rspec stub, specs are now happy & this PR is ready for review! |
55a2596 to
f4faace
Compare
7f7e1e1 to
66d55fd
Compare
|
Ok, I'm finally able to replicate these CI failures via docker file, looking into them |
f47db3a to
c68d2dc
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #13 +/- ##
==========================================
+ Coverage 86.54% 88.84% +2.29%
==========================================
Files 23 25 +2
Lines 1078 1156 +78
Branches 77 85 +8
==========================================
+ Hits 933 1027 +94
+ Misses 145 129 -16 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
7073419 to
7c817e7
Compare
|
Hey @lekemula, looks like I got it working, though its more changes that I would've liked. Library ChangesBreaking: requires solargraph 0.56. This was needed to do get some tests to pass, but idk if its actually required. Lmk if this is a problem & you want me to investigate getting it to work w/ 0.52 Otherwise, the following is added:
Eg. module ModuleName
def example_method
end
end
Rspec.configure do |any_var|
any_var.include ModuleName
endWill include CI Changes
|
9d4d3f2 to
49f22c1
Compare
|
|
||
| - name: Cache Docs | ||
| run: |- | ||
| # Vendor files: don't do them |
There was a problem hiding this comment.
Can we add more context on why we don't need vendor files? My understanding is that it is because we run specs via appraisal gem, is that correct?
There was a problem hiding this comment.
Bad comment on my part - we still have vendor files, just they're excluded in a different way in the sg workspace. By default, only vendor/** get excluded. The only change is **/vendor/**/*, ie. "Exclude vendor files everywhere, not just in the top dir"
| restore-keys: | | ||
| bundle-use-ruby-${{ matrix.os }}-${{ matrix.ruby-version }}-${{ hashFiles('solargraph-rspec/solargraph-rspec.gemspec') }} | ||
| path: solargraph-rspec/gemfiles/vendor/bundle | ||
| key: bundle-use-ruby-${{ matrix.ruby-version }}-${{ hashFiles('solargraph-rspec/Gemfile', 'solargraph-rspec/gemfiles/default.gemfile.lock') }} |
There was a problem hiding this comment.
Good catch, but I think we need to check solargraph-rspec.gemspec, and solargraph-rspec/Gemfile, and Appraisals file instead.
| key: bundle-use-ruby-${{ matrix.ruby-version }}-${{ hashFiles('solargraph-rspec/Gemfile', 'solargraph-rspec/gemfiles/default.gemfile.lock') }} | |
| key: bundle-use-ruby-${{ matrix.ruby-version }}-${{ hashFiles('solargraph-rspec/Gemfile', 'Appraisals') }} |
The solargraph-rspec/gemfiles/default.gemfile.lock is just a product of the Appraisals file, where in the future there could potentially be more dependency versions.
There was a problem hiding this comment.
I'm actually not so sure - the gemlock file is the source of truth on pinned gems for tests, which could be updated without either of those 2 changing
| - name: Set up yardocs | ||
| # yard gems caches the yardocs into <gem_path>/doc/.yardoc path, hence they should be cached by ruby gems cache | ||
| run: cd solargraph-rspec && bundle exec appraisal yard gems --verbose | ||
| # - name: Run Rubocop |
There was a problem hiding this comment.
Please don't forget to bring this back again.
|
|
||
| - name: Run tests | ||
| run: cd solargraph-rspec && bundle exec appraisal rspec --format progress | ||
| run: cd solargraph-rspec && bundle exec rspec --format progress |
There was a problem hiding this comment.
I removed the whole
appraisalpart - I'm basically simulating it via theBUNDLE_GEMFILEenv var the top, which is what appraisal does anyways.
I'd prefer to keep the Appraisal gem in place. While I understand that you're replicating its behavior under the hood, relying on the gem provides a clear standard and well-maintained documentation. This makes it easier for other contributors to understand how things work without needing to dig into custom logic.
There was a problem hiding this comment.
important: These changes are more appropriate for the Convention#global method rather than Convention#local, since RSpec.configure applies global configuration.
Additionally, this approach helps avoid redundant requires and pins in individual spec files, which could unnecessarily increase Solargraph's memory usage.
There was a problem hiding this comment.
True - the one concern I have (which btw, not done right now) is "how do we handle updates to this file"? Imo the simple and easy approach is to call reset if the file name matches one of the configured paths but idk how I'd propagate that to the rest of the files (even via global)
There was a problem hiding this comment.
Imo its not a HUGE issue since those files are edited rarely (let alone to include a module) but still, something to think about
There was a problem hiding this comment.
True - the one concern I have (which btw, not done right now) is "how do we handle updates to this file"?
That's a very good point that I overlooked. As you said, these files tend not to change often, and I also don't find that to be the end of the world. One in theory could fix that by restarting the LSP, albeit not an ideal solution.
What we could do, though, is to include these pins in #local when the current file paths (ie. source_map.filename) match:
COMMON_HELPER_FILES = [
'spec/spec_helper.rb',
'spec/rails_helper.rb'
].freeze
I think/hope this would ensure that whenever these files are changed, we would get the latest includes on the spec files. Can we try this?
If it does not work, I'd still go with #global first and seek a suggestion on the solargraph side. Maybe @castwide could have other ideas.
| COMMON_HELPER_FILES = [ | ||
| 'spec/spec_helper.rb', | ||
| 'spec/rails_helper.rb' | ||
| ].freeze |
There was a problem hiding this comment.
Suggestion: Make these configurable and move to Solargraph::Rspec::Config#config_helper_files. This would allow users to add more files as needed.
| end | ||
|
|
||
| def extra_requires | ||
| included_modules.map(&:file).uniq + Dir['spec/support/**/*.rb'] |
There was a problem hiding this comment.
All (present) helper files are required
spec/spec_helper.rb,spec/rails_helper.rb&spec/support/**/*.rb.
If we do not exclude the spec/support/**/*.rb, is the additional require needed?
| # @param file [String] | ||
| # | ||
| # @return [Array<INCLUDED_MODULE_DATA>] | ||
| def extract_included_modules(ast, file) |
There was a problem hiding this comment.
Can we please extract this into a: Solargraph::Rspec::SpecConfigurationWalker, similar to lib/solargraph/rspec/spec_walker.rb?
I would prefer to keep everything isolated within that module, while keeping the plugin/pin logic in this class. That has proven helpful when switching between different parsers last time.
There was a problem hiding this comment.
What do you think about having a spec ast module? It'll include the normal walker, the spec walker & the new config walker?
There was a problem hiding this comment.
I'd prefer keeping unit tests matching the file names and separated. It makes it easier to navigate between source/test files (I use https://github.com/tpope/vim-projectionist) or run them via guard (which I plan to add in the future).
For integration-like specs (ie. test cases in convention_spec.rb), I'm more relaxed having specs which don't match the file name and rather be named by the functionality under test or a category of tests. convention_spec.rb ought to be split rather soon, since it has grown quite a bit already, and 3rd party plugins tests are a good candidate for extraction for example.
There was a problem hiding this comment.
Hey sorry - I think I worded another thing badly. I meant a module for walkers in general, which would include the spec walker that already exists & a new class for the rspec config walker (and, in the future, a factory bot walker)
There was a problem hiding this comment.
Oh yeah, that would make totally sense! 💯
Thanks for the notes, @ShadiestGoat — that approach seemed to work while testing in this repo. 💪 That said, I think we might have a potential issue. It’s not something we necessarily need to solve right now, but it’s worth noting:
Might be worth exploring options or workarounds in Solargraph’s configuration down the line. |
I 100% agree on your rails point. In the app I test this stuff on (~250 app files, ~600 files including spec) I had to change the inclusion patter to look something like: include:
- app/**/*.rb
- lib/**/*.rb
- db/schema.rb
- spec/*.rb
- spec/support/**/*.rbBut thats not really ideal to ask a user to do, but idk this seems like more of a solargraph problem |
|
(I've switched to draft mode till I get this back into a reviewable state after the requested changes) |
Credits to ShadiestGoat for #13 I mostly cherry-picked the changes from there and addressed my own feedback with the help of Claude Code. Co-authored-by: Lucy Dryaeva <48590492+ShadiestGoat@users.noreply.github.com> Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Credits to ShadiestGoat for #13 I mostly cherry-picked the changes from there and addressed my own feedback with the help of Claude Code. Co-authored-by: Lucy Dryaeva <48590492+ShadiestGoat@users.noreply.github.com> Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Credits to ShadiestGoat for #13 I mostly cherry-picked the changes from there and addressed my own feedback with the help of Claude Code. Co-authored-by: Lucy Dryaeva <48590492+ShadiestGoat@users.noreply.github.com>
Credits to ShadiestGoat for #13 I mostly cherry-picked the changes from there and addressed my own feedback with the help of Claude Code. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Lucy Dryaeva <48590492+ShadiestGoat@users.noreply.github.com>
* Add Rspec included modules support Credits to ShadiestGoat for #13 I mostly cherry-picked the changes from there and addressed my own feedback with the help of Claude Code. * Update Changelog * Update README Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Lucy Dryaeva <48590492+ShadiestGoat@users.noreply.github.com>
|
Hi @ShadiestGoat, I was keen to move this forward quickly, so I hope you don't mind me stepping in to address the remaining feedback. Really appreciate your contributions here 🙏 I might do the same with #14 unless you plan to work on it soon, because that would be a HUGE feature! 🚀 |
|
Thank you, I totally forgot about this. I'd love to finish up #14, I'll be free on Sunday/sat evening to finish it up. It's actually a new years resolution of mine to do more oss stuff, so I'd be glad to finish! |
@ShadiestGoat, I saw in your profile that Ruby was not one of your backend languages, so I thought maybe you moved to something else. But glad to hear that you plan to stick with us for a little longer ❤️ |
|
Ha! It's not one of my preferred languages - I like my languages strict, but I do use ruby at work on a daily basis so what can you do. I have grown to like a lot of it's weirdness though haha |
This doesn't work atm. @lekemula could you take a look?
The goal of this is to grab everything that is included in
Rspec.configure, and then include them under examples, example groups & hooks. Afaik, through the power of ❇️ inheritence ❇️, including them in the example group classes (& requiring the needed files) should "just work". I've tried to use the 4 namespaces I know of, but please let me know if I am way off base?As a side note - I took the design of these processors directly from
solargraph-railsso thanks to the maintainer <3