rspec-rails-swagger 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/rspec/rails/swagger.rb +16 -0
- data/lib/rspec/rails/swagger/configuration.rb +16 -0
- data/lib/rspec/rails/swagger/document.rb +32 -0
- data/lib/rspec/rails/swagger/formatter.rb +105 -0
- data/lib/rspec/rails/swagger/helpers.rb +258 -0
- data/lib/rspec/rails/swagger/request_builder.rb +91 -0
- data/lib/rspec/rails/swagger/version.rb +10 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ee3d27df0e7ec24ced93bd4a298f649b86715b12
|
4
|
+
data.tar.gz: 0e96a4167c43c555b94b81d93901939311e0dd98
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 217c592d0a3331819d7264a7356885ec3e69d8cc075aa7a6f98e524f5dcf96466adefefd16214772abdbd42a494f5df78d4bc3e6cc1482f86c797d3f12bc0c35
|
7
|
+
data.tar.gz: d9b5651ac3f9c4a76c09ca9efce6e0f671f4c5264c79dfaa0356ada5e7f13c18cdf1336352a7e8f0a9a70fb45cd427f1fd591015d755c63442c85d359f86eb66
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rspec/core'
|
2
|
+
require 'rspec/rails/swagger/configuration'
|
3
|
+
require 'rspec/rails/swagger/document'
|
4
|
+
require 'rspec/rails/swagger/formatter'
|
5
|
+
require 'rspec/rails/swagger/helpers'
|
6
|
+
require 'rspec/rails/swagger/request_builder'
|
7
|
+
require 'rspec/rails/swagger/version'
|
8
|
+
|
9
|
+
module RSpec
|
10
|
+
module Rails
|
11
|
+
module Swagger
|
12
|
+
initialize_configuration RSpec.configuration
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Rails
|
3
|
+
module Swagger
|
4
|
+
# Fake class to document RSpec Swagger configuration options.
|
5
|
+
class Configuration
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.initialize_configuration(config)
|
9
|
+
config.add_setting :swagger_root
|
10
|
+
config.add_setting :swagger_docs, default: {}
|
11
|
+
|
12
|
+
Helpers.add_swagger_type_configurations(config)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Rails
|
3
|
+
module Swagger
|
4
|
+
class Document
|
5
|
+
attr_accessor :data
|
6
|
+
|
7
|
+
def initialize(data)
|
8
|
+
@data = data.deep_symbolize_keys
|
9
|
+
end
|
10
|
+
|
11
|
+
def [](value)
|
12
|
+
data[value]
|
13
|
+
end
|
14
|
+
|
15
|
+
def resolve_ref(ref)
|
16
|
+
unless %r{#/(?<location>parameters|definitions)/(?<name>.+)} =~ ref
|
17
|
+
raise ArgumentError, "Invalid reference: #{ref}"
|
18
|
+
end
|
19
|
+
|
20
|
+
result = data.fetch(location.to_sym, {})[name.to_sym]
|
21
|
+
raise ArgumentError, "Reference value does not exist: #{ref}" unless result
|
22
|
+
|
23
|
+
if location == 'parameters'
|
24
|
+
result.merge(name: name)
|
25
|
+
end
|
26
|
+
|
27
|
+
result
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'rspec/core/formatters/base_text_formatter'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Rails
|
5
|
+
module Swagger
|
6
|
+
class Formatter < RSpec::Core::Formatters::BaseTextFormatter
|
7
|
+
RSpec::Core::Formatters.register self, :example_finished, :close
|
8
|
+
|
9
|
+
def documents
|
10
|
+
# We don't try to load the docs in `initalize` because when running
|
11
|
+
# `rspec -f RSpec::Swagger::Formatter` RSpec initalized this class
|
12
|
+
# before `swagger_helper` has run.
|
13
|
+
@documents ||= ::RSpec.configuration.swagger_docs
|
14
|
+
end
|
15
|
+
|
16
|
+
def example_finished(notification)
|
17
|
+
metadata = notification.example.metadata
|
18
|
+
return unless metadata[:swagger_object] == :response
|
19
|
+
|
20
|
+
# metadata.each do |k, v|
|
21
|
+
# puts "#{k}\t#{v}" if k.to_s.starts_with?("swagger")
|
22
|
+
# end
|
23
|
+
|
24
|
+
document = document_for(metadata[:swagger_document])
|
25
|
+
path_item = path_item_for(document, metadata[:swagger_path_item])
|
26
|
+
operation = operation_for(path_item, metadata[:swagger_operation])
|
27
|
+
response_for(operation, metadata[:swagger_response])
|
28
|
+
end
|
29
|
+
|
30
|
+
def close(_notification)
|
31
|
+
documents.each{|k, v| write_json(k, v)}
|
32
|
+
end
|
33
|
+
|
34
|
+
def write_json(name, document)
|
35
|
+
root = ::RSpec.configuration.swagger_root
|
36
|
+
# It would be good to at least warn if the name includes some '../' that
|
37
|
+
# takes it out of root directory.
|
38
|
+
target = Pathname(name).expand_path(root)
|
39
|
+
target.dirname.mkpath
|
40
|
+
target.write(JSON.pretty_generate(document))
|
41
|
+
end
|
42
|
+
|
43
|
+
def document_for(doc_name = nil)
|
44
|
+
if doc_name
|
45
|
+
documents.fetch(doc_name)
|
46
|
+
else
|
47
|
+
documents.values.first
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def path_item_for(document, swagger_path_item)
|
52
|
+
name = swagger_path_item[:path]
|
53
|
+
|
54
|
+
document[:paths] ||= {}
|
55
|
+
document[:paths][name] ||= {}
|
56
|
+
if swagger_path_item[:parameters]
|
57
|
+
document[:paths][name][:parameters] = prepare_parameters(swagger_path_item[:parameters])
|
58
|
+
end
|
59
|
+
document[:paths][name]
|
60
|
+
end
|
61
|
+
|
62
|
+
def operation_for(path, swagger_operation)
|
63
|
+
method = swagger_operation[:method]
|
64
|
+
|
65
|
+
path[method] ||= {responses: {}}
|
66
|
+
path[method].tap do |operation|
|
67
|
+
if swagger_operation[:parameters]
|
68
|
+
operation[:parameters] = prepare_parameters(swagger_operation[:parameters])
|
69
|
+
end
|
70
|
+
operation.merge!(swagger_operation.slice(
|
71
|
+
:summary, :description, :externalDocs, :operationId,
|
72
|
+
:consumes, :produces, :schemes, :deprecated, :security
|
73
|
+
))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def response_for(operation, swagger_response)
|
78
|
+
status = swagger_response[:status_code]
|
79
|
+
|
80
|
+
operation[:responses][status] ||= {}
|
81
|
+
operation[:responses][status].tap do |response|
|
82
|
+
if swagger_response[:examples]
|
83
|
+
response[:examples] = prepare_examples(swagger_response[:examples])
|
84
|
+
end
|
85
|
+
response.merge!(swagger_response.slice(:description, :schema, :headers))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def prepare_parameters(params)
|
90
|
+
params.values
|
91
|
+
end
|
92
|
+
|
93
|
+
def prepare_examples(examples)
|
94
|
+
if examples["application/json"].present?
|
95
|
+
begin
|
96
|
+
examples["application/json"] = JSON.parse(examples["application/json"])
|
97
|
+
rescue JSON::ParserError
|
98
|
+
end
|
99
|
+
end
|
100
|
+
examples
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,258 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Rails
|
3
|
+
module Swagger
|
4
|
+
module Helpers
|
5
|
+
# paths: (Paths)
|
6
|
+
# /pets: (Path Item)
|
7
|
+
# post: (Operation)
|
8
|
+
# tags:
|
9
|
+
# - pet
|
10
|
+
# summary: Add a new pet to the store
|
11
|
+
# description: ""
|
12
|
+
# operationId: addPet
|
13
|
+
# consumes:
|
14
|
+
# - application/json
|
15
|
+
# produces:
|
16
|
+
# - application/json
|
17
|
+
# parameters: (Parameters)
|
18
|
+
# - in: body
|
19
|
+
# name: body
|
20
|
+
# description: Pet object that needs to be added to the store
|
21
|
+
# required: false
|
22
|
+
# schema:
|
23
|
+
# $ref: "#/definitions/Pet"
|
24
|
+
# responses: (Responses)
|
25
|
+
# "405": (Response)
|
26
|
+
# description: Invalid input
|
27
|
+
|
28
|
+
# The helpers serve as a DSL.
|
29
|
+
def self.add_swagger_type_configurations(config)
|
30
|
+
# The filters are used to ensure that the methods are nested correctly
|
31
|
+
# and following the Swagger schema.
|
32
|
+
config.extend Paths, type: :request
|
33
|
+
config.extend PathItem, swagger_object: :path_item
|
34
|
+
config.extend Parameters, swagger_object: :path_item
|
35
|
+
config.extend Operation, swagger_object: :operation
|
36
|
+
config.extend Parameters, swagger_object: :operation
|
37
|
+
config.extend Response, swagger_object: :response
|
38
|
+
end
|
39
|
+
|
40
|
+
module Paths
|
41
|
+
def path template, attributes = {}, &block
|
42
|
+
attributes.symbolize_keys!
|
43
|
+
|
44
|
+
raise ArgumentError, "Path must start with a /" unless template.starts_with?('/')
|
45
|
+
|
46
|
+
#TODO template might be a $ref
|
47
|
+
meta = {
|
48
|
+
swagger_object: :path_item,
|
49
|
+
swagger_document: attributes[:swagger_document] || RSpec.configuration.swagger_docs.keys.first,
|
50
|
+
swagger_path_item: {path: template}
|
51
|
+
}
|
52
|
+
describe(template, meta, &block)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
module PathItem
|
57
|
+
METHODS = %w(get put post delete options head patch).freeze
|
58
|
+
|
59
|
+
def operation method, attributes = {}, &block
|
60
|
+
attributes.symbolize_keys!
|
61
|
+
|
62
|
+
method = method.to_s.downcase
|
63
|
+
validate_method! method
|
64
|
+
|
65
|
+
meta = {
|
66
|
+
swagger_object: :operation,
|
67
|
+
swagger_operation: attributes.merge(method: method.to_sym).reject{ |v| v.nil? }
|
68
|
+
}
|
69
|
+
describe(method.to_s, meta, &block)
|
70
|
+
end
|
71
|
+
|
72
|
+
METHODS.each do |method|
|
73
|
+
define_method(method) do |attributes = {}, &block|
|
74
|
+
operation(method, attributes, &block)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def validate_method! method
|
81
|
+
unless METHODS.include? method.to_s
|
82
|
+
raise ArgumentError, "Operation has an invalid 'method' value. Try: #{METHODS}."
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
module Parameters
|
88
|
+
def parameter name, attributes = {}
|
89
|
+
attributes.symbolize_keys!
|
90
|
+
|
91
|
+
# Look for $refs
|
92
|
+
if name.respond_to?(:has_key?)
|
93
|
+
ref = name.delete(:ref) || name.delete('ref')
|
94
|
+
full_param = resolve_document(metadata).resolve_ref(ref)
|
95
|
+
|
96
|
+
validate_parameter! full_param
|
97
|
+
|
98
|
+
param = { '$ref' => ref }
|
99
|
+
key = parameter_key(full_param)
|
100
|
+
else
|
101
|
+
validate_parameter! attributes
|
102
|
+
|
103
|
+
# Path attributes are always required
|
104
|
+
attributes[:required] = true if attributes[:in] == :path
|
105
|
+
|
106
|
+
param = { name: name.to_s }.merge(attributes)
|
107
|
+
key = parameter_key(param)
|
108
|
+
end
|
109
|
+
|
110
|
+
parameters_for_object[key] = param
|
111
|
+
end
|
112
|
+
|
113
|
+
def resolve_document metadata
|
114
|
+
# TODO: It's really inefficient to keep recreating this. It'd be nice
|
115
|
+
# if we could cache them some place.
|
116
|
+
name = metadata[:swagger_document]
|
117
|
+
Document.new(RSpec.configuration.swagger_docs[name])
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
# This key ensures uniqueness based on the 'name' and 'in' values.
|
123
|
+
def parameter_key parameter
|
124
|
+
"#{parameter[:in]}&#{parameter[:name]}"
|
125
|
+
end
|
126
|
+
|
127
|
+
def parameters_for_object
|
128
|
+
object_key = "swagger_#{metadata[:swagger_object]}".to_sym
|
129
|
+
object_data = metadata[object_key] ||= {}
|
130
|
+
object_data[:parameters] ||= {}
|
131
|
+
end
|
132
|
+
|
133
|
+
def validate_parameter! attributes
|
134
|
+
validate_location! attributes[:in]
|
135
|
+
|
136
|
+
if attributes[:in].to_s == 'body'
|
137
|
+
unless attributes[:schema].present?
|
138
|
+
raise ArgumentError, "Parameter is missing required 'schema' value."
|
139
|
+
end
|
140
|
+
else
|
141
|
+
validate_type! attributes[:type]
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def validate_location! location
|
146
|
+
unless location.present?
|
147
|
+
raise ArgumentError, "Parameter is missing required 'in' value."
|
148
|
+
end
|
149
|
+
|
150
|
+
locations = %w(query header path formData body)
|
151
|
+
unless locations.include? location.to_s
|
152
|
+
raise ArgumentError, "Parameter has an invalid 'in' value. Try: #{locations}."
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def validate_type! type
|
157
|
+
unless type.present?
|
158
|
+
raise ArgumentError, "Parameter is missing required 'type' value."
|
159
|
+
end
|
160
|
+
|
161
|
+
types = %w(string number integer boolean array file)
|
162
|
+
unless types.include? type.to_s
|
163
|
+
raise ArgumentError, "Parameter has an invalid 'type' value. Try: #{types}."
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
module Operation
|
169
|
+
def consumes *mime_types
|
170
|
+
metadata[:swagger_operation][:consumes] = mime_types
|
171
|
+
end
|
172
|
+
|
173
|
+
def produces *mime_types
|
174
|
+
metadata[:swagger_operation][:produces] = mime_types
|
175
|
+
end
|
176
|
+
|
177
|
+
def response status_code, attributes = {}, &block
|
178
|
+
attributes.symbolize_keys!
|
179
|
+
|
180
|
+
validate_status_code! status_code
|
181
|
+
validate_description! attributes[:description]
|
182
|
+
|
183
|
+
meta = {
|
184
|
+
swagger_object: :response,
|
185
|
+
swagger_response: attributes.merge(status_code: status_code)
|
186
|
+
}
|
187
|
+
describe(status_code, meta) do
|
188
|
+
self.module_exec(&block) if block_given?
|
189
|
+
|
190
|
+
# To make a request we need:
|
191
|
+
# - the details we've collected in the metadata
|
192
|
+
# - parameter values defined using let()
|
193
|
+
# RSpec tries to limit access to metadata inside of it() / before()
|
194
|
+
# / after() blocks but that scope is the only place you can access
|
195
|
+
# the let() values. The solution the swagger_rails dev came up with
|
196
|
+
# is to use the example.metadata passed into the block with the
|
197
|
+
# block's scope which has access to the let() values.
|
198
|
+
before do |example|
|
199
|
+
builder = RequestBuilder.new(example.metadata, self)
|
200
|
+
method = builder.method
|
201
|
+
path = [builder.path, builder.query].join
|
202
|
+
headers = builder.headers
|
203
|
+
body = builder.body
|
204
|
+
|
205
|
+
# Run the request
|
206
|
+
if ::Rails::VERSION::MAJOR >= 5
|
207
|
+
self.send(method, path, {params: body, headers: headers})
|
208
|
+
else
|
209
|
+
self.send(method, path, body, headers)
|
210
|
+
end
|
211
|
+
|
212
|
+
if example.metadata[:capture_examples]
|
213
|
+
examples = example.metadata[:swagger_response][:examples] ||= {}
|
214
|
+
examples[response.content_type.to_s] = response.body
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
# TODO: see if we can get the caller to show up in the error
|
219
|
+
# backtrace for this test.
|
220
|
+
it("returns the correct status code") do
|
221
|
+
expect(response).to have_http_status(status_code)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
private
|
227
|
+
|
228
|
+
def validate_status_code! status_code
|
229
|
+
unless status_code == :default || (100..599).cover?(status_code)
|
230
|
+
raise ArgumentError, "status_code must be an integer 100 to 599, or :default"
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def validate_description! description
|
235
|
+
unless description.present?
|
236
|
+
raise ArgumentError, "Response is missing required 'description' value."
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
module Response
|
242
|
+
def capture_example
|
243
|
+
metadata[:capture_examples] = true
|
244
|
+
end
|
245
|
+
|
246
|
+
def schema definition
|
247
|
+
definition.symbolize_keys!
|
248
|
+
|
249
|
+
ref = definition.delete(:ref)
|
250
|
+
schema = ref ? { '$ref' => ref } : definition
|
251
|
+
|
252
|
+
metadata[:swagger_response][:schema] = schema
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Rails
|
3
|
+
module Swagger
|
4
|
+
class RequestBuilder
|
5
|
+
attr_reader :metadata, :instance
|
6
|
+
|
7
|
+
def initialize(metadata, instance)
|
8
|
+
@metadata, @instance = metadata, instance
|
9
|
+
end
|
10
|
+
|
11
|
+
def document
|
12
|
+
@document ||= begin
|
13
|
+
name = metadata[:swagger_document]
|
14
|
+
Document.new(RSpec.configuration.swagger_docs[name])
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def method
|
19
|
+
metadata[:swagger_operation][:method]
|
20
|
+
end
|
21
|
+
|
22
|
+
def produces
|
23
|
+
metadata[:swagger_operation][:produces] || document[:produces]
|
24
|
+
end
|
25
|
+
|
26
|
+
def consumes
|
27
|
+
metadata[:swagger_operation][:consumes] || document[:consumes]
|
28
|
+
end
|
29
|
+
|
30
|
+
def parameters location = nil
|
31
|
+
path_item = metadata[:swagger_path_item] || {}
|
32
|
+
operation = metadata[:swagger_operation] || {}
|
33
|
+
params = path_item.fetch(:parameters, {}).merge(operation.fetch(:parameters, {}))
|
34
|
+
if location.present?
|
35
|
+
params.select{ |k, _| k.starts_with? "#{location}&" }
|
36
|
+
else
|
37
|
+
params
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def parameter_values location
|
42
|
+
# Don't bother looking at the full parameter bodies since all we need
|
43
|
+
# are location and name which are in the key.
|
44
|
+
values = parameters(location)
|
45
|
+
.keys
|
46
|
+
.map{ |k| k.split('&').last }
|
47
|
+
.map{ |name| [name, instance.send(name)] }
|
48
|
+
Hash[values]
|
49
|
+
end
|
50
|
+
|
51
|
+
def headers
|
52
|
+
headers = {}
|
53
|
+
|
54
|
+
# Match the names that Rails uses internally
|
55
|
+
headers['HTTP_ACCEPT'] = produces.join(';') if produces.present?
|
56
|
+
headers['CONTENT_TYPE'] = consumes.first if consumes.present?
|
57
|
+
|
58
|
+
# TODO: do we need to do some capitalization to match the rack
|
59
|
+
# conventions?
|
60
|
+
parameter_values(:header).each { |k, v| headers[k] = v }
|
61
|
+
|
62
|
+
headers
|
63
|
+
end
|
64
|
+
|
65
|
+
def path
|
66
|
+
base_path = document[:basePath] || ''
|
67
|
+
# Find params in the path and replace them with values defined in
|
68
|
+
# in the example group.
|
69
|
+
base_path + metadata[:swagger_path_item][:path].gsub(/(\{.*?\})/) do |match|
|
70
|
+
# QUESTION: Should check that the parameter is actually defined in
|
71
|
+
# `parameters` before fetch a value?
|
72
|
+
instance.send(match[1...-1])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def query
|
77
|
+
query_params = parameter_values(:query).to_query
|
78
|
+
"?#{query_params}" unless query_params.blank?
|
79
|
+
end
|
80
|
+
|
81
|
+
def body
|
82
|
+
# And here all we need is the first half of the key to find the body
|
83
|
+
# parameter and its name to fetch a value.
|
84
|
+
if key = parameters(:body).keys.first
|
85
|
+
instance.send(key.split('&').last).to_json
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec-rails-swagger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- andrew morton
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec-rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
description: Inspired by swagger_rails
|
42
|
+
email: drewish@katherinehouse.com
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- lib/rspec/rails/swagger.rb
|
48
|
+
- lib/rspec/rails/swagger/configuration.rb
|
49
|
+
- lib/rspec/rails/swagger/document.rb
|
50
|
+
- lib/rspec/rails/swagger/formatter.rb
|
51
|
+
- lib/rspec/rails/swagger/helpers.rb
|
52
|
+
- lib/rspec/rails/swagger/request_builder.rb
|
53
|
+
- lib/rspec/rails/swagger/version.rb
|
54
|
+
homepage: https://github.com/drewish/rspec-rails-swagger
|
55
|
+
licenses:
|
56
|
+
- MIT
|
57
|
+
metadata: {}
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - "~>"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '2.0'
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
requirements: []
|
73
|
+
rubyforge_project:
|
74
|
+
rubygems_version: 2.5.1
|
75
|
+
signing_key:
|
76
|
+
specification_version: 4
|
77
|
+
summary: Generate Swagger docs from RSpec integration tests
|
78
|
+
test_files: []
|