Scenarios plugin

Plugin details

Scenarios are a drop in replacement for YAML fixtures. Instead of encouraging you to create a mindless amount of raw data in the form of YAML, scenarios encourage you to create code that populates your tables with the appropriate records.

Websitehttp://faithfulcode.rubyforge.org/docs/scenarios/ Repositoryhttp://faithfulcode.rubyforge.org/svn/plugins/trunk/scenarios/ Author Adam Williams, John W. Long, Chris Redinger Tags Fixtures LicenseMIT

Documentation

Install the plugin:
ruby script/plugin install http://faithfulcode.rubyforge.org/svn/plugins/trunk/scenarios/

Scenarios should be placed in the spec/scenarios directory of your Rails project. Scenario file names always end in "_scenario.rb" and classes end in "Scenario".

A simple scenario looks like this:

  # in spec/scenarios/users_scenario.rb
  class UsersScenario < Scenario::Base
    def load
      create_record :user, :john, :name => 'John', :password => 'doodaht'
      create_record :user, :cindy, :name => 'Cindy', :password => 'whoot!'
    end
  end



In the example above, I'm using the create_record instance method to create two users: John and Cindy. Notice the calls to create_record. There are three parameters. The first is the singular name of the table to insert the record into, the second is the symbolic name of the record (more on that later), and the third is a hash of the attributes of the record.

To use the UsersScenario in a description, you should declare it using the scenario method:

  # in spec/models/user_spec.rb
  describe User do
    scenario :users
    
    it "should allow me to do something with John" do
      user = users(:john)
      user.password.should == "doodaht"
    end
  end



Notice that it is easy to load an instance of a model object using its symbolic name with a reader method, similar to that of Rails' fixtures. In the example above, I loaded John with the reader method users and the symbolic name :john. (Remember that in the Users scenario I declared that John should be accessible through the symbolic name :john.)

=== Composition

In real life your scenarios will probably grow quite complicated. The scenarios plugin allows you to deal with this complexity through composition.

Here's a simple example:

  # in spec/scenarios/posts_scenario.rb
  class PostsScenario < Scenario::Base
    def load
      create_record :post, :first, :title => "First Post"
      create_record :post, :second, :title => "Second Post"
    end
  end
  
  # in spec/scnearios/comments_scenario.rb
  class CommentsScenario < Scenario::Base
    uses :posts
    
    def load
      create_record :comment, :first, :body => "Nice post!", :post_id => post_id(:first)
      create_record :comment, :second, :body => "I like it.", :post_id => post_id(:first)
      create_record :comment, :third, :body => "I thoroughly disagree.", :post_id => post_id(:second)
    end
  end



In the example above, the CommentsScenario declares that it depends on the Posts scenario with the uses class method. This means that if you load the CommentsScenario, the PostsScenario will be loaded first and the CommentsScenario will have access to all the data loaded by the PostsScenario in its own load method. Note that inside the load method I'm using another form of reader methed which simply gives you the id for a symbolic name (in this case: post_id). This is most useful for making associations, as done here with comments and posts.

=== Helper Methods

Another way of simplifying your scenarios and specs is through helper methods.The Scenarios plugin provides a handy way to declare helper methods that are accessible from inside the scenario and also from inside related RSpec examples:

  # in spec/scenarios/users_scenario.rb
  class UsersScenario < Scenario::Base
    def load
      create_user :name => "John"
    end

    helpers do
      def create_user(attributes={})
        create_record :user, attributes[:name].downcase.intern, attributes
      end
      def login_as(user)
        @request.session[:user_id] = user.id
      end
    end
  end



Helper methods declared inside the helpers block are mixed into the scenario when it is instantiated and mixed into examples that declare that they are using the scenario. Also, in the case where one scenario uses another, the using scenario will have the helper methods of the used scenario.

  # in spec/controllers/projects_controller_spec.rb
  describe "Projects screen" do
    scenario :users
    
    it "should show active projects" do
      login_as(users(:john))
      get :projects
      @response.should have_tag('#active_projects')
    end
  end



Notice that in the RSpec example I have access to the login_as helper method declared inside the helpers block of the UsersScenario. Scenario helpers are a great way to share helper methods between specs that use a specific scenario.

=== Load Rake Task

The Scenarios plugin provides a single Rake task, db:scenario:load, which you may use in a fashion similar to Rails fixtures' db:fixtures:load.

  rake db:scenario:load SCENARIO=comments



When invoked, this task will populate the development database with the named scenario.

If you do not specify SCENARIO, the task will expect to find a default scenario (a file 'default_scenario.rb' having DefaultScenario defined in it). It is our practice to have it such that this scenario uses a number of our other scenarios, thereby:

* encouraging us to use test data that looks good in the running development application
* allowing us to troubleshoot failing tests in the running development application

Further Documentation

There is currently no advanced documentation for this plugin.

New documentation

Edit plugin | Back in time (6 older versions) | Last edited by: scott, 11 months ago