apipie-rails 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rubocop-challenger.yml +28 -0
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +37 -0
  5. data/.rubocop_todo.yml +2001 -0
  6. data/CHANGELOG.md +24 -0
  7. data/README.rst +45 -2
  8. data/Rakefile +0 -5
  9. data/apipie-rails.gemspec +11 -7
  10. data/lib/apipie/dsl_definition.rb +3 -3
  11. data/lib/apipie/extractor/writer.rb +2 -2
  12. data/lib/apipie/generator/generator.rb +2 -0
  13. data/lib/apipie/generator/swagger/swagger.rb +2 -0
  14. data/lib/apipie/generator/swagger/type.rb +16 -0
  15. data/lib/apipie/generator/swagger/type_extractor.rb +70 -0
  16. data/lib/apipie/generator/swagger/warning.rb +77 -0
  17. data/lib/apipie/generator/swagger/warning_writer.rb +48 -0
  18. data/lib/apipie/method_description/api.rb +12 -0
  19. data/lib/apipie/method_description/apis_service.rb +82 -0
  20. data/lib/apipie/method_description.rb +1 -46
  21. data/lib/apipie/param_description.rb +1 -1
  22. data/lib/apipie/swagger_generator.rb +76 -81
  23. data/lib/apipie/validator.rb +13 -0
  24. data/lib/apipie/version.rb +1 -1
  25. data/lib/apipie-rails.rb +9 -1
  26. data/lib/generators/apipie/install/install_generator.rb +1 -1
  27. data/lib/generators/apipie/views_generator.rb +1 -1
  28. data/lib/tasks/apipie.rake +2 -2
  29. data/spec/controllers/included_param_group_controller_spec.rb +13 -0
  30. data/spec/dummy/Rakefile +1 -1
  31. data/spec/dummy/app/controllers/included_param_group_controller.rb +19 -0
  32. data/spec/dummy/app/helpers/random_param_group.rb +8 -0
  33. data/spec/dummy/components/test_engine/test_engine.gemspec +1 -1
  34. data/spec/dummy/config/application.rb +1 -1
  35. data/spec/dummy/config/boot.rb +2 -2
  36. data/spec/dummy/config/environment.rb +1 -1
  37. data/spec/dummy/config/routes.rb +1 -0
  38. data/spec/dummy/config.ru +1 -1
  39. data/spec/dummy/script/rails +2 -2
  40. data/spec/lib/application_spec.rb +1 -1
  41. data/spec/lib/extractor/writer_spec.rb +7 -5
  42. data/spec/lib/generator/swagger/type_extractor_spec.rb +61 -0
  43. data/spec/lib/generator/swagger/warning_spec.rb +51 -0
  44. data/spec/lib/generator/swagger/warning_writer_spec.rb +59 -0
  45. data/spec/lib/method_description/apis_service_spec.rb +60 -0
  46. data/spec/lib/param_description_spec.rb +18 -0
  47. data/spec/lib/rake_spec.rb +1 -1
  48. data/spec/lib/swagger/rake_swagger_spec.rb +4 -4
  49. data/spec/spec_helper.rb +8 -4
  50. data/spec/support/custom_bool_validator.rb +17 -0
  51. metadata +49 -30
data/CHANGELOG.md CHANGED
@@ -4,6 +4,30 @@
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
+
8
+
9
+ ## [v0.9.0](https://github.com/Apipie/apipie-rails/tree/v0.9.0) (2023-01-03)
10
+ [Full Changelog](https://github.com/Apipie/apipie-rails/compare/v0.8.2...v0.9.0)
11
+ * [Refactor] Move Swagger types and warnings under `/generator` namespace [#803](https://github.com/Apipie/apipie-rails/pull/803) (Panos Dalitsouris)
12
+ * [Refactor] Creates `Apipie::MethodDescription::ApisService` [#805](https://github.com/Apipie/apipie-rails/pull/805) (Panos Dalitsouris)
13
+ * [Refactor] Change output folder to `spec/dummy/tmp/` [#804](https://github.com/Apipie/apipie-rails/pull/804) (Panos Dalitsouris)
14
+ * Fix tiny typo in docs [#798](https://github.com/Apipie/apipie-rails/pull/798) (Erik-B. Ernst)
15
+ * Fix Generated docs.json output [#787](https://github.com/Apipie/apipie-rails/pull/787) (Jeremy Liberman)
16
+ * 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)
17
+ * Remove/clean up dev dependencies and unused rake tasks [#777](https://github.com/Apipie/apipie-rails/pull/777) (Mathieu Jobin)
18
+ - remove unused rake task
19
+ * Setup Rubocop Challenger [#776](https://github.com/Apipie/apipie-rails/pull/776) (Mathieu Jobin)
20
+
21
+ ## [v0.8.2](https://github.com/Apipie/apipie-rails/tree/v0.8.2) (2022-09-03)
22
+ [Full Changelog](https://github.com/Apipie/apipie-rails/compare/v0.8.1...v0.8.2)
23
+ * Allow custom validators to opt out of allow_blank behavior [#762](https://github.com/Apipie/apipie-rails/pull/762). (Stephen Hanson)
24
+ * Enforce test coverage, set current 89% as minimum [#764](https://github.com/Apipie/apipie-rails/pull/764). (Mathieu Jobin)
25
+ * Add contributing instructions to readme [#763](https://github.com/Apipie/apipie-rails/pull/763). (Stephen Hanson)
26
+ * Fix readme formatting [#765](https://github.com/Apipie/apipie-rails/pull/765). (Stephen Hanson)
27
+ * Adds expected_type to IntegerValidator example [#769](https://github.com/Apipie/apipie-rails/pull/769). (Jeremy Liberman)
28
+ * Update readme with error handling example [#768](https://github.com/Apipie/apipie-rails/pull/768). (Jesse Eisenberg)
29
+ * Fix scope incorrectly set to nil when a param_group is used inside an array_of_hash and the param_group is in a different module / controller. [#693](https://github.com/Apipie/apipie-rails/pull/693) [#774](https://github.com/Apipie/apipie-rails/pull/774). (Omkar Joshi / Oliver Iyer)
30
+
7
31
  ## [v0.8.1](https://github.com/Apipie/apipie-rails/tree/v0.8.1) (2022-05-26)
8
32
  [Full Changelog](https://github.com/Apipie/apipie-rails/compare/v0.8.0...v0.8.1)
9
33
  * Remove warning that came back as of [#752](https://github.com/Apipie/apipie-rails/pull/752). [#761](https://github.com/Apipie/apipie-rails/pull/761) (Jorge Santos / Mathieu Jobin)
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
@@ -1156,6 +1156,21 @@ is raised and can be rescued and processed. It contains a description
1156
1156
  of the parameter value expectations. Validations can be turned off
1157
1157
  in the configuration file.
1158
1158
 
1159
+ Here is an example of how to rescue and process a +ParamMissing+ or
1160
+ +ParamInvalid+ error from within the ApplicationController.
1161
+
1162
+ .. code:: ruby
1163
+
1164
+ class ApplicationController < ActionController::Base
1165
+
1166
+ # ParamError is superclass of ParamMissing, ParamInvalid
1167
+ rescue_from Apipie::ParamError do |e|
1168
+ render text: e.message, status: :unprocessable_entity
1169
+ end
1170
+
1171
+ # ...
1172
+ end
1173
+
1159
1174
  Parameter validation normally happens after before_actions, just before
1160
1175
  your controller method is invoked. If you prefer to control when parameter
1161
1176
  validation occurs, set the configuration parameter ``validate`` to ``:explicitly``.
@@ -1368,6 +1383,10 @@ So we create apipie_validators.rb initializer with this content:
1368
1383
  def description
1369
1384
  "Must be #{@type}."
1370
1385
  end
1386
+
1387
+ def expected_type
1388
+ 'numeric'
1389
+ end
1371
1390
  end
1372
1391
 
1373
1392
  Parameters of the build method:
@@ -1385,6 +1404,16 @@ options
1385
1404
  block
1386
1405
  Block converted into Proc, use it as you desire. In this example nil.
1387
1406
 
1407
+ If your validator includes valid values that respond true to `.blank?`, you
1408
+ should also define:
1409
+
1410
+ .. code:: ruby
1411
+
1412
+ def ignore_allow_blank?
1413
+ true
1414
+ end
1415
+
1416
+ so that the validation does not fail for valid values.
1388
1417
 
1389
1418
  ============
1390
1419
  Versioning
@@ -1872,6 +1901,20 @@ provided it uses Apipie as a backend.
1872
1901
 
1873
1902
  And if you write one on your own, don't hesitate to share it with us!
1874
1903
 
1904
+ ====================
1905
+ Contributing
1906
+ ====================
1907
+
1908
+ Since this gem does not have a Gemfile, you need to specify it in your shell with:
1909
+
1910
+ .. code:: shell
1911
+ BUNDLE_GEMFILE='gemfiles/Gemfile.rails61'
1912
+
1913
+ Then, you can install dependencies and run the test suite:
1914
+
1915
+ .. code:: shell
1916
+ > bundle install
1917
+ > bundle exec rspec
1875
1918
 
1876
1919
  ====================
1877
1920
  Disqus Integration
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,12 +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"
28
- s.add_development_dependency "json-schema", "~> 2.8"
30
+ s.add_development_dependency 'rubocop_challenger'
31
+ s.add_development_dependency "simplecov"
32
+ s.add_development_dependency "sqlite3"
29
33
  end
@@ -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)
@@ -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)
@@ -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
@@ -125,7 +125,7 @@ module Apipie
125
125
  end
126
126
 
127
127
  def blank_forbidden?
128
- !Apipie.configuration.ignore_allow_blank_false && !allow_blank && !validator.is_a?(Validator::BooleanValidator)
128
+ !Apipie.configuration.ignore_allow_blank_false && !allow_blank && !validator.ignore_allow_blank?
129
129
  end
130
130
 
131
131
  def process_value(value)