= genspec Simple, expressive Rails 3 generator testing for RSpec. For the Rails 2.3 version, use genspec 0.1.x. == Installation sudo gem install genspec --pre ...then, in your Gemfile... group :test do config.gem 'genspec' end Warning: The prerelease version is for Rails 3.0 and is NOT compatible with 2.x! See the master branch for the Rails 2.3 version. == Usage Just like rspec-rails uses the structure of your spec/ directory to infer which test is being run (controllers, helpers, lib, etc.), you just need to create a spec/generators directory and put your generator specs in there. A basic generator spec might look something like this: # in spec/generators/custom_controller_spec.rb require 'spec_helper' describe :custom_controller do context "with no arguments or options" do it "should generate a help message" do subject.should output("A Help Message") end end context "with a name argument" do with_args :users it "should generate a UsersController" do subject.should generate("app/controllers/users_controller.rb") end end end === Specifying Arguments You may have noticed in the example above that we used _with_args_ to set up arguments passed into the generator. We can also pass any options we wish into that array. For instance, to pretend the _--verbose_ option was passed, we could use the following spec: describe :custom_controller do context "with --verbose option" do with_args "--verbose" # . . . end end Here is another example using _with_args_: describe :custom_controller do context "with a users controller and index, new, edit actions" do with_args :users, :index, :new, :edit # . . . end end Note that no matter what you specify as arguments, they'll be converted to an array of Strings -- because this is what gets passed into the generator if you run it from the command line. You can bypass that by passing an :object => true option as the last argument: describe :custom_controller do with_args MyFancyObject.new, :object => true # . . . end Finally, you can also let with_args generate a context for you: describe :custom_controller do with_args :users, :index, :new, :edit do # . . . end end This will generate an RSpec context that reads something like, "...with arguments [:users, :index, :new, :edit]". === Checking for Output If you need to test the generator's feedback rather than the generator's results, you can use the _output_ matcher to assert that your generator has produced some specific content in its output (which would be either a logger of some sort or $stdout). This is helpful for making sure your help message is accurate, for instance. # Ex 1: String it "should generate a help message" do subject.should output("A Help Message") end # Ex 2: Regular Expression it "should generate a help message" do subject.should output(/A [hH]elp Message/) end === Checking Generated Files This is the preferred way to test which files were actually generated, because this matcher checks your generator's *behavior*. That means it won't care _how_ a file is generated, as long as it _is_ generated. It's as simple as passing the name of the file you expected to be generated: it "should generate a readme file" do subject.should generate("README") end You can also check the generated file's content by simply passing a block. The _content_ argument in the block is a simple String containing the content of the file: it "should generate a model called 'user'" do subject.should generate("app/models/user.rb") { |content| content.should =~ /class User < ActiveRecord\:\:Base/ } end === Checking Generation Methods This is the most intrusive form of generation matching. While powerful, it will also make your tests brittle, because there's a high likelihood that even minor changes to your generators will require you to update the spec to match. However, sometimes you need to verify that some action occurs which can't be validated using the methods above, such as adding a gem source to the Gemfile. You can use the generation method matcher for this. it "should add a gem source" do subject.should generate(:add_source, "http://gems.github.com") end # -or- it "should add a gem source" do subject.should call_action(:add_source, "http://gems.github.com") end # -or- it "should add a gem source" do subject.should add_source("http://gems.github.com") end Note that all three of the above examples accomplish exactly the same task. Use whichever is most expressive for you. You can stop passing arguments at any time. This has the effect of widening the range of acceptable parameters. For instance, the following example does the same thing but will accept _any_ source URL, as long as the _add_source_ action is called: it "should add a gem source" do subject.should generate(:add_source) end Any method added to Thor, the backend code that drives Rails generators, should be picked up automatically by GenSpec. == 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 Colin MacKenzie IV. See LICENSE for details.