grape 1.5.0 → 1.5.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f34ddc6f9f11346067b19a6d7f8e333e433a14c1866e68714815a9e8a457487a
4
- data.tar.gz: c95b6956bcb2e5f2e61035ec4af7ee3dcaaa53f7743bde69e7363c9a24edc317
3
+ metadata.gz: fc2b398e9ad95e7e4bb2641bbdaada929d992cd50fb551b56dbafe5f03a75589
4
+ data.tar.gz: 03765fbe9d5dafb28b531f2a454f06b2ac59d16ea28691036de797b8e64ced06
5
5
  SHA512:
6
- metadata.gz: fef19eceff9814554a70cc0fa04d24e2cdbbba91af8f663a07a3278694c4cda2664b521d5390a57f8f1ccf7dc41dff85d602423d47aa27c87ca7d73b9d6e64ba
7
- data.tar.gz: f1b2f404754216ba613e0250a6788ce9bbd02bd0560f2981c1847ca917398ede0f429ae03cdaf31bd3447e20248310f4ba7837511fe811ceb4ddee3b7c59df23
6
+ metadata.gz: a078c1c951ff6e5dfee34c78ab04e1f2866be316af23de469db12301ec3c86eb53bcdc9c8ac478aabe02bd3dc34f4772166e49bdf85ef731a051a8d0de73441f
7
+ data.tar.gz: 7146c097cfced8308f1efb314fb3ace44f30013af8a58a01e9a41a9aca497bd5591c060cabdcc542f25d5660b842548916282541fe869f627538ef51bb083c66
@@ -1,3 +1,16 @@
1
+ ### 1.5.1 (2020/11/15)
2
+
3
+ #### Fixes
4
+
5
+ * Your contribution here.
6
+ * [#2129](https://github.com/ruby-grape/grape/pull/2129): Fix validation error when Required Array nested inside an optional array, for Multiparam validators - [@dwhenry](https://github.com/dwhenry).
7
+ * [#2128](https://github.com/ruby-grape/grape/pull/2128): Fix validation error when Required Array nested inside an optional array - [@dwhenry](https://github.com/dwhenry).
8
+ * [#2127](https://github.com/ruby-grape/grape/pull/2127): Fix a performance issue with dependent params - [@dnesteryuk](https://github.com/dnesteryuk).
9
+ * [#2126](https://github.com/ruby-grape/grape/pull/2126): Fix warnings about redefined attribute accessors in `AttributeTranslator` - [@samsonjs](https://github.com/samsonjs).
10
+ * [#2121](https://github.com/ruby-grape/grape/pull/2121): Fix 2.7 deprecation warning in validator_factory - [@Legogris](https://github.com/Legogris).
11
+ * [#2115](https://github.com/ruby-grape/grape/pull/2115): Fix declared_params regression with multiple allowed types - [@stanhu](https://github.com/stanhu).
12
+ * [#2123](https://github.com/ruby-grape/grape/pull/2123): Fix 2.7 deprecation warning in middleware/stack - [@Legogris](https://github.com/Legogris).
13
+
1
14
  ### 1.5.0 (2020/10/05)
2
15
 
3
16
  #### Fixes
data/README.md CHANGED
@@ -156,8 +156,7 @@ content negotiation, versioning and much more.
156
156
 
157
157
  ## Stable Release
158
158
 
159
- You're reading the documentation for the stable release of Grape, 1.5.0.
160
- Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
159
+ You're reading the documentation for the stable release of Grape, 1.5.1.
161
160
 
162
161
  ## Project Resources
163
162
 
@@ -2039,10 +2038,10 @@ end
2039
2038
 
2040
2039
  # is NOT the same as
2041
2040
 
2042
- get ':status' do # this makes param[:status] available
2041
+ get ':status' do # this makes params[:status] available
2043
2042
  end
2044
2043
 
2045
- # This will make both param[:status_id] and param[:id] available
2044
+ # This will make both params[:status_id] and params[:id] available
2046
2045
 
2047
2046
  get 'statuses/:status_id/reviews/:id' do
2048
2047
  end
@@ -1,6 +1,28 @@
1
1
  Upgrading Grape
2
2
  ===============
3
3
 
4
+ ### Upgrading to >= 1.5.1
5
+
6
+ #### Dependent params
7
+
8
+ If you use [dependent params](https://github.com/ruby-grape/grape#dependent-parameters) with
9
+ `Grape::Extensions::Hash::ParamBuilder`, make sure a parameter to be dependent on is set as a Symbol.
10
+ If a String is given, a parameter that other parameters depend on won't be found even if it is present.
11
+
12
+ _Correct_:
13
+ ```ruby
14
+ given :matrix do
15
+ # dependent params
16
+ end
17
+ ```
18
+
19
+ _Wrong_:
20
+ ```ruby
21
+ given 'matrix' do
22
+ # dependent params
23
+ end
24
+ ```
25
+
4
26
  ### Upgrading to >= 1.5.0
5
27
 
6
28
  Prior to 1.3.3, the `declared` helper would always return the complete params structure if `include_missing=true` was set. In 1.3.3 a regression was introduced such that a missing Hash with or without nested parameters would always resolve to `{}`.
@@ -94,7 +94,7 @@ module Grape
94
94
 
95
95
  if type == 'Hash' && !has_children
96
96
  {}
97
- elsif type == 'Array' || type&.start_with?('[')
97
+ elsif type == 'Array' || type&.start_with?('[') && !type&.include?(',')
98
98
  []
99
99
  elsif type == 'Set' || type&.start_with?('#<Set')
100
100
  Set.new
@@ -227,13 +227,17 @@ module Grape
227
227
 
228
228
  alias group requires
229
229
 
230
- def map_params(params, element)
230
+ class EmptyOptionalValue; end
231
+
232
+ def map_params(params, element, is_array = false)
231
233
  if params.is_a?(Array)
232
234
  params.map do |el|
233
- map_params(el, element)
235
+ map_params(el, element, true)
234
236
  end
235
237
  elsif params.is_a?(Hash)
236
- params[element] || {}
238
+ params[element] || (@optional && is_array ? EmptyOptionalValue : {})
239
+ elsif params == EmptyOptionalValue
240
+ EmptyOptionalValue
237
241
  else
238
242
  {}
239
243
  end
@@ -70,9 +70,9 @@ module Grape
70
70
  middlewares[i]
71
71
  end
72
72
 
73
- def insert(index, *args, &block)
73
+ def insert(index, *args, **kwargs, &block)
74
74
  index = assert_index(index, :before)
75
- middleware = self.class::Middleware.new(*args, &block)
75
+ middleware = self.class::Middleware.new(*args, **kwargs, &block)
76
76
  middlewares.insert(index, middleware)
77
77
  end
78
78
 
@@ -83,8 +83,8 @@ module Grape
83
83
  insert(index + 1, *args, &block)
84
84
  end
85
85
 
86
- def use(*args, &block)
87
- middleware = self.class::Middleware.new(*args, &block)
86
+ def use(*args, **kwargs, &block)
87
+ middleware = self.class::Middleware.new(*args, **kwargs, &block)
88
88
  middlewares.push(middleware)
89
89
  end
90
90
 
@@ -4,7 +4,7 @@ module Grape
4
4
  class Router
5
5
  # this could be an OpenStruct, but doesn't work in Ruby 2.3.0, see https://bugs.ruby-lang.org/issues/12251
6
6
  class AttributeTranslator
7
- attr_reader :attributes, :request_method, :requirements
7
+ attr_reader :attributes
8
8
 
9
9
  ROUTE_ATTRIBUTES = %i[
10
10
  prefix
@@ -48,6 +48,14 @@ module Grape
48
48
  def yield_attributes(_resource_params, _attrs)
49
49
  raise NotImplementedError
50
50
  end
51
+
52
+ # This is a special case so that we can ignore tree's where option
53
+ # values are missing lower down. Unfortunately we can remove this
54
+ # are the parameter parsing stage as they are required to ensure
55
+ # the correct indexing is maintained
56
+ def skip?(val)
57
+ val == Grape::DSL::Parameters::EmptyOptionalValue
58
+ end
51
59
  end
52
60
  end
53
61
  end
@@ -6,7 +6,7 @@ module Grape
6
6
  private
7
7
 
8
8
  def yield_attributes(resource_params, _attrs)
9
- yield resource_params
9
+ yield resource_params, skip?(resource_params)
10
10
  end
11
11
  end
12
12
  end
@@ -61,8 +61,9 @@ module Grape
61
61
  end
62
62
 
63
63
  return params.any? { |param| meets_dependency?(param, request_params) } if params.is_a?(Array)
64
- return false unless params.respond_to?(:with_indifferent_access)
65
- params = params.with_indifferent_access
64
+
65
+ # params might be anything what looks like a hash, so it must implement a `key?` method
66
+ return false unless params.respond_to?(:key?)
66
67
 
67
68
  @dependent_on.each do |dependency|
68
69
  if dependency.is_a?(Hash)
@@ -7,7 +7,7 @@ module Grape
7
7
 
8
8
  def yield_attributes(val, attrs)
9
9
  attrs.each do |attr_name|
10
- yield val, attr_name, empty?(val)
10
+ yield val, attr_name, empty?(val), skip?(val)
11
11
  end
12
12
  end
13
13
 
@@ -8,7 +8,7 @@ module Grape
8
8
  options[:options],
9
9
  options[:required],
10
10
  options[:params_scope],
11
- options[:opts])
11
+ **options[:opts])
12
12
  end
13
13
  end
14
14
  end
@@ -43,7 +43,8 @@ module Grape
43
43
  # there may be more than one error per field
44
44
  array_errors = []
45
45
 
46
- attributes.each do |val, attr_name, empty_val|
46
+ attributes.each do |val, attr_name, empty_val, skip_value|
47
+ next if skip_value
47
48
  next if !@scope.required? && empty_val
48
49
  next unless @scope.meets_dependency?(val, params)
49
50
  begin
@@ -7,7 +7,8 @@ module Grape
7
7
  attributes = MultipleAttributesIterator.new(self, @scope, params)
8
8
  array_errors = []
9
9
 
10
- attributes.each do |resource_params|
10
+ attributes.each do |resource_params, skip_value|
11
+ next if skip_value
11
12
  begin
12
13
  validate_params!(resource_params)
13
14
  rescue Grape::Exceptions::Validation => e
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Grape
4
4
  # The current version of Grape.
5
- VERSION = '1.5.0'
5
+ VERSION = '1.5.1'
6
6
  end
@@ -16,6 +16,7 @@ describe Grape::Endpoint do
16
16
  requires :first
17
17
  optional :second
18
18
  optional :third, default: 'third-default'
19
+ optional :multiple_types, types: [Integer, String]
19
20
  optional :nested, type: Hash do
20
21
  optional :fourth
21
22
  optional :fifth
@@ -96,6 +97,16 @@ describe Grape::Endpoint do
96
97
  expect(JSON.parse(last_response.body)['nested']['fourth']).to be_nil
97
98
  end
98
99
 
100
+ it 'should show nil for multiple allowed types if include_missing is true' do
101
+ subject.get '/declared' do
102
+ declared(params, include_missing: true)
103
+ end
104
+
105
+ get '/declared?first=present'
106
+ expect(last_response.status).to eq(200)
107
+ expect(JSON.parse(last_response.body)['multiple_types']).to be_nil
108
+ end
109
+
99
110
  it 'does not work in a before filter' do
100
111
  subject.before do
101
112
  declared(params)
@@ -113,7 +124,7 @@ describe Grape::Endpoint do
113
124
  end
114
125
  get '/declared?first=present'
115
126
  expect(last_response.status).to eq(200)
116
- expect(JSON.parse(last_response.body).keys.size).to eq(10)
127
+ expect(JSON.parse(last_response.body).keys.size).to eq(11)
117
128
  end
118
129
 
119
130
  it 'has a optional param with default value all the time' do
@@ -13,8 +13,8 @@ describe Grape::Validations::MultipleAttributesIterator do
13
13
  { first: 'string', second: 'string' }
14
14
  end
15
15
 
16
- it 'yields the whole params hash without the list of attrs' do
17
- expect { |b| iterator.each(&b) }.to yield_with_args(params)
16
+ it 'yields the whole params hash and the skipped flag without the list of attrs' do
17
+ expect { |b| iterator.each(&b) }.to yield_with_args(params, false)
18
18
  end
19
19
  end
20
20
 
@@ -24,7 +24,17 @@ describe Grape::Validations::MultipleAttributesIterator do
24
24
  end
25
25
 
26
26
  it 'yields each element of the array without the list of attrs' do
27
- expect { |b| iterator.each(&b) }.to yield_successive_args(params[0], params[1])
27
+ expect { |b| iterator.each(&b) }.to yield_successive_args([params[0], false], [params[1], false])
28
+ end
29
+ end
30
+
31
+ context 'when params is empty optional placeholder' do
32
+ let(:params) do
33
+ [Grape::DSL::Parameters::EmptyOptionalValue, { first: 'string2', second: 'string2' }]
34
+ end
35
+
36
+ it 'yields each element of the array without the list of attrs' do
37
+ expect { |b| iterator.each(&b) }.to yield_successive_args([Grape::DSL::Parameters::EmptyOptionalValue, true], [params[1], false])
28
38
  end
29
39
  end
30
40
  end
@@ -15,7 +15,7 @@ describe Grape::Validations::SingleAttributeIterator do
15
15
 
16
16
  it 'yields params and every single attribute from the list' do
17
17
  expect { |b| iterator.each(&b) }
18
- .to yield_successive_args([params, :first, false], [params, :second, false])
18
+ .to yield_successive_args([params, :first, false, false], [params, :second, false, false])
19
19
  end
20
20
  end
21
21
 
@@ -26,8 +26,8 @@ describe Grape::Validations::SingleAttributeIterator do
26
26
 
27
27
  it 'yields every single attribute from the list for each of the array elements' do
28
28
  expect { |b| iterator.each(&b) }.to yield_successive_args(
29
- [params[0], :first, false], [params[0], :second, false],
30
- [params[1], :first, false], [params[1], :second, false]
29
+ [params[0], :first, false, false], [params[0], :second, false, false],
30
+ [params[1], :first, false, false], [params[1], :second, false, false]
31
31
  )
32
32
  end
33
33
 
@@ -36,9 +36,20 @@ describe Grape::Validations::SingleAttributeIterator do
36
36
 
37
37
  it 'marks params with empty values' do
38
38
  expect { |b| iterator.each(&b) }.to yield_successive_args(
39
- [params[0], :first, true], [params[0], :second, true],
40
- [params[1], :first, true], [params[1], :second, true],
41
- [params[2], :first, false], [params[2], :second, false]
39
+ [params[0], :first, true, false], [params[0], :second, true, false],
40
+ [params[1], :first, true, false], [params[1], :second, true, false],
41
+ [params[2], :first, false, false], [params[2], :second, false, false]
42
+ )
43
+ end
44
+ end
45
+
46
+ context 'when missing optional value' do
47
+ let(:params) { [Grape::DSL::Parameters::EmptyOptionalValue, 10] }
48
+
49
+ it 'marks params with skipped values' do
50
+ expect { |b| iterator.each(&b) }.to yield_successive_args(
51
+ [params[0], :first, false, true], [params[0], :second, false, true],
52
+ [params[1], :first, false, false], [params[1], :second, false, false],
42
53
  )
43
54
  end
44
55
  end
@@ -883,6 +883,274 @@ describe Grape::Validations do
883
883
  end
884
884
  expect(declared_params).to eq([items: [:key, { optional_subitems: [:value] }, { required_subitems: [:value] }]])
885
885
  end
886
+
887
+ context <<~DESC do
888
+ Issue occurs whenever:
889
+ * 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
892
+ * 3rd level is a required item (can be any type)
893
+ * additional levels do not effect the issue from occuring
894
+ DESC
895
+
896
+ it "example based off actual real world use case" do
897
+ subject.params do
898
+ requires :orders, type: Array do
899
+ requires :id, type: Integer
900
+ optional :drugs, type: Array do
901
+ requires :batches, type: Array do
902
+ requires :batch_no, type: String
903
+ end
904
+ end
905
+ end
906
+ end
907
+
908
+ subject.get '/validate_required_arrays_under_optional_arrays' do
909
+ 'validate_required_arrays_under_optional_arrays works!'
910
+ end
911
+
912
+ data = {
913
+ orders: [
914
+ { id: 77, drugs: [{batches: [{batch_no: "A1234567"}]}]},
915
+ { id: 70 }
916
+ ]
917
+ }
918
+
919
+ 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.status).to eq(200)
922
+ end
923
+
924
+ it "simplest example using Arry -> Array -> Hash -> String" do
925
+ subject.params do
926
+ requires :orders, type: Array do
927
+ requires :id, type: Integer
928
+ optional :drugs, type: Array do
929
+ requires :batch_no, type: String
930
+ end
931
+ end
932
+ end
933
+
934
+ subject.get '/validate_required_arrays_under_optional_arrays' do
935
+ 'validate_required_arrays_under_optional_arrays works!'
936
+ end
937
+
938
+ data = {
939
+ orders: [
940
+ { id: 77, drugs: [{batch_no: "A1234567"}]},
941
+ { id: 70 }
942
+ ]
943
+ }
944
+
945
+ 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.status).to eq(200)
948
+ end
949
+
950
+ it "simplest example using Arry -> Hash -> String" do
951
+ subject.params do
952
+ requires :orders, type: Array do
953
+ requires :id, type: Integer
954
+ optional :drugs, type: Hash do
955
+ requires :batch_no, type: String
956
+ end
957
+ end
958
+ end
959
+
960
+ subject.get '/validate_required_arrays_under_optional_arrays' do
961
+ 'validate_required_arrays_under_optional_arrays works!'
962
+ end
963
+
964
+ data = {
965
+ orders: [
966
+ { id: 77, drugs: {batch_no: "A1234567"}},
967
+ { id: 70 }
968
+ ]
969
+ }
970
+
971
+ 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.status).to eq(200)
974
+ end
975
+
976
+ it "correctly indexes invalida data" do
977
+ subject.params do
978
+ requires :orders, type: Array do
979
+ requires :id, type: Integer
980
+ optional :drugs, type: Array do
981
+ requires :batch_no, type: String
982
+ requires :quantity, type: Integer
983
+ end
984
+ end
985
+ end
986
+
987
+ subject.get '/correctly_indexes' do
988
+ 'correctly_indexes works!'
989
+ end
990
+
991
+ data = {
992
+ orders: [
993
+ { id: 70 },
994
+ { id: 77, drugs: [{batch_no: "A1234567", quantity: 12}, {batch_no: "B222222"}]}
995
+ ]
996
+ }
997
+
998
+ get '/correctly_indexes', data
999
+ expect(last_response.body).to eq("orders[1][drugs][1][quantity] is missing")
1000
+ expect(last_response.status).to eq(400)
1001
+ end
1002
+
1003
+ context "multiple levels of optional and requires settings" do
1004
+ before do
1005
+ subject.params do
1006
+ requires :top, type: Array do
1007
+ requires :top_id, type: Integer, allow_blank: false
1008
+ optional :middle_1, type: Array do
1009
+ requires :middle_1_id, type: Integer, allow_blank: false
1010
+ optional :middle_2, type: Array do
1011
+ requires :middle_2_id, type: String, allow_blank: false
1012
+ optional :bottom, type: Array do
1013
+ requires :bottom_id, type: Integer, allow_blank: false
1014
+ end
1015
+ end
1016
+ end
1017
+ end
1018
+ end
1019
+
1020
+ subject.get '/multi_level' do
1021
+ 'multi_level works!'
1022
+ end
1023
+ end
1024
+
1025
+ it "with valid data" do
1026
+ data = {
1027
+ top: [
1028
+ { 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}]}]}]},
1031
+ { top_id: 2, middle_1: [
1032
+ {middle_1_id: 21}, {middle_1_id: 22, middle_2: [
1033
+ {middle_2_id: 221}]}]},
1034
+ { top_id: 3, middle_1: [
1035
+ {middle_1_id: 31}, {middle_1_id: 32}]},
1036
+ { top_id: 4 }
1037
+ ]
1038
+ }
1039
+
1040
+ get '/multi_level', data
1041
+ expect(last_response.body).to eq("multi_level works!")
1042
+ expect(last_response.status).to eq(200)
1043
+ end
1044
+
1045
+ it "with invalid data" do
1046
+ data = {
1047
+ top: [
1048
+ { 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}]}]}]},
1051
+ { top_id: 2, middle_1: [
1052
+ {middle_1_id: 21}, {middle_1_id: 22, middle_2: [{middle_2_id: nil}]}]},
1053
+ { top_id: 3, middle_1: [
1054
+ {middle_1_id: nil}, {middle_1_id: 32}]},
1055
+ { top_id: nil, missing_top_id: 4 }
1056
+ ]
1057
+ }
1058
+ # debugger
1059
+ 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
+ ])
1066
+ expect(last_response.status).to eq(400)
1067
+ end
1068
+ end
1069
+ end
1070
+
1071
+ it "exactly_one_of" do
1072
+ subject.params do
1073
+ requires :orders, type: Array do
1074
+ requires :id, type: Integer
1075
+ optional :drugs, type: Hash do
1076
+ optional :batch_no, type: String
1077
+ optional :batch_id, type: String
1078
+ exactly_one_of :batch_no, :batch_id
1079
+ end
1080
+ end
1081
+ end
1082
+
1083
+ subject.get '/exactly_one_of' do
1084
+ 'exactly_one_of works!'
1085
+ end
1086
+
1087
+ data = {
1088
+ orders: [
1089
+ { id: 77, drugs: {batch_no: "A1234567"}},
1090
+ { id: 70 }
1091
+ ]
1092
+ }
1093
+
1094
+ get '/exactly_one_of', data
1095
+ expect(last_response.body).to eq("exactly_one_of works!")
1096
+ expect(last_response.status).to eq(200)
1097
+ end
1098
+
1099
+ it "at_least_one_of" do
1100
+ subject.params do
1101
+ requires :orders, type: Array do
1102
+ requires :id, type: Integer
1103
+ optional :drugs, type: Hash do
1104
+ optional :batch_no, type: String
1105
+ optional :batch_id, type: String
1106
+ at_least_one_of :batch_no, :batch_id
1107
+ end
1108
+ end
1109
+ end
1110
+
1111
+ subject.get '/at_least_one_of' do
1112
+ 'at_least_one_of works!'
1113
+ end
1114
+
1115
+ data = {
1116
+ orders: [
1117
+ { id: 77, drugs: {batch_no: "A1234567"}},
1118
+ { id: 70 }
1119
+ ]
1120
+ }
1121
+
1122
+ get '/at_least_one_of', data
1123
+ expect(last_response.body).to eq("at_least_one_of works!")
1124
+ expect(last_response.status).to eq(200)
1125
+ end
1126
+
1127
+ it "all_or_none_of" do
1128
+ subject.params do
1129
+ requires :orders, type: Array do
1130
+ requires :id, type: Integer
1131
+ optional :drugs, type: Hash do
1132
+ optional :batch_no, type: String
1133
+ optional :batch_id, type: String
1134
+ all_or_none_of :batch_no, :batch_id
1135
+ end
1136
+ end
1137
+ end
1138
+
1139
+ subject.get '/all_or_none_of' do
1140
+ 'all_or_none_of works!'
1141
+ end
1142
+
1143
+ data = {
1144
+ orders: [
1145
+ { id: 77, drugs: {batch_no: "A1234567", batch_id: "12"}},
1146
+ { id: 70 }
1147
+ ]
1148
+ }
1149
+
1150
+ get '/all_or_none_of', data
1151
+ expect(last_response.body).to eq("all_or_none_of works!")
1152
+ expect(last_response.status).to eq(200)
1153
+ end
886
1154
  end
887
1155
 
888
1156
  context 'multiple validation errors' do
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.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bleigh
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-05 00:00:00.000000000 Z
11
+ date: 2020-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -369,10 +369,10 @@ licenses:
369
369
  - MIT
370
370
  metadata:
371
371
  bug_tracker_uri: https://github.com/ruby-grape/grape/issues
372
- changelog_uri: https://github.com/ruby-grape/grape/blob/v1.5.0/CHANGELOG.md
373
- documentation_uri: https://www.rubydoc.info/gems/grape/1.5.0
374
- source_code_uri: https://github.com/ruby-grape/grape/tree/v1.5.0
375
- post_install_message:
372
+ changelog_uri: https://github.com/ruby-grape/grape/blob/v1.5.1/CHANGELOG.md
373
+ documentation_uri: https://www.rubydoc.info/gems/grape/1.5.1
374
+ source_code_uri: https://github.com/ruby-grape/grape/tree/v1.5.1
375
+ post_install_message:
376
376
  rdoc_options: []
377
377
  require_paths:
378
378
  - lib
@@ -387,123 +387,123 @@ required_rubygems_version: !ruby/object:Gem::Requirement
387
387
  - !ruby/object:Gem::Version
388
388
  version: '0'
389
389
  requirements: []
390
- rubygems_version: 3.1.3
391
- signing_key:
390
+ rubygems_version: 3.0.3
391
+ signing_key:
392
392
  specification_version: 4
393
393
  summary: A simple Ruby framework for building REST-like APIs.
394
394
  test_files:
395
- - spec/spec_helper.rb
396
- - spec/integration/eager_load/eager_load_spec.rb
397
- - spec/integration/multi_xml/xml_spec.rb
398
- - spec/integration/multi_json/json_spec.rb
399
395
  - spec/shared/versioning_examples.rb
400
- - spec/support/basic_auth_encode_helpers.rb
401
- - spec/support/endpoint_faker.rb
402
- - spec/support/chunks.rb
403
- - spec/support/file_streamer.rb
404
396
  - spec/support/versioned_helpers.rb
405
397
  - spec/support/content_type_helpers.rb
406
398
  - spec/support/eager_load.rb
399
+ - spec/support/basic_auth_encode_helpers.rb
400
+ - spec/support/file_streamer.rb
401
+ - spec/support/chunks.rb
402
+ - spec/support/endpoint_faker.rb
407
403
  - spec/support/integer_helpers.rb
408
- - spec/grape/middleware/error_spec.rb
409
- - spec/grape/middleware/globals_spec.rb
410
- - spec/grape/middleware/formatter_spec.rb
411
- - spec/grape/middleware/auth/strategies_spec.rb
412
- - spec/grape/middleware/auth/dsl_spec.rb
413
- - spec/grape/middleware/auth/base_spec.rb
414
- - spec/grape/middleware/stack_spec.rb
415
- - spec/grape/middleware/exception_spec.rb
416
- - spec/grape/middleware/versioner_spec.rb
417
- - spec/grape/middleware/versioner/accept_version_header_spec.rb
418
- - spec/grape/middleware/versioner/header_spec.rb
419
- - spec/grape/middleware/versioner/path_spec.rb
420
- - spec/grape/middleware/versioner/param_spec.rb
421
- - spec/grape/middleware/base_spec.rb
422
- - spec/grape/config_spec.rb
423
- - spec/grape/loading_spec.rb
424
- - spec/grape/endpoint_spec.rb
425
- - spec/grape/api_spec.rb
426
- - spec/grape/util/reverse_stackable_values_spec.rb
427
- - spec/grape/util/stackable_values_spec.rb
428
- - spec/grape/util/inheritable_setting_spec.rb
429
- - spec/grape/util/strict_hash_configuration_spec.rb
430
- - spec/grape/util/inheritable_values_spec.rb
431
- - spec/grape/integration/rack_spec.rb
432
- - spec/grape/integration/rack_sendfile_spec.rb
433
- - spec/grape/integration/global_namespace_function_spec.rb
434
- - spec/grape/validations_spec.rb
435
- - spec/grape/entity_spec.rb
436
- - spec/grape/exceptions/validation_spec.rb
437
- - spec/grape/exceptions/invalid_accept_header_spec.rb
438
- - spec/grape/exceptions/missing_option_spec.rb
439
- - spec/grape/exceptions/invalid_response_spec.rb
440
- - spec/grape/exceptions/body_parse_errors_spec.rb
441
- - spec/grape/exceptions/invalid_formatter_spec.rb
442
- - spec/grape/exceptions/missing_mime_type_spec.rb
443
- - spec/grape/exceptions/unknown_options_spec.rb
444
- - spec/grape/exceptions/validation_errors_spec.rb
445
- - spec/grape/exceptions/unknown_validator_spec.rb
446
- - spec/grape/exceptions/invalid_versioner_option_spec.rb
447
- - spec/grape/exceptions/base_spec.rb
448
- - spec/grape/presenters/presenter_spec.rb
449
- - spec/grape/validations/single_attribute_iterator_spec.rb
404
+ - spec/grape/api/namespace_parameters_in_route_spec.rb
405
+ - spec/grape/api/routes_with_requirements_spec.rb
406
+ - spec/grape/api/nested_helpers_spec.rb
407
+ - spec/grape/api/required_parameters_in_route_spec.rb
408
+ - spec/grape/api/shared_helpers_exactly_one_of_spec.rb
409
+ - spec/grape/api/parameters_modification_spec.rb
410
+ - spec/grape/api/optional_parameters_in_route_spec.rb
411
+ - spec/grape/api/inherited_helpers_spec.rb
412
+ - spec/grape/api/required_parameters_with_invalid_method_spec.rb
413
+ - spec/grape/api/custom_validations_spec.rb
414
+ - spec/grape/api/defines_boolean_in_params_spec.rb
415
+ - spec/grape/api/shared_helpers_spec.rb
416
+ - spec/grape/api/invalid_format_spec.rb
417
+ - spec/grape/api/deeply_included_options_spec.rb
418
+ - spec/grape/api/instance_spec.rb
419
+ - spec/grape/api/patch_method_helpers_spec.rb
420
+ - spec/grape/api/recognize_path_spec.rb
421
+ - spec/grape/api_remount_spec.rb
422
+ - spec/grape/validations/types_spec.rb
450
423
  - spec/grape/validations/attributes_iterator_spec.rb
451
- - spec/grape/validations/types/primitive_coercer_spec.rb
452
- - spec/grape/validations/types/set_coercer_spec.rb
453
424
  - spec/grape/validations/types/array_coercer_spec.rb
454
- - spec/grape/validations/params_scope_spec.rb
455
- - spec/grape/validations/instance_behaivour_spec.rb
456
- - spec/grape/validations/multiple_attributes_iterator_spec.rb
457
- - spec/grape/validations/types_spec.rb
425
+ - spec/grape/validations/types/set_coercer_spec.rb
426
+ - spec/grape/validations/types/primitive_coercer_spec.rb
458
427
  - spec/grape/validations/validators/regexp_spec.rb
428
+ - spec/grape/validations/validators/default_spec.rb
429
+ - spec/grape/validations/validators/values_spec.rb
430
+ - spec/grape/validations/validators/same_as_spec.rb
459
431
  - spec/grape/validations/validators/mutual_exclusion_spec.rb
460
- - spec/grape/validations/validators/exactly_one_of_spec.rb
461
432
  - spec/grape/validations/validators/except_values_spec.rb
462
- - spec/grape/validations/validators/presence_spec.rb
463
- - spec/grape/validations/validators/all_or_none_spec.rb
433
+ - spec/grape/validations/validators/exactly_one_of_spec.rb
464
434
  - spec/grape/validations/validators/allow_blank_spec.rb
465
- - spec/grape/validations/validators/same_as_spec.rb
466
- - spec/grape/validations/validators/default_spec.rb
467
- - spec/grape/validations/validators/values_spec.rb
468
- - spec/grape/validations/validators/at_least_one_of_spec.rb
469
435
  - spec/grape/validations/validators/coerce_spec.rb
436
+ - spec/grape/validations/validators/presence_spec.rb
437
+ - spec/grape/validations/validators/at_least_one_of_spec.rb
470
438
  - spec/grape/validations/validators/zh-CN.yml
471
- - spec/grape/extensions/param_builders/hashie/mash_spec.rb
472
- - spec/grape/extensions/param_builders/hash_spec.rb
473
- - spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb
439
+ - spec/grape/validations/validators/all_or_none_spec.rb
440
+ - spec/grape/validations/params_scope_spec.rb
441
+ - spec/grape/validations/multiple_attributes_iterator_spec.rb
442
+ - spec/grape/validations/instance_behaivour_spec.rb
443
+ - spec/grape/validations/single_attribute_iterator_spec.rb
444
+ - spec/grape/config_spec.rb
474
445
  - spec/grape/parser_spec.rb
475
- - spec/grape/request_spec.rb
446
+ - spec/grape/exceptions/body_parse_errors_spec.rb
447
+ - spec/grape/exceptions/missing_option_spec.rb
448
+ - spec/grape/exceptions/invalid_accept_header_spec.rb
449
+ - spec/grape/exceptions/validation_spec.rb
450
+ - spec/grape/exceptions/unknown_validator_spec.rb
451
+ - spec/grape/exceptions/validation_errors_spec.rb
452
+ - spec/grape/exceptions/invalid_response_spec.rb
453
+ - spec/grape/exceptions/unknown_options_spec.rb
454
+ - spec/grape/exceptions/invalid_formatter_spec.rb
455
+ - spec/grape/exceptions/invalid_versioner_option_spec.rb
456
+ - spec/grape/exceptions/missing_mime_type_spec.rb
457
+ - spec/grape/exceptions/base_spec.rb
458
+ - spec/grape/path_spec.rb
459
+ - spec/grape/util/stackable_values_spec.rb
460
+ - spec/grape/util/strict_hash_configuration_spec.rb
461
+ - spec/grape/util/inheritable_setting_spec.rb
462
+ - spec/grape/util/reverse_stackable_values_spec.rb
463
+ - spec/grape/util/inheritable_values_spec.rb
464
+ - spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb
465
+ - spec/grape/extensions/param_builders/hash_spec.rb
466
+ - spec/grape/extensions/param_builders/hashie/mash_spec.rb
467
+ - spec/grape/integration/rack_spec.rb
468
+ - spec/grape/integration/rack_sendfile_spec.rb
469
+ - spec/grape/integration/global_namespace_function_spec.rb
476
470
  - spec/grape/endpoint/declared_spec.rb
477
- - spec/grape/api/parameters_modification_spec.rb
478
- - spec/grape/api/patch_method_helpers_spec.rb
479
- - spec/grape/api/required_parameters_with_invalid_method_spec.rb
480
- - spec/grape/api/nested_helpers_spec.rb
481
- - spec/grape/api/defines_boolean_in_params_spec.rb
482
- - spec/grape/api/invalid_format_spec.rb
483
- - spec/grape/api/required_parameters_in_route_spec.rb
484
- - spec/grape/api/instance_spec.rb
485
- - spec/grape/api/namespace_parameters_in_route_spec.rb
486
- - spec/grape/api/recognize_path_spec.rb
487
- - spec/grape/api/shared_helpers_exactly_one_of_spec.rb
488
- - spec/grape/api/inherited_helpers_spec.rb
489
- - spec/grape/api/shared_helpers_spec.rb
490
- - spec/grape/api/deeply_included_options_spec.rb
491
- - spec/grape/api/routes_with_requirements_spec.rb
492
- - spec/grape/api/custom_validations_spec.rb
493
- - spec/grape/api/optional_parameters_in_route_spec.rb
494
- - spec/grape/api_remount_spec.rb
495
- - spec/grape/named_api_spec.rb
496
- - spec/grape/dsl/request_response_spec.rb
497
- - spec/grape/dsl/desc_spec.rb
498
- - spec/grape/dsl/logger_spec.rb
471
+ - spec/grape/presenters/presenter_spec.rb
472
+ - spec/grape/endpoint_spec.rb
473
+ - spec/grape/api_spec.rb
474
+ - spec/grape/middleware/exception_spec.rb
475
+ - spec/grape/middleware/versioner/param_spec.rb
476
+ - spec/grape/middleware/versioner/header_spec.rb
477
+ - spec/grape/middleware/versioner/path_spec.rb
478
+ - spec/grape/middleware/versioner/accept_version_header_spec.rb
479
+ - spec/grape/middleware/globals_spec.rb
480
+ - spec/grape/middleware/stack_spec.rb
481
+ - spec/grape/middleware/formatter_spec.rb
482
+ - spec/grape/middleware/error_spec.rb
483
+ - spec/grape/middleware/auth/dsl_spec.rb
484
+ - spec/grape/middleware/auth/strategies_spec.rb
485
+ - spec/grape/middleware/auth/base_spec.rb
486
+ - spec/grape/middleware/versioner_spec.rb
487
+ - spec/grape/middleware/base_spec.rb
488
+ - spec/grape/entity_spec.rb
489
+ - spec/grape/dsl/settings_spec.rb
490
+ - spec/grape/dsl/callbacks_spec.rb
491
+ - spec/grape/dsl/middleware_spec.rb
492
+ - spec/grape/dsl/inside_route_spec.rb
499
493
  - spec/grape/dsl/configuration_spec.rb
500
- - spec/grape/dsl/validations_spec.rb
501
494
  - spec/grape/dsl/parameters_spec.rb
495
+ - spec/grape/dsl/logger_spec.rb
502
496
  - spec/grape/dsl/helpers_spec.rb
503
- - spec/grape/dsl/middleware_spec.rb
504
- - spec/grape/dsl/headers_spec.rb
505
- - spec/grape/dsl/callbacks_spec.rb
506
- - spec/grape/dsl/settings_spec.rb
497
+ - spec/grape/dsl/request_response_spec.rb
507
498
  - spec/grape/dsl/routing_spec.rb
508
- - spec/grape/dsl/inside_route_spec.rb
509
- - spec/grape/path_spec.rb
499
+ - spec/grape/dsl/headers_spec.rb
500
+ - spec/grape/dsl/validations_spec.rb
501
+ - spec/grape/dsl/desc_spec.rb
502
+ - spec/grape/validations_spec.rb
503
+ - spec/grape/named_api_spec.rb
504
+ - spec/grape/loading_spec.rb
505
+ - spec/grape/request_spec.rb
506
+ - spec/integration/eager_load/eager_load_spec.rb
507
+ - spec/integration/multi_xml/xml_spec.rb
508
+ - spec/integration/multi_json/json_spec.rb
509
+ - spec/spec_helper.rb