I already published my first rails gem but not yet with any tests included. This gem is just a simple helper which I want to test with rspec. But I have no idea how I can test a helper within a gem with rspec.
I tried to create a file spec/helper/development_ribbon_helper_spec.rb:
require 'spec_helper'
describe DevelopmentRibbonHelper do
end
But when I execute rspec I get this error:
development_ribbon_helper_spec.rb:3:in `<top (required)>': uninitialized constant DevelopmentRibbonHelper (NameError)
You can find the whole source code on github.
It looks like you may be trying to write a rails engine gem, correct? Since your helper file is located outside of lib/, your spec_helper will need to know how to load your rails engine.
One way to do this is to create a dummy rails app in your spec/ directory. This setup is well-described in this post: http://reinteractive.net/posts/2-start-your-engines.
Alternatively, you can move the helper file into lib/development_ribbon and require it in your development_ribbon.rb file:
require "development_ribbon/development_ribbon_helper"
Then, in your rails apps that use the gem, you could include the helper in application_helper.rb
module ApplicationHelper
include DevelopmentRibbon::DevelopmentRibbonHelper
end
Related
I have helper method for rspec test like this :
<bla_bla_helper.rb>
Module blabla
def bla
end
end
Where should i place this module?
This module is only for rspec test.
Past version of Rails used spec/support directory, should i use this directory?
In RSpec you use spec/support to place the helpers, matchers, shared contexts etc that your specs need. This path is added to the load path so you can simply do require 'foo' in your specs to require spec/support/foo.rb.
Some projects use a glob in spec/spec_helper.rb to require all the files in the spec/support directory.
This is just an RSpec convention that has nothing to do with Rails, so the practice isn't going to change with Rails versions.
I usually place mine inside spec/support/helpers and include it in the configuration via rails_helper.
Here's an example of including the devise API auth helper that I am using for my application.
config.include DeviseApiAuthHelper, type: :controller
Yes you can continue using spec/support directory.
I have a controller "A" which requires a file in a subdirectory of app/lib (ex: app/lib/a_folder/my_class.rb).
So I did something like this :
require 'a_folder/my_class'
class AController < ApplicationController
# Some stuff using MyClass
end
It works well when I use the application, but doesn't work when I launch RSpec.
This is how my RSpec file looks:
require 'spec_helper'
require 'lib/import_functions' # Rails.root/spec/lib/import_functions.rb
RSpec.describe AController, type: controller do
# My tests routines
end
When I start rspec it tells me the require in the controller file doesn't found the file (`require': cannot load such file), while it works well when I start the app.
I've added a puts $LOAD_PATH just before the require and it appears that Rails.root/app/lib is not present.
I use Rails 3.2 and rspec-rails 3.2.
Does anyone have any idea why it happens and how to fix it please ?
Thank you for your future answers.
lib files are not auto loaded. You can put the following configuration in your application.rb, it has a problem also it will load all files under lib directory.
config.autoload_paths += "#{Rails.root}/lib/"
Or you can load your lib files in your RSpec as following code
require_relative "../../lib/a_folder/my_class.rb"
or
require 'lib/a_folder/my_class.rb'
I have written a generator which creates the following ruby file and folder:
app/tests/test.rb
in the test.rb file I have a Test class which looks like this:
class Test < MyCustomModule::MyCustomClass::Base
...
end
Now, I want to use its functionality in one of the show.html.erb files creating new instance like this:
Test.new(...).render(...).html_safe
but I am getting the following error:
uninitialized constant MyCustomModule::MyCustomClass::Base
I have use the following answer to link my gem and my rails application. It seems to work as I am able to use the generator, but the gem module and class are not seen in the rails application.
Could anyone tell how to fix this issue?
I have try to follow the tips posted here but still nothing changed:
Adding config.autoload_paths += Dir["#{config.root}/lib/**/"] in application.rb file
I have created my gem structure looking at CarrierWave gem, so the naming should be correct
I try to disable config.threadsafe! but it is already disabled since config.cache_classes and config.eager_load are set to false in development
DEPRECATION WARNING: config.threadsafe! is deprecated. Rails
applications behave by default as thread safe in production as long as
config.cache_classes and config.eager_load are set to true.
Also, looking at adding-asset-to-your-gems rails documentation, it is said that:
A good example of this is the jquery-rails gem which comes with Rails
as the standard JavaScript library gem. This gem contains an engine
class which inherits from Rails::Engine. By doing this, Rails is
informed that the directory for this gem may contain assets and the
app/assets, lib/assets and vendor/assets directories of this engine
are added to the search path of Sprockets.
So, I have done this, and put my model class file in assets folder, but the result is the same.
The following screenshots demonstrate my real case:
The screenshot below displays my gem file structure
Here you can see how I am loading the gem in my Rails application Gemfile:
gem 'thumbnail_hover_effect', '0.0.3', github: 'thumbnail_hover_effec/thumbnail_hover_effec', branch: 'master'
Then I am using the gem generator a ruby file with a cutstom name in app/thumbnails/test.rb folder with the following code:
class Test < ThumbnailHoverEffect::Image::Base
...
end
and trying to use the Test class gives me uninitialized constant ThumbnailHoverEffect::Image::Base error.
Back in the gem files, these are how the thumbnail_hover_effect file looks like
require 'thumbnail_hover_effect/version'
require 'thumbnail_hover_effect/engine'
require 'thumbnail_hover_effect/image'
module ThumbnailHoverEffect
# Your code goes here...
end
and hoe the image file looks like:
module ThumbnailHoverEffect
#
class Image
...
end
end
From what you've posted here there is no ThumbnailHoverEffect::Image::Base defined. Rails autoloading conventions (which you should not be depending on a gem btw, more on that later) would be looking for this file in thumbnail_hover_effect/image/base.rb, but the directory structure you printed does not have that. Of course you could define the class in thumbnail_hover_effect/image.rb and it would work, but the abridged snippet you posted does not show that. So where is ThumbnailHoverEffect::Image::Base defined?
If it's in thumbnail_hover_effect/image/base.rb then that would indicate the file is not being loaded. You can sanity check this by putting a puts 'loading this stupid file' at the top of thumbnail_hover_effect/image/base.rb. That will allow you to bisect the problem by seeing whether there is a problem with your definition of the class, or whether the problem is with loading the proper files. Debugging is all about bisecting the problem.
I have the simple following code, which is working in a ruby (not rails) app:
require 'gmail'
Gmail.new('my_account', 'my_password') do |gmail|
end
I am able to get a connection to the Gmail account and do some stuff in there.
However, I want to use this Gem in a Rails app, and therefore I have tried adding the following into the Gemfile:
gem "ruby-gmail", "0.2.1"
gem "mime", "0.1"
However, when I try to use this in a rake task, like this:
task :scrap_receipts_gmail => :environment do
Gmail.new('my_account', 'my_password') do |gmail|
puts gmail.inspect
end
end
I get the following error:
uninitialized constant Object::Gmail
This is solved if I add require 'gmail'. My question is:
Why would I have to require gmail, if I have already specified that in the Gemfile?
The module/class namespace has to match the directory structure. For example, in lib/foo/bar.rb, if and only if the namespace is Foo::Bar can it be auto loaded by Rails, otherwise you have to require it explicitly.
In this case, Gmail is defined as a class, which doesn't match the directory structure. If Gmail was defined as a module (namespace ::Gmail matchs directory structure), then you'll never need to explicitly require "gmail".
I'm really tired of typing my_ar_object.errors.full_messages in my console when i'm testing things...
So, I want to define this:
module ActiveRecord
class Base
def err
errors.full_messages
end
end
end
in my ~/.irbrc so that it is exclusive to script/console.
I don't want to define it in some rails initializer since I don't believe it belongs in the rails project (this is a irb helper)
The problem is, when I do that, this happens:
/.../gems/rails-2.3.5/lib/initializer.rb:437:in `initialize_database':NoMethodError: undefined method `configurations=' for ActiveRecord::Base:Class
Any ideas how I might make this work?
Did you load ActiveRecord in your .irbrc before defining the err method? Try adding
require 'active_record'
or
require 'rubygems'
gem 'activerecord', '2.3.5' # or whatever version you use
before defining the err method.
And another hint: irb looks for an .irbrc file in the current directory and in your home dir. So you could also craft a project-specific .irbrc in your project root directory. This way, you don't have to introduce ActiveRecord to your default irb config since it is a rather hefty dependency.