The following spec passes fine in Ruby 2.1.5 but fails in 2.2.0 and I can't tell what that's all about:
# job.rb
class Job < ActiveRecord::Base
validates :link, :url => true
end
# job_spec.rb
require 'rails_helper'
describe Job do
describe "#create" do
["blah", "http://", " "].each do |bad_link|
it {
should_not allow_value(bad_link).for(:link)
}
end
end
end
fail log looks like this:
1) Job#create should not allow link to be set to "http://"
Failure/Error: should_not allow_value(bad_link).for(:link)
Expected errors when link is set to "http://",
got no errors
# ./spec/models/job_spec.rb:14:in `block (4 levels) in <top (required)>'
I find the only way to for that spec to pass with Ruby 2.2.0 is to include the validates_url gem in my project!!
Does anyone know this is about?
Maybe my solution isn't ideal, but it works.
Replace validates_url gem by validates gem. It has UrlValidator (written by me), which is well tested.
gem 'validates' # in Gemfile
validates :link, :url => true # you needn't to change something. Just remove validates_url from your Gemfile
P.S. It's a strange way - to test functionality of gem. Functionality should be tested in gem already.
P.P.S. I'm strongly recommend you to move to ruby 2.2.1 (or 2.2.2) instead of 2.2.0, because of 2.2.0 has a lot of bugs
Related
Let us take Rails gem for example
Before require 'rails'
irb(main):001:0> Rails
NameError: uninitialized constant Rails
irb(main):002:0> ActionPack
NameError: uninitialized constant ActionPack
After require 'rails'
irb(main):005:0> require 'rails'
true
irb(main):007:0> Rails.constants
[:Railtie, :Rack, :Initializable, :Configuration, :WelcomeController, :InfoController, :VERSION, :Paths, :Info, :MailersController, :Application, :Engine]
irb(main):009:0> ActionPack.methods-Object.methods
[:gem_version, :version, :initialize_copy]
So now the ActionPack module is available in the console, what other modules or class (if any) are available and how to know about those modules?
Thats up to the gem developer. To see how your Name- and Objectspace changed there should be many clever ways.
I answer shortly how to find out which new Module (-Constants) there are:
initial_modules = Module.constants
# -> [:Object, :Module, :Class, :BasicObject, :Kernel, :NilClass, ...]
require 'rails'
Module.constants - initial_modules # all NEW constants
# -> [:Pathname, :OpenSSL, :Digest, :SecureRandom, :Concurrent, :I18n, :CGI, :ActiveSupport, :Set, :SortedSet, :Timeout, :TimeoutError, :Logger, :LoggerSilence, :DateAndTime, :Psych, :StringScanner, :ScanError, :Date, :DateTime, :YAML, :Base64, :TSort, :Rails, :BigDecimal, :BigMath, :TZInfo, :ThreadSafe, :Threadsafe, :SynchronizedDelegator, :JSON, :OpenStruct, :Singleton, :Mutex_m, :ActionPack, :Rack, :ActionDispatch, :Mime]
As you see, this also comes with a lot of new stuff that is required (but not provided) by Rails, like Date, OpenSSL, etc.pp.
Actually, requirements can happen at runtime, too, such that this lists grows as you use the code.
Hope that helps a bit.
I'm writing a model test for my Applications model, which accepts_nested_attributes_for(:user). Here's the test that's failing:
describe UserApplication, "associations" do
it { should belong_to(:user) }
it { should accept_nested_attributes_for(:user) }
end
And here's the model:
class UserApplication < ActiveRecord::Base
#attr_accessible all the fields
belongs_to :user
accepts_nested_attributes_for :user
end
I'm using rspec with shoulda-matchers 2.8, and from my research this should all work fine. No spring or any other weirdness, either. Here's the error I'm seeing:
1) UserApplication association
Failure/Error: it { should accept_nested_attributes_for(:user) }
NoMethodError:
undefined method `accept_nested_attributes_for' for #<RSpec::Core::ExampleGroup::Nested_2:0x007fec5c641a40>
# ./spec/models/user_application_spec.rb:25:in `block (2 levels) in <top (required)>'
I'm not sure what could be causing this. Could this be some weird gem conflict shenanigans or am I missing something obvious?
Okay, so I have to give credit to #PeterAlfvin for giving me the tools to see what was wrong. My gemfile specified gem 'shoulda-matchers' but that was only loading up version 1.0, which didn't have support for accepts_nested_attributes_for. His suggestion, via https://stackoverflow.com/a/2954632/1008891 pointed me in the right direction. Specifying 2.8.0 fixed the problem without immediately breaking anything.
I followed codeschool tutorial, but I encountered some troubles.
Here is zombie_spec.rb
#spec/model/zombie_spec.rb
require 'spec_helper'
require 'zombie'
describe Zombie do
it 'is invalid without a name' do
zombie = Zombie.new
zombie.should_not be_valid
end
end
zombie.rb
#spec/zombie.rb
class Zombie < ActiveRecord::Base
validates :name, presence: true
...
end
After I typed rspec spec/models/zombie_spec.rb, it throw uninitialized constant ActiveRecord (NameError)
I've put this project on github
I think the tutorial might be trying to transition from using RSpec on a plain Ruby object to using the rspec-rails gem on an ActiveRecord object. For the examples that use rspec-rails, you should have a model in the file app/models/zombie.rb. This is what the spec in spec/models/zombie_spec.rb will look for. Also, your specs will need to require rails_helper rather than spec_helper.
# app/models/zombie.rb
class Zombie < ActiveRecord::Base
validates :name, presence: true
def hungry?
true
end
end
# spec/models/zombie_spec.rb
require 'rails_helper'
describe Zombie do
it 'is invalid without a name' do
zombie = Zombie.new
zombie.should_not be_valid
end
end
Zombie is extending ActiveRecord::Base but your code can't find ActiveRecord.
To fix that you can require 'activerecord' within zombie.rb. Depending on whether or not it's installed, you may need to also gem install activerecord from your command line or, alternatively, add gem 'activerecord' to your Gemfile and run bundle install
I found an example that worked well for me:
require 'rails_helper'
RSpec.describe Auction, :type => :model do
it "is valid with valid attributes"
it "is not valid without a title"
it "is not valid without a description"
it "is not valid without a start_date"
it "is not valid without a end_date"
end
I am new to ruby, so I am not 100% sure why it needs this ":type" attribute, but it fixed my problem.
(Source)
I recently upgraded to rails 4.2 and I found that friendly ID stopped working. Not sure if this a bug or if I am literally just failing at using friendly id.
After the update my tests started failing, for example I have the following test:
context "Fiendly ID" do
it "should find by name" do
permission = FactoryGirl.create(:can_read)
Xaaron::Permission.find(permission.permission_name.parameterize).should_not eql nil
end
end
This test never use to fail but now its spitting out:
Failure/Error: Xaaron::Permission.find(permission.permission_name.parameterize).should_not eql nil
ActiveRecord::RecordNotFound:
Couldn't find Xaaron::Permission with 'id'=can_read2
# ./.bundle/gems/gems/activerecord-4.2.0/lib/active_record/core.rb:154:in `find'
# ./spec/models/xaaron/permission_spec.rb:21:in `block (3 levels) in <top (required)>'
With that in mind here is my model:
module Xaaron
class Permission < ActiveRecord::Base
extend FriendlyId
friendly_id :permission_name, use: [:slugged, :finders, :history]
has_many :roles_permissions
has_many :roles, :through => :roles_permissions
validates :permission_name, presence: true, uniqueness: true
def should_generate_new_friendly_id?
permission_name_changed?
end
end
end
notice the :finders. I am running 5.0.3 for Friendly ID. Is this something new with active record or have I failed at using Friendly ID?
The finders module is compatible with Rails 4.2. only in the 5.1. version (not yet released). You can of course already test the version but keep in mind that it's still in beta.
gem "friendly_id", "5.1.0.beta.1"
I have some seed data (for price ranges) that is the same in prod, dev, test and doesn't change. I need that data in my test db to run my cuke tests.
I am load my seed data into test DB before the scenario loads, but it's failing.
I have the following in my features/support/env.rb file
# from http://www.andhapp.com/blog/2009/11/07/using-factory_girl-with-cucumber/
Before do
require 'factory_girl_rails'
# Dir.glob(File.join(File.dirname(__FILE__), '../../spec/factories/*.rb')).each {|f| require f }
Dir.glob(File.join(File.dirname(__FILE__), '../../db/seeds.rb')).each {|f| require f }
end
Which loads the following file:
# wipe out all previous data
Price.delete_all #is there a factory way of doing this?
# set defaults
Factory.define :price do |price|
price.id 1
price.price_range "$100"
end
# insert seed data
#price = Factory(:price, :id => 1, :price_range => "$100 - $500")
#price = Factory(:price, :id => 2, :price_range => "$500 - $1,000")
#price = Factory(:price, :id => 3, :price_range => "$1,000 - $1,000")
#price = Factory(:price, :id => 4, :price_range => "$10,000 - $100,000")
I get the following error message:
Factory already defined: price (Factory::DuplicateDefinitionError)
/Library/Ruby/Gems/1.8/gems/factory_girl-1.3.3/lib/factory_girl/factory.rb:61:in `define'
/Applications/MAMP/htdocs/rails_testing/feedbackd/features/support/../../db/seeds.rb:16
/Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:239:in `require'
/Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:239:in `require'
/Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:227:in `load_dependency'
/Library/Ruby/Gems/1.8/gems/activesupport-3.0.3/lib/active_support/dependencies.rb:239:in `require'
/Applications/MAMP/htdocs/rails_testing/feedbackd/features/support/env.rb:92
/Applications/MAMP/htdocs/rails_testing/feedbackd/features/support/env.rb:92:in `each'
/Applications/MAMP/htdocs/rails_testing/feedbackd/features/support/env.rb:92:in `Before'
Any thoughts?
You can only call Factory.define :price once, and I would probably not put it in the file that it's in right now. Do you have a factories folder? It usually lives in spec/factories. In there I would create the file price.rb, and define your factory once, there. factory_girl should automatically load all of those definitions up for you once.
If you're using Rails3 and you have factory_girl_rails in your Gemfile, then you don't even need that require 'factory_girl_rails', it does it for you.
Also if you have a new-ish version of cucumber the installer should automatically have added this section for you in env.rb:
if defined?(ActiveRecord::Base)
begin
require 'database_cleaner'
DatabaseCleaner.strategy = :truncation
rescue LoadError => ignore_if_database_cleaner_not_present
end
end
DatabaseCleaner is a good way to do the truncation instead of using your Price.delete_all
The last thing is seeds.rb - It's a good concept and something very similar to what we do in one of our apps at work.
But keep in mind, everything in the features/support directory is automatically required by cucumber, so you don't need to have that Dir.glob nonsense.
With factory_girl we don't use the default rails seeds file because it's not really applicable (in our opinion).
I would just add a file named anything (ours is named db_setup.rb) that looks something like this:
Before do
# Truncates the DB before each Scenario,
# make sure you've added database_cleaner to your Gemfile.
DatabaseCleaner.clean
Factory(:price, :attr1 => 'blah'...)
# More factories here etc
end
Take a look at hooks:
https://github.com/aslakhellesoy/cucumber/wiki/Hooks
You can use tagged hooks to only load up specific seed data, much like you would only execute specific tags in cucumber.
You can also employ the heavy handed rails way and do a rake db:test:clone.