Sorbet warning: method redefined when using Structs in tests - ruby-on-rails

Recently, while working on a gem that interacts with Sorbet T::Struct, I started to see this warning in my test suite:
(eval):1: warning: method redefined; discarding old __t_props_generated_serialize
/Users/maxveldink/.asdf/installs/ruby/3.2.0/lib/ruby/gems/3.2.0/gems/sorbet-runtime-0.5.10626/lib/types/props/has_lazily_specialized_methods.rb:91: warning: previous definition of __t_props_generated_serialize was here
It's only present in a subset of tests; the ones that interact with T::Structs and attempt to convert them into an ActiveRecord model. It doesn't appear when I use the gem at runtime and doesn't appear to affect the tests at all. I'd just like to know where it's coming from and attempt to fix it.
I've traced the warning to when I'm autoloading the test T::Structs that I use in the tests. However, I think it might be happening at a different part of the flow, because it only appears on test using the singleton method path from the Ejectable module.

Related

DEPRECATION WARNING: Initialization autoloaded the constants ActionText::ContentHelper and ActionText::TagHelper

I'm trying to understand the deprecation warning:
DEPRECATION WARNING: Initialization autoloaded the constants
ActionText::ContentHelper and ActionText::TagHelper.
Being able to do this is deprecated. Autoloading during initialization is
going
to be an error condition in future versions of Rails.
Reloading does not reboot the application, and therefore code executed during
initialization does not run again. So, if you reload
ActionText::ContentHelper, for example,
the expected changes won't be reflected in that stale Module object.
These autoloaded constants have been unloaded.
In order to autoload safely at boot time, please wrap your code in a reloader
callback this way:
Rails.application.reloader.to_prepare do
# Autoload classes and modules needed at boot time here.
end
That block runs when the application boots, and every time there is a reload.
For historical reasons, it may run twice, so it has to be idempotent.
Check the "Autoloading and Reloading Constants" guide to learn more about how
Rails autoloads and reloads.
(called from <top (required)> at
/home/keith/development/pciapp/config/environment.rb:5)
What does this deprecation warning mean and how do I resolve it?
A bit of sleuthing revealed two sources of this deprecation warning in my Rails 6.1 app.
I referenced ActionMailer::Base in a couple of initializers. Based on the suggestion in the Rails Guides (https://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration), I decided to move all those references to environment.rb.
The same deprecation error was also apparently being generated by the mailgun-ruby gem v 1.2.3. It appears the deprecation warning has been fixed in v 1.2.4.
it was an issue in rails 6.0.0 https://github.com/rails/rails/issues/36546 updating to rails 6.0.1 should fix this

Find all undefined variables in Ruby file?

I am coming across lot of production issues related to undefined variables. How can I FIND all undefined variables in Ruby file? Is there any gem/script which can scan through code files and detect possible issues.. This way I can test code before production deployment or accepting Pull Requests.
This can't really be done. There are too many ways a variable could be defined. There's also an equal number of ways a variable that should be defined could be set to nil for whatever reason.
You can run Ruby with warnings enabled (-w on the command-line), which will complain vigorously about these things. It will only complain about variables along the execution path of the code, so if there are sections you don't exercise, you won't get warnings.
This is why having a test suite that exhaustively tests branches is essential to shaking out bugs like this. If you have an if in your code, you need two tests for it. If you have two if clauses, you may need three or four. Anything with a case will need all branches tested. This can be a lot of work for a project that's got a lot of business logic in it.
Since Ruby isn't compiled per-se, it's not really able to detect these sorts of issues before the code is run. What's in your file and what actually gets executed can be worlds apart depending on the impact of other parts of code. This is not true in more conservative languages like C or Rust.
Test Unit is built into rails so write some unit tests. Then run with rake test.
Try the rspec and simplecov gems.
rspec allows you to write unit tests that find undefined variables.
simplecov measures code coverage to make sure your tests cover all variables.

Fails to run Rspec due to Reform error: "undefined method `feature' for Reform::Form:Class (NoMethodError)"

I'm just trying to run some tests, and I get this error:
undefined method `feature' for Reform::Form:Class (NoMethodError)
It happens in /usr/local/bundle/gems/reform-2.2.3/lib/reform/form.rb:75,
that line in form.rb is the first time the DSL word feature is used.
Of course this does not happen when I run my rails app but only when I run rspec..
It is defined in the Disposable gem used by reform. At first I thought that the problem is with an older version of rspec but even after I updated to the latest versions, things are still broken. Reading the code or documentation did not lead me to any specific behavior of loading that is different between tests and application runs.
The versions of gems I use are:
rspec-3.3.0, reform-2.2.3, disposable-0.3.2
Does anyone have a clue?
-- Update --
After removing the entire test framework (removing RSpec and deleting all related files) and installing again I got to the point that RSpec is running by itself but when trying to load my environment in the test file it fails on the same error.
Well, the problem was that we added an override of Reform's Contract and did not do it too gracefully, thus not requiring all the things the original Reform Contract required. As a fix we now created a base
Contract that inherits from Reform::Contract instead of overriding it and now all works well. The only reason we found it when running RSpec and not in running Rails c is because of different loading order of things.

After installing paper_trail, get "irb: warn: can't alias context from irb_context." from rails console

I've tested this by running rails c both before and after git stash. On Rails 4.1 in Mavericks, after following the instructions to add the versions table and adding has_paper_trail to three models, whenever I run rails c I get
irb: warn: can't alias context from irb_context.
I've spent some time Googling without much luck, there's old threads talking about rspec, but I don't see how that's relevant since I'm not using it. Any ideas why this is happening?
RSpec used to polute provide Object top-level methods, e.g. describe, context, etc. Fortunately they've got rid of all the monkey patching in version 3, and now all these methods are namespaced under RSpec.
One can change this behaviour through the expose_dsl_globally config flag. For backwards compatibility, it defaults to true.
The warning shows up when you open the console because paper_trail automatically loads its rspec helpers when rspec is found. And it calls RSpec.configure before you have the chance to tweak your own configuration.
One possible solution would be paper_trail to disable the automatically loading and let users to load it themselves when they see fit. However, I am not aware of the internals of the library, so I can't guarantee this wouldn't break other things.
Best!
This is now fixed in papertrail 4.0.0, here's the commit.

Problems with loading and including a module (dev vs. test)

I think I understand the basics of requiring and including modules* in Ruby on Rails, but I can't figure out what's going on with an issue I'm having. I'm using Ruby 1.9.3 with Rails 3.2.1.
I have a module called Utils in /lib/_utils.rb, which currently just has some logging functions in it. In most other files in the app, I'm able to execute the following code and use the logger without any problem:
logger = Utils::SingletonLogger.get_logger
Note that in model code, I generally use an instance variable instead of a local variable, and that seems to work fine as well.
Also note that this does NOT require me to have
include Utils
in the code.
The problem is that, in at least one controller, I have to explicitly require and include the module before it will work. Well, usually anyway. Most of the time I get a NameError because it doesn't recognize Utils as a constant. Other times, it throws a ransack error. And once it a great while, it just works. If I add just the include Utils line, I get a similar NameError, though with a shorter error message.
And best of all, this only happens in the test environment, and not in my local dev instance.
For now, I've commented out all the logging in this one file, but I'd like to understand what's going on. I've added
config.autoload_once_paths += %W(#{config.root}/lib)
to application.rb, thinking this would insure that the actual code is available to any file in the application. I guess I'm supposed to need
include Utils
in every file that uses this module, but I don't understand why that doesn't seem to be required in other files, or why I should have to re-require the module file in this controller.
I'd appreciate any insight or guidance.
*Briefly - require/load reads the module's actual source code file into memory, include makes the module's methods available in a different file. I assume that I really only want to require/load a file once per instance of the application - that having it executed every time a new class is used is unsightly at best, and inefficient at worst.
I think the problem involved some combination of the following:
The module's file name didn't match the name of the module, so it didn't get picked up by the autoload.
I had an explicit require statement in a couple of files, but not others. I think when the files containing the require were executed before ones that weren't, the system could find the module, otherwise, it couldn't.
At least during the troubleshooting, I sometimes had the include statement outside of class definitions, which apparently is non-standard at best, meaningless at worst.
I used the module name as a prefix, which seems to work okay when everything else is set up correctly, but may have confused the interpreter at other times. I think this is standard when calling module methods directly, and it may mean that you don't have to include the module, though I'm not sure on that point yet.
I had a model's initialize method overridden, which may not have contributed to this problem, but did throw exceptions that interfered with debugging.
I still don't know why this flaked out in test, but not in dev.
I use Rails 3.2.11
Please follow the path
Users ▸ [your username]▸ .rvm ▸ gems ▸ ruby-1.9.3-p545 ▸ gems ▸ railties-3.2.11 ▸ lib ▸ rails ▸ engine
access file : configuration.rb
replace
paths.add "lib", :load_path => true
by
paths.add "lib", :eager_load => true
Hope this help!

Resources