require File.dirname(__FILE__) + '/../default_values' # Author: Kristian Mandrup # email: kmandrup@gmail.com require 'generators/rspec_rails3_gen_base' # ================== # TODO: Make hooks for other generators work!!! # see 'hook_for' # ================== module Rspec module Generators class ScaffoldGenerator < NamedBase class_option :default_file_extension, :type => :string, :aliases => "-fe", :default => 'html.erb', :desc => "Default file extension for views" class_option :skip_fixture, :type => :boolean, :aliases => "-F", :default => false, :desc => "Skip Fixture creation" class_option :skip_migration, :type => :boolean, :aliases => "-M", :default => false, :desc => "Skip Migration creation" no_tasks do attr_accessor :model_name attr_accessor :model_attributes attr_accessor :controller_actions alias :attributes :model_attributes alias :attributes= :model_attributes= end argument :model_name, :type => :string, :required => true, :banner => 'ModelName' argument :args_for_c_m, :type => :array, :default => [], :banner => 'controller_actions and model:attributes' def initialize(*args, &block) super @my_options ||= {} @controller_actions = [] @model_attributes = [] args_for_c_m.each do |arg| if arg == '!' @my_options[:invert] = true elsif arg.include?(':') @model_attributes << Rails::Generators::GeneratedAttribute.new(*arg.split(':')) else @controller_actions << arg @controller_actions << 'create' if arg == 'new' @controller_actions << 'update' if arg == 'edit' end end @controller_actions.uniq! @model_attributes.uniq! if options.do_invert? || @controller_actions.empty? @controller_actions = all_actions - @controller_actions end if @model_attributes.empty? @my_options[:skip_model] = true # default to skipping model if no attributes passed if model_exists? model_columns_for_attributes.each do |column| @model_attributes << Rails::Generators::GeneratedAttribute.new(column.name.to_s, column.type.to_s) end else @model_attributes << Rails::Generators::GeneratedAttribute.new('name', 'string') end end end def create_files # Controller, helper, views, and spec directories. # empty_directory 'spec/controllers' # empty_directory 'spec/routing' # empty_directory 'spec/models' # empty_directory 'spec/helpers' # empty_directory 'spec/fixtures' # empty_directory 'spec/views' # empty_directory 'spec/integration' # Controller spec, class, and helper. # template 'controller_spec.rb', # File.join('spec/controllers', controller_class_path, "#{controller_file_name}_controller_spec.rb") # # # template 'helper_spec.erb', # File.join('spec/helpers', class_path, "#{controller_file_name}_helper_spec.rb") # # # View specs # template "edit_erb_spec.rb", # File.join('spec/views', controller_class_path, controller_file_name, "edit.#{default_file_extension}_spec.rb") # template "index_erb_spec.rb", # File.join('spec/views', controller_class_path, controller_file_name, "index.#{default_file_extension}_spec.rb") # template "new_erb_spec.rb", # File.join('spec/views', controller_class_path, controller_file_name, "new.#{default_file_extension}_spec.rb") # template "show_erb_spec.rb", # File.join('spec/views', controller_class_path, controller_file_name, "show.#{default_file_extension}_spec.rb") no_fixture = options[:skip_fixture] ? '--skip-fixture' : '' skip_migration = options[:skip_migration] ? '--skip-migration' : '' flags = [no_fixture, skip_migration].join(' ') actions_str = controller_actions.join(' ') generate "rspec:controller #{controller_file_name} #{actions_str}" attribs = model_attributes.map{|a| a.to_s}.join(' ') generate "rspec:model #{controller_file_name} #{attribs} #{flags}" empty_directory 'spec/routing' template 'routing_spec.rb', File.join('spec/routing', controller_class_path, "#{controller_file_name}_routing_spec.rb") end # tries to find generator within rspec first, then in rails # use :in, fx :in => :rails to be more specific! # TODO: Make hooks work!!! # hook_for :integration_spec # hook_for :model # hook_for :migration # hook_for :scaffold # hook_for :layout no_tasks do def default_file_extension options[:default_file_extension] end def controller_class_name "#{class_name}Controller" end def controller_class_path class_path || "controller/#{name}" end def controller_file_name name end def model_exists? File.exist? destination_path("app/models/#{singular_name}.rb") end def destination_path(path) File.join(destination_root, path) end def scaffold_views %w[ index show new edit ] end def actions @controller_actions end def all_actions %w[index show new create edit update destroy] end def action?(name) controller_actions.include? name.to_s end def actions?(*names) names.all? { |name| action? name } end def singular_name model_name.underscore end def plural_name model_name.underscore.pluralize end def class_name model_name.camelize end def plural_class_name plural_name.camelize end end end end end # What is this for??? module Rails module Generators class GeneratedAttribute def input_type @input_type ||= map_to_input_type end protected def map_to_input_type case type when :text "textarea" else "input" end end end end end