railsforge 1.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +129 -435
  3. data/lib/railsforge/analyzers/controller_analyzer.rb +29 -55
  4. data/lib/railsforge/analyzers/database_analyzer.rb +16 -30
  5. data/lib/railsforge/analyzers/metrics_analyzer.rb +8 -22
  6. data/lib/railsforge/analyzers/model_analyzer.rb +29 -46
  7. data/lib/railsforge/analyzers/performance_analyzer.rb +34 -94
  8. data/lib/railsforge/analyzers/refactor_analyzer.rb +77 -57
  9. data/lib/railsforge/analyzers/security_analyzer.rb +34 -91
  10. data/lib/railsforge/analyzers/spec_analyzer.rb +17 -31
  11. data/lib/railsforge/cli.rb +28 -645
  12. data/lib/railsforge/cli_minimal.rb +10 -55
  13. data/lib/railsforge/diff.rb +57 -0
  14. data/lib/railsforge/doctor.rb +52 -225
  15. data/lib/railsforge/formatter.rb +128 -0
  16. data/lib/railsforge/issue.rb +23 -0
  17. data/lib/railsforge/loader.rb +5 -64
  18. data/lib/railsforge/version.rb +1 -1
  19. metadata +15 -82
  20. data/lib/railsforge/api_generator.rb +0 -397
  21. data/lib/railsforge/audit.rb +0 -289
  22. data/lib/railsforge/config.rb +0 -181
  23. data/lib/railsforge/database_analyzer.rb +0 -300
  24. data/lib/railsforge/feature_generator.rb +0 -560
  25. data/lib/railsforge/generator.rb +0 -313
  26. data/lib/railsforge/generators/api_generator.rb +0 -392
  27. data/lib/railsforge/generators/base_generator.rb +0 -75
  28. data/lib/railsforge/generators/demo_generator.rb +0 -307
  29. data/lib/railsforge/generators/devops_generator.rb +0 -287
  30. data/lib/railsforge/generators/form_generator.rb +0 -180
  31. data/lib/railsforge/generators/job_generator.rb +0 -176
  32. data/lib/railsforge/generators/monitoring_generator.rb +0 -134
  33. data/lib/railsforge/generators/policy_generator.rb +0 -220
  34. data/lib/railsforge/generators/presenter_generator.rb +0 -173
  35. data/lib/railsforge/generators/query_generator.rb +0 -174
  36. data/lib/railsforge/generators/serializer_generator.rb +0 -166
  37. data/lib/railsforge/generators/service_generator.rb +0 -122
  38. data/lib/railsforge/generators/stimulus_controller_generator.rb +0 -129
  39. data/lib/railsforge/generators/test_generator.rb +0 -289
  40. data/lib/railsforge/generators/view_component_generator.rb +0 -169
  41. data/lib/railsforge/graph.rb +0 -270
  42. data/lib/railsforge/mailer_generator.rb +0 -191
  43. data/lib/railsforge/plugins/plugin_loader.rb +0 -60
  44. data/lib/railsforge/plugins.rb +0 -30
  45. data/lib/railsforge/profiles.rb +0 -99
  46. data/lib/railsforge/refactor_analyzer.rb +0 -401
  47. data/lib/railsforge/refactor_controller.rb +0 -277
  48. data/lib/railsforge/refactors/refactor_controller.rb +0 -117
  49. data/lib/railsforge/template_loader.rb +0 -105
  50. data/lib/railsforge/templates/v1/form/spec_template.rb +0 -18
  51. data/lib/railsforge/templates/v1/form/template.rb +0 -28
  52. data/lib/railsforge/templates/v1/job/spec_template.rb +0 -17
  53. data/lib/railsforge/templates/v1/job/template.rb +0 -13
  54. data/lib/railsforge/templates/v1/policy/spec_template.rb +0 -41
  55. data/lib/railsforge/templates/v1/policy/template.rb +0 -57
  56. data/lib/railsforge/templates/v1/presenter/spec_template.rb +0 -12
  57. data/lib/railsforge/templates/v1/presenter/template.rb +0 -13
  58. data/lib/railsforge/templates/v1/query/spec_template.rb +0 -12
  59. data/lib/railsforge/templates/v1/query/template.rb +0 -16
  60. data/lib/railsforge/templates/v1/serializer/spec_template.rb +0 -13
  61. data/lib/railsforge/templates/v1/serializer/template.rb +0 -11
  62. data/lib/railsforge/templates/v1/service/spec_template.rb +0 -12
  63. data/lib/railsforge/templates/v1/service/template.rb +0 -25
  64. data/lib/railsforge/templates/v1/stimulus_controller/template.rb +0 -35
  65. data/lib/railsforge/templates/v1/view_component/template.rb +0 -24
  66. data/lib/railsforge/templates/v2/job/template.rb +0 -49
  67. data/lib/railsforge/templates/v2/query/template.rb +0 -66
  68. data/lib/railsforge/templates/v2/service/spec_template.rb +0 -33
  69. data/lib/railsforge/templates/v2/service/template.rb +0 -71
  70. data/lib/railsforge/templates/v3/job/template.rb +0 -72
  71. data/lib/railsforge/templates/v3/query/spec_template.rb +0 -54
  72. data/lib/railsforge/templates/v3/query/template.rb +0 -115
  73. data/lib/railsforge/templates/v3/service/spec_template.rb +0 -51
  74. data/lib/railsforge/templates/v3/service/template.rb +0 -93
  75. data/lib/railsforge/wizard.rb +0 -265
  76. data/lib/railsforge/wizard_tui.rb +0 -286
@@ -1,5 +1,5 @@
1
1
  # Version module for RailsForge gem
2
2
  # Defines the current version of the gem
3
3
  module RailsForge
4
- VERSION = "0.2.0"
4
+ VERSION = "2.1.0"
5
5
  end
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: railsforge
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - RailsForge Contributors
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-10 00:00:00.000000000 Z
11
+ date: 2026-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: thor
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.3'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.3'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: bundler
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -81,10 +67,11 @@ dependencies:
81
67
  - !ruby/object:Gem::Version
82
68
  version: '1.85'
83
69
  description: |
84
- RailsForge is a comprehensive command-line tool for automatically generating
85
- essential Rails application components, including monitoring configurations,
86
- DevOps setups, and security/performance analyzers.
87
- email:
70
+ RailsForge analyzes Rails applications and produces structured,
71
+ severity-ranked diagnostics with actionable fixes. Run
72
+ `railsforge doctor` to get a health score and full issue report
73
+ for your codebase.
74
+ email:
88
75
  executables:
89
76
  - railsforge
90
77
  extensions: []
@@ -103,77 +90,23 @@ files:
103
90
  - lib/railsforge/analyzers/refactor_analyzer.rb
104
91
  - lib/railsforge/analyzers/security_analyzer.rb
105
92
  - lib/railsforge/analyzers/spec_analyzer.rb
106
- - lib/railsforge/api_generator.rb
107
- - lib/railsforge/audit.rb
108
93
  - lib/railsforge/cli.rb
109
94
  - lib/railsforge/cli_minimal.rb
110
- - lib/railsforge/config.rb
111
- - lib/railsforge/database_analyzer.rb
95
+ - lib/railsforge/diff.rb
112
96
  - lib/railsforge/doctor.rb
113
- - lib/railsforge/feature_generator.rb
114
- - lib/railsforge/generator.rb
115
- - lib/railsforge/generators/api_generator.rb
116
- - lib/railsforge/generators/base_generator.rb
117
- - lib/railsforge/generators/demo_generator.rb
118
- - lib/railsforge/generators/devops_generator.rb
119
- - lib/railsforge/generators/form_generator.rb
120
- - lib/railsforge/generators/job_generator.rb
121
- - lib/railsforge/generators/monitoring_generator.rb
122
- - lib/railsforge/generators/policy_generator.rb
123
- - lib/railsforge/generators/presenter_generator.rb
124
- - lib/railsforge/generators/query_generator.rb
125
- - lib/railsforge/generators/serializer_generator.rb
126
- - lib/railsforge/generators/service_generator.rb
127
- - lib/railsforge/generators/stimulus_controller_generator.rb
128
- - lib/railsforge/generators/test_generator.rb
129
- - lib/railsforge/generators/view_component_generator.rb
130
- - lib/railsforge/graph.rb
97
+ - lib/railsforge/formatter.rb
98
+ - lib/railsforge/issue.rb
131
99
  - lib/railsforge/loader.rb
132
- - lib/railsforge/mailer_generator.rb
133
- - lib/railsforge/plugins.rb
134
- - lib/railsforge/plugins/plugin_loader.rb
135
- - lib/railsforge/profiles.rb
136
100
  - lib/railsforge/profiles/admin_app.yml
137
101
  - lib/railsforge/profiles/api_only.yml
138
102
  - lib/railsforge/profiles/blog.yml
139
103
  - lib/railsforge/profiles/standard.yml
140
- - lib/railsforge/refactor_analyzer.rb
141
- - lib/railsforge/refactor_controller.rb
142
- - lib/railsforge/refactors/refactor_controller.rb
143
- - lib/railsforge/template_loader.rb
144
- - lib/railsforge/templates/v1/form/spec_template.rb
145
- - lib/railsforge/templates/v1/form/template.rb
146
- - lib/railsforge/templates/v1/job/spec_template.rb
147
- - lib/railsforge/templates/v1/job/template.rb
148
- - lib/railsforge/templates/v1/policy/spec_template.rb
149
- - lib/railsforge/templates/v1/policy/template.rb
150
- - lib/railsforge/templates/v1/presenter/spec_template.rb
151
- - lib/railsforge/templates/v1/presenter/template.rb
152
- - lib/railsforge/templates/v1/query/spec_template.rb
153
- - lib/railsforge/templates/v1/query/template.rb
154
- - lib/railsforge/templates/v1/serializer/spec_template.rb
155
- - lib/railsforge/templates/v1/serializer/template.rb
156
- - lib/railsforge/templates/v1/service/spec_template.rb
157
- - lib/railsforge/templates/v1/service/template.rb
158
- - lib/railsforge/templates/v1/stimulus_controller/template.rb
159
- - lib/railsforge/templates/v1/view_component/template.rb
160
- - lib/railsforge/templates/v2/job/template.rb
161
- - lib/railsforge/templates/v2/query/template.rb
162
- - lib/railsforge/templates/v2/service/spec_template.rb
163
- - lib/railsforge/templates/v2/service/template.rb
164
- - lib/railsforge/templates/v3/job/template.rb
165
- - lib/railsforge/templates/v3/query/spec_template.rb
166
- - lib/railsforge/templates/v3/query/template.rb
167
- - lib/railsforge/templates/v3/service/spec_template.rb
168
- - lib/railsforge/templates/v3/service/template.rb
169
104
  - lib/railsforge/version.rb
170
- - lib/railsforge/wizard.rb
171
- - lib/railsforge/wizard_tui.rb
172
105
  homepage: https://github.com/mfifth/RailsForge
173
106
  licenses:
174
107
  - MIT
175
108
  metadata: {}
176
- post_install_message:
109
+ post_install_message:
177
110
  rdoc_options: []
178
111
  require_paths:
179
112
  - lib
@@ -188,8 +121,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
188
121
  - !ruby/object:Gem::Version
189
122
  version: '0'
190
123
  requirements: []
191
- rubygems_version: 3.4.1
192
- signing_key:
124
+ rubygems_version: 3.2.3
125
+ signing_key:
193
126
  specification_version: 4
194
- summary: A Rails development toolkit with generators and analyzers
127
+ summary: Rails application health diagnostics
195
128
  test_files: []
@@ -1,397 +0,0 @@
1
- module RailsForge
2
- # ApiGenerator module handles generating API resources
3
- module ApiGenerator
4
- # Error class for invalid resource names
5
- class InvalidResourceNameError < StandardError; end
6
-
7
- # Simple pluralize helper
8
- def self.pluralize(word)
9
- return word + 's' unless word.end_with?('s')
10
- return word + 'es' if word.end_with?('sh') || word.end_with?('ch')
11
- word + 's'
12
- end
13
-
14
- # Simple underscore helper
15
- def self.underscore(word)
16
- word.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
17
- .gsub(/([a-z\d])([A-Z])/, '\1_\2')
18
- .downcase
19
- end
20
-
21
- # Validates the resource name
22
- def self.validate_resource_name(name)
23
- if name.nil? || name.strip.empty?
24
- raise InvalidResourceNameError, "Resource name cannot be empty"
25
- end
26
-
27
- unless name =~ /\A[A-Z][a-zA-Z0-9]*\z/
28
- raise InvalidResourceNameError, "Resource name must be in PascalCase (e.g., User)"
29
- end
30
- end
31
-
32
- # Generates an API resource with all necessary files
33
- def self.generate(resource_name, with_spec: true, version: "v1", namespace: "api")
34
- validate_resource_name(resource_name)
35
-
36
- base_path = find_rails_app_path
37
- raise InvalidResourceNameError, "Not in a Rails application directory" unless base_path
38
-
39
- results = []
40
-
41
- # Generate directories
42
- controller_dir = File.join(base_path, "app", "controllers", namespace, version)
43
- FileUtils.mkdir_p(controller_dir)
44
-
45
- serializer_dir = File.join(base_path, "app", "serializers")
46
- FileUtils.mkdir_p(serializer_dir)
47
-
48
- policy_dir = File.join(base_path, "app", "policies")
49
- FileUtils.mkdir_p(policy_dir)
50
-
51
- service_dir = File.join(base_path, "app", "services")
52
- FileUtils.mkdir_p(service_dir)
53
-
54
- query_dir = File.join(base_path, "app", "queries")
55
- FileUtils.mkdir_p(query_dir)
56
-
57
- results << generate_controller(base_path, resource_name, namespace, version)
58
- results << generate_serializer(base_path, resource_name)
59
- results << generate_policy(base_path, resource_name)
60
- results << generate_service(base_path, resource_name)
61
- results << generate_query(base_path, resource_name)
62
-
63
- if with_spec
64
- spec_dir = File.join(base_path, "spec", "requests", namespace, version)
65
- FileUtils.mkdir_p(spec_dir)
66
- results << generate_request_spec(base_path, resource_name, namespace, version)
67
- end
68
-
69
- "API resource '#{resource_name}' generated successfully with #{results.count} files!"
70
- end
71
-
72
- def self.generate_controller(base_path, resource_name, namespace, version)
73
- resource_plural = pluralize(resource_name)
74
- resource_underscore = underscore(resource_name)
75
- resource_underscore_plural = pluralize(resource_underscore)
76
-
77
- file_name = "#{resource_underscore}_controller.rb"
78
- file_path = File.join(base_path, "app", "controllers", namespace, version, file_name)
79
-
80
- return " Skipping controller (already exists)" if File.exist?(file_path)
81
-
82
- content = <<~RUBY
83
- # API Controller for #{resource_name}
84
- # Version: #{version}
85
- # Namespace: #{namespace}
86
- #
87
- # Generates standard CRUD actions for REST API
88
- class #{resource_plural}Controller < ApplicationController
89
- before_action :set_#{resource_underscore}, only: [:show, :update, :destroy]
90
- before_action :authenticate_user!, unless: :devise_controller?
91
-
92
- # GET /#{resource_underscore_plural}
93
- def index
94
- @#{resource_underscore_plural} = #{resource_name}Query.call
95
- render json: #{resource_name}Serializer.new(@#{resource_underscore_plural}).serializable_hash
96
- end
97
-
98
- # GET /#{resource_underscore_plural}/:id
99
- def show
100
- render json: #{resource_name}Serializer.new(@#{resource_underscore}).serializable_hash
101
- end
102
-
103
- # POST /#{resource_underscore_plural}
104
- def create
105
- @result = Create#{resource_name}Service.call(#{resource_underscore}_params)
106
-
107
- if @result.success?
108
- render json: #{resource_name}Serializer.new(@result.#{resource_underscore}).serializable_hash, status: :created
109
- else
110
- render json: { errors: @result.errors }, status: :unprocessable_entity
111
- end
112
- end
113
-
114
- # PATCH/PUT /#{resource_underscore_plural}/:id
115
- def update
116
- @result = Update#{resource_name}Service.call(@#{resource_underscore}, #{resource_underscore}_params)
117
-
118
- if @result.success?
119
- render json: #{resource_name}Serializer.new(@result.#{resource_underscore}).serializable_hash
120
- else
121
- render json: { errors: @result.errors }, status: :unprocessable_entity
122
- end
123
- end
124
-
125
- # DELETE /#{resource_underscore_plural}/:id
126
- def destroy
127
- @#{resource_underscore}.destroy
128
- head :no_content
129
- end
130
-
131
- private
132
-
133
- def set_#{resource_underscore}
134
- @#{resource_underscore} = #{resource_name}.find(params[:id])
135
- end
136
-
137
- def #{resource_underscore}_params
138
- params.require(:#{resource_underscore}).permit(:name)
139
- end
140
- end
141
- RUBY
142
-
143
- File.write(file_path, content)
144
- puts " Created app/controllers/#{namespace}/#{version}/#{file_name}"
145
- file_path
146
- end
147
-
148
- def self.generate_serializer(base_path, resource_name)
149
- file_name = "#{underscore(resource_name)}_serializer.rb"
150
- file_path = File.join(base_path, "app", "serializers", file_name)
151
-
152
- return " Skipping serializer (already exists)" if File.exist?(file_path)
153
-
154
- content = <<~RUBY
155
- # Serializer for #{resource_name}
156
- class #{resource_name}Serializer < ApplicationSerializer
157
- attributes :id, :name, :created_at, :updated_at
158
- end
159
- RUBY
160
-
161
- File.write(file_path, content)
162
- puts " Created app/serializers/#{file_name}"
163
- file_path
164
- end
165
-
166
- def self.generate_policy(base_path, resource_name)
167
- file_name = "#{underscore(resource_name)}_policy.rb"
168
- file_path = File.join(base_path, "app", "policies", file_name)
169
-
170
- return " Skipping policy (already exists)" if File.exist?(file_path)
171
-
172
- content = <<~RUBY
173
- # Policy for #{resource_name}
174
- class #{resource_name}Policy
175
- attr_reader :user, :record
176
-
177
- def initialize(user, record)
178
- @user = user
179
- @record = record
180
- end
181
-
182
- def index?
183
- true
184
- end
185
-
186
- def show?
187
- true
188
- end
189
-
190
- def create?
191
- user.present?
192
- end
193
-
194
- def update?
195
- user.present?
196
- end
197
-
198
- def destroy?
199
- user.present?
200
- end
201
-
202
- class Scope
203
- def initialize(user, scope)
204
- @user = user
205
- @scope = scope
206
- end
207
-
208
- def resolve
209
- scope.all
210
- end
211
- end
212
- end
213
- RUBY
214
-
215
- File.write(file_path, content)
216
- puts " Created app/policies/#{file_name}"
217
- file_path
218
- end
219
-
220
- def self.generate_service(base_path, resource_name)
221
- res_underscore = underscore(resource_name)
222
-
223
- # Create service
224
- file_name = "create_#{res_underscore}_service.rb"
225
- file_path = File.join(base_path, "app", "services", file_name)
226
-
227
- unless File.exist?(file_path)
228
- content = <<~RUBY
229
- # Service for creating #{resource_name}
230
- class Create#{resource_name}Service
231
- def initialize(params)
232
- @params = params
233
- end
234
-
235
- def call
236
- @#{res_underscore} = #{resource_name}.create!(@params)
237
- Result.new(success: true, #{res_underscore}: @#{res_underscore})
238
- rescue => e
239
- Result.new(success: false, errors: e.message)
240
- end
241
-
242
- class Result
243
- attr_reader :#{res_underscore}, :errors
244
- def initialize(success:, #{res_underscore}: nil, errors: nil)
245
- @success = success
246
- @#{res_underscore} = #{res_underscore}
247
- @errors = errors
248
- end
249
-
250
- def success?
251
- @success
252
- end
253
- end
254
- end
255
- RUBY
256
-
257
- File.write(file_path, content)
258
- puts " Created app/services/#{file_name}"
259
- end
260
-
261
- # Update service
262
- file_name = "update_#{res_underscore}_service.rb"
263
- file_path = File.join(base_path, "app", "services", file_name)
264
-
265
- unless File.exist?(file_path)
266
- content = <<~RUBY
267
- # Service for updating #{resource_name}
268
- class Update#{resource_name}Service
269
- def initialize(#{res_underscore}, params)
270
- @#{res_underscore} = #{res_underscore}
271
- @params = params
272
- end
273
-
274
- def call
275
- if @#{res_underscore}.update(@params)
276
- Result.new(success: true, #{res_underscore}: @#{res_underscore})
277
- else
278
- Result.new(success: false, errors: @#{res_underscore}.errors.full_messages)
279
- end
280
- end
281
-
282
- class Result
283
- attr_reader :#{res_underscore}, :errors
284
- def initialize(success:, #{res_underscore}: nil, errors: nil)
285
- @success = success
286
- @#{res_underscore} = #{res_underscore}
287
- @errors = errors
288
- end
289
-
290
- def success?
291
- @success
292
- end
293
- end
294
- end
295
- RUBY
296
-
297
- File.write(file_path, content)
298
- puts " Created app/services/#{file_name}"
299
- end
300
-
301
- "services"
302
- end
303
-
304
- def self.generate_query(base_path, resource_name)
305
- file_name = "find_#{underscore(resource_name)}.rb"
306
- file_path = File.join(base_path, "app", "queries", file_name)
307
-
308
- return " Skipping query (already exists)" if File.exist?(file_path)
309
-
310
- content = <<~RUBY
311
- # Query for finding #{resource_name}
312
- class Find#{resource_name}
313
- def initialize(scope: nil)
314
- @scope = scope || #{resource_name}.all
315
- end
316
-
317
- def call
318
- @scope
319
- end
320
- end
321
- RUBY
322
-
323
- File.write(file_path, content)
324
- puts " Created app/queries/#{file_name}"
325
- file_path
326
- end
327
-
328
- def self.generate_request_spec(base_path, resource_name, namespace, version)
329
- resource_plural = pluralize(resource_name)
330
- resource_underscore = underscore(resource_name)
331
-
332
- file_name = "#{resource_underscore}_spec.rb"
333
- file_path = File.join(base_path, "spec", "requests", namespace, version, file_name)
334
-
335
- return " Skipping spec (already exists)" if File.exist?(file_path)
336
-
337
- content = <<~RUBY
338
- require 'rails_helper'
339
-
340
- RSpec.describe "#{namespace.capitalize}::#{version.capitalize}::#{resource_plural}Controller" do
341
- let(:user) { User.create!(name: "Test", email: "test@example.com") }
342
- let(:#{resource_underscore}) { #{resource_name}.create!(name: "Test #{resource_name}") }
343
-
344
- before do
345
- sign_in user
346
- end
347
-
348
- describe "GET /index" do
349
- it "returns a success response" do
350
- get :index
351
- expect(response).to be_successful
352
- end
353
- end
354
-
355
- describe "GET /show" do
356
- it "returns a success response" do
357
- get :show, params: { id: #{resource_underscore}.id }
358
- expect(response).to be_successful
359
- end
360
- end
361
-
362
- describe "POST /create" do
363
- it "creates a new #{resource_underscore}" do
364
- expect {
365
- post :create, params: { #{resource_underscore}: { name: "New #{resource_name}" } }
366
- }.to change(#{resource_name}, :count).by(1)
367
- end
368
- end
369
-
370
- describe "DELETE /destroy" do
371
- it "deletes the #{resource_underscore}" do
372
- #{resource_underscore}
373
- expect {
374
- delete :destroy, params: { id: #{resource_underscore}.id }
375
- }.to change(#{resource_name}, :count).by(-1)
376
- end
377
- end
378
- end
379
- RUBY
380
-
381
- File.write(file_path, content)
382
- puts " Created spec/requests/#{namespace}/#{version}/#{file_name}"
383
- file_path
384
- end
385
-
386
- def self.find_rails_app_path
387
- path = Dir.pwd
388
- 10.times do
389
- return path if File.exist?(File.join(path, "config", "application.rb"))
390
- parent = File.dirname(path)
391
- break if parent == path
392
- path = parent
393
- end
394
- nil
395
- end
396
- end
397
- end