How to access Rails test helper code from the console? - ruby-on-rails

Using vanilla ActiveSupport::TestCase, I've added several helper methods that generate test model objects in test/test_helper.rb. In this file is a reopening of ActiveSupport::TestCase that contains the helper methods.
Now suppose I'm in the Ruby Console (or pry, with the Rails environment loaded), and I want to fiddle with these test methods. I can load the file: load "test/test_helper.rb" but I can't create a TestCase instance that will let me access those test methods to play with them:
[4] pry(main)> tc = ActiveSupport::TestCase.new
ArgumentError: wrong number of arguments (0 for 1)
[5] pry(main)> tc = ActiveSupport::TestCase.new(1)
TypeError: 1 is not a symbol
[6] pry(main)> tc = ActiveSupport::TestCase.new(:unit)
ArgumentError: uncaught throw :invalid_test
I've tried in vain to follow the trail of breadcrumbs in source files to find the TestCase initialize method so I could figure out what it's insisting on here.
Can someone help me with how to think about problems like this and figure out a workaround?

Copied from this link: https://gist.github.com/1297510
On your terminal type:
RAILS_ENV=test pry

For your specific case, in my version of ActiveSupport (3.22.2.8), I was able to do the following:
ActiveSupport::TestCase.new('some_string')
In general though, there's several options:
using a debugger like pry can be helpful, to step through the issue.
find the source code via gem open activesupport or find where your gems are installed with gem environment
most gems are open source and are easily found on github.com, etc. Just be careful that you're looking at the correct version.

Related

RSpec Stubbing Java Static Method ArgumentError

I am attempting to stub a Java static method in my specs for my JRuby class which imports some Java libraries. I get the following error for the method call:
Failure/Error: JCoDestinationManager.getDestination('properties')
ArgumentError:
Wrong number of arguments. Expected 0, got 1.
That's the JCo Java static method. I created a small spec file to try and isolate the issue:
require 'rails_helper'
describe SapClient do
let(:destination) { double(Java::ComSapConnJcoRt::RfcDestination) }
before do
allow(JCoDestinationManager).to receive(:getDestination).and_return destination
end
it 'can be created' do
c = SapClient.new
expect(c).to_not be_nil
end
end
If I add the with clause like so, I still get the same result.
allow(JCoDestinationManager).to receive(:getDestination).with('properties').and_return destination
The strange part to me is that I only encounter this project in rails. If I copy the code over to a Sinatra project and run these specs there, all is well. I created a new Rails project and a new Sinatra project and installed the same versions of RSpec, verified RSpec mocks were the same version, etc. and still saw the discrepancy in behavior.
When I throw in a pry and observe what happens when I just call
JCoDestinationManager.getDestination
With no arguments, I get the mock destination that I define. If I comment out the allow statement, I see a real RfcDestination get created.
While searching, only thing I saw that seemed close to what I'm observing here is from https://github.com/rspec/rspec-mocks/issues/919 but apparently the solution to this problem was a jruby issue that has since been fixed.
Rails Gemfile
Rails Gemfile.lock
Sinatra Gemfile
Sinatra Gemfile.lock

Rails REPL that is more than irb/pry but less than rails console

I frequently want to try out small code snippets, often much smaller than classes, and even functions, just to make sure it works by itself so I don't need to test it by running a bunch of scripts, simply to fix small errors in a line of code or so.
Besides irb/pry, I want to test Rails-specific code, such as Object.blank?. So with that, I want to have the Rails library loaded, but I don't need the full functionality that Rails console gives me. Especially when the application is not in a working state, the REPL will not open at all, and merely present a stack trace of the failure at hand.
If anybody knew how to achieve this middle ground, maybe through the use of a particular gem path and require statement to load one of the other REPLs I have mentioned, could you illustrate those commands?
I am working inside of a project using RVM to manage the gemset, and would like to not modify that environment at all, maybe only my general terminal environment, if possible.
.blank? is from ActiveSupport. You can actually just load ActiveSupport without the rest of Rails:
irb(main):001:0> require 'active_support/all'
irb(main):002:0> [].blank?
=> true
The all.rb file loads all of ActiveSupport.
The same can be done with ActiveRecord and other rails components; for example:
irb(main):001:0> require 'active_record'
=> true
irb(main):002:0> class NewModel < ActiveRecord::Base; end
=> nil
irb(main):003:0> NewModel.new
ActiveRecord::ConnectionNotEstablished: No connection pool for NewModel
This gives an error because I didn't bother setting up a database, but it shows that Rails is pretty modular. I've used ActiveRecord in projects without Rails (the rails gem is actually an empty gem which just defines the various active_* gems as dependencies).
Most of the Rails "magic" come from Active Support Core Extensions. You can include that in a regular irb session to get most of the connivence methods like blank?.
Start an IRB session and run
require 'active_support'
require 'active_support/core_ext'

undefined method `translate' for I18n:Module

On a server i had an installation of the gollum wiki. It ran fine. Now I also had to install redmine on that same server. This was a big pain, as redmine refused to run with puma. I had to mess around a lot with different gems to make it work at all.
But for some reason i now get an error from gollum, whenever i try to create a new wiki page:
NoMethodError at /create/old/git-tips
undefined method `translate' for I18n:Module
The stack trace shows that the error occurs in this line of stringex:
/var/lib/gems/1.9.1/gems/stringex-2.0.5/lib/stringex/localization/backend/i18n.rb in i18n_translations_for
::I18n.translate("stringex", :locale => locale, :default => {})
So i checked the installed packages with gem list and the required version of i18n 0.6.1 is there.
Any idea, what could be wrong and how to fix this?
For reference here's the output of gem list.
This may or may not help, but I had a similar problem on a large code base where there was an application-specific I18n module (which included some custom helper methods), but this was overriding the 't' method (a shortened form of translate).
In this case I found I could force the base-level I18n module by using two colons...
::I18n.t('thing')

Call a method and initiate debugging from the rails console without editing the source code?

Sometimes when I'm working in the rails console, I find I want to step through a particular method (from my rails app) in the debugger. In the past I have done this by temporarily adding a debugger statement to the source code of the method, then calling that method from the console.
Is there a way I can "step into" a method from the console, without editing its source code?
This would be particularly nice on a shared development server, so that I wouldn't need to throw in random debugger statements with vi and remember to remove them later.
I tried the following but not surprisingly it doesn't work:
$ rails c --debugger
=> Debugger enabled
Loading development environment (Rails 3.2.13)
irb(main):001:0> def startdebug
irb(main):002:1> debugger
irb(main):003:1> MyModel.last.my_method
irb(main):004:1> end
=> nil
irb(main):005:0> startdebug
It says
*** No sourcefile available for (irb)
And soon I end up stepping through irb code rather than my_method.
mhm this sound a bit like metaprogramming for me, you may inject a debugging method at runtime in your model, which will add the debugging statement just before the method call so you can inspect the call as needed, like:
m = MyModel.last
m.class.send(:define_method, :debug_my_method){debugger; my_method}
m.debug_my_method
this should do on the irb (just tested it on may rails console)

What does "Anonymous modules have no name to be referenced by" really mean?

I'm upgrading my Rails app to work with Ruby 1.9 and I keep encountering errors like this:
Anonymous modules have no name to be referenced by
/home/foo/.gem/ruby/1.9.1/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:585:in `to_constant_name'
/home/foo/.gem/ruby/1.9.1/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:391:in `qualified_name_for'
/home/foo/.gem/ruby/1.9.1/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:104:in `rescue in const_missing'
/home/foo/.gem/ruby/1.9.1/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:94:in `const_missing'
/home/foo/app/config/environment.rb:66:in `block in <top (required)>'
etc.
Google finds all kinds of hits for this, but each of them pertains to a specific fix for one specific gem or app. None of them explain what the message really means.
What is an "anonymous module"?
Where is this error message coming from? (The Ruby interpreter itself?)
What is different about Ruby 1.9 that causes this? (Rails 2.3.8 with Ruby 1.8.7 does not encounter this.)
What is the general/proper way to fix this error?
Line 66 of environment.rb is the configuration for super_exception_notifier (old version, 2.0.8):
ExceptionNotifier.configure_exception_notifier do |config|
config[:sender_address] = %("Foo" <foo#foo.com>)
config[:exception_recipients] = %w(foo#foo.com)
config[:skip_local_notification] = false
end
From what I can tell, ExceptionNotifier is undefined, and ActiveSupport is trying to magically load it, but fails and then fails again trying to print a nice error message.
An anonymous module is a module that is declared like so:
Fred = Module.new do
def meth1
"hello"
end
def meth2
"bye"
end
end
instead of by using the regular Module mod_name <block> syntax. Since they have no module name, you can't retrieve the module name. to_constant_name is attempting to call desc.name.blank? where desc is an anonymous module (with no name).
This error is coming from the ActiveSupport module, which may indicate a bug in the active_support gem or may indicate that some other piece of code is using ActiveSupport incorrectly. The error message alone doesn't give enough information to identify the culprit (to me at least, someone with more rails experience might be able to provide more insight).
Without knowing the offending code it's also hard to say exactly why this error is popping up with 1.9, or what needs to be done to fix it. Considering that there are a lot of un- and under-maintained gems out there that have not been updated for 1.9 yet, I would suspect that ActiveSupport is not the source of the problem. Upgrade all of your gems that have 1.9-compatible versions, and then try disabling your other gems one at a time (if you can) and see if you still get the error.
If you provide a list of the other gems that you are using, someone else who may have encountered the error before may be able to provide some details.
This may happen if you try to exploit ActiveRecord's internal class and module contexts in the wrong way. I had this error yesterday while working on a gem which extends deep inner workings of ActiveRecord. I finally managed to get around this problem by redesigning my code which exploits the inner contexts. It would be interesting to see the surrounding lines of environment.rb:66 for further analysis.
This may happen when the class name doesn't match the filename, in
my case it was a file named application.rb contaning the ApplicationController
class. Renaming the file to application_controller.rb solved the problem.
When I got this error, it was due to a misspelling while defining a class. If you are getting this error, it may be worth examining your module and class definitions for typos.

Resources