grape 0.12.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grape might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Appraisals +9 -4
- data/CHANGELOG.md +265 -215
- data/CONTRIBUTING.md +4 -4
- data/Gemfile +0 -1
- data/Gemfile.lock +166 -0
- data/README.md +426 -161
- data/RELEASING.md +14 -6
- data/Rakefile +30 -33
- data/UPGRADING.md +54 -23
- data/benchmark/simple.rb +27 -0
- data/gemfiles/rack_1.5.2.gemfile +13 -0
- data/gemfiles/rails_3.gemfile +2 -2
- data/gemfiles/rails_4.gemfile +1 -2
- data/grape.gemspec +6 -7
- data/lib/grape/api.rb +24 -4
- data/lib/grape/dsl/callbacks.rb +20 -0
- data/lib/grape/dsl/configuration.rb +59 -2
- data/lib/grape/dsl/helpers.rb +8 -3
- data/lib/grape/dsl/inside_route.rb +100 -45
- data/lib/grape/dsl/parameters.rb +96 -7
- data/lib/grape/dsl/request_response.rb +1 -1
- data/lib/grape/dsl/routing.rb +17 -4
- data/lib/grape/dsl/settings.rb +36 -1
- data/lib/grape/dsl/validations.rb +7 -5
- data/lib/grape/endpoint.rb +102 -57
- data/lib/grape/error_formatter/base.rb +6 -6
- data/lib/grape/exceptions/base.rb +5 -5
- data/lib/grape/exceptions/invalid_version_header.rb +10 -0
- data/lib/grape/exceptions/unknown_parameter.rb +10 -0
- data/lib/grape/exceptions/validation_errors.rb +4 -3
- data/lib/grape/formatter/serializable_hash.rb +3 -2
- data/lib/grape/http/headers.rb +0 -1
- data/lib/grape/locale/en.yml +5 -1
- data/lib/grape/middleware/auth/base.rb +2 -2
- data/lib/grape/middleware/auth/dsl.rb +1 -1
- data/lib/grape/middleware/auth/strategies.rb +1 -1
- data/lib/grape/middleware/base.rb +8 -4
- data/lib/grape/middleware/error.rb +3 -2
- data/lib/grape/middleware/filter.rb +1 -1
- data/lib/grape/middleware/formatter.rb +64 -45
- data/lib/grape/middleware/globals.rb +3 -3
- data/lib/grape/middleware/versioner/accept_version_header.rb +5 -7
- data/lib/grape/middleware/versioner/header.rb +113 -50
- data/lib/grape/middleware/versioner/param.rb +5 -8
- data/lib/grape/middleware/versioner/parse_media_type_patch.rb +20 -0
- data/lib/grape/middleware/versioner/path.rb +3 -6
- data/lib/grape/namespace.rb +13 -2
- data/lib/grape/path.rb +4 -3
- data/lib/grape/request.rb +40 -0
- data/lib/grape/route.rb +5 -0
- data/lib/grape/util/content_types.rb +9 -9
- data/lib/grape/util/env.rb +22 -0
- data/lib/grape/util/file_response.rb +21 -0
- data/lib/grape/util/inheritable_setting.rb +23 -2
- data/lib/grape/util/inheritable_values.rb +1 -1
- data/lib/grape/util/stackable_values.rb +5 -2
- data/lib/grape/util/strict_hash_configuration.rb +2 -1
- data/lib/grape/validations/attributes_iterator.rb +8 -3
- data/lib/grape/validations/params_scope.rb +164 -22
- data/lib/grape/validations/types/build_coercer.rb +53 -0
- data/lib/grape/validations/types/custom_type_coercer.rb +183 -0
- data/lib/grape/validations/types/file.rb +28 -0
- data/lib/grape/validations/types/json.rb +65 -0
- data/lib/grape/validations/types/multiple_type_coercer.rb +76 -0
- data/lib/grape/validations/types/variant_collection_coercer.rb +59 -0
- data/lib/grape/validations/types/virtus_collection_patch.rb +16 -0
- data/lib/grape/validations/types.rb +144 -0
- data/lib/grape/validations/validators/all_or_none.rb +1 -1
- data/lib/grape/validations/validators/allow_blank.rb +3 -3
- data/lib/grape/validations/validators/base.rb +7 -0
- data/lib/grape/validations/validators/coerce.rb +32 -34
- data/lib/grape/validations/validators/presence.rb +2 -3
- data/lib/grape/validations/validators/regexp.rb +2 -4
- data/lib/grape/validations/validators/values.rb +3 -3
- data/lib/grape/validations.rb +5 -0
- data/lib/grape/version.rb +2 -1
- data/lib/grape.rb +15 -12
- data/pkg/grape-0.13.0.gem +0 -0
- data/spec/grape/api/custom_validations_spec.rb +5 -4
- data/spec/grape/api/deeply_included_options_spec.rb +7 -7
- data/spec/grape/api/nested_helpers_spec.rb +4 -2
- data/spec/grape/api/shared_helpers_spec.rb +8 -8
- data/spec/grape/api_spec.rb +151 -54
- data/spec/grape/dsl/configuration_spec.rb +13 -0
- data/spec/grape/dsl/helpers_spec.rb +16 -2
- data/spec/grape/dsl/inside_route_spec.rb +40 -4
- data/spec/grape/dsl/parameters_spec.rb +0 -6
- data/spec/grape/dsl/routing_spec.rb +1 -1
- data/spec/grape/dsl/validations_spec.rb +18 -0
- data/spec/grape/endpoint_spec.rb +130 -6
- data/spec/grape/entity_spec.rb +10 -8
- data/spec/grape/exceptions/invalid_accept_header_spec.rb +1 -15
- data/spec/grape/exceptions/validation_errors_spec.rb +28 -0
- data/spec/grape/integration/rack_spec.rb +3 -2
- data/spec/grape/middleware/base_spec.rb +40 -16
- data/spec/grape/middleware/error_spec.rb +16 -15
- data/spec/grape/middleware/exception_spec.rb +45 -43
- data/spec/grape/middleware/formatter_spec.rb +34 -5
- data/spec/grape/middleware/versioner/header_spec.rb +79 -47
- data/spec/grape/path_spec.rb +10 -10
- data/spec/grape/presenters/presenter_spec.rb +2 -2
- data/spec/grape/request_spec.rb +100 -0
- data/spec/grape/util/inheritable_values_spec.rb +14 -0
- data/spec/grape/util/stackable_values_spec.rb +10 -0
- data/spec/grape/validations/params_scope_spec.rb +86 -0
- data/spec/grape/validations/types_spec.rb +95 -0
- data/spec/grape/validations/validators/coerce_spec.rb +364 -10
- data/spec/grape/validations/validators/values_spec.rb +27 -15
- data/spec/grape/validations_spec.rb +53 -24
- data/spec/shared/versioning_examples.rb +2 -2
- data/spec/spec_helper.rb +0 -1
- data/spec/support/versioned_helpers.rb +2 -2
- metadata +55 -14
- data/.gitignore +0 -46
- data/.rspec +0 -2
- data/.rubocop.yml +0 -7
- data/.rubocop_todo.yml +0 -84
- data/.travis.yml +0 -20
- data/.yardopts +0 -2
- data/lib/backports/active_support/deep_dup.rb +0 -49
- data/lib/backports/active_support/duplicable.rb +0 -88
- data/lib/grape/http/request.rb +0 -27
@@ -1,13 +1,13 @@
|
|
1
1
|
module Grape
|
2
2
|
class API
|
3
|
-
Boolean = Virtus::Attribute::Boolean
|
3
|
+
Boolean = Virtus::Attribute::Boolean
|
4
4
|
end
|
5
5
|
|
6
6
|
module Validations
|
7
7
|
class CoerceValidator < Base
|
8
8
|
def validate_param!(attr_name, params)
|
9
9
|
fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message_key: :coerce unless params.is_a? Hash
|
10
|
-
new_value = coerce_value(
|
10
|
+
new_value = coerce_value(params[attr_name])
|
11
11
|
if valid_type?(new_value)
|
12
12
|
params[attr_name] = new_value
|
13
13
|
else
|
@@ -15,52 +15,50 @@ module Grape
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
class InvalidValue; end
|
19
|
-
|
20
18
|
private
|
21
19
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
20
|
+
def valid_type?(val)
|
21
|
+
# Special value to denote coercion failure
|
22
|
+
return false if val.instance_of?(Types::InvalidValue)
|
27
23
|
|
28
|
-
|
29
|
-
# allow nil, to ignore when a parameter is absent
|
24
|
+
# Allow nil, to ignore when a parameter is absent
|
30
25
|
return true if val.nil?
|
31
|
-
if klass == Virtus::Attribute::Boolean
|
32
|
-
val.is_a?(TrueClass) || val.is_a?(FalseClass) || (val.is_a?(String) && val.empty?)
|
33
|
-
elsif klass == Rack::Multipart::UploadedFile
|
34
|
-
val.is_a?(Hashie::Mash) && val.key?(:tempfile)
|
35
|
-
elsif [DateTime, Date, Numeric].any? { |vclass| vclass >= klass }
|
36
|
-
return true if val.is_a?(String) && val.empty?
|
37
|
-
val.is_a?(klass)
|
38
|
-
else
|
39
|
-
val.is_a?(klass)
|
40
|
-
end
|
41
|
-
end
|
42
26
|
|
43
|
-
|
44
|
-
if @option.is_a?(Array) || @option.is_a?(Set)
|
45
|
-
_valid_array_type?(@option.first, val)
|
46
|
-
else
|
47
|
-
_valid_single_type?(@option, val)
|
48
|
-
end
|
27
|
+
converter.value_coerced? val
|
49
28
|
end
|
50
29
|
|
51
|
-
def coerce_value(
|
30
|
+
def coerce_value(val)
|
52
31
|
# Don't coerce things other than nil to Arrays or Hashes
|
53
|
-
|
54
|
-
|
55
|
-
|
32
|
+
unless (@option[:method] && !val.nil?) || type.is_a?(Virtus::Attribute)
|
33
|
+
return val || [] if type == Array
|
34
|
+
return val || Set.new if type == Set
|
35
|
+
return val || {} if type == Hash
|
36
|
+
end
|
56
37
|
|
57
|
-
converter = Virtus::Attribute.build(type)
|
58
38
|
converter.coerce(val)
|
59
39
|
|
60
40
|
# not the prettiest but some invalid coercion can currently trigger
|
61
41
|
# errors in Virtus (see coerce_spec.rb:75)
|
62
42
|
rescue
|
63
|
-
InvalidValue.new
|
43
|
+
Types::InvalidValue.new
|
44
|
+
end
|
45
|
+
|
46
|
+
# Type to which the parameter will be coerced.
|
47
|
+
#
|
48
|
+
# @return [Class]
|
49
|
+
def type
|
50
|
+
@option[:type]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Create and cache the attribute object
|
54
|
+
# that will be used for parameter coercion
|
55
|
+
# and type checking.
|
56
|
+
#
|
57
|
+
# See {Types.build_coercer}
|
58
|
+
#
|
59
|
+
# @return [Virtus::Attribute]
|
60
|
+
def converter
|
61
|
+
@converter ||= Types.build_coercer(type, @option[:method])
|
64
62
|
end
|
65
63
|
end
|
66
64
|
end
|
@@ -7,9 +7,8 @@ module Grape
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def validate_param!(attr_name, params)
|
10
|
-
|
11
|
-
|
12
|
-
end
|
10
|
+
return if params.respond_to?(:key?) && params.key?(attr_name)
|
11
|
+
fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message_key: :presence
|
13
12
|
end
|
14
13
|
end
|
15
14
|
end
|
@@ -2,10 +2,8 @@ module Grape
|
|
2
2
|
module Validations
|
3
3
|
class RegexpValidator < Base
|
4
4
|
def validate_param!(attr_name, params)
|
5
|
-
|
6
|
-
|
7
|
-
fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message_key: :regexp
|
8
|
-
end
|
5
|
+
return unless params.key?(attr_name) && !params[attr_name].nil? && !(params[attr_name].to_s =~ @option)
|
6
|
+
fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message_key: :regexp
|
9
7
|
end
|
10
8
|
end
|
11
9
|
end
|
@@ -7,13 +7,13 @@ module Grape
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def validate_param!(attr_name, params)
|
10
|
+
return unless params.is_a?(Hash)
|
10
11
|
return unless params[attr_name] || required_for_root_scope?
|
11
12
|
|
12
13
|
values = @values.is_a?(Proc) ? @values.call : @values
|
13
14
|
param_array = params[attr_name].nil? ? [nil] : Array.wrap(params[attr_name])
|
14
|
-
|
15
|
-
|
16
|
-
end
|
15
|
+
return if param_array.all? { |param| values.include?(param) }
|
16
|
+
fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message_key: :values
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
data/lib/grape/validations.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module Grape
|
2
|
+
# Registry to store and locate known Validators.
|
2
3
|
module Validations
|
3
4
|
class << self
|
4
5
|
attr_accessor :validators
|
@@ -6,6 +7,10 @@ module Grape
|
|
6
7
|
|
7
8
|
self.validators = {}
|
8
9
|
|
10
|
+
# Register a new validator, so it can be used to validate parameters.
|
11
|
+
# @param short_name [String] all lower-case, no spaces
|
12
|
+
# @param klass [Class] the validator class. Should inherit from
|
13
|
+
# Validations::Base.
|
9
14
|
def self.register_validator(short_name, klass)
|
10
15
|
validators[short_name] = klass
|
11
16
|
end
|
data/lib/grape/version.rb
CHANGED
data/lib/grape.rb
CHANGED
@@ -9,25 +9,21 @@ require 'hashie'
|
|
9
9
|
require 'set'
|
10
10
|
require 'active_support/version'
|
11
11
|
require 'active_support/core_ext/hash/indifferent_access'
|
12
|
-
|
13
|
-
if ActiveSupport::VERSION::MAJOR >= 4
|
14
|
-
require 'active_support/core_ext/object/deep_dup'
|
15
|
-
else
|
16
|
-
require_relative 'backports/active_support/deep_dup'
|
17
|
-
end
|
18
|
-
|
19
|
-
require 'active_support/ordered_hash'
|
20
|
-
require 'active_support/core_ext/object/conversions'
|
12
|
+
require 'active_support/core_ext/object/blank'
|
21
13
|
require 'active_support/core_ext/array/extract_options'
|
14
|
+
require 'active_support/core_ext/array/wrap'
|
22
15
|
require 'active_support/core_ext/hash/deep_merge'
|
16
|
+
require 'active_support/core_ext/hash/reverse_merge'
|
17
|
+
require 'active_support/core_ext/hash/except'
|
23
18
|
require 'active_support/dependencies/autoload'
|
24
|
-
require '
|
19
|
+
require 'active_support/notifications'
|
25
20
|
require 'multi_json'
|
26
21
|
require 'multi_xml'
|
27
|
-
require 'virtus'
|
28
22
|
require 'i18n'
|
29
23
|
require 'thread'
|
30
24
|
|
25
|
+
require 'virtus'
|
26
|
+
|
31
27
|
I18n.load_path << File.expand_path('../grape/locale/en.yml', __FILE__)
|
32
28
|
|
33
29
|
module Grape
|
@@ -44,7 +40,8 @@ module Grape
|
|
44
40
|
|
45
41
|
autoload :Cookies
|
46
42
|
autoload :Validations
|
47
|
-
autoload :Request
|
43
|
+
autoload :Request
|
44
|
+
autoload :Env, 'grape/util/env'
|
48
45
|
end
|
49
46
|
|
50
47
|
module Http
|
@@ -66,12 +63,14 @@ module Grape
|
|
66
63
|
autoload :InvalidVersionerOption
|
67
64
|
autoload :UnknownValidator
|
68
65
|
autoload :UnknownOptions
|
66
|
+
autoload :UnknownParameter
|
69
67
|
autoload :InvalidWithOptionForRepresent
|
70
68
|
autoload :IncompatibleOptionValues
|
71
69
|
autoload :MissingGroupTypeError, 'grape/exceptions/missing_group_type'
|
72
70
|
autoload :UnsupportedGroupTypeError, 'grape/exceptions/unsupported_group_type'
|
73
71
|
autoload :InvalidMessageBody
|
74
72
|
autoload :InvalidAcceptHeader
|
73
|
+
autoload :InvalidVersionHeader
|
75
74
|
end
|
76
75
|
|
77
76
|
module ErrorFormatter
|
@@ -129,6 +128,7 @@ module Grape
|
|
129
128
|
autoload :StackableValues
|
130
129
|
autoload :InheritableSetting
|
131
130
|
autoload :StrictHashConfiguration
|
131
|
+
autoload :FileResponse
|
132
132
|
end
|
133
133
|
|
134
134
|
module DSL
|
@@ -159,6 +159,8 @@ module Grape
|
|
159
159
|
end
|
160
160
|
end
|
161
161
|
|
162
|
+
require 'grape/util/content_types'
|
163
|
+
|
162
164
|
require 'grape/validations/validators/base'
|
163
165
|
require 'grape/validations/attributes_iterator'
|
164
166
|
require 'grape/validations/validators/allow_blank'
|
@@ -172,5 +174,6 @@ require 'grape/validations/validators/regexp'
|
|
172
174
|
require 'grape/validations/validators/values'
|
173
175
|
require 'grape/validations/params_scope'
|
174
176
|
require 'grape/validations/validators/all_or_none'
|
177
|
+
require 'grape/validations/types'
|
175
178
|
|
176
179
|
require 'grape/version'
|
Binary file
|
@@ -2,10 +2,11 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Grape::Validations do
|
4
4
|
before do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
module CustomValidationsSpec
|
6
|
+
class DefaultLength < Grape::Validations::Base
|
7
|
+
def validate_param!(attr_name, params)
|
8
|
+
@option = params[:max].to_i if params.key?(:max)
|
9
|
+
return if params[attr_name].length <= @option
|
9
10
|
fail Grape::Exceptions::Validation, params: [@scope.full_name(attr_name)], message: "must be at the most #{@option} characters long"
|
10
11
|
end
|
11
12
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
module
|
3
|
+
module DeeplyIncludedOptionsSpec
|
4
4
|
module Defaults
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
included do
|
@@ -11,11 +11,11 @@ module API
|
|
11
11
|
module Admin
|
12
12
|
module Defaults
|
13
13
|
extend ActiveSupport::Concern
|
14
|
-
include
|
14
|
+
include DeeplyIncludedOptionsSpec::Defaults
|
15
15
|
end
|
16
16
|
|
17
17
|
class Users < Grape::API
|
18
|
-
include
|
18
|
+
include DeeplyIncludedOptionsSpec::Admin::Defaults
|
19
19
|
|
20
20
|
resource :users do
|
21
21
|
get do
|
@@ -24,14 +24,14 @@ module API
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
27
|
-
end
|
28
27
|
|
29
|
-
class Main < Grape::API
|
30
|
-
|
28
|
+
class Main < Grape::API
|
29
|
+
mount DeeplyIncludedOptionsSpec::Admin::Users
|
30
|
+
end
|
31
31
|
end
|
32
32
|
|
33
33
|
describe Grape::API do
|
34
|
-
subject { Main }
|
34
|
+
subject { DeeplyIncludedOptionsSpec::Main }
|
35
35
|
|
36
36
|
def app
|
37
37
|
subject
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Grape::API::Helpers do
|
4
|
-
|
4
|
+
module NestedHelpersSpec
|
5
5
|
module HelperMethods
|
6
6
|
extend Grape::API::Helpers
|
7
7
|
def current_user
|
@@ -28,8 +28,10 @@ describe Grape::API::Helpers do
|
|
28
28
|
class Main < Grape::API
|
29
29
|
mount Nested
|
30
30
|
end
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
+
subject do
|
34
|
+
NestedHelpersSpec::Main
|
33
35
|
end
|
34
36
|
|
35
37
|
def app
|
@@ -1,18 +1,18 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Grape::API::Helpers do
|
4
|
-
|
5
|
-
|
4
|
+
subject do
|
5
|
+
shared_params = Module.new do
|
6
|
+
extend Grape::API::Helpers
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
params :pagination do
|
9
|
+
optional :page, type: Integer
|
10
|
+
optional :size, type: Integer
|
11
|
+
end
|
10
12
|
end
|
11
|
-
end
|
12
13
|
|
13
|
-
subject do
|
14
14
|
Class.new(Grape::API) do
|
15
|
-
helpers
|
15
|
+
helpers shared_params
|
16
16
|
format :json
|
17
17
|
|
18
18
|
params do
|