parametric 0.0.1 → 0.2.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.
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'default validators' do
4
+
5
+ def test_validator(payload, key, name, eligible, valid, *args)
6
+ validator = Parametric.registry.policies[name]
7
+ validator = validator.new(*args) if validator.respond_to?(:new)
8
+ expect(validator.eligible?(payload[key], key, payload)).to eq eligible
9
+ expect(validator.valid?(payload[key], key, payload)).to eq valid
10
+ end
11
+
12
+ describe ':format' do
13
+ it {
14
+ test_validator({key: 'Foobar'}, :key, :format, true, true, /^Foo/)
15
+ test_validator({key: 'Foobar'}, :key, :format, true, false, /^Bar/)
16
+ test_validator({foo: 'Foobar'}, :key, :format, false, true, /^Foo/)
17
+ }
18
+ end
19
+
20
+ describe ':email' do
21
+ it {
22
+ test_validator({key: 'foo@bar.com'}, :key, :email, true, true)
23
+ test_validator({key: 'foo@'}, :key, :email, true, false)
24
+ test_validator({foo: 'foo@bar.com'}, :key, :email, false, true)
25
+ }
26
+ end
27
+
28
+ describe ':required' do
29
+ it {
30
+ test_validator({key: 'foo'}, :key, :required, true, true)
31
+ test_validator({key: ''}, :key, :required, true, true)
32
+ test_validator({key: nil}, :key, :required, true, true)
33
+ test_validator({foo: 'foo'}, :key, :required, true, false)
34
+ }
35
+ end
36
+
37
+ describe ':present' do
38
+ it {
39
+ test_validator({key: 'foo'}, :key, :present, true, true)
40
+ test_validator({key: ''}, :key, :present, true, false)
41
+ test_validator({key: nil}, :key, :present, true, false)
42
+ test_validator({foo: 'foo'}, :key, :present, true, false)
43
+ }
44
+ end
45
+
46
+ describe ':declared' do
47
+ it {
48
+ test_validator({key: 'foo'}, :key, :declared, true, true)
49
+ test_validator({key: ''}, :key, :declared, true, true)
50
+ test_validator({key: nil}, :key, :declared, true, true)
51
+ test_validator({foo: 'foo'}, :key, :declared, false, true)
52
+ }
53
+ end
54
+
55
+ describe ':gt' do
56
+ it {
57
+ test_validator({key: 10}, :key, :gt, true, true, 9)
58
+ test_validator({key: '10'}, :key, :gt, true, true, 9)
59
+ test_validator({key: 10}, :key, :gt, true, false, 11)
60
+ test_validator({key: '10'}, :key, :gt, true, false, 11)
61
+ test_validator({foo: '10'}, :key, :gt, true, true, 11)
62
+ }
63
+ end
64
+
65
+ describe ':lt' do
66
+ it {
67
+ test_validator({key: 10}, :key, :lt, true, true, 11)
68
+ test_validator({key: '10'}, :key, :lt, true, true, 11)
69
+ test_validator({key: 10}, :key, :lt, true, false, 9)
70
+ test_validator({key: '10'}, :key, :lt, true, false, 9)
71
+ test_validator({foo: '10'}, :key, :lt, true, true, 9)
72
+ }
73
+ end
74
+
75
+ describe ':options' do
76
+ it {
77
+ test_validator({key: 'b'}, :key, :options, true, true, %w(a b c))
78
+ test_validator({key: 'd'}, :key, :options, true, false, %w(a b c))
79
+ test_validator({key: ['c', 'b']}, :key, :options, true, true, %w(a b c))
80
+ test_validator({key: ['c', 'b', 'd']}, :key, :options, true, false, %w(a b c))
81
+ test_validator({foo: 'b'}, :key, :options, false, true, %w(a b c))
82
+ }
83
+ end
84
+
85
+ describe ':array' do
86
+ it {
87
+ test_validator({key: ['a', 'b']}, :key, :array, true, true)
88
+ test_validator({key: []}, :key, :array, true, true)
89
+ test_validator({key: nil}, :key, :array, true, false)
90
+ test_validator({key: 'hello'}, :key, :array, true, false)
91
+ test_validator({key: 123}, :key, :array, true, false)
92
+ test_validator({foo: []}, :key, :array, true, true)
93
+ }
94
+ end
95
+
96
+ describe ':object' do
97
+ it {
98
+ test_validator({key: {'a' =>'b'}}, :key, :object, true, true)
99
+ test_validator({key: {}}, :key, :object, true, true)
100
+ test_validator({key: ['a', 'b']}, :key, :object, true, false)
101
+ test_validator({key: nil}, :key, :object, true, false)
102
+ test_validator({key: 123}, :key, :object, true, false)
103
+ test_validator({foo: {}}, :key, :object, true, true)
104
+ }
105
+ end
106
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parametric
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ismael Celis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-13 00:00:00.000000000 Z
11
+ date: 2019-09-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -40,6 +40,20 @@ dependencies:
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 3.4.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 3.4.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: byebug
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - ">="
@@ -67,15 +81,31 @@ files:
67
81
  - LICENSE.txt
68
82
  - README.md
69
83
  - Rakefile
84
+ - bin/console
70
85
  - lib/parametric.rb
71
- - lib/parametric/hash.rb
72
- - lib/parametric/params.rb
86
+ - lib/parametric/block_validator.rb
87
+ - lib/parametric/context.rb
88
+ - lib/parametric/default_types.rb
89
+ - lib/parametric/dsl.rb
90
+ - lib/parametric/field.rb
91
+ - lib/parametric/field_dsl.rb
73
92
  - lib/parametric/policies.rb
74
- - lib/parametric/utils.rb
93
+ - lib/parametric/registry.rb
94
+ - lib/parametric/results.rb
95
+ - lib/parametric/schema.rb
96
+ - lib/parametric/struct.rb
75
97
  - lib/parametric/version.rb
76
98
  - parametric.gemspec
77
- - spec/parametric_spec.rb
99
+ - spec/custom_block_validator_spec.rb
100
+ - spec/dsl_spec.rb
101
+ - spec/expand_spec.rb
102
+ - spec/field_spec.rb
103
+ - spec/policies_spec.rb
104
+ - spec/schema_spec.rb
105
+ - spec/schema_walk_spec.rb
78
106
  - spec/spec_helper.rb
107
+ - spec/struct_spec.rb
108
+ - spec/validators_spec.rb
79
109
  homepage: ''
80
110
  licenses:
81
111
  - MIT
@@ -96,11 +126,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
126
  version: '0'
97
127
  requirements: []
98
128
  rubyforge_project:
99
- rubygems_version: 2.1.11
129
+ rubygems_version: 2.7.7
100
130
  signing_key:
101
131
  specification_version: 4
102
132
  summary: DSL for declaring allowed parameters with options, regexp patern and default
103
133
  values.
104
134
  test_files:
105
- - spec/parametric_spec.rb
135
+ - spec/custom_block_validator_spec.rb
136
+ - spec/dsl_spec.rb
137
+ - spec/expand_spec.rb
138
+ - spec/field_spec.rb
139
+ - spec/policies_spec.rb
140
+ - spec/schema_spec.rb
141
+ - spec/schema_walk_spec.rb
106
142
  - spec/spec_helper.rb
143
+ - spec/struct_spec.rb
144
+ - spec/validators_spec.rb
@@ -1,36 +0,0 @@
1
- module Parametric
2
- module Hash
3
-
4
- def self.included(base)
5
- base.send(:include, Params)
6
- base.send(:include, Enumerable)
7
- base.extend Forwardable
8
- base.send(:def_delegators, :params,
9
- :[],
10
- :[]=,
11
- :each,
12
- :each_value,
13
- :each_key,
14
- :each_pair,
15
- :keys,
16
- :values,
17
- :values_at,
18
- :fetch,
19
- :size,
20
- :to_hash,
21
- :merge,
22
- :merge!,
23
- :replace,
24
- :update,
25
- :has_key?,
26
- :key?,
27
- :key,
28
- :select,
29
- :select!,
30
- :delete,
31
- :store
32
- )
33
- end
34
-
35
- end
36
- end
@@ -1,60 +0,0 @@
1
- module Parametric
2
-
3
- module Params
4
-
5
- def self.included(base)
6
- base.send(:attr_reader, :params)
7
- base.extend DSL
8
- end
9
-
10
- def initialize(raw_params = {})
11
- @params = _reduce(raw_params)
12
- end
13
-
14
- def available_params
15
- @available_params ||= params.each_with_object({}) do |(k,v),memo|
16
- memo[k] = v if Utils.present?(v)
17
- end
18
- end
19
-
20
- def schema
21
- @schema ||= params.each_with_object({}) do |(k,v),memo|
22
- memo[k] = {
23
- value: Utils.value(v),
24
- label: self.class._allowed_params[k][:label],
25
- multiple: !!self.class._allowed_params[k][:multiple]
26
- }
27
- memo[k][:match] = self.class._allowed_params[k][:match].to_s if self.class._allowed_params[k].has_key?(:match)
28
- memo[k][:options] = self.class._allowed_params[k][:options] if self.class._allowed_params[k].has_key?(:options)
29
- end
30
- end
31
-
32
- protected
33
-
34
- def _reduce(raw_params)
35
- self.class._allowed_params.each_with_object({}) do |(key,options),memo|
36
- policy = Policies::Policy.new(raw_params[key], options)
37
- policy = policy.wrap(Policies::MultiplePolicy) if options[:multiple]
38
- policy = policy.wrap(Policies::OptionsPolicy) if options[:options]
39
- policy = policy.wrap(Policies::MatchPolicy) if options[:match]
40
- policy = policy.wrap(Policies::DefaultPolicy) if options.has_key?(:default)
41
- policy = policy.wrap(Policies::SinglePolicy) unless options[:multiple]
42
-
43
- memo[key] = policy.value
44
- end
45
- end
46
-
47
- module DSL
48
- def _allowed_params
49
- @allowed_params ||= {}
50
- end
51
-
52
- def param(field_name, label = '', opts = {})
53
- opts[:label] = label
54
- _allowed_params[field_name] = opts
55
- end
56
- end
57
-
58
- end
59
-
60
- end
@@ -1,24 +0,0 @@
1
- module Parametric
2
- module Utils
3
- def self.value(val)
4
- if val.nil?
5
- ''
6
- elsif val.is_a?(Array)
7
- val.join(',')
8
- else
9
- val
10
- end
11
- end
12
-
13
- def self.present?(value)
14
- case value
15
- when String
16
- value.strip != ''
17
- when Array, Hash
18
- value.any?
19
- else
20
- !value.nil?
21
- end
22
- end
23
- end
24
- end
@@ -1,182 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Parametric do
4
- it 'should have a version number' do
5
- Parametric::VERSION.should_not be_nil
6
- end
7
-
8
- describe Parametric do
9
-
10
- let(:klass) do
11
- Class.new do
12
- include Parametric::Params
13
- param :name, 'User name'
14
- param :page, 'page number', default: 1
15
- param :per_page, 'items per page', default: 50
16
- param :status, 'status', options: ['one', 'two', 'three'], multiple: true
17
- param :piped_status, 'status with pipes', multiple: true, separator: '|'
18
- param :country, 'country', options: ['UK', 'CL', 'JPN']
19
- param :email, 'email', match: /\w+@\w+\.\w+/
20
- param :emails, 'emails', match: /\w+@\w+\.\w+/, multiple: true, default: 'default@email.com'
21
- end
22
- end
23
-
24
- describe '#params' do
25
- let(:subject) { klass.new(foo: 'bar', per_page: 20, status: 'four') }
26
-
27
- it 'ignores undeclared fields' do
28
- subject.params.has_key?(:foo).should be_false
29
- end
30
-
31
- it 'sets passed values' do
32
- subject.params[:per_page].should == 20
33
- end
34
-
35
- it 'uses defaults if no value passed' do
36
- subject.params[:page].should == 1
37
- end
38
-
39
- it 'does not set value if outside of declared options' do
40
- subject.params[:status].should == []
41
- end
42
-
43
- it 'does not set value if it does not :match' do
44
- klass.new(email: 'my@email').params[:email].should be_nil
45
- end
46
-
47
- it 'does set value if it does :match' do
48
- klass.new(email: 'my@email.com').params[:email].should == 'my@email.com'
49
- end
50
-
51
- it 'only sets value for :multiple values that :match' do
52
- klass.new(emails: 'my@email,your,her@email.com').params[:emails].should == ['her@email.com']
53
- end
54
-
55
- it 'returns :default wrapped in array if :multiple' do
56
- klass.new().params[:emails].should == ['default@email.com']
57
- end
58
-
59
- it 'turns :multiple comma-separated values into arrays' do
60
- klass.new(status: 'one,three').params[:status].should == ['one', 'three']
61
- end
62
-
63
- it 'turns :multiple separated values with custom separator into arrays' do
64
- klass.new(piped_status: 'one|three').params[:piped_status].should == ['one', 'three']
65
- end
66
-
67
- it 'does not turn non-multiple comma-separated values into arrays' do
68
- klass.new(name: 'foo,bar').params[:name].should == 'foo,bar'
69
- end
70
-
71
- it 'filters out undeclared options' do
72
- klass.new(status: 'one,three,fourteen').params[:status].should == ['one', 'three']
73
- end
74
-
75
- it 'defaults empty multiple options to empty array' do
76
- klass.new().params[:status].should == []
77
- end
78
-
79
- it 'wraps single multiple options in array' do
80
- klass.new(status: 'one').params[:status].should == ['one']
81
- end
82
-
83
- it 'does not accept comma-separated values outside of options unless :multiple == true' do
84
- klass.new(country: 'UK,CL').params[:country].should be_nil
85
- end
86
-
87
- it 'does accept single option' do
88
- klass.new(country: 'UK').params[:country].should == 'UK'
89
- end
90
-
91
- it 'does not accept single option if not in declared options' do
92
- klass.new(country: 'USA').params[:country].should be_nil
93
- end
94
- end
95
-
96
- describe '#available_params' do
97
- let(:subject) { klass.new(foo: 'bar', name: 'lala', per_page: 20, status: 'four') }
98
-
99
- it 'only includes declared params with values or defaults' do
100
- subject.available_params.keys.sort.should == [:emails, :name, :page, :per_page]
101
- subject.available_params[:emails].should == ["default@email.com"]
102
- subject.available_params[:name].should == 'lala'
103
- subject.available_params[:per_page].should == 20
104
- subject.available_params[:page].should == 1
105
- end
106
- end
107
-
108
- describe '#schema' do
109
- let(:subject) { klass.new(foo: 'bar', name: 'lala', per_page: 20, status: 'four') }
110
-
111
- it 'returns full param definitions with populated value' do
112
- regexp = /\w+@\w+\.\w+/.to_s
113
-
114
- subject.schema[:name][:label].should == 'User name'
115
- subject.schema[:name][:value].should == 'lala'
116
-
117
- subject.schema[:page][:label].should == 'page number'
118
- subject.schema[:page][:value].should == 1
119
-
120
- subject.schema[:per_page][:label].should == 'items per page'
121
- subject.schema[:per_page][:value].should == 20
122
-
123
- subject.schema[:status][:label].should == 'status'
124
- subject.schema[:status][:value].should == ''
125
- subject.schema[:status][:options].should == ['one', 'two', 'three']
126
- subject.schema[:status][:multiple].should be_true
127
-
128
- subject.schema[:piped_status][:label].should == 'status with pipes'
129
- subject.schema[:piped_status][:value].should == ''
130
- subject.schema[:piped_status][:multiple].should be_true
131
-
132
- subject.schema[:country][:label].should == 'country'
133
- subject.schema[:country][:value].should == ''
134
- subject.schema[:country][:options].should == ['UK', 'CL', 'JPN']
135
-
136
- subject.schema[:email][:label].should == 'email'
137
- subject.schema[:email][:value].should == ''
138
- subject.schema[:email][:match].should == regexp
139
-
140
- subject.schema[:emails][:label].should == 'emails'
141
- subject.schema[:emails][:value].should == 'default@email.com'
142
- subject.schema[:emails][:multiple].should be_true
143
- subject.schema[:emails][:match].should == regexp
144
- end
145
- end
146
- end
147
-
148
- describe Parametric::Hash do
149
- let(:klass) do
150
- Class.new do
151
- include Parametric::Hash
152
- param :name, 'User name'
153
- param :page, 'page number', default: 1
154
- param :per_page, 'items per page', default: 50
155
- end
156
- end
157
-
158
- let(:subject) { klass.new(name: 'Ismael', page: 2) }
159
-
160
- it 'quacks like a hash' do
161
- subject[:name].should == 'Ismael'
162
- subject[:page].should == 2
163
- subject[:per_page].should == 50
164
- subject.map{|k,v| k}.sort.should == [:name, :page, :per_page]
165
- subject.keys.sort.should == [:name, :page, :per_page]
166
- subject.values.map(&:to_s).sort.should == ['2', '50', 'Ismael']
167
- subject.fetch(:page, 0).should == 2
168
- subject.fetch(:foo, 0).should == 0
169
- subject.merge(foo: 22).should == {name: 'Ismael', page: 2, per_page: 50, foo: 22}
170
- subject.select{|k,v| k == :name}.should == {name: 'Ismael'}
171
- end
172
-
173
- it 'has #available_params' do
174
- subject.available_params[:name].should == 'Ismael'
175
- end
176
-
177
- it 'has #schema' do
178
- subject.schema[:name][:label].should == 'User name'
179
- subject.schema[:name][:value].should == 'Ismael'
180
- end
181
- end
182
- end