focuslight-validator 0.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 030827b98f945a997ab1cb763a7eb06eccc056e8
4
+ data.tar.gz: f82194c2a9738884198a68b2c903a0303f3f5bb9
5
+ SHA512:
6
+ metadata.gz: 1723f550b4a205fd30f46af70832b638a276d7e0d1b60cf6fd648e454ef9d5276c945ffc4c5e9b9ba9090d6c9e3eda5457f145d639f651478451364d43e19ebd
7
+ data.tar.gz: 6164367cc18db7cfec3b0fc7e82b130e757060f253f0c0e8e2b9e24c7f3596f220c4c7b6e5f45105a93bd797331857eb71a20dc95c2d477ecd0d65274c0be6b8
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in focuslight-validator.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 TAGOMORI Satoshi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,73 @@
1
+ # Focuslight::Validator
2
+
3
+ Validate http request parameters (or others) by defined rule, without models.
4
+
5
+ SYNOPSIS:
6
+
7
+ require 'focuslight-validator'
8
+
9
+ result = Validator.validate(params, {
10
+ :request_param_key_name => { # single key, single value
11
+ :default => default_value,
12
+ :rule => [
13
+ Validator.rule(:not_null),
14
+ Validator.rule(:int_range, 0..10),
15
+ ],
16
+ },
17
+ :array_value_key_name => { # single key, array value
18
+ :array => true
19
+ :size => 1..10 # default is unlimited (empty also allowed)
20
+ # default cannot be used
21
+ :rule => [ ... ]
22
+ }
23
+ # ...
24
+ [:param1, :param2, :param3] => { # rule for combination of 2 or more params
25
+ # default cannot be used
26
+ :rule => Validator::Rule.new(->(p1, p2, p3){ ... }, "error_message")
27
+ },
28
+ }
29
+
30
+ result.has_error? #=> true/false
31
+ result.errors #=> Hash( { param_name => "error message" } )
32
+
33
+ ## Installation
34
+
35
+ Add this line to your application's Gemfile:
36
+
37
+ gem 'focuslight-validator'
38
+
39
+ And then execute:
40
+
41
+ $ bundle
42
+
43
+ Or install it yourself as:
44
+
45
+ $ gem install focuslight-validator
46
+
47
+ ## Usage
48
+
49
+ TBD: default/array/size/rule
50
+
51
+ ### Available built-in rules
52
+
53
+ TBD
54
+
55
+ ### Lambda rule
56
+
57
+ TBD
58
+
59
+ ### Array value validation
60
+
61
+ TBD
62
+
63
+ ### Combination validation
64
+
65
+ TBD
66
+
67
+ ## Contributing
68
+
69
+ 1. Fork it ( http://github.com/<my-github-username>/focuslight-validator/fork )
70
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
71
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
72
+ 4. Push to the branch (`git push origin my-new-feature`)
73
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'focuslight/validator/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "focuslight-validator"
8
+ spec.version = Focuslight::Validator::VERSION
9
+ spec.authors = ["TAGOMORI Satoshi"]
10
+ spec.email = ["tagomoris@gmail.com"]
11
+ spec.summary = %q{Validate http request parameters (or others) by defined rule, without models.}
12
+ # spec.description = %q{TODO: Write a longer description. Optional.}
13
+ spec.homepage = "https://github.com/focuslight/focuslight-validator"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ end
@@ -0,0 +1 @@
1
+ require "focuslight/validator"
@@ -0,0 +1,149 @@
1
+ require "focuslight/validator/version"
2
+ require "focuslight/validator/rule"
3
+ require "focuslight/validator/result"
4
+
5
+ module Focuslight
6
+ module Validator
7
+ def self.validate(params, spec)
8
+ result = Result.new
9
+ spec.each do |key, specitem|
10
+ if key.is_a?(Array)
11
+ validate_multi_key(result, params, key, specitem)
12
+ elsif specitem[:array]
13
+ validate_array(result, params, key, specitem)
14
+ else
15
+ validate_single(result, params, key, specitem)
16
+ end
17
+ end
18
+ result
19
+ end
20
+
21
+ def self.validate_single(result, params, key_arg, spec)
22
+ key = key_arg.to_sym
23
+
24
+ value = params[key]
25
+ if spec.has_key?(:default) && value.nil?
26
+ value = spec[:default]
27
+ end
28
+ if spec[:excludable] && value.nil?
29
+ result[key] = nil
30
+ return
31
+ end
32
+
33
+ rules = [spec[:rule]].flatten.compact
34
+
35
+ errors = []
36
+ valid = true
37
+ formatted = value
38
+
39
+ rules.each do |rule|
40
+ if rule.check(value)
41
+ formatted = rule.format(value)
42
+ else
43
+ result.error(key, rule.message)
44
+ valid = false
45
+ end
46
+ end
47
+
48
+ if valid
49
+ result[key] = formatted
50
+ end
51
+ end
52
+
53
+ def self.validate_array(result, params, key_arg, spec)
54
+ key = key_arg.to_sym
55
+
56
+ values = params[key]
57
+ if spec.has_key?(:default)
58
+ raise ArgumentError, "array parameter cannot have :default"
59
+ end
60
+ if spec[:excludable] && value.nil?
61
+ result[key] = []
62
+ end
63
+
64
+ if spec.has_key?(:size)
65
+ if (values.nil? || values.size == 0) && !spec[:size].include?(0)
66
+ result.error(key, "not allowed for empty")
67
+ return
68
+ end
69
+ if !spec[:size].include?(values.size)
70
+ result.error(key, "doesn't have values specified: #{spec[:size]}")
71
+ return
72
+ end
73
+ end
74
+
75
+ unless values.is_a?(Array)
76
+ values = [values]
77
+ end
78
+
79
+ rules = [spec[:rule]].flatten.compact
80
+
81
+ error_values = []
82
+ valid = true
83
+ formatted_values = []
84
+
85
+ values.each do |value|
86
+ errors = []
87
+ formatted = nil
88
+ rules.each do |rule|
89
+ if rule.check(value)
90
+ formatted = rule.format(value)
91
+ else
92
+ result.error(key, rule.message)
93
+ valid = false
94
+ end
95
+ end
96
+ error_values += errors
97
+ formatted_values.push(formatted) if formatted
98
+ end
99
+
100
+ if valid
101
+ result[key] = formatted_values
102
+ end
103
+ end
104
+
105
+ def self.validate_multi_key(result, params, keys, spec)
106
+ values = keys.map{|key| params[key.to_sym]}
107
+ if spec.has_key?(:default)
108
+ raise ArgumentError, "multi key validation spec cannot have :default"
109
+ end
110
+
111
+ rules = [spec[:rule]].flatten.compact
112
+ errors = []
113
+
114
+ rules.each do |rule|
115
+ unless rule.check(*values)
116
+ result.error(keys.map{|s| s.to_s}.join(','), rule.message)
117
+ end
118
+ end
119
+ end
120
+
121
+ def self.rule(type, *args)
122
+ args.flatten!
123
+ case type
124
+ when :not_blank
125
+ Rule.new(->(v){not v.nil? and not v.strip.empty?}, "missing or blank", :strip)
126
+ when :choice
127
+ Rule.new(->(v){args.include?(v)}, "invalid value")
128
+ when :int
129
+ Rule.new(->(v){v =~ /^-?\d+$/}, "invalid integer", :to_i)
130
+ when :uint
131
+ Rule.new(->(v){v =~ /^\d+$/}, "invalid integer (>= 0)", :to_i)
132
+ when :natural
133
+ Rule.new(->(v){v =~ /^\d+$/ && v.to_i >= 1}, "invalid integer (>= 1)", :to_i)
134
+ when :float, :double, :real
135
+ Rule.new(->(v){v =~ /^\-?(\d+\.?\d*|\.\d+)(e[+-]\d+)?$/}, "invalid floating point num", :to_f)
136
+ when :int_range
137
+ Rule.new(->(v){args.first.include?(v.to_i)}, "invalid number in range #{args.first}", :to_i)
138
+ when :bool
139
+ Rule.new(->(v){v =~ /^(0|1|true|false)$/i}, "invalid bool value", ->(v){!!(v =~ /^(1|true)$/i)})
140
+ when :regexp
141
+ Rule.new(->(v){v =~ args.first}, "invalid input for pattern #{args.first.source}")
142
+ when :lambda
143
+ Rule.new(*args)
144
+ else
145
+ raise ArgumentError, "unknown validator rule: #{type}"
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,32 @@
1
+ module Focuslight
2
+ module Validator
3
+ class Result
4
+ attr_reader :errors
5
+
6
+ def initialize
7
+ @errors = {}
8
+ @params = {}
9
+ end
10
+
11
+ def hash
12
+ @params.dup
13
+ end
14
+
15
+ def [](name)
16
+ @params[name.to_sym]
17
+ end
18
+
19
+ def []=(name, value)
20
+ @params[name.to_sym] = value
21
+ end
22
+
23
+ def error(param, message)
24
+ @errors[param.to_sym] = "#{param}: " + message
25
+ end
26
+
27
+ def has_error?
28
+ not @errors.empty?
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,27 @@
1
+ module Focuslight
2
+ module Validator
3
+ class Rule
4
+ attr_reader :message
5
+
6
+ def initialize(checker, invalid_message, formatter=nil)
7
+ @checker = checker
8
+ @message = invalid_message
9
+ @formatter = formatter
10
+ end
11
+
12
+ def check(*values)
13
+ @checker.(*values)
14
+ end
15
+
16
+ def format(value)
17
+ if @formatter && @formatter.is_a?(Symbol)
18
+ value.send(@formatter)
19
+ elsif @formatter
20
+ @formatter.(value)
21
+ else
22
+ value
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ module Focuslight
2
+ module Validator
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
@@ -0,0 +1,9 @@
1
+ require_relative './spec_helper'
2
+
3
+ describe Focuslight do
4
+ it 'has modules that passes syntax check' do
5
+ Dir.glob(__dir__ + '/../lib/**/*.rb').each do |file|
6
+ require file
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,177 @@
1
+ require_relative './spec_helper'
2
+
3
+ require 'focuslight/validator'
4
+
5
+ describe Focuslight::Validator do
6
+ describe '.rule' do
7
+ it 'returns not_blank predefined rule' do
8
+ r = Focuslight::Validator.rule(:not_blank)
9
+ expect(r.check(nil)).to be_false
10
+ expect(r.check("")).to be_false
11
+ expect(r.check(" ")).to be_false
12
+ expect(r.check("a")).to be_true
13
+
14
+ expect(r.format("a")).to eql("a")
15
+ expect(r.format(" a ")).to eql("a")
16
+
17
+ expect(r.message).to eql("missing or blank")
18
+ end
19
+
20
+ it 'returns choice predefined rule' do
21
+ r1 = Focuslight::Validator.rule(:choice, "x", "y", "z")
22
+ expect(r1.check("a")).to be_false
23
+ expect(r1.check("x")).to be_true
24
+ expect(r1.check("z")).to be_true
25
+
26
+ expect(r1.format("x")).to eql("x")
27
+
28
+ expect(r1.message).to eql("invalid value")
29
+
30
+ r2 = Focuslight::Validator.rule(:choice, ["x", "y", "z"])
31
+ expect(r2.check("a")).to be_false
32
+ expect(r2.check("x")).to be_true
33
+ expect(r2.check("z")).to be_true
34
+
35
+ expect(r2.format("x")).to eql("x")
36
+ end
37
+
38
+ it 'returns int predefined rule' do
39
+ r = Focuslight::Validator.rule(:int)
40
+ expect(r.check("0")).to be_true
41
+ expect(r.check("100")).to be_true
42
+ expect(r.check("-21")).to be_true
43
+ expect(r.check("1.0")).to be_false
44
+ expect(r.check("-3e10")).to be_false
45
+ expect(r.check("xyz")).to be_false
46
+
47
+ expect(r.format("0")).to eql(0)
48
+ expect(r.format("100")).to eql(100)
49
+ expect(r.format("-21")).to eql(-21)
50
+
51
+ expect(r.message).to eql("invalid integer")
52
+ end
53
+
54
+ it 'returns uint predefined rule' do
55
+ r = Focuslight::Validator.rule(:uint)
56
+ expect(r.check("0")).to be_true
57
+ expect(r.check("100")).to be_true
58
+ expect(r.check("-21")).to be_false
59
+ expect(r.check("1.0")).to be_false
60
+ expect(r.check("-3e10")).to be_false
61
+ expect(r.check("xyz")).to be_false
62
+
63
+ expect(r.format("0")).to eql(0)
64
+ expect(r.format("100")).to eql(100)
65
+
66
+ expect(r.message).to eql("invalid integer (>= 0)")
67
+ end
68
+
69
+ it 'returns natural predefined rule' do
70
+ r = Focuslight::Validator.rule(:natural)
71
+ expect(r.check("0")).to be_false
72
+ expect(r.check("100")).to be_true
73
+ expect(r.check("-21")).to be_false
74
+ expect(r.check("1.0")).to be_false
75
+ expect(r.check("-3e10")).to be_false
76
+ expect(r.check("xyz")).to be_false
77
+
78
+ expect(r.format("0")).to eql(0)
79
+ expect(r.format("100")).to eql(100)
80
+
81
+ expect(r.message).to eql("invalid integer (>= 1)")
82
+ end
83
+
84
+ it 'returns float/double/real predefined rule' do
85
+ r1 = Focuslight::Validator.rule(:float)
86
+ r2 = Focuslight::Validator.rule(:double)
87
+ r3 = Focuslight::Validator.rule(:real)
88
+ [r1, r2, r3].each do |r|
89
+ expect(r.check("0")).to be_true
90
+ expect(r.check("0.0")).to be_true
91
+ expect(r.check("1.0")).to be_true
92
+ expect(r.check("1e+10")).to be_true
93
+ expect(r.check("2e-10")).to be_true
94
+ expect(r.check("-2e-10")).to be_true
95
+ expect(r.check("e")).to be_false
96
+ expect(r.check("xyz")).to be_false
97
+ expect(r.check("")).to be_false
98
+
99
+ expect(r.format("0")).to eql(0.0)
100
+ expect(r.format("0.0")).to eql(0.0)
101
+ expect(r.format("1.0")).to eql(1.0)
102
+ expect(r.format("1e+10")).to eql(1e+10)
103
+ expect(r.format("2e-10")).to eql(2e-10)
104
+ expect(r.format("-2e-10")).to eql(-2e-10)
105
+
106
+ expect(r.message).to eql("invalid floating point num")
107
+ end
108
+ end
109
+
110
+ it 'returns int_range predefined rule' do
111
+ r1 = Focuslight::Validator.rule(:int_range, 0..3)
112
+ expect(r1.check("0")).to be_true
113
+ expect(r1.check("1")).to be_true
114
+ expect(r1.check("3")).to be_true
115
+ expect(r1.check("-1")).to be_false
116
+
117
+ expect(r1.format("0")).to eql(0)
118
+
119
+ expect(r1.message).to eql("invalid number in range 0..3")
120
+
121
+ r2 = Focuslight::Validator.rule(:int_range, 1..3)
122
+ expect(r2.check("0")).to be_false
123
+ expect(r2.check("1")).to be_true
124
+ expect(r2.check("3")).to be_true
125
+ expect(r2.check("-1")).to be_false
126
+
127
+ expect(r2.format("1")).to eql(1)
128
+
129
+ expect(r2.message).to eql("invalid number in range 1..3")
130
+ end
131
+
132
+ it 'returns bool predefined rule, which parse numeric 1/0 as true/false' do
133
+ r = Focuslight::Validator.rule(:bool)
134
+ expect(r.check("0")).to be_true
135
+ expect(r.check("1")).to be_true
136
+ expect(r.check("true")).to be_true
137
+ expect(r.check("True")).to be_true
138
+ expect(r.check("false")).to be_true
139
+ expect(r.check("nil")).to be_false
140
+ expect(r.check("maru")).to be_false
141
+ expect(r.check("")).to be_false
142
+
143
+ expect(r.format("0")).to equal(false)
144
+ expect(r.format("1")).to equal(true)
145
+ expect(r.format("true")).to equal(true)
146
+ expect(r.format("True")).to equal(true)
147
+ expect(r.format("false")).to equal(false)
148
+
149
+ expect(r.message).to eql("invalid bool value")
150
+ end
151
+
152
+ it 'return regexp predefined rule' do
153
+ r = Focuslight::Validator.rule(:regexp, /^[0-9a-f]{4}$/i)
154
+ expect(r.check("000")).to be_false
155
+ expect(r.check("0000")).to be_true
156
+ expect(r.check("00000")).to be_false
157
+ expect(r.check("a0a0")).to be_true
158
+ expect(r.check("FFFF")).to be_true
159
+
160
+ str = "FfFf"
161
+ expect(r.format(str)).to equal(str)
162
+
163
+ expect(r.message).to eql("invalid input for pattern ^[0-9a-f]{4}$")
164
+ end
165
+
166
+ it 'returns rule instance whatever we want with "lambda" rule name' do
167
+ r = Focuslight::Validator.rule(:lambda, ->(v){ v == 'kazeburo' }, "kazeburo only permitted", :to_sym)
168
+ expect(r.check("kazeburo")).to be_true
169
+ expect(r.check(" ")).to be_false
170
+ expect(r.check("tagomoris")).to be_false
171
+
172
+ expect(r.format("kazeburo")).to eql(:kazeburo)
173
+
174
+ expect(r.message).to eql("kazeburo only permitted")
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,27 @@
1
+ require_relative './spec_helper'
2
+
3
+ require 'focuslight/validator'
4
+
5
+ describe Focuslight::Validator::Result do
6
+ it 'indicate that it has errors or not' do
7
+ r = Focuslight::Validator::Result.new
8
+ expect(r.has_error?).to be_false
9
+ r.error(:key, "error 1")
10
+ expect(r.has_error?).to be_true
11
+ expect(r.errors).to eql({key: "key: error 1"})
12
+ r.error(:key2, "error 2")
13
+ expect(r.has_error?).to be_true
14
+ expect(r.errors).to eql({key:"key: error 1", key2:"key2: error 2"})
15
+ end
16
+
17
+ it 'can contain values like Hash, but keys are symbolized' do
18
+ r = Focuslight::Validator::Result.new
19
+ expect(r[:something]).to be_nil
20
+ r['something'] = 'somevalue'
21
+ expect(r[:something]).to eql("somevalue")
22
+ r[:key1] = "value1"
23
+ expect(r[:key1]).to eql("value1")
24
+ r[:key2] = ["value2", "value2alt"]
25
+ expect(r[:key2]).to eql(["value2", "value2alt"])
26
+ end
27
+ end
@@ -0,0 +1,68 @@
1
+ require_relative './spec_helper'
2
+
3
+ require 'focuslight/validator'
4
+
5
+ describe Focuslight::Validator::Rule do
6
+ it 'can be initialized with 2 or 3 arguments' do
7
+ expect{ Focuslight::Validator::Rule.new() }.to raise_error(ArgumentError)
8
+ r1 = Focuslight::Validator::Rule.new(->(v){ v.nil? }, "message")
9
+ r2 = Focuslight::Validator::Rule.new(->(v){ v.nil? }, "message", ->(v){ nil })
10
+ expect{ Focuslight::Validator::Rule.new(->(v){ v.nil? }, "message", ->(v){ nil }, "something") }.to raise_error(ArgumentError)
11
+ end
12
+
13
+ describe '#check' do
14
+ it 'can validate value with first argument lambda' do
15
+ r1 = Focuslight::Validator::Rule.new(->(v){ v.nil? }, "only nil")
16
+ expect(r1.check(nil)).to be_true
17
+ expect(r1.check("str")).to be_false
18
+
19
+ r2 = Focuslight::Validator::Rule.new(->(v){ v.to_i == 1 }, "one")
20
+ expect(r2.check("0")).to be_false
21
+ expect(r2.check("1.00")).to be_true
22
+ expect(r2.check("1")).to be_true
23
+ expect(r2.check("2")).to be_false
24
+ end
25
+
26
+ it 'can receive 2 or more values for lambda arguments if specified' do
27
+ r1 = Focuslight::Validator::Rule.new(->(v1,v2,v3){ v1.to_i > v2.to_i && v2.to_i > v3.to_i }, "order by desc")
28
+ expect(r1.check("1","2","3")).to be_false
29
+ expect(r1.check("3","2","1")).to be_true
30
+ expect{ r1.check("3") }.to raise_error(ArgumentError)
31
+
32
+ r2 = Focuslight::Validator::Rule.new(->(v1){ v1.to_i > 0 }, "greater than zero")
33
+ expect{ r2.check("1", "2") }.to raise_error(ArgumentError)
34
+ end
35
+ end
36
+
37
+ describe '#format' do
38
+ context 'when formatter not specified' do
39
+ it 'returns value itself' do
40
+ r = Focuslight::Validator::Rule.new(->(v){ v.size == 3 }, "3chars")
41
+ str = "abc"
42
+ expect(r.format(str)).to equal(str)
43
+ end
44
+ end
45
+ context 'when formatter lambda specified' do
46
+ it 'returns lambda return value' do
47
+ r = Focuslight::Validator::Rule.new(->(v){ v == '0' }, 'zero', ->(v){ 0 })
48
+ expect(r.format("0")).to eql(0)
49
+ end
50
+ end
51
+ context 'when formatter symbol specified' do
52
+ it 'returns value from Symbol.to_proc' do
53
+ r = Focuslight::Validator::Rule.new(->(v){ v == '1' || v == '2' }, 'one or two', :to_i)
54
+ expect(r.format("1")).to eql(1)
55
+ expect(r.format("2")).to eql(2)
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '#message' do
61
+ it 'returns predefined message' do
62
+ r = Focuslight::Validator::Rule.new(->(v){ v.nil? }, "nil only allowed")
63
+ expect(r.message).to eql("nil only allowed")
64
+ expect(r.message).to eql("nil only allowed")
65
+ expect(r.message).to eql("nil only allowed")
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,121 @@
1
+ require_relative './spec_helper'
2
+
3
+ require 'focuslight/validator'
4
+
5
+ describe Focuslight::Validator do
6
+ describe '.validate_single' do
7
+ it 'returns default value as valid value for params without specified key' do
8
+ result = Focuslight::Validator::Result.new
9
+ params = {key1: "1", key2: "2"}
10
+ spec = {default: "0", rule: Focuslight::Validator.rule(:not_blank)}
11
+ Focuslight::Validator.validate_single(result, params, :key3, spec)
12
+
13
+ expect(result[:key3]).to eql("0")
14
+ end
15
+
16
+ it 'checks and formats about specified single key, that should have single value in params' do
17
+ params = {key1: "1", key2: "2", keyx: "x"}
18
+
19
+ result1 = Focuslight::Validator::Result.new
20
+ spec1 = {rule: Focuslight::Validator.rule(:not_blank)}
21
+ Focuslight::Validator.validate_single(result1, params, :key1, spec1)
22
+ Focuslight::Validator.validate_single(result1, params, :key2, spec1)
23
+ Focuslight::Validator.validate_single(result1, params, :keyx, spec1)
24
+ expect(result1.has_error?).to be_false
25
+ expect(result1[:key1]).to eql("1")
26
+ expect(result1[:key2]).to eql("2")
27
+ expect(result1[:keyx]).to eql("x")
28
+
29
+ result2 = Focuslight::Validator::Result.new
30
+ spec2 = {rule: [ Focuslight::Validator.rule(:not_blank), Focuslight::Validator.rule(:uint) ]}
31
+ Focuslight::Validator.validate_single(result2, params, :key1, spec2)
32
+ Focuslight::Validator.validate_single(result2, params, :key2, spec2)
33
+ Focuslight::Validator.validate_single(result2, params, :keyx, spec2)
34
+ expect(result2.has_error?).to be_true
35
+ expect(result2[:key1]).to eql(1)
36
+ expect(result2[:key2]).to eql(2)
37
+ expect(result2[:keyx]).to be_nil
38
+ expect(result2.errors).to eql({keyx: "keyx: invalid integer (>= 0)"})
39
+ end
40
+ end
41
+
42
+ describe '.validate_array' do
43
+ it 'cannot accept default spec' do
44
+ params = {key1: ["0", "1", "2"], key2: [], key3: ["kazeburo"]}
45
+
46
+ result1 = Focuslight::Validator::Result.new
47
+ spec1 = {array: true, default: 1, rule: Focuslight::Validator.rule(:not_blank)}
48
+ expect{ Focuslight::Validator.validate_array(result1, params, :key1, spec1) }.to raise_error(ArgumentError)
49
+ end
50
+
51
+ it 'checks array size' do
52
+ params = {key1: ["0", "1", "2"], key2: [], key3: ["kazeburo"]}
53
+
54
+ result1 = Focuslight::Validator::Result.new
55
+ spec1 = {array: true, size: 0..3, rule: Focuslight::Validator.rule(:not_blank)}
56
+ Focuslight::Validator.validate_array(result1, params, :key1, spec1)
57
+ Focuslight::Validator.validate_array(result1, params, :key2, spec1)
58
+ Focuslight::Validator.validate_array(result1, params, :key3, spec1)
59
+ expect(result1.has_error?).to be_false
60
+ expect(result1[:key1]).to eql(["0", "1", "2"])
61
+ expect(result1[:key2]).to eql([])
62
+ expect(result1[:key3]).to eql(["kazeburo"])
63
+
64
+ result2 = Focuslight::Validator::Result.new
65
+ spec2 = {array: true, size: 1...3, rule: Focuslight::Validator.rule(:not_blank)}
66
+ Focuslight::Validator.validate_array(result2, params, :key1, spec2)
67
+ Focuslight::Validator.validate_array(result2, params, :key2, spec2)
68
+ Focuslight::Validator.validate_array(result2, params, :key3, spec2)
69
+ expect(result2.has_error?).to be_true
70
+ expect(result2[:key1]).to be_nil
71
+ expect(result2[:key2]).to be_nil
72
+ expect(result2[:key3]).to eql(["kazeburo"])
73
+ end
74
+
75
+ it 'formats all elements of valid field' do
76
+ params = {key1: ["0", "1", "2"], key2: [], key3: ["kazeburo"]}
77
+
78
+ result1 = Focuslight::Validator::Result.new
79
+ spec1 = {array: true, size: 0..3, rule: Focuslight::Validator.rule(:not_blank)}
80
+ Focuslight::Validator.validate_array(result1, params, :key1, spec1)
81
+ Focuslight::Validator.validate_array(result1, params, :key2, spec1)
82
+ Focuslight::Validator.validate_array(result1, params, :key3, spec1)
83
+ expect(result1.has_error?).to be_false
84
+ expect(result1[:key1]).to eql(["0", "1", "2"])
85
+ expect(result1[:key2]).to eql([])
86
+ expect(result1[:key3]).to eql(["kazeburo"])
87
+
88
+ result2 = Focuslight::Validator::Result.new
89
+ spec2 = {array: true, size: 0..3, rule: [Focuslight::Validator.rule(:not_blank), Focuslight::Validator.rule(:uint)]}
90
+ Focuslight::Validator.validate_array(result2, params, :key1, spec2)
91
+ Focuslight::Validator.validate_array(result2, params, :key2, spec2)
92
+ Focuslight::Validator.validate_array(result2, params, :key3, spec2)
93
+ expect(result2.has_error?).to be_true
94
+ expect(result2[:key1]).to eql([0, 1, 2])
95
+ expect(result2[:key2]).to eql([])
96
+ expect(result2[:key3]).to be_nil
97
+ end
98
+ end
99
+ describe '.validate_multi_key' do
100
+ it 'does not accept default keyword' do
101
+ params = {key1: "10", key2: "1", key3: "0", key4: "5", key5: "3"}
102
+ result = Focuslight::Validator::Result.new
103
+ spec = { default: 1, rule: Focuslight::Validator::Rule.new(->(x,y,z){ x.to_i + y.to_i + z.to_i < 15 }, "too large") }
104
+ expect{ Focuslight::Validator.validate_multi_key(result, params, [:key1, :key2, :key3], spec) }.to raise_error(ArgumentError)
105
+ end
106
+
107
+ it 'checks complex expression with array key (multi field validation)' do
108
+ params = {key1: "10", key2: "1", key3: "0", key4: "5", key5: "3"}
109
+ spec = { rule: Focuslight::Validator::Rule.new(->(x,y,z){ x.to_i + y.to_i + z.to_i < 15 }, "too large") }
110
+
111
+ r1 = Focuslight::Validator::Result.new
112
+ Focuslight::Validator.validate_multi_key(r1, params, [:key1, :key2, :key3], spec)
113
+ expect(r1.has_error?).to be_false
114
+
115
+ r2 = Focuslight::Validator::Result.new
116
+ Focuslight::Validator.validate_multi_key(r2, params, [:key1, :key2, :key4], spec)
117
+ expect(r2.has_error?).to be_true
118
+ expect(r2.errors).to eql({:'key1,key2,key4' => "key1,key2,key4: too large"})
119
+ end
120
+ end
121
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: focuslight-validator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - TAGOMORI Satoshi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description:
56
+ email:
57
+ - tagomoris@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - focuslight-validator.gemspec
68
+ - lib/focuslight-validator.rb
69
+ - lib/focuslight/validator.rb
70
+ - lib/focuslight/validator/result.rb
71
+ - lib/focuslight/validator/rule.rb
72
+ - lib/focuslight/validator/version.rb
73
+ - spec/spec_helper.rb
74
+ - spec/syntax_spec.rb
75
+ - spec/validator_predefined_rules_spec.rb
76
+ - spec/validator_result_spec.rb
77
+ - spec/validator_rule_spec.rb
78
+ - spec/validator_spec.rb
79
+ homepage: https://github.com/focuslight/focuslight-validator
80
+ licenses:
81
+ - MIT
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project:
99
+ rubygems_version: 2.2.2
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: Validate http request parameters (or others) by defined rule, without models.
103
+ test_files:
104
+ - spec/spec_helper.rb
105
+ - spec/syntax_spec.rb
106
+ - spec/validator_predefined_rules_spec.rb
107
+ - spec/validator_result_spec.rb
108
+ - spec/validator_rule_spec.rb
109
+ - spec/validator_spec.rb