Commit e1eb984c by andrew morton Committed by GitHub

Merge pull request #6 from drewish/rename-rspec-rails-swagger

Rename to rspec-rails-swagger
parents c6b2d183 5e1f4157
# RSpec Swagger # RSpec Swagger
[![Build Status](https://travis-ci.org/drewish/rspec-swagger.svg?branch=master)](https://travis-ci.org/drewish/rspec-swagger) [![Build Status](https://travis-ci.org/drewish/rspec-rails-swagger.svg?branch=master)](https://travis-ci.org/drewish/rspec-rails-swagger)
[![Code Climate](https://codeclimate.com/github/drewish/rspec-swagger/badges/gpa.svg)](https://codeclimate.com/github/drewish/rspec-swagger) [![Code Climate](https://codeclimate.com/github/drewish/rspec-rails-swagger/badges/gpa.svg)](https://codeclimate.com/github/drewish/rspec-rails-swagger)
This gem helps you generate Swagger docs by using RSpec to document the paths. This gem helps you generate Swagger docs by using RSpec to document the paths.
You execute a command to run the tests and generate the `.json` output. Running You execute a command to run the tests and generate the `.json` output. Running
...@@ -15,7 +15,7 @@ The design of this was heavily influenced by the awesome [swagger_rails gem](htt ...@@ -15,7 +15,7 @@ The design of this was heavily influenced by the awesome [swagger_rails gem](htt
- Add the gem to your Rails app's `Gemfile`: - Add the gem to your Rails app's `Gemfile`:
```rb ```rb
group :development, :test do group :development, :test do
gem 'rspec-swagger' gem 'rspec-rails-swagger'
end end
``` ```
- If you don't already have a `spec/rails_helper.rb` file run: - If you don't already have a `spec/rails_helper.rb` file run:
...@@ -23,7 +23,7 @@ end ...@@ -23,7 +23,7 @@ end
rails generate rspec:install rails generate rspec:install
``` ```
- Create `spec/swagger_helper.rb` file (eventually [this will become a - Create `spec/swagger_helper.rb` file (eventually [this will become a
generator](https://github.com/drewish/rspec-swagger/issues/3)): generator](https://github.com/drewish/rspec-rails-swagger/issues/3)):
```rb ```rb
require 'rspec/swagger' require 'rspec/swagger'
require 'rails_helper' require 'rails_helper'
...@@ -55,7 +55,7 @@ end ...@@ -55,7 +55,7 @@ end
## Generate the docs ## Generate the docs
Eventually [this will become a rake task](https://github.com/drewish/rspec-swagger/issues/2): Eventually [this will become a rake task](https://github.com/drewish/rspec-rails-swagger/issues/2):
``` ```
bundle exec rspec -f RSpec::Swagger::Formatter --order defined -t swagger_object bundle exec rspec -f RSpec::Swagger::Formatter --order defined -t swagger_object
``` ```
......
require 'rspec/core'
require 'rspec/rails/swagger/configuration'
require 'rspec/rails/swagger/document'
require 'rspec/rails/swagger/formatter'
require 'rspec/rails/swagger/helpers'
require 'rspec/rails/swagger/request_builder'
require 'rspec/rails/swagger/version'
module RSpec
module Rails
module Swagger
initialize_configuration RSpec.configuration
end
end
end
module RSpec module RSpec
module Swagger module Rails
# Fake class to document RSpec Swagger configuration options. module Swagger
class Configuration # Fake class to document RSpec Swagger configuration options.
end class Configuration
end
def self.initialize_configuration(config) def self.initialize_configuration(config)
config.add_setting :swagger_root config.add_setting :swagger_root
config.add_setting :swagger_docs, default: {} config.add_setting :swagger_docs, default: {}
Helpers.add_swagger_type_configurations(config) Helpers.add_swagger_type_configurations(config)
end
end end
end end
end end
module RSpec module RSpec
module Swagger module Rails
class Document module Swagger
attr_accessor :data class Document
attr_accessor :data
def initialize(data) def initialize(data)
@data = data.deep_symbolize_keys @data = data.deep_symbolize_keys
end end
def [](value)
data[value]
end
def resolve_ref(ref) def [](value)
unless %r{#/(?<location>parameters|definitions)/(?<name>.+)} =~ ref data[value]
raise ArgumentError, "Invalid reference: #{ref}"
end end
result = data.fetch(location.to_sym, {})[name.to_sym] def resolve_ref(ref)
raise ArgumentError, "Reference value does not exist: #{ref}" unless result unless %r{#/(?<location>parameters|definitions)/(?<name>.+)} =~ ref
raise ArgumentError, "Invalid reference: #{ref}"
end
if location == 'parameters' result = data.fetch(location.to_sym, {})[name.to_sym]
result.merge(name: name) raise ArgumentError, "Reference value does not exist: #{ref}" unless result
end
if location == 'parameters'
result.merge(name: name)
end
result result
end
end end
end end
end end
......
require 'rspec/core/formatters/base_text_formatter' require 'rspec/core/formatters/base_text_formatter'
module RSpec module RSpec
module Swagger module Rails
class Formatter < RSpec::Core::Formatters::BaseTextFormatter module Swagger
RSpec::Core::Formatters.register self, :example_finished, :close class Formatter < RSpec::Core::Formatters::BaseTextFormatter
RSpec::Core::Formatters.register self, :example_finished, :close
def documents
# We don't try to load the docs in `initalize` because when running def documents
# `rspec -f RSpec::Swagger::Formatter` RSpec initalized this class # We don't try to load the docs in `initalize` because when running
# before `swagger_helper` has run. # `rspec -f RSpec::Swagger::Formatter` RSpec initalized this class
@documents ||= ::RSpec.configuration.swagger_docs # before `swagger_helper` has run.
end @documents ||= ::RSpec.configuration.swagger_docs
end
def example_finished(notification) def example_finished(notification)
metadata = notification.example.metadata metadata = notification.example.metadata
return unless metadata[:swagger_object] == :response return unless metadata[:swagger_object] == :response
# metadata.each do |k, v| # metadata.each do |k, v|
# puts "#{k}\t#{v}" if k.to_s.starts_with?("swagger") # puts "#{k}\t#{v}" if k.to_s.starts_with?("swagger")
# end # end
document = document_for(metadata[:swagger_document]) document = document_for(metadata[:swagger_document])
path_item = path_item_for(document, metadata[:swagger_path_item]) path_item = path_item_for(document, metadata[:swagger_path_item])
operation = operation_for(path_item, metadata[:swagger_operation]) operation = operation_for(path_item, metadata[:swagger_operation])
response_for(operation, metadata[:swagger_response]) response_for(operation, metadata[:swagger_response])
end end
def close(_notification) def close(_notification)
documents.each{|k, v| write_json(k, v)} documents.each{|k, v| write_json(k, v)}
end end
def write_json(name, document) def write_json(name, document)
root = ::RSpec.configuration.swagger_root root = ::RSpec.configuration.swagger_root
# It would be good to at least warn if the name includes some '../' that # It would be good to at least warn if the name includes some '../' that
# takes it out of root directory. # takes it out of root directory.
target = Pathname(name).expand_path(root) target = Pathname(name).expand_path(root)
target.dirname.mkpath target.dirname.mkpath
target.write(JSON.pretty_generate(document)) target.write(JSON.pretty_generate(document))
end end
def document_for(doc_name = nil) def document_for(doc_name = nil)
if doc_name if doc_name
documents.fetch(doc_name) documents.fetch(doc_name)
else else
documents.values.first documents.values.first
end
end end
end
def path_item_for(document, swagger_path_item) def path_item_for(document, swagger_path_item)
name = swagger_path_item[:path] name = swagger_path_item[:path]
document[:paths] ||= {} document[:paths] ||= {}
document[:paths][name] ||= {} document[:paths][name] ||= {}
if swagger_path_item[:parameters] if swagger_path_item[:parameters]
document[:paths][name][:parameters] = prepare_parameters(swagger_path_item[:parameters]) document[:paths][name][:parameters] = prepare_parameters(swagger_path_item[:parameters])
end
document[:paths][name]
end end
document[:paths][name]
end
def operation_for(path, swagger_operation)
method = swagger_operation[:method]
path[method] ||= {responses: {}} def operation_for(path, swagger_operation)
path[method].tap do |operation| method = swagger_operation[:method]
if swagger_operation[:parameters]
operation[:parameters] = prepare_parameters(swagger_operation[:parameters]) path[method] ||= {responses: {}}
path[method].tap do |operation|
if swagger_operation[:parameters]
operation[:parameters] = prepare_parameters(swagger_operation[:parameters])
end
operation.merge!(swagger_operation.slice(
:summary, :description, :externalDocs, :operationId,
:consumes, :produces, :schemes, :deprecated, :security
))
end end
operation.merge!(swagger_operation.slice(
:summary, :description, :externalDocs, :operationId,
:consumes, :produces, :schemes, :deprecated, :security
))
end end
end
def response_for(operation, swagger_response) def response_for(operation, swagger_response)
status = swagger_response[:status_code] status = swagger_response[:status_code]
operation[:responses][status] ||= {} operation[:responses][status] ||= {}
operation[:responses][status].tap do |response| operation[:responses][status].tap do |response|
if swagger_response[:examples] if swagger_response[:examples]
response[:examples] = prepare_examples(swagger_response[:examples]) response[:examples] = prepare_examples(swagger_response[:examples])
end
response.merge!(swagger_response.slice(:description, :schema, :headers))
end end
response.merge!(swagger_response.slice(:description, :schema, :headers))
end end
end
def prepare_parameters(params) def prepare_parameters(params)
params.values params.values
end end
def prepare_examples(examples) def prepare_examples(examples)
if examples["application/json"].present? if examples["application/json"].present?
begin begin
examples["application/json"] = JSON.parse(examples["application/json"]) examples["application/json"] = JSON.parse(examples["application/json"])
rescue JSON::ParserError rescue JSON::ParserError
end
end end
examples
end end
examples
end end
end end
end end
......
module RSpec module RSpec
module Swagger module Rails
module Helpers module Swagger
# paths: (Paths) module Helpers
# /pets: (Path Item) # paths: (Paths)
# post: (Operation) # /pets: (Path Item)
# tags: # post: (Operation)
# - pet # tags:
# summary: Add a new pet to the store # - pet
# description: "" # summary: Add a new pet to the store
# operationId: addPet # description: ""
# consumes: # operationId: addPet
# - application/json # consumes:
# produces: # - application/json
# - application/json # produces:
# parameters: (Parameters) # - application/json
# - in: body # parameters: (Parameters)
# name: body # - in: body
# description: Pet object that needs to be added to the store # name: body
# required: false # description: Pet object that needs to be added to the store
# schema: # required: false
# $ref: "#/definitions/Pet" # schema:
# responses: (Responses) # $ref: "#/definitions/Pet"
# "405": (Response) # responses: (Responses)
# description: Invalid input # "405": (Response)
# description: Invalid input
# The helpers serve as a DSL.
def self.add_swagger_type_configurations(config) # The helpers serve as a DSL.
# The filters are used to ensure that the methods are nested correctly def self.add_swagger_type_configurations(config)
# and following the Swagger schema. # The filters are used to ensure that the methods are nested correctly
config.extend Paths, type: :request # and following the Swagger schema.
config.extend PathItem, swagger_object: :path_item config.extend Paths, type: :request
config.extend Parameters, swagger_object: :path_item config.extend PathItem, swagger_object: :path_item
config.extend Operation, swagger_object: :operation config.extend Parameters, swagger_object: :path_item
config.extend Parameters, swagger_object: :operation config.extend Operation, swagger_object: :operation
config.extend Response, swagger_object: :response config.extend Parameters, swagger_object: :operation
end config.extend Response, swagger_object: :response
end
module Paths module Paths
def path template, attributes = {}, &block def path template, attributes = {}, &block
attributes.symbolize_keys! attributes.symbolize_keys!
raise ArgumentError, "Path must start with a /" unless template.starts_with?('/') raise ArgumentError, "Path must start with a /" unless template.starts_with?('/')
#TODO template might be a $ref #TODO template might be a $ref
meta = { meta = {
swagger_object: :path_item, swagger_object: :path_item,
swagger_document: attributes[:swagger_document] || RSpec.configuration.swagger_docs.keys.first, swagger_document: attributes[:swagger_document] || RSpec.configuration.swagger_docs.keys.first,
swagger_path_item: {path: template} swagger_path_item: {path: template}
} }
describe(template, meta, &block) describe(template, meta, &block)
end
end end
end
module PathItem module PathItem
METHODS = %w(get put post delete options head patch).freeze METHODS = %w(get put post delete options head patch).freeze
def operation method, attributes = {}, &block def operation method, attributes = {}, &block
attributes.symbolize_keys! attributes.symbolize_keys!
method = method.to_s.downcase method = method.to_s.downcase
validate_method! method validate_method! method
meta = { meta = {
swagger_object: :operation, swagger_object: :operation,
swagger_operation: attributes.merge(method: method.to_sym).reject{ |v| v.nil? } swagger_operation: attributes.merge(method: method.to_sym).reject{ |v| v.nil? }
} }
describe(method.to_s, meta, &block) describe(method.to_s, meta, &block)
end end
METHODS.each do |method| METHODS.each do |method|
define_method(method) do |attributes = {}, &block| define_method(method) do |attributes = {}, &block|
operation(method, attributes, &block) operation(method, attributes, &block)
end
end end
end
private private
def validate_method! method def validate_method! method
unless METHODS.include? method.to_s unless METHODS.include? method.to_s
raise ArgumentError, "Operation has an invalid 'method' value. Try: #{METHODS}." raise ArgumentError, "Operation has an invalid 'method' value. Try: #{METHODS}."
end
end end
end end
end
module Parameters module Parameters
def parameter name, attributes = {} def parameter name, attributes = {}
attributes.symbolize_keys! attributes.symbolize_keys!
# Look for $refs # Look for $refs
if name.respond_to?(:has_key?) if name.respond_to?(:has_key?)
ref = name.delete(:ref) || name.delete('ref') ref = name.delete(:ref) || name.delete('ref')
full_param = resolve_document(metadata).resolve_ref(ref) full_param = resolve_document(metadata).resolve_ref(ref)
validate_parameter! full_param validate_parameter! full_param
param = { '$ref' => ref } param = { '$ref' => ref }
key = parameter_key(full_param) key = parameter_key(full_param)
else else
validate_parameter! attributes validate_parameter! attributes
# Path attributes are always required # Path attributes are always required
attributes[:required] = true if attributes[:in] == :path attributes[:required] = true if attributes[:in] == :path
param = { name: name.to_s }.merge(attributes) param = { name: name.to_s }.merge(attributes)
key = parameter_key(param) key = parameter_key(param)
end end
parameters_for_object[key] = param parameters_for_object[key] = param
end end
def resolve_document metadata def resolve_document metadata
# TODO: It's really inefficient to keep recreating this. It'd be nice # TODO: It's really inefficient to keep recreating this. It'd be nice
# if we could cache them some place. # if we could cache them some place.
name = metadata[:swagger_document] name = metadata[:swagger_document]
Document.new(RSpec.configuration.swagger_docs[name]) Document.new(RSpec.configuration.swagger_docs[name])
end end
private private
# This key ensures uniqueness based on the 'name' and 'in' values. # This key ensures uniqueness based on the 'name' and 'in' values.
def parameter_key parameter def parameter_key parameter
"#{parameter[:in]}&#{parameter[:name]}" "#{parameter[:in]}&#{parameter[:name]}"
end end
def parameters_for_object def parameters_for_object
object_key = "swagger_#{metadata[:swagger_object]}".to_sym object_key = "swagger_#{metadata[:swagger_object]}".to_sym
object_data = metadata[object_key] ||= {} object_data = metadata[object_key] ||= {}
object_data[:parameters] ||= {} object_data[:parameters] ||= {}
end end
def validate_parameter! attributes def validate_parameter! attributes
validate_location! attributes[:in] validate_location! attributes[:in]
if attributes[:in].to_s == 'body' if attributes[:in].to_s == 'body'
unless attributes[:schema].present? unless attributes[:schema].present?
raise ArgumentError, "Parameter is missing required 'schema' value." raise ArgumentError, "Parameter is missing required 'schema' value."
end
else
validate_type! attributes[:type]
end end
else
validate_type! attributes[:type]
end end
end
def validate_location! location def validate_location! location
unless location.present? unless location.present?
raise ArgumentError, "Parameter is missing required 'in' value." raise ArgumentError, "Parameter is missing required 'in' value."
end end
locations = %w(query header path formData body) locations = %w(query header path formData body)
unless locations.include? location.to_s unless locations.include? location.to_s
raise ArgumentError, "Parameter has an invalid 'in' value. Try: #{locations}." raise ArgumentError, "Parameter has an invalid 'in' value. Try: #{locations}."
end
end end
end
def validate_type! type def validate_type! type
unless type.present? unless type.present?
raise ArgumentError, "Parameter is missing required 'type' value." raise ArgumentError, "Parameter is missing required 'type' value."
end end
types = %w(string number integer boolean array file) types = %w(string number integer boolean array file)
unless types.include? type.to_s unless types.include? type.to_s
raise ArgumentError, "Parameter has an invalid 'type' value. Try: #{types}." raise ArgumentError, "Parameter has an invalid 'type' value. Try: #{types}."
end
end end
end end
end
module Operation module Operation
def consumes *mime_types def consumes *mime_types
metadata[:swagger_operation][:consumes] = mime_types metadata[:swagger_operation][:consumes] = mime_types
end end
def produces *mime_types def produces *mime_types
metadata[:swagger_operation][:produces] = mime_types metadata[:swagger_operation][:produces] = mime_types
end end
def response status_code, attributes = {}, &block def response status_code, attributes = {}, &block
attributes.symbolize_keys! attributes.symbolize_keys!
validate_status_code! status_code validate_status_code! status_code
validate_description! attributes[:description] validate_description! attributes[:description]
meta = { meta = {
swagger_object: :response, swagger_object: :response,
swagger_response: attributes.merge(status_code: status_code) swagger_response: attributes.merge(status_code: status_code)
} }
describe(status_code, meta) do describe(status_code, meta) do
self.module_exec(&block) if block_given? self.module_exec(&block) if block_given?
# To make a request we need: # To make a request we need:
# - the details we've collected in the metadata # - the details we've collected in the metadata
# - parameter values defined using let() # - parameter values defined using let()
# RSpec tries to limit access to metadata inside of it() / before() # RSpec tries to limit access to metadata inside of it() / before()
# / after() blocks but that scope is the only place you can access # / after() blocks but that scope is the only place you can access
# the let() values. The solution the swagger_rails dev came up with # the let() values. The solution the swagger_rails dev came up with
# is to use the example.metadata passed into the block with the # is to use the example.metadata passed into the block with the
# block's scope which has access to the let() values. # block's scope which has access to the let() values.
before do |example| before do |example|
builder = RequestBuilder.new(example.metadata, self) builder = RequestBuilder.new(example.metadata, self)
method = builder.method method = builder.method
path = [builder.path, builder.query].join path = [builder.path, builder.query].join
headers = builder.headers headers = builder.headers
body = builder.body body = builder.body
# Run the request # Run the request
if ::Rails::VERSION::MAJOR >= 5 if ::Rails::VERSION::MAJOR >= 5
self.send(method, path, {params: body, headers: headers}) self.send(method, path, {params: body, headers: headers})
else else
self.send(method, path, body, headers) self.send(method, path, body, headers)
end
if example.metadata[:capture_examples]
examples = example.metadata[:swagger_response][:examples] ||= {}
examples[response.content_type.to_s] = response.body
end
end end
if example.metadata[:capture_examples] # TODO: see if we can get the caller to show up in the error
examples = example.metadata[:swagger_response][:examples] ||= {} # backtrace for this test.
examples[response.content_type.to_s] = response.body it("returns the correct status code") do
expect(response).to have_http_status(status_code)
end end
end end
# TODO: see if we can get the caller to show up in the error
# backtrace for this test.
it("returns the correct status code") do
expect(response).to have_http_status(status_code)
end
end end
end
private private
def validate_status_code! status_code def validate_status_code! status_code
unless status_code == :default || (100..599).cover?(status_code) unless status_code == :default || (100..599).cover?(status_code)
raise ArgumentError, "status_code must be an integer 100 to 599, or :default" raise ArgumentError, "status_code must be an integer 100 to 599, or :default"
end
end end
end
def validate_description! description def validate_description! description
unless description.present? unless description.present?
raise ArgumentError, "Response is missing required 'description' value." raise ArgumentError, "Response is missing required 'description' value."
end
end end
end end
end
module Response module Response
def capture_example def capture_example
metadata[:capture_examples] = true metadata[:capture_examples] = true
end end
def schema definition def schema definition
definition.symbolize_keys! definition.symbolize_keys!
ref = definition.delete(:ref) ref = definition.delete(:ref)
schema = ref ? { '$ref' => ref } : definition schema = ref ? { '$ref' => ref } : definition
metadata[:swagger_response][:schema] = schema metadata[:swagger_response][:schema] = schema
end
end end
end end
end end
......
module RSpec module RSpec
module Swagger module Rails
class RequestBuilder module Swagger
attr_reader :metadata, :instance class RequestBuilder
attr_reader :metadata, :instance
def initialize(metadata, instance) def initialize(metadata, instance)
@metadata, @instance = metadata, instance @metadata, @instance = metadata, instance
end end
def document def document
@document ||= begin @document ||= begin
name = metadata[:swagger_document] name = metadata[:swagger_document]
Document.new(RSpec.configuration.swagger_docs[name]) Document.new(RSpec.configuration.swagger_docs[name])
end
end end
end
def method def method
metadata[:swagger_operation][:method] metadata[:swagger_operation][:method]
end end
def produces def produces
metadata[:swagger_operation][:produces] || document[:produces] metadata[:swagger_operation][:produces] || document[:produces]
end end
def consumes def consumes
metadata[:swagger_operation][:consumes] || document[:consumes] metadata[:swagger_operation][:consumes] || document[:consumes]
end end
def parameters location = nil def parameters location = nil
path_item = metadata[:swagger_path_item] || {} path_item = metadata[:swagger_path_item] || {}
operation = metadata[:swagger_operation] || {} operation = metadata[:swagger_operation] || {}
params = path_item.fetch(:parameters, {}).merge(operation.fetch(:parameters, {})) params = path_item.fetch(:parameters, {}).merge(operation.fetch(:parameters, {}))
if location.present? if location.present?
params.select{ |k, _| k.starts_with? "#{location}&" } params.select{ |k, _| k.starts_with? "#{location}&" }
else else
params params
end
end end
end
def parameter_values location def parameter_values location
# Don't bother looking at the full parameter bodies since all we need # Don't bother looking at the full parameter bodies since all we need
# are location and name which are in the key. # are location and name which are in the key.
values = parameters(location) values = parameters(location)
.keys .keys
.map{ |k| k.split('&').last } .map{ |k| k.split('&').last }
.map{ |name| [name, instance.send(name)] } .map{ |name| [name, instance.send(name)] }
Hash[values] Hash[values]
end end
def headers def headers
headers = {} headers = {}
# Match the names that Rails uses internally # Match the names that Rails uses internally
headers['HTTP_ACCEPT'] = produces.join(';') if produces.present? headers['HTTP_ACCEPT'] = produces.join(';') if produces.present?
headers['CONTENT_TYPE'] = consumes.first if consumes.present? headers['CONTENT_TYPE'] = consumes.first if consumes.present?
# TODO: do we need to do some capitalization to match the rack # TODO: do we need to do some capitalization to match the rack
# conventions? # conventions?
parameter_values(:header).each { |k, v| headers[k] = v } parameter_values(:header).each { |k, v| headers[k] = v }
headers headers
end end
def path def path
base_path = document[:basePath] || '' base_path = document[:basePath] || ''
# Find params in the path and replace them with values defined in # Find params in the path and replace them with values defined in
# in the example group. # in the example group.
base_path + metadata[:swagger_path_item][:path].gsub(/(\{.*?\})/) do |match| base_path + metadata[:swagger_path_item][:path].gsub(/(\{.*?\})/) do |match|
# QUESTION: Should check that the parameter is actually defined in # QUESTION: Should check that the parameter is actually defined in
# `parameters` before fetch a value? # `parameters` before fetch a value?
instance.send(match[1...-1]) instance.send(match[1...-1])
end
end end
end
def query def query
query_params = parameter_values(:query).to_query query_params = parameter_values(:query).to_query
"?#{query_params}" unless query_params.blank? "?#{query_params}" unless query_params.blank?
end end
def body def body
# And here all we need is the first half of the key to find the body # And here all we need is the first half of the key to find the body
# parameter and its name to fetch a value. # parameter and its name to fetch a value.
if key = parameters(:body).keys.first if key = parameters(:body).keys.first
instance.send(key.split('&').last).to_json instance.send(key.split('&').last).to_json
end
end end
end end
end end
......
module RSpec module RSpec
# Version information for RSpec Swagger. module Rails
module Swagger # Version information for RSpec Swagger.
module Version module Swagger
STRING = '0.1.0' module Version
STRING = '0.1.0'
end
end end
end end
end end
require 'rspec/core'
require 'rspec/swagger/configuration'
require 'rspec/swagger/document'
require 'rspec/swagger/formatter'
require 'rspec/swagger/helpers'
require 'rspec/swagger/request_builder'
require 'rspec/swagger/version'
module RSpec
module Swagger
initialize_configuration RSpec.configuration
end
end
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__) $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
require "rspec/swagger/version" require "rspec/rails/swagger/version"
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = 'rspec-swagger' s.name = 'rspec-rails-swagger'
s.version = RSpec::Swagger::Version::STRING s.version = RSpec::Rails::Swagger::Version::STRING
s.licenses = ['MIT'] s.licenses = ['MIT']
s.summary = "Generate Swagger docs from RSpec integration tests" s.summary = "Generate Swagger docs from RSpec integration tests"
s.description = "Inspired by swagger_rails" s.description = "Inspired by swagger_rails"
s.author = "andrew morton" s.author = "andrew morton"
s.email = 'drewish@katherinehouse.com' s.email = 'drewish@katherinehouse.com'
s.files = [ s.files = [
'lib/rspec/swagger.rb', 'lib/rspec/rails/swagger.rb',
'lib/rspec/swagger/configuration.rb', 'lib/rspec/rails/swagger/configuration.rb',
'lib/rspec/swagger/document.rb', 'lib/rspec/rails/swagger/document.rb',
'lib/rspec/swagger/formatter.rb', 'lib/rspec/rails/swagger/formatter.rb',
'lib/rspec/swagger/helpers.rb', 'lib/rspec/rails/swagger/helpers.rb',
'lib/rspec/swagger/request_builder.rb', 'lib/rspec/rails/swagger/request_builder.rb',
'lib/rspec/swagger/version.rb', 'lib/rspec/rails/swagger/version.rb',
] ]
s.homepage = 'https://github.com/drewish/rspec-swagger' s.homepage = 'https://github.com/drewish/rspec-rails-swagger'
s.required_ruby_version = '~> 2.0' s.required_ruby_version = '~> 2.0'
s.add_runtime_dependency 'rails', '>= 3.1' s.add_runtime_dependency 'rails', '>= 3.1'
......
require 'swagger_helper' require 'swagger_helper'
RSpec.describe RSpec::Swagger::Document do RSpec.describe RSpec::Rails::Swagger::Document do
subject { described_class.new(data) } subject { described_class.new(data) }
let(:data) { minimial_example } let(:data) { minimial_example }
...@@ -53,10 +53,10 @@ RSpec.describe RSpec::Swagger::Document do ...@@ -53,10 +53,10 @@ RSpec.describe RSpec::Swagger::Document do
end end
def minimial_example def minimial_example
YAML.load_file(File.expand_path('../../../fixtures/files/minimal.yml', __FILE__)) YAML.load_file(File.expand_path('../../../../fixtures/files/minimal.yml', __FILE__))
end end
def instagram_example def instagram_example
YAML.load_file(File.expand_path('../../../fixtures/files/instagram.yml', __FILE__)) YAML.load_file(File.expand_path('../../../../fixtures/files/instagram.yml', __FILE__))
end end
end end
require 'swagger_helper' require 'swagger_helper'
RSpec.describe RSpec::Swagger::Formatter do RSpec.describe RSpec::Rails::Swagger::Formatter do
let(:output) { StringIO.new } let(:output) { StringIO.new }
let(:formatter) { described_class.new(output) } let(:formatter) { described_class.new(output) }
let(:documents) { {'minimal.json' => minimal} } let(:documents) { {'minimal.json' => minimal} }
......
require 'swagger_helper' require 'swagger_helper'
RSpec.describe RSpec::Swagger::Helpers::Paths do RSpec.describe RSpec::Rails::Swagger::Helpers::Paths do
let(:klass) do let(:klass) do
Class.new do Class.new do
include RSpec::Swagger::Helpers::Paths include RSpec::Rails::Swagger::Helpers::Paths
attr_accessor :metadata attr_accessor :metadata
def describe *args ; end def describe *args ; end
end end
...@@ -36,10 +36,10 @@ RSpec.describe RSpec::Swagger::Helpers::Paths do ...@@ -36,10 +36,10 @@ RSpec.describe RSpec::Swagger::Helpers::Paths do
end end
end end
RSpec.describe RSpec::Swagger::Helpers::PathItem do RSpec.describe RSpec::Rails::Swagger::Helpers::PathItem do
let(:klass) do let(:klass) do
Class.new do Class.new do
include RSpec::Swagger::Helpers::PathItem include RSpec::Rails::Swagger::Helpers::PathItem
attr_accessor :metadata attr_accessor :metadata
def describe *args ; end def describe *args ; end
end end
...@@ -97,10 +97,10 @@ RSpec.describe RSpec::Swagger::Helpers::PathItem do ...@@ -97,10 +97,10 @@ RSpec.describe RSpec::Swagger::Helpers::PathItem do
end end
end end
RSpec.describe RSpec::Swagger::Helpers::Parameters do RSpec.describe RSpec::Rails::Swagger::Helpers::Parameters do
let(:klass) do let(:klass) do
Class.new do Class.new do
include RSpec::Swagger::Helpers::Parameters include RSpec::Rails::Swagger::Helpers::Parameters
attr_accessor :metadata attr_accessor :metadata
def describe *args ; end def describe *args ; end
def resolve_document *args ; end def resolve_document *args ; end
...@@ -176,10 +176,10 @@ RSpec.describe RSpec::Swagger::Helpers::Parameters do ...@@ -176,10 +176,10 @@ RSpec.describe RSpec::Swagger::Helpers::Parameters do
end end
RSpec.describe RSpec::Swagger::Helpers::Operation do RSpec.describe RSpec::Rails::Swagger::Helpers::Operation do
let(:klass) do let(:klass) do
Class.new do Class.new do
include RSpec::Swagger::Helpers::Operation include RSpec::Rails::Swagger::Helpers::Operation
attr_accessor :metadata attr_accessor :metadata
def describe *args ; end def describe *args ; end
end end
...@@ -207,10 +207,10 @@ RSpec.describe RSpec::Swagger::Helpers::Operation do ...@@ -207,10 +207,10 @@ RSpec.describe RSpec::Swagger::Helpers::Operation do
end end
end end
RSpec.describe RSpec::Swagger::Helpers::Response do RSpec.describe RSpec::Rails::Swagger::Helpers::Response do
let(:klass) do let(:klass) do
Class.new do Class.new do
include RSpec::Swagger::Helpers::Response include RSpec::Rails::Swagger::Helpers::Response
attr_accessor :metadata attr_accessor :metadata
def describe *args ; end def describe *args ; end
end end
......
require 'swagger_helper' require 'swagger_helper'
RSpec.describe RSpec::Swagger::RequestBuilder do RSpec.describe RSpec::Rails::Swagger::RequestBuilder do
describe '#initialize' do describe '#initialize' do
it 'stores metadata and instance' do it 'stores metadata and instance' do
metadata = { foo: :bar } metadata = { foo: :bar }
......
require 'swagger_helper' require 'swagger_helper'
RSpec.describe RSpec::Swagger do RSpec.describe RSpec::Rails::Swagger do
it "loads" do it "loads" do
expect(RSpec::Swagger::Version::STRING).to eq '0.1.0' expect(RSpec::Rails::Swagger::Version::STRING).to eq '0.1.0'
end end
end end
require 'rspec/swagger' require 'rspec/rails/swagger'
# This file was generated by the `rspec --init` command. Conventionally, all # This file was generated by the `rspec --init` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
......
require 'rspec/swagger' require 'rspec/rails/swagger'
require 'rails_helper' require 'rails_helper'
RSpec.configure do |config| RSpec.configure do |config|
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment