diff --git a/hobofields/rails_generators/hobofield_model/USAGE b/hobofields/rails_generators/hobofield_model/USAGE new file mode 100644 index 000000000..29013a9a8 --- /dev/null +++ b/hobofields/rails_generators/hobofield_model/USAGE @@ -0,0 +1,29 @@ +Description: + Stubs out a new model. Pass the model name, either CamelCased or + under_scored, and an optional list of attribute pairs as arguments. + + Attribute pairs are column_name:sql_type arguments specifying the + model's attributes. Timestamps are added by default, so you don't have to + specify them by hand as 'created_at:datetime updated_at:datetime'. + + You don't have to think up every attribute up front, but it helps to + sketch out a few so you can start working with the model immediately. + + This generates a model class in app/models, a unit test in test/unit, + a test fixture in test/fixtures/singular_name.yml, and a migration in + db/migrate. + +Examples: + `./script/generate hobofield_model account` + + creates an Account model, test, fixture, and migration: + Model: app/models/account.rb + Test: test/unit/account_test.rb + Fixtures: test/fixtures/accounts.yml + + `./script/generate hobofield_model post title:string body:text published:boolean` + + creates a Post model with a string title, text body, and published flag. + +After the model is created, and the fields are specified, use hobofield +to create the migrations incrementally. diff --git a/hobofields/rails_generators/hobofield_model/hobofield_model_generator.rb b/hobofields/rails_generators/hobofield_model/hobofield_model_generator.rb new file mode 100644 index 000000000..78636e5e4 --- /dev/null +++ b/hobofields/rails_generators/hobofield_model/hobofield_model_generator.rb @@ -0,0 +1,38 @@ +class HobofieldModelGenerator < Rails::Generator::NamedBase + default_options :skip_timestamps => false, :skip_fixture => false + + def manifest + record do |m| + # Check for class naming collisions. + m.class_collisions class_path, class_name, "#{class_name}Test" + + # Model, test, and fixture directories. + m.directory File.join('app/models', class_path) + m.directory File.join('test/unit', class_path) + m.directory File.join('test/fixtures', class_path) + + # Create stubs + m.template "model.rb.erb", "app/models/#{name}.rb" + m.template "test.rb.erb", "test/unit/#{name}_test.rb" + + unless options[:skip_fixture] + m.template 'fixtures.yml.erb', File.join('test/fixtures', "#{table_name}.yml") + end + + end + end + + protected + def banner + "Usage: #{$0} #{spec.name} ModelName [field:type, field:type]" + end + + def add_options!(opt) + opt.separator '' + opt.separator 'Options:' + opt.on("--skip-timestamps", + "Don't add timestamps to the migration file for this model") { |v| options[:skip_timestamps] = v } + opt.on("--skip-fixture", + "Don't generation a fixture file for this model") { |v| options[:skip_fixture] = v} + end +end \ No newline at end of file diff --git a/hobofields/rails_generators/hobofield_model/templates/fixtures.yml.erb b/hobofields/rails_generators/hobofield_model/templates/fixtures.yml.erb new file mode 100644 index 000000000..c21035113 --- /dev/null +++ b/hobofields/rails_generators/hobofield_model/templates/fixtures.yml.erb @@ -0,0 +1,19 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html + +<% unless attributes.empty? -%> +one: +<% for attribute in attributes -%> + <%= attribute.name %>: <%= attribute.default %> +<% end -%> + +two: +<% for attribute in attributes -%> + <%= attribute.name %>: <%= attribute.default %> +<% end -%> +<% else -%> +# one: +# column: value +# +# two: +# column: value +<% end -%> diff --git a/hobofields/rails_generators/hobofield_model/templates/model.rb.erb b/hobofields/rails_generators/hobofield_model/templates/model.rb.erb new file mode 100644 index 000000000..25cb2085b --- /dev/null +++ b/hobofields/rails_generators/hobofield_model/templates/model.rb.erb @@ -0,0 +1,10 @@ +class <%= class_name %> < ActiveRecord::Base + fields do + <% for attribute in attributes -%> + <%= attribute.type %> :<%= attribute.name %> + <% end -%> + <% unless options[:skip_timestamps] %> + timestamps + <% end -%> + end +end \ No newline at end of file diff --git a/hobofields/rails_generators/hobofield_model/templates/test.rb.erb b/hobofields/rails_generators/hobofield_model/templates/test.rb.erb new file mode 100644 index 000000000..96bd34ada --- /dev/null +++ b/hobofields/rails_generators/hobofield_model/templates/test.rb.erb @@ -0,0 +1,8 @@ +require 'test_helper' + +class <%= class_name %>Test < ActiveSupport::TestCase + # Replace this with your real tests. + def test_truth + assert true + end +end diff --git a/hobofields/test/test_generator_helper.rb b/hobofields/test/test_generator_helper.rb new file mode 100644 index 000000000..9d9debfc0 --- /dev/null +++ b/hobofields/test/test_generator_helper.rb @@ -0,0 +1,29 @@ +begin + require File.dirname(__FILE__) + '/test_helper' +rescue LoadError + require 'test/unit' +end +require 'fileutils' + +# Must set before requiring generator libs. +TMP_ROOT = File.dirname(__FILE__) + "/tmp" unless defined?(TMP_ROOT) +PROJECT_NAME = "myproject" unless defined?(PROJECT_NAME) +app_root = File.join(TMP_ROOT, PROJECT_NAME) +if defined?(APP_ROOT) + APP_ROOT.replace(app_root) +else + APP_ROOT = app_root +end +if defined?(RAILS_ROOT) + RAILS_ROOT.replace(app_root) +else + RAILS_ROOT = app_root +end + +begin + require 'rubigen' +rescue LoadError + require 'rubygems' + require 'rubigen' +end +require 'rubigen/helpers/generator_test_helper' diff --git a/hobofields/test/test_hobofield_model_generator.rb b/hobofields/test/test_hobofield_model_generator.rb new file mode 100644 index 000000000..989e5aed3 --- /dev/null +++ b/hobofields/test/test_hobofield_model_generator.rb @@ -0,0 +1,52 @@ +require File.join(File.dirname(__FILE__), "test_generator_helper.rb") + +require 'rails_generator' + +class TestHobofieldModelGenerator < Test::Unit::TestCase + include RubiGen::GeneratorTestHelper + + def setup + bare_setup + end + + def teardown + bare_teardown + end + + # Some generator-related assertions: + # assert_generated_file(name, &block) # block passed the file contents + # assert_directory_exists(name) + # assert_generated_class(name, &block) + # assert_generated_module(name, &block) + # assert_generated_test_for(name, &block) + # The assert_generated_(class|module|test_for) &block is passed the body of the class/module within the file + # assert_has_method(body, *methods) # check that the body has a list of methods (methods with parentheses not supported yet) + # + # Other helper methods are: + # app_root_files - put this in teardown to show files generated by the test method (e.g. p app_root_files) + # bare_setup - place this in setup method to create the APP_ROOT folder for each test + # bare_teardown - place this in teardown method to destroy the TMP_ROOT or APP_ROOT folder after each test + + def test_generator_without_options + name = "my_model" + run_generator('hobofield_model', [name], sources) + assert_generated_file("app/models/my_model.rb") + assert_generated_class("app/models/my_model") do |body| + end + + assert_generated_file("test/unit/my_model_test.rb") + assert_generated_class("test/unit/my_model_test") do |body| + assert_has_method "test_truth" + end + end + + private + def sources + [RubiGen::PathSource.new(:test, File.join(File.dirname(__FILE__),"..", generator_path)) + ] + end + + def generator_path + "rails_generators" + end +end