grape 1.5.3 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +23 -3
  4. data/UPGRADING.md +43 -1
  5. data/grape.gemspec +5 -5
  6. data/lib/grape/api/instance.rb +13 -17
  7. data/lib/grape/api.rb +5 -12
  8. data/lib/grape/cookies.rb +2 -0
  9. data/lib/grape/dsl/desc.rb +3 -5
  10. data/lib/grape/dsl/helpers.rb +6 -4
  11. data/lib/grape/dsl/inside_route.rb +17 -8
  12. data/lib/grape/dsl/middleware.rb +4 -4
  13. data/lib/grape/dsl/parameters.rb +3 -3
  14. data/lib/grape/dsl/request_response.rb +9 -6
  15. data/lib/grape/dsl/routing.rb +2 -2
  16. data/lib/grape/dsl/settings.rb +5 -5
  17. data/lib/grape/endpoint.rb +20 -35
  18. data/lib/grape/error_formatter/json.rb +2 -6
  19. data/lib/grape/error_formatter/xml.rb +2 -6
  20. data/lib/grape/exceptions/validation.rb +1 -2
  21. data/lib/grape/formatter/json.rb +1 -0
  22. data/lib/grape/formatter/serializable_hash.rb +2 -1
  23. data/lib/grape/formatter/xml.rb +1 -0
  24. data/lib/grape/middleware/base.rb +2 -0
  25. data/lib/grape/middleware/formatter.rb +4 -4
  26. data/lib/grape/middleware/stack.rb +2 -2
  27. data/lib/grape/middleware/versioner/accept_version_header.rb +3 -5
  28. data/lib/grape/middleware/versioner/header.rb +6 -4
  29. data/lib/grape/middleware/versioner/param.rb +1 -0
  30. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +2 -1
  31. data/lib/grape/middleware/versioner/path.rb +2 -0
  32. data/lib/grape/path.rb +1 -0
  33. data/lib/grape/request.rb +1 -0
  34. data/lib/grape/router/pattern.rb +1 -1
  35. data/lib/grape/router/route.rb +2 -2
  36. data/lib/grape/router.rb +6 -0
  37. data/lib/grape/util/inheritable_setting.rb +1 -3
  38. data/lib/grape/util/lazy_value.rb +3 -2
  39. data/lib/grape/validations/params_scope.rb +88 -55
  40. data/lib/grape/validations/types/custom_type_coercer.rb +1 -0
  41. data/lib/grape/validations/types/dry_type_coercer.rb +1 -1
  42. data/lib/grape/validations/types/json.rb +2 -1
  43. data/lib/grape/validations/types/primitive_coercer.rb +3 -3
  44. data/lib/grape/validations/validators/all_or_none.rb +1 -0
  45. data/lib/grape/validations/validators/as.rb +4 -8
  46. data/lib/grape/validations/validators/at_least_one_of.rb +1 -0
  47. data/lib/grape/validations/validators/base.rb +4 -1
  48. data/lib/grape/validations/validators/coerce.rb +1 -5
  49. data/lib/grape/validations/validators/default.rb +1 -0
  50. data/lib/grape/validations/validators/exactly_one_of.rb +1 -0
  51. data/lib/grape/validations/validators/multiple_params_base.rb +2 -0
  52. data/lib/grape/validations/validators/mutual_exclusion.rb +1 -0
  53. data/lib/grape/validations/validators/presence.rb +1 -0
  54. data/lib/grape/validations/validators/regexp.rb +1 -0
  55. data/lib/grape/validations/validators/same_as.rb +1 -0
  56. data/lib/grape/validations/validators/values.rb +3 -0
  57. data/lib/grape/version.rb +1 -1
  58. data/lib/grape.rb +1 -1
  59. data/spec/grape/api/custom_validations_spec.rb +1 -0
  60. data/spec/grape/api/routes_with_requirements_spec.rb +8 -8
  61. data/spec/grape/api_spec.rb +126 -37
  62. data/spec/grape/dsl/callbacks_spec.rb +1 -1
  63. data/spec/grape/dsl/middleware_spec.rb +1 -1
  64. data/spec/grape/dsl/parameters_spec.rb +1 -0
  65. data/spec/grape/dsl/routing_spec.rb +1 -1
  66. data/spec/grape/endpoint/declared_spec.rb +247 -0
  67. data/spec/grape/endpoint_spec.rb +5 -5
  68. data/spec/grape/entity_spec.rb +9 -9
  69. data/spec/grape/middleware/auth/dsl_spec.rb +1 -1
  70. data/spec/grape/middleware/error_spec.rb +1 -2
  71. data/spec/grape/middleware/formatter_spec.rb +2 -2
  72. data/spec/grape/middleware/stack_spec.rb +3 -1
  73. data/spec/grape/validations/params_scope_spec.rb +37 -3
  74. data/spec/grape/validations/single_attribute_iterator_spec.rb +1 -1
  75. data/spec/grape/validations/types/primitive_coercer_spec.rb +2 -2
  76. data/spec/grape/validations/validators/coerce_spec.rb +13 -10
  77. data/spec/grape/validations/validators/except_values_spec.rb +2 -2
  78. data/spec/grape/validations/validators/values_spec.rb +15 -11
  79. data/spec/grape/validations_spec.rb +54 -42
  80. data/spec/shared/versioning_examples.rb +2 -2
  81. data/spec/spec_helper.rb +1 -1
  82. data/spec/support/basic_auth_encode_helpers.rb +1 -1
  83. metadata +6 -6
@@ -98,6 +98,7 @@ describe Grape::Validations::ParamsScope do
98
98
 
99
99
  def self.parse(value)
100
100
  raise if value == 'invalid'
101
+
101
102
  new(value)
102
103
  end
103
104
 
@@ -144,7 +145,7 @@ describe Grape::Validations::ParamsScope do
144
145
  get '/renaming-coerced', foo: ' there we go '
145
146
 
146
147
  expect(last_response.status).to eq(200)
147
- expect(last_response.body).to eq('there we go-')
148
+ expect(last_response.body).to eq('-there we go')
148
149
  end
149
150
 
150
151
  it do
@@ -180,6 +181,28 @@ describe Grape::Validations::ParamsScope do
180
181
  expect(last_response.status).to eq(200)
181
182
  expect(last_response.body).to eq('{"baz":{"qux":"any"}}')
182
183
  end
184
+
185
+ it 'renaming can be defined before default' do
186
+ subject.params do
187
+ optional :foo, as: :bar, default: 'before'
188
+ end
189
+ subject.get('/rename-before-default') { declared(params)[:bar] }
190
+ get '/rename-before-default'
191
+
192
+ expect(last_response.status).to eq(200)
193
+ expect(last_response.body).to eq('before')
194
+ end
195
+
196
+ it 'renaming can be defined after default' do
197
+ subject.params do
198
+ optional :foo, default: 'after', as: :bar
199
+ end
200
+ subject.get('/rename-after-default') { declared(params)[:bar] }
201
+ get '/rename-after-default'
202
+
203
+ expect(last_response.status).to eq(200)
204
+ expect(last_response.body).to eq('after')
205
+ end
183
206
  end
184
207
 
185
208
  context 'array without coerce type explicitly given' do
@@ -568,7 +591,7 @@ describe Grape::Validations::ParamsScope do
568
591
  it 'allows renaming of dependent on parameter' do
569
592
  subject.params do
570
593
  optional :a, as: :b
571
- given b: ->(val) { val == 'x' } do
594
+ given a: ->(val) { val == 'x' } do
572
595
  requires :c
573
596
  end
574
597
  end
@@ -582,7 +605,7 @@ describe Grape::Validations::ParamsScope do
582
605
  expect(last_response.status).to eq 200
583
606
  end
584
607
 
585
- it 'raises an error if the dependent parameter is not the renamed one' do
608
+ it 'does not raise if the dependent parameter is not the renamed one' do
586
609
  expect do
587
610
  subject.params do
588
611
  optional :a, as: :b
@@ -590,6 +613,17 @@ describe Grape::Validations::ParamsScope do
590
613
  requires :c
591
614
  end
592
615
  end
616
+ end.not_to raise_error
617
+ end
618
+
619
+ it 'raises an error if the dependent parameter is the renamed one' do
620
+ expect do
621
+ subject.params do
622
+ optional :a, as: :b
623
+ given :b do
624
+ requires :c
625
+ end
626
+ end
593
627
  end.to raise_error(Grape::Exceptions::UnknownParameter)
594
628
  end
595
629
 
@@ -49,7 +49,7 @@ describe Grape::Validations::SingleAttributeIterator do
49
49
  it 'marks params with skipped values' do
50
50
  expect { |b| iterator.each(&b) }.to yield_successive_args(
51
51
  [params[0], :first, false, true], [params[0], :second, false, true],
52
- [params[1], :first, false, false], [params[1], :second, false, false],
52
+ [params[1], :first, false, false], [params[1], :second, false, false]
53
53
  )
54
54
  end
55
55
  end
@@ -12,7 +12,7 @@ describe Grape::Validations::Types::PrimitiveCoercer do
12
12
  let(:type) { BigDecimal }
13
13
 
14
14
  it 'coerces to BigDecimal' do
15
- expect(subject.call(5)).to eq(BigDecimal(5))
15
+ expect(subject.call(5)).to eq(BigDecimal('5'))
16
16
  end
17
17
 
18
18
  it 'coerces an empty string to nil' do
@@ -127,7 +127,7 @@ describe Grape::Validations::Types::PrimitiveCoercer do
127
127
  end
128
128
 
129
129
  it 'returns a value as it is when the given value is BigDecimal' do
130
- expect(subject.call(BigDecimal(0))).to eq(BigDecimal(0))
130
+ expect(subject.call(BigDecimal('0'))).to eq(BigDecimal('0'))
131
131
  end
132
132
  end
133
133
  end
@@ -31,9 +31,9 @@ describe Grape::Validations::CoerceValidator do
31
31
 
32
32
  it 'i18n error on malformed input' do
33
33
  I18n.available_locales = %i[en zh-CN]
34
- I18n.load_path << File.expand_path('../zh-CN.yml', __FILE__)
34
+ I18n.load_path << File.expand_path('zh-CN.yml', __dir__)
35
35
  I18n.reload!
36
- I18n.locale = 'zh-CN'.to_sym
36
+ I18n.locale = :'zh-CN'
37
37
  subject.params do
38
38
  requires :age, type: Integer
39
39
  end
@@ -48,7 +48,7 @@ describe Grape::Validations::CoerceValidator do
48
48
 
49
49
  it 'gives an english fallback error when default locale message is blank' do
50
50
  I18n.available_locales = %i[en pt-BR]
51
- I18n.locale = 'pt-BR'.to_sym
51
+ I18n.locale = :'pt-BR'
52
52
  subject.params do
53
53
  requires :age, type: Integer
54
54
  end
@@ -84,9 +84,10 @@ describe Grape::Validations::CoerceValidator do
84
84
  before do
85
85
  subject.params do
86
86
  requires :a, types: { value: [Boolean, String], message: 'type cast is invalid' }, coerce_with: (lambda do |val|
87
- if val == 'yup'
87
+ case val
88
+ when 'yup'
88
89
  true
89
- elsif val == 'false'
90
+ when 'false'
90
91
  0
91
92
  else
92
93
  val
@@ -650,7 +651,7 @@ describe Grape::Validations::CoerceValidator do
650
651
 
651
652
  it 'parses parameters with Array[Array[String]] type and coerce_with' do
652
653
  subject.params do
653
- requires :values, type: Array[Array[String]], coerce_with: ->(val) { val.is_a?(String) ? [val.split(/,/).map(&:strip)] : val }
654
+ requires :values, type: Array[Array[String]], coerce_with: ->(val) { val.is_a?(String) ? [val.split(',').map(&:strip)] : val }
654
655
  end
655
656
  subject.post '/coerce_nested_strings' do
656
657
  params[:values]
@@ -834,9 +835,10 @@ describe Grape::Validations::CoerceValidator do
834
835
  before do
835
836
  subject.params do
836
837
  requires :int, type: Integer, coerce_with: (lambda do |val|
837
- if val == '0'
838
+ case val
839
+ when '0'
838
840
  nil
839
- elsif val.match?(/^-?\d+$/)
841
+ when /^-?\d+$/
840
842
  val.to_i
841
843
  else
842
844
  val
@@ -1201,9 +1203,10 @@ describe Grape::Validations::CoerceValidator do
1201
1203
  before do
1202
1204
  subject.params do
1203
1205
  requires :a, types: [Boolean, String], coerce_with: (lambda do |val|
1204
- if val == 'yup'
1206
+ case val
1207
+ when 'yup'
1205
1208
  true
1206
- elsif val == 'false'
1209
+ when 'false'
1207
1210
  0
1208
1211
  else
1209
1212
  val
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  describe Grape::Validations::ExceptValuesValidator do
6
6
  module ValidationsSpec
7
7
  class ExceptValuesModel
8
- DEFAULT_EXCEPTS = ['invalid-type1', 'invalid-type2', 'invalid-type3'].freeze
8
+ DEFAULT_EXCEPTS = %w[invalid-type1 invalid-type2 invalid-type3].freeze
9
9
  class << self
10
10
  attr_accessor :excepts
11
11
 
@@ -170,7 +170,7 @@ describe Grape::Validations::ExceptValuesValidator do
170
170
  it 'raises IncompatibleOptionValues when type is incompatible with values array' do
171
171
  subject = Class.new(Grape::API)
172
172
  expect do
173
- subject.params { optional :type, except_values: ['valid-type1', 'valid-type2', 'valid-type3'], type: Symbol }
173
+ subject.params { optional :type, except_values: %w[valid-type1 valid-type2 valid-type3], type: Symbol }
174
174
  end.to raise_error Grape::Exceptions::IncompatibleOptionValues
175
175
  end
176
176
 
@@ -5,8 +5,8 @@ require 'spec_helper'
5
5
  describe Grape::Validations::ValuesValidator do
6
6
  module ValidationsSpec
7
7
  class ValuesModel
8
- DEFAULT_VALUES = ['valid-type1', 'valid-type2', 'valid-type3'].freeze
9
- DEFAULT_EXCEPTS = ['invalid-type1', 'invalid-type2', 'invalid-type3'].freeze
8
+ DEFAULT_VALUES = %w[valid-type1 valid-type2 valid-type3].freeze
9
+ DEFAULT_EXCEPTS = %w[invalid-type1 invalid-type2 invalid-type3].freeze
10
10
  class << self
11
11
  def values
12
12
  @values ||= []
@@ -27,6 +27,10 @@ describe Grape::Validations::ValuesValidator do
27
27
  @excepts ||= []
28
28
  @excepts << except
29
29
  end
30
+
31
+ def include?(value)
32
+ values.include?(value)
33
+ end
30
34
  end
31
35
  end
32
36
 
@@ -106,7 +110,7 @@ describe Grape::Validations::ValuesValidator do
106
110
  end
107
111
 
108
112
  params do
109
- requires :type, values: ->(v) { ValuesModel.values.include? v }
113
+ requires :type, values: ->(v) { ValuesModel.include? v }
110
114
  end
111
115
  get '/lambda_val' do
112
116
  { type: params[:type] }
@@ -214,14 +218,14 @@ describe Grape::Validations::ValuesValidator do
214
218
  put '/optional_with_array_of_string_values'
215
219
 
216
220
  params do
217
- requires :type, values: { proc: ->(v) { ValuesModel.values.include? v } }
221
+ requires :type, values: { proc: ->(v) { ValuesModel.include? v } }
218
222
  end
219
223
  get '/proc' do
220
224
  { type: params[:type] }
221
225
  end
222
226
 
223
227
  params do
224
- requires :type, values: { proc: ->(v) { ValuesModel.values.include? v }, message: 'failed check' }
228
+ requires :type, values: { proc: ->(v) { ValuesModel.include? v }, message: 'failed check' }
225
229
  end
226
230
  get '/proc/message'
227
231
 
@@ -420,21 +424,21 @@ describe Grape::Validations::ValuesValidator do
420
424
  it 'raises IncompatibleOptionValues on an invalid default value from proc' do
421
425
  subject = Class.new(Grape::API)
422
426
  expect do
423
- subject.params { optional :type, values: ['valid-type1', 'valid-type2', 'valid-type3'], default: ValidationsSpec::ValuesModel.values.sample + '_invalid' }
427
+ subject.params { optional :type, values: %w[valid-type1 valid-type2 valid-type3], default: "#{ValidationsSpec::ValuesModel.values.sample}_invalid" }
424
428
  end.to raise_error Grape::Exceptions::IncompatibleOptionValues
425
429
  end
426
430
 
427
431
  it 'raises IncompatibleOptionValues on an invalid default value' do
428
432
  subject = Class.new(Grape::API)
429
433
  expect do
430
- subject.params { optional :type, values: ['valid-type1', 'valid-type2', 'valid-type3'], default: 'invalid-type' }
434
+ subject.params { optional :type, values: %w[valid-type1 valid-type2 valid-type3], default: 'invalid-type' }
431
435
  end.to raise_error Grape::Exceptions::IncompatibleOptionValues
432
436
  end
433
437
 
434
438
  it 'raises IncompatibleOptionValues when type is incompatible with values array' do
435
439
  subject = Class.new(Grape::API)
436
440
  expect do
437
- subject.params { optional :type, values: ['valid-type1', 'valid-type2', 'valid-type3'], type: Symbol }
441
+ subject.params { optional :type, values: %w[valid-type1 valid-type2 valid-type3], type: Symbol }
438
442
  end.to raise_error Grape::Exceptions::IncompatibleOptionValues
439
443
  end
440
444
 
@@ -648,9 +652,9 @@ describe Grape::Validations::ValuesValidator do
648
652
  end
649
653
 
650
654
  it 'accepts multiple valid values' do
651
- get '/proc', type: ['valid-type1', 'valid-type3']
655
+ get '/proc', type: %w[valid-type1 valid-type3]
652
656
  expect(last_response.status).to eq 200
653
- expect(last_response.body).to eq({ type: ['valid-type1', 'valid-type3'] }.to_json)
657
+ expect(last_response.body).to eq({ type: %w[valid-type1 valid-type3] }.to_json)
654
658
  end
655
659
 
656
660
  it 'rejects a single invalid value' do
@@ -660,7 +664,7 @@ describe Grape::Validations::ValuesValidator do
660
664
  end
661
665
 
662
666
  it 'rejects an invalid value among valid ones' do
663
- get '/proc', type: ['valid-type1', 'invalid-type1', 'valid-type3']
667
+ get '/proc', type: %w[valid-type1 invalid-type1 valid-type3]
664
668
  expect(last_response.status).to eq 400
665
669
  expect(last_response.body).to eq({ error: 'type does not have a valid value' }.to_json)
666
670
  end
@@ -494,6 +494,7 @@ describe Grape::Validations do
494
494
  class DateRangeValidator < Grape::Validations::Base
495
495
  def validate_param!(attr_name, params)
496
496
  return if params[attr_name][:from] <= params[attr_name][:to]
497
+
497
498
  raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: "'from' must be lower or equal to 'to'")
498
499
  end
499
500
  end
@@ -887,13 +888,13 @@ describe Grape::Validations do
887
888
  context <<~DESC do
888
889
  Issue occurs whenever:
889
890
  * param structure with at least three levels
890
- * 1st level item is a required Array that has >1 entry with an optional item present and >1 entry with an optional item missing
891
- * 2nd level is an optional Array or Hash
891
+ * 1st level item is a required Array that has >1 entry with an optional item present and >1 entry with an optional item missing#{' '}
892
+ * 2nd level is an optional Array or Hash#{' '}
892
893
  * 3rd level is a required item (can be any type)
893
894
  * additional levels do not effect the issue from occuring
894
895
  DESC
895
896
 
896
- it "example based off actual real world use case" do
897
+ it 'example based off actual real world use case' do
897
898
  subject.params do
898
899
  requires :orders, type: Array do
899
900
  requires :id, type: Integer
@@ -911,17 +912,17 @@ describe Grape::Validations do
911
912
 
912
913
  data = {
913
914
  orders: [
914
- { id: 77, drugs: [{batches: [{batch_no: "A1234567"}]}]},
915
+ { id: 77, drugs: [{ batches: [{ batch_no: 'A1234567' }] }] },
915
916
  { id: 70 }
916
917
  ]
917
918
  }
918
919
 
919
920
  get '/validate_required_arrays_under_optional_arrays', data
920
- expect(last_response.body).to eq("validate_required_arrays_under_optional_arrays works!")
921
+ expect(last_response.body).to eq('validate_required_arrays_under_optional_arrays works!')
921
922
  expect(last_response.status).to eq(200)
922
923
  end
923
924
 
924
- it "simplest example using Array -> Array -> Hash -> String" do
925
+ it 'simplest example using Array -> Array -> Hash -> String' do
925
926
  subject.params do
926
927
  requires :orders, type: Array do
927
928
  requires :id, type: Integer
@@ -937,17 +938,17 @@ describe Grape::Validations do
937
938
 
938
939
  data = {
939
940
  orders: [
940
- { id: 77, drugs: [{batch_no: "A1234567"}]},
941
+ { id: 77, drugs: [{ batch_no: 'A1234567' }] },
941
942
  { id: 70 }
942
943
  ]
943
944
  }
944
945
 
945
946
  get '/validate_required_arrays_under_optional_arrays', data
946
- expect(last_response.body).to eq("validate_required_arrays_under_optional_arrays works!")
947
+ expect(last_response.body).to eq('validate_required_arrays_under_optional_arrays works!')
947
948
  expect(last_response.status).to eq(200)
948
949
  end
949
950
 
950
- it "simplest example using Array -> Hash -> String" do
951
+ it 'simplest example using Array -> Hash -> String' do
951
952
  subject.params do
952
953
  requires :orders, type: Array do
953
954
  requires :id, type: Integer
@@ -963,17 +964,17 @@ describe Grape::Validations do
963
964
 
964
965
  data = {
965
966
  orders: [
966
- { id: 77, drugs: {batch_no: "A1234567"}},
967
+ { id: 77, drugs: { batch_no: 'A1234567' } },
967
968
  { id: 70 }
968
969
  ]
969
970
  }
970
971
 
971
972
  get '/validate_required_arrays_under_optional_arrays', data
972
- expect(last_response.body).to eq("validate_required_arrays_under_optional_arrays works!")
973
+ expect(last_response.body).to eq('validate_required_arrays_under_optional_arrays works!')
973
974
  expect(last_response.status).to eq(200)
974
975
  end
975
976
 
976
- it "correctly indexes invalida data" do
977
+ it 'correctly indexes invalida data' do
977
978
  subject.params do
978
979
  requires :orders, type: Array do
979
980
  requires :id, type: Integer
@@ -991,16 +992,16 @@ describe Grape::Validations do
991
992
  data = {
992
993
  orders: [
993
994
  { id: 70 },
994
- { id: 77, drugs: [{batch_no: "A1234567", quantity: 12}, {batch_no: "B222222"}]}
995
+ { id: 77, drugs: [{ batch_no: 'A1234567', quantity: 12 }, { batch_no: 'B222222' }] }
995
996
  ]
996
997
  }
997
998
 
998
999
  get '/correctly_indexes', data
999
- expect(last_response.body).to eq("orders[1][drugs][1][quantity] is missing")
1000
+ expect(last_response.body).to eq('orders[1][drugs][1][quantity] is missing')
1000
1001
  expect(last_response.status).to eq(400)
1001
1002
  end
1002
1003
 
1003
- context "multiple levels of optional and requires settings" do
1004
+ context 'multiple levels of optional and requires settings' do
1004
1005
  before do
1005
1006
  subject.params do
1006
1007
  requires :top, type: Array do
@@ -1022,53 +1023,62 @@ describe Grape::Validations do
1022
1023
  end
1023
1024
  end
1024
1025
 
1025
- it "with valid data" do
1026
+ it 'with valid data' do
1026
1027
  data = {
1027
1028
  top: [
1028
1029
  { top_id: 1, middle_1: [
1029
- {middle_1_id: 11}, {middle_1_id: 12, middle_2: [
1030
- {middle_2_id: 121}, {middle_2_id: 122, bottom: [{bottom_id: 1221}]}]}]},
1030
+ { middle_1_id: 11 }, { middle_1_id: 12, middle_2: [
1031
+ { middle_2_id: 121 }, { middle_2_id: 122, bottom: [{ bottom_id: 1221 }] }
1032
+ ] }
1033
+ ] },
1031
1034
  { top_id: 2, middle_1: [
1032
- {middle_1_id: 21}, {middle_1_id: 22, middle_2: [
1033
- {middle_2_id: 221}]}]},
1035
+ { middle_1_id: 21 }, { middle_1_id: 22, middle_2: [
1036
+ { middle_2_id: 221 }
1037
+ ] }
1038
+ ] },
1034
1039
  { top_id: 3, middle_1: [
1035
- {middle_1_id: 31}, {middle_1_id: 32}]},
1040
+ { middle_1_id: 31 }, { middle_1_id: 32 }
1041
+ ] },
1036
1042
  { top_id: 4 }
1037
1043
  ]
1038
1044
  }
1039
1045
 
1040
1046
  get '/multi_level', data
1041
- expect(last_response.body).to eq("multi_level works!")
1047
+ expect(last_response.body).to eq('multi_level works!')
1042
1048
  expect(last_response.status).to eq(200)
1043
1049
  end
1044
1050
 
1045
- it "with invalid data" do
1051
+ it 'with invalid data' do
1046
1052
  data = {
1047
1053
  top: [
1048
1054
  { top_id: 1, middle_1: [
1049
- {middle_1_id: 11}, {middle_1_id: 12, middle_2: [
1050
- {middle_2_id: 121}, {middle_2_id: 122, bottom: [{bottom_id: nil}]}]}]},
1055
+ { middle_1_id: 11 }, { middle_1_id: 12, middle_2: [
1056
+ { middle_2_id: 121 }, { middle_2_id: 122, bottom: [{ bottom_id: nil }] }
1057
+ ] }
1058
+ ] },
1051
1059
  { top_id: 2, middle_1: [
1052
- {middle_1_id: 21}, {middle_1_id: 22, middle_2: [{middle_2_id: nil}]}]},
1060
+ { middle_1_id: 21 }, { middle_1_id: 22, middle_2: [{ middle_2_id: nil }] }
1061
+ ] },
1053
1062
  { top_id: 3, middle_1: [
1054
- {middle_1_id: nil}, {middle_1_id: 32}]},
1063
+ { middle_1_id: nil }, { middle_1_id: 32 }
1064
+ ] },
1055
1065
  { top_id: nil, missing_top_id: 4 }
1056
1066
  ]
1057
1067
  }
1058
1068
  # debugger
1059
1069
  get '/multi_level', data
1060
- expect(last_response.body.split(", ")).to match_array([
1061
- "top[3][top_id] is empty",
1062
- "top[2][middle_1][0][middle_1_id] is empty",
1063
- "top[1][middle_1][1][middle_2][0][middle_2_id] is empty",
1064
- "top[0][middle_1][1][middle_2][1][bottom][0][bottom_id] is empty"
1065
- ])
1070
+ expect(last_response.body.split(', ')).to match_array([
1071
+ 'top[3][top_id] is empty',
1072
+ 'top[2][middle_1][0][middle_1_id] is empty',
1073
+ 'top[1][middle_1][1][middle_2][0][middle_2_id] is empty',
1074
+ 'top[0][middle_1][1][middle_2][1][bottom][0][bottom_id] is empty'
1075
+ ])
1066
1076
  expect(last_response.status).to eq(400)
1067
1077
  end
1068
1078
  end
1069
1079
  end
1070
1080
 
1071
- it "exactly_one_of" do
1081
+ it 'exactly_one_of' do
1072
1082
  subject.params do
1073
1083
  requires :orders, type: Array do
1074
1084
  requires :id, type: Integer
@@ -1086,17 +1096,17 @@ describe Grape::Validations do
1086
1096
 
1087
1097
  data = {
1088
1098
  orders: [
1089
- { id: 77, drugs: {batch_no: "A1234567"}},
1099
+ { id: 77, drugs: { batch_no: 'A1234567' } },
1090
1100
  { id: 70 }
1091
1101
  ]
1092
1102
  }
1093
1103
 
1094
1104
  get '/exactly_one_of', data
1095
- expect(last_response.body).to eq("exactly_one_of works!")
1105
+ expect(last_response.body).to eq('exactly_one_of works!')
1096
1106
  expect(last_response.status).to eq(200)
1097
1107
  end
1098
1108
 
1099
- it "at_least_one_of" do
1109
+ it 'at_least_one_of' do
1100
1110
  subject.params do
1101
1111
  requires :orders, type: Array do
1102
1112
  requires :id, type: Integer
@@ -1114,17 +1124,17 @@ describe Grape::Validations do
1114
1124
 
1115
1125
  data = {
1116
1126
  orders: [
1117
- { id: 77, drugs: {batch_no: "A1234567"}},
1127
+ { id: 77, drugs: { batch_no: 'A1234567' } },
1118
1128
  { id: 70 }
1119
1129
  ]
1120
1130
  }
1121
1131
 
1122
1132
  get '/at_least_one_of', data
1123
- expect(last_response.body).to eq("at_least_one_of works!")
1133
+ expect(last_response.body).to eq('at_least_one_of works!')
1124
1134
  expect(last_response.status).to eq(200)
1125
1135
  end
1126
1136
 
1127
- it "all_or_none_of" do
1137
+ it 'all_or_none_of' do
1128
1138
  subject.params do
1129
1139
  requires :orders, type: Array do
1130
1140
  requires :id, type: Integer
@@ -1142,13 +1152,13 @@ describe Grape::Validations do
1142
1152
 
1143
1153
  data = {
1144
1154
  orders: [
1145
- { id: 77, drugs: {batch_no: "A1234567", batch_id: "12"}},
1155
+ { id: 77, drugs: { batch_no: 'A1234567', batch_id: '12' } },
1146
1156
  { id: 70 }
1147
1157
  ]
1148
1158
  }
1149
1159
 
1150
1160
  get '/all_or_none_of', data
1151
- expect(last_response.body).to eq("all_or_none_of works!")
1161
+ expect(last_response.body).to eq('all_or_none_of works!')
1152
1162
  expect(last_response.status).to eq(200)
1153
1163
  end
1154
1164
  end
@@ -1177,6 +1187,7 @@ describe Grape::Validations do
1177
1187
  class Customvalidator < Grape::Validations::Base
1178
1188
  def validate_param!(attr_name, params)
1179
1189
  return if params[attr_name] == 'im custom'
1190
+
1180
1191
  raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: 'is not custom!')
1181
1192
  end
1182
1193
  end
@@ -1325,6 +1336,7 @@ describe Grape::Validations do
1325
1336
  class CustomvalidatorWithOptions < Grape::Validations::Base
1326
1337
  def validate_param!(attr_name, params)
1327
1338
  return if params[attr_name] == @option[:text]
1339
+
1328
1340
  raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message)
1329
1341
  end
1330
1342
  end
@@ -70,7 +70,7 @@ shared_examples_for 'versioning' do
70
70
 
71
71
  subject.version 'v1', macro_options do
72
72
  get 'version' do
73
- 'version ' + request.env['api.version']
73
+ "version #{request.env['api.version']}"
74
74
  end
75
75
  end
76
76
 
@@ -94,7 +94,7 @@ shared_examples_for 'versioning' do
94
94
 
95
95
  subject.version 'v1', macro_options do
96
96
  get 'version' do
97
- 'version ' + request.env['api.version']
97
+ "version #{request.env['api.version']}"
98
98
  end
99
99
  end
100
100
 
data/spec/spec_helper.rb CHANGED
@@ -10,7 +10,7 @@ require 'rubygems'
10
10
  require 'bundler'
11
11
  Bundler.require :default, :test
12
12
 
13
- Dir["#{File.dirname(__FILE__)}/support/*.rb"].each do |file|
13
+ Dir["#{File.dirname(__FILE__)}/support/*.rb"].sort.each do |file|
14
14
  require file
15
15
  end
16
16
 
@@ -4,7 +4,7 @@ module Spec
4
4
  module Support
5
5
  module Helpers
6
6
  def encode_basic_auth(username, password)
7
- 'Basic ' + Base64.encode64("#{username}:#{password}")
7
+ "Basic #{Base64.encode64("#{username}:#{password}")}"
8
8
  end
9
9
  end
10
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.3
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bleigh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-07 00:00:00.000000000 Z
11
+ date: 2021-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -371,9 +371,9 @@ licenses:
371
371
  - MIT
372
372
  metadata:
373
373
  bug_tracker_uri: https://github.com/ruby-grape/grape/issues
374
- changelog_uri: https://github.com/ruby-grape/grape/blob/v1.5.3/CHANGELOG.md
375
- documentation_uri: https://www.rubydoc.info/gems/grape/1.5.3
376
- source_code_uri: https://github.com/ruby-grape/grape/tree/v1.5.3
374
+ changelog_uri: https://github.com/ruby-grape/grape/blob/v1.6.0/CHANGELOG.md
375
+ documentation_uri: https://www.rubydoc.info/gems/grape/1.6.0
376
+ source_code_uri: https://github.com/ruby-grape/grape/tree/v1.6.0
377
377
  post_install_message:
378
378
  rdoc_options: []
379
379
  require_paths:
@@ -382,7 +382,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
382
382
  requirements:
383
383
  - - ">="
384
384
  - !ruby/object:Gem::Version
385
- version: 2.4.0
385
+ version: 2.5.0
386
386
  required_rubygems_version: !ruby/object:Gem::Requirement
387
387
  requirements:
388
388
  - - ">="