Merge pull request #2 from hdpuk86/merge-master-fork

Merge master fork
This commit is contained in:
Hayley Prior 2019-10-24 21:34:04 +01:00 committed by GitHub
commit 2e9015dd12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 317 additions and 37 deletions

17
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,17 @@
## Describe the bug
A clear and concise description of what the bug is.
## Steps to Test or Reproduce
Please provide an example repo or the steps to reproduce the behavior.
## Expected behavior
A clear and concise description of what you expected to happen.
## Screenshots
If applicable, add screenshots to help explain your problem.
## Additional context
Add any other context about the problem here.
## Rswag Version
The version of rswag are you using.

View File

@ -0,0 +1,11 @@
## Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is.
## Describe the solution you'd like
A clear and concise description of what you want to happen.
## Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
## Additional context
Add any other context or screenshots about the feature request here.

View File

@ -0,0 +1,15 @@
## Problem
A clear and concise description of what the problem is.
## Solution
A clear and concise description of what the solution is.
### Related Issues
Links to any related issues.
### Checklist
- [ ] Added tests
- [ ] Changelog updated
### Steps to Test or Reproduce
Outline the steps to test or reproduce the PR here.

View File

@ -13,15 +13,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### Fixed
### Security ### Security
## [2.1.0] - 2019-10-17
### Added
- New Spec Generator [#75](https://github.com/rswag/rswag/pull/75)
- Support for Options and Trace verbs; You must use a framework that supports this, for Options Rails 6.1+ Rails 6 does not support Trace. [#237](https://github.com/rswag/rswag/pull/75)
### Changed
- Update swagger-ui to 3.18.2 [#240](https://github.com/rswag/rswag/pull/240)
## [2.0.6] - 2019-10-03 ## [2.0.6] - 2019-10-03
### Added ### Added
- Support for Rails 6 [#228](https://github.com/rswag/rswag/pull/228) - Support for Rails 6 [#228](https://github.com/rswag/rswag/pull/228)
- Support for Windows paths [#176](https://github.com/rswag/rswag/pull/176) - Support for Windows paths [#176](https://github.com/rswag/rswag/pull/176)
### Changed ### Changed
- Show response body when error code is not expected [#117](https://github.com/rswag/rswag/pull/177) - Show response body when error code is not expected [#117](https://github.com/rswag/rswag/pull/177)
### Deprecated
### Removed
### Fixed
### Security
## [2.0.5] - 2018-07-10 ## [2.0.5] - 2018-07-10

View File

@ -1,6 +1,7 @@
rswag rswag
========= =========
[![Build Status](https://travis-ci.org/rswag/rswag.svg?branch=master)](https://travis-ci.org/rswag/rswag) [![Build Status](https://travis-ci.org/rswag/rswag.svg?branch=master)](https://travis-ci.org/rswag/rswag)
[![Maintainability](https://api.codeclimate.com/v1/badges/1175b984edc4610f82ab/maintainability)](https://codeclimate.com/github/rswag/rswag/maintainability)
[Swagger](http://swagger.io) tooling for Rails API's. Generate beautiful API documentation, including a UI to explore and test operations, directly from your rspec integration tests. [Swagger](http://swagger.io) tooling for Rails API's. Generate beautiful API documentation, including a UI to explore and test operations, directly from your rspec integration tests.
@ -14,8 +15,8 @@ Once you have an API that can describe itself in Swagger, you've opened the trea
|Rswag Version|Swagger (OpenAPI) Spec.|swagger-ui| |Rswag Version|Swagger (OpenAPI) Spec.|swagger-ui|
|----------|----------|----------| |----------|----------|----------|
|[master](https://github.com/rswag/rswag/tree/master)|2.0|3.23.11| |[master](https://github.com/rswag/rswag/tree/master)|2.0|3.18.2|
|[2.0.6](https://github.com/rswag/rswag/tree/2.0.6)|2.0|3.17.3| |[2.1.1](https://github.com/rswag/rswag/tree/2.1.1)|2.0|3.18.2|
|[1.6.0](https://github.com/rswag/rswag/tree/1.6.0)|2.0|2.2.5| |[1.6.0](https://github.com/rswag/rswag/tree/1.6.0)|2.0|2.2.5|
## Getting Started ## ## Getting Started ##
@ -26,14 +27,15 @@ Once you have an API that can describe itself in Swagger, you've opened the trea
gem 'rswag' gem 'rswag'
``` ```
or if you like to avoid loading rspec in other bundler groups. or if you like to avoid loading rspec in other bundler groups load the rswag-specs component separately.
Note: Adding it to the :development group is not strictly necessary, but without it, generators and rake tasks must be preceded by RAILS_ENV=test.
```ruby ```ruby
# Gemfile # Gemfile
gem 'rswag-api' gem 'rswag-api'
gem 'rswag-ui' gem 'rswag-ui'
group :test do group :development, :test do
gem 'rspec-rails' gem 'rspec-rails'
gem 'rswag-specs' gem 'rswag-specs'
end end
@ -48,7 +50,8 @@ Once you have an API that can describe itself in Swagger, you've opened the trea
Or run the install generators for each package separately if you installed Rswag as separate gems, as indicated above: Or run the install generators for each package separately if you installed Rswag as separate gems, as indicated above:
```ruby ```ruby
rails g rswag:api:install rswag:ui:install rails g rswag:api:install
rails g rswag:ui:install
RAILS_ENV=test rails g rswag:specs:install RAILS_ENV=test rails g rswag:specs:install
``` ```
@ -126,6 +129,8 @@ Once you have an API that can describe itself in Swagger, you've opened the trea
rake rswag:specs:swaggerize rake rswag:specs:swaggerize
``` ```
This common command is also aliased as `rake rswag`.
5. Spin up your app and check out the awesome, auto-generated docs at _/api-docs_! 5. Spin up your app and check out the awesome, auto-generated docs at _/api-docs_!
## The rspec DSL ## ## The rspec DSL ##

10
node_modules/.yarn-integrity generated vendored Normal file
View File

@ -0,0 +1,10 @@
{
"systemParams": "darwin-x64-72",
"modulesFolders": [],
"flags": [],
"linkedModules": [],
"topLevelPatterns": [],
"lockfileEntries": {},
"files": [],
"artifacts": {}
}

View File

@ -1,4 +1,5 @@
require 'json' require 'json'
require 'yaml'
module Rswag module Rswag
module Api module Api
@ -14,7 +15,7 @@ module Rswag
filename = "#{@config.resolve_swagger_root(env)}/#{path}" filename = "#{@config.resolve_swagger_root(env)}/#{path}"
if env['REQUEST_METHOD'] == 'GET' && File.file?(filename) if env['REQUEST_METHOD'] == 'GET' && File.file?(filename)
swagger = load_json(filename) swagger = parse_file(filename)
@config.swagger_filter.call(swagger, env) unless @config.swagger_filter.nil? @config.swagger_filter.call(swagger, env) unless @config.swagger_filter.nil?
return [ return [
@ -29,6 +30,18 @@ module Rswag
private private
def parse_file(filename)
if /\.ya?ml$/ === filename
load_yaml(filename)
else
load_json(filename)
end
end
def load_yaml(filename)
YAML.safe_load(File.read(filename))
end
def load_json(filename) def load_json(filename)
JSON.parse(File.read(filename)) JSON.parse(File.read(filename))
end end

View File

@ -0,0 +1,5 @@
swagger: '2.0'
info:
title: API V1
version: v1
paths: {}

View File

@ -76,6 +76,21 @@ module Rswag
expect(response[2].join).to include('"host":"tempuri.org"') expect(response[2].join).to include('"host":"tempuri.org"')
end end
end end
context 'when a path maps to a yaml swagger file' do
let(:env) { env_defaults.merge('PATH_INFO' => 'v1/swagger.yml') }
it 'returns a 200 status' do
expect(response.length).to eql(3)
expect(response.first).to eql('200')
end
it 'returns contents of the swagger file' do
expect(response.length).to eql(3)
expect(response[1]).to include( 'Content-Type' => 'application/json')
expect(response[2].join).to include('"title":"API V1"')
end
end
end end
end end
end end

View File

@ -0,0 +1,9 @@
Description:
This creates an RSpec request spec to define Swagger documentation for a
controller. It will create a test for each of the controller's methods.
Example:
rails generate rspec:swagger V3::AccountsController
This will create:
spec/requests/v3/accounts_spec.rb

View 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

View File

@ -0,0 +1,30 @@
require 'swagger_helper'
RSpec.describe '<%= controller_path %>', type: :request do
<% @routes.each do | template, path_item | %>
path '<%= template %>' do
<% unless path_item[:params].empty? -%>
# You'll want to customize the parameter types...
<% 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| -%>
let(:<%= param %>) { '123' }
<% end -%>
<% end -%>
after do |example|
example.metadata[:response][:examples] = { 'application/json' => JSON.parse(response.body, symbolize_names: true) }
end
run_test!
end
end
<% end -%>
end
<% end -%>
end

View 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

View File

@ -5,6 +5,10 @@ module Rswag
rake_tasks do rake_tasks do
load File.expand_path('../../../tasks/rswag-specs_tasks.rake', __FILE__) load File.expand_path('../../../tasks/rswag-specs_tasks.rake', __FILE__)
end end
generators do
require 'generators/rspec/swagger_generator.rb'
end
end end
end end
end end

View File

@ -16,3 +16,6 @@ namespace :rswag do
end end
end end
end end
task :rswag => ['rswag:specs:swaggerize']

View 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

View File

@ -4,7 +4,7 @@ require 'generators/rswag/specs/install/install_generator'
module Rswag module Rswag
module Specs module Specs
describe InstallGenerator do RSpec.describe InstallGenerator do
include GeneratorSpec::TestCase include GeneratorSpec::TestCase
destination File.expand_path('../tmp', __FILE__) destination File.expand_path('../tmp', __FILE__)

View File

@ -3,7 +3,7 @@ require 'rswag/specs/configuration'
module Rswag module Rswag
module Specs module Specs
describe Configuration do RSpec.describe Configuration do
subject { described_class.new(rspec_config) } subject { described_class.new(rspec_config) }
let(:rspec_config) { OpenStruct.new(swagger_root: swagger_root, swagger_docs: swagger_docs) } let(:rspec_config) { OpenStruct.new(swagger_root: swagger_root, swagger_docs: swagger_docs) }

View File

@ -3,7 +3,7 @@ require 'rswag/specs/example_group_helpers'
module Rswag module Rswag
module Specs module Specs
describe ExampleGroupHelpers do RSpec.describe ExampleGroupHelpers do
subject { double('example_group') } subject { double('example_group') }
before do before do

View File

@ -3,7 +3,7 @@ require 'rswag/specs/example_helpers'
module Rswag module Rswag
module Specs module Specs
describe ExampleHelpers do RSpec.describe ExampleHelpers do
subject { double('example') } subject { double('example') }
before do before do

View File

@ -3,7 +3,7 @@ require 'rswag/specs/request_factory'
module Rswag module Rswag
module Specs module Specs
describe RequestFactory do RSpec.describe RequestFactory do
subject { RequestFactory.new(config) } subject { RequestFactory.new(config) }
before do before do

View File

@ -3,7 +3,7 @@ require 'rswag/specs/response_validator'
module Rswag module Rswag
module Specs module Specs
describe ResponseValidator do RSpec.describe ResponseValidator do
subject { ResponseValidator.new(config) } subject { ResponseValidator.new(config) }
before do before do

View File

@ -4,7 +4,7 @@ require 'ostruct'
module Rswag module Rswag
module Specs module Specs
describe SwaggerFormatter do RSpec.describe SwaggerFormatter do
subject { described_class.new(output, config) } subject { described_class.new(output, config) }
# Mock out some infrastructure # Mock out some infrastructure

View File

@ -5,9 +5,15 @@
"requires": true, "requires": true,
"dependencies": { "dependencies": {
"swagger-ui-dist": { "swagger-ui-dist": {
<<<<<<< HEAD
"version": "3.23.11", "version": "3.23.11",
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.23.11.tgz", "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.23.11.tgz",
"integrity": "sha512-ipENHHH/sqpngTpHXUwg55eAOZ7b2UVayUwwuWPA6nQSPhjBVXX4zOPpNKUwQIFOl3oIwVvZF7mqoxH7pMgVzA==" "integrity": "sha512-ipENHHH/sqpngTpHXUwg55eAOZ7b2UVayUwwuWPA6nQSPhjBVXX4zOPpNKUwQIFOl3oIwVvZF7mqoxH7pMgVzA=="
=======
"version": "3.18.2",
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.18.2.tgz",
"integrity": "sha512-pWAEiKkgWUJvjmLW9AojudnutJ+NTn5g6OdNLj1iIJWwCkoy40K3Upwa24DqFbmIE4vLX4XplND61hp2L+s5vg=="
>>>>>>> origin/master
} }
} }
} }

View File

@ -3,6 +3,10 @@
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
<<<<<<< HEAD
"swagger-ui-dist": "3.23.11" "swagger-ui-dist": "3.23.11"
=======
"swagger-ui-dist": "3.18.2"
>>>>>>> origin/master
} }
} }

View File

@ -0,0 +1,2 @@
//= link_tree ../images
//= link_directory ../stylesheets .css

View File

View File

@ -1,6 +1,6 @@
require 'rails_helper' require 'rails_helper'
feature 'swagger-ui', js: true do RSpec.feature 'swagger-ui', js: true do
scenario 'browsing api-docs' do scenario 'browsing api-docs' do
visit '/api-docs' visit '/api-docs'

View File

@ -1,6 +1,6 @@
require 'swagger_helper' require 'swagger_helper'
describe 'Auth Tests API', type: :request, swagger_doc: 'v1/swagger.json' do RSpec.describe 'Auth Tests API', type: :request, swagger_doc: 'v1/swagger.json' do
path '/auth-tests/basic' do path '/auth-tests/basic' do
post 'Authenticates with basic auth' do post 'Authenticates with basic auth' do

View File

@ -1,6 +1,6 @@
require 'swagger_helper' require 'swagger_helper'
describe 'Blogs API', type: :request, swagger_doc: 'v1/swagger.json' do RSpec.describe 'Blogs API', type: :request, swagger_doc: 'v1/swagger.json' do
let(:api_key) { 'fake_key' } let(:api_key) { 'fake_key' }
path '/blogs' do path '/blogs' do

View File

@ -1,7 +1,7 @@
require 'spec_helper' require 'spec_helper'
require 'rake' require 'rake'
describe 'rswag:specs:swaggerize' do RSpec.describe 'rswag:specs:swaggerize' do
let(:swagger_root) { Rails.root.to_s + '/swagger' } let(:swagger_root) { Rails.root.to_s + '/swagger' }
before do before do
TestApp::Application.load_tasks TestApp::Application.load_tasks

4
yarn.lock Normal file
View File

@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1