mirror of
https://github.com/ditkrg/rswag.git
synced 2026-01-23 06:16:42 +00:00
Merge pull request #245 from BookOfGreg/feature/spec_generator
Feature/spec generator
This commit is contained in:
commit
47eb1e49ee
@ -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
|
||||
22
rswag-specs/lib/generators/rspec/swagger_generator.rb
Normal file
22
rswag-specs/lib/generators/rspec/swagger_generator.rb
Normal file
@ -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
|
||||
@ -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| -%>
|
||||
parameter '<%= param %>', in: :body, type: :string
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% path_item[:actions].each do | action, details | -%>
|
||||
<% path_item[:params].each do |param| -%>
|
||||
parameter name: '<%= param %>', in: :path, type: :string, description: '<%= param %>'
|
||||
<% 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
|
||||
@ -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
|
||||
58
rswag-specs/lib/rswag/route_parser.rb
Normal file
58
rswag-specs/lib/rswag/route_parser.rb
Normal file
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 ]
|
||||
|
||||
44
rswag-specs/spec/generators/rspec/swagger_generator_spec.rb
Normal file
44
rswag-specs/spec/generators/rspec/swagger_generator_spec.rb
Normal file
@ -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
|
||||
Loading…
Reference in New Issue
Block a user