focuslight 0.1.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/.env +13 -0
- data/.gitignore +21 -0
- data/.travis.yml +9 -0
- data/CHANGELOG.md +21 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/Procfile +3 -0
- data/Procfile-gem +3 -0
- data/README.md +162 -0
- data/Rakefile +37 -0
- data/bin/focuslight +7 -0
- data/config.ru +6 -0
- data/focuslight.gemspec +41 -0
- data/lib/focuslight.rb +6 -0
- data/lib/focuslight/cli.rb +56 -0
- data/lib/focuslight/config.rb +27 -0
- data/lib/focuslight/data.rb +258 -0
- data/lib/focuslight/graph.rb +240 -0
- data/lib/focuslight/init.rb +13 -0
- data/lib/focuslight/logger.rb +89 -0
- data/lib/focuslight/rrd.rb +393 -0
- data/lib/focuslight/validator.rb +220 -0
- data/lib/focuslight/version.rb +3 -0
- data/lib/focuslight/web.rb +614 -0
- data/lib/focuslight/worker.rb +97 -0
- data/public/css/bootstrap.min.css +7 -0
- data/public/favicon.ico +0 -0
- data/public/fonts/glyphicons-halflings-regular.eot +0 -0
- data/public/fonts/glyphicons-halflings-regular.svg +229 -0
- data/public/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/public/fonts/glyphicons-halflings-regular.woff +0 -0
- data/public/js/bootstrap.min.js +7 -0
- data/public/js/jquery-1.10.2.min.js +6 -0
- data/public/js/jquery-1.10.2.min.map +0 -0
- data/public/js/jquery.storageapi.min.js +2 -0
- data/public/js/site.js +214 -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
- data/view/add_complex.erb +143 -0
- data/view/base.erb +200 -0
- data/view/docs.erb +125 -0
- data/view/edit.erb +102 -0
- data/view/edit_complex.erb +158 -0
- data/view/index.erb +19 -0
- data/view/list.erb +22 -0
- data/view/view.erb +42 -0
- data/view/view_graph.erb +16 -0
- metadata +345 -0
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
|
@@ -0,0 +1,143 @@
|
|
1
|
+
<form id="complex-form" class="hxrpost form-horizontal" method="post" action="<%= url_for '/add_complex' %>" role="form">
|
2
|
+
|
3
|
+
<fieldset>
|
4
|
+
|
5
|
+
<div class="form-group">
|
6
|
+
<label for="" class="control-label col-sm-3">Path</label>
|
7
|
+
<div class="col-sm-8">
|
8
|
+
<div class="input-group">
|
9
|
+
<span class="input-group-addon">/</span>
|
10
|
+
<input type="text" class="form-control" name="service_name" value="<%= params[:service_name] %>" />
|
11
|
+
<span class="input-group-addon">/</span>
|
12
|
+
<input type="text" class="form-control" name="section_name" value="<%= params[:section_name] %>" />
|
13
|
+
<span class="input-group-addon">/</span>
|
14
|
+
<input type="text" class="form-control" name="graph_name" value="<%= params[:graph_name] %>" />
|
15
|
+
</div>
|
16
|
+
<p class="help-block">Graph's URI(service name/section name/graph name)</p>
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
|
20
|
+
<div class="form-group">
|
21
|
+
<label for="" class="col-sm-3 control-label">Description</label>
|
22
|
+
<div class="col-sm-9">
|
23
|
+
<input type="text" class="form-control" name="description" value="<%= params[:description] %>" />
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
|
27
|
+
<div class="form-group">
|
28
|
+
<label for="" class="control-label col-sm-3">Display sum up value</label>
|
29
|
+
<div class="col-sm-4">
|
30
|
+
<select name="sumup" class="form-control">
|
31
|
+
<option value="0" <%= selected?(params[:sumup], 0) %>>disable</option>
|
32
|
+
<option value="1" <%= selected?(params[:sumup], 1) %>>enable</option>
|
33
|
+
</select>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
|
37
|
+
<div class="form-group">
|
38
|
+
<label for="" class="control-label col-sm-3">Display order</label>
|
39
|
+
<div class="col-sm-4">
|
40
|
+
<select name="sort" class="form-control">
|
41
|
+
<% (0..19).map(&:to_i).reverse.each do |i| %>
|
42
|
+
<option value="<%= i %>" <%= selected?(params[:sort], i) %>><%= i %></option>
|
43
|
+
<% end %>
|
44
|
+
</select>
|
45
|
+
<p class="help-block">19 is top</p>
|
46
|
+
</div>
|
47
|
+
</div>
|
48
|
+
|
49
|
+
</fieldset>
|
50
|
+
|
51
|
+
<fieldset>
|
52
|
+
<legend>Data</legend>
|
53
|
+
|
54
|
+
<div class="form-group">
|
55
|
+
<label for="" class="control-label col-sm-2">Series-1</label>
|
56
|
+
<div class="col-sm-10">
|
57
|
+
|
58
|
+
<table class="table table-bordered table-striped">
|
59
|
+
<tr>
|
60
|
+
<th style="width: 6%;"> </th>
|
61
|
+
<th style="width: 18%;">Type</th>
|
62
|
+
<th style="width: 62%;">Path</th>
|
63
|
+
<th style="width: 13%; text-align: center">Mode</th>
|
64
|
+
</tr>
|
65
|
+
<tr>
|
66
|
+
<td> </td>
|
67
|
+
<td><select name="type-1" class="form-control">
|
68
|
+
<option value="AREA" <%= selected?(params[:'type-1'], 'AREA') %>>AREA</option>
|
69
|
+
<option value="LINE1" <%= selected?(params[:'type-1'], 'LINE1') %>>LINE</option>
|
70
|
+
<option value="LINE2" <%= selected?(params[:'type-1'], 'LINE2') %>>LINE(Bold)</option>
|
71
|
+
</select></td>
|
72
|
+
<td><select name="path-1" class="form-control">
|
73
|
+
<% graphs.each do |row| %>
|
74
|
+
<option value="<%= row[:id] %>">/<%= row[:service_name] %>/<%= row[:section_name] %>/<%= row[:graph_name] %></option>
|
75
|
+
<% end %>
|
76
|
+
</select></td>
|
77
|
+
</tr>
|
78
|
+
</table>
|
79
|
+
</div>
|
80
|
+
</div>
|
81
|
+
|
82
|
+
<div class="form-group">
|
83
|
+
<label for="" class="control-label col-sm-2">Series-2 and more</label>
|
84
|
+
<div class="col-sm-10">
|
85
|
+
|
86
|
+
<table class="table table-bordered table-striped" id="add-data-tbl">
|
87
|
+
<tr>
|
88
|
+
<th style="width: 6%;"> </th>
|
89
|
+
<th style="width: 18%;">Type</th>
|
90
|
+
<th style="width: 39%;">Path</th>
|
91
|
+
<th style="width: 12%; text-align: center;">Mode</th>
|
92
|
+
<th style="width: 12%; text-align: center;">Stack</th>
|
93
|
+
<th style="width: 12%; text-align: center;"> </th>
|
94
|
+
</tr>
|
95
|
+
|
96
|
+
<tr>
|
97
|
+
<td> </td>
|
98
|
+
<td><select name="type-add" id="type-add" class="form-control">
|
99
|
+
<option value="AREA">AREA</option>
|
100
|
+
<option value="LINE1">LINE</option>
|
101
|
+
<option value="LINE2">LINE(Bold)</option>
|
102
|
+
</select></t>
|
103
|
+
<td><select name="path-add" id="path-add" class="form-control">
|
104
|
+
<% graphs.each do |row| %>
|
105
|
+
<option value="<%= row[:id] %>">/<%= row[:service_name] %>/<%= row[:section_name] %>/<%= row[:graph_name] %></option>
|
106
|
+
<% end %>
|
107
|
+
</select></td>
|
108
|
+
<td style="text-align:center;"><select name="stack-add" id="stack-add" class="form-control">
|
109
|
+
<option value="1">enable</option>
|
110
|
+
<option value="0">disable</option>
|
111
|
+
</select>
|
112
|
+
</td>
|
113
|
+
<td style="text-align:center;"><button id="add-new-row" class="btn btn-default" style="padding: 3px 14px 4px;">Add</button></td>
|
114
|
+
</tr>
|
115
|
+
</table>
|
116
|
+
</div>
|
117
|
+
</div>
|
118
|
+
|
119
|
+
</fieldset>
|
120
|
+
|
121
|
+
<fieldset>
|
122
|
+
<legend>Preview</legend>
|
123
|
+
|
124
|
+
<div class="form-group">
|
125
|
+
<div class="col-sm-offset-2 col-sm-10">
|
126
|
+
<div id="preview-graph"></div>
|
127
|
+
</div>
|
128
|
+
</div>
|
129
|
+
|
130
|
+
</fieldset>
|
131
|
+
|
132
|
+
<hr />
|
133
|
+
|
134
|
+
<div class="form-group">
|
135
|
+
<div class="col-sm-offset-3 col-sm-9">
|
136
|
+
<input type="submit" class="btn btn-primary" value="Add" />
|
137
|
+
</div>
|
138
|
+
</div>
|
139
|
+
|
140
|
+
</form>
|
141
|
+
<br />
|
142
|
+
<br />
|
143
|
+
|