From 77d00407a4e0a6de2f4a37b5a4b49458d4e37915 Mon Sep 17 00:00:00 2001 From: Greg Myers Date: Wed, 16 Oct 2019 20:51:53 +0100 Subject: [PATCH 1/4] whitespace linting --- rswag-specs/lib/rswag/specs/extended_schema.rb | 4 ++-- rswag-specs/lib/rswag/specs/railtie.rb | 2 +- rswag-specs/lib/rswag/specs/request_factory.rb | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rswag-specs/lib/rswag/specs/extended_schema.rb b/rswag-specs/lib/rswag/specs/extended_schema.rb index 62eb4ee..29888f8 100644 --- a/rswag-specs/lib/rswag/specs/extended_schema.rb +++ b/rswag-specs/lib/rswag/specs/extended_schema.rb @@ -3,7 +3,7 @@ require 'json-schema' module Rswag module Specs class ExtendedSchema < JSON::Schema::Draft4 - + def initialize super @attributes['type'] = ExtendedTypeAttribute @@ -13,7 +13,7 @@ module Rswag end class ExtendedTypeAttribute < JSON::Schema::TypeV4Attribute - + def self.validate(current_schema, data, fragments, processor, validator, options={}) return if data.nil? && current_schema.schema['x-nullable'] == true super diff --git a/rswag-specs/lib/rswag/specs/railtie.rb b/rswag-specs/lib/rswag/specs/railtie.rb index 43e2302..994a8a4 100644 --- a/rswag-specs/lib/rswag/specs/railtie.rb +++ b/rswag-specs/lib/rswag/specs/railtie.rb @@ -5,7 +5,7 @@ module Rswag rake_tasks do load File.expand_path('../../../tasks/rswag-specs_tasks.rake', __FILE__) end - + generators do require 'generators/rspec/swagger/swagger_generator.rb' end diff --git a/rswag-specs/lib/rswag/specs/request_factory.rb b/rswag-specs/lib/rswag/specs/request_factory.rb index 7106015..14b1edc 100644 --- a/rswag-specs/lib/rswag/specs/request_factory.rb +++ b/rswag-specs/lib/rswag/specs/request_factory.rb @@ -54,7 +54,7 @@ module Rswag definitions[key] end - def add_verb(request, metadata) + def add_verb(request, metadata) request[:verb] = metadata[:operation][:verb] end @@ -104,7 +104,7 @@ module Rswag end # Content-Type header - consumes = metadata[:operation][:consumes] || swagger_doc[:consumes] + consumes = metadata[:operation][:consumes] || swagger_doc[:consumes] if consumes content_type = example.respond_to?(:'Content-Type') ? example.send(:'Content-Type') : consumes.first tuples << [ 'Content-Type', content_type ] From 778d25038558cb59cf6d2c20fac6bd6877b011d8 Mon Sep 17 00:00:00 2001 From: Greg Myers Date: Wed, 16 Oct 2019 21:12:36 +0100 Subject: [PATCH 2/4] Split file join path --- rswag-specs/lib/generators/rspec/swagger/swagger_generator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rswag-specs/lib/generators/rspec/swagger/swagger_generator.rb b/rswag-specs/lib/generators/rspec/swagger/swagger_generator.rb index 48f92aa..81feeb9 100644 --- a/rswag-specs/lib/generators/rspec/swagger/swagger_generator.rb +++ b/rswag-specs/lib/generators/rspec/swagger/swagger_generator.rb @@ -11,7 +11,7 @@ module Rspec end def create_spec_file - template 'spec.rb', File.join('spec/requests', "#{controller_path}_spec.rb") + template 'spec.rb', File.join('spec', 'requests', "#{controller_path}_spec.rb") end private From 189a7ef06136e42307c2d8b9d1c9a438d48add3e Mon Sep 17 00:00:00 2001 From: Greg Myers Date: Wed, 16 Oct 2019 22:05:14 +0100 Subject: [PATCH 3/4] Move spec generator files, organize whitespace in generator output --- .../lib/generators/rspec/{swagger => }/USAGE | 0 .../rspec/swagger/swagger_generator.rb | 24 ------- .../lib/generators/rspec/swagger_generator.rb | 22 +++++++ .../rspec/{swagger => }/templates/spec.rb | 24 +++---- .../lib/rspec/rails/swagger/route_parser.rb | 62 ------------------- rswag-specs/lib/rswag/route_parser.rb | 58 +++++++++++++++++ 6 files changed, 92 insertions(+), 98 deletions(-) rename rswag-specs/lib/generators/rspec/{swagger => }/USAGE (100%) delete mode 100644 rswag-specs/lib/generators/rspec/swagger/swagger_generator.rb create mode 100644 rswag-specs/lib/generators/rspec/swagger_generator.rb rename rswag-specs/lib/generators/rspec/{swagger => }/templates/spec.rb (59%) delete mode 100644 rswag-specs/lib/rspec/rails/swagger/route_parser.rb create mode 100644 rswag-specs/lib/rswag/route_parser.rb diff --git a/rswag-specs/lib/generators/rspec/swagger/USAGE b/rswag-specs/lib/generators/rspec/USAGE similarity index 100% rename from rswag-specs/lib/generators/rspec/swagger/USAGE rename to rswag-specs/lib/generators/rspec/USAGE diff --git a/rswag-specs/lib/generators/rspec/swagger/swagger_generator.rb b/rswag-specs/lib/generators/rspec/swagger/swagger_generator.rb deleted file mode 100644 index 81feeb9..0000000 --- a/rswag-specs/lib/generators/rspec/swagger/swagger_generator.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'rspec/rails/swagger/route_parser' -require 'rails/generators' - -module Rspec - module Generators - class SwaggerGenerator < ::Rails::Generators::NamedBase - source_root File.expand_path('../templates', __FILE__) - - def setup - @routes = RSpec::Rails::Swagger::RouteParser.new(controller_path).routes - end - - def create_spec_file - template 'spec.rb', File.join('spec', 'requests', "#{controller_path}_spec.rb") - end - - private - - def controller_path - file_path.chomp('_controller') - end - end - end -end diff --git a/rswag-specs/lib/generators/rspec/swagger_generator.rb b/rswag-specs/lib/generators/rspec/swagger_generator.rb new file mode 100644 index 0000000..ddb862c --- /dev/null +++ b/rswag-specs/lib/generators/rspec/swagger_generator.rb @@ -0,0 +1,22 @@ +require 'rswag/route_parser' +require 'rails/generators' + +module Rspec + class SwaggerGenerator < ::Rails::Generators::NamedBase + source_root File.expand_path('../templates', __FILE__) + + def setup + @routes = Rswag::RouteParser.new(controller_path).routes + end + + def create_spec_file + template 'spec.rb', File.join('spec', 'requests', "#{controller_path}_spec.rb") + end + + private + + def controller_path + file_path.chomp('_controller') + end + end +end diff --git a/rswag-specs/lib/generators/rspec/swagger/templates/spec.rb b/rswag-specs/lib/generators/rspec/templates/spec.rb similarity index 59% rename from rswag-specs/lib/generators/rspec/swagger/templates/spec.rb rename to rswag-specs/lib/generators/rspec/templates/spec.rb index 75ff7b3..0673596 100644 --- a/rswag-specs/lib/generators/rspec/swagger/templates/spec.rb +++ b/rswag-specs/lib/generators/rspec/templates/spec.rb @@ -1,22 +1,22 @@ require 'swagger_helper' RSpec.describe '<%= controller_path %>', type: :request do - <% @routes.each do | template, path_item | %> +<% @routes.each do | template, path_item | %> path '<%= template %>' do -<% unless path_item[:params].empty? -%> +<% unless path_item[:params].empty? -%> # You'll want to customize the parameter types... - <% path_item[:params].each do |param| -%> +<% path_item[:params].each do |param| -%> parameter '<%= param %>', in: :body, type: :string - <% end -%> -<% end -%> -<% path_item[:actions].each do | action, details | -%> +<% end -%> +<% end -%> +<% path_item[:actions].each do | action, details | %> <%= action %>('<%= details[:summary] %>') do response(200, 'successful') do -<% unless path_item[:params].empty? -%> - <% path_item[:params].each do |param| -%> +<% unless path_item[:params].empty? -%> +<% path_item[:params].each do |param| -%> let(:<%= param %>) { '123' } - <% end -%> -<% end -%> +<% end -%> +<% end -%> after do |example| example.metadata[:response][:examples] = { 'application/json' => JSON.parse(response.body, symbolize_names: true) } @@ -24,7 +24,7 @@ RSpec.describe '<%= controller_path %>', type: :request do run_test! end end -<% end -%> +<% end -%> end -<% end -%> +<% end -%> end diff --git a/rswag-specs/lib/rspec/rails/swagger/route_parser.rb b/rswag-specs/lib/rspec/rails/swagger/route_parser.rb deleted file mode 100644 index 9ab9513..0000000 --- a/rswag-specs/lib/rspec/rails/swagger/route_parser.rb +++ /dev/null @@ -1,62 +0,0 @@ -module RSpec - module Rails - module Swagger - class RouteParser - attr_reader :controller - - def initialize(controller) - @controller = controller - end - - def routes - ::Rails.application.routes.routes.select do |route| - route.defaults[:controller] == controller - end.reduce({}) do |tree, route| - path = path_from(route) - verb = verb_from(route) - tree[path] ||= { params: params_from(route), actions: {} } - tree[path][:actions][verb] = { summary: summary_from(route) } - tree - end - end - - private - - def path_from(route) - route.path.spec.to_s - .chomp('(.:format)') # Ignore any format suffix - .gsub(/:([^\/.?]+)/, '{\1}') # Convert :id to {id} - end - - def verb_from(route) - verb = route.verb - if verb.kind_of? String - verb.downcase - else - verb.source.gsub(/[$^]/, '').downcase - end - end - - def summary_from(route) - verb = route.requirements[:action] - noun = route.requirements[:controller].split('/').last.singularize - - # Apply a few customizations to make things more readable - case verb - when 'index' - verb = 'list' - noun = noun.pluralize - when 'destroy' - verb = 'delete' - end - - "#{verb} #{noun}" - end - - def params_from(route) - route.segments - ['format'] - end - end - end - end -end diff --git a/rswag-specs/lib/rswag/route_parser.rb b/rswag-specs/lib/rswag/route_parser.rb new file mode 100644 index 0000000..523b36b --- /dev/null +++ b/rswag-specs/lib/rswag/route_parser.rb @@ -0,0 +1,58 @@ +module Rswag + class RouteParser + attr_reader :controller + + def initialize(controller) + @controller = controller + end + + def routes + ::Rails.application.routes.routes.select do |route| + route.defaults[:controller] == controller + end.reduce({}) do |tree, route| + path = path_from(route) + verb = verb_from(route) + tree[path] ||= { params: params_from(route), actions: {} } + tree[path][:actions][verb] = { summary: summary_from(route) } + tree + end + end + + private + + def path_from(route) + route.path.spec.to_s + .chomp('(.:format)') # Ignore any format suffix + .gsub(/:([^\/.?]+)/, '{\1}') # Convert :id to {id} + end + + def verb_from(route) + verb = route.verb + if verb.kind_of? String + verb.downcase + else + verb.source.gsub(/[$^]/, '').downcase + end + end + + def summary_from(route) + verb = route.requirements[:action] + noun = route.requirements[:controller].split('/').last.singularize + + # Apply a few customizations to make things more readable + case verb + when 'index' + verb = 'list' + noun = noun.pluralize + when 'destroy' + verb = 'delete' + end + + "#{verb} #{noun}" + end + + def params_from(route) + route.segments - ['format'] + end + end +end From 4d29e090109e3de9732391b400097afb4afac7eb Mon Sep 17 00:00:00 2001 From: Greg Myers Date: Wed, 16 Oct 2019 23:19:24 +0100 Subject: [PATCH 4/4] Add spec generator test --- .../lib/generators/rspec/templates/spec.rb | 2 +- .../generators/rspec/fixtures/spec/.gitkeep | 0 .../rspec/swagger_generator_spec.rb | 44 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 rswag-specs/spec/generators/rspec/fixtures/spec/.gitkeep create mode 100644 rswag-specs/spec/generators/rspec/swagger_generator_spec.rb diff --git a/rswag-specs/lib/generators/rspec/templates/spec.rb b/rswag-specs/lib/generators/rspec/templates/spec.rb index 0673596..346e348 100644 --- a/rswag-specs/lib/generators/rspec/templates/spec.rb +++ b/rswag-specs/lib/generators/rspec/templates/spec.rb @@ -6,7 +6,7 @@ RSpec.describe '<%= controller_path %>', type: :request do <% unless path_item[:params].empty? -%> # You'll want to customize the parameter types... <% path_item[:params].each do |param| -%> - parameter '<%= param %>', in: :body, type: :string + parameter name: '<%= param %>', in: :path, type: :string, description: '<%= param %>' <% end -%> <% end -%> <% path_item[:actions].each do | action, details | %> diff --git a/rswag-specs/spec/generators/rspec/fixtures/spec/.gitkeep b/rswag-specs/spec/generators/rspec/fixtures/spec/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/rswag-specs/spec/generators/rspec/swagger_generator_spec.rb b/rswag-specs/spec/generators/rspec/swagger_generator_spec.rb new file mode 100644 index 0000000..f11ea65 --- /dev/null +++ b/rswag-specs/spec/generators/rspec/swagger_generator_spec.rb @@ -0,0 +1,44 @@ +require 'generator_spec' +require 'generators/rspec/swagger_generator' +require 'tmpdir' + +module Rspec + describe SwaggerGenerator do + include GeneratorSpec::TestCase + destination Dir.mktmpdir + + before(:all) do + prepare_destination + fixtures_dir = File.expand_path('../fixtures', __FILE__) + FileUtils.cp_r("#{fixtures_dir}/spec", destination_root) + end + + after(:all) do + + end + + it 'installs the swagger_helper for rspec' do + allow_any_instance_of(Rswag::RouteParser).to receive(:routes).and_return(fake_routes) + run_generator ['Posts::CommentsController'] + + assert_file('spec/requests/posts/comments_spec.rb') do |content| + assert_match(/parameter name: 'post_id', in: :path, type: :string/, content) + assert_match(/patch\('update_comments comment'\)/, content) + end + end + + private + + def fake_routes + { + "/posts/{post_id}/comments/{id}" => { + :params => ["post_id", "id"], + :actions => { + "get" => { :summary=>"show comment" }, + "patch" => { :summary=>"update_comments comment" } + } + } + } + end + end +end