I'm trying to make a simple validation, the main issue I thing is the Rails version (I have been using RSpec with Rails 4) because I'm using it with Rails 3.2 and Ruby 1.9.3.
This is the code in my Model
expect(section).to have(1).errors_on(:name)
and it return this error
1) Admin::Section is invalid without name
Failure/Error: expect(section).to have(1).errors_on(:name)
NoMethodError:
undefined method `have' for #<RSpec::ExampleGroups::AdminSection:0x007f81cf6e72d0>
My gem list is this
* rspec-core (3.0.1)
* rspec-expectations (3.0.1)
* rspec-mocks (3.0.1)
* rspec-rails (3.0.1)
* rspec-support (3.0.0)
I can make it pass with should be_valid but it is deprecated.
If I use have_at_least the error is on errors_on
See this pull request. have(n) was extracted rspec-collection_matchers gem
You can include it or just use one of the following:
expect(section.error_on(:name)size).to eq(1)
expect(section.error_on(:name)).to be_present
expect(section).to have_validation_error("your error message").on(:name)
Related
I have a Rails 4.2 framework and use Kaminari to paginate. Everything works great, but I want to test everything with Capybara, thus I run into the page conflict. So I wanted to rename the page_method_name of Kaminari and followed the guide from them:
$ bundle exec rails g Kaminari:config
This results in this file
app/config/initializers/kaminari_config.rb
Kaminari.configure do |config|
config.page_method_name = :plant
end
In which I simply uncommented the config.page_method_name and set it to :plant (as an example from the Kaminari docs to avoid any reserved method name conflicts for something like :kaminari_page).
Then I adjusted the appropriate controller to
def index
#q = Interaction.published.order(updated_at: :desc).limit(200).ransack(params[:q])
#selection = #q.result
#interactions = Kaminari.paginate_array(#selection).plant(params[:page]).per(10)
respond_to do |format|
format.html
format.js
end
end
I restarted everything and got this error when visiting the
undefined method `plant' for #Kaminari::PaginatableArray:0x00005568fb42ba30
Gemfile.lock:
kaminari (1.2.1)
activesupport (>= 4.1.0)
kaminari-actionview (= 1.2.1)
kaminari-activerecord (= 1.2.1)
kaminari-core (= 1.2.1)
kaminari-actionview (1.2.1)
actionview
kaminari-core (= 1.2.1)
kaminari-activerecord (1.2.1)
activerecord
kaminari-core (= 1.2.1)
kaminari-core (1.2.1)
I was then googling around and also added require 'kaminari' (which does not make so much sense, because I did not get the uninit constant error) and also included the Kaminari configure section into the class Application < Rails::Application inside config/application.rb.
Nothing worked, always the same error.
You show your files location as app/config/initializiers/kaminari_config.rb. If that is the actual location of your file it fully explains why the method doesn't exist. The location should be app/config/initializers/kaminari_config.rb. With the location you specified it wouldn't be automatically loaded when the app starts.
If the location you showed is just a type then that wouldn't be the cause, but if you didn't include Capybara into the global object, which you shouldn't be doing anyway, then you wouldn't have a name collision. Current versions of Capybara issue a warning when you do include it into the global object specifically for this reason.
Also is there any reason you're grabbing all the results and then paging them, rather than using the page (or plant) and per scopes that would be defined on Interaction?
I have this code which works fine (!!! without the first line "task..."!!!) in console. It creates events in DB. However no luck when running the rake (rake fetch_ttt):
task :fetch_ttt => :environment do
require 'nokogiri'
require 'open-uri'
url = "http://www.example.com"
doc = Nokogiri::HTML(open(url))
doc.css("#eventrow").each do |item|
unless Event.find_by_name(item.at_css("a").text).present?
Event.create(
:start_time => item.at_css("#eventdate").text,
:name => item.at_css("a").text,
:url => item.at_css("a")[:href]
)
end
end
end
This is the trace (not much in dry run neither):
** Invoke fetch_ttt (first_time)
** Invoke environment (first_time)
** Execute (dry run) environment
** Execute (dry run) fetch_ttt
It has been fine couple hours ago. Since then I did a "bundle update", made some DB migrations, edited associations. I tried rolling back migrations and removed model association changes with no luck. I suspect the gems.
Below the 3 gems I rolled back to the previous versions to see if they are responsible but not. And the full diff.
old ones:
gem 'rake', '10.5.0'
gem 'http', '0.9.8'
gem 'ipaddress', '0.8.2'
full diff:
- bcrypt (3.1.10)
+ bcrypt (3.1.11)
- carrierwave (0.10.0)
+ carrierwave (0.11.2)
+ mimemagic (>= 0.3.0)
- concurrent-ruby (1.0.0)
+ concurrent-ruby (1.0.2)
- devise (3.5.6)
+ devise (4.1.1)
- railties (>= 3.2.6, < 5)
+ railties (>= 4.1.0, < 5.1)
- thread_safe (~> 0.1)
- domain_name (0.5.20160128)
+ domain_name (0.5.20160310)
- excon (0.45.4)
+ excon (0.49.0)
- excon (~> 0.45)
+ excon (~> 0.49)
****lots of stuff related to "fog" gem
- http (0.9.8)
+ http (0.9.9)
- ipaddress (0.8.2)
+ ipaddress (0.8.3)
- mime-types (2.99)
- mini_magick (4.4.0)
+ mime-types (2.99.1)
+ mimemagic (0.3.1)
+ mini_magick (4.5.1)
mini_portile2 (2.0.0)
- minitest (5.8.4)
- multi_json (1.11.2)
+ minitest (5.9.0)
+ multi_json (1.12.0)
- rails_stdout_logging (0.0.4)
+ rails_stdout_logging (0.0.5)
- responders (2.1.1)
+ responders (2.2.0)
- sprockets (3.5.2)
+ sprockets (3.6.0)
- sprockets-rails (3.0.1)
+ sprockets-rails (3.0.4)
- tilt (2.0.2)
+ tilt (2.0.4)
Rails 4.2.5, Ruby 2.1.4, I am on C9 IDE. But doesn't work on heroku neither.
UPDATE
reverted back to rake 10.5.0 (and did grep rake Gemfile.lock) now in the console I only get:
<Rake::Task fetch_ttt => [environment]>
scraping doesn't run at all :(
I don't think there's enough info here to give a definitive answer, but I would start by investigating the root cause for why it isn't working on heroku.
For example, does the rake task run at all? How do you know?
If so, do heroku run rails c and try doing the sequence of code yourself. Inspect the database records before and after you expect a chance. What happened?
If it didn't run, what type of output did you get? heroku logs can also be helpful.
One other little tip, it's possible to use byebug with heroku logs -t. Although I only recommend this in your staging environment and only if you're willing to clean up the git history afterwards.
In short, my answer is I would solve it by debugging more directly. Hope this helps.
outcommented
#require 'nokogiri'
#require 'open-uri'
and now it works. Even with rake 11.1.2
I am using the APIonRails tutorial and they have this:
require 'spec_helper'
describe ApiConstraints do
let(:api_constraints_v1) { ApiConstraints.new(version: 1) }
let(:api_constraints_v2) { ApiConstraints.new(version: 2, default: true) }
describe "matches?" do
it "returns true when the version matches the 'Accept' header" do
request = double(host: 'api.marketplace.dev',
headers: {"Accept" => "application/vnd.marketplace.v1"})
api_constraints_v1.matches?(request).should be_true
end
it "returns the default version when 'default' option is specified" do
request = double(host: 'api.marketplace.dev')
api_constraints_v2.matches?(request).should be_true
end
end
end
In an example, but I have come to understand that this is using the old syntax.
To convert this into the new syntax, I am trying this:
require 'rails_helper'
describe ApiConstraints do
let(:api_constraints_v1) { ApiConstraints.new(version: 1) }
let(:api_constraints_v2) { ApiConstraints.new(version: 2, default: true) }
describe "matches?" do
it "returns true when the version matches the 'Accept' header" do
request = double(host: 'api.localhost:3000',
headers: {"Accept" => "application/vnd.marketplace.v1"})
expect(request).to match(api_constraints_v1)
end
it "returns the default version when 'default' option is specified" do
request = double(host: 'api.localhost:3000')
expect api_constraints_v2.matches?(request).to_be true
end
end
end
This is the error I am getting:
Failures:
1) ApiConstraints matches? returns true when the version matches the 'Accept' header
Failure/Error: expect(request).to match(api_constraints_v1)
expected #<RSpec::Mocks::Double:0x3feeedaf60c4 #name=nil> to match #<ApiConstraints:0x007fddde50f9b0 #version=1, #default=nil>
Diff:
## -1,2 +1,2 ##
-#<ApiConstraints:0x007fddde50f9b0 #default=nil, #version=1>
+#<RSpec::Mocks::Double:0x3feeedaf60c4 #name=nil>
# ./lib/spec/api_constraints_spec.rb:11:in `block (3 levels) in <top (required)>'
2) ApiConstraints matches? returns the default version when 'default' option is specified
Failure/Error: expect api_constraints_v2.matches?(request).to_be true
NoMethodError:
undefined method `to_be' for true:TrueClass
Did you mean? to_enum
to_s
# ./lib/spec/api_constraints_spec.rb:16:in `block (3 levels) in <top (required)>'
Finished in 0.0045 seconds (files took 6.52 seconds to load)
2 examples, 2 failures
Failed examples:
rspec ./lib/spec/api_constraints_spec.rb:8 # ApiConstraints matches? returns true when the version matches the 'Accept' header
rspec ./lib/spec/api_constraints_spec.rb:14 # ApiConstraints matches? returns the default version when 'default' option is specified
What could be causing this?
Edit 1
Per My Gemfile.lock, these are the versions of my relevant gems:
rspec (3.1.0)
rspec-core (~> 3.1.0)
rspec-expectations (~> 3.1.0)
rspec-mocks (~> 3.1.0)
rspec-core (3.1.7)
rspec-support (~> 3.1.0)
rspec-expectations (3.1.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.1.0)
rspec-mocks (3.1.3)
rspec-support (~> 3.1.0)
rspec-rails (3.1.0)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 3.1.0)
rspec-expectations (~> 3.1.0)
rspec-mocks (~> 3.1.0)
rspec-support (~> 3.1.0)
rspec-support (3.1.2)
rubyzip (1.2.0)
selenium-webdriver (2.53.0)
childprocess (~> 0.5)
rubyzip (~> 1.0)
websocket (~> 1.0)
shellany (0.0.1)
shoulda (3.5.0)
shoulda-context (~> 1.0, >= 1.0.1)
shoulda-matchers (>= 1.4.1, < 3.0)
shoulda-context (1.2.1)
shoulda-matchers (2.8.0)
activesupport (>= 3.0.0)
What is the correct new syntax I should use to be able to achieve the same thing that the original code achieves?
In the original test change
api_constraints_v1.matches?(request).should be_true
to
expect(api_constraints_v1.matches?(request)).to be_truthy
or
expect(api_constraints_v1.matches?(request)).to be(true)
if you expect only a boolean value to be returned.
change
expect request.to eq(api_constraints_v1)
to
expect(request).to eq(api_constraints_v1)
and the same problem in the other spec...
expect is a method to which you give the thing that the expectation is going on (ie request)...
after you get the result from the request method - you then call to on it...
The way you had it before... you are first calling to on request and then passing the result of that to expect... ie, grouping matters ;)
I've used the same ApiConstraints in my rails-api-base project and it crashes when you try matches? with a non-default version without specifying the Accept header.
I added the following test (which crashes):
it 'returns false when not default and no Accept header' do
request = double(host: 'api.marketplace.dev')
expect(api_constraints_v1.matches?(request)).to be false
end
And I fixed ApiConstraints:
def matches?(req)
#default ||
(req.respond_to?('headers') &&
req.headers.key?('Accept') &&
req.headers['Accept'].include?("application/vnd.marketplace.v#{#version}"))
end
Hope it helps!
I'm trying to use the activerecord-import gem and I've followed the directions on the wiki to a tee but I'm getting a NoMethodError: undefined method 'import' for #<Class:0x8b009b0>. Here's my code (basically the same as the example from the wiki)
class ExampleCode
def self.testing
orders = []
10.times do |i|
orders << Order.new(:raw_data => "order #{i}")
end
Order.import orders
end
end
I call the method like so:
ExampleCode.testing
I've tried on windows, linux, with a sqlite database, a mysql database and still no luck. And I'm certain I have the gem installed:
actionmailer (3.2.6, 3.2.3, 3.2.1, 3.2.0)
actionpack (3.2.6, 3.2.3, 3.2.1, 3.2.0)
activemodel (3.2.6, 3.2.3, 3.2.1, 3.2.0)
activerecord (3.2.6, 3.2.3, 3.2.1, 3.2.0)
activerecord-import (0.2.10)
activerecord-oracle_enhanced-adapter (1.4.1)
activerecord-sqlserver-adapter (3.2.1)....
I even tried to use require (which shouldn't be necessary when the gem is installed. I haven't seen this come up anywhere else so I fear I must to missing something very obvious
You'll have to import active_record and activerecord-import
i.e.
require active_record
require activerecord-import
(as mentioned in the wiki)
The reason being, ruby won't know about it unless you explicitly import those libraries. In case of a rails project, rails imports all gems mentioned in the Gemfile for you.
I ran into the same thing; turns out that for me at least I had the gem included within a test block in the gemfile. make sure that when you include it it's not just limited to one app environment in the gem file.
I keep getting the following error when sending a simple e-mail via ActionMailer in Rails:
NoMethodError: undefined method `encode!' for "Hello":String
This is triggered whenever the following is run:
def hello_world_email()
mail( :from => "me",
:to => "you,
:subject => "Hello World"
)
end
From researching this, it looks like it's caused by the differences between Ruby 1.8.7 and 1.9.*, which has built-in character encoding support.
Is there any way of getting ActionMailer to work with Ruby 1.8.7 and avoid this issue? (I can upgrade Ruby on my machine, but I can't do the same for everyone else working on the project). Given that the whole of Rails 3.0.9 (of which ActionMailer is a part) is meant to work with Ruby 1.8.7, I keep thinking that there must be a way...
Note: My exact version of Ruby is ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0] (pre-installed on OSX).
You may have an issue with using Ruby 1.8 and having a constant Encoding defined by a gem.
For example we found an issue with a class that was including REXML at a global scope.
The line in question in the library was:
value.encode!(charset) if defined?(Encoding) && charset
This is checking for a global constant called Encoding. (Which could be defined in any gem at global scope.) Our problem was actually the include which then made REXML::Encoding available everywhere as Encoding. You could try grepping or acking your codebase for "module Encoding" or "class Encoding".
Hope this helps.
The stack trace below defines the problem.
NoMethodError: undefined method `encode!' for "Generate":String
mail (2.2.19) lib/mail/fields/unstructured_field.rb:169:in `encode'
mail (2.2.19) lib/mail/fields/unstructured_field.rb:138:in `fold'
mail (2.2.19) lib/mail/fields/unstructured_field.rb:108:in `wrapped_value'
mail (2.2.19) lib/mail/fields/unstructured_field.rb:70:in `do_encode'
mail (2.2.19) lib/mail/fields/unstructured_field.rb:52:in `encoded'
mail (2.2.19) lib/mail/field.rb:123:in `send'
mail (2.2.19) lib/mail/field.rb:123:in `method_missing'
mail (2.2.19) lib/mail/header.rb:190:in `encoded'
mail (2.2.19) lib/mail/header.rb:189:in `each'
mail (2.2.19) lib/mail/header.rb:189:in `encoded'
mail (2.2.19) lib/mail/message.rb:1708:in `encoded'
actionmailer (3.0.10) lib/action_mailer/base.rb:445:in `set_payload_for_mail'
actionmailer (3.0.10) lib/action_mailer/base.rb:425:in `deliver_mail'
activesupport (3.0.10) lib/active_support/notifications.rb:52:in `instrument'
activesupport (3.0.10) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (3.0.10) lib/active_support/notifications.rb:52:in `instrument'
actionmailer (3.0.10) lib/action_mailer/base.rb:424:in `deliver_mail'
mail (2.2.19) lib/mail/message.rb:230:in `deliver'
I had the same error, when trying to test my devise confirmation emails. Weird thing was, running the test isolated did not throw this exception. Running the whole stack did. After doing a binary search, i found, that one of my specs used REXML to parse some content.
require 'spec_helper'
require 'rexml/document'
include REXML
doc = Document.new(response.body)
I dont't know, why i included REXML, presumably, because i wanted to save the REXML:: in front of Document. But changing the code to this fixed the problem:
require 'spec_helper'
require 'rexml/document'
doc = REXML::Document.new(response.body)
if you happen to use code like this somewhere, this may fix this encode! issue with ruby 1.8.7
I found the issue to be with the mailer gem, changing to 2.2.13 fixed it for me.