sinatra-my-params 0.0.5 → 0.0.9
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 +4 -4
- data/lib/permit_params.rb +63 -18
- data/spec/permit_params_spec.rb +131 -49
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8391c458014310cc388fc93e899320baa879567e50ca8cb875e3a19e20ae5984
|
4
|
+
data.tar.gz: a928880e81d7f1cfb6d91d2da10347398f8eca11b85bf808eca3c12af8f7a675
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c18faa501799088dcf64962e616789b38a78176f4b0fdfc3b0c123e157b3f799ee7638243d6fb522ab55de945d296206d0c71e46436c4ff30444e5ee95ba8300
|
7
|
+
data.tar.gz: 257127aa4473a46ee13031cef5251f9b94cbb7195444130e0cb6011fc25376bab83a09e52a5c5b03c1e2e02e7a923d3fe942702c88370b65824b3ecf87fb3a11
|
data/lib/permit_params.rb
CHANGED
@@ -1,18 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module PermitParams
|
2
4
|
class InvalidParameterError < StandardError
|
3
5
|
attr_accessor :param, :options
|
4
6
|
end
|
5
7
|
|
6
|
-
def permitted_params(params, permitted = {}, strong_validation = false)
|
8
|
+
def permitted_params(params, permitted = {}, strong_validation = false, options = {})
|
7
9
|
return params if permitted.empty?
|
8
|
-
|
10
|
+
|
9
11
|
coerced_params = Hash.new({})
|
10
12
|
|
11
13
|
params.each do |key, value|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
next unless permitted?(permitted: permitted, key: key, value: value)
|
15
|
+
|
16
|
+
coerced = coerce(
|
17
|
+
param: value,
|
18
|
+
type: permitted[key.to_sym],
|
19
|
+
strong_validation: strong_validation,
|
20
|
+
options: options
|
21
|
+
)
|
22
|
+
coerced_params[key] = coerced unless coerced.nil?
|
16
23
|
end
|
17
24
|
coerced_params
|
18
25
|
end
|
@@ -20,38 +27,76 @@ module PermitParams
|
|
20
27
|
private
|
21
28
|
|
22
29
|
Boolean = :boolean
|
30
|
+
Any = :any
|
31
|
+
Shape = :shape
|
32
|
+
|
33
|
+
def permitted?(permitted:, key:, value:)
|
34
|
+
permitted.keys.map(&:to_s).include?(key.to_s) && !value.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
def coerce(param:, type:, strong_validation: false, options: {})
|
38
|
+
return param if type == Any
|
23
39
|
|
24
|
-
def coerce(param, type, strong_validation = false, options = {})
|
25
40
|
begin
|
26
41
|
return nil if param.nil?
|
27
|
-
return param if
|
28
|
-
|
42
|
+
return param if begin
|
43
|
+
param.is_a?(type)
|
44
|
+
rescue StandardError
|
45
|
+
false
|
46
|
+
end
|
47
|
+
return coerce_integer(param, options) if type == Integer
|
29
48
|
return Float(param) if type == Float
|
30
49
|
return String(param) if type == String
|
31
50
|
return Date.parse(param) if type == Date
|
32
51
|
return Time.parse(param) if type == Time
|
33
52
|
return DateTime.parse(param) if type == DateTime
|
34
|
-
return coerce_array(param) if type == Array
|
35
|
-
return
|
53
|
+
return coerce_array(param, options) if type == Array
|
54
|
+
return coerce_shape(param, options) if type == Shape
|
55
|
+
return coerce_hash(param, options) if type == Hash
|
36
56
|
return coerce_boolean(param) if [TrueClass, FalseClass, Boolean].include? type
|
37
|
-
|
57
|
+
|
58
|
+
nil
|
38
59
|
rescue ArgumentError
|
39
60
|
raise InvalidParameterError, "'#{param}' is not a valid #{type}" if strong_validation
|
40
61
|
end
|
41
62
|
end
|
42
63
|
|
43
|
-
def
|
44
|
-
|
64
|
+
def coerce_integer(param, options = {})
|
65
|
+
Integer(param, options[:integer_precision] || 10)
|
66
|
+
end
|
67
|
+
|
68
|
+
def coerce_array(param, options = {})
|
69
|
+
Array(param.split(options[:delimiter] || ',').map(&:strip))
|
45
70
|
end
|
46
71
|
|
47
|
-
def coerce_hash(param)
|
48
|
-
|
72
|
+
def coerce_hash(param, options = {})
|
73
|
+
return param if param.is_a?(Hash)
|
74
|
+
|
75
|
+
key_value = param.split(options[:delimiter] || ',').map(&:strip).map do |c|
|
76
|
+
c.split(options[:separator] || ':').map(&:strip)
|
77
|
+
end
|
78
|
+
Hash[key_value]
|
49
79
|
end
|
50
80
|
|
51
81
|
def coerce_boolean(param)
|
52
|
-
coerced = /^(false|f|no|n|0)$/i === param.to_s
|
82
|
+
coerced = if /^(false|f|no|n|0)$/i === param.to_s
|
83
|
+
false
|
84
|
+
else
|
85
|
+
/^(true|t|yes|y|1)$/i === param.to_s ? true : nil
|
86
|
+
end
|
53
87
|
raise ArgumentError if coerced.nil?
|
88
|
+
|
54
89
|
coerced
|
55
90
|
end
|
56
|
-
end
|
57
91
|
|
92
|
+
def coerce_shape(param, options = {})
|
93
|
+
hash = coerce_hash(param)
|
94
|
+
has_shape?(hash, options[:shape]) ? hash : nil
|
95
|
+
end
|
96
|
+
|
97
|
+
def has_shape?(hash, shape)
|
98
|
+
hash.all? do |k, v|
|
99
|
+
v.is_a?(Hash) ? has_shape?(v, shape[k]) : shape[k] === v
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/spec/permit_params_spec.rb
CHANGED
@@ -1,87 +1,154 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'permit_params'
|
5
|
+
require 'rspec'
|
6
|
+
require 'rack/test'
|
5
7
|
|
6
8
|
include PermitParams
|
7
9
|
|
8
|
-
describe
|
9
|
-
it
|
10
|
-
input = { param_1:
|
11
|
-
expect
|
10
|
+
describe 'exceptions' do
|
11
|
+
it 'should raise error when at least one param is invalid' do
|
12
|
+
input = { param_1: 'a' }
|
13
|
+
expect do
|
12
14
|
permitted_params(input, { param_1: Integer }, true)
|
13
|
-
|
15
|
+
end.to raise_error(InvalidParameterError, "'a' is not a valid Integer")
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should allow all params when no restriction is given' do
|
19
|
+
input = { param_1: 'a string' }
|
20
|
+
expect(input).to eq permitted_params(input)
|
14
21
|
end
|
15
22
|
|
16
|
-
it
|
17
|
-
input = { param_1:
|
23
|
+
it 'should remove a string when a pemitted is integer' do
|
24
|
+
input = { param_1: 'a string' }
|
25
|
+
output = {}
|
26
|
+
expect(output).to eq permitted_params(input, { param_1: Integer })
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should return an integer when a pemitted is integer' do
|
30
|
+
input = { param_1: 1 }
|
31
|
+
expect(input).to eq permitted_params(input, { param_1: Integer })
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should return an integer when a pemitted can be cast into integer' do
|
35
|
+
input = { param_1: '1' }
|
36
|
+
output = { param_1: 1 }
|
37
|
+
expect(output).to eq permitted_params(input, { param_1: Integer })
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should return a string when a pemitted is string' do
|
41
|
+
input = { param_1: 'a string' }
|
18
42
|
expect(input).to eq permitted_params(input, { param_1: String })
|
19
43
|
end
|
20
44
|
|
21
|
-
it
|
45
|
+
it 'should return a float when a pemitted is float' do
|
22
46
|
input = { param_1: 10.0 }
|
23
47
|
expect(input).to eq permitted_params(input, { param_1: Float })
|
24
48
|
end
|
25
49
|
|
26
|
-
it
|
50
|
+
it 'should return a date when a pemitted is date' do
|
27
51
|
input = { param_1: Date.new }
|
28
52
|
expect(input).to eq permitted_params(input, { param_1: Date })
|
29
53
|
end
|
30
54
|
|
31
|
-
it
|
55
|
+
it 'should return a time when a pemitted is time' do
|
32
56
|
input = { param_1: Time.new }
|
33
57
|
expect(input).to eq permitted_params(input, { param_1: Time })
|
34
58
|
end
|
35
59
|
|
36
|
-
it
|
37
|
-
input = { param_1:
|
38
|
-
expect(input).to eq permitted_params(input, { param_1: Integer })
|
39
|
-
end
|
40
|
-
|
41
|
-
it "should return an integer when a pemitted can be cast into integer" do
|
42
|
-
input = { param_1: "1" }
|
43
|
-
output = { param_1: 1 }
|
44
|
-
expect(output).to eq permitted_params(input, { param_1: Integer })
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should return a false(boolean) when a pemitted is boolean" do
|
48
|
-
input = { param_1: "false" }
|
60
|
+
it 'should return a false(boolean) when a pemitted is boolean' do
|
61
|
+
input = { param_1: 'false' }
|
49
62
|
output = { param_1: false }
|
50
63
|
expect(output).to eq permitted_params(input, { param_1: Boolean })
|
51
64
|
end
|
52
65
|
|
53
|
-
it
|
54
|
-
input = { param_1:
|
66
|
+
it 'should return a true(boolean) when a pemitted is boolean' do
|
67
|
+
input = { param_1: 'true' }
|
55
68
|
output = { param_1: true }
|
56
69
|
expect(output).to eq permitted_params(input, { param_1: Boolean })
|
57
70
|
end
|
58
71
|
|
59
|
-
it
|
60
|
-
input = { param_1: [1,2] }
|
72
|
+
it 'should return an array when a pemitted is array' do
|
73
|
+
input = { param_1: [1, 2] }
|
61
74
|
expect(input).to eq permitted_params(input, { param_1: Array })
|
62
75
|
end
|
63
76
|
|
64
|
-
it
|
77
|
+
it 'should return an array when a pemitted is array' do
|
78
|
+
input = { param_1: '1, 2' }
|
79
|
+
output = { param_1: %w[1 2] }
|
80
|
+
expect(output).to eq permitted_params(input, { param_1: Array })
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should return an array when a pemitted is array' do
|
84
|
+
input = { param_1: '1; 2' }
|
85
|
+
output = { param_1: %w[1 2] }
|
86
|
+
expect(output).to eq permitted_params(input, { param_1: Array }, false, { delimiter: ';' })
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should return a hash when a pemitted is hash' do
|
90
|
+
input = { param_1: 'a: 1, b: 2' }
|
91
|
+
output = { param_1: { 'a' => '1', 'b' => '2' } }
|
92
|
+
expect(output).to eq permitted_params(input, { param_1: Hash })
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should return a hash when a pemitted is hash' do
|
96
|
+
input = { param_1: 'a: 1; b: 2' }
|
97
|
+
output = { param_1: { 'a' => '1', 'b' => '2' } }
|
98
|
+
expect(output).to eq permitted_params(input, { param_1: Hash }, false, { delimiter: ';' })
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should return a hash when a pemitted is hash' do
|
65
102
|
input = { param_1: { a: 1 } }
|
66
103
|
expect(input).to eq permitted_params(input, { param_1: Hash })
|
67
104
|
end
|
68
105
|
|
69
|
-
it
|
70
|
-
input = { param_1: { :
|
106
|
+
it 'should return a hash when a pemitted is shape' do
|
107
|
+
input = { param_1: { a: 1, b: 2 } }
|
108
|
+
expect(input).to eq permitted_params(
|
109
|
+
input,
|
110
|
+
{ param_1: Shape },
|
111
|
+
false,
|
112
|
+
{ shape: { a: Integer, b: Integer } }
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should return a hash when a pemitted is shape(deep)' do
|
117
|
+
input = { param_1: { a: { b: 2 } } }
|
118
|
+
expect(input).to eq permitted_params(
|
119
|
+
input,
|
120
|
+
{ param_1: Shape },
|
121
|
+
false,
|
122
|
+
{ shape: { a: { b: Integer } } }
|
123
|
+
)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should return a empty when a pemitted is shape not defined' do
|
127
|
+
input = { param_1: { a: 1, b: 2 } }
|
128
|
+
expect({}).to eq permitted_params(
|
129
|
+
input,
|
130
|
+
{ param_1: Shape },
|
131
|
+
false,
|
132
|
+
{ shape: { a: Integer } }
|
133
|
+
)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should return a hash when a pemitted is hash' do
|
137
|
+
input = { param_1: { a: { b: 1 } } }
|
71
138
|
expect(input).to eq permitted_params(input, { param_1: Hash })
|
72
139
|
end
|
73
140
|
|
74
|
-
it
|
141
|
+
it 'should return a hash when a pemitted is hash' do
|
75
142
|
input = { param_1: { "a": 1 } }
|
76
143
|
expect(input).to eq permitted_params(input, { param_1: Hash })
|
77
144
|
end
|
78
145
|
|
79
|
-
it
|
80
|
-
input = { number: 1, string:
|
81
|
-
output = { number: 1, string:
|
146
|
+
it 'should return a several types for several inputs' do
|
147
|
+
input = { number: 1, string: 'string', bol: 'true', array: [1, 2], hsh: { a: 3 } }
|
148
|
+
output = { number: 1, string: 'string', bol: true, array: [1, 2], hsh: { a: 3 } }
|
82
149
|
expect(output).to eq permitted_params(
|
83
|
-
input,
|
84
|
-
{
|
150
|
+
input,
|
151
|
+
{
|
85
152
|
number: Integer,
|
86
153
|
string: String,
|
87
154
|
bol: Boolean,
|
@@ -91,15 +158,30 @@ describe "exceptions" do
|
|
91
158
|
)
|
92
159
|
end
|
93
160
|
|
94
|
-
it
|
95
|
-
|
96
|
-
|
97
|
-
expect(output).to eq permitted_params(input, { param_1: Integer })
|
98
|
-
end
|
161
|
+
it 'returns the paramter without casting if Any' do
|
162
|
+
class TestClass
|
163
|
+
attr_accessor :some_attribute
|
99
164
|
|
100
|
-
|
101
|
-
|
102
|
-
|
165
|
+
def initialize(some_attribute: nil)
|
166
|
+
@some_attribute = some_attribute
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
input = { param_1: '1' }
|
171
|
+
output = { param_1: '1' }
|
172
|
+
expect(output).to eq permitted_params(input, { param_1: Any })
|
173
|
+
|
174
|
+
input = {
|
175
|
+
param_1: TestClass.new(some_attribute: 'a string')
|
176
|
+
}
|
177
|
+
output = permitted_params(input, { param_1: Any })
|
178
|
+
expect(input[:param_1].some_attribute).to eq output[:param_1].some_attribute
|
179
|
+
|
180
|
+
input = {
|
181
|
+
param_1: TestClass.new(some_attribute: 1),
|
182
|
+
param_2: 2
|
183
|
+
}
|
184
|
+
output = permitted_params(input, { param_1: Any })
|
185
|
+
expect(input[:param_1].some_attribute).to eq output[:param_1].some_attribute
|
103
186
|
end
|
104
187
|
end
|
105
|
-
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra-my-params
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marco Aviles
|
@@ -10,7 +10,7 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2021-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description: A simple
|
13
|
+
description: A simple params sanitizer(originally created for sinatra)
|
14
14
|
email: gdmarav374@gmail.com
|
15
15
|
executables: []
|
16
16
|
extensions: []
|