├── Gemfile ├── lib ├── generators │ ├── mustache │ │ ├── controller │ │ │ ├── templates │ │ │ │ ├── view.html.mustache.erb │ │ │ │ └── view.rb.erb │ │ │ └── controller_generator.rb │ │ ├── scaffold │ │ │ ├── templates │ │ │ │ ├── _form.html.mustache.erb │ │ │ │ ├── edit.html.mustache.erb │ │ │ │ ├── new.html.mustache.erb │ │ │ │ ├── show.html.mustache.erb │ │ │ │ ├── index.html.mustache.erb │ │ │ │ ├── show.rb.erb │ │ │ │ ├── index.rb.erb │ │ │ │ ├── new.rb.erb │ │ │ │ └── edit.rb.erb │ │ │ └── scaffold_generator.rb │ │ ├── install │ │ │ ├── templates │ │ │ │ ├── config │ │ │ │ │ └── initializers │ │ │ │ │ │ └── mustache.rb │ │ │ │ └── lib │ │ │ │ │ └── mustache_rails.rb │ │ │ └── install_generator.rb │ │ └── README.md │ ├── data_mapper │ │ ├── observer │ │ │ ├── templates │ │ │ │ └── observer.rb │ │ │ └── observer_generator.rb │ │ ├── model │ │ │ ├── templates │ │ │ │ ├── model.rb │ │ │ │ └── migration.rb │ │ │ └── model_generator.rb │ │ └── migration │ │ │ ├── templates │ │ │ └── migration.rb │ │ │ └── migration_generator.rb │ ├── shoulda │ │ ├── model │ │ │ ├── templates │ │ │ │ └── model.rb │ │ │ └── model_generator.rb │ │ ├── scaffold │ │ │ ├── scaffold_generator.rb │ │ │ └── templates │ │ │ │ └── scaffold.rb │ │ └── controller │ │ │ ├── controller_generator.rb │ │ │ └── templates │ │ │ └── controller.rb │ ├── koala │ │ └── install │ │ │ ├── templates │ │ │ ├── config │ │ │ │ ├── facebook.yml.tt │ │ │ │ └── initializers │ │ │ │ │ └── koala.rb.tt │ │ │ └── app │ │ │ │ └── helpers │ │ │ │ └── facebook_helper.rb.tt │ │ │ └── install_generator.rb │ ├── koala.rb │ ├── mustache.rb │ ├── shoulda.rb │ ├── active_model │ │ └── model │ │ │ ├── templates │ │ │ └── model.rb │ │ │ └── model_generator.rb │ ├── active_model.rb │ ├── helpers │ │ ├── model_helper.rb │ │ └── migration_helper.rb │ └── data_mapper.rb ├── rails3-generators │ └── version.rb └── rails3-generators.rb ├── test ├── lib │ └── generators │ │ ├── mustache │ │ ├── testing_helper.rb │ │ ├── controller_generator_test.rb │ │ └── scaffold_generator_test.rb │ │ ├── koala │ │ └── install_generator_test.rb │ │ ├── data_mapper │ │ ├── observer_generator_test.rb │ │ ├── migration_generator_test.rb │ │ └── model_generator_test.rb │ │ ├── active_model │ │ └── model_generator_test.rb │ │ └── shoulda │ │ ├── scaffold_generator_test.rb │ │ └── controller_generator_test.rb ├── fixtures │ └── routes.rb └── test_helper.rb ├── .gitignore ├── Rakefile ├── README.rdoc ├── rails3-generators.gemspec ├── Gemfile.lock └── CHANGELOG.rdoc /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /lib/generators/mustache/controller/templates/view.html.mustache.erb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/rails3-generators/version.rb: -------------------------------------------------------------------------------- 1 | module Rails3 2 | module Generators 3 | VERSION = "1.0.0" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/lib/generators/mustache/testing_helper.rb: -------------------------------------------------------------------------------- 1 | require_generators :mustache => ['scaffold', 'controller', 'install'] -------------------------------------------------------------------------------- /lib/generators/mustache/controller/templates/view.rb.erb: -------------------------------------------------------------------------------- 1 | class <%= singular_name.camelize %>::<%= @action.camelize %> < Mustache::Rails 2 | 3 | end -------------------------------------------------------------------------------- /lib/generators/data_mapper/observer/templates/observer.rb: -------------------------------------------------------------------------------- 1 | class <%= class_name %>Observer 2 | include DataMapper::Observer 3 | 4 | observe <%= class_name %> 5 | end 6 | -------------------------------------------------------------------------------- /lib/generators/shoulda/model/templates/model.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class <%= class_name %>Test < ActiveSupport::TestCase 4 | should "be valid" do 5 | assert <%= class_name %>.new.valid? 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/generators/mustache/scaffold/templates/_form.html.mustache.erb: -------------------------------------------------------------------------------- 1 |

<% for attribute in attributes -%> 2 | {{{<%= attribute.name %>_label}}}: {{{<%= attribute.name %>_text_field}}}
3 | <% end -%>

4 | {{{form_submit}}} -------------------------------------------------------------------------------- /lib/generators/koala/install/templates/config/facebook.yml.tt: -------------------------------------------------------------------------------- 1 | development: 2 | app_id: YOUR APP ID 3 | secret: YOUR SECRET 4 | test: 5 | app_id: YOUR APP ID 6 | secret: YOUR SECRET 7 | production: 8 | app_id: YOUR APP ID 9 | secret: YOUR SECRET 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## MAC OS 2 | .DS_Store 3 | 4 | ## TEXTMATE 5 | *.tmproj 6 | tmtags 7 | 8 | ## EMACS 9 | *~ 10 | \#* 11 | .\#* 12 | 13 | ## VIM 14 | *.swp 15 | 16 | ## PROJECT::GENERAL 17 | coverage 18 | rdoc 19 | pkg 20 | .bundle 21 | 22 | ## PROJECT::SPECIFIC 23 | tmp/**/* 24 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | require "bundler/gem_tasks" 3 | 4 | require "rake/testtask" 5 | Rake::TestTask.new(:test) do |test| 6 | test.libs << "lib" << "test" 7 | test.pattern = "test/**/*_test.rb" 8 | test.verbose = true 9 | end 10 | 11 | task :default => :test 12 | -------------------------------------------------------------------------------- /lib/generators/koala.rb: -------------------------------------------------------------------------------- 1 | module Koala 2 | module Generators 3 | module TemplatePath 4 | def source_root 5 | @_koala_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'koala', generator_name, 'templates')) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/generators/mustache/install/templates/config/initializers/mustache.rb: -------------------------------------------------------------------------------- 1 | # Be sure to install mustache gem and include mustache gem in project Gemfile. 2 | 3 | # Template Handler 4 | require 'mustache_rails' 5 | # Generator 6 | Rails.application.config.generators.template_engine :mustache 7 | -------------------------------------------------------------------------------- /lib/generators/mustache/scaffold/templates/edit.html.mustache.erb: -------------------------------------------------------------------------------- 1 |

Editing <%= singular_name.capitalize %>

2 | 3 | {{{errors_display_div}}} 4 | 5 |
6 | {{{<%= singular_name %>_form_tag}}} 7 | {{> form }} 8 | 9 |
10 | Back to record 11 | -------------------------------------------------------------------------------- /lib/generators/mustache/scaffold/templates/new.html.mustache.erb: -------------------------------------------------------------------------------- 1 |

New <%= singular_name.capitalize %>

2 | 3 | {{{errors_display_div}}} 4 | 5 |
6 | {{{<%= singular_name %>_form_tag}}} 7 | {{> form }} 8 | 9 |
10 | 11 | Back to listing 12 | -------------------------------------------------------------------------------- /lib/generators/mustache.rb: -------------------------------------------------------------------------------- 1 | class Mustache 2 | module Generators 3 | module TemplatePath 4 | def source_root 5 | @_mustache_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'mustache', generator_name, 'templates')) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /lib/generators/mustache/scaffold/templates/show.html.mustache.erb: -------------------------------------------------------------------------------- 1 |

Displaying <%= singular_name.capitalize %>

2 | 3 | <% for attribute in attributes -%> 4 |

<%= attribute.human_name %>: {{<%= attribute.name %>}}

5 | <% end -%> 6 | 7 | Edit | Back 8 | -------------------------------------------------------------------------------- /lib/generators/koala/install/templates/app/helpers/facebook_helper.rb.tt: -------------------------------------------------------------------------------- 1 | module FacebookHelper 2 | 3 | def facebook_cookies 4 | @facebook_cookies ||= Koala::Facebook::OAuth.new.get_user_from_cookie(cookies) 5 | end 6 | 7 | def access_token 8 | @access_token ||= facebook_cookies['access_token'] 9 | end 10 | 11 | end 12 | -------------------------------------------------------------------------------- /lib/generators/shoulda.rb: -------------------------------------------------------------------------------- 1 | require 'rails/generators/named_base' 2 | 3 | module Shoulda 4 | module Generators 5 | class Base < Rails::Generators::NamedBase #:nodoc: 6 | def self.source_root 7 | @_shoulda_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'shoulda', generator_name, 'templates')) 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /lib/generators/mustache/scaffold/templates/index.html.mustache.erb: -------------------------------------------------------------------------------- 1 |

Listing <%= plural_name.capitalize %>

2 | 3 | {{#listing}} 4 | 5 |

6 | <% attributes.collect do |attribute| -%> 7 | <%= attribute.human_name %>: {{<%= attribute.name %>}} 8 | <% end.join(" | ") -%> 9 | | Details

10 | 11 | {{/listing}} 12 | 13 |

New

14 | -------------------------------------------------------------------------------- /lib/generators/data_mapper/model/templates/model.rb: -------------------------------------------------------------------------------- 1 | class <%= class_name %><%= "< #{options[:parent].classify}" if parent? %> 2 | <% unless parent? -%> 3 | include DataMapper::Resource 4 | 5 | property :id, Serial 6 | <% end -%> 7 | <% attributes.each do |attribute| -%> 8 | property :<%= attribute.name %>, <%= attribute.type_class %> 9 | <% end -%> 10 | 11 | <%= timestamp_statements if timestamps? %> 12 | end 13 | -------------------------------------------------------------------------------- /lib/generators/active_model/model/templates/model.rb: -------------------------------------------------------------------------------- 1 | class <%= class_name %> 2 | include ActiveModel::Serialization 3 | include ActiveModel::Validations 4 | <% if read_properties? %> 5 | attr_reader <%= read_properties %> 6 | <% end %> 7 | <% if write_properties? %> 8 | attr_writer <%= write_properties %> 9 | <% end %> 10 | <% if accessor_properties? %> 11 | attr_accessor <%= accessor_properties %> 12 | <% end %> 13 | end 14 | -------------------------------------------------------------------------------- /lib/generators/data_mapper/observer/observer_generator.rb: -------------------------------------------------------------------------------- 1 | require 'generators/data_mapper' 2 | 3 | module DataMapper 4 | module Generators 5 | class ObserverGenerator < Base 6 | check_class_collision :suffix => "Observer" 7 | 8 | def create_observer_file 9 | template 'observer.rb', File.join('app/models', class_path, "#{file_name}_observer.rb") 10 | end 11 | 12 | hook_for :test_framework 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/generators/mustache/scaffold/templates/show.rb.erb: -------------------------------------------------------------------------------- 1 | class <%= plural_name.camelize %>::Show < Mustache::Rails 2 | 3 | <% for attribute in attributes -%> 4 | def <%= attribute.name %> 5 | <%= singular_name %>.<%= attribute.name %> 6 | end 7 | 8 | <% end -%> 9 | 10 | def edit_path 11 | edit_<%= singular_name %>_path(@<%= singular_name %>) 12 | end 13 | 14 | def index_path 15 | <%= plural_name %>_path 16 | end 17 | 18 | end -------------------------------------------------------------------------------- /lib/generators/mustache/install/install_generator.rb: -------------------------------------------------------------------------------- 1 | require 'generators/mustache' 2 | 3 | class Mustache 4 | module Generators 5 | class InstallGenerator < ::Rails::Generators::Base 6 | extend TemplatePath 7 | 8 | def copy_initializer_files 9 | copy_file "config/initializers/mustache.rb", "config/initializers/mustache.rb" 10 | copy_file "lib/mustache_rails.rb", "lib/mustache_rails.rb" 11 | end 12 | 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/generators/mustache/scaffold/templates/index.rb.erb: -------------------------------------------------------------------------------- 1 | class <%= plural_name.camelize %>::Index < Mustache::Rails 2 | 3 | def new_path 4 | new_<%= singular_name %>_path() 5 | end 6 | 7 | def listing 8 | <%= plural_name %>.collect do |record| 9 | { 10 | <% for attribute in attributes -%> 11 | :<%= attribute.name %> => record.<%= attribute.name %>, 12 | <% end -%> 13 | :show_path => <%= singular_name %>_path(record) 14 | } 15 | end 16 | end 17 | 18 | end -------------------------------------------------------------------------------- /lib/generators/shoulda/scaffold/scaffold_generator.rb: -------------------------------------------------------------------------------- 1 | require 'generators/shoulda' 2 | 3 | module Shoulda 4 | module Generators 5 | class ScaffoldGenerator < Base 6 | include Rails::Generators::ResourceHelpers 7 | 8 | check_class_collision :suffix => 'ControllerTest' 9 | 10 | def create_controller_file 11 | template 'scaffold.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb") 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/generators/data_mapper/model/templates/migration.rb: -------------------------------------------------------------------------------- 1 | migration <%= migration_number.to_i %>, :<%= migration_file_name %> do 2 | up do 3 | create_table :<%= table_name %> do 4 | <% attributes.each do |attribute| -%> 5 | column :<%= attribute.name -%>, <%= attribute.type_class %> 6 | <% end -%> 7 | <% if options[:timestamps] %> 8 | column :created_at, DateTime 9 | column :updated_at, DateTime 10 | <% end -%> 11 | end 12 | end 13 | 14 | down do 15 | drop_table :<%= table_name %> 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /test/lib/generators/koala/install_generator_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Koala::Generators::InstallGeneratorTest < Rails::Generators::TestCase 4 | destination File.join(Rails.root) 5 | tests Koala::Generators::InstallGenerator 6 | arguments [] 7 | 8 | setup :prepare_destination 9 | 10 | test 'Koala is installed' do 11 | run_generator 12 | 13 | assert_file "config/facebook.yml" 14 | assert_file "config/initializers/koala.rb" 15 | assert_file "app/helpers/facebook_helper.rb" 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/generators/shoulda/model/model_generator.rb: -------------------------------------------------------------------------------- 1 | require 'generators/shoulda' 2 | 3 | module Shoulda 4 | module Generators 5 | class ModelGenerator < Base 6 | argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" 7 | class_option :dir, :type => :string, :default => "test/unit", :desc => "The directory where the model tests should go" 8 | 9 | def create_model_test_file 10 | template 'model.rb', File.join(options[:dir], "#{singular_name}_test.rb") 11 | end 12 | 13 | hook_for :fixture_replacement 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/generators/koala/install/install_generator.rb: -------------------------------------------------------------------------------- 1 | require 'generators/koala' 2 | 3 | module Koala 4 | module Generators 5 | class InstallGenerator < Rails::Generators::Base 6 | extend TemplatePath 7 | 8 | def copy_config_file 9 | template "config/facebook.yml.tt", "config/facebook.yml" 10 | end 11 | 12 | def copy_initializer_file 13 | template "config/initializers/koala.rb.tt", "config/initializers/koala.rb" 14 | end 15 | 16 | def copy_helper_file 17 | template "app/helpers/facebook_helper.rb.tt", "app/helpers/facebook_helper.rb" 18 | end 19 | 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/generators/shoulda/controller/controller_generator.rb: -------------------------------------------------------------------------------- 1 | require 'generators/shoulda' 2 | 3 | module Shoulda 4 | module Generators 5 | class ControllerGenerator < Base 6 | argument :actions, :type => :array, :default => [], :banner => "action action" 7 | class_option :dir, :type => :string, :default => "test/functional", :desc => "The directory where the controller tests should go" 8 | 9 | check_class_collision :suffix => 'ControllerTest' 10 | 11 | def create_controller_file 12 | template 'controller.rb', File.join(options[:dir], "#{file_name}_controller_test.rb") 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /test/lib/generators/data_mapper/observer_generator_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require_generator :data_mapper => ['observer'] 3 | 4 | class DataMapper::Generators::ObserverGeneratorTest < Rails::Generators::TestCase 5 | destination File.join(Rails.root) 6 | tests DataMapper::Generators::ObserverGenerator 7 | 8 | setup :prepare_destination 9 | setup :copy_routes 10 | 11 | test "invoke with model name" do 12 | name = 'account' 13 | content = run_generator %w(Account) 14 | 15 | assert_file "app/models/#{name}_observer.rb" do |account| 16 | assert_class "Account", account do |klass| 17 | assert_match /include DataMapper::Observer/, klass 18 | assert_match /observe\s+#{name.camelize}/, klass 19 | end 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /lib/generators/data_mapper/migration/templates/migration.rb: -------------------------------------------------------------------------------- 1 | migration <%= migration_number.to_i %>, :<%= migration_file_name %> do 2 | up do 3 | <% unless attributes.empty? -%> 4 | modify_table :<%= table_name %> do 5 | <% attributes.each do |attribute| -%> 6 | <%= migration_action %>_column :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type_class %><% end -%> 7 | <% end -%> 8 | end 9 | <% end -%> 10 | end 11 | 12 | down do 13 | <% unless attributes.empty? -%> 14 | modify_table :<%= table_name %> do 15 | <% attributes.reverse.each do |attribute| -%> 16 | <%= migration_action == 'add' ? 'drop' : 'add' %>_column :<%= attribute.name %><% if migration_action == 'drop' %>, :<%= attribute.type_class %><% end -%> 17 | <% end -%> 18 | end 19 | <% end -%> 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/generators/data_mapper/migration/migration_generator.rb: -------------------------------------------------------------------------------- 1 | require 'generators/data_mapper' 2 | 3 | module DataMapper 4 | module Generators 5 | class MigrationGenerator < Base 6 | argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" 7 | class_option :id, :type => :numeric, :desc => "The id to be used in this migration" 8 | 9 | def create_migration_file 10 | set_local_assigns! 11 | migration_template "migration.rb", "db/migrate/#{file_name}.rb" 12 | end 13 | 14 | protected 15 | attr_reader :migration_action 16 | 17 | def set_local_assigns! 18 | if file_name =~ /^(add|remove|drop)_.*_(?:to|from)_(.*)/ 19 | @migration_action = $1 == 'add' ? 'add' : 'drop' 20 | @table_name = $2.pluralize 21 | end 22 | end 23 | 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/generators/active_model.rb: -------------------------------------------------------------------------------- 1 | require 'rails/generators/named_base' 2 | require 'rails/generators/migration' 3 | require 'rails/generators/active_model' 4 | 5 | require 'generators/helpers/migration_helper' 6 | 7 | module ActiveModel 8 | module Generators 9 | class Base < Rails::Generators::NamedBase #:nodoc: 10 | 11 | def self.source_root 12 | @_activemodel_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 13 | 'active_model', generator_name, 'templates')) 14 | end 15 | 16 | end 17 | 18 | class ActiveModel < Rails::Generators::ActiveModel #:nodoc: 19 | end 20 | end 21 | end 22 | 23 | module Rails 24 | module Generators 25 | class GeneratedAttribute #:nodoc: 26 | def type_class 27 | return 'DateTime' if type.to_s == 'datetime' 28 | return type.to_s.camelcase 29 | end 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/generators/koala/install/templates/config/initializers/koala.rb.tt: -------------------------------------------------------------------------------- 1 | # config/initializers/koala.rb 2 | # Monkey-patch in Facebook config so Koala knows to 3 | # automatically use Facebook settings from here if none are given 4 | 5 | module Facebook 6 | CONFIG = YAML.load(ERB.new(File.read("#{Rails.root}/config/facebook.yml")).result)[Rails.env] 7 | APP_ID = CONFIG['app_id'] 8 | SECRET = CONFIG['secret_key'] 9 | end 10 | 11 | Koala::Facebook::OAuth.class_eval do 12 | def initialize_with_default_settings(*args) 13 | case args.size 14 | when 0, 1 15 | raise "application id and/or secret are not specified in the config" unless Facebook::APP_ID && Facebook::SECRET 16 | initialize_without_default_settings(Facebook::APP_ID.to_s, Facebook::SECRET.to_s, args.first) 17 | when 2, 3 18 | initialize_without_default_settings(*args) 19 | end 20 | end 21 | 22 | alias_method_chain :initialize, :default_settings 23 | end 24 | -------------------------------------------------------------------------------- /lib/generators/helpers/model_helper.rb: -------------------------------------------------------------------------------- 1 | module Rails3Generators 2 | module Helpers 3 | module Model 4 | 5 | attr_accessor :model_attributes, :model_indexes 6 | 7 | def parse_model_attributes(with_indexes = true) 8 | @model_attributes = [] 9 | @model_indexes = {} 10 | end 11 | 12 | def arg_name(arg) 13 | arg.split(':').first 14 | end 15 | 16 | def arg_type(arg) 17 | arg.split(':')[1] || 'string' 18 | end 19 | 20 | def model_name 21 | name 22 | end 23 | 24 | def model_exists? 25 | File.exist? destination_path("app/models/#{singular_name}.rb") 26 | end 27 | 28 | def singular_name 29 | model_name.underscore 30 | end 31 | 32 | def plural_name 33 | model_name.underscore.pluralize 34 | end 35 | 36 | def class_name 37 | model_name.camelize 38 | end 39 | 40 | def plural_class_name 41 | plural_name.camelize 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /test/lib/generators/mustache/controller_generator_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'lib/generators/mustache/testing_helper' 3 | 4 | class Mustache::Generators::ControllerGeneratorTest < Rails::Generators::TestCase 5 | destination File.join(Rails.root) 6 | tests Rails::Generators::ControllerGenerator 7 | arguments %w(Account foo bar --template-engine mustache) 8 | 9 | setup :prepare_destination 10 | setup :copy_routes 11 | 12 | test "should generate mustache views" do 13 | run_generator 14 | assert_file "app/views/account/foo.rb" 15 | assert_file "app/views/account/bar.rb" 16 | end 17 | 18 | test "should generate mustache views as classes with scoped names extending Mustache::Rails" do 19 | run_generator 20 | assert_file "app/views/account/foo.rb", 21 | %r(class Account::Foo < Mustache::Rails) 22 | assert_file "app/views/account/bar.rb", 23 | %r(class Account::Bar < Mustache::Rails) 24 | end 25 | 26 | test "should generate mustache template files" do 27 | run_generator 28 | assert_file "app/templates/account/foo.html.mustache" 29 | assert_file "app/templates/account/bar.html.mustache" 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /lib/rails3-generators.rb: -------------------------------------------------------------------------------- 1 | require "rails/generators" 2 | 3 | module Rails3Generators 4 | end 5 | 6 | Rails::Generators.hidden_namespaces << "rails" 7 | 8 | %w(active_record data_mapper active_model).each do |orm| 9 | Rails::Generators.hidden_namespaces << 10 | [ 11 | "#{orm}:migration", 12 | "#{orm}:model", 13 | "#{orm}:observer", 14 | "#{orm}:session_migration", 15 | ] 16 | end 17 | 18 | %w(test_unit rspec shoulda).each do |test| 19 | Rails::Generators.hidden_namespaces << 20 | [ 21 | "#{test}:controller", 22 | "#{test}:helper", 23 | "#{test}:integration", 24 | "#{test}:mailer", 25 | "#{test}:model", 26 | "#{test}:observer", 27 | "#{test}:scaffold", 28 | "#{test}:view", 29 | "#{test}:performance", 30 | "#{test}:plugin", 31 | ] 32 | end 33 | 34 | %w(fabrication factory_girl machinist).each do |fixture_replacement| 35 | Rails::Generators.hidden_namespaces << 36 | [ 37 | "#{fixture_replacement}:model", 38 | ] 39 | end 40 | 41 | %w(erb haml mustache).each do |template| 42 | Rails::Generators.hidden_namespaces << 43 | [ 44 | "#{template}:controller", 45 | "#{template}:scaffold", 46 | "#{template}:mailer" 47 | ] 48 | end 49 | 50 | Rails::Generators.hidden_namespaces.flatten! 51 | -------------------------------------------------------------------------------- /lib/generators/active_model/model/model_generator.rb: -------------------------------------------------------------------------------- 1 | require 'generators/active_model' 2 | 3 | module ActiveModel 4 | module Generators 5 | class ModelGenerator < Base 6 | argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" 7 | 8 | check_class_collision 9 | 10 | def create_model_file 11 | template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb") 12 | end 13 | 14 | def read_properties? 15 | attributes.any?{|attr| attr.type == :read } 16 | end 17 | 18 | def read_properties 19 | attributes.select{|attr| attr.type == :read}.map{|attr| ":#{attr.name}" }.join(",") 20 | end 21 | 22 | def write_properties? 23 | attributes.any?{|attr| attr.type == :write } 24 | end 25 | 26 | def write_properties 27 | attributes.select{|attr| attr.type == :write }.map{|attr| ":#{attr.name}" }.join(",") 28 | end 29 | 30 | def accessor_properties? 31 | attributes.any?{|attr| attr.type == :all } 32 | end 33 | 34 | def accessor_properties 35 | attributes.select{|attr| attr.type == :all }.map{|attr| ":#{attr.name}" }.join(",") 36 | end 37 | 38 | hook_for :test_framework 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /test/lib/generators/active_model/model_generator_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require_generator :active_model => ['model'] 3 | 4 | class ActiveModel::Generators::ModelGeneratorTest < Rails::Generators::TestCase 5 | destination File.join(Rails.root) 6 | tests ActiveModel::Generators::ModelGenerator 7 | 8 | setup :prepare_destination 9 | setup :copy_routes 10 | 11 | test "invoke with model name" do 12 | content = run_generator %w(Account) 13 | 14 | assert_file "app/models/account.rb" do |account| 15 | assert_class "Account", account do |klass| 16 | assert_match /include ActiveModel::Validations/, klass 17 | assert_match /include ActiveModel::Serialization/, klass 18 | end 19 | end 20 | end 21 | 22 | test "invoke with model name and accessors" do 23 | content = run_generator %w(Account name:all age:read color:write ) 24 | 25 | assert_file "app/models/account.rb" do |account| 26 | assert_class "Account", account do |klass| 27 | assert_match /include ActiveModel::Validations/, klass 28 | assert_match /include ActiveModel::Serialization/, klass 29 | assert_match /attr_reader :age/, klass 30 | assert_match /attr_writer :color/, klass 31 | assert_match /attr_accessor :name/, klass 32 | end 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lib/generators/mustache/scaffold/scaffold_generator.rb: -------------------------------------------------------------------------------- 1 | require 'generators/mustache' 2 | require 'rails/generators/erb/scaffold/scaffold_generator' 3 | 4 | class Mustache 5 | module Generators 6 | class ScaffoldGenerator < Erb::Generators::ScaffoldGenerator 7 | extend TemplatePath 8 | 9 | # TODO Layout files? snusnu claims his template engine supports layouts: 10 | # http://github.com/defunkt/mustache/issues/#issue/3/comment/263445 11 | 12 | def copy_view_files 13 | views = available_views 14 | views.delete("index") if options[:singleton] 15 | 16 | views.each do |view| 17 | template "#{view}.rb.erb", 18 | File.join("app/views", controller_file_path, "#{view}.rb") 19 | template "#{view}.html.mustache.erb", 20 | File.join("app/templates", 21 | controller_file_path, 22 | "#{view}.html.mustache") 23 | end 24 | template "_form.html.mustache.erb", 25 | File.join("app/templates", 26 | controller_file_path, 27 | "_form.html.mustache") 28 | end 29 | 30 | private 31 | 32 | def available_views 33 | %w(index edit show new) 34 | end 35 | 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /test/lib/generators/shoulda/scaffold_generator_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Shoulda::Generators::ScaffoldGeneratorTest < Rails::Generators::TestCase 4 | destination File.join(Rails.root) 5 | tests Rails::Generators::ScaffoldGenerator 6 | arguments %w(accounts --test-framework shoulda) 7 | 8 | setup :prepare_destination 9 | setup :copy_routes 10 | 11 | test "should invoke test framework" do 12 | run_generator 13 | assert_file "test/functional/accounts_controller_test.rb" 14 | end 15 | 16 | test "should create test class" do 17 | run_generator 18 | assert_file "test/functional/accounts_controller_test.rb" do |controller_test| 19 | assert_class "AccountsControllerTest", controller_test 20 | end 21 | end 22 | 23 | test "should create controller action tests" do 24 | run_generator 25 | assert_file "test/functional/accounts_controller_test.rb" do |controller_test| 26 | assert_class "AccountsControllerTest", controller_test do |klass| 27 | assert_match /context "index action"/, klass 28 | assert_match /context "show action"/, klass 29 | assert_match /context "new action"/, klass 30 | assert_match /context "create action"/, klass 31 | assert_match /context "edit action"/, klass 32 | assert_match /context "update action"/, klass 33 | assert_match /context "destroy action"/, klass 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /test/lib/generators/data_mapper/migration_generator_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require_generator :data_mapper => ['migration'] 3 | 4 | class DataMapper::Generators::MigrationGeneratorTest < Rails::Generators::TestCase 5 | destination File.join(Rails.root) 6 | tests DataMapper::Generators::MigrationGenerator 7 | 8 | setup :prepare_destination 9 | setup :copy_routes 10 | 11 | test "invoke with name of migration" do 12 | name = 'account' 13 | run_generator %w{Account} 14 | migration_name = Dir[File.join(Rails.root, "db/migrate/*_#{name}.rb")].first 15 | if migration_name 16 | assert_file migration_name do |migration| 17 | assert_match /up do/, migration 18 | assert_match /down do/, migration 19 | end 20 | else 21 | fail "No migration generated for #{name}" 22 | end 23 | end 24 | 25 | test "invoke with name and attributes" do 26 | name = 'account' 27 | run_generator %w{Account name:string} 28 | migration_name = Dir[File.join(Rails.root, "db/migrate/*_#{name}.rb")].first 29 | if migration_name 30 | assert_file migration_name do |migration| 31 | assert_match /up do/, migration 32 | assert_match /down do/, migration 33 | assert_match /modify_table :#{name.tableize}/, migration 34 | end 35 | else 36 | fail "No migration generated for #{name}" 37 | end 38 | end 39 | 40 | end 41 | -------------------------------------------------------------------------------- /lib/generators/mustache/README.md: -------------------------------------------------------------------------------- 1 | ## Rails 3 Generators for Mustache 2 | 3 | [Mustache](http://github.com/defunkt/mustache) support for [Rails 3](http://weblog.rubyonrails.org/2010/6/8/rails-3-0-beta-4-now-rc-in-days) is [still developing](http://github.com/defunkt/mustache/issues/#issue/3). Following the work of others, I have built a provisional template handler that is included with these generators. To install it in your project, `rails g mustache:install` 4 | 5 | I'm assuming that the Mustache template engine that gets the official blessing will expect to find files where Chris W. and others have suggested the files should go, so I have built my generators and provisional template handler accordingly. I.e. the files for widget views go in: 6 | 7 | * app/views/widgets/action.rb for view class definitions 8 | * app/templates/widgets/action.html.mustache for templates 9 | 10 | 11 | ### To Do 12 | 13 | * Enable mustache layout usage (uses default application.erb for now) 14 | * Add controller-retrofit generator to build default mustache views for existing controllers 15 | * Generate different fields for different attribute types 16 | * Helper generation for leaner view files 17 | 18 | ### Thanks 19 | 20 | * Louis T. for running the umbrella Rails 3 Generators project and giving me pointers on writing generators. 21 | * Paul Barry for invaluable help figuring out how Rails template handlers work. 22 | * José Valim, Paul Barry, and Jeremy McAnally for good information. 23 | -------------------------------------------------------------------------------- /lib/generators/mustache/controller/controller_generator.rb: -------------------------------------------------------------------------------- 1 | require 'generators/mustache' 2 | require 'rails/generators/named_base' 3 | 4 | class Mustache 5 | module Generators 6 | class ControllerGenerator < ::Rails::Generators::NamedBase 7 | extend TemplatePath 8 | 9 | argument :actions, :type => :array, :default => [], :banner => "action action" 10 | 11 | def create_view_files 12 | model_path = File.join(class_path, file_name) 13 | 14 | base_mustache_view_path = File.join("app/views", model_path) 15 | empty_directory base_mustache_view_path 16 | 17 | base_mustache_template_path = File.join("app/templates", model_path) 18 | empty_directory base_mustache_template_path 19 | 20 | actions.each do |action| 21 | @action = action 22 | mustache_view_path = File.join(base_mustache_view_path, 23 | "#{action}.rb") 24 | mustache_template_path = File.join(base_mustache_template_path, 25 | "#{action}.html.mustache") 26 | 27 | template "view.rb.erb", mustache_view_path 28 | template "view.html.mustache.erb", mustache_template_path 29 | end 30 | end 31 | 32 | protected 33 | 34 | def handler 35 | :haml 36 | end 37 | end 38 | end 39 | end -------------------------------------------------------------------------------- /test/lib/generators/shoulda/controller_generator_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class Shoulda::Generators::ControllerGeneratorTest < Rails::Generators::TestCase 4 | destination File.join(Rails.root) 5 | tests Rails::Generators::ControllerGenerator 6 | arguments %w(accounts index show new create edit update destroy --test-framework shoulda) 7 | 8 | setup :prepare_destination 9 | setup :copy_routes 10 | 11 | test "should invoke test framework" do 12 | run_generator 13 | assert_file "test/functional/accounts_controller_test.rb" 14 | end 15 | 16 | test "should create test class" do 17 | run_generator 18 | assert_file "test/functional/accounts_controller_test.rb" do |controller_test| 19 | assert_class "AccountsControllerTest", controller_test 20 | end 21 | end 22 | 23 | test "should create controller action tests" do 24 | run_generator 25 | assert_file "test/functional/accounts_controller_test.rb" do |controller_test| 26 | assert_class "AccountsControllerTest", controller_test do |klass| 27 | assert_match /context "index action"/, klass 28 | assert_match /context "show action"/, klass 29 | assert_match /context "new action"/, klass 30 | assert_match /context "create action"/, klass 31 | assert_match /context "edit action"/, klass 32 | assert_match /context "update action"/, klass 33 | assert_match /context "destroy action"/, klass 34 | end 35 | end 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /lib/generators/mustache/scaffold/templates/new.rb.erb: -------------------------------------------------------------------------------- 1 | class <%= plural_name.camelize %>::New < Mustache::Rails 2 | 3 | <%# TODO: extract errors_display settings to to module methods -%> 4 | def errors_display_div 5 | return "" unless <%= singular_name %>.errors.any? 6 | content_tag("div", :id=>"errorExplanation", :class=>"errorExplanation") do 7 | content_tag("h2", error_header) + content_tag("ul") do 8 | <%= singular_name %>.errors.full_messages.inject("") do |memo,msg| 9 | memo += content_tag("li", msg) 10 | end 11 | end 12 | end 13 | end 14 | 15 | def <%= singular_name %>_form_tag 16 | form_tag(create_path, :class => "<%= singular_name %>_form", :id => "edit_<%= singular_name %>_#{<%= singular_name %>.id}_form") 17 | end 18 | 19 | <% for attribute in attributes -%> 20 | def <%= attribute.name %>_label 21 | label :<%= singular_name %>, :<%= attribute.name %> 22 | end 23 | <%# TODO: Different fields for different attribute types -%> 24 | 25 | def <%= attribute.name %>_text_field 26 | text_field(:<%= singular_name %>, :<%= attribute.name %>, :id => "<%= attribute.name %>_text_field") 27 | end 28 | 29 | <% end -%> 30 | 31 | def form_submit 32 | submit_tag "Create" 33 | end 34 | 35 | 36 | def index_path 37 | <%= plural_name %>_path 38 | end 39 | 40 | private 41 | 42 | def create_path 43 | <%= plural_name %>_path 44 | end 45 | 46 | def error_header 47 | "u r dong it rong" 48 | end 49 | 50 | end -------------------------------------------------------------------------------- /lib/generators/data_mapper/model/model_generator.rb: -------------------------------------------------------------------------------- 1 | require 'generators/data_mapper' 2 | 3 | module DataMapper 4 | module Generators 5 | class ModelGenerator < Base 6 | argument :attributes, :type => :array, :default => [], :banner => "field:type field:type" 7 | class_option :id, :type => :numeric, :desc => "The id to be used in the migration" 8 | 9 | check_class_collision 10 | 11 | class_option :migration, :type => :boolean 12 | class_option :timestamps, :type => :boolean 13 | class_option :parent, :type => :string, :desc => "The parent class for the generated model" 14 | 15 | def create_migration_file 16 | if migration? && parent? 17 | file_name = "create_#{file_path.gsub(/\//, '_').pluralize}" 18 | migration_template "migration.rb", "db/migrate/#{file_name}.rb" 19 | end 20 | end 21 | 22 | def create_model_file 23 | template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb") 24 | end 25 | 26 | protected 27 | 28 | def migration? 29 | options[:migration] 30 | end 31 | 32 | def timestamps? 33 | options[:timestamps] 34 | end 35 | 36 | def parent? 37 | options[:parent] 38 | end 39 | 40 | def timestamp_statements 41 | %q{ 42 | property :created_at, DateTime 43 | # property :created_on, Date 44 | 45 | property :updated_at, DateTime 46 | # property :updated_on, Date 47 | } 48 | end 49 | 50 | hook_for :test_framework 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/generators/mustache/scaffold/templates/edit.rb.erb: -------------------------------------------------------------------------------- 1 | class <%= plural_name.camelize %>::Edit < Mustache::Rails 2 | 3 | <%# TODO: extract errors_display settings to to module methods -%> 4 | def errors_display_div 5 | return "" unless <%= singular_name %>.errors.any? 6 | content_tag("div", :id=>"errorExplanation", :class=>"errorExplanation") do 7 | content_tag("h2", error_header) + content_tag("ul") do 8 | <%= singular_name %>.errors.full_messages.inject("") do |memo,msg| 9 | memo += content_tag("li", msg) 10 | end 11 | end 12 | end 13 | end 14 | 15 | def <%= singular_name %>_form_tag 16 | form_tag(update_path, :class => "<%= singular_name %>_form", :method => :put, :id => "edit_<%= singular_name %>_#{<%= singular_name %>.id}_form") 17 | end 18 | 19 | <% for attribute in attributes -%> 20 | def <%= attribute.name %>_label 21 | label :<%= singular_name %>, :<%= attribute.name %> 22 | end 23 | <%# TODO: Different fields for different attribute types -%> 24 | 25 | def <%= attribute.name %>_text_field 26 | text_field(:<%= singular_name %>, :<%= attribute.name %>, :id => "<%= attribute.name %>_text_field") 27 | end 28 | 29 | <% end -%> 30 | 31 | def form_submit 32 | submit_tag "Update" 33 | end 34 | 35 | def show_path 36 | <%= singular_name %>_path(<%= singular_name %>) 37 | end 38 | 39 | def index_path 40 | <%= plural_name %>_path 41 | end 42 | 43 | private 44 | 45 | def update_path 46 | <%= singular_name %>_path(<%= singular_name %>) 47 | end 48 | 49 | def error_header 50 | "u r dong it rong" 51 | end 52 | 53 | end -------------------------------------------------------------------------------- /lib/generators/helpers/migration_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rails/generators/migration' 2 | 3 | module Rails3Generators 4 | module MigrationHelper 5 | include Rails::Generators::Migration 6 | 7 | attr_accessor :migration_number 8 | 9 | module ClassMethods 10 | def migration_lookup_at(dirname) #:nodoc: 11 | Dir.glob("#{dirname}/[0-9]*_*.rb") 12 | end 13 | 14 | def migration_exists?(dirname, file_name) #:nodoc: 15 | migration_lookup_at(dirname).grep(/\d+_#{file_name}.rb$/).first 16 | end 17 | 18 | def current_migration_number(dirname) #:nodoc: 19 | migration_lookup_at(dirname).collect do |file| 20 | File.basename(file).split("_").first.to_i 21 | end.max.to_i 22 | end 23 | 24 | def next_migration_number(dirname) #:nodoc: 25 | orm = Rails.configuration.generators.options[:rails][:orm] 26 | require "rails/generators/#{orm}" 27 | "#{orm.to_s.camelize}::Generators::Base".constantize.next_migration_number(dirname) 28 | rescue 29 | raise NotImplementedError 30 | end 31 | end 32 | 33 | def self.included(base) #:nodoc: 34 | base.extend ClassMethods 35 | end 36 | 37 | 38 | def run_migration(options) 39 | run "rails g migration #{options}" 40 | end 41 | 42 | protected 43 | 44 | def model_exists?(name) 45 | File.exists?(File.join(Rails.root, "app/models/#{name}.rb")) 46 | end 47 | 48 | def model_file(name) 49 | File.join(Rails.root, "app/models/#{name}.rb") 50 | end 51 | end 52 | end 53 | 54 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = rails3-generators 2 | 3 | Rails 3 compatible generators for gems that don't have them yet 4 | 5 | == Install 6 | 7 | gem install rails3-generators 8 | 9 | and add the following to your project's Gemfile 10 | 11 | gem "rails3-generators" 12 | 13 | == Notes/Use 14 | 15 | The Factory Girl generators have moved to {the factory_girl_rails gem}[https://github.com/thoughtbot/factory_girl_rails]. 16 | 17 | The Haml generators have moved to {the haml-rails gem}[http://github.com/indirect/haml-rails]. 18 | 19 | The jQuery generators have moved to {the jquery-rails gem}[http://github.com/indirect/jquery-rails]. 20 | 21 | The MongoMapper generators moved to {the mongo_mapper gem}[https://github.com/jnunemaker/mongomapper]. 22 | 23 | The SimpleForm generators moved to {the simple_form gem}[https://github.com/plataformatec/simple_form]. 24 | 25 | The Formtastic generators moved to {the fortastic gem}[https://github.com/justinfrench/formtastic]. 26 | 27 | The Authlogic generators moved to {the authlogic gem}[https://github.com/binarylogic/authlogic]. 28 | 29 | == Note on Patches/Pull Requests 30 | 31 | * Fork the project. 32 | * Make your feature addition or bug fix. 33 | * Add tests for it. This is important so I don't break it in a 34 | future version unintentionally. 35 | * Commit, do not mess with rakefile, version, or history. 36 | (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) 37 | * Send me a pull request. Bonus points for topic branches. 38 | 39 | == Contributors 40 | 41 | * DataMapper: José Valim 42 | * Shoulda: Peter Haza 43 | 44 | and more[http://github.com/indirect/rails3-generators/contributors] 45 | 46 | == License 47 | 48 | Ruby license or MIT license, take your pick 49 | -------------------------------------------------------------------------------- /test/lib/generators/data_mapper/model_generator_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require_generator :data_mapper => ['model'] 3 | 4 | class DataMapper::Generators::ModelGeneratorTest < Rails::Generators::TestCase 5 | destination File.join(Rails.root) 6 | tests DataMapper::Generators::ModelGenerator 7 | 8 | setup :prepare_destination 9 | setup :copy_routes 10 | 11 | test "invoke with model name" do 12 | content = run_generator %w(Account) 13 | 14 | assert_file "app/models/account.rb" do |account| 15 | assert_class "Account", account do |klass| 16 | assert_match /include DataMapper::Resource/, klass 17 | assert_match /property :id, Serial/, klass 18 | end 19 | end 20 | end 21 | 22 | test "invoke with model name and attributes" do 23 | content = run_generator %w(Account name:string age:integer) 24 | 25 | assert_file "app/models/account.rb" do |account| 26 | assert_class "Account", account do |klass| 27 | assert_match /property :name, String/, klass 28 | assert_match /property :age, Integer/, klass 29 | end 30 | end 31 | end 32 | 33 | test "invoke with model name and --timestamps option" do 34 | content = run_generator %w(Account --timestamps) 35 | 36 | assert_file "app/models/account.rb" do |account| 37 | assert_class "Account", account do |klass| 38 | assert_match /property :created_at, DateTime/, klass 39 | assert_match /property :updated_at, DateTime/, klass 40 | end 41 | end 42 | end 43 | 44 | test "invoke with model name and --parent option" do 45 | content = run_generator %w(Admin --parent User) 46 | assert_file "app/models/admin.rb" do |account| 47 | assert_class "Admin", account do |klass| 48 | assert_no_match /property :id, Serial/, klass 49 | assert_match /<\s+User/, klass 50 | end 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /test/fixtures/routes.rb: -------------------------------------------------------------------------------- 1 | TestApp.routes.draw do |map| 2 | # The priority is based upon order of creation: 3 | # first created -> highest priority. 4 | 5 | # Sample of regular route: 6 | # match 'products/:id' => 'catalog#view' 7 | # Keep in mind you can assign values other than :controller and :action 8 | 9 | # Sample of named route: 10 | # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase 11 | # This route can be invoked with purchase_url(:id => product.id) 12 | 13 | # Sample resource route (maps HTTP verbs to controller actions automatically): 14 | # resources :products 15 | 16 | # Sample resource route with options: 17 | # resources :products do 18 | # member do 19 | # get :short 20 | # post :toggle 21 | # end 22 | # 23 | # collection do 24 | # get :sold 25 | # end 26 | # end 27 | 28 | # Sample resource route with sub-resources: 29 | # resources :products do 30 | # resources :comments, :sales 31 | # resource :seller 32 | # end 33 | 34 | # Sample resource route with more complex sub-resources 35 | # resources :products do 36 | # resources :comments 37 | # resources :sales do 38 | # get :recent, :on => :collection 39 | # end 40 | # end 41 | 42 | # Sample resource route within a namespace: 43 | # namespace :admin do 44 | # # Directs /admin/products/* to Admin::ProductsController 45 | # # (app/controllers/admin/products_controller.rb) 46 | # resources :products 47 | # end 48 | 49 | # You can have the root of your site routed with "root" 50 | # just remember to delete public/index.html. 51 | # root :to => "welcome#index" 52 | 53 | # See how all your routes lay out with "rake routes" 54 | 55 | # This is a legacy wild controller route that's not recommended for RESTful applications. 56 | # Note: This route will make all actions in every controller accessible via GET requests. 57 | # match ':controller(/:action(/:id(.:format)))' 58 | end 59 | -------------------------------------------------------------------------------- /rails3-generators.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | require File.expand_path("../lib/rails3-generators/version", __FILE__) 3 | 4 | Gem::Specification.new do |s| 5 | s.name = "rails3-generators" 6 | s.version = Rails3::Generators::VERSION 7 | s.platform = Gem::Platform::RUBY 8 | s.authors = ["Jose Valim", "Anuj Dutta", "Paul Berry", "Jeff Tucker", "Louis T.", "Jai-Gouk Kim", "Darcy Laycock", "Peter Haza", "Peter Gumeson", "Kristian Mandrup", "Alejandro Juarez"] 9 | s.email = "andre@arko.net" 10 | s.homepage = "https://github.com/indirect/rails3-generators" 11 | s.summary = "Rails 3 compatible generators" 12 | s.description = "Rails 3 compatible generators for gems that don't have them yet" 13 | 14 | s.rubyforge_project = "rails3-generators" 15 | s.required_rubygems_version = ">= 1.3.6" 16 | 17 | s.add_dependency "railties", ">= 3.0.0" 18 | s.add_development_dependency "bundler", ">= 1.0.0" 19 | s.add_development_dependency "rake" 20 | s.add_development_dependency "test-unit" 21 | s.add_development_dependency "rails", ">= 3.0.0" 22 | s.add_development_dependency "factory_girl" 23 | 24 | s.files = `git ls-files`.split("\n") 25 | s.executables = `git ls-files`.split("\n").select{|f| f =~ /^bin/} 26 | s.require_path = "lib" 27 | 28 | s.extra_rdoc_files = ["README.rdoc", "CHANGELOG.rdoc"] 29 | 30 | s.post_install_message = %Q{ 31 | rails3-generators-#{Rails3::Generators::VERSION} 32 | 33 | MongoMapper generators removed. MongoMapper (https://github.com/jnunemaker/mongomapper) has its own generators. 34 | 35 | SimpleForm generators removed. SimpleForm (https://github.com/plataformatec/simple_form) has its own generators. 36 | 37 | Formtastic generators removed. Formtastic (https://github.com/justinfrench/formtastic) has its own generators. 38 | 39 | Authlogic generators removed. Authlogic (https://github.com/binarylogic/authlogic) has its own generators. 40 | 41 | Be sure to check out the wiki, https://wiki.github.com/indirect/rails3-generators/, 42 | for information about recent changes to this project. 43 | } 44 | end 45 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require 'bundler' 2 | Bundler.require 3 | 4 | require 'test/unit' 5 | require 'rails/all' 6 | require 'rails/generators' 7 | require 'rails/generators/test_case' 8 | 9 | class TestApp < Rails::Application 10 | config.root = File.dirname(__FILE__) 11 | end 12 | Rails.application = TestApp 13 | 14 | module Rails 15 | def self.root 16 | @root ||= File.expand_path(File.join(File.dirname(__FILE__), '..', 'tmp', 'rails')) 17 | end 18 | end 19 | Rails.application.config.root = Rails.root 20 | 21 | Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f} 22 | 23 | def copy_routes 24 | routes = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'routes.rb')) 25 | destination = File.join(Rails.root, "config") 26 | FileUtils.mkdir_p(destination) 27 | FileUtils.cp File.expand_path(routes), destination 28 | end 29 | 30 | # Asserts the given class exists in the given content. When a block is given, 31 | # it yields the content of the class. 32 | # 33 | # assert_file "test/functional/accounts_controller_test.rb" do |controller_test| 34 | # assert_class "AccountsControllerTest", controller_test do |klass| 35 | # assert_match /context "index action"/, klass 36 | # end 37 | # end 38 | # 39 | def assert_class(klass, content) 40 | assert content =~ /class #{klass}(\(.+\))?(.*?)\nend/m, "Expected to have class #{klass}" 41 | yield $2.strip if block_given? 42 | end 43 | 44 | def generator_list 45 | { 46 | :rails => ['scaffold', 'controller'], 47 | :koala => ['install'], 48 | :shoulda => ['controller', 'scaffold'] 49 | } 50 | end 51 | 52 | def path_prefix(name) 53 | case name 54 | when :rails 55 | 'rails/generators' 56 | else 57 | 'generators' 58 | end 59 | end 60 | 61 | def require_generators(generator_list) 62 | generator_list.each do |name, generators| 63 | generators.each do |generator_name| 64 | require File.join(path_prefix(name), name.to_s, generator_name.to_s, "#{generator_name}_generator") 65 | end 66 | end 67 | end 68 | alias :require_generator :require_generators 69 | 70 | require_generators generator_list 71 | -------------------------------------------------------------------------------- /lib/generators/shoulda/scaffold/templates/scaffold.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class <%= controller_class_name %>ControllerTest < ActionController::TestCase 4 | 5 | context "index action" do 6 | should "render index template" do 7 | get :index 8 | assert_template 'index' 9 | end 10 | end 11 | 12 | context "show action" do 13 | should "render show template" do 14 | get :show, :id => <%= class_name %>.first 15 | assert_template 'show' 16 | end 17 | end 18 | 19 | context "new action" do 20 | should "render new template" do 21 | get :new 22 | assert_template 'new' 23 | end 24 | end 25 | 26 | context "create action" do 27 | should "render new template when model is invalid" do 28 | <%= class_name %>.any_instance.stubs(:valid?).returns(false) 29 | post :create 30 | assert_template 'new' 31 | end 32 | 33 | should "redirect when model is valid" do 34 | <%= class_name %>.any_instance.stubs(:valid?).returns(true) 35 | post :create 36 | assert_redirected_to 37 | end 38 | end 39 | 40 | context "edit action" do 41 | should "render edit template" do 42 | get :edit, :id => <%= class_name %>.first 43 | assert_template 'edit' 44 | end 45 | end 46 | 47 | context "update action" do 48 | should "render edit template when model is invalid" do 49 | <%= class_name %>.any_instance.stubs(:valid?).returns(false) 50 | put :update, :id => <%= class_name %>.first 51 | assert_template 'edit' 52 | end 53 | 54 | should "redirect when model is valid" do 55 | <%= class_name %>.any_instance.stubs(:valid?).returns(true) 56 | put :update, :id => <%= class_name %>.first 57 | assert_redirected_to 58 | end 59 | end 60 | 61 | context "destroy action" do 62 | should "destroy model and redirect to index action" do 63 | <%= singular_name %> = <%= class_name %>.first 64 | delete :destroy, :id => <%= singular_name %> 65 | assert_redirected_to 66 | assert !<%= class_name %>.exists?(<%= singular_name %>.id) 67 | end 68 | end 69 | 70 | end 71 | -------------------------------------------------------------------------------- /lib/generators/data_mapper.rb: -------------------------------------------------------------------------------- 1 | require 'rails/generators/named_base' 2 | require 'rails/generators/migration' 3 | require 'rails/generators/active_model' 4 | 5 | require 'generators/helpers/migration_helper' 6 | 7 | module DataMapper 8 | module Generators 9 | class Base < Rails::Generators::NamedBase #:nodoc: 10 | include Rails3Generators::MigrationHelper 11 | # include Rails::Generators::Migration 12 | 13 | def self.source_root 14 | @_datamapper_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 15 | 'data_mapper', generator_name, 'templates')) 16 | end 17 | 18 | protected 19 | 20 | # Datamapper does not care if migrations have the same name as long as 21 | # they have different ids. 22 | # 23 | def migration_exists?(dirname, file_name) #:nodoc: 24 | false 25 | end 26 | 27 | # Implement the required interface for Rails::Generators::Migration. 28 | # 29 | def next_migration_number(dirname) #:nodoc: 30 | if options[:id] 31 | "%.3d" % options[:id] 32 | else 33 | "%.3d" % (current_migration_number(dirname) + 1) 34 | end 35 | end 36 | end 37 | 38 | class ActiveModel < Rails::Generators::ActiveModel #:nodoc: 39 | def self.all(klass) 40 | "#{klass}.all" 41 | end 42 | 43 | def self.find(klass, params=nil) 44 | "#{klass}.get(#{params})" 45 | end 46 | 47 | def self.build(klass, params=nil) 48 | if params 49 | "#{klass}.new(#{params})" 50 | else 51 | "#{klass}.new" 52 | end 53 | end 54 | 55 | def save 56 | "#{name}.save" 57 | end 58 | 59 | def update_attributes(params=nil) 60 | "#{name}.update(#{params})" 61 | end 62 | 63 | def errors 64 | "#{name}.errors" 65 | end 66 | 67 | def destroy 68 | "#{name}.destroy" 69 | end 70 | end 71 | end 72 | end 73 | 74 | module Rails 75 | module Generators 76 | class GeneratedAttribute #:nodoc: 77 | def type_class 78 | return 'DateTime' if type.to_s == 'datetime' 79 | return type.to_s.camelcase 80 | end 81 | end 82 | end 83 | end 84 | -------------------------------------------------------------------------------- /lib/generators/shoulda/controller/templates/controller.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class <%= class_name %>ControllerTest < ActionController::TestCase 4 | <% if actions.include?('index') -%> 5 | 6 | context "index action" do 7 | should "render index template" do 8 | get :index 9 | assert_template 'index' 10 | end 11 | end 12 | <% end -%> 13 | <% if actions.include?('show') -%> 14 | 15 | context "show action" do 16 | should "render show template" do 17 | get :show, :id => <%= class_name %>.first 18 | assert_template 'show' 19 | end 20 | end 21 | <% end -%> 22 | <% if actions.include?('new') -%> 23 | 24 | context "new action" do 25 | should "render new template" do 26 | get :new 27 | assert_template 'new' 28 | end 29 | end 30 | <% end -%> 31 | <% if actions.include?('create') -%> 32 | 33 | context "create action" do 34 | should "render new template when model is invalid" do 35 | <%= class_name %>.any_instance.stubs(:valid?).returns(false) 36 | post :create 37 | assert_template 'new' 38 | end 39 | 40 | should "redirect when model is valid" do 41 | <%= class_name %>.any_instance.stubs(:valid?).returns(true) 42 | post :create 43 | assert_redirected_to 44 | end 45 | end 46 | <% end -%> 47 | <% if actions.include?('edit') -%> 48 | 49 | context "edit action" do 50 | should "render edit template" do 51 | get :edit, :id => <%= class_name %>.first 52 | assert_template 'edit' 53 | end 54 | end 55 | <% end -%> 56 | <% if actions.include?('update') -%> 57 | 58 | context "update action" do 59 | should "render edit template when model is invalid" do 60 | <%= class_name %>.any_instance.stubs(:valid?).returns(false) 61 | put :update, :id => <%= class_name %>.first 62 | assert_template 'edit' 63 | end 64 | 65 | should "redirect when model is valid" do 66 | <%= class_name %>.any_instance.stubs(:valid?).returns(true) 67 | put :update, :id => <%= class_name %>.first 68 | assert_redirected_to 69 | end 70 | end 71 | <% end -%> 72 | <% if actions.include?('destroy') -%> 73 | 74 | context "destroy action" do 75 | should "destroy model and redirect to index action" do 76 | <%= singular_name %> = <%= class_name %>.first 77 | delete :destroy, :id => <%= singular_name %> 78 | assert_redirected_to 79 | assert !<%= class_name %>.exists?(<%= singular_name %>.id) 80 | end 81 | end 82 | <% end -%> 83 | 84 | end 85 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | rails3-generators (1.0.0) 5 | railties (>= 3.0.0) 6 | 7 | GEM 8 | remote: https://rubygems.org/ 9 | specs: 10 | actionmailer (3.2.8) 11 | actionpack (= 3.2.8) 12 | mail (~> 2.4.4) 13 | actionpack (3.2.8) 14 | activemodel (= 3.2.8) 15 | activesupport (= 3.2.8) 16 | builder (~> 3.0.0) 17 | erubis (~> 2.7.0) 18 | journey (~> 1.0.4) 19 | rack (~> 1.4.0) 20 | rack-cache (~> 1.2) 21 | rack-test (~> 0.6.1) 22 | sprockets (~> 2.1.3) 23 | activemodel (3.2.8) 24 | activesupport (= 3.2.8) 25 | builder (~> 3.0.0) 26 | activerecord (3.2.8) 27 | activemodel (= 3.2.8) 28 | activesupport (= 3.2.8) 29 | arel (~> 3.0.2) 30 | tzinfo (~> 0.3.29) 31 | activeresource (3.2.8) 32 | activemodel (= 3.2.8) 33 | activesupport (= 3.2.8) 34 | activesupport (3.2.8) 35 | i18n (~> 0.6) 36 | multi_json (~> 1.0) 37 | arel (3.0.2) 38 | builder (3.0.3) 39 | erubis (2.7.0) 40 | factory_girl (4.1.0) 41 | activesupport (>= 3.0.0) 42 | hike (1.2.1) 43 | i18n (0.6.1) 44 | journey (1.0.4) 45 | json (1.7.5) 46 | mail (2.4.4) 47 | i18n (>= 0.4.0) 48 | mime-types (~> 1.16) 49 | treetop (~> 1.4.8) 50 | mime-types (1.19) 51 | multi_json (1.3.6) 52 | polyglot (0.3.3) 53 | rack (1.4.1) 54 | rack-cache (1.2) 55 | rack (>= 0.4) 56 | rack-ssl (1.3.2) 57 | rack 58 | rack-test (0.6.2) 59 | rack (>= 1.0) 60 | rails (3.2.8) 61 | actionmailer (= 3.2.8) 62 | actionpack (= 3.2.8) 63 | activerecord (= 3.2.8) 64 | activeresource (= 3.2.8) 65 | activesupport (= 3.2.8) 66 | bundler (~> 1.0) 67 | railties (= 3.2.8) 68 | railties (3.2.8) 69 | actionpack (= 3.2.8) 70 | activesupport (= 3.2.8) 71 | rack-ssl (~> 1.3.2) 72 | rake (>= 0.8.7) 73 | rdoc (~> 3.4) 74 | thor (>= 0.14.6, < 2.0) 75 | rake (0.9.2.2) 76 | rdoc (3.12) 77 | json (~> 1.4) 78 | sprockets (2.1.3) 79 | hike (~> 1.2) 80 | rack (~> 1.0) 81 | tilt (~> 1.1, != 1.3.0) 82 | test-unit (2.5.2) 83 | thor (0.16.0) 84 | tilt (1.3.3) 85 | treetop (1.4.10) 86 | polyglot 87 | polyglot (>= 0.3.1) 88 | tzinfo (0.3.33) 89 | 90 | PLATFORMS 91 | ruby 92 | 93 | DEPENDENCIES 94 | bundler (>= 1.0.0) 95 | factory_girl 96 | rails (>= 3.0.0) 97 | rails3-generators! 98 | rake 99 | test-unit 100 | -------------------------------------------------------------------------------- /lib/generators/mustache/install/templates/lib/mustache_rails.rb: -------------------------------------------------------------------------------- 1 | require 'mustache' 2 | 3 | class Mustache 4 | 5 | # Remember to use {{{yield}}} (3 mustaches) to skip escaping HTML 6 | # Using {{{tag}}} will skip escaping HTML so if your mustache methods return 7 | # HTML, be sure to interpolate them using 3 mustaches. 8 | 9 | class Rails < Mustache 10 | attr_accessor :view 11 | 12 | def method_missing(method, *args, &block) 13 | view.send(method, *args, &block) 14 | end 15 | 16 | def respond_to?(method, include_private=false) 17 | super(method, include_private) || view.respond_to?(method, include_private) 18 | end 19 | 20 | # Redefine where Mustache::Rails templates locate their partials: 21 | # 22 | # (1) in the same directory as the current template file. 23 | # (2) in the shared templates path (can be configured via Config.shared_path=(value)) 24 | # 25 | def partial(name) 26 | partial_name = "_#{name}.#{Config.template_extension}" 27 | template_dir = Pathname.new(self.class.template_file).dirname 28 | partial_path = File.expand_path("#{template_dir}/#{partial_name}") 29 | unless File.file?(partial_path) 30 | partial_path = "#{Config.shared_path}/#{partial_name}" 31 | end 32 | File.read(partial_path) 33 | end 34 | 35 | # You can change these defaults in, say, a Rails initializer or 36 | # environment.rb, e.g.: 37 | # 38 | # Mustache::Rails::Config.template_base_path = Rails.root.join('app', 'templates') 39 | module Config 40 | def self.template_base_path 41 | @template_base_path ||= ::Rails.root.join('app', 'templates') 42 | end 43 | 44 | def self.template_base_path=(value) 45 | @template_base_path = value 46 | end 47 | 48 | def self.template_extension 49 | @template_extension ||= 'html.mustache' 50 | end 51 | 52 | def self.template_extension=(value) 53 | @template_extension = value 54 | end 55 | 56 | def self.shared_path 57 | @shared_path ||= ::Rails.root.join('app', 'templates', 'shared') 58 | end 59 | 60 | def self.shared_path=(value) 61 | @shared_path = value 62 | end 63 | end 64 | 65 | class TemplateHandler < ActionView::Template::Handler 66 | 67 | include ActionView::Template::Handlers::Compilable 68 | 69 | self.default_format = :mustache 70 | 71 | # @return [String] its evaled in the context of the action view 72 | # hence the hack below 73 | # 74 | # @param [ActionView::Template] 75 | def compile(template) 76 | mustache_class = mustache_class_from_template(template) 77 | mustache_class.template_file = mustache_template_file(template) 78 | 79 | <<-MUSTACHE 80 | mustache = ::#{mustache_class}.new 81 | mustache.view = self 82 | mustache[:yield] = content_for(:layout) 83 | mustache.context.update(local_assigns) 84 | variables = controller.instance_variable_names 85 | variables -= %w[@template] 86 | 87 | if controller.respond_to?(:protected_instance_variables) 88 | variables -= controller.protected_instance_variables 89 | end 90 | 91 | variables.each do |name| 92 | mustache.instance_variable_set(name, controller.instance_variable_get(name)) 93 | end 94 | 95 | # Declaring an +attr_reader+ for each instance variable in the 96 | # Mustache::Rails subclass makes them available to your templates. 97 | mustache.class.class_eval do 98 | attr_reader *variables.map { |name| name.sub(/^@/, '').to_sym } 99 | end 100 | 101 | mustache.render 102 | MUSTACHE 103 | end 104 | 105 | private 106 | 107 | def mustache_class_from_template(template) 108 | const_name = ActiveSupport::Inflector.camelize(template.virtual_path.to_s) 109 | defined?(const_name) ? const_name.constantize : Mustache 110 | end 111 | 112 | def mustache_template_file(template) 113 | "#{Config.template_base_path}/#{template.virtual_path}.#{Config.template_extension}" 114 | end 115 | 116 | end 117 | end 118 | end 119 | 120 | ::ActiveSupport::Dependencies.autoload_paths += [Rails.root.join('app', 'views')] 121 | ::ActionView::Template.register_template_handler(:rb, Mustache::Rails::TemplateHandler) 122 | -------------------------------------------------------------------------------- /CHANGELOG.rdoc: -------------------------------------------------------------------------------- 1 | == TODO 2 | * Write some documentation. (In both the github wiki and the source code) 3 | 4 | == 1.0.0 5 | * optimize 6 | * MongoMapper generators removed. MongoMapper (https://github.com/jnunemaker/mongomapper) has its own generators. 7 | * SimpleForm generators removed. SimpleForm (https://github.com/plataformatec/simple_form) has its own generators. 8 | * Erubis generator removed. 9 | * Formtastic generators removed. Formtastic (https://github.com/justinfrench/formtastic) has its own generators. 10 | * Authlogic generators removed. Authlogic (https://github.com/binarylogic/authlogic) has its own generators. 11 | 12 | == 0.17.5 13 | * optimize 14 | * Remove FactoryGirl 15 | 16 | == 0.17.4 17 | * optimize 18 | * Allow use of both FactoryGirl 1 and 2. (Louis T.) 19 | 20 | == 0.17.3 21 | * optimize 22 | * Update FactoryGirl generator to use version 2.0.0 syntax (Kevin Faustino) 23 | 24 | == 0.17.2 25 | * optimize 26 | * Documentation on how to use a generator{factory_girl} (John Joseph Bachir) 27 | 28 | == 0.17.1 29 | * fixed 30 | * MongoMapper provides find(id), not first(id). 31 | See http://stackoverflow.com/questions/4646745 (Semyon Perepelitsa) 32 | 33 | == 0.17.0 34 | * enhancements 35 | * Added a generator for creating models with no persistent. 36 | They still include ActiveModel::Validations and ActiveModel::Serialization. 37 | 38 | When generating properties you can use the following as types to create the required accessor 39 | 40 | read - generate read_accessor 41 | write - generate write_accessor 42 | all - generate attr_accessor 43 | 44 | (Colin Gemmel) 45 | 46 | == 0.16.0 47 | * optimize 48 | * Machinist generators removed. Machinist 2 (https://github.com/notahat/machinist) has its own generators. 49 | * Fabrication generators removed. Fabrication (https://github.com/paulelliott/fabrication) has its own generators. 50 | * Mongoid generators removed. Mongoid (https://github.com/mongoid/mongoid) has its own generators. 51 | 52 | == 0.15.0 53 | * optimize 54 | * Use bundler, remove Jeweler. 55 | 56 | * fix 57 | * update test. (remove references to libs that were previously removed) 58 | 59 | == 0.14.0 60 | * enhancements 61 | * added Fabricator 62 | 63 | == 0.13.0 64 | * optimize 65 | * The Haml generators have moved to {the haml-rails gem}[http://github.com/indirect/haml-rails]. 66 | * The jQuery generators have moved to {the jquery-rails gem}[http://github.com/indirect/jquery-rails]. 67 | 68 | == 0.12.1 69 | * optimize 70 | * changed jqueryui option to --ui 71 | 72 | == 0.12.0 73 | * enhancements 74 | * added jqueryui (ProGNOMmers [Maurizio]) 75 | 76 | == 0.11.0 77 | * enhancements 78 | * Added new mongo_mapper generator for mongo mapper 0.8 with lots of extra features [Kristian Mandrup] 79 | * Added mongoid generator for mongoid 2.0.beta with features similar to new mongo_mapper [Kristian Mandrup] 80 | 81 | * optimize 82 | * renamed datamapper to data_mapper 83 | * renamed mongomapper to mongo_mapper. 84 | 85 | * fix 86 | * added DataMapper Tests 87 | * added MongoMapper Tests 88 | 89 | == 0.10.4 90 | * optimize 91 | * Update jquery install by removing unneeded initializer file 92 | * Update mustache_rails to user autoload_paths instead of load_paths 93 | 94 | == 0.10.3 95 | * optimize 96 | * add --extension option to machinist blueprints. (I like using ".blueprint". --Louis T.) 97 | 98 | == 0.10.1 99 | * optimize 100 | * move mustache generators to correct hidden_namespaces location. (mustache:install was being hidden) 101 | 102 | == 0.10.0 103 | * enhancements 104 | * added mustache:install 105 | * added mustache:controller 106 | * added mustache:scaffold 107 | 108 | * fix 109 | * fixed shoulda controller CamelCase problem. 110 | 111 | == 0.9.2 112 | * enhancements 113 | * added koala:install 114 | 115 | == 0.9.1 116 | * enhancements 117 | * added jquery:install 118 | 119 | * optimize 120 | * simplified haml:install generator. 121 | 122 | == 0.9.0 123 | 124 | * optimize 125 | * simplified and clean up generators. 126 | * Added erubis template engine generator to avoid fighting with rails' built-in erb template engine 127 | * included Generators 128 | * authlogic:session 129 | 130 | * datamapper:migration 131 | * datamapper:model 132 | * datamapper:observer 133 | 134 | * erubis:controller 135 | * erubis:scaffold 136 | 137 | * fabrication:model 138 | * factory_girl:model 139 | 140 | * formtastic:scaffold 141 | 142 | * haml:controller 143 | * haml:install 144 | * haml:scaffold 145 | 146 | * machinist:model 147 | 148 | * mongomapper:model 149 | * mongomapper:observer 150 | 151 | * shoulda:controller 152 | * shoulda:model 153 | 154 | * simple_form:scaffold 155 | -------------------------------------------------------------------------------- /test/lib/generators/mustache/scaffold_generator_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'lib/generators/mustache/testing_helper' 3 | 4 | class Mustache::Generators::ScaffoldGeneratorTest < Rails::Generators::TestCase 5 | destination File.join(Rails.root) 6 | tests Rails::Generators::ScaffoldGenerator 7 | arguments %w(product_line title:string price:integer --template-engine mustache) 8 | 9 | setup :prepare_destination 10 | setup :copy_routes 11 | 12 | test "should generate mustache views for each action" do 13 | run_generator 14 | %w(index edit new show).each { |view| assert_file "app/views/product_lines/#{view}.rb" } 15 | end 16 | 17 | test "should generate a form partial mustache template" do 18 | run_generator 19 | assert_file "app/templates/product_lines/_form.html.mustache" 20 | end 21 | 22 | test "should generate mustache templates for each action" do 23 | run_generator 24 | %w(index edit new show).each { |view| assert_file "app/templates/product_lines/#{view}.html.mustache" } 25 | end 26 | 27 | ### SHOW 28 | 29 | test "should place methods for each attribute in the show view" do 30 | run_generator 31 | assert_file "app/views/product_lines/show.rb", 32 | %r(def title) 33 | assert_file "app/views/product_lines/show.rb", 34 | %r(def price) 35 | end 36 | 37 | test "should place methods for edit path and index path in the show view" do 38 | run_generator 39 | assert_file "app/views/product_lines/show.rb", 40 | %r(def edit_path) 41 | assert_file "app/views/product_lines/show.rb", 42 | %r(def index_path) 43 | end 44 | 45 | test "should place attribute tags in the mustache template for show action" do 46 | run_generator 47 | assert_file "app/templates/product_lines/show.html.mustache", 48 | %r(\{\{title\}\}) 49 | assert_file "app/templates/product_lines/show.html.mustache", 50 | %r(\{\{price\}\}) 51 | end 52 | 53 | test "should place tags for edit path and index path in the mustache template for show action" do 54 | run_generator 55 | assert_file "app/templates/product_lines/show.html.mustache", 56 | %r(\{\{edit_path\}\}) 57 | assert_file "app/templates/product_lines/show.html.mustache", 58 | %r(\{\{index_path\}\}) 59 | end 60 | 61 | ### INDEX 62 | 63 | test "should place methods for listing each item in the index view" do 64 | run_generator 65 | assert_file "app/views/product_lines/index.rb", 66 | %r(def listing) 67 | end 68 | 69 | test "should place methods for new path in the index view" do 70 | run_generator 71 | assert_file "app/views/product_lines/index.rb", 72 | %r(def new_path) 73 | end 74 | 75 | test "should place 'listing' loop tags in the mustache template for index action" do 76 | run_generator 77 | assert_file "app/templates/product_lines/index.html.mustache", 78 | %r(\{\{#listing\}\}) 79 | assert_file "app/templates/product_lines/index.html.mustache", 80 | %r(\{\{/listing\}\}) 81 | end 82 | 83 | test "should place a tag for each attribute in the mustache template for index action" do 84 | run_generator 85 | assert_file "app/templates/product_lines/index.html.mustache", 86 | %r(\{\{title\}\}) 87 | assert_file "app/templates/product_lines/index.html.mustache", 88 | %r(\{\{price\}\}) 89 | end 90 | 91 | test "should place a tag for the item's show link the mustache template for index action" do 92 | run_generator 93 | assert_file "app/templates/product_lines/index.html.mustache", 94 | %r(\{\{show_path\}\}) 95 | end 96 | 97 | test "should place a tag for a new index link the mustache template for index action" do 98 | run_generator 99 | assert_file "app/templates/product_lines/index.html.mustache", 100 | %r(\{\{new_path\}\}) 101 | end 102 | 103 | 104 | ### FORM partial 105 | 106 | test "should place attribute tags in the mustache template for form partial" do 107 | run_generator 108 | assert_file "app/templates/product_lines/_form.html.mustache", 109 | %r(\{\{title_label\}\}) 110 | assert_file "app/templates/product_lines/_form.html.mustache", 111 | %r(\{\{title_text_field\}\}) 112 | assert_file "app/templates/product_lines/_form.html.mustache", 113 | %r(\{\{price_text_field\}\}) 114 | assert_file "app/templates/product_lines/_form.html.mustache", 115 | %r(\{\{price_label\}\}) 116 | end 117 | 118 | 119 | ### NEW 120 | 121 | test "should place a method that returns a form tag to create item" do 122 | run_generator 123 | assert_file "app/views/product_lines/new.rb", 124 | %r(def product_line_form_tag\s*form_tag\(create_path,) 125 | end 126 | 127 | test "should place label and form input methods for each item attribute in the new view" do 128 | run_generator 129 | assert_file "app/views/product_lines/new.rb", 130 | %r(def title_label) 131 | assert_file "app/views/product_lines/new.rb", 132 | %r(def title_text_field) 133 | assert_file "app/views/product_lines/new.rb", 134 | %r(def price_label) 135 | assert_file "app/views/product_lines/new.rb", 136 | %r(def price_text_field) 137 | end 138 | 139 | test "should place methods for create path and index path in the new view" do 140 | run_generator 141 | assert_file "app/views/product_lines/new.rb", 142 | %r(def index_path) 143 | assert_file "app/views/product_lines/new.rb", 144 | %r(def create_path) 145 | end 146 | 147 | 148 | test "should place a new form tag in the mustache template for new action" do 149 | run_generator 150 | assert_file "app/templates/product_lines/new.html.mustache", 151 | %r(\{\{product_line_form_tag\}\}) 152 | end 153 | 154 | test "should place tags for index path in the mustache template for new action" do 155 | run_generator 156 | assert_file "app/templates/product_lines/new.html.mustache", 157 | %r(\{\{index_path\}\}) 158 | end 159 | 160 | 161 | ### EDIT 162 | 163 | test "should place a method that returns a form tag to update item in the edit view" do 164 | run_generator 165 | assert_file "app/views/product_lines/edit.rb", 166 | %r(def product_line_form_tag\s*form_tag\(update_path,) 167 | end 168 | 169 | test "should place label and form input methods for each item attribute in the edit view" do 170 | run_generator 171 | assert_file "app/views/product_lines/edit.rb", 172 | %r(def title_label) 173 | assert_file "app/views/product_lines/edit.rb", 174 | %r(def title_text_field) 175 | assert_file "app/views/product_lines/edit.rb", 176 | %r(def price_label) 177 | assert_file "app/views/product_lines/edit.rb", 178 | %r(def price_text_field) 179 | end 180 | 181 | test "should place methods for update path and show path in the edit view" do 182 | run_generator 183 | assert_file "app/views/product_lines/edit.rb", 184 | %r(def show_path) 185 | assert_file "app/views/product_lines/edit.rb", 186 | %r(def update_path) 187 | end 188 | 189 | 190 | test "should place a form tag in the mustache template for edit action" do 191 | run_generator 192 | assert_file "app/templates/product_lines/edit.html.mustache", 193 | %r(\{\{product_line_form_tag\}\}) 194 | end 195 | 196 | test "should place tags for show path in the mustache template for edit action" do 197 | run_generator 198 | assert_file "app/templates/product_lines/edit.html.mustache", 199 | %r(\{\{show_path\}\}) 200 | end 201 | 202 | end 203 | 204 | --------------------------------------------------------------------------------