RSpec 2 library for specifying and testing generators
This project contains RSpec 2 matchers, helpers and various utilities to assist in writing Rails 3 generator specs.
Rails 3 has a Rails::Generators::TestCase class for use with Test-Unit, to help test generators. This TestCase contains specific custom assertion methods that can be used to assert generator behavior. To create an RSpec 2 equivalent, I wrapped Rails::Generators::TestCase for use with RSpec 2 and created some RSpec 2 matchers that mimic the assertion methods of the Test-Unit TestCase. I have also a bunch of "extra goodies" to the mix. The new intuitive DSL RSpec DSL for specifying/testing generators should make it very easy and intuitive to test your Rails 3 generators with RSpec 2 :)
Please advice if you find any issues or have suggestions for improvements. The code is not as pretty as it could be, so feel free to refactor and improve this gem to your hearts desire!
gem install generator-spec
Install from code
The gem is a jewel based on jeweler. To install the gem from the code, simply use the jeweler rake task:
The following demonstrates usage of this gem. There are many more options and DSL convenience methods.
First setup the spec_helper.rb. Here is an example configuration.
# spec/spec_helper.rb require 'rspec' require 'generators_spec' # configure it like this to use default settings RSpec::Generator.configure do |config| config.debug = false config.remove_temp_dir = true config.default_rails_root(__FILE__) end # or customize the location of the temporary Rails 3 app dir used RSpec::Generator.configure do |config| config.debug = false config.remove_temp_dir = true config.rails_root = '~/my/rails/folder' end
Specs for generators
I recommend having a separate spec for each generator called a 'generator spec'. You can use the special require_generator statement to ensure that one or more generators are loaded and made available for the spec.
This will load the generator :
If the generator is in a namespace, use a nested approach like this:
require_generators :canable => ['model', 'user']
This will load the generators:
You can also load generators from multiple namespaces and mix and match like this
require_generators [:canable => ['model', 'user'], :other => :side, :simple]
Auto-require all generators
You can also require all generators or all within a specific namespace like this:
require_generators :all require_generators :canable => :all
Using a shared generator loader file
If you have multiple generators in a shared namespace, the following alternative approach can be used. Create a file that loads all the generators you are specifying in this folder, fx all generators in a specific namespace. Then include this 'generator load file' in each spec.
This uses the 'require_all' gem functionality
Example usage: require generators
# spec/generators/canable.rb require_generators :canable => ['model', 'user']
# spec/generators/canable/model_generator_spec.rb ... # load generators to spec require 'generators/canable' describe 'model_generator' do ... end
# spec/generators/canable/user_generator_spec.rb ... # load generators to spec require 'generators/canable' describe 'user_generator' do ... end
Example: full generator spec
# spec/generators/model_generator_spec.rb require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') # list of generators to spec are loaded require 'generators/canable' describe 'model_generator' do # include Rails model helpers for ActiveRecord # available: MongoMapper, Mongoid and DataMapper include RSpec::Rails::Orm::ActiveRecord before :each do # define generator to test setup_generator 'model_generator' do tests Canable::Generators::ModelGenerator end # ensure clean state before run remove_model :account end after :each do # ensure clean state after each run remove_model :account end it "should not work without an existing Account model file" do with_generator do |g| g.run_generator :account.args g.should_not generate_file :account, :model end end it "should decorate an existing Account model file with 'include Canable:Ables'" do with_generator do |g| create_model :account g.run_generator 'account'.args g.should generate_model :account do |content| content.should have_class :account do |klass| klass.should include_module 'Canable::Ables' end end end end end
Note on Patches/Pull Requests
- Fork the project.
- Make your feature addition or bug fix.
- Add tests for it. This is important so I don't break it in a future version unintentionally.
- Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
- Send me a pull request. Bonus points for topic branches.
Copyright (c) 2010 Kristian Mandrup. See LICENSE for details.