Updated Rails to 2.1.0
[gitorious:georgyos-clone.git] / vendor / plugins / rspec_on_rails / generators / rspec_scaffold / rspec_scaffold_generator.rb
1 class RspecScaffoldGenerator < Rails::Generator::NamedBase
2   default_options :skip_migration => false
3   
4   attr_reader   :controller_name,
5                 :controller_class_path,
6                 :controller_file_path,
7                 :controller_class_nesting,
8                 :controller_class_nesting_depth,
9                 :controller_class_name,
10                 :controller_singular_name,
11                 :controller_plural_name,
12                 :resource_edit_path,
13                 :default_file_extension
14   alias_method  :controller_file_name,  :controller_singular_name
15   alias_method  :controller_table_name, :controller_plural_name
16
17   def initialize(runtime_args, runtime_options = {})
18     super
19
20     @controller_name = @name.pluralize
21
22     base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
23     @controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
24
25     if @controller_class_nesting.empty?
26       @controller_class_name = @controller_class_name_without_nesting
27     else
28       @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
29     end
30     
31     if Rails::VERSION::STRING < "2.0.0"
32       @resource_generator = "scaffold_resource"
33       @default_file_extension = "rhtml"
34                 else
35       @resource_generator = "scaffold"
36       @default_file_extension = "html.erb"
37     end
38     
39     if ActionController::Base.respond_to?(:resource_action_separator)
40       @resource_edit_path = "/edit"
41     else
42       @resource_edit_path = ";edit"
43     end
44   end
45
46   def manifest
47     record do |m|
48       
49       # Check for class naming collisions.
50       m.class_collisions(controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper")
51       m.class_collisions(class_path, "#{class_name}")
52
53       # Controller, helper, views, and spec directories.
54       m.directory(File.join('app/models', class_path))
55       m.directory(File.join('app/controllers', controller_class_path))
56       m.directory(File.join('app/helpers', controller_class_path))
57       m.directory(File.join('app/views', controller_class_path, controller_file_name))
58       m.directory(File.join('spec/controllers', controller_class_path))
59       m.directory(File.join('spec/models', class_path))
60       m.directory(File.join('spec/helpers', class_path))
61       m.directory File.join('spec/fixtures', class_path)
62       m.directory File.join('spec/views', controller_class_path, controller_file_name)
63       
64       # Controller spec, class, and helper.
65       m.template 'rspec_scaffold:routing_spec.rb',
66         File.join('spec/controllers', controller_class_path, "#{controller_file_name}_routing_spec.rb")
67
68       m.template 'rspec_scaffold:controller_spec.rb',
69         File.join('spec/controllers', controller_class_path, "#{controller_file_name}_controller_spec.rb")
70
71       m.template "#{@resource_generator}:controller.rb",
72         File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
73
74       m.template 'rspec_scaffold:helper_spec.rb',
75         File.join('spec/helpers', class_path, "#{controller_file_name}_helper_spec.rb")
76
77       m.template "#{@resource_generator}:helper.rb",
78         File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb")
79
80       for action in scaffold_views
81         m.template(
82           "#{@resource_generator}:view_#{action}.#{@default_file_extension}",
83           File.join('app/views', controller_class_path, controller_file_name, "#{action}.#{default_file_extension}")
84         )
85       end
86       
87       # Model class, unit test, and fixtures.
88       m.template 'model:model.rb',      File.join('app/models', class_path, "#{file_name}.rb")
89       m.template 'model:fixtures.yml',  File.join('spec/fixtures', class_path, "#{table_name}.yml")
90       m.template 'rspec_model:model_spec.rb',       File.join('spec/models', class_path, "#{file_name}_spec.rb")
91
92       # View specs
93       m.template "rspec_scaffold:edit_erb_spec.rb",
94         File.join('spec/views', controller_class_path, controller_file_name, "edit.#{default_file_extension}_spec.rb")
95       m.template "rspec_scaffold:index_erb_spec.rb",
96         File.join('spec/views', controller_class_path, controller_file_name, "index.#{default_file_extension}_spec.rb")
97       m.template "rspec_scaffold:new_erb_spec.rb",
98         File.join('spec/views', controller_class_path, controller_file_name, "new.#{default_file_extension}_spec.rb")
99       m.template "rspec_scaffold:show_erb_spec.rb",
100         File.join('spec/views', controller_class_path, controller_file_name, "show.#{default_file_extension}_spec.rb")
101
102       unless options[:skip_migration]
103         m.migration_template(
104           'model:migration.rb', 'db/migrate', 
105           :assigns => {
106             :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}",
107             :attributes     => attributes
108           }, 
109           :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
110         )
111       end
112
113       m.route_resources controller_file_name
114
115     end
116   end
117
118   protected
119     # Override with your own usage banner.
120     def banner
121       "Usage: #{$0} rspec_scaffold ModelName [field:type field:type]"
122     end
123
124     def add_options!(opt)
125       opt.separator ''
126       opt.separator 'Options:'
127       opt.on("--skip-migration", 
128              "Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
129     end
130
131     def scaffold_views
132       %w[ index show new edit ]
133     end
134
135     def model_name 
136       class_name.demodulize
137     end
138 end
139
140 module Rails
141   module Generator
142     class GeneratedAttribute
143       def default_value
144         @default_value ||= case type
145           when :int, :integer               then "\"1\""
146           when :float                       then "\"1.5\""
147           when :decimal                     then "\"9.99\""
148           when :datetime, :timestamp, :time then "Time.now"
149           when :date                        then "Date.today"
150           when :string                      then "\"MyString\""
151           when :text                        then "\"MyText\""
152           when :boolean                     then "false"
153           else
154             ""
155         end      
156       end
157
158       def input_type
159         @input_type ||= case type
160           when :text                        then "textarea"
161           else
162             "input"
163         end      
164       end
165     end
166   end
167 end