Ruby Pry locate test file that triggered pry - ruby

I have a block of code that triggers my pry session via an integration test but no unit test exists. As such I'm not sure which test is exercising this code and need to run all tests each time I want it to trigger. Is there a way, in a pry session, to bubble up the test/test file? I do not need the _file_ that triggered the pry session.
My best solution has been to raise errors while in the pry session and then continue the test suite hoping that'll flub up a test and be able to locate that test in the testing report. This approach is a bit too much like stabbing in the dark.

You should be able to get the full call stack by simply invoking caller:
$ pry
[1] pry(main)> caller
=> ["/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/pry_instance.rb:290:in `eval'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/pry_instance.rb:290:in `evaluate_ruby'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/pry_instance.rb:659:in `handle_line'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/pry_instance.rb:261:in `block (2 levels) in eval'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/pry_instance.rb:260:in `catch'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/pry_instance.rb:260:in `block in eval'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/pry_instance.rb:259:in `catch'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/pry_instance.rb:259:in `eval'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/repl.rb:77:in `block in repl'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/repl.rb:67:in `loop'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/repl.rb:67:in `repl'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/repl.rb:38:in `block in start'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/input_lock.rb:61:in `__with_ownership'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/input_lock.rb:78:in `with_ownership'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/repl.rb:38:in `start'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/repl.rb:15:in `start'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/pry_class.rb:191:in `start'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/lib/pry/cli.rb:119:in `start'",
"/home/john/.gem/ruby/2.7.0/gems/pry-0.13.1/bin/pry:13:in `<top (required)>'",
"/home/john/.gem/ruby/2.7.0/bin/pry:23:in `load'",
"/home/john/.gem/ruby/2.7.0/bin/pry:23:in `<main>'"]

Related

Using `require 'classname'` causes "No such file to load -- Classname" error on Heroku

TLDR: Using require 'classname' in another model file (so I can deserialize a column) works locally but results in the No such file to load -- Classname error when deploying to Heroku.
I've made the admittedly poor design decision to serialize a model attribute which contains an array of another model's objects (UserCategoryQueue has a serialized queue of Card objects). In order to actually de-serialize these objects, I've followed the advice in YAML::load raises undefined class/module error to use require 'Card' in the files where I need to deserialize that column. That avoids the issue where YAML doesn't know what it's looking at when it gets to the Card object.
This works fine on the localhost server but has resulted in a lot of issues when deploying to Heroku, all of the form No such file to load -- Card". Initially, this occurred during the asset precompilation phase, then I precompiled the assets myself and the same error has moved to when I try to run $ heroku run rake db:migrate to get everything set up for the first time.
Sample Files:
# app/models/user_category_queue.rb
class UserCategoryQueue < ActiveRecord::Base
...
# Our queue of Cards
serialize :queue, Array
end
# app/models/quiz.rb
class Quiz < ActiveRecord::Base
...
require 'Card'
...
# grab a random card from the user's queues
# produces YAML error without the above require statement
def sample_card
self.user.user_category_queues.sample.queue.sample
end
end
This ultimately resulted in the following errors on pushing to Heroku (prior to any asset precompilation attempts on my part):
Running: rake assets:precompile
rake aborted!
No such file to load -- Card
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `require'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `block in require'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:213:in `load_dependency'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `require'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/app/models/quiz.rb:18:in `<class:Quiz>'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/app/models/quiz.rb:1:in `<top (required)>'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `require'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `block in require'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:213:in `load_dependency'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `require'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:329:in `require_or_load'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:288:in `depend_on'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:206:in `require_dependency'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/engine.rb:465:in `block (2 levels) in eager_load!'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/engine.rb:464:in `each'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/engine.rb:464:in `block in eager_load!'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/engine.rb:462:in `each'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/engine.rb:462:in `eager_load!'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/engine.rb:347:in `eager_load!'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/application/finisher.rb:56:in `each'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/application/finisher.rb:56:in `block in <module:Finisher>'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/initializable.rb:30:in `instance_exec'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/initializable.rb:30:in `run'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/initializable.rb:55:in `block in run_initializers'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/initializable.rb:54:in `run_initializers'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/application.rb:215:in `initialize!'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/railtie/configurable.rb:30:in `method_missing'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/config/environment.rb:5:in `<top (required)>'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `require'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `block in require'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:213:in `load_dependency'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `require'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/application.rb:189:in `require_environment!'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/railties-4.0.0/lib/rails/application.rb:249:in `block in run_tasks_blocks'
/tmp/build_d0e6e2b8-a3fd-4a90-ae44-e703b0093401/vendor/bundle/ruby/2.0.0/gems/sprockets-rails-2.0.0/lib/sprockets/rails/task.rb:54:in `block (2 levels) in define'
Tasks: TOP => environment
(See full trace by running task with --trace)
!
! Precompiling assets failed.
As I said, even when precompiling assets, though the push went fine, the ensuing database migration had the same error pop up.
Heroku runs a case-sensitive filesystem, whereas your OS may not be case-sensitive. Try changing that require to this instead:
require 'card'
As a general rule of thumb, most files within Ruby are required using lowercase letters with underscores serving as a word separator, like this:
require 'card_shuffler'

How to run shell commands on server in Capistrano v3?

I'm new to Capistrano and I've tried using Capistrano's DSL to run shell commands on the server ('run', 'execute', etc.), but it appears that it was deprecated. After searching and searching for a functional equivalent, I still am lost.
Current code:
desc 'Do something'
task :do_something
execute 'echo sometext'
end
Output:
cap aborted!
undefined method `execute' for main:Object
/Users/Justin/Dropbox/xxxx/xxxx/xxxx/Capfile:45:in `block (2 levels) in <top (required)>'
/Users/Justin/.rvm/gems/ruby-2.0.0-p247/bundler/gems/capistrano-2dc1627838f9/lib/capistrano/application.rb:12:in `run'
/Users/Justin/.rvm/gems/ruby-2.0.0-p247/bundler/gems/capistrano-2dc1627838f9/bin/cap:3:in `<top (required)>'
/Users/Justin/.rvm/gems/ruby-2.0.0-p247/bin/cap:23:in `load'
/Users/Justin/.rvm/gems/ruby-2.0.0-p247/bin/cap:23:in `<main>'
/Users/Justin/.rvm/gems/ruby-2.0.0-p247/bin/ruby_noexec_wrapper:14:in `eval'
/Users/Justin/.rvm/gems/ruby-2.0.0-p247/bin/ruby_noexec_wrapper:14:in `<main>'
Tasks: TOP => deploy:do_something
In Capistrano v3, you must specify where you want to run the code by calling on with a list of hostnames, e.g.
task :execute_on_server do
on "root#example.com" do
execute "some_command"
end
end
If you have roles set up, you can use the roles method as a convenience:
role :mailserver, "root#mail.example.com"
task :check_mail do
on roles(:mailserver) do
execute "some_command"
end
end
There is some v3 documentation here: http://www.capistranorb.com/

RSpec shorter backtrace output for test failures

I'm using RSpec (latest Version, 2.12.2) to test a small Ruby class I'm working on. My problem is that when an RSpec test fails, the test output seems incredibly verbose, and shows a huge list of error messages, almost what seems to be a full backtrace. This means I have to scroll up to see the actual error message and the top of the trace.
I believe by default RSpec is supposed to do this but it doesn't seem to be doing it for me. For example, if I run rspec spec/my_spec.rb:132 (just run one test that's on L132), I get this output:
Failure/Error: #f.has_changed?("test").should be_true
expected: true value
got: false
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-expectations-2.12.1/lib/rspec/expectations/fail_with.rb:33:in `fail_with'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-expectations-2.12.1/lib/rspec/expectations/handler.rb:33:in `handle_matcher'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-expectations-2.12.1/lib/rspec/expectations/syntax.rb:53:in `should'
# /Users/JackFranklin/Dropbox/Sites/rubygems/filefixtures/spec/filefixtures_spec.rb:137:in `block (4 levels) in <top (required)>'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example.rb:114:in `instance_eval'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example.rb:114:in `block in run'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example.rb:254:in `with_around_each_hooks'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example.rb:111:in `run'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:388:in `block in run_examples'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:384:in `map'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:384:in `run_examples'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:369:in `run'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `block in run'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `map'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `run'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `block in run'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `map'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/example_group.rb:370:in `run'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:28:in `block (2 levels) in run'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:28:in `map'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:28:in `block in run'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/reporter.rb:34:in `report'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/command_line.rb:25:in `run'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/runner.rb:80:in `run'
# /Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-core-2.12.2/lib/rspec/core/runner.rb:17:in `block in autorun'
Which, as you can see, is absolutely massive. I've not got any RSpec config files around that could be altering the configuration passed to RSpec.
Has anyone seen this before? I've tried Googling but searches have been fruitless.
Edit: I then set up config to make sure it was applying the default backtrace cleaning:
RSpec.configure do |config|
# RSpec automatically cleans stuff out of backtraces;
# sometimes this is annoying when trying to debug something e.g. a gem
config.backtrace_clean_patterns = [
/\/lib\d*\/ruby\//,
/bin\//,
/gems/,
/spec\/spec_helper\.rb/,
/lib\/rspec\/(core|expectations|matchers|mocks)/
]
end
But this doesn't make a difference. Looking at the output, it should be having most of it filtered out but it seems like the configuration isn't being applied?
Edit again:
In my config, I can even run cleaned_from_backtrace?(line) to see if a line should be cleaned. This returns true:
config.cleaned_from_backtrace?("/Users/JackFranklin/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/rspec-expectations-2.12.1/lib/rspec/expectations/fail_with.rb:33:in `fail_with'")
But the actual output in the terminal remains the same!
Edit 3:
I am running RSpec with the command rspec, and nothing more. The project's .rspec file contains:
--color
--format progress
And there is no ~/.rspec file either that could be applying settings.
So after a bit more chatting with the RSpec folk on Github, I managed to hunt down the problem.
The problem was that by default, RSpec removes lines from the backtrace that match the Regex /gems/. I had my project within a folder with gems in the name: ~/Dropbox/rubygems/myproject, so every line of the backtrace was being removed, and when that happens, RSpec sensibly shows you the entire backtrace.
That explains the behaviour I was seeing.
It's always something silly like that. I hope if anyone else does this, perhaps this answer will save them some time.
Looks like you're running RSpec with -b, for a full backtrace. Normally, RSpec won't show its own internal backtrace like that, even when your test fails badly (i.e. throws an exception rather than just failing an assertion). If you're not explicitly running it with -b or --backtrace, check and make sure that you don't have that set in a .rspec config file, or that your IDE or whatever isn't passing it.
As Jim said, there's a -b or --backtrace option that will enable the full backtrace. Bear in mind that it's not just the .rspec file that could be triggering it; there's also ~/.rspec (for a developer's preferred options).
The other thing to bear in mind is that a formatter can spit out whatever portion of the backtrace that it wants. The formatters expose a simple way for any 3rd-party formatter to respect the backtrace-filtering configuration, but it you're using a 3rd-party formatter there is no guarantee it is using that properly. Are you using one of the built-in rspec formatters?
Finally, if it's not one of those things, I'm out of ideas. I'd have to have an example to play with to answer your question. Can you come up with a reproducible example (in a gist, hopefully)? I try to hang out in the rspec channel of irc.freenode.net regularly, so maybe you can catch me there and we can do some troubleshooting that way.
From version 3.4.0 / 2015-11-11 it is possible to filter backtrace by option:
RSpec.configure do |config|
config.filter_rails_from_backtrace!
end

How to set the path to the classes being tested with Cucumber?

I've tried following two written guides and one youtube video (http://www.youtube.com/watch?v=8ZmawOCDeyo) and they either skip over an important step (or it just works for them) but not for me.
I have created the following folder structure:
RubyBots\
features\
step_definitions\
creating_a_vehicle_for_an_ai_bot_steps.rb
support\
env.rb
creating_a_vehicle_for_an_ai_bot.feature
vehicle.rb
vehicle_factory.rb
Contents of creating_a_vehicle_for_an_ai_bot_steps.rb:
Given /^I have vehicle factory$/ do
#vehicle_factory = VehicleFactory.new
end
When /^I use it to build a basic vehicle$/ do
#new_vehicle = #vehicle_factory.build
end
Then /^I should have receive a basic vehicle$/ do
#test #new_vechile
end
Contents of vehicle_factory.rb:
class VehicleFactory
def initialize(name)
p name
end
end
Contents of env.rb file:
require 'vehicle_factory'
require 'vehicle'
I execute Cucumber (with no parameters) from inside a CMD window inside the RubyBots directory and I receive the following error:
no such file to load -- vehicle_factory (LoadError)
<internal:lib/rubygems/custom_require>:29:in `require'
<internal:lib/rubygems/custom_require>:29:in `require'
D:/Code/RubyBots/features/support/env.rb:1:in `<top (required)>'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cucumber-1.0.1/lib/cucumber/rb_support/rb_language.rb:143:in `load'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cucumber-1.0.1/lib/cucumber/rb_support/rb_language.rb:143:in `load_code_file'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cucumber-1.0.1/lib/cucumber/runtime/support_code.rb:176:in `load_file'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cucumber-1.0.1/lib/cucumber/runtime/support_code.rb:78:in `block in load_files!'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cucumber-1.0.1/lib/cucumber/runtime/support_code.rb:77:in `each'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cucumber-1.0.1/lib/cucumber/runtime/support_code.rb:77:in `load_files!'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cucumber-1.0.1/lib/cucumber/runtime.rb:137:in `load_step_definitions'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cucumber-1.0.1/lib/cucumber/runtime.rb:39:in `run!'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cucumber-1.0.1/lib/cucumber/cli/main.rb:43:in `execute!'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cucumber-1.0.1/lib/cucumber/cli/main.rb:20:in `execute'
C:/Ruby192/lib/ruby/gems/1.9.1/gems/cucumber-1.0.1/bin/cucumber:14:in `<top (required)>'
C:/Ruby192/bin/cucumber:19:in `load'
C:/Ruby192/bin/cucumber:19:in `<main>'
If I delete the env.rb file from the support directory I get the follow error when running Cucumber:
Scenario: Using a vehicle factory to build a basic vehicle # Features\creating_a_vehicle_for_an_ai_bot.feature:6
Given I have vehicle factory # Features/creating_a_vehicle_for_an_ai_bot_steps.rb:1
uninitialized constant Object::VehicleFactory (NameError)
./Features/creating_a_vehicle_for_an_ai_bot_steps.rb:2:in `/^I have vehicle factory$/'
Features\creating_a_vehicle_for_an_ai_bot.feature:7:in `Given I have vehicle factory'
When I use it to build a basic vehicle # Features/creating_a_vehicle_for_an_ai_bot_steps.rb:5
Then I should have receive a basic vehicle # Features/creating_a_vehicle_for_an_ai_bot_steps.rb:9
Failing Scenarios:
cucumber Features\creating_a_vehicle_for_an_ai_bot.feature:6 # Scenario: Using a vehicle factory to build a basic vehicle
I've tried everything I can think of and my google-fu is failing me - I hope it's something non-trivial so I'm not embarrassed, but easy to fix, so that I can move on! :)
Thanks for the help!
Your class is called VehicleFactory but you're trying to call vehicle_factory.new in creating_a_vehicle_for_an_ai_bot_steps.rb.
Also, I believe Cucumber expects a particular directory structure:
RubyBots/
features/
step_definitions/
creating_a_vehicle_for_an_ai_bot_steps.rb
support/
env.rb
creating_a_vehicle_for_an_ai_bot.feature
You'll need to require your own files from env.rb appropriately. Ruby doesn't work out any paths for you. One way of auto-requiring files based on symbol name (the way Rails does it) is described in my blog post (it relies on ActiveSupport 2.3 but should be similar for the current version).

DRb::DRbServerNotFound passing Sinatra params

I have a Sinatra application and DRb server object paired. When I try to pass the Sinatra params hash to a method on my server object I get DRb::DRbConnError …
DRb::DRbServerNotFound, yet the same method works when I pass a simple hash directly.
Why am I getting this error with the Sinatra params hash?
What are the easiest and most correct workarounds to fix this problem?
Here's a simple test case:
# server.rb
require 'drb'
class Server; def echo( hash ); hash; end; end
DRb.start_service 'druby://localhost:9007', Server.new
DRb.thread.join
# app.rb
require 'sinatra'
require 'drb'
SERVER = DRbObject.new_with_uri 'druby://localhost:9007'
get("/params"){ SERVER.echo(params).inspect }
get("/hash" ){ SERVER.echo(hello:'world').inspect }
With both of these running in their own processes:
phrogz$ curl http://localhost:4567/hash
{:hello=>"world"}
phrogz$ curl http://localhost:4567/params
DRb::DRbConnError - DRb::DRbServerNotFound:
/usr/local/lib/ruby/1.9.1/drb/drb.rb:1653:in `current_server'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:1721:in `to_id'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:1050:in `initialize'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:642:in `new'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:642:in `make_proxy'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:559:in `rescue in dump'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:556:in `dump'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:603:in `block in send_request'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:602:in `each'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:602:in `send_request'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:903:in `send_request'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:1196:in `send_message'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:1088:in `block (2 levels) in method_missing'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:1172:in `open'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:1087:in `block in method_missing'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:1105:in `with_friend'
/usr/local/lib/ruby/1.9.1/drb/drb.rb:1086:in `method_missing'
app.rb:4:in `block in <main>'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1152:in `call'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1152:in `block in compile!'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:724:in `instance_eval'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:724:in `route_eval'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:708:in `block (2 levels) in route!'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:758:in `block in process_route'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:755:in `catch'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:755:in `process_route'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:707:in `block in route!'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:706:in `each'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:706:in `route!'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:843:in `dispatch!'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:644:in `block in call!'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:808:in `instance_eval'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:808:in `block in invoke'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:808:in `catch'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:808:in `invoke'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:644:in `call!'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:629:in `call'
/usr/local/lib/ruby/gems/1.9.1/gems/rack-1.2.2/lib/rack/head.rb:9:in `call'
/usr/local/lib/ruby/gems/1.9.1/gems/rack-1.2.2/lib/rack/commonlogger.rb:18:in `call'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/showexceptions.rb:21:in `call'
/usr/local/lib/ruby/gems/1.9.1/gems/rack-1.2.2/lib/rack/methodoverride.rb:24:in `call'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1272:in `block in call'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1303:in `synchronize'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1272:in `call'
/usr/local/lib/ruby/gems/1.9.1/gems/rack-1.2.2/lib/rack/content_length.rb:13:in `call'
/usr/local/lib/ruby/gems/1.9.1/gems/rack-1.2.2/lib/rack/chunked.rb:15:in `call'
/usr/local/lib/ruby/gems/1.9.1/gems/thin-1.2.11/lib/thin/connection.rb:84:in `block in pre_process'
/usr/local/lib/ruby/gems/1.9.1/gems/thin-1.2.11/lib/thin/connection.rb:82:in `catch'
/usr/local/lib/ruby/gems/1.9.1/gems/thin-1.2.11/lib/thin/connection.rb:82:in `pre_process'
/usr/local/lib/ruby/gems/1.9.1/gems/thin-1.2.11/lib/thin/connection.rb:57:in `process'
/usr/local/lib/ruby/gems/1.9.1/gems/thin-1.2.11/lib/thin/connection.rb:42:in `receive_data'
/usr/local/lib/ruby/gems/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run_machine'
/usr/local/lib/ruby/gems/1.9.1/gems/eventmachine-0.12.10/lib/eventmachine.rb:256:in `run'
/usr/local/lib/ruby/gems/1.9.1/gems/thin-1.2.11/lib/thin/backends/base.rb:61:in `start'
/usr/local/lib/ruby/gems/1.9.1/gems/thin-1.2.11/lib/thin/server.rb:159:in `start'
/usr/local/lib/ruby/gems/1.9.1/gems/rack-1.2.2/lib/rack/handler/thin.rb:14:in `run'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/base.rb:1234:in `run!'
/usr/local/lib/ruby/gems/1.9.1/gems/sinatra-1.2.6/lib/sinatra/main.rb:25:in `block in <module:Sinatra>'
This is running under Ruby 1.9.2 on OS X, not that I think it makes a difference.
Short answer
You need to add
DRb.start_service
to app.rb before you try to make a remote call.
Explanation if you're interested
The Sinatra params hash is created with an associated block to handle the case when missing keys are referenced (here's the source). This means there's a Proc object associated with it.
Drb passes arguments back and forth by Marshalling them. However, from the Marshal docs:
Some objects cannot be dumped: if the objects to be dumped include bindings, procedure or method objects, instances of class IO, or singleton objects, a TypeError will be raised.
So there's going to be problems trying to pass this params hash about over the wire, as it contains an unmarshallable procedure object.
Now onto the Drb docs:
However, if an object cannot be marshalled, a dRuby reference to it is passed or returned instead. This will turn up at the remote end as a DRbObject instance. All methods invoked upon this remote proxy are forwarded to the local object, as described in the discussion of DRbObjects. This has semantics similar to the normal Ruby pass-by-reference.
Good news, it should still work. So what's wrong? A bit further on in the Drb docs we find this in the example code:
# Start a local DRbServer to handle callbacks.
#
# Not necessary for this small example, but will be required
# as soon as we pass a non-marshallable object as an argument
# to a dRuby call.
DRb.start_service
So what appears to be happening is Drb is trying to get a remote reference for the procedure object to pass to the server, but is unable as there's no Drb service set up client side.
Original answer
(I'll leave this here, it might me of interest. It was a resting point on my journey to figuring it all out. It's also a possible alternate solution. Interestingly, it appears that I'm now the more knowledgable person I referred to, at least with respect to the why.)
Here's a possible workaround. The problem seems to be with hashes created with a block to deal with missing keys (which Sinatra's params hash is), so you could extract the contents of the hash into a new one. params.clone and params.merge({}) both appear to retain the proc (you can check with Hash#default_proc), but {}.merge(params) (or merge!) gives you a nice clean hash that works with Drb.
So, in this example, do this:
get("/params"){ SERVER.echo({}.merge params).inspect
Why this happens with Drb and hashes with procs, and whether this is the easiest or most correct workaround, I'll leave to someone more knowledgable.

Resources