grape 1.5.3 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  - - ">="