File: scaffold_generator.rb

package info (click to toggle)
ruby-rspec-rails 7.1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,796 kB
  • sloc: ruby: 11,068; sh: 198; makefile: 6
file content (136 lines) | stat: -rw-r--r-- 4,259 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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