parametric 0.0.1 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -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