sinatra-my-params 0.0.6 → 0.0.10

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