lib/generators/rspec/scaffold/scaffold_generator.rb
require 'generators/rspec'
require 'rails/generators/resource_helpers'
module Rspec
module Generators
# @private
class ScaffoldGenerator < Base
include ::Rails::Generators::ResourceHelpers
source_paths << File.expand_path('../helper/templates', __dir__)
argument :attributes, type: :array, default: [], banner: "field:type field:type"
class_option :orm, desc: "ORM used to generate the controller"
class_option :template_engine, desc: "Template engine to generate view files"
class_option :singleton, type: :boolean, desc: "Supply to create a singleton controller"
class_option :api, type: :boolean, desc: "Skip specs unnecessary for API-only apps"
class_option :controller_specs, type: :boolean, default: false, desc: "Generate controller specs"
class_option :request_specs, type: :boolean, default: true, desc: "Generate request specs"
class_option :view_specs, type: :boolean, default: true, desc: "Generate view specs"
class_option :helper_specs, type: :boolean, default: true, desc: "Generate helper specs"
class_option :routing_specs, type: :boolean, default: true, desc: "Generate routing specs"
def initialize(*args, &blk)
@generator_args = args.first
super(*args, &blk)
end
def generate_controller_spec
return unless options[:controller_specs]
if options[:api]
template 'api_controller_spec.rb', template_file(folder: 'controllers', suffix: '_controller')
else
template 'controller_spec.rb', template_file(folder: 'controllers', suffix: '_controller')
end
end
def generate_request_spec
return unless options[:request_specs]
if options[:api]
template 'api_request_spec.rb', template_file(folder: 'requests')
else
template 'request_spec.rb', template_file(folder: 'requests')
end
end
def generate_view_specs
return if options[:api]
return unless options[:view_specs] && options[:template_engine]
copy_view :edit
copy_view :index unless options[:singleton]
copy_view :new
copy_view :show
end
def generate_routing_spec
return unless options[:routing_specs]
template_file = target_path(
'routing',
controller_class_path,
"#{controller_file_name}_routing_spec.rb"
)
template 'routing_spec.rb', template_file
end
protected
attr_reader :generator_args
def copy_view(view)
template "#{view}_spec.rb",
target_path("views", controller_file_path, "#{view}.html.#{options[:template_engine]}_spec.rb")
end
# support for namespaced-resources
def ns_file_name
return file_name if ns_parts.empty?
"#{ns_prefix.map(&:underscore).join('/')}_#{ns_suffix.singularize.underscore}"
end
# support for namespaced-resources
def ns_table_name
return table_name if ns_parts.empty?
"#{ns_prefix.map(&:underscore).join('/')}/#{ns_suffix.tableize}"
end
def ns_parts
@ns_parts ||= begin
parts = generator_args[0].split(/\/|::/)
parts.size > 1 ? parts : []
end
end
def ns_prefix
@ns_prefix ||= ns_parts[0..-2]
end
def ns_suffix
@ns_suffix ||= ns_parts[-1]
end
def value_for(attribute)
raw_value_for(attribute).inspect
end
def raw_value_for(attribute)
case attribute.type
when :string
attribute.name.titleize
when :integer, :float
@attribute_id_map ||= {}
@attribute_id_map[attribute] ||= @attribute_id_map.keys.size.next + attribute.default
else
attribute.default
end
end
def template_file(folder:, suffix: '')
target_path(folder, controller_class_path, "#{controller_file_name}#{suffix}_spec.rb")
end
def banner
self.class.banner
end
def show_helper(resource_name = file_name)
"#{singular_route_name}_url(#{resource_name})"
end
end
end
end