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.