# RSpec 2 add-on for specifying and testing generators This project contains RSpec 2 matchers, helpers and various utilities to assist in writing Generator specs. There is additional support for writing specs for Generators in Rails 3. ## Why? 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. This RSpec DSL should make it very easy and enjoyable to spec and test your Generators with RSpec 2 :) ## Feedback Please let me know if you find any issues or have suggestions for improvements. ## Install gem install generator-spec The gem is a jewel based on [jeweler](http://github.com/technicalpickles/jeweler). To install the gem from the code, simply use the jeweler rake task: rake install ## Usage The following demonstrates usage of this library. There are many more options and DSL convenience methods (see wiki, code or specs). ### Configuration First setup the *spec_helper.rb*. Here is an example configuration.
# spec/spec_helper.rb
  
require 'rspec'
require 'generator-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__)
  config.logger = :stdout # :file to output to a log file, logger only active when debug is true
end

# or customize the location of the temporary Rails 3 app dir used
RSpec::Generator.configure do |config|
  # ...
  config.rails_root = '~/my/rails/folder'
end

### Specs for generators I recommend having a separate spec file for each generator (generator specs). You can use the special *require_generator* statement to ensure that one or more generators are loaded and made available for a given spec.
require_generator :canable
This will load the generator : `generators/canabale_generator.rb` If the generator is in a namespace (subfolder of generators), use a nested approach like this:
require_generators :canable => ['model', 'user']
This will load the generators: `generators/canable/model_generator.rb` and `generators/canable/user_generator.rb` You can also load generators from multiple namespaces and mix and match like this. I recommend against this however as it is difficult to read.
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 ### Example: full generator spec
# spec/generators/model_generator_spec.rb  

require 'spec_helper'

# list of generators to spec are loaded
require_generator :canable

describe 'model_generator' do
  # include Rails model helpers for ActiveRecord
  # available: 

  # Other ORM options - :mongo_mapper, :mongoid and :data_mapper
  # note: use_orm auto-includes the :model helper module
  use_orm :active_record
  
  # load helper modules and make available inside spec blocks
  # here the module in rails_helpers/rails_migration is included 
  # to load multiple helpers use the method -  use_helpers
  use_helper :migration
  
  before :each do              
    # define generator to test
    setup_generator 'model_generator' do
      tests Canable::Generators::ModelGenerator
    end    
    # ensure clean state before each run
    remove_model :account
  end

  after :each do              
    # ensure clean state after each run  
    remove_model :account
  end

  describe "the weird stuff!!!" do
    before :each do
      @generator = with_generator do |g|   
        g.run_generator :account.args
      end
    end
    
    it "should not work without an existing Account model file" do            
      @generator.should_not generate_file :account, :model
    end
  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
## Code specs There are a bunch of specialized ruby code matchers in the matchers/content folder which can be used to spec code files in general. Check out the specs in spec/generator_spec/matchers/content for examples on how to use these. ## Rails specs The rails_helpers folder contains a bunch of files which makes it easy to spec rails files and to perform various "Rails mutations". These mutations make it easy to setup the temporary Rails app in a specific pre-condition, which is required for a given spec. ### Examples: Rails helpers require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper') describe 'controller' do include RSpec::Rails::Controller before :each do create_controller :account do %q{ def index end } end end after :each do remove_controller :account end it "should have an account_controller file that contains an AccountController class with an index method inside" do Rails.application.should have_controller :account do |controller_file| controller_file.should have_controller_class :account do |klass| klass.should have_method :index 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 Copyright (c) 2010 Kristian Mandrup. See LICENSE for details.