"Attempted to redefine prop" error with T::Struct - sorbet

I'm trying to make use of T::Struct to avoid some boilerplate in a class:
https://github.com/andyw8/codeclimate-engine-rb/pull/13/commits/d1fd72e22a4b9737ef2fe759215fb1c73c25e3bb
srb tc doesn't report any errors, but when I run the tests it fails with:
ArgumentError:
Attempted to redefine prop :check_name that's already defined without specifying :override => true: {:type=>String, :type_is_custom_type=>nil, :type_is_serializable=>nil, :type_is_array_of_serializable=>false, :type_is_hash_of_serializable_values=>false, :type_is_hash_of_custom_type_keys=>false, :type_object=>#<T::Types::Simple:0x00007fc611266e78 #raw_type=String>, :type_needs_clone=>false, :accessor_key=>:#check_name, :sensitivity=>nil, :pii=>nil, :extra=>nil, :serialized_form=>"check_name", :fully_optional=>false, :need_nil_read_check=>nil}
# /Users/awaite/.rvm/gems/ruby-2.4.4/gems/sorbet-runtime-0.5.5188/lib/types/props/decorator.rb:56:in `add_prop_definition'
# /Users/awaite/.rvm/gems/ruby-2.4.4/gems/sorbet-runtime-0.5.5188/lib/types/private/methods/call_validation.rb:126:in `call'
# /Users/awaite/.rvm/gems/ruby-2.4.4/gems/sorbet-runtime-0.5.5188/lib/types/private/methods/call_validation.rb:126:in `validate_call'
# /Users/awaite/.rvm/gems/ruby-2.4.4/gems/sorbet-runtime-0.5.5188/lib/types/private/methods/call_validation.rb:186:in `block in create_validator_slow'
# /Users/awaite/.rvm/gems/ruby-2.4.4/gems/sorbet-runtime-0.5.5188/lib/types/props/optional.rb:48:in `add_prop_definition'
# /Users/awaite/.rvm/gems/ruby-2.4.4/gems/sorbet-runtime-0.5.5188/lib/types/props/serializable.rb:311:in `add_prop_definition'
# /Users/awaite/.rvm/gems/ruby-2.4.4/gems/sorbet-runtime-0.5.5188/lib/types/props/decorator.rb:490:in `prop_defined'
# /Users/awaite/.rvm/gems/ruby-2.4.4/gems/sorbet-runtime-0.5.5188/lib/types/private/methods/call_validation.rb:126:in `call'
# /Users/awaite/.rvm/gems/ruby-2.4.4/gems/sorbet-runtime-0.5.5188/lib/types/private/methods/call_validation.rb:126:in `validate_call'
# /Users/awaite/.rvm/gems/ruby-2.4.4/gems/sorbet-runtime-0.5.5188/lib/types/private/methods/call_validation.rb:186:in `block in create_validator_slow'
# /Users/awaite/.rvm/gems/ruby-2.4.4/gems/sorbet-runtime-0.5.5188/lib/types/props/_props.rb:109:in `prop'
# ./lib/cc_engine/issue.rb:8:in `<class:Issue>'
If I re-order the props, I get the same error but for description instead.
Is it perhaps because I'm using a struct but also defining methods on it? I know Ruby's Struct supports that but I'm not sure about Sorbet's T::Struct.

Solved: I had to add a dependency, require "cc_engine/location" (although I don't yet understand why it caused that particular error message).

I got this error when I tried to type a value prior to its type being defined
class MyStruct < T::Struct
extend T::Sig
const :some_const, MyEnumType
class MyEnumType < T::Enum
...
end
end
Moving the definition of MyEnumType to be above the definition of some_const fixed the issue.

Related

Error occurred when loading a custom Julia module

I have been puzzled by how to define and use custom module in Julia.
For example, I defined a module named myMoldule to wrap a mutable struct Param and a function add in D:\\run\\defineModule.jl:
module myMoldule
export Param, add
mutable struct Param
x ::Int64
y ::Int64
end
function add(x::Int64, y::Int64)
sum ::Int64
sum = x + y
return sum
end
end
and used this module in D:\\run\\useModule.jl like:
include("D:\\run\\defineModule.jl")
using .myMoldule
function testModule()
param = Param(1, 2)
sum = add(param.x, param.y)
println(sum)
end
An error occurred when running testModule() as follows:
julia> testModule()
ERROR: UndefVarError: Param not defined
Stacktrace:
[1] testModule() at D:\run\useModule.jl:8
[2] top-level scope at none:1
Note that I used the absolute path in the include(...) to avoid using LOAD_PATH stuff, and added . before the module name (i.e., using .myMoldule).
What seems to be the problem?
P.S.: Julia version information:
julia> versioninfo()
Julia Version 1.5.2
Commit 539f3ce943 (2020-09-23 23:17 UTC)
Platform Info:
OS: Windows (x86_64-w64-mingw32)
CPU: Intel(R) Core(TM) i7-8700K CPU # 3.70GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-9.0.1 (ORCJIT, skylake)
Environment:
JULIA_DEPOT_PATH = C:\Users\f\.julia;C:\opt\JuliaPro-1.5.2-1\Julia-1.5.2\local\share\julia;C:\opt\JuliaPro-1.5.2-1\Julia-1.5.2\share\julia
JULIA_LOAD_PATH = #;#v#.#;#stdlib
JULIA_NUM_THREADS = 6
JULIA_PKG_SERVER = pkg.juliahub.com
Corrections to be made:
sum is a function in Base you should use a different name
no need to declare sum variable (and it should be named something like mysum)
Remove space before ::
Module names should start with a CapitalLetter
You have a typo in module name perhaps you are loading a different module than you think?
Once corrected your code works.
The issue happens because you are using .MyModule1, not in the MyModule2, and thus you import Param to the Main module but not to the MyModule2, thus Module2 does not see Param.
If you will put using ..MyModule1 (two dots instead of one as you there is one more level) into MyModule2 this issue will go.
However, your code still will not work, since julia's include function just runs all the content of the included file, thus even you included the same file, you will create different instances of the modules. This warning WARNING: replacing module... indicates that somewhere in your code you might use the different version of the module (in you case, Main.Module1 and Main.Module2.Module1).
The common practice in julia is to include all the files in one place (they should be included only once). For instance, you can put all the includes in the file useModule.jl:
include("./defineModule1.jl")
include("./defineModule2.jl")
using .MyModule1
using .MyModule2
function testModule()
param = Param(1, 2)
# call myAdd to get the sum of param.x and param.y
sumValue = myAdd(param)
println(sumValue)
# call mySubtract to get the difference of param.x and param.y
difValue = mySubtract(param)
println(difValue)
end
Do not include files in other places. e.g.
defineModule2.jl content:
module MyModule2
using ..MyModule1
export myAdd, mySubtract
function myAdd(param::Param)
return param.x + param.y
end
function mySubtract(param::Param)
return param.x - param.y
end
end # end of module
Questioner's note: The following new question voted downwards (perhaps) was extended form the original one and was well answered by Vitaliy Yakovchuk.
I fixed all the issues pointed out by Przemyslaw Szufel. In my case above, it's not the improper ways of naming that cause the issue.
Now, I have a better exmaple to clarify my issue.
Suppose that, to meet the needs, I have to seperate my julia source code into two modules, e.g., define of a mutable struct Param in defineModule1.jl and define of functions in defineModule2.jl. The code scripts are as follows:
"D:\\run\\defineModule1.jl":
module MyModule1
export Param
mutable struct Param
x::Int64
y::Int64
end
end # end of module
"D:\\run\\defineModule2.jl":
include("D:\\run\\defineModule1.jl"); using .MyModule1
module MyModule2
export myAdd, mySubtract
function myAdd(param::Param)
return param.x + param.y
end
function mySubtract(param::Param)
return param.x - param.y
end
end # end of module
Note that Param is not defined here, and to make Param available, a line include("D:\\run\\defineModule1.jl"); using .MyModule1 is added as the first line of this file.
"D:\\run\\useModule.jl":
include("D:\\run\\defineModule1.jl"); using .MyModule1
include("D:\\run\\defineModule2.jl"); using .MyModule2
function testModule()
param = Param(1, 2)
# call myAdd to get the sum of param.x and param.y
sumValue = myAdd(param)
println(sumValue)
# call mySubtract to get the difference of param.x and param.y
difValue = mySubtract(param)
println(difValue)
end
Note that both function myAdd(param) and mySubtract(param) in the script defineModule2.jl need the predefined mutable struct Param in defineModule1.jl.
This is what I got when I run D:\\run\\useModule.jl:
julia> include("D:\\run\\useModule.jl")
WARNING: replacing module MyModule1.
WARNING: replacing module MyModule1.
WARNING: replacing module MyModule2.
ERROR: LoadError: LoadError: UndefVarError: Param not defined
Stacktrace:
[1] top-level scope at D:\run\defineModule2.jl:7
[2] include(::String) at .\client.jl:457
[3] top-level scope at D:\run\useModule.jl:2
[4] include(::String) at .\client.jl:457
[5] top-level scope at none:1
in expression starting at D:\run\defineModule2.jl:7
in expression starting at D:\run\useModule.jl:2
I believed that, by using the following lines in the beginning of "D:\run\useModule.jl", the mutable struct Param should have be found:
include("D:\\run\\defineModule1.jl"); using .MyModule1
include("D:\\run\\defineModule2.jl"); using .MyModule2
...
Still, error LoadError: UndefVarError: Param not defined is reported.
So, Why can't Param be found by D:\\run\\useModule.jl?

Rails test fails requests did not finish in 60 seconds

After upgrading rails from 4.2 to 5.2 my test gets stuck on a request while it is working in development server I'm getting following failure on running test suit.
Failures:
1) cold end overview shows cold end stats
Failure/Error: example.run
RuntimeError:
Requests did not finish in 60 seconds
# /home/asnad/.rvm/gems/ruby-2.5.0/gems/capybara-2.18.0/lib/capybara/server.rb:94:in `rescue in wait_for_pending_requests'
# /home/asnad/.rvm/gems/ruby-2.5.0/gems/capybara-2.18.0/lib/capybara/server.rb:91:in `wait_for_pending_requests'
# /home/asnad/.rvm/gems/ruby-2.5.0/gems/capybara-2.18.0/lib/capybara/session.rb:130:in `reset!'
# /home/asnad/.rvm/gems/ruby-2.5.0/gems/capybara-2.18.0/lib/capybara.rb:314:in `block in reset_sessions!'
# /home/asnad/.rvm/gems/ruby-2.5.0/gems/capybara-2.18.0/lib/capybara.rb:314:in `reverse_each'
# /home/asnad/.rvm/gems/ruby-2.5.0/gems/capybara-2.18.0/lib/capybara.rb:314:in `reset_sessions!'
# /home/asnad/.rvm/gems/ruby-2.5.0/gems/capybara-2.18.0/lib/capybara/rspec.rb:22:in `block (2 levels) in <top (required)>'
# ./spec/spec_helper.rb:43:in `block (3 levels) in <top (required)>'
# /home/asnad/.rvm/gems/ruby-2.5.0/gems/database_cleaner-1.6.2/lib/database_cleaner/generic/base.rb:16:in `cleaning'
# /home/asnad/.rvm/gems/ruby-2.5.0/gems/database_cleaner-1.6.2/lib/database_cleaner/base.rb:98:in `cleaning'
# /home/asnad/.rvm/gems/ruby-2.5.0/gems/database_cleaner-1.6.2/lib/database_cleaner/configuration.rb:86:in `block (2 levels) in cleaning'
# /home/asnad/.rvm/gems/ruby-2.5.0/gems/database_cleaner-1.6.2/lib/database_cleaner/configuration.rb:87:in `cleaning'
# ./spec/spec_helper.rb:37:in `block (2 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# Timeout::Error:
# execution expired
# /home/asnad/.rvm/gems/ruby-2.5.0/gems/capybara-2.18.0/lib/capybara/server.rb:92:in `sleep'
Top 1 slowest examples (62.59 seconds, 97.0% of total time):
cold end overview shows cold end stats
62.59 seconds ./spec/features/cold_end_overview_spec.rb:13
Finished in 1 minute 4.51 seconds (files took 4.15 seconds to load)
1 example, 1 failure
my spec_helper.rb has configurations
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
config.around(:each) do |example|
DatabaseCleaner[:active_record].clean_with(:truncation)
DatabaseCleaner.cleaning do
if example.metadata.key?(:js) || example.metadata[:type] == :feature
# VCR.configure { |c| c.ignore_localhost = true }
WebMock.allow_net_connect!
VCR.turn_off!
VCR.eject_cassette
example.run
else
# WebMock.disable_net_connect!
VCR.turn_on!
cassette_name = example.metadata[:full_description]
.split(/\s+/, 2)
.join('/')
.underscore.gsub(/[^\w\/]+/, '_')
# VCR.configure { |c| c.ignore_localhost = false }
VCR.use_cassette(cassette_name) { example.run }
VCR.turn_off!
WebMock.allow_net_connect!
end
end
end
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.filter_run :focus
config.run_all_when_everything_filtered = true
config.example_status_persistence_file_path = "spec/examples.txt"
if config.files_to_run.one?
config.default_formatter = 'doc'
end
# Print the 10 slowest examples and example groups at the
# end of the spec run, to help surface which specs are running
# particularly slow.
config.profile_examples = 10
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = :random
# Seed global randomization in this process using the `--seed` CLI option.
# Setting this allows you to use `--seed` to deterministically reproduce
# test failures related to randomization by passing the same `--seed` value
# as the one that triggered the failure.
Kernel.srand config.seed
end
# Selenium::WebDriver.logger.level = :debug
# Selenium::WebDriver.logger.output = 'selenium.log'
Capybara.register_driver :selenium_chrome_headless do |app|
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(chromeOptions: { args: %w[headless no-sandbox disable-dev-shm-usage disable-gpu window-size=1200,1500] }, loggingPrefs: { browser: 'ALL' })
Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities)
end
Chromedriver.set_version '2.39'
Capybara.javascript_driver = :selenium_chrome_headless
Capybara::Screenshot.prune_strategy = :keep_last_run
in my spec the line sign_in current_user takes too much time actually it redirects to a page and do not get response even long time while it is working on development environment.
what can be the reason if you need anything else please comment.
I've just arrived here myself after upgrading from 4.2 to 5.1 and now 5.2, and I'm seeing the same thing in my testing, when I have frozen a test in mid-request with binding.pry, I get the message Requests did not finish in 60 seconds. What a great story, skip to the end for tl;dr (I may have figured it out.)
Now I have upgraded all of the gems, incrementally so I can preserve the capacity to bisect and observe the source of interesting changes like this one. I only noticed this new 60 second timeout after changing over from chromedriver-helper which reported it had been deprecated to the new webdrivers gem that's taking over, but that seems to be not related as I searched webdrivers for any timeout or 60 second value, and only found references to an unrelated Pull Request #60 (fixes Issue #59).
I checked my gem source directory for this message, Requests did not finish in 60 seconds, and found it was not in fact an older version of Capybara, but that it has been raised from versions dating back to at least 3.9.0, and in the most current version 3.24.0 in lib/capybara/server.rb.
The object used there is a Timer which you can find an interface to it here, in the helper:
https://github.com/teamcapybara/capybara/blob/320ee96bb8f63ac9055f7522961a1e1cf8078a8a/lib/capybara/helpers.rb#L79
This particular message is raised out of the method wait_for_pending_requests which passes a hard 60 into the :expire_in named parameter, then after sends any errors that were encountered in the server thread. This means the time is not configurable, probably 60 seconds is a reasonable length of time to wait for a web request in progress to complete, although it's a bit inconvenient for my test.
That method is only called in one place, reset!, which you can find defined here in capybara/session.rb: https://github.com/teamcapybara/capybara/blob/320ee96bb8f63ac9055f7522961a1e1cf8078a8a/lib/capybara/session.rb#L126
The reset! method is an interesting one that comes with some documentation about how it's used. #server&.wait_for_pending_requests looks like it might call wait_for_pending_requests if it has an active server thread in a request, and then raise_server_error! which similarly acts only if #server&.error is truthy.
Now we find that reset! comes with two aliases, this message reset! is received whenever Capybara calls cleanup! or reset_session!. At this point we can probably understand what happened, but it's still a little bit mysterious when I've been using chromedriver-helper and selenium testing for several years, but never recall seeing this 60 second timeout before. I'm hesitant to point the finger at webdriver, but I don't have any other answers for why this timeout is new. I haven't done really anything that could account for it but upgrade to this gem, and any other gems, plus clearing out deprecation warnings.
It seems possible that in Rails 5.1+, capybara calls reset! a lot more, maybe more than in between test examples. Especially when you read that documentation of the method and think about what Single-Page focus there has been now, and consider all of the things that reset! documentation tells you it doesn't reset, clear browser cache/HTML 5 local storage/IndexedDB/Web SQL database/etc — or maybe I'm imagining it, and this isn't new. But I'm imagining there are a lot of ways that it can call reset! and not land in this timeout code, that are likely to be driver-dependent.
Did you change to webdrivers gem by any chance when you did your Rails upgrade?
Edit: I reverted to chromedriver-helper just to be sure, and that wasn't it. What's actually happening is my test is failing in one thread, but the server has left a binding.pry session open. Capybara has moved onto the next test, and thus to get a fresh session it has called reset!, but 60 seconds later I am still in my pry session, and the server is still not ready to serve a root request. I have a feeling that the threading behavior of capybara has changed, in my memory a pry session opened during a server request would block the test from failing until it had returned. But that's apparently not what's happening anymore.
How did you arrive here? I have no idea unfortunately, but this is a fair description of what's happening when that message is received.

delayed_job - NameError - uninitilized constant

I have this custom job which is located in /lib/jobs/MessageNotificationJob.rb
class MessageNotificationJob < Struct.new(:user_id, :message_id)
def perform
#user = User.find(user_id)
#message = Message.find(message_id)
if !message.reciever_open
MessagesMailer.message_notification(#user, #message ).deliver
end
end
end
I call it from a method in the MessagesController with
Delayed::Job.enqueue(MessageNotificationJob.new(#user.id, #msg.id))
In my application.rb I have
config.autoload_paths += Dir["#{config.root}/lib/**/"]
But I get the error
NameError - uninitialized constant MessagesController::MessageNotificationJob:
How do I fix this? I've tried several variations, with this as the latest one as a solution to a similar question. I am missing something?
I haven't used the latest DelayedJob, but it looks an awful like the delayed job doesn't have the MessageNotificationJob class loaded when it runs. Try the following:
# file: config/initializers/custom.rb
require 'message_notification_job'
See also this wiki entry -- I think newer versions of DJ improved the error message (rather than silently failing), but the underlying cause is the same.

Cucumber "--format progress" doesn't work

In my cucumber.yml I've tried to add this option (default: --drb --format progress), but it return an error :
Exception encountered: #<ArgumentError: wrong number of arguments (3 for 2)
Error creating formatter: progress>
When I take it in brackets default: --drb --"format progress" it doesn't helps:
invalid option: --format progress (OptionParser::InvalidOption)
So maybe there is no option, but it should be
And "format pretty" works correctly without any brackets.
I want see not all scenarios in console, but just which has an errors, perhaps there is another way to do this.
Full trace:
wrong number of arguments (3 for 2)
Error creating formatter: progress (ArgumentError)
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/activerecord-3.1.0/lib/active_record/base.rb:1543:in `initialize'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/cli/configuration.rb:168:in `new'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/cli/configuration.rb:168:in `block in formatters'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/cli/configuration.rb:163:in `map'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/cli/configuration.rb:163:in `formatters'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/cli/configuration.rb:68:in `build_tree_walker'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/runtime.rb:42:in `run!'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/cli/main.rb:43:in `execute!'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/cli/main.rb:20:in `execute'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/bin/cucumber:14:in `<top (required)>'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/bin/cucumber:19:in `load'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/bin/cucumber:19:in `<main>'
And If I write option in cucumer.yml the error slightly different:
Exception encountered: #<ArgumentError: wrong number of arguments (3 for 2)
Error creating formatter: progress>
backtrace:
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/activerecord-3.1.0/lib/active_record/base.rb:1543:in `initialize'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/cli/configuration.rb:168:in `new'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/cli/configuration.rb:168:in `block in formatters'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/cli/configuration.rb:163:in `map'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/cli/configuration.rb:163:in `formatters'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/cli/configuration.rb:68:in `build_tree_walker'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/runtime.rb:42:in `run!'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/cucumber-1.1.0/lib/cucumber/cli/main.rb:43:in `execute!'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/spork-0.9.0.rc9/lib/spork/test_framework/cucumber.rb:24:in `run_tests'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/spork-0.9.0.rc9/lib/spork/run_strategy/forking.rb:13:in `block in run'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/spork-0.9.0.rc9/lib/spork/forker.rb:21:in `block in initialize'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/spork-0.9.0.rc9/lib/spork/forker.rb:18:in `fork'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/spork-0.9.0.rc9/lib/spork/forker.rb:18:in `initialize'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/spork-0.9.0.rc9/lib/spork/run_strategy/forking.rb:9:in `new'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/spork-0.9.0.rc9/lib/spork/run_strategy/forking.rb:9:in `run'
/home/alder/.rvm/gems/ruby-1.9.2-p290#global/gems/spork-0.9.0.rc9/lib/spork/server.rb:48:in `run'
/home/alder/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/drb/drb.rb:1558:in `perform_without_block'
/home/alder/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/drb/drb.rb:1518:in `perform'
/home/alder/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/drb/drb.rb:1592:in `block (2 levels) in main_loop'
/home/alder/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/drb/drb.rb:1588:in `loop'
/home/alder/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/drb/drb.rb:1588:in `block in main_loop'
I have a Spork by the way maybe it's a problem.
Based on the updated information in your question, I think I see the problem (hence I'm posting another answer as it's completely different to my other one). It looks like Cucumber is trying to instantiate an ActiveRecord class, so I suspect you have a model named 'Progress' in your project somewhere, which Cucumber is trying to create instead of of the actual formatter.
I was able to reproduce your problem (close enough, anyway) by adding this class in the 'support' folder:
class Progress
def initialize
raise "I don't exist!"
end
end
According to the docs, you should be able to specify a fully qualified class name here i.e. --format Cucumber::Formatter::Progress, to force Cucumber to use it's own formatter. However, I tried this and it still doesn't work, there seems to be a bug in how Cucumber resolves the fully-qualified name.
I was able to get around this by adding this line to my env.rb file:
require 'cucumber/formatter/progress'
Which then allowed me to run cucumber --format progress successfully.
I think that, as env.rb gets executed before any other code, then Cucumber's Progress class will be the first one that gets found when creating the formatter.
It looks from the output you've pasted in, that you have an extra angle ('>') bracket floating around in your cucumber.yml file:
Error creating formatter: progress>
Unless that's a typo in your question, for some reason Cucumber is trying to create a formatter named 'progress>', so you probably just need to find and remove the extra angle bracket.
Edit: This wasn't the problem at all, see my other answer

Geokit Gem 1.5 and Ruby 1.9.2 => "incompatible character encodings: UTF-8 and ASCII-8BIT"

I am currently writing a rails app using bleeding edge stuff. Rails3, rSpec2, Ruby 1.9.2 and Geokit 1.5.0. When i try to geocode addresses that have special characters that are not in ASCII-8Bit i get this error:
incompatible character encodings:
UTF-8 and ASCII-8BIT
The Trace is like this:
1) Spot Basic Validations should calculate lat and lng
Failure/Error: spot = Spot.create!({
incompatible character encodings: UTF-8 and ASCII-8BIT
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/geokit-1.5.0/lib/geokit/geocoders.rb:435:in `do_geocode'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/geokit-1.5.0/lib/geokit/geocoders.rb:126:in `geocode'
# ./app/models/spot.rb:26:in `geocode_address'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activesupport-3.0.0.rc/lib/active_support/callbacks.rb:409:in `_run_validation_callbacks'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activemodel-3.0.0.rc/lib/active_model/validations/callbacks.rb:53:in `run_validations!'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activemodel-3.0.0.rc/lib/active_model/validations.rb:168:in `valid?'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/validations.rb:55:in `valid?'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/validations.rb:75:in `perform_validations'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/validations.rb:49:in `save!'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/attribute_methods/dirty.rb:30:in `save!'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/transactions.rb:242:in `block in save!'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/transactions.rb:289:in `block in with_transaction_returning_status'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/connection_adapters/abstract/database_statements.rb:139:in `transaction'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/transactions.rb:204:in `transaction'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/transactions.rb:287:in `with_transaction_returning_status'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/transactions.rb:242:in `save!'
# /Users/nilsriedemann/.rvm/gems/ruby-1.9.2-rc2/gems/activerecord-3.0.0.rc/lib/active_record/validations.rb:34:in `create!'
# ./spec/models/spot_spec.rb:13:in `block (2 levels) in <top (required)>'
I used # coding: utf-8 in all of my related files (specs, factories and model). Yet i get this error when i use an address like "Elsassers Straße 27".
Any hints? I thought Geokit was already compatible with 1.9.1 and therefore with all this new encoding thing.
Using CGI.escape is not a good idea, as it gives unexpected results. Try "Oslo, Norway" with and without CGI.escape, you'll see what I mean.
A better solution is to use Iconv on the location:
ic = Iconv.new('US-ASCII//IGNORE', 'UTF-8')
utf8location = ic.iconv(location)
Cheers!
EDIT: I had a suggestion by Wes Gamble for a edit here, which I think is relevant:
Using //IGNORE will remove any non-ASCII characters. But in many (most) cases, you may want to transliterate certain characters such as umlauts (e.g. "Zürich" will become "Zurich") or carons (e.g "Niš" will become "Nis") in order to successfully geocode them. If you ignore non-ASCII characters, then "Zürich" will become "Zrich" and "Niš" will become "Ni", neither of which will successfully geocode.
For this you want to use
ic = Iconv.new('US-ASCII//TRANSLIT', 'UTF-8')
Note that the conversion will throw an exception if the transliteration cannot be completed so make sure you handle that.
CGI.escape seems to be more accurate than Geokit::Inflector::url_escape.
Here are the results of encoding "Elsassers Straße 27"
>> CGI.escape(address)
=> "Elsassers+Stra%C3%9Fe+27"
While
>> Geokit::Inflector::url_escape(address)
=> "Elsassers+Stra%C3e+27"
The letter ß should show as c39F (as per http://www.utf8-chartable.de/unicode-utf8-table.pl)
In addition, debug statement was blowing up (I knew there was a reason to check if debug logging is enabled :)
So, here is my solution for GoogleGeocoder3, I guess others will have a similar problem
module Geokit
module Geocoders
class GoogleGeocoder3 < Geocoder
def self.do_geocode(address, options = {})
bias_str = options[:bias] ? construct_bias_string_from_options(options[:bias]) : ''
address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
#use CGI.escape instead of Geokit::Inflector::url_escape
url ="http://maps.google.com/maps/api/geocode/json?sensor=false&address=#{CGI.escape(address_str)}#{bias_str}"
res = self.call_geocoder_service(url)
return GeoLoc.new if !res.is_a?(Net::HTTPSuccess)
json = res.body
# escape results of json
logger.debug "Google geocoding. Address: #{address}. Result: #{CGI.escape(json)}"
return self.json2GeoLoc(json, address)
end
end
end
end
Are you using Postgres and pg gem v0.8? Upgrade to 0.9
I know it a very very late answer, but I have written a Google geocoder for the Geokit gem that handles all of this Incompatibility errors. This Geocoder uses the newest V3 API of Google's geocoding service. The advantage is that now it does not parse XML but rather JSON which is faster, paired with the required gem Yajl (a super fast json parser for ruby) is way faster. My benchmarks show about 1.5x times faster than the old way.
https://github.com/rubymaniac/geokit-gem
I had the same problem and I solved this by adding CGI.escape() like this:
geo = Geokit::Geocoders::MultiGeocoder.geocode(CGI.escape(address))