I am getting the following error in Ruby Koans:
AboutHashes#test_accessing_hashes_with_fetch has damaged your karma.
The Master says:
You have not yet reached enlightenment.
I sense frustration. Do not be afraid to ask for help.
The answers you seek...
class or module required
Please meditate on the following code:
/home/s/Downloads/github/rubykoans/about_hashes.rb:26:in `test_accessing_hashes_with_fetch'
The line in question is part of the following method:
def test_accessing_hashes_with_fetch
hash = { :one => "uno" }
assert_equal "uno", hash.fetch(:one)
assert_raise(nil) do
hash.fetch(:doesnt_exist)
end
As you can see, it is asking for a class or module, so I am confused as this is not an error I've encountered before in the Koans.
The problem is on these lines:
assert_raise(nil) do
hash.fetch(:doesnt_exist)
end
The assert_raise test macro expects as its argument a class of Exception. You provided nil.
To skip to the answer, calling fetch on a hash with a key that doesn't exist in the hash will raise a KeyError Exception. So the test should have this:
assert_raise(KeyError) do
hash.fetch(:doesnt_exist)
end
Related
error:C:\Users\RR\Desktop\ruby_sandbox>ruby classes.rb classes.rb:44:
syntax error, unexpected end-of-input, expecting keyword_end
my code is:
class Animal
attr_accessor :name,:age,:sex,:location
def initialize(age=18,sex="not available",location="not specified")
puts "details of animal"
#age=age
#sex=sex
#location=location
end
def condition(age,name)
if animal.age>animal1.age
puts "#{animal.name } is older than #{animal1.name}"
else
puts "animals age are in increasing order"
end
end
Please take care about your indentation while writing ruby you will see where you missed the end keyword.
But in your case the problem is not only about the indentation before start to fix it. You can check some documentation about Class and Instance Methods in Ruby or this tutorial can help you in your case.
Good luck.
Rspec code is
it "calls calculate_word_frequency when created" do
expect_any_instance_of(LineAnalyzer).to receive(:calculate_word_frequency)
LineAnalyzer.new("", 1)
end
Code of class is
def initialize(content,line_number)
#content = content
#line_number = line_number
end
def calculate_word_frequency
h = Hash.new(0)
abc = #content.split(' ')
abc.each { |word| h[word.downcase] += 1 }
sort = h.sort_by {|_key, value| value}.reverse
puts #highest_wf_count = sort.first[1]
a = h.select{|key, hash| hash == #highest_wf_count }
puts #highest_wf_words = a.keys
end
This test gives an error
LineAnalyzer calls calculate_word_frequency when created
Failure/Error: DEFAULT_FAILURE_NOTIFIER = lambda { |failure, _opts| raise failure }
Exactly one instance should have received the following message(s) but didn't: calculate_word_frequency
How I resolve this error.How I pass this test?
I believe you were asking "Why do I get this error message?" and not "Why does my spec not pass?"
The reason you're getting this particular error message is you used expect_any_instance_of in your spec, so RSpec raised the error within its own code rather than in yours essentially because it reached the end of execution without an exception, but without your spy being called either. The important part of the error message is this: Exactly one instance should have received the following message(s) but didn't: calculate_word_frequency. That's why your spec failed; it's just that apparently RSpec decided to give you a far less useful exception and backtrace.
I ran into the same problem with one of my specs today, but it was nothing more serious than a failed expectation. Hopefully this helps clear it up for you.
The entire point of this test is to insure that the constructor invokes the method. It's written very clearly, in a very straight forward way.
If you want the test to pass, modify the constructor so it invokes the method.
If I run this simple Ruby code regularly, it works fine:
class String
def add_two
self + "2"
end
end
puts "hello".add_two
It prints "hello2" as it should. But this fails:
:ruby
class String
def add_two
self + "2"
end
end
puts "hello".add_two
This code produces an error:
NoMethodError at /
undefined method `add_two' for "hello":String
Any ideas what's wrong?
(Not sure if it matters, but I'm using HAML with Sinatra, which is running on Apache with the Passenger module.)
I would suggest that String is in another namespace and therefor another class.
What happens with that?
class ::String
I put your code as is into one of my Haml views in a Rails app and I got a different error to you:
SyntaxError at /
class definition in method body
So I wondered whether it was Haml's :ruby filter that was complaining, but since it "Parses the filtered text with the normal Ruby interpreter", it seemed unlikely. So, I searched for more info about the error and found references (see below) that led me to this, which works (but, really, should never be used):
:ruby
String.module_eval do
def add_two
self + "2"
end
end
puts "hello".add_two
References:
Class inside a Method Body
Class (Re)definition in Method Body
Consider the following two trivial models:
class Iq
def score
#Some Irrelevant Code
end
end
class Person
def iq_score
Iq.new(self).score #error here
end
end
And the following Rspec test:
describe "#iq_score" do
let(:person) { Person.new }
it "creates an instance of Iq with the person" do
Iq.should_receive(:new).with(person)
Iq.any_instance.stub(:score).and_return(100.0)
person.iq_score
end
end
When I run this test (or, rather, an analogous one), it appears the stub has not worked:
Failure/Error: person.iq_score
NoMethodError:
undefined method `iq_score' for nil:NilClass
The failure, as you might guess, is on the line marked "error here" above. When the should_receive line is commented out, this error disappears. What's going on?
Since RSpec has extended stubber functionality, now following way is correct:
Iq.should_receive(:new).with(person).and_call_original
It will (1) check expectation (2) return control to original function, not just return nil.
You're stubbing away the initializer:
Iq.should_receive(:new).with(person)
returns nil, so Iq.new is nil. To fix, just do this:
Iq.should_receive(:new).with(person).and_return(mock('iq', :iq_score => 34))
person.iq_score.should == 34 // assert it is really the mock you get
I am trying to follow a tutorial on TDD with RSpec that contains the following line:
it 'must have a first_name' do
p = Person.new
p.should_not be_valid
p.errors.on(:first_name).should_not be_nil
end
However I receive the following message in my test:
undefined method `on' for #ActiveModel::Errors:0x007fde0c3eceb0>
What is the correct way to write the code above.
The correct function is errors_on. So that line should be
p.errors_on(:first_name).should_not be_nil