Rspec, fail testing date - ruby-on-rails

I'm trying to test this :
it "should calculate the max_validation_deadline" do
tasting = Tasting.create!(valid_attributes)
expect ( tasting.max_validation_deadline.to_s ).to eq(today_plus_one.to_s)
end
But it fails. When I'm debugging it I'm having this.
(byebug) tasting.max_validation_deadline.to_s
"2016-12-13 01:00:00 UTC"
(byebug) today_plus_one.to_s
"2016-12-13 01:00:00 UTC"
(byebug) expect ( tasting.max_validation_deadline.to_s ).to eq(today_plus_one.to_s)
*** ArgumentError Exception: bad value for range
Why does it fail saying bad value for range as I'm passing two strings ?
Edit
Here is a full byebug when I'm not testing with to_s.
bundle exec rspec spec/models/tasting_spec.rb
........
[76, 85] in server/spec/models/tasting_spec.rb
76: end
77:
78: it "should calculate the max_validation_deadline" do
79: tasting = Tasting.create!(valid_attributes)
80: byebug
=> 81: expect ( tasting.max_validation_deadline ).to eq(today_plus_one)
82: end
83:
84: it "should calculate the current_opened_places" do
85: tasting = Tasting.create!(valid_attributes)
(byebug) expect ( tasting.max_validation_deadline ).to eq(today_plus_one)
*** NoMethodError Exception: undefined method `to' for Tue, 13 Dec 2016 01:00:00 UTC +00:00:Time
nil
(byebug)

It's a formatting error.
Replace...
expect ( tasting.max_validation_deadline ).to eq(today_plus_one)
with...
expect( tasting.max_validation_deadline ).to eq(today_plus_one)
In the first method, the (expression).to is the passed parameter, when it should be just (expression)
You can demonstrate this problem easily...
expect ("hello").to eq("hello")
generates "bad value for range"
expect("hello").to eq("hello")
is fine.

Related

Date.today.to_s(:long) not converting to string

I am working on an assignment and I have written the following method based on our instructions:
def create_todolist(params)
due_date = Date.today.to_s(:long)
TodoList.create(list_name: params[:name],list_due_date: params[:due_date])
end
But when I run the rspec test, I get the following error:
1) Assignment rq03 rq03.2 assignment code has create_todolist method should create_todolist with provided parameters
Failure/Error: expect(testList.list_due_date).to eq due_date
expected: Thu, 07 May 2020
got: "2020-05-07"
(compared using ==)
Diff:
## -1,2 +1,2 ##
-Thu, 07 May 2020
+"2020-05-07"
# ./spec/assignment_spec.rb:177:in `block (4 levels) in <top (required)>'
# ./spec/assignment_spec.rb:14:in `block (2 levels) in <top (required)>'
Here is the rspec test:
context "rq03.2 assignment code has create_todolist method" do
it { is_expected.to respond_to(:create_todolist) }
it "should create_todolist with provided parameters" do
expect(TodoList.find_by list_name: "mylist").to be_nil
due_date=Date.today
assignment.create_todolist(:name=> 'mylist', :due_date=>due_date)
testList = TodoList.find_by list_name: 'mylist'
expect(testList.id).not_to be_nil
expect(testList.list_name).to eq "mylist"
expect(testList.list_due_date).to eq due_date
expect(testList.created_at).not_to be_nil
expect(testList.updated_at).not_to be_nil
end
end
At first I had just due_date = Date.today and was getting the same error and I'm not sure how to fix it. I'm wondering if it is because I am using a different version of ruby/rails than what was used when the course was created ( 5 years ago -_-).
Any help would be greatly appreciated!
Thank you :)
You are trying to compare a Date object:
due_date = Date.today
With a string object you generated while you created your record:
Date.today.to_s(:long)
As you can see, these are different types of objects:
Date.today.to_s(:long)
=> "May 07, 2020"
Date.today.to_s(:long).class
=> String
Date.today
=> 2020-05-07
Date.today.class
=> Date
Date.today.to_s(:long) == Date.today
=> false
I figured it out. When I was creating the TodoLists table, I didn't specify the migration type as :date. so by default, due_date was set to be a string. So I set to type :date and changed due_date to equal:
due_date = Date.today
Thank you for taking the time to help me out :)

Rails/Rspec - objects not existing until interacted with

I have the following code where I create some instances of records using FactoryBot:
describe "#force_recalculation_of_lab_container_labs" do
(1..5).each do |n|
let("lab_#{n}".to_sym) { create(:lab) }
let("lab_container_#{n}".to_sym) { create(:skill_path) }
let("lab_collection_#{n}".to_sym) do
create(:lab_collection, lab_container: eval("lab_container_#{n}"))
end
end
context 'when adding labs' do
it "starts with 0 labs" do
expect(lab_collection_1.labs.count).to eq(0)
end
(1..3).each do |n|
let("lab_collection_inclusion_#{n}") do
create(:lab_collection_inclusion,
included_item_id: eval("lab_#{n}").id,
included_item_type: 'Lab',
lab_collection_id: eval("lab_collection_1").id,
subscribed: 0)
end
end
it "updates the lab total correctly after adding labs" do
binding.pry
end
end
end
From my pry point, I receive the following:
LabCollectionInclusion.count
=> 0
lab_collection_1.lab_collection_inclusions.count
=> 0
When I then call a record individually, it appears to then exist:
lab_collection_inclusion_1
<LabCollectionInclusion:0x000055a45c985b10
id: 1,
included_item_id: 1,
included_item_type: "Lab",
lab_collection_id: 4,
subscribed: false,
created_at: Thu, 01 Nov 2018 10:48:00 UTC +00:00,
updated_at: Thu, 01 Nov 2018 10:48:00 UTC +00:00>
After which point it exists when searching:
LabCollectionInclusion.count
=> 1
lab_collection_1.lab_collection_inclusions.count
=> 1
Obviously I don't want to have to do this for every record so my 2 questions are first of all why is this happening, and second of all how to correct it?
Thanks in advance
This is expected behavior because let is designed to lazy-evaluated. Quote from the docs of let:
Note that let is lazy-evaluated: it is not evaluated until the first time the method it defines is invoked. You can use let! to force the method's invocation before each example.
As described in the documentation: Just let! (note the !) instead of let when you need the records to be created without calling them by their name first.

post command not rendering data in Rspec

I have defined a controller Add. In controller i have defined a function (add_params)
def add_values
ans = params[:first_element] + params[:second_element]
render :json => {:result => ans}.to_json
end
in routes file i have declared post :add_params
if i call curl -X POST -H "Content-Type:application/json" -d '{"first_element" : 3, "second_element" :2}' http://localhost:8000/add/add_values it return {"result":5}
but when i tried to test in Rspec as
describe AddController, :type => :request do
it "must return 5" do
post "http://localhost:8000/add/add_values", {"first_element" : 3, "second_element" :2}.to_json
expect(JSON.parse(response.body)["result"]).to eq "5"
end
end
it gives error as
Failure/Error: expect(response["result_is"]).to eq 5
expected: 5
got: nil
(compared using ==)
# ./spec/controller/add_controller_spec.rb:67:in `block (2 levels) in <top (required)>'
i am using rails 3.2.16 , ruby 2.1.5 , rspec 3.0.0
Is pretty weird that you receive
Failure/Error: expect(response["result_is"]).to eq 5
if your expectation is
expect(JSON.parse(response.body)["result"]).to eq "5"
the parameters of expect function are different one each other.
You should receive an error like this
Failure/Error: expect(JSON.parse(response.body)["result_is"]).to eq "5"
Are you sure your expectation is not
expect(response["result_is"]).to eq 5
?

Tests are not passing

I'm using RSpec for tests and I don't know how to get this to green.
In this case, I have a model called "PartType" that holds an attribute called "quotation".
The value for quotation comes from a form, so it will be a string.
To demonstrate you can go to console and type:
(1..1000).includes?("50") # false
but..
(1..1000).includes?(50) # true
And this value can have decimals. So I needed to do a "type_cast".
I have this on my PartTypemodel:
before_validation :fix_quotation, :if => :quotation_changed?
protected
def fix_quotation
self[:quotation] = quotation_before_type_cast.tr(' $, ' , '.' )
end
This are working as expected BUT when go to tests, it fails.
Here is my part_type_spec.rb:
require 'spec_helper'
describe PartType do
before(:each) do
#attr = { :title => "Silver", :quotation => 100 }
end
it "should create a instance given a valid attributes" do
PartType.create!(#attr)
end
it "should accept null value for quotation" do
PartType.new(#attr.merge(:quotation => nil)).should be_valid
end
it "should accept 0 value for quotation" do
PartType.new(#attr.merge(:quotation => 0)).should be_valid
end
end
And finally the failing tests:
Failures:
1) PartType should create a instance given a valid attributes
Failure/Error: PartType.create!(#attr)
NoMethodError:
undefined method tr' for 100:Fixnum
# ./app/models/part_type.rb:7:infix_quotation'
# ./spec/models/part_type_spec.rb:10:in `block (2 levels) in '
2) PartType should accept 0 value for quotation
Failure/Error: PartType.new(#attr.merge(:quotation => 0)).should be_valid
NoMethodError:
undefined method tr' for 0:Fixnum
# ./app/models/part_type.rb:7:infix_quotation'
# ./spec/models/part_type_spec.rb:18:in `block (2 levels) in '
Finished in 0.06089 seconds
3 examples, 2 failures
Your include? snippets are wrong, I got false in the first, true in the second.
before_validation is executed and quotation_before_type_cast is expected to be a String but it is a Fixnum. Change 100 to '100' and 0 to '0'.

I am not able to subtract two dates from each other using Ruby...why?

this is the code I have. It is a method for a contact.rb (Contact is a model):
def event_delay event
# find instance of contact_event
puts "+++++++++++++++inside event_delay method"
event_class = event.class.name
event_id = event_class.foreign_key.to_sym
#puts event_id
contact_event_class = "Contact#{event_class}".constantize
#puts contact_event_class
contact_event = contact_event_class.first(:conditions =>
{:contact_id => self.id,
event_id => event.id})
#puts "inspect contact_event"
#puts contact_event.inspect
if !contact_event.nil?
puts "---- #{contact_event.title} not nill"
puts contact_event.id
date_sent = contact_event.date_sent
target_send_date = self.date_entered + event.days
puts "date_sent:"
puts date_sent.to_date
puts "target send date:"
puts target_send_date
return date_sent - target_send_date
end
end
The goal is to return the difference in days between the time a date_sent to the time target_send_date. But I get the following error:
undefined method `-#' for Sun, 08 Aug 2010:Date
Maybe both values are not dates? The - method is defined so that's why I'm thinking that you might not have two dates. Does this work in irb for you?
irb(main):001:0> require "date"
=> true
irb(main):002:0> Date.new(2010, 10, 20) - Date.new(2010, 9, 20)
=> Rational(30, 1)
irb(main):003:0>
After migrating to Rails 3.2, I got the same strange error when running specs, but was able to isolate it:
3.days.ago - Date.today
=> NoMethodError: undefined method `-#' for Sun, 29 Apr 2012:Date
'3.days.ago' produces an ActiveSupport::TimeWithZone object, which (apparently) does not mix with the Date object that Date.today gives you.

Resources