From 0ab12a9a3a5a453435a5e770a24b9941746193bd Mon Sep 17 00:00:00 2001 From: Larry Gebhardt Date: Sun, 8 Mar 2020 18:06:00 -0400 Subject: [PATCH] Add processor generator, allow resource generator to create others Restructure the generators directory structure Controller generator can now add routes --- jsonapi-resources.gemspec | 2 +- lib/generators/jsonapi/USAGE | 13 ---- lib/generators/jsonapi/controller/USAGE | 11 ++++ .../controller/controller_generator.rb | 62 +++++++++++++++++++ .../controller/templates/controller.rb.tt | 4 ++ .../jsonapi/controller_generator.rb | 14 ----- lib/generators/jsonapi/processor/USAGE | 8 +++ .../jsonapi/processor/processor_generator.rb | 22 +++++++ .../processor/templates/processor.rb.tt | 4 ++ lib/generators/jsonapi/resource/USAGE | 13 ++++ .../jsonapi/resource/resource_generator.rb | 35 +++++++++++ .../jsonapi/resource/templates/resource.rb.tt | 4 ++ lib/generators/jsonapi/resource_generator.rb | 14 ----- .../jsonapi/templates/jsonapi_controller.rb | 4 -- .../jsonapi/templates/jsonapi_resource.rb | 4 -- .../jsonapi/app_template/config/routes.rb | 3 + .../jsonapi/controller_generator_test.rb | 19 ++++-- .../jsonapi/processor_generator_test.rb | 35 +++++++++++ .../jsonapi/resource_generator_test.rb | 39 +++++++++--- 19 files changed, 249 insertions(+), 61 deletions(-) delete mode 100644 lib/generators/jsonapi/USAGE create mode 100644 lib/generators/jsonapi/controller/USAGE create mode 100644 lib/generators/jsonapi/controller/controller_generator.rb create mode 100644 lib/generators/jsonapi/controller/templates/controller.rb.tt delete mode 100644 lib/generators/jsonapi/controller_generator.rb create mode 100644 lib/generators/jsonapi/processor/USAGE create mode 100644 lib/generators/jsonapi/processor/processor_generator.rb create mode 100644 lib/generators/jsonapi/processor/templates/processor.rb.tt create mode 100644 lib/generators/jsonapi/resource/USAGE create mode 100644 lib/generators/jsonapi/resource/resource_generator.rb create mode 100644 lib/generators/jsonapi/resource/templates/resource.rb.tt delete mode 100644 lib/generators/jsonapi/resource_generator.rb delete mode 100644 lib/generators/jsonapi/templates/jsonapi_controller.rb delete mode 100644 lib/generators/jsonapi/templates/jsonapi_resource.rb create mode 100644 test/lib/generators/jsonapi/app_template/config/routes.rb create mode 100644 test/lib/generators/jsonapi/processor_generator_test.rb diff --git a/jsonapi-resources.gemspec b/jsonapi-resources.gemspec index 030d600e0..784307a64 100644 --- a/jsonapi-resources.gemspec +++ b/jsonapi-resources.gemspec @@ -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' diff --git a/lib/generators/jsonapi/USAGE b/lib/generators/jsonapi/USAGE deleted file mode 100644 index 4cebf40e6..000000000 --- a/lib/generators/jsonapi/USAGE +++ /dev/null @@ -1,13 +0,0 @@ -Description: - Generator for JSONAPI Resources - -Examples: - rails generate jsonapi:resource Post - - This will create: - app/resources/post_resource.rb - - rails generate jsonapi:controller Post - - This will create: - app/controllers/posts_controller.rb diff --git a/lib/generators/jsonapi/controller/USAGE b/lib/generators/jsonapi/controller/USAGE new file mode 100644 index 000000000..6433e7c44 --- /dev/null +++ b/lib/generators/jsonapi/controller/USAGE @@ -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 diff --git a/lib/generators/jsonapi/controller/controller_generator.rb b/lib/generators/jsonapi/controller/controller_generator.rb new file mode 100644 index 000000000..39d0e3351 --- /dev/null +++ b/lib/generators/jsonapi/controller/controller_generator.rb @@ -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 diff --git a/lib/generators/jsonapi/controller/templates/controller.rb.tt b/lib/generators/jsonapi/controller/templates/controller.rb.tt new file mode 100644 index 000000000..6b95eaafd --- /dev/null +++ b/lib/generators/jsonapi/controller/templates/controller.rb.tt @@ -0,0 +1,4 @@ +<% module_namespacing do -%> +class <%= class_name.pluralize %>Controller < <%= base_controller %> +end +<% end -%> diff --git a/lib/generators/jsonapi/controller_generator.rb b/lib/generators/jsonapi/controller_generator.rb deleted file mode 100644 index 41ee4eb1e..000000000 --- a/lib/generators/jsonapi/controller_generator.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Jsonapi - class ControllerGenerator < Rails::Generators::NamedBase - source_root File.expand_path('../templates', __FILE__) - - def create_resource - template_file = File.join( - 'app/controllers', - class_path, - "#{file_name.pluralize}_controller.rb" - ) - template 'jsonapi_controller.rb', template_file - end - end -end diff --git a/lib/generators/jsonapi/processor/USAGE b/lib/generators/jsonapi/processor/USAGE new file mode 100644 index 000000000..a500c912a --- /dev/null +++ b/lib/generators/jsonapi/processor/USAGE @@ -0,0 +1,8 @@ +Description: + Processor Generator for JSONAPI Resources + +Examples: + rails generate jsonapi:processor Post + + This will: + create: app/processors/post_processor.rb diff --git a/lib/generators/jsonapi/processor/processor_generator.rb b/lib/generators/jsonapi/processor/processor_generator.rb new file mode 100644 index 000000000..12c9658ae --- /dev/null +++ b/lib/generators/jsonapi/processor/processor_generator.rb @@ -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 diff --git a/lib/generators/jsonapi/processor/templates/processor.rb.tt b/lib/generators/jsonapi/processor/templates/processor.rb.tt new file mode 100644 index 000000000..07da3dfa5 --- /dev/null +++ b/lib/generators/jsonapi/processor/templates/processor.rb.tt @@ -0,0 +1,4 @@ +<% module_namespacing do -%> +class <%= class_name.singularize %>Processor < <%= base_processor %> +end +<% end -%> diff --git a/lib/generators/jsonapi/resource/USAGE b/lib/generators/jsonapi/resource/USAGE new file mode 100644 index 000000000..9f0b10eb2 --- /dev/null +++ b/lib/generators/jsonapi/resource/USAGE @@ -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 diff --git a/lib/generators/jsonapi/resource/resource_generator.rb b/lib/generators/jsonapi/resource/resource_generator.rb new file mode 100644 index 000000000..c1a9d6191 --- /dev/null +++ b/lib/generators/jsonapi/resource/resource_generator.rb @@ -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 diff --git a/lib/generators/jsonapi/resource/templates/resource.rb.tt b/lib/generators/jsonapi/resource/templates/resource.rb.tt new file mode 100644 index 000000000..5c5d947ee --- /dev/null +++ b/lib/generators/jsonapi/resource/templates/resource.rb.tt @@ -0,0 +1,4 @@ +<% module_namespacing do -%> +class <%= class_name.singularize %>Resource < <%= base_resource %> +end +<% end -%> diff --git a/lib/generators/jsonapi/resource_generator.rb b/lib/generators/jsonapi/resource_generator.rb deleted file mode 100644 index 80aa24b4d..000000000 --- a/lib/generators/jsonapi/resource_generator.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Jsonapi - class ResourceGenerator < Rails::Generators::NamedBase - source_root File.expand_path('../templates', __FILE__) - - def create_resource - template_file = File.join( - 'app/resources', - class_path, - "#{file_name.singularize}_resource.rb" - ) - template 'jsonapi_resource.rb', template_file - end - end -end diff --git a/lib/generators/jsonapi/templates/jsonapi_controller.rb b/lib/generators/jsonapi/templates/jsonapi_controller.rb deleted file mode 100644 index 8266f029a..000000000 --- a/lib/generators/jsonapi/templates/jsonapi_controller.rb +++ /dev/null @@ -1,4 +0,0 @@ -<% module_namespacing do -%> -class <%= class_name.pluralize %>Controller < JSONAPI::ResourceController -end -<% end -%> diff --git a/lib/generators/jsonapi/templates/jsonapi_resource.rb b/lib/generators/jsonapi/templates/jsonapi_resource.rb deleted file mode 100644 index dfe76c19e..000000000 --- a/lib/generators/jsonapi/templates/jsonapi_resource.rb +++ /dev/null @@ -1,4 +0,0 @@ -<% module_namespacing do -%> -class <%= class_name.singularize %>Resource < JSONAPI::Resource -end -<% end -%> diff --git a/test/lib/generators/jsonapi/app_template/config/routes.rb b/test/lib/generators/jsonapi/app_template/config/routes.rb new file mode 100644 index 000000000..c06383a17 --- /dev/null +++ b/test/lib/generators/jsonapi/app_template/config/routes.rb @@ -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 diff --git a/test/lib/generators/jsonapi/controller_generator_test.rb b/test/lib/generators/jsonapi/controller_generator_test.rb index faed0637c..d810efefb 100644 --- a/test/lib/generators/jsonapi/controller_generator_test.rb +++ b/test/lib/generators/jsonapi/controller_generator_test.rb @@ -1,10 +1,10 @@ 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 @@ -12,14 +12,25 @@ 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 diff --git a/test/lib/generators/jsonapi/processor_generator_test.rb b/test/lib/generators/jsonapi/processor_generator_test.rb new file mode 100644 index 000000000..775012691 --- /dev/null +++ b/test/lib/generators/jsonapi/processor_generator_test.rb @@ -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 diff --git a/test/lib/generators/jsonapi/resource_generator_test.rb b/test/lib/generators/jsonapi/resource_generator_test.rb index c12e69122..70f9b8b7c 100644 --- a/test/lib/generators/jsonapi/resource_generator_test.rb +++ b/test/lib/generators/jsonapi/resource_generator_test.rb @@ -1,10 +1,10 @@ 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 @@ -12,19 +12,44 @@ 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