How to generate 'minitest/spec' based gems via bundler? - ruby-on-rails

bundle gem gem_name --test=minitest
allows for choosing minitest, but how to make bundler generate code for minitest/spec instead of minitest/test.

This seems to work now:
bundle gem myapp --test minitest

It is not currently possible.
-t, --test=minitest, --test=rspec
Specify the test framework that Bundler should use when generating
the project. Acceptable values are minitest and rspec. The
GEM_NAME.gemspec will be configured and a skeleton test/spec
directory will be created based on this option. If this option is
unspecified, an interactive prompt will be displayed and the answer
will be saved in Bundler's global config for future bundle gem use.
However the bundle gem generator generates less than 10 lines of tests, so converting to MiniTest::Spec is hardly a herculean task.

Related

Bundler is deprecating bundle console in favor of bin/console. Can anyone provide more clarity as to how bin/console should work?

I have a custom ruby gem that relies heavily on bundle console. Nothing special or fancy, just an interactive console with the set of gems defined by the Gemfile included. We use the console a lot during development.
Currently when I run the command, I receive the following deprecation message:
[DEPRECATED] bundle console will be replaced by bin/console generated by bundle gem <name>
Digging around in the bundler docs I found the following explanation:
The bundle console will be removed and replaced with bin/console.
Over time we found bundle console hard to maintain because every
user would want to add her own specific tweaks to it. In order to
ease maintenance and reduce bikeshedding discussions, we're removing
the bundle console command in favor of a bin/console script
created by bundle gem on gem generation that users can tweak to
their needs.
Can anyone with knowledge provide a more detailed explanation? This gem currently does not have a bin directory. I'm happy to make one, I'm just not sure what should be in the file. Running bundle gem as described in the note above raises an error (as expected).
This is the file that is generated at bin/console:
#!/usr/bin/env ruby
require "bundler/setup"
require "(your gem name here)"
# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.
# (If you use this, don't forget to add pry to your Gemfile!)
# require "pry"
# Pry.start
require "irb"
IRB.start(__FILE__)
You can see the template in the rubygems GitHub repo.

rails plugin vs bundle gem

This two commands seem to generate practically the same thing
rails plugin new __name__
bundle gem __name__
There is a hidden detail I haven't notice?
which one do you use, and basically, why?
Thanks
They can all generate a barebone gem but they are different.
rails plugin new could generate a dummy app inside test, and a basic test_helper, which would be very handy if you want to add some functional/integration tests in gem. You can also revise that a bit to use Rspec. bundle gem would not do that.
If you develop the gem for Rails and need such tests, rails plugin would be better. Otherwise bundle or a gem generating gem jeweller.
Plugins are more or less deprecated in favor of gems in recent versions of Rails.
As far as I can tell, running rails plugin my_gem simply creates a 'my_gem' directory in the root of your rails app.
It's not too much different from running bundle gem my_gem except that it stubs out a couple of test files, and runs bundle install.
This may be useful if you're creating a gem that's made to be run on rails - where you need a "rails environment" (see the test/dummy/app directory).
Still, if you do it this way, it appears the gem is added right into the root of your rails project. You could always move it, but if you were to run bundle gem you could do so wherever you want.

Strategies for gem tests to ensure the gem works with Rails 3.x and 4.0?

I've seen a few examples of dummy Rails apps (for testing, so they live under test or spec dirs, typically) for use with the Appraisals gem that supposedly work with both Rails 3.x and Rails 4, but they seem hackish and not fully functional. It is somewhat expected, as it is a stripped down Frankenstein monster that is trying to be compatible with various versions of Rails 3 as well as Rails 4.
I've referred to projects that attempt to do this sort of testing (as of late March 2013) like less-rails and ember-rails, but this way to test with various version of Rails doesn't seem very clean, and it is non-trivial to try to debug a non-standard Rails application, especially in a beta version of Rails.
It would be great to have a cleaner way to test that allows you to have a full Rails application for each version of Rails to test with that through some magic is not that difficult to setup or maintain and don't require non-standard path hacks in places, etc.
What are the available strategies for testing gems with various versions of Rails (including at least latest Rails 3.1.x, 3.2.x, and 4.0.0.beta1), and what are the pros and cons of each?
A few options from the related thread on the rails-core list:
Option 1: Appraisal gem and single Rails dummy app
Ken Collins mentioned using appraisal and a Rails "dummy" app:
I test minitest-spec-rails against 3.0, 3.1, 3,2 and 4.0 using a mix
of appraisal and dummy_app that minimally configures itself depending
which rails version it is testing against. Some links:
https://github.com/metaskills/minitest-spec-rails
https://github.com/metaskills/minitest-spec-rails/blob/master/test/dummy_app/init.rb
Similar techniques are used in less-rails, ember-rails, and high_voltage among others.
I used a similar setup to high_voltage in restful_json (v3.3.0) but with a full Rails app created with 4.0.0-beta1 that I modified minimally to also work with Rails 3.1.x/3.2.x.
Update: May want to see permitters for more recent example.
Pros: Fairly simple. Can test against various Rails versions from command-line, etc. Can be very minimal Rails app configuration, or can use full Rails app with minor differences.
Cons: Still reusing same Rails app for multiple Rails versions, so some conditionals and unneeded config. (Possible issues with some files not being applicable in another version of Rails, etc. but does not appear to be a big problem.)
Option 2: Rails version as environment variable with single Gemfile, single Rails dummy app, relying on travis-ci to test in multiple versions
Steve Klabnik mentioned a solution that works with a single Gemfile, a single full Rails app (even though under "dummy" dir, and no use of the appraisal gem, by relying on travis-ci to test:
I've been meaning to discuss this topic more, as I've been doing it
for a bunch of my gems lately. I have two that do this:
Draper: https://github.com/drapergem/draper
LocaleSetter: https://github.com/jcasimir/locale_setter/
Basically, I embed an entire Rails application into the gem, and then
run it against multiple versions of Rails on travis via env vars.
Pros: Simple. No dependency on appraisal gem (not that it is a problem, but may be easier to maintain).
Cons: Still reusing same Rails app for multiple Rails versions from what I can tell. Unless using travis-ci or something that starts with a clean gemset (i.e. if running at command-line), not currently differentiating gemsets so newer gem may be used with older Rails, etc., but Steve said if that were to cause a problem, you could just blow away the lock and re-bundle.
There's a third option : using multiple gemfiles and multiple dummy apps.
Gemfiles
Bundler has an useful option named --gemfile. With it, you can specify what file to use instead of Gemfile, and it will generate a lock file after the same name :
bundle install --gemfile Gemfile.rails3
bundle install --gemfile Gemfile.rails4
This will generate Gemfile.rails3.lock and Gemfile.rails4.lock. So, those Gemfiles can be a copy of your main Gemfile forcing rails version :
source "http://rubygems.org"
gemspec
gem "jquery-rails"
gem "rails", '~>4'
Using gemfiles from dummy apps
Then you have two dummy apps, one for rails-3 and one for rails-4. To use their proper gemfile while running (for example) migrations :
cd test/dummy_rails3
BUNDLE_GEMFILE=../../Gemfile.rails3 bundle exec rake db:migrate
cd ../dummy_rails4
BUNDLE_GEMFILE=../../Gemfile.rails4 bundle exec rake db:migrate
Yeah, that's probably the worst part. But this is mostly a one time setup.
Using gemfiles from rake
To instruct which version to use while running tests, set the environment variable BUNDLE_GEMFILE in Rakefile :
#!/usr/bin/env rake
rails_version = ENV[ 'RAILS_VERSION' ] || '4'
if rails_version == '3'
ENV[ 'BUNDLE_GEMFILE' ] = 'Gemfile.rails3'
else
ENV[ 'BUNDLE_GEMFILE' ] = 'Gemfile.rails4'
end
begin
require 'bundler/setup'
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
I prefer to ask the user to pass RAILS_VERSION instead of directly BUNDLE_GEMFILE because it's easier to remember and we can just pass "3" or "4".
Using correct dummy app from tests
Finally, in test_helper, switch the dummy app depending on what rails version has been asked for :
# Configure Rails Environment
ENV["RAILS_ENV"] = "test"
dummy_app = ENV[ 'RAILS_VERSION' ] == '3' ? 'dummy_rails3' : 'dummy_rails4'
require File.expand_path("../#{dummy_app}/config/environment.rb", __FILE__)
require "rails/test_help"
From your user perspective
For your user to run tests, he will have to do a one time setup by running the migration tasks with BUNDLE_GEMFILE, which is not that sexy.
But once done, user can run tests against rails-3 and rails-4 without the need to generate the Gemfile each time he wants to switch version, and you can have version specific code and configuration within your test apps without having to put if Rails.version >= '4' statements everywhere.
To run specs :
RAILS_VERSION=3 bundle exec rake test
bundle exec rake test # rails-4 is the default in code I wrote
You can see an example for this method in my activerecord_any_of gem.

How to add a gem dependency and bundle install

Is it possible to add a gem dependency to a Rails 3 app programmatically through ruby code?
EDIT
I'm trying to achieve that when I launch a rake task or a ruby script my rails app becomes a sass rails app.
I have a bunch of file that needs to be copied and after that I'd like to add:
gem 'sass'
to my Gemfile and run bundle install automatically.
Today's railscasts features Guard!
One of the guard extensions is guard-bundler which has this code that can achieve what I need.
https://github.com/guard/guard-bundler/blob/master/lib/guard/bundler.rb
I thought that there was a way to perform similar tasks with the Bundler class.

Couldn't find 'rspec' generator

I'm trying to install RSpec as a gem after having it installed as a plugin. I've gone ahead and followed the directions found here http://github.com/dchelimsky/rspec-rails/wikis for the section titled rspec and rspec-rails gems. When I run ruby script/generate rspec, I get the error Couldn't find 'rspec' generator. Do only the plugins work? If so, why do they even offer the gems for rspec and rspec-rails? I'm running a frozen copy of Rails 2.1.2, and the version of rpsec and rspec-rails I'm using is the newest for today (Nov 7, 2008) 1.1.11.
EDIT Nov 12, 2008
I have both the rspec and rspec-rails gems installed. I've unpacked the gems into the vender/gems folder. Both are version 1.1.11.
Since RSpec has been become the default testing framework in Rails you no longer need to create spec docs via the rspec generators:
Rails 2 RSpec generator
rails generate rspec_model mymodel
Rails 3 RSpec generator
With RSpec as the default testing framework simply use Rails' own generators. This will construct all of the files you need including the RSpec tests. e.g.
$rails generate model mymodel
invoke active_record
create db/migrate/20110531144454_create_mymodels.rb
create app/models/mymodel.rb
invoke rspec
create spec/models/mymodel_spec.rb
Have you installed both rspec and rspec-rails gems?
script/generate rspec
requires rspec-rails gem to be installed.
For Rails 3 and rspec 2+
You must make sure you include 'rspec' and rspec-rails' in your Gemfile
Run Bundle Install
then run rails g rspec:install
If you are using rails 2.3 You need to use
ruby script/plugin install git://github.com/dchelimsky/rspec-rails.git -r 'refs/tags/1.3.3'
and then
ruby script/generate rspec
Is there supposed to be an 'rspec' generator? I've only used the following:
script/generate rspec_model mymodel
script/generate rspec_controller mycontroller
I've had this problem before, it boiled down to the version of RSpec I had not working with the version of Rails I was using. IIRC it was a 2.1 Rails and the updated RSpec hadn't been released as a gem. In fact, 1.1.11 is the gem I have, which would be the latest available (ignoring github gems), so I'm pretty sure that's exactly what my problem was.
I've taken to just using the head of master rspec with whatever version of Rails I happen to be on, it seems stable to me (and isn't going to break things in production, unless somehow a test broke with a false positive).
I do it with git using submodules, for example:
git submodule add git://github.com/dchelimsky/rspec.git vendor/plugins/rspec
git submodule add git://github.com/dchelimsky/rspec-rails.git vendor/plugins/rspec_on_rails
In case anyone is wondering about Rails 3 now,
this seems to do the trick for me:
http://github.com/rspec/rspec-rails/blob/29817932b99fc45adaa93c3f75d503c69aafcaef/README.markdown
I'm using rails 2.3.9. I started of trying to use the gem(s) but just couldn't get the generator for rspec to show up. Then I installed the plugin(s) using the instructions on https://github.com/dchelimsky/rspec/wiki/rails and that did the trick.
On Fedora 9 (OLPC) I did:
$ sudo gem install rspec
$ sudo gem install rspec-rails
Those got me to where I could run
$ ruby script/generate rspec
This worked for me, whereas the git instructions did not work.
If you are using bundler version 1.0.8 you should $ gem update bundler to a newer version 1.0.9.
I had the same symptons and updating bundler helped me out.
Now $ rails g is using gems defined in the Gemfile. Also I grouped my gems like this:
source 'http://rubygems.org'
gem 'rails', '3.0.3'
gem 'sqlite3-ruby', :require => 'sqlite3'
group :test, :development do
gem 'capybara', '0.4.1.1'
gem 'database_cleaner'
gem 'cucumber-rails'
gem 'rspec-rails', '~> 2.4'
gem 'launchy'
end
(Note that test gems are also in the :development group.)
Have a nice day :)
Lukas
If you type script/rails generate, the only RSpec generator you'll actually see is rspec:install. That's because RSpec is registered with Rails as the test framework, so whenever you generate application components like models, controllers, etc, RSpec specs are generated instead of Test::Unit tests.
Please note that the generators are there to help you get started, but they are no substitute for writing your own examples, and they are only guaranteed to work out of the box for the default scenario (ActiveRecord & Webrat).
https://github.com/rspec/rspec-rails
You might need to run bundle exec :
bundle exec rails g rspec:install
You'll need to do
sudo gem install cucumber-rails

Resources