Skip to content

Commit

Permalink
Add processor generator, allow resource generator to create others
Browse files Browse the repository at this point in the history
Restructure the generators directory structure
Controller generator can now add routes
  • Loading branch information
lgebhardt committed Mar 8, 2020
1 parent 978f590 commit cb15a02
Show file tree
Hide file tree
Showing 19 changed files with 249 additions and 61 deletions.
2 changes: 1 addition & 1 deletion jsonapi-resources.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
spec.require_paths = ['lib']
spec.required_ruby_version = '>= 2.3'

spec.add_development_dependency 'bundler', '~> 1.17.3'
spec.add_development_dependency 'bundler'
spec.add_development_dependency 'rake'
spec.add_development_dependency 'minitest', '~> 5.10', '!= 5.10.2'
spec.add_development_dependency 'minitest-spec-rails'
Expand Down
13 changes: 0 additions & 13 deletions lib/generators/jsonapi/USAGE

This file was deleted.

11 changes: 11 additions & 0 deletions lib/generators/jsonapi/controller/USAGE
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Description:
Controller Generator for JSONAPI Resources

Examples:
rails generate jsonapi:controller Post

This will:
create: app/controllers/posts_controller.rb
add: a route to routes.rb

Note: If the resource is namespaced the namespace will be duplicated for each route
62 changes: 62 additions & 0 deletions lib/generators/jsonapi/controller/controller_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
module Jsonapi
class ControllerGenerator < Rails::Generators::NamedBase
source_root File.expand_path('../templates', __FILE__)

class_option :base_controller, type: :string, default: 'JSONAPI::ResourceController'
class_option :skip_routes, type: :boolean, desc: "Don't add routes to config/routes.rb."

def create_resource
template_file = File.join(
'app/controllers',
class_path,
"#{file_name.pluralize}_controller.rb"
)
template 'controller.rb.tt', template_file
end

def add_routes
return if options[:skip_routes]
route generate_routing_code
end

private

def base_controller
options['base_controller']
end

# This method creates nested route entry for namespaced resources.
# For eg. rails g controller foo/bar/baz index show
# Will generate -
# namespace :foo do
# namespace :bar do
# get 'baz/index'
# get 'baz/show'
# end
# end
def generate_routing_code
depth = 0
lines = []

# Create 'namespace' ladder
# namespace :foo do
# namespace :bar do
regular_class_path.each do |ns|
lines << indent("namespace :#{ns} do\n", depth * 2)
depth += 1
end

lines << indent(%{jsonapi_resources :#{file_name.pluralize}\n}, depth * 2)

# Create `end` ladder
# end
# end
until depth.zero?
depth -= 1
lines << indent("end\n", depth * 2)
end

lines.join
end
end
end
4 changes: 4 additions & 0 deletions lib/generators/jsonapi/controller/templates/controller.rb.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<% module_namespacing do -%>
class <%= class_name.pluralize %>Controller < <%= base_controller %>
end
<% end -%>
14 changes: 0 additions & 14 deletions lib/generators/jsonapi/controller_generator.rb

This file was deleted.

8 changes: 8 additions & 0 deletions lib/generators/jsonapi/processor/USAGE
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Description:
Processor Generator for JSONAPI Resources

Examples:
rails generate jsonapi:processor Post

This will:
create: app/processors/post_processor.rb
22 changes: 22 additions & 0 deletions lib/generators/jsonapi/processor/processor_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module Jsonapi
class ProcessorGenerator < Rails::Generators::NamedBase
source_root File.expand_path('../templates', __FILE__)

class_option :base_processor, type: :string, default: 'JSONAPI::Processor'

def create_processor
template_file = File.join(
'app/processors',
class_path,
"#{file_name.singularize}_processor.rb"
)
template 'processor.rb.tt', template_file
end

private

def base_processor
options['base_processor']
end
end
end
4 changes: 4 additions & 0 deletions lib/generators/jsonapi/processor/templates/processor.rb.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<% module_namespacing do -%>
class <%= class_name.singularize %>Processor < <%= base_processor %>
end
<% end -%>
13 changes: 13 additions & 0 deletions lib/generators/jsonapi/resource/USAGE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Description:
Generator for JSONAPI Resources

Options:
--controller Also generate a controller
--processor Also generate a processor
--model Also generate a model

Examples:
rails generate jsonapi:resource Post

This will:
create: app/resources/post_resource.rb
35 changes: 35 additions & 0 deletions lib/generators/jsonapi/resource/resource_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require 'rails/generators'

module Jsonapi
class ResourceGenerator < Rails::Generators::NamedBase
source_root File.expand_path('../templates', __FILE__)

class_option :base_resource, type: :string, default: 'JSONAPI::Resource'
class_option :controller, type: :boolean, default: false, desc: "Create a controller."
class_option :processor, type: :boolean, default: false, desc: "Create a processor."
class_option :skip_routes, type: :boolean, desc: "Don't add routes to config/routes.rb."

hook_for :controller do |controller|
invoke controller, [ file_path ]
end

hook_for :processor do |processor|
invoke processor, [ file_path ]
end

def create_resource
template_file = File.join(
'app/resources',
class_path,
"#{file_name.singularize}_resource.rb"
)
template 'resource.rb.tt', template_file
end

private

def base_resource
options['base_resource']
end
end
end
4 changes: 4 additions & 0 deletions lib/generators/jsonapi/resource/templates/resource.rb.tt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<% module_namespacing do -%>
class <%= class_name.singularize %>Resource < <%= base_resource %>
end
<% end -%>
14 changes: 0 additions & 14 deletions lib/generators/jsonapi/resource_generator.rb

This file was deleted.

4 changes: 0 additions & 4 deletions lib/generators/jsonapi/templates/jsonapi_controller.rb

This file was deleted.

4 changes: 0 additions & 4 deletions lib/generators/jsonapi/templates/jsonapi_resource.rb

This file was deleted.

3 changes: 3 additions & 0 deletions test/lib/generators/jsonapi/app_template/config/routes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Rails.application.routes.draw do
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
19 changes: 15 additions & 4 deletions test/lib/generators/jsonapi/controller_generator_test.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
require File.expand_path('../../../../test_helper', __FILE__)
require 'generators/jsonapi/controller_generator'
require 'generators/jsonapi/controller/controller_generator'

module Jsonapi
class ControllerGeneratorTest < Rails::Generators::TestCase
tests ControllerGenerator
destination Rails.root.join('../controllers')
destination File.expand_path('../tmp', __dir__ )
setup :prepare_destination
teardown :cleanup_destination_root

def cleanup_destination_root
FileUtils.rm_rf destination_root
end

def prepare_destination
super
FileUtils.cp_r File.expand_path('app_template/', __dir__ ) + '/.', destination_root
end

test "controller is created" do
run_generator ["post"]
assert_file 'app/controllers/posts_controller.rb', /class PostsController < JSONAPI::ResourceController/
end

test "base controller class is settable" do
run_generator %w[post --base_controller BaseController]
assert_file 'app/controllers/posts_controller.rb', /class PostsController < BaseController/
end

test "controller is created with namespace" do
run_generator ["api/v1/post"]
assert_file 'app/controllers/api/v1/posts_controller.rb', /class Api::V1::PostsController < JSONAPI::ResourceController/
run_generator ["api/post"]
assert_file 'app/controllers/api/posts_controller.rb', /class Api::PostsController < JSONAPI::ResourceController/
assert_file 'config/routes.rb', /^ namespace :api do\n jsonapi_resources :posts\n end$/
end
end
end
35 changes: 35 additions & 0 deletions test/lib/generators/jsonapi/processor_generator_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require File.expand_path('../../../../test_helper', __FILE__)
require 'generators/jsonapi/processor/processor_generator'

module Jsonapi
class ProcessorGeneratorTest < Rails::Generators::TestCase
tests ProcessorGenerator
destination File.expand_path('../tmp', __dir__ )
setup :prepare_destination
teardown :cleanup_destination_root

def cleanup_destination_root
FileUtils.rm_rf destination_root
end

test "processor is created" do
run_generator %w[post]
assert_file 'app/processors/post_processor.rb', /class PostProcessor < JSONAPI::Processor/
end

test "base processor class is settable" do
run_generator %w[post --base_processor BaseProcessor]
assert_file 'app/processors/post_processor.rb', /class PostProcessor < BaseProcessor/
end

test "processor is singular" do
run_generator %w[posts]
assert_file 'app/processors/post_processor.rb', /class PostProcessor < JSONAPI::Processor/
end

test "processor is created with namespace" do
run_generator %w[api/v1/post]
assert_file 'app/processors/api/v1/post_processor.rb', /class Api::V1::PostProcessor < JSONAPI::Processor/
end
end
end
39 changes: 32 additions & 7 deletions test/lib/generators/jsonapi/resource_generator_test.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1,55 @@
require File.expand_path('../../../../test_helper', __FILE__)
require 'generators/jsonapi/resource_generator'
require 'generators/jsonapi/resource/resource_generator'

module Jsonapi
class ResourceGeneratorTest < Rails::Generators::TestCase
tests ResourceGenerator
destination Rails.root.join('../resources')
destination File.expand_path('../tmp', __dir__ )
setup :prepare_destination
teardown :cleanup_destination_root

def cleanup_destination_root
FileUtils.rm_rf destination_root
end

def prepare_destination
super
FileUtils.cp_r File.expand_path('app_template/', __dir__ ) + '/.', destination_root
end

test "resource is created" do
run_generator ["post"]
run_generator %w[post]
assert_file 'app/resources/post_resource.rb', /class PostResource < JSONAPI::Resource/
end

test "resource created with controller and processors" do
run_generator %w[post --controller --processor]
assert_file 'app/resources/post_resource.rb', /class PostResource < JSONAPI::Resource/
assert_file 'app/controllers/posts_controller.rb', /class PostsController < JSONAPI::ResourceController/
assert_file 'app/processors/post_processor.rb', /class PostProcessor < JSONAPI::Processor/
end

test "base resource class is settable" do
run_generator %w[post --base_resource BaseResource]
assert_file 'app/resources/post_resource.rb', /class PostResource < BaseResource/
end

test "resource is singular" do
run_generator ["posts"]
run_generator %w[posts]
assert_file 'app/resources/post_resource.rb', /class PostResource < JSONAPI::Resource/
end

test "resource is created with namespace" do
run_generator ["api/v1/post"]
assert_file 'app/resources/api/v1/post_resource.rb', /class Api::V1::PostResource < JSONAPI::Resource/
test "namespaced resource is created" do
run_generator %w[api/post]
assert_file 'app/resources/api/post_resource.rb', /class Api::PostResource < JSONAPI::Resource/
end

test "namespaced resource, controller and processor are created" do
run_generator %w[api/post --controller --processor]
assert_file 'app/resources/api/post_resource.rb', /class Api::PostResource < JSONAPI::Resource/
assert_file 'app/controllers/api/posts_controller.rb', /class Api::PostsController < JSONAPI::ResourceController/
assert_file 'app/processors/api/post_processor.rb', /class Api::PostProcessor < JSONAPI::Processor/
assert_file 'config/routes.rb', /^ namespace :api do\n jsonapi_resources :posts\n end$/
end
end
end

0 comments on commit cb15a02

Please sign in to comment.