apipie-rails 1.4.0 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/.rubocop_todo.yml +46 -135
- data/CHANGELOG.md +16 -0
- data/apipie-rails.gemspec +1 -0
- data/lib/apipie/application.rb +6 -6
- data/lib/apipie/error_description.rb +7 -5
- data/lib/apipie/extractor/recorder.rb +3 -3
- data/lib/apipie/extractor/writer.rb +6 -6
- data/lib/apipie/generator/swagger/method_description/api_schema_service.rb +2 -2
- data/lib/apipie/generator/swagger/method_description/parameters_service.rb +7 -7
- data/lib/apipie/generator/swagger/param_description/builder.rb +3 -3
- data/lib/apipie/generator/swagger/param_description/in.rb +1 -1
- data/lib/apipie/generator/swagger/param_description/path_params_composite.rb +10 -10
- data/lib/apipie/generator/swagger/param_description/type.rb +5 -1
- data/lib/apipie/generator/swagger/resource_description_composite.rb +5 -5
- data/lib/apipie/generator/swagger/type_extractor.rb +1 -1
- data/lib/apipie/generator/swagger/warning.rb +2 -2
- data/lib/apipie/helpers.rb +1 -1
- data/lib/apipie/response_description.rb +10 -5
- data/lib/apipie/routes_formatter.rb +1 -1
- data/lib/apipie/static_dispatcher.rb +2 -2
- data/lib/apipie/version.rb +1 -1
- data/lib/tasks/apipie.rake +4 -4
- data/spec/controllers/api/v1/architectures_controller_spec.rb +3 -3
- data/spec/controllers/api/v2/nested/resources_controller_spec.rb +1 -1
- data/spec/controllers/concerns_controller_spec.rb +2 -2
- data/spec/controllers/extended_controller_spec.rb +2 -2
- data/spec/controllers/included_param_group_controller_spec.rb +1 -1
- data/spec/controllers/pets_controller_spec.rb +1 -1
- data/spec/controllers/users_controller_spec.rb +64 -63
- data/spec/dummy/app/controllers/extending_concern.rb +7 -7
- data/spec/dummy/app/controllers/pets_controller.rb +4 -4
- data/spec/dummy/app/controllers/pets_using_auto_views_controller.rb +2 -2
- data/spec/dummy/app/controllers/pets_using_self_describing_classes_controller.rb +16 -16
- data/spec/dummy/app/controllers/sample_controller.rb +31 -31
- data/spec/lib/apipie/application_spec.rb +2 -2
- data/spec/lib/apipie/extractor/writer_spec.rb +8 -8
- data/spec/lib/apipie/generator/swagger/param_description/builder_spec.rb +30 -0
- data/spec/lib/apipie/generator/swagger/param_description/type_spec.rb +29 -2
- data/spec/lib/apipie/method_description_spec.rb +2 -2
- data/spec/lib/apipie/param_description_spec.rb +47 -47
- data/spec/lib/apipie/param_group_spec.rb +4 -4
- data/spec/lib/apipie/resource_description_spec.rb +2 -2
- data/spec/lib/apipie/validator_spec.rb +12 -12
- data/spec/lib/swagger/swagger_dsl_spec.rb +40 -40
- data/spec/spec_helper.rb +5 -2
- data/spec/test_engine/memes_controller_spec.rb +1 -1
- metadata +138 -4
@@ -324,7 +324,7 @@ module Apipie
|
|
324
324
|
desc ||= case @action.to_s
|
325
325
|
when "show", "create", "update", "destroy"
|
326
326
|
name = name.singularize
|
327
|
-
"#{@action.capitalize} #{
|
327
|
+
"#{@action.capitalize} #{/^[aeiou]/.match?(name) ? 'an' : 'a'} #{name}"
|
328
328
|
when "index"
|
329
329
|
"List #{name}"
|
330
330
|
end
|
@@ -341,7 +341,7 @@ module Apipie
|
|
341
341
|
params.sort_by {|n,_| n }.each do |(name, desc)|
|
342
342
|
desc[:type] = (desc[:type] && desc[:type].first) || Object
|
343
343
|
code << "#{indent}param"
|
344
|
-
if
|
344
|
+
if /\W/.match?(name)
|
345
345
|
code << " :'#{name}'"
|
346
346
|
else
|
347
347
|
code << " :#{name}"
|
@@ -397,7 +397,7 @@ module Apipie
|
|
397
397
|
lines_to_add = []
|
398
398
|
block_level = 0
|
399
399
|
ensure_line_breaks(controller_content.lines).first(action_line).reverse_each do |line|
|
400
|
-
if
|
400
|
+
if /\s*\bend\b\s*/.match?(line)
|
401
401
|
block_level += 1
|
402
402
|
end
|
403
403
|
if block_level > 0
|
@@ -405,10 +405,10 @@ module Apipie
|
|
405
405
|
else
|
406
406
|
added_lines << line
|
407
407
|
end
|
408
|
-
if
|
408
|
+
if /\s*\b(module|class|def)\b /.match?(line)
|
409
409
|
break
|
410
410
|
end
|
411
|
-
next unless
|
411
|
+
next unless /do\s*(\|.*?\|)?\s*$/.match?(line)
|
412
412
|
block_level -= 1
|
413
413
|
if block_level == 0
|
414
414
|
added_lines.concat(lines_to_add)
|
@@ -426,7 +426,7 @@ module Apipie
|
|
426
426
|
# https://github.com/puppetlabs/puppet/blob/0dc44695/lib/puppet/util/monkey_patches.rb
|
427
427
|
def ensure_line_breaks(lines)
|
428
428
|
if lines.to_a.size > 1 && lines.first !~ /\n\Z/
|
429
|
-
lines.map { |l|
|
429
|
+
lines.map { |l| !/\n\Z/.match?(l) ? (l << "\n") : l }.to_enum
|
430
430
|
else
|
431
431
|
lines
|
432
432
|
end
|
@@ -17,8 +17,8 @@ class Apipie::Generator::Swagger::MethodDescription::ApiSchemaService
|
|
17
17
|
end
|
18
18
|
|
19
19
|
parameters = Apipie::Generator::Swagger::MethodDescription::ParametersService
|
20
|
-
|
21
|
-
|
20
|
+
.new(@method_description, path: path, http_method: api.normalized_http_method)
|
21
|
+
.call
|
22
22
|
|
23
23
|
paths[path.swagger_path(@method_description)] ||= {}
|
24
24
|
paths[path.swagger_path(@method_description)][api.normalized_http_method] = {
|
@@ -40,7 +40,7 @@ class Apipie::Generator::Swagger::MethodDescription::ParametersService
|
|
40
40
|
|
41
41
|
if Apipie.configuration.generator.swagger.json_input_uses_refs?
|
42
42
|
composite = composite
|
43
|
-
|
43
|
+
.referenced("#{@method_description.operation_id}_input")
|
44
44
|
end
|
45
45
|
|
46
46
|
swagger_schema_for_body = composite.to_swagger
|
@@ -80,7 +80,7 @@ class Apipie::Generator::Swagger::MethodDescription::ParametersService
|
|
80
80
|
warn_path_parameter_not_described(name, @path)
|
81
81
|
|
82
82
|
result[name.to_sym] = Apipie::Generator::Swagger::ParamDescription
|
83
|
-
|
83
|
+
.create_for_missing_param(@method_description, name)
|
84
84
|
end
|
85
85
|
|
86
86
|
result
|
@@ -89,15 +89,15 @@ class Apipie::Generator::Swagger::MethodDescription::ParametersService
|
|
89
89
|
|
90
90
|
def body_param_descriptions
|
91
91
|
@body_param_descriptions ||= all_params
|
92
|
-
|
93
|
-
|
92
|
+
.reject { |k, _| @path.param?(k) }
|
93
|
+
.values
|
94
94
|
end
|
95
95
|
|
96
96
|
def path_param_descriptions
|
97
97
|
@path_param_descriptions ||= all_params
|
98
|
-
|
99
|
-
|
100
|
-
|
98
|
+
.select { |k, _| @path.param?(k) }
|
99
|
+
.each_value { |desc| desc.required = true }
|
100
|
+
.values
|
101
101
|
end
|
102
102
|
|
103
103
|
# @return [Array]
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class Apipie::Generator::Swagger::ParamDescription::Builder
|
2
2
|
# @param [Apipie::ParamDescription] param_description
|
3
3
|
# @param [TrueClass, FalseClass] in_schema
|
4
|
-
# @param [Apipie::MethodDescription] controller_method
|
4
|
+
# @param [Apipie::MethodDescription, nil] controller_method
|
5
5
|
def initialize(param_description, in_schema:, controller_method:)
|
6
6
|
@param_description = param_description
|
7
7
|
@in_schema = in_schema
|
@@ -98,8 +98,8 @@ class Apipie::Generator::Swagger::ParamDescription::Builder
|
|
98
98
|
def warn_optional_without_default_value(definition)
|
99
99
|
if !required? && !definition.key?(:default)
|
100
100
|
method_id =
|
101
|
-
if @param_description.is_a?(Apipie::ResponseDescriptionAdapter::PropDesc)
|
102
|
-
@controller_method
|
101
|
+
if @controller_method.present? && @param_description.is_a?(Apipie::ResponseDescriptionAdapter::PropDesc)
|
102
|
+
@controller_method.method_name
|
103
103
|
else
|
104
104
|
Apipie::Generator::Swagger::MethodDescription::Decorator.new(@controller_method).ruby_name
|
105
105
|
end
|
@@ -26,21 +26,21 @@ class Apipie::Generator::Swagger::ParamDescription::PathParamsComposite
|
|
26
26
|
context.add_to_prefix!(desc.name)
|
27
27
|
|
28
28
|
out = Apipie::Generator::Swagger::ParamDescription::PathParamsComposite
|
29
|
-
|
30
|
-
|
29
|
+
.new(desc.validator.params_ordered, context)
|
30
|
+
.to_swagger
|
31
31
|
|
32
32
|
@result.concat(out)
|
33
33
|
else
|
34
34
|
param_entry =
|
35
35
|
Apipie::Generator::Swagger::ParamDescription::Builder
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
36
|
+
.new(desc, in_schema: false, controller_method: context.controller_method)
|
37
|
+
.with_description(language: context.language)
|
38
|
+
.with_name(prefix: context.prefix)
|
39
|
+
.with_type(with_null: context.allow_null?)
|
40
|
+
.with_in(
|
41
|
+
http_method: context.http_method,
|
42
|
+
default_in_value: context.default_in_value
|
43
|
+
).to_swagger
|
44
44
|
|
45
45
|
@result << param_entry
|
46
46
|
end
|
@@ -114,7 +114,11 @@ class Apipie::Generator::Swagger::ParamDescription::Type
|
|
114
114
|
def warn_hash_without_internal_typespec
|
115
115
|
method_id =
|
116
116
|
if @param_description.is_a?(Apipie::ResponseDescriptionAdapter::PropDesc)
|
117
|
-
@controller_method.
|
117
|
+
if @controller_method.present?
|
118
|
+
@controller_method.method_name
|
119
|
+
else
|
120
|
+
Apipie::Generator::Swagger::MethodDescription::Decorator.new(nil).ruby_name
|
121
|
+
end
|
118
122
|
else
|
119
123
|
Apipie::Generator::Swagger::MethodDescription::Decorator.new(@param_description.method_description).ruby_name
|
120
124
|
end
|
@@ -41,11 +41,11 @@ class Apipie::Generator::Swagger::ResourceDescriptionComposite
|
|
41
41
|
next unless method_description.show
|
42
42
|
|
43
43
|
result = Apipie::Generator::Swagger::MethodDescription::ApiSchemaService
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
44
|
+
.new(
|
45
|
+
Apipie::Generator::Swagger::MethodDescription::Decorator.new(method_description),
|
46
|
+
language: @language
|
47
|
+
)
|
48
|
+
.call
|
49
49
|
|
50
50
|
results.deep_merge!(result)
|
51
51
|
end
|
@@ -18,7 +18,7 @@ class Apipie::Generator::Swagger::TypeExtractor
|
|
18
18
|
date: Apipie::Generator::Swagger::Type.new('string', 'date'),
|
19
19
|
dateTime: Apipie::Generator::Swagger::Type.new('string', 'date-time'),
|
20
20
|
password: Apipie::Generator::Swagger::Type.new('string', 'password')
|
21
|
-
}
|
21
|
+
}.freeze
|
22
22
|
|
23
23
|
# @param [Apipie::Validator::BaseValidator, ResponseDescriptionAdapter::PropDesc::Validator, nil] validator
|
24
24
|
def initialize(validator)
|
@@ -17,7 +17,7 @@ class Apipie::Generator::Swagger::Warning
|
|
17
17
|
optional_without_default_value: OPTIONAL_WITHOUT_DEFAULT_VALUE_CODE,
|
18
18
|
param_ignored_in_form_data: PARAM_IGNORED_IN_FORM_DATA_CODE,
|
19
19
|
path_param_not_described_code: PATH_PARAM_NOT_DESCRIBED_CODE
|
20
|
-
}
|
20
|
+
}.freeze
|
21
21
|
|
22
22
|
MESSAGES = {
|
23
23
|
MISSING_METHOD_SUMMARY_CODE => "Missing short description for method",
|
@@ -28,7 +28,7 @@ class Apipie::Generator::Swagger::Warning
|
|
28
28
|
OPTIONAL_WITHOUT_DEFAULT_VALUE_CODE => "The parameter :%{parameter} is optional but default value is not specified (use :default_value => ...)",
|
29
29
|
PARAM_IGNORED_IN_FORM_DATA_CODE => "Ignoring param :%{parameter} -- cannot include Hash without fields in a formData specification",
|
30
30
|
PATH_PARAM_NOT_DESCRIBED_CODE => "The parameter :%{name} appears in the path %{path} but is not described"
|
31
|
-
}
|
31
|
+
}.freeze
|
32
32
|
|
33
33
|
attr_reader :code
|
34
34
|
|
data/lib/apipie/helpers.rb
CHANGED
@@ -88,11 +88,16 @@ module Apipie
|
|
88
88
|
|
89
89
|
@method_description = method_description
|
90
90
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
91
|
+
@code =
|
92
|
+
if code.is_a? Symbol
|
93
|
+
begin
|
94
|
+
Rack::Utils.status_code(code)
|
95
|
+
rescue ArgumentError
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
else
|
99
|
+
code
|
100
|
+
end
|
96
101
|
|
97
102
|
@description = options[:desc]
|
98
103
|
if @description.nil?
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Apipie
|
2
2
|
class RoutesFormatter
|
3
|
-
API_METHODS = %w{GET POST PUT PATCH OPTIONS DELETE}
|
3
|
+
API_METHODS = %w{GET POST PUT PATCH OPTIONS DELETE}.freeze
|
4
4
|
|
5
5
|
# The entry method called by Apipie to extract the array
|
6
6
|
# representing the api dsl from the routes definition.
|
@@ -16,8 +16,8 @@ module Apipie
|
|
16
16
|
def match?(path)
|
17
17
|
# Replace all null bytes
|
18
18
|
path = ::Rack::Utils.unescape(path || '')
|
19
|
-
|
20
|
-
|
19
|
+
.encode(Encoding::UTF_8, invalid: :replace, replace: '')
|
20
|
+
.gsub("\x0", '')
|
21
21
|
|
22
22
|
full_path = path.empty? ? @root : File.join(@root, path)
|
23
23
|
paths = "#{full_path}#{ext}"
|
data/lib/apipie/version.rb
CHANGED
data/lib/tasks/apipie.rake
CHANGED
@@ -70,17 +70,17 @@ namespace :apipie do
|
|
70
70
|
with_loaded_documentation do
|
71
71
|
out = ENV["OUT_REF"] || File.join(Rails.root, Apipie.configuration.doc_path, 'apidoc_ref')
|
72
72
|
paths = generate_swagger_using_args(args, out)
|
73
|
-
paths.each
|
73
|
+
paths.each do |path|
|
74
74
|
existing_files_in_dir = Pathname(out).children(true)
|
75
75
|
|
76
76
|
make_reference = false
|
77
77
|
|
78
78
|
# reference filenames have the format <basename>.<counter>.swagger_ref
|
79
|
-
reference_files = existing_files_in_dir.select
|
79
|
+
reference_files = existing_files_in_dir.select do |f|
|
80
80
|
f.extname == '.swagger_ref' &&
|
81
81
|
f.basename.sub_ext("").extname.delete('.').to_i > 0 &&
|
82
82
|
f.basename.sub_ext("").sub_ext("") == path.basename.sub_ext("")
|
83
|
-
|
83
|
+
end
|
84
84
|
if reference_files.empty?
|
85
85
|
print "Reference file does not exist for [#{path}]\n"
|
86
86
|
counter = 1
|
@@ -111,7 +111,7 @@ namespace :apipie do
|
|
111
111
|
if reference_files.length > num_refs_to_keep
|
112
112
|
(reference_files - reference_files[-num_refs_to_keep..-1]).each(&:delete)
|
113
113
|
end
|
114
|
-
|
114
|
+
end
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
@@ -4,7 +4,7 @@ describe Api::V1::ArchitecturesController do
|
|
4
4
|
describe "resource description" do
|
5
5
|
subject { Apipie.get_resource_description(Api::V1::ArchitecturesController, "1.0") }
|
6
6
|
|
7
|
-
it "
|
7
|
+
it "is version 1.0" do
|
8
8
|
expect(subject._version).to eq('1.0')
|
9
9
|
|
10
10
|
expect(Apipie.resource_descriptions['1.0'].size).to eq(2)
|
@@ -14,11 +14,11 @@ describe Api::V1::ArchitecturesController do
|
|
14
14
|
context "there is another version" do
|
15
15
|
let(:v2) { archv2 = Apipie.get_resource_description(Api::V2::ArchitecturesController, "2.0") }
|
16
16
|
|
17
|
-
it "
|
17
|
+
it "has unique doc url" do
|
18
18
|
expect(subject.doc_url).not_to eq(v2.doc_url)
|
19
19
|
end
|
20
20
|
|
21
|
-
it "
|
21
|
+
it "has unique methods" do
|
22
22
|
expect(subject._methods.keys).to include(:index)
|
23
23
|
expect(v2._methods.keys).to include(:index)
|
24
24
|
expect(subject._methods[:index]).not_to eq(v2._methods[:index])
|
@@ -20,7 +20,7 @@ describe Api::V2::Nested::ResourcesController do
|
|
20
20
|
describe '.get_resource_id' do
|
21
21
|
subject { Apipie.get_resource_id(Api::V2::Nested::ResourcesController) }
|
22
22
|
|
23
|
-
it "
|
23
|
+
it "has resource_id set" do
|
24
24
|
expect(subject).to eq("resource")
|
25
25
|
end
|
26
26
|
end
|
@@ -7,12 +7,12 @@ describe ConcernsController do
|
|
7
7
|
expect(Apipie["concern_resources#show"]).to be
|
8
8
|
end
|
9
9
|
|
10
|
-
it "
|
10
|
+
it "replies to valid request" do
|
11
11
|
get :show, :params => { :id => '5' }, :session => { :user_id => "secret_hash" }
|
12
12
|
assert_response :success
|
13
13
|
end
|
14
14
|
|
15
|
-
it "
|
15
|
+
it "passes if required parameter is missing" do
|
16
16
|
expect { get :show, :params => { :id => '5' } }.not_to raise_error
|
17
17
|
end
|
18
18
|
|
@@ -2,13 +2,13 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe ExtendedController do
|
4
4
|
|
5
|
-
it '
|
5
|
+
it 'includes params from both original controller and extending concern' do
|
6
6
|
expect(Apipie["extended#create"].params.keys).to eq [:oauth, :user, :admin]
|
7
7
|
user_param = Apipie["extended#create"].params[:user]
|
8
8
|
expect(user_param.validator.params_ordered.map(&:name)).to eq [:name, :password, :from_concern]
|
9
9
|
end
|
10
10
|
|
11
|
-
it '
|
11
|
+
it 'includes updated metadata' do
|
12
12
|
expect(Apipie['extended#create'].metadata).to eq metadata: 'data'
|
13
13
|
end
|
14
14
|
end
|
@@ -5,7 +5,7 @@ describe IncludedParamGroupController do
|
|
5
5
|
|
6
6
|
let(:dsl_data) { ActionController::Base.send(:_apipie_dsl_data_init) }
|
7
7
|
|
8
|
-
it "
|
8
|
+
it "does not error when there is a param_group that is deeply nested in response description" do
|
9
9
|
subject = Apipie.get_resource_description(IncludedParamGroupController, Apipie.configuration.default_version)
|
10
10
|
expect(subject._methods.keys).to include(:show)
|
11
11
|
end
|
@@ -4,7 +4,7 @@ require 'rspec/expectations'
|
|
4
4
|
require 'apipie/rspec/response_validation_helper'
|
5
5
|
require "json-schema"
|
6
6
|
|
7
|
-
RSpec.describe PetsController
|
7
|
+
RSpec.describe PetsController do
|
8
8
|
it "does not raise error when rendered output matches the described response" do
|
9
9
|
response = get :return_and_validate_expected_response, format: :json
|
10
10
|
expect(response).to match_declared_responses
|