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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +73 -0
- data/Rakefile +1 -0
- data/focuslight-validator.gemspec +24 -0
- data/lib/focuslight-validator.rb +1 -0
- data/lib/focuslight/validator.rb +149 -0
- data/lib/focuslight/validator/result.rb +32 -0
- data/lib/focuslight/validator/rule.rb +27 -0
- data/lib/focuslight/validator/version.rb +5 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/syntax_spec.rb +9 -0
- data/spec/validator_predefined_rules_spec.rb +177 -0
- data/spec/validator_result_spec.rb +27 -0
- data/spec/validator_rule_spec.rb +68 -0
- data/spec/validator_spec.rb +121 -0
- metadata +109 -0
checksums.yaml
ADDED
@@ -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
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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
|
data/Rakefile
ADDED
@@ -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
|
data/spec/spec_helper.rb
ADDED
data/spec/syntax_spec.rb
ADDED
@@ -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
|