apipie-rails 0.8.2 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +7 -0
  3. data/.github/workflows/rubocop-challenger.yml +28 -0
  4. data/.rubocop.yml +37 -0
  5. data/.rubocop_todo.yml +1991 -0
  6. data/CHANGELOG.md +19 -0
  7. data/README.rst +4 -4
  8. data/Rakefile +0 -5
  9. data/apipie-rails.gemspec +10 -7
  10. data/app/controllers/apipie/apipies_controller.rb +1 -1
  11. data/lib/apipie/application.rb +4 -4
  12. data/lib/apipie/dsl_definition.rb +4 -4
  13. data/lib/apipie/extractor/writer.rb +4 -4
  14. data/lib/apipie/generator/generator.rb +2 -0
  15. data/lib/apipie/generator/swagger/swagger.rb +2 -0
  16. data/lib/apipie/generator/swagger/type.rb +16 -0
  17. data/lib/apipie/generator/swagger/type_extractor.rb +70 -0
  18. data/lib/apipie/generator/swagger/warning.rb +77 -0
  19. data/lib/apipie/generator/swagger/warning_writer.rb +48 -0
  20. data/lib/apipie/method_description/api.rb +12 -0
  21. data/lib/apipie/method_description/apis_service.rb +82 -0
  22. data/lib/apipie/method_description.rb +3 -48
  23. data/lib/apipie/resource_description.rb +1 -1
  24. data/lib/apipie/swagger_generator.rb +76 -81
  25. data/lib/apipie/validator.rb +4 -0
  26. data/lib/apipie/version.rb +1 -1
  27. data/lib/apipie-rails.rb +9 -1
  28. data/lib/generators/apipie/install/install_generator.rb +1 -1
  29. data/lib/generators/apipie/views_generator.rb +1 -1
  30. data/lib/tasks/apipie.rake +4 -4
  31. data/spec/controllers/apipies_controller_spec.rb +2 -2
  32. data/spec/controllers/users_controller_spec.rb +1 -1
  33. data/spec/dummy/Rakefile +1 -1
  34. data/spec/dummy/app/controllers/users_controller.rb +1 -1
  35. data/spec/dummy/components/test_engine/test_engine.gemspec +1 -1
  36. data/spec/dummy/config/application.rb +1 -1
  37. data/spec/dummy/config/boot.rb +2 -2
  38. data/spec/dummy/config/environment.rb +1 -1
  39. data/spec/dummy/config/initializers/apipie.rb +2 -2
  40. data/spec/dummy/config/routes.rb +1 -0
  41. data/spec/dummy/config.ru +1 -1
  42. data/spec/dummy/script/rails +2 -2
  43. data/spec/lib/application_spec.rb +1 -1
  44. data/spec/lib/extractor/writer_spec.rb +8 -6
  45. data/spec/lib/generator/swagger/type_extractor_spec.rb +61 -0
  46. data/spec/lib/generator/swagger/warning_spec.rb +51 -0
  47. data/spec/lib/generator/swagger/warning_writer_spec.rb +59 -0
  48. data/spec/lib/method_description/apis_service_spec.rb +60 -0
  49. data/spec/lib/param_description_spec.rb +4 -4
  50. data/spec/lib/rake_spec.rb +2 -4
  51. data/spec/lib/swagger/rake_swagger_spec.rb +4 -4
  52. data/spec/lib/validator_spec.rb +1 -1
  53. data/spec/spec_helper.rb +4 -4
  54. metadata +39 -38
data/CHANGELOG.md CHANGED
@@ -4,6 +4,25 @@
4
4
  Also deleted the `Gemfile` that was now a broken symlink.
5
5
  please use `export BUNDLE_GEMFILE='gemfiles/Gemfile.rails61'; bundle exec rspec` to run the test suite
6
6
 
7
+ ## [v0.9.1](https://github.com/Apipie/apipie-rails/tree/v0.9.1) (2023-01-16)
8
+ [Full Changelog](https://github.com/Apipie/apipie-rails/compare/v0.9.0...v0.9.1)
9
+ * [Refactor] Create test cache files under a not version controlled directory [#809](https://github.com/Apipie/apipie-rails/pull/809) (Panos Dalitsouris)
10
+ * [Ruby] Support for Ruby 3.2 [#807](https://github.com/Apipie/apipie-rails/pull/807) (Mathieu Jobin)
11
+ * [Fix] Reverted conditional assignment operators that caused #559 [#806](https://github.com/Apipie/apipie-rails/pull/806) (Nick L. Deltik)
12
+ * [Rubocop] Autocorrect Style/SymbolProc [#793](https://github.com/Apipie/apipie-rails/pull/793) (Rubocop Challenger)
13
+
14
+ ## [v0.9.0](https://github.com/Apipie/apipie-rails/tree/v0.9.0) (2023-01-03)
15
+ [Full Changelog](https://github.com/Apipie/apipie-rails/compare/v0.8.2...v0.9.0)
16
+ * [Refactor] Move Swagger types and warnings under `/generator` namespace [#803](https://github.com/Apipie/apipie-rails/pull/803) (Panos Dalitsouris)
17
+ * [Refactor] Creates `Apipie::MethodDescription::ApisService` [#805](https://github.com/Apipie/apipie-rails/pull/805) (Panos Dalitsouris)
18
+ * [Refactor] Change output folder to `spec/dummy/tmp/` [#804](https://github.com/Apipie/apipie-rails/pull/804) (Panos Dalitsouris)
19
+ * Fix tiny typo in docs [#798](https://github.com/Apipie/apipie-rails/pull/798) (Erik-B. Ernst)
20
+ * Fix Generated docs.json output [#787](https://github.com/Apipie/apipie-rails/pull/787) (Jeremy Liberman)
21
+ * Rubocop Fixes [#775](https://github.com/Apipie/apipie-rails/pull/775), [#778](https://github.com/Apipie/apipie-rails/pull/778), [#780](https://github.com/Apipie/apipie-rails/pull/780), [#790](https://github.com/Apipie/apipie-rails/pull/790), [#783](https://github.com/Apipie/apipie-rails/pull/783), [#785](https://github.com/Apipie/apipie-rails/pull/785) (RuboCop)
22
+ * Remove/clean up dev dependencies and unused rake tasks [#777](https://github.com/Apipie/apipie-rails/pull/777) (Mathieu Jobin)
23
+ - remove unused rake task
24
+ * Setup Rubocop Challenger [#776](https://github.com/Apipie/apipie-rails/pull/776) (Mathieu Jobin)
25
+
7
26
  ## [v0.8.2](https://github.com/Apipie/apipie-rails/tree/v0.8.2) (2022-09-03)
8
27
  [Full Changelog](https://github.com/Apipie/apipie-rails/compare/v0.8.1...v0.8.2)
9
28
  * Allow custom validators to opt out of allow_blank behavior [#762](https://github.com/Apipie/apipie-rails/pull/762). (Stephen Hanson)
data/README.rst CHANGED
@@ -2,8 +2,8 @@
2
2
  API Documentation Tool
3
3
  ========================
4
4
 
5
- .. image:: https://travis-ci.org/Apipie/apipie-rails.svg?branch=master
6
- :target: https://travis-ci.org/Apipie/apipie-rails
5
+ .. image:: https://github.com/Apipie/apipie-rails/actions/workflows/build.yml/badge.svg
6
+ :target: https://github.com/Apipie/apipie-rails/actions/workflows/build.yml
7
7
  .. image:: https://codeclimate.com/github/Apipie/apipie-rails.svg
8
8
  :target: https://codeclimate.com/github/Apipie/apipie-rails
9
9
  .. image:: https://badges.gitter.im/Apipie/apipie-rails.svg
@@ -150,7 +150,7 @@ Example:
150
150
  resource_description do
151
151
  short 'Site members'
152
152
  formats ['json']
153
- param :id, Fixnum, :desc => "User ID", :required => false
153
+ param :id, Integer, :desc => "User ID", :required => false
154
154
  param :resource_param, Hash, :desc => 'Param description for all methods' do
155
155
  param :ausername, String, :desc => "Username for login", :required => true
156
156
  param :apassword, String, :desc => "Password for login", :required => true
@@ -1375,7 +1375,7 @@ So we create apipie_validators.rb initializer with this content:
1375
1375
  end
1376
1376
 
1377
1377
  def self.build(param_description, argument, options, block)
1378
- if argument == Integer || argument == Fixnum
1378
+ if argument == Integer
1379
1379
  self.new(param_description, argument)
1380
1380
  end
1381
1381
  end
data/Rakefile CHANGED
@@ -6,8 +6,3 @@ RSpec::Core::RakeTask.new(:spec)
6
6
  desc 'Default: run specs.'
7
7
  task :default => :spec
8
8
 
9
- desc "Generate code coverage"
10
- RSpec::Core::RakeTask.new(:coverage) do |t|
11
- t.rcov = true
12
- t.rcov_opts = ['--exclude', 'spec']
13
- end
data/apipie-rails.gemspec CHANGED
@@ -1,5 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
2
+ $:.push File.expand_path('lib', __dir__)
3
3
  require "apipie/version"
4
4
 
5
5
  Gem::Specification.new do |s|
@@ -18,13 +18,16 @@ Gem::Specification.new do |s|
18
18
 
19
19
  s.add_dependency "actionpack", ">= 5.0"
20
20
  s.add_dependency "activesupport", ">= 5.0"
21
+
22
+ # Optional dependencies
23
+ s.add_development_dependency "maruku" # for Markdown support
24
+ s.add_development_dependency "RedCloth" # for Textile support
25
+
26
+ # Dev/tests only dependencies
27
+ s.add_development_dependency "json-schema", "~> 2.8"
21
28
  s.add_development_dependency "rspec-rails", "~> 3.0"
22
- s.add_development_dependency "sqlite3"
23
- s.add_development_dependency "minitest"
24
- s.add_development_dependency "maruku"
25
- s.add_development_dependency "RedCloth"
26
29
  s.add_development_dependency "rake"
27
- s.add_development_dependency "rdoc"
30
+ s.add_development_dependency 'rubocop_challenger'
28
31
  s.add_development_dependency "simplecov"
29
- s.add_development_dependency "json-schema", "~> 2.8"
32
+ s.add_development_dependency "sqlite3"
30
33
  end
@@ -177,7 +177,7 @@ module Apipie
177
177
  end
178
178
 
179
179
  cache_file = File.join(Apipie.configuration.cache_dir, path)
180
- if File.exists?(cache_file)
180
+ if File.exist?(cache_file)
181
181
  content_type = case params[:format]
182
182
  when "json" then "application/json"
183
183
  else "text/html"
@@ -242,13 +242,13 @@ module Apipie
242
242
 
243
243
  # initialize variables for gathering dsl data
244
244
  def init_env
245
- @resource_descriptions ||= HashWithIndifferentAccess.new { |h, version| h[version] = {} }
246
- @controller_to_resource_id ||= {}
247
- @param_groups ||= {}
245
+ @resource_descriptions = HashWithIndifferentAccess.new { |h, version| h[version] = {} }
246
+ @controller_to_resource_id = {}
247
+ @param_groups = {}
248
248
  @swagger_generator = Apipie::SwaggerGenerator.new(self)
249
249
 
250
250
  # what versions does the controller belong in (specified by resource_description)?
251
- @controller_versions ||= Hash.new { |h, controller| h[controller.to_s] = [] }
251
+ @controller_versions = Hash.new { |h, controller| h[controller.to_s] = [] }
252
252
  end
253
253
 
254
254
  def recorded_examples
@@ -139,7 +139,7 @@ module Apipie
139
139
  #
140
140
  # Example:
141
141
  # api :desc => "Show user profile", :path => "/users/", :version => '1.0 - 3.4.2012'
142
- # param :id, Fixnum, :desc => "User ID", :required => true
142
+ # param :id, Integer, :desc => "User ID", :required => true
143
143
  # desc <<-EOS
144
144
  # Long description...
145
145
  # EOS
@@ -278,7 +278,7 @@ module Apipie
278
278
  end
279
279
  end
280
280
 
281
- if (Apipie.configuration.validate == :implicitly || Apipie.configuration.validate == true)
281
+ if Apipie.configuration.validate == :implicitly || Apipie.configuration.validate == true
282
282
  old_method = instance_method(description.method)
283
283
 
284
284
  define_method(description.method) do |*args|
@@ -360,7 +360,7 @@ module Apipie
360
360
  # Reuses param group for this method. The definition is looked up
361
361
  # in scope of this controller. If the group was defined in
362
362
  # different controller, the second param can be used to specify it.
363
- # when using action_aware parmas, you can specify :as =>
363
+ # when using action_aware params, you can specify :as =>
364
364
  # :create or :update to explicitly say how it should behave
365
365
  def param_group(name, scope_or_options = nil, options = {})
366
366
  if scope_or_options.is_a? Hash
@@ -533,7 +533,7 @@ module Apipie
533
533
  end
534
534
 
535
535
  def _apipie_perform_concern_subst(string)
536
- return _apipie_concern_subst.reduce(string) do |ret, (key, val)|
536
+ _apipie_concern_subst.reduce(string) do |ret, (key, val)|
537
537
  ret.gsub(":#{key}", val)
538
538
  end
539
539
  end
@@ -116,7 +116,7 @@ module Apipie
116
116
 
117
117
  def convert_file_value hash
118
118
  hash.each do |k, v|
119
- if (v.is_a?(Rack::Test::UploadedFile) || v.is_a?(ActionDispatch::Http::UploadedFile))
119
+ if v.is_a?(Rack::Test::UploadedFile) || v.is_a?(ActionDispatch::Http::UploadedFile)
120
120
  hash[k] = "<FILE CONTENT '#{v.original_filename}'>"
121
121
  elsif v.is_a?(Hash)
122
122
  hash[k] = convert_file_value(v)
@@ -190,7 +190,7 @@ module Apipie
190
190
  end
191
191
 
192
192
  def load_old_examples
193
- if File.exists?(@examples_file)
193
+ if File.exist?(@examples_file)
194
194
  if defined? SafeYAML
195
195
  return YAML.load_file(@examples_file, :safe=>false)
196
196
  else
@@ -295,7 +295,7 @@ module Apipie
295
295
  end
296
296
 
297
297
  def controller_content
298
- raise ControllerNotFound.new unless controller_path && File.exists?(controller_path)
298
+ raise ControllerNotFound.new unless controller_path && File.exist?(controller_path)
299
299
  @controller_content ||= File.read(controller_path)
300
300
  end
301
301
 
@@ -323,7 +323,7 @@ module Apipie
323
323
  desc ||= case @action.to_s
324
324
  when "show", "create", "update", "destroy"
325
325
  name = name.singularize
326
- "#{@action.capitalize} #{name =~ /^[aeiou]/ ? "an" : "a"} #{name}"
326
+ "#{@action.capitalize} #{name =~ /^[aeiou]/ ? 'an' : 'a'} #{name}"
327
327
  when "index"
328
328
  "List #{name}"
329
329
  end
@@ -0,0 +1,2 @@
1
+ module Apipie::Generator
2
+ end
@@ -0,0 +1,2 @@
1
+ module Apipie::Generator::Swagger
2
+ end
@@ -0,0 +1,16 @@
1
+ class Apipie::Generator::Swagger::Type
2
+ attr_reader :str_format
3
+
4
+ def initialize(type, str_format = nil)
5
+ @type = type
6
+ @str_format = str_format
7
+ end
8
+
9
+ def to_s
10
+ @type
11
+ end
12
+
13
+ def ==(other)
14
+ other.to_s == self.to_s
15
+ end
16
+ end
@@ -0,0 +1,70 @@
1
+ class Apipie::Generator::Swagger::TypeExtractor
2
+ TYPES = {
3
+ numeric: 'number',
4
+ hash: 'object',
5
+ array: 'array',
6
+ enum: 'enum',
7
+
8
+ # see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types
9
+ integer: Apipie::Generator::Swagger::Type.new('integer', 'int32'),
10
+ long: Apipie::Generator::Swagger::Type.new('integer', 'int64'),
11
+ number: Apipie::Generator::Swagger::Type.new('number'),
12
+ float: Apipie::Generator::Swagger::Type.new('number', 'float'),
13
+ double: Apipie::Generator::Swagger::Type.new('number', 'double'),
14
+ string: Apipie::Generator::Swagger::Type.new('string'),
15
+ byte: Apipie::Generator::Swagger::Type.new('string', 'byte'),
16
+ binary: Apipie::Generator::Swagger::Type.new('string', 'binary'),
17
+ boolean: Apipie::Generator::Swagger::Type.new('boolean'),
18
+ date: Apipie::Generator::Swagger::Type.new('string', 'date'),
19
+ dateTime: Apipie::Generator::Swagger::Type.new('string', 'date-time'),
20
+ password: Apipie::Generator::Swagger::Type.new('string', 'password')
21
+ }
22
+
23
+ # @param [Apipie::Validator::BaseValidator, ResponseDescriptionAdapter::PropDesc::Validator, nil] validator
24
+ def initialize(validator)
25
+ @validator = validator
26
+ end
27
+
28
+ # @param [Hash<Symbol, Apipie::Generator::Swagger::Warning>] warnings
29
+ def extract_with_warnings(warnings = {})
30
+ if boolean? && warnings[:boolean].present?
31
+ Apipie::Generator::Swagger::WarningWriter.instance.warn(warnings[:boolean])
32
+ end
33
+
34
+ extract
35
+ end
36
+
37
+ private
38
+
39
+ def extract
40
+ expected_type =
41
+ if string?
42
+ :string
43
+ elsif boolean?
44
+ :boolean
45
+ elsif enum?
46
+ :enum
47
+ else
48
+ @validator.expected_type.to_sym
49
+ end
50
+
51
+ TYPES[expected_type] || @validator.expected_type
52
+ end
53
+
54
+ def string?
55
+ @validator.blank?
56
+ end
57
+
58
+ def enum?
59
+ @validator.is_a?(Apipie::Validator::EnumValidator) ||
60
+ (@validator.respond_to?(:is_enum?) && @validator.is_enum?)
61
+ end
62
+
63
+ def boolean?
64
+ @_boolean ||= enum? && boolean_values?
65
+ end
66
+
67
+ def boolean_values?
68
+ @validator.values.to_set == Set.new([true, false])
69
+ end
70
+ end
@@ -0,0 +1,77 @@
1
+ class Apipie::Generator::Swagger::Warning
2
+ MISSING_METHOD_SUMMARY_CODE = 100
3
+ ADDED_MISSING_SLASH_CODE = 101
4
+ NO_RETURN_CODES_SPECIFIED_CODE = 102
5
+ HASH_WITHOUT_INTERNAL_TYPESPEC_CODE = 103
6
+ OPTIONAL_PARAM_IN_PATH_CODE = 104
7
+ OPTIONAL_WITHOUT_DEFAULT_VALUE_CODE = 105
8
+ PARAM_IGNORED_IN_FORM_DATA_CODE = 106
9
+ PATH_PARAM_NOT_DESCRIBED_CODE = 107
10
+ INFERRING_BOOLEAN_CODE = 108
11
+
12
+ CODES = {
13
+ missing_method_summary: MISSING_METHOD_SUMMARY_CODE,
14
+ added_missing_slash: ADDED_MISSING_SLASH_CODE,
15
+ no_return_codes_specified: NO_RETURN_CODES_SPECIFIED_CODE,
16
+ hash_without_internal_typespec: HASH_WITHOUT_INTERNAL_TYPESPEC_CODE,
17
+ optional_param_in_path: OPTIONAL_PARAM_IN_PATH_CODE,
18
+ optional_without_default_value: OPTIONAL_WITHOUT_DEFAULT_VALUE_CODE,
19
+ param_ignored_in_form_data: PARAM_IGNORED_IN_FORM_DATA_CODE,
20
+ path_param_not_described_code: PATH_PARAM_NOT_DESCRIBED_CODE,
21
+ inferring_boolean: INFERRING_BOOLEAN_CODE
22
+ }
23
+
24
+ MESSAGES = {
25
+ MISSING_METHOD_SUMMARY_CODE => "Missing short description for method",
26
+ ADDED_MISSING_SLASH_CODE => "Added missing / at beginning of path: %{path}",
27
+ HASH_WITHOUT_INTERNAL_TYPESPEC_CODE => "The parameter :%{parameter} is a generic Hash without an internal type specification",
28
+ NO_RETURN_CODES_SPECIFIED_CODE => "No return codes ('errors') specified",
29
+ OPTIONAL_PARAM_IN_PATH_CODE => "The parameter :%{parameter} is 'in-path'. Ignoring 'not required' in DSL",
30
+ OPTIONAL_WITHOUT_DEFAULT_VALUE_CODE => "The parameter :%{parameter} is optional but default value is not specified (use :default_value => ...)",
31
+ PARAM_IGNORED_IN_FORM_DATA_CODE => "Ignoring param :%{parameter} -- cannot include Hash without fields in a formData specification",
32
+ PATH_PARAM_NOT_DESCRIBED_CODE => "The parameter :%{name} appears in the path %{path} but is not described",
33
+ INFERRING_BOOLEAN_CODE => "The parameter [%{parameter}] is Enum with [true, false] values. Inferring 'boolean'"
34
+ }
35
+
36
+ attr_reader :code
37
+
38
+ def initialize(code, info_message, method_id)
39
+ @code = code
40
+ @info_message = info_message
41
+ @method_id = method_id
42
+ end
43
+
44
+ def id
45
+ "#{@method_id}#{@code}#{@info_message}"
46
+ end
47
+
48
+ def warning_message
49
+ "WARNING (#{@code}): [#{@method_id}] -- #{@info_message}"
50
+ end
51
+
52
+ def warn
53
+ Warning.warn(warning_message)
54
+ end
55
+
56
+ def warn_through_writer
57
+ Apipie::Generator::Swagger::WarningWriter.instance.warn(self)
58
+ end
59
+
60
+ # @param [Integer] code
61
+ # @param [Hash] message_attributes
62
+ #
63
+ # @return [Apipie::Generator::Swagger::Warning]
64
+ def self.for_code(code, method_id, message_attributes = {})
65
+ if !CODES.values.include?(code)
66
+ raise ArgumentError, 'Unknown warning code'
67
+ end
68
+
69
+ info_message = if message_attributes.present?
70
+ self::MESSAGES[code] % message_attributes
71
+ else
72
+ self::MESSAGES[code]
73
+ end
74
+
75
+ Apipie::Generator::Swagger::Warning.new(code, info_message, method_id)
76
+ end
77
+ end
@@ -0,0 +1,48 @@
1
+ class Apipie::Generator::Swagger::WarningWriter
2
+ include Singleton
3
+
4
+ def initialize
5
+ @issued_warnings = []
6
+ end
7
+
8
+ # @param [Apipie::Generator::Swagger::Warning] warning
9
+ def warn(warning)
10
+ return if muted_warning?(warning)
11
+
12
+ warning.warn
13
+
14
+ @issued_warnings << warning.id
15
+ end
16
+
17
+ def issued_warnings?
18
+ @issued_warnings.count > 0
19
+ end
20
+
21
+ private
22
+
23
+ # @param [Apipie::Generator::Swagger::Warning] warning
24
+ #
25
+ # @return [TrueClass, FalseClass]
26
+ def muted_warning?(warning)
27
+ @issued_warnings.include?(warning.id) ||
28
+ suppressed_warning?(warning.code) ||
29
+ suppress_warnings?
30
+ end
31
+
32
+ # @param [Integer] warning_number
33
+ #
34
+ # @return [TrueClass, FalseClass]
35
+ def suppressed_warning?(warning_number)
36
+ suppress_warnings_config.is_a?(Array) && suppress_warnings_config.include?(warning_number)
37
+ end
38
+
39
+ # @return [TrueClass, FalseClass]
40
+ def suppress_warnings?
41
+ suppress_warnings_config == true
42
+ end
43
+
44
+ # @return [FalseClass, TrueClass, Array]
45
+ def suppress_warnings_config
46
+ Apipie.configuration.swagger_suppress_warnings
47
+ end
48
+ end
@@ -0,0 +1,12 @@
1
+ class Apipie::MethodDescription::Api
2
+ attr_accessor :short_description, :path, :http_method, :from_routes,
3
+ :options, :returns
4
+
5
+ def initialize(method, path, desc, options)
6
+ @http_method = method.to_s
7
+ @path = path
8
+ @short_description = desc
9
+ @from_routes = options[:from_routes]
10
+ @options = options
11
+ end
12
+ end
@@ -0,0 +1,82 @@
1
+ # Service that builds the appropriate Apipie::MethodDescription::Api
2
+ # required by Apipie::MethodDescription
3
+ #
4
+ class Apipie::MethodDescription::ApisService
5
+ # @param [Apipie::ResourceDescription] resource
6
+ # @param [Symbol] controller_action
7
+ # @param [Hash] dsl
8
+ def initialize(resource, controller_action, dsl)
9
+ @resource = resource
10
+ @controller_action = controller_action
11
+ @dsl = dsl
12
+ end
13
+
14
+ # @return [Array<Apipie::MethodDescription::Api>]
15
+ def call
16
+ api_args.map do |http_method, path, desc, opts|
17
+ Apipie::MethodDescription::Api.new(
18
+ http_method,
19
+ concern_subst(path),
20
+ concern_subst(desc),
21
+ opts
22
+ )
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def concern_subst(path)
29
+ return if path.blank?
30
+
31
+ if from_concern?
32
+ @resource.controller._apipie_perform_concern_subst(path)
33
+ else
34
+ path
35
+ end
36
+ end
37
+
38
+ # @return [Array<Array>]
39
+ def api_args
40
+ return @dsl[:api_args] if !api_from_routes?
41
+
42
+ api_args = @dsl[:api_args].dup
43
+
44
+ api_args_from_routes = routes.map do |route_info|
45
+ [
46
+ route_info[:verb],
47
+ route_info[:path],
48
+ route_info[:desc],
49
+ (route_info[:options] || {}).merge(from_routes: true)
50
+ ]
51
+ end
52
+
53
+ api_args.concat(api_args_from_routes)
54
+ end
55
+
56
+ def api_from_routes?
57
+ @dsl[:api_from_routes].present?
58
+ end
59
+
60
+ def from_concern?
61
+ @dsl[:from_concern] == true
62
+ end
63
+
64
+ def description
65
+ @dsl[:api_from_routes][:desc]
66
+ end
67
+
68
+ def options
69
+ @dsl[:api_from_routes][:options]
70
+ end
71
+
72
+ # @return [Array<Hash>]
73
+ def routes
74
+ Apipie.routes_for_action(
75
+ @resource.controller,
76
+ @controller_action,
77
+ { desc: description, options: options }
78
+ )
79
+ end
80
+ end
81
+
82
+
@@ -1,22 +1,6 @@
1
- require 'set'
2
1
  module Apipie
3
2
 
4
3
  class MethodDescription
5
-
6
- class Api
7
-
8
- attr_accessor :short_description, :path, :http_method, :from_routes, :options, :returns
9
-
10
- def initialize(method, path, desc, options)
11
- @http_method = method.to_s
12
- @path = path
13
- @short_description = desc
14
- @from_routes = options[:from_routes]
15
- @options = options
16
- end
17
-
18
- end
19
-
20
4
  attr_reader :full_description, :method, :resource, :apis, :examples, :see, :formats, :headers, :show
21
5
  attr_accessor :metadata
22
6
 
@@ -24,9 +8,7 @@ module Apipie
24
8
  @method = method.to_s
25
9
  @resource = resource
26
10
  @from_concern = dsl_data[:from_concern]
27
- @apis = api_data(dsl_data).map do |mthd, path, desc, opts|
28
- MethodDescription::Api.new(mthd, concern_subst(path), concern_subst(desc), opts)
29
- end
11
+ @apis = ApisService.new(resource, method, dsl_data).call
30
12
 
31
13
  desc = dsl_data[:description] || ''
32
14
  @full_description = Apipie.markup_to_html(desc)
@@ -53,7 +35,7 @@ module Apipie
53
35
 
54
36
  @params_ordered = dsl_data[:params].map do |args|
55
37
  Apipie::ParamDescription.from_dsl_data(self, args)
56
- end.reject{|p| p.response_only? }
38
+ end.reject(&:response_only?)
57
39
 
58
40
  @params_ordered = ParamDescription.unify(@params_ordered)
59
41
  @headers = dsl_data[:headers]
@@ -102,7 +84,7 @@ module Apipie
102
84
  parent = Apipie.get_resource_description(@resource.controller.superclass)
103
85
 
104
86
  # get tags from parent resource description
105
- parent_tags = [parent, @resource].compact.flat_map { |resource| resource._tag_list_arg }
87
+ parent_tags = [parent, @resource].compact.flat_map(&:_tag_list_arg)
106
88
  Apipie::TagListDescription.new((parent_tags + @tag_list).uniq.compact)
107
89
  end
108
90
 
@@ -203,23 +185,6 @@ module Apipie
203
185
 
204
186
  private
205
187
 
206
- def api_data(dsl_data)
207
- ret = dsl_data[:api_args].dup
208
- if dsl_data[:api_from_routes]
209
- desc = dsl_data[:api_from_routes][:desc]
210
- options = dsl_data[:api_from_routes][:options]
211
-
212
- api_from_routes = Apipie.routes_for_action(resource.controller, method, {:desc => desc, :options => options}).map do |route_info|
213
- [route_info[:verb],
214
- route_info[:path],
215
- route_info[:desc],
216
- (route_info[:options] || {}).merge(:from_routes => true)]
217
- end
218
- ret.concat(api_from_routes)
219
- end
220
- ret
221
- end
222
-
223
188
  def merge_params(params, new_params)
224
189
  new_param_names = Set.new(new_params.map(&:name))
225
190
  params.delete_if { |p| new_param_names.include?(p.name) }
@@ -259,16 +224,6 @@ module Apipie
259
224
  example << "\n" << format_example_data(ex[:response_data]).to_s if ex[:response_data]
260
225
  example
261
226
  end
262
-
263
- def concern_subst(string)
264
- return if string.nil?
265
- if from_concern?
266
- resource.controller._apipie_perform_concern_subst(string)
267
- else
268
- string
269
- end
270
- end
271
-
272
227
  end
273
228
 
274
229
  end
@@ -7,7 +7,7 @@ module Apipie
7
7
  # path - relative path (/api/articles)
8
8
  # methods - array of keys to Apipie.method_descriptions (array of Apipie::MethodDescription)
9
9
  # name - human readable alias of resource (Articles)
10
- # id - resouce name
10
+ # id - resource name
11
11
  # formats - acceptable request/response format types
12
12
  # headers - array of headers
13
13
  # deprecated - boolean indicating if resource is deprecated