Howto Rails Generators with SeaCucumber

Over the weekend I spent some time working on some generators for SeaCucumber the javascript testing framework I am working on with Mike Ward. There is quite a bit of redundant HTML code that serves as plumbing to the framework and a generator would simplify that.

I found the most useful generator documentation is on the RoR wiki: Understanding Generators.

The generator code itself was very simple although it will be interesting to try for a more complex generator.

class SeacucumberGenerator < Rails::Generator::NamedBase
  def manifest
    record do |m|
      m.directory File.join('test/javascripts')
      m.directory File.join('public/javascripts')      

      m.file 'unittest.js', File.join("public", "javascripts", "unittest.js")
      m.file 'test.css', File.join("test", "javascripts", "test.css")

      m.template('javascript_template.js',
          File.join("public", "javascripts", "#{file_name}.js"))
      m.template('seacucumber_template.html',
          File.join("test", "javascripts", "#{file_name}_test.html"))
    end
  end
end

This generator does three basic things.

  • m.directory - Creates directories if necessary.
  • m.file - Copies static files without modification to the target directory.
  • m.template - Executes the two templates using ERB and writes them to the target location.

I used a NamedBase which take an argument. For example I might run this:

script/generate seacucumber MyFunction

Rails::Generator::NamedBase exposes a number of accessible attributes which are created from the argument. The most useful thing this class does is provide a bunch of attributes you can use from the manifest or template. It takes a trip to the source code to find out what they all are. To save time I thought I’d list them along with their values which follow standard rails inflection rules:

  • name MyFunction
  • class_name MyFunction
  • singular_name my_function
  • plural_name my_functions
  • table_name my_functions
  • class_path (blank)
  • file_path my_function
  • class_nesting (blank)
  • class_nesting_depth 0

Next I need to add a bit more sophistication to the templates I am generating to make them sensible for when someone is starting to develop a JavaScript function and needs to generate the Sea Cucumber plumbing.

Leave a Reply