Why is this Rails 4 model test failing? - ruby-on-rails

I have the following model test in Rails 4:
require 'test_helper'
class AwardTest < ActiveSupport::TestCase
def test_validity_of_year
# test for rejection of missing year
award = Award.new({name: "Test award, student_id: 1"})
assert !award.valid?
# test under lower boundary
award.year = 1979
assert !award.valid?
# lower boundary
award.year = 1980
assert award.valid?
# top boundary
award.year = Date.today.year
assert award.valid?
# top boundary case, award isn't valid for next year
award.year = Date.today.year + 1
assert !award.valid?
end
end
Here is the award model:
class Award < ApplicationRecord
belongs_to :student
validates_presence_of :name, :year
validates_inclusion_of :year, in: (1980..Date.today.year)
end
Here is the output of my award_test.rb
bundle exec rake test TEST=test/models/award_test.rb
DEPRECATION WARNING: alias_method_chain is deprecated. Please, use Module#prepend instead. From module, you can access the original method using super. (called from included at .rvm/gems/ruby-2.2.2#rails/gems/turbolinks-2.5.3/lib/turbolinks/xhr_url_for.rb:7)
Run options: --seed 53138
# Running:
F
Failure:
AwardTest#test_validity_of_year [/Users/marklocklear/sandbox/students03/test/models/award_test.rb:16]:
Failed assertion, no message given.
bin/rails test test/models/award_test.rb:4
Finished in 0.042099s, 23.7538 runs/s, 71.2614 assertions/s.
1 runs, 3 assertions, 1 failures, 0 errors, 0 skips
If I run this manually in the console I get...
2.2.2 :037 > award = Award.new({name: "Test award", student_id: 1})
=> #<Award id: nil, name: "Test award", year: nil, student_id: 1, created_at: nil, updated_at: nil>
2.2.2 :038 > award.valid?
Student Load (0.1ms) SELECT "students".* FROM "students" WHERE "students"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
=> false
2.2.2 :039 > award.year = 1979
=> 1979
2.2.2 :040 > award.valid?
=> false
2.2.2 :041 > award.year = 1980
=> 1980
2.2.2 :042 > award.valid?
=> true

Related

comparison of String with ActiveSupport::TimeWithZone failed

My application gives users the opportunity to create events with a start and end time:
>> Event.where('end_time < ?', 1.days.ago).first
Event Load (0.3ms) SELECT "events".* FROM "events" WHERE (end_time < '2017-12-21 13:30:36.411209') ORDER BY "events"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<Event id: 1, user_id: 1, place: "london", start_time: "2017-08-26 20:00", end_time: "2017-08-26 22:00", note: "Note", note_id: 355, picture: "dwarf_hammering.jpg", created_at: "2017-08-14 11:27:16", updated_at: "2017-08-14 11:27:16">
As you can see the start_time and end_time are String with a pre-defined format, and Active Record is able to compare them against a Time instance.
I created a Sidekiq job to delete all events that are older than one day:
class EventsCleanerWorker
include Sidekiq::Worker
def perform
events = Event.where('end_time < ?', 1.days.ago)
if events.any?
events.delete_all
end
end
end
Inside test/fixtures/events.yml I created 6 events: two of them have an end_time older than one day, as the event below:
event3:
user: John
place: "London"
start_time: 3.days.ago.strftime("%Y-%m-%d %H:%M")
end_time: 2.days.ago.strftime("%Y-%m-%d %H:%M")
note: "A thrilling adventure"
Then I created the following test:
def test_events_cleaner_worker_inline_mode
assert Event.count == 6
assert events(:event3).end_time < 1.days.ago
EventsCleanerWorker.perform_async
assert Event.all.reload.count == 4
assert_equal 0, EventsCleanerWorker.jobs.size
end
However, when I run this test I receive the following error:
ArgumentError: comparison of String with ActiveSupport::TimeWithZone failed
This error is referred to assert events(:event3).end_time < 1.days.ago
If I remove this line the test fails because the test expects Event.all.reload.count to be 6 instead of 4. I have no idea why the string generated by end_time inside the events fixtures cannot be compared against Time, while this is possible in the dev environment.
start_time and end_time in the fixture should be embed in ERB as follows:
event3:
user: John
place: "London"
start_time: <%= 3.days.ago.strftime("%Y-%m-%d %H:%M") %>
end_time: <%= 2.days.ago.strftime("%Y-%m-%d %H:%M") %>
note: "A thrilling adventure"

How to show values of a instance with line break in Rails console

I start to using pry in a rails console.
When I get a instance of a Rails model, the values are shown without line breaks like this:
pry(#<Class:0x1022f60e0>):1> first
=> #<Article id: 1, name: "What is Music", content: "Music is an art form in which the medium is sound o...", created_at: "2011-08-24 20:35:29", updated_at: "2011-08-24 20:37:22", published_at: "2011-05-13 23:00:00">
from http://railscasts.com/episodes/280-pry-with-rails?view=asciicast
Is there way to show the values with line breaks like this?
Article
id: 1
name: "What is Music"
content: "Music is an art form in which the medium is sound o..."
created_at: "2011-08-24 20:35:29"
updated_at: "2011-08-24 20:37:22"
published_at: "2011-05-13 23:00:00"
You could call .to_yaml on the model instance! It returns a string that's formatted almost exactly like you're requesting it to be.
Here are some examples of to_yaml output:
http://yaml4r.sourceforge.net/doc/page/examples.htm
I would recommend that you install awesome_print.
Add it to your Gemfile:
group :development do
gem 'awesome_print'
end
And install it with bundle install.
Now use ap to print it in the console:
pry(#<Class:0x1022f60e0>):1> ap first
#<Article:0x1022f60e0> {
:id => 1,
:name => "What is Music"
:content => "Music is an art form in which the medium is sound o..."
:created_at => "2011-08-24 20:35:29"
:updated_at => "2011-08-24 20:37:22"
:published_at => "2011-05-13 23:00:00"
}
I think, the below trick will work for you.
arup#linux-wzza:~/Rails/model_prac> rails c
Loading development environment (Rails 4.1.4)
2.1.2 :001 > Comment.first
Comment Load (0.4ms) SELECT "comments".* FROM "comments" ORDER BY "comments"."id" ASC LIMIT 1
=> #<Comment id: 1, value_old: "I am a good Boy.", value_new: "I am a bad Boy.", created_at: "2014-08-02 17:36:14", updated_at: "2014-08-02 18:21:42">
2.1.2 :002 > y Comment.first
Comment Load (0.4ms) SELECT "comments".* FROM "comments" ORDER BY "comments"."id" ASC LIMIT 1
--- !ruby/object:Comment
attributes:
id: 1
value_old: I am a good Boy.
value_new: I am a bad Boy.
created_at: 2014-08-02 17:36:14.249466000 Z
updated_at: 2014-08-02 18:21:42.511522000 Z
=> nil
2.1.2 :003 >

Mongomapper querying on 'belongs_to' model

I have two models:
class Post
include MongoMapper::Document
many :comments
key :content, String
end
and
class Comment
include MongoMapper::Document
belongs_to :post
key :post_id, ObjectId
key :content, String
end
in a rails console session I can find all Posts:
Post.all # -> [#<Post _id: BSON::ObjectId('519b0b613…
and all comments associated with a Post:
post = Post.first # -> #<Post _id: BSON::ObjectId('519b0b613e477b…
post.comments # -> [#<Comment _id: BSON::ObjectId('519d14f93e…
however, the following query strangely returns an empty array
Comment.all # -> []
Why? How can I get a list of all comments independently of the posts?
With models exactly as per your post, it works for me as shown in the the following test,
running rails (3.2.13), mongo_mapper (0.12.0), mongo (1.6.4). Next time please post the full minimal script, you probably just have a simple error.
test/unit/post_test.rb
require 'test_helper'
class PostTest < ActiveSupport::TestCase
def setup
Post.delete_all
Comment.delete_all
end
test "post and comment" do
post = Post.create(:content => 'Twas brillig')
comment = Comment.create(:post_id => post.id, :content => 'and the slythy toves')
post.comments << comment
assert_equal 1, Post.count
assert_equal 1, Comment.count
puts
puts "all posts: #{Post.all.inspect}"
puts "first post comments: #{Post.first.comments.inspect}"
puts "all comments: #{Comment.all.inspect}"
end
end
$ rake test
Run options:
# Running tests:
[1/1] PostTest#test_post_and_comment
all posts: [#<Post _id: BSON::ObjectId('51ddb56a7f11ba9bbf000001'), content: "Twas brillig">]
first post comments: [#<Comment _id: BSON::ObjectId('51ddb56a7f11ba9bbf000002'), content: "and the slythy toves", post_id: BSON::ObjectId('51ddb56a7f11ba9bbf000001')>]
all comments: [#<Comment _id: BSON::ObjectId('51ddb56a7f11ba9bbf000002'), content: "and the slythy toves", post_id: BSON::ObjectId('51ddb56a7f11ba9bbf000001')>]
Finished tests in 0.036030s, 27.7546 tests/s, 0.0000 assertions/s.
1 tests, 0 assertions, 0 failures, 0 errors, 0 skips
ruby -v: ruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-darwin12.3.0]

RSpec Model Validation failing but works fine in Rails Console?

I have been really stuck on this problem. My validation for my model fails (like it should) when I'm testing it out in rails console, but my rspec example fails because it validates anyway (which it shouldn't). What am I missing here or where should I start looking?
Thanks,
Ivan
See below:
ivan:~/Development/ruby/IvanEnviromanRefinery [git:master+] → bundle exec rspec ../refinerycms-link/
.............................F.
Failures:
1) BlogPost bookmark links must have a link url if it is a link
Failure/Error: Factory.build(:post,
expected valid? to return false, got true
# /Users/ivan/Development/ruby/refinerycms-link/spec/models/blog_post_spec.rb:197:in `block (3 levels) in <top (required)>'
Finished in 6.56 seconds
31 examples, 1 failure
Failed examples:
rspec /Users/ivan/Development/ruby/refinerycms-link/spec/models/blog_post_spec.rb:196 # BlogPost bookmark links must have a link url if it is a link
ivan:~/Development/ruby/IvanEnviromanRefinery [git:master+] → rails console
Loading development environment (Rails 3.0.9)
ruby-1.9.2-p180 :001 > b = BlogPost.new
=> #<BlogPost id: nil, title: nil, body: nil, draft: nil, published_at: nil, created_at: nil, updated_at: nil, user_id: nil, cached_slug: nil, custom_url: nil, link_url: nil, is_link: nil, custom_teaser: nil>
ruby-1.9.2-p180 :002 > b.title=' 2011-06-24 8:34 '
=> " 2011-06-24 8:34 "
ruby-1.9.2-p180 :003 > b.body='goo'
=> "goo"
ruby-1.9.2-p180 :004 > b.is_link = true
=> true
ruby-1.9.2-p180 :005 > b.valid?
=> false
ruby-1.9.2-p180 :007 > b.save
=> false
ruby-1.9.2-p180 :008 > b.errors
=> {:link_url=>["must have a link_url if is_link is true"]}
ruby-1.9.2-p180 :009 >
require 'spec_helper'
Dir[File.expand_path('../../../features/support/factories/*.rb', __FILE__)].each{|factory| require factory}
describe BlogPost do
let(:blog_post ) { Factory :post }
...
describe "bookmark links" do
it "may have a bookmark link" do
Factory.build(:post,
:title => "a link",
:body => "link text",
:is_link => true,
:link_url => "http://example.com").should be_valid
end
it "must have a link url if it is a link" do
Factory.build(:post,
:title => "a link",
:body => "link text",
:is_link => true).should_not be_valid
end
end
end
Are you certain that in your second expectation the link_url isnt set somehow? Try outputting the value and check the logs
it "must have a link url if it is a link" do
post = Factory.build(:post,
:title => "a link",
:body => "link text",
:is_link => true)
Rails.logger.info "Post link: #{post.link_url}"
post.should_not be_valid
end

Rails: Some seeds don't appear to be saving

It appears some of my seeds are not saving. For starters, I will show a console session so you can see that the 'instructor_id' is indeed being set in the console, but not when I seed.
ruby-1.9.2-p180 :015 > c = Course.find 2
Course Load (1.6ms) SELECT "courses".* FROM "courses" WHERE "courses"."id" = $1 LIMIT 1 [["id", 2]]
=> #<Course id: 2, name: "Microcomputers II Lab", course_code: "CE-420L", instructor_id: nil, school_id: nil, created_at: "2011-06-04 19:40:32", updated_at: "2011-06-04 19:40:32">
ruby-1.9.2-p180 :016 > c.instructor = Instructor.first
Instructor Load (0.6ms) SELECT "instructors".* FROM "instructors" LIMIT 1
=> #<Instructor id: 1, name: "Instructor Name", created_at: "2011-06-04 19:40:32", updated_at: "2011-06-04 19:40:32">
ruby-1.9.2-p180 :017 > c
=> #<Course id: 2, name: "Microcomputers II Lab", course_code: "CE-420L", instructor_id: 1, school_id: nil, created_at: "2011-06-04 19:40:32", updated_at: "2011-06-04 19:40:32">
From looking at the console, you can see that when I call c.instructor = Instructor.first, it is correctly setting my instructor_id.
Now, in the seeds file I have variables. (This is just a snippet)
### Instructors ###
puts "Creating Instructors"
instructor_1 = Instructor.find_or_create_by_name("Instructor Name")
### Courses ###
puts "Creating Courses"
ce420L = Course.find_or_create_by_name("Microcomputers II Lab", :course_code => "CE-420L")
### Add the Instructor to the Course ###
puts "Adding an Instructor to the Courses"
ce420L.instructor = instructor_1
But when I run the seeds using 'rake db:seed', it is correctly creating all of my models, and most of my relationships. But it is not setting the instructor properly.
Thoughts?
EDIT:
Just tried:
ce420 = Course.find_or_initialize_by_name("Microcomputers II")
ce420.instructor_id = instructor_1.id
ce420.save!
And it did not save my instructor.
Here are my models.
class Instructor < ActiveRecord::Base
### ASSOCIATIONS ###
has_many :courses
end
class Course < ActiveRecord::Base
belongs_to :instructor
end
Did you run...
ce420L.save!
... after assigning the instructor?
Much faster to do this:
### Courses ###
puts "Creating Courses belonging to Instructor 1"
ce420L = Course.find_or_initialize_by_name("Microcomputers II Lab") :course_code => "CE-420L")
ce420L.instructor_id = instructor_1.id
ce420L.save
Note the following:
You had an errant comma after your find_or_create on ce420L.
Doing the assignment together with the course creation prevents the system from validating and saving ce420L twice.
You can try assigning the specific ID as I did, i.e. ce420L.instructor_id = ...
If this doesn't work, check your Instructor Model to ensure you don't have any callbacks getting in the way.

Resources