haveapi 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +11 -0
- data/Rakefile +1 -0
- data/haveapi.gemspec +1 -1
- data/lib/haveapi/authentication/chain.rb +4 -0
- data/lib/haveapi/hooks.rb +68 -11
- data/lib/haveapi/model_adapters/active_record.rb +1 -1
- data/lib/haveapi/{params/param.rb → parameters/typed.rb} +4 -1
- data/lib/haveapi/params.rb +2 -2
- data/lib/haveapi/spec/api_builder.rb +75 -0
- data/lib/haveapi/spec/api_response.rb +41 -0
- data/lib/haveapi/spec/helpers.rb +5 -99
- data/lib/haveapi/spec/mock_action.rb +32 -0
- data/lib/haveapi/spec/spec_methods.rb +121 -0
- data/lib/haveapi/version.rb +1 -1
- data/lib/haveapi/views/main_layout.erb +3 -1
- data/lib/haveapi.rb +1 -1
- data/spec/action/dsl_spec.rb +199 -0
- data/spec/authorization_spec.rb +113 -0
- data/spec/common_spec.rb +47 -0
- data/spec/documentation_spec.rb +29 -0
- data/spec/envelope_spec.rb +33 -0
- data/spec/hooks_spec.rb +146 -0
- data/spec/parameters/typed_spec.rb +93 -0
- data/spec/params_spec.rb +190 -0
- data/spec/resource_spec.rb +63 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/validators/acceptance_spec.rb +29 -0
- data/spec/validators/confirmation_spec.rb +46 -0
- data/spec/validators/custom_spec.rb +6 -0
- data/spec/validators/exclusion_spec.rb +32 -0
- data/spec/validators/format_spec.rb +54 -0
- data/spec/validators/inclusion_spec.rb +43 -0
- data/spec/validators/length_spec.rb +45 -0
- data/spec/validators/numericality_spec.rb +70 -0
- data/spec/validators/presence_spec.rb +47 -0
- metadata +27 -4
- /data/lib/haveapi/{params → parameters}/resource.rb +0 -0
data/spec/params_spec.rb
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
describe HaveAPI::Params do
|
2
|
+
class MyResource < HaveAPI::Resource
|
3
|
+
params(:all) do
|
4
|
+
string :res_param1
|
5
|
+
string :res_param2
|
6
|
+
end
|
7
|
+
|
8
|
+
class Index < HaveAPI::Actions::Default::Index
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
class Show < HaveAPI::Actions::Default::Show
|
13
|
+
output do
|
14
|
+
string :not_label
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Create < HaveAPI::Actions::Default::Create
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'executes all blocks' do
|
24
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
25
|
+
p.add_block Proc.new { string :param1 }
|
26
|
+
p.add_block Proc.new { string :param2 }
|
27
|
+
p.add_block Proc.new { string :param3 }
|
28
|
+
p.exec
|
29
|
+
expect(p.params.map { |p| p.name }).to contain_exactly(*%i(param1 param2 param3))
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns deduced singular namespace' do
|
33
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
34
|
+
expect(p.namespace).to eq(:my_resource)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'returns deduced plural namespace' do
|
38
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
39
|
+
p.layout = :object_list
|
40
|
+
expect(p.namespace).to eq(:my_resources)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'returns set namespace' do
|
44
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
45
|
+
p.namespace = :custom_ns
|
46
|
+
expect(p.namespace).to eq(:custom_ns)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'uses params from parent resource' do
|
50
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
51
|
+
p.add_block Proc.new { use :all }
|
52
|
+
p.exec
|
53
|
+
expect(p.params.map { |p| p.name }).to contain_exactly(*%i(res_param1 res_param2))
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'has param requires' do
|
57
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
58
|
+
p.add_block Proc.new { requires :p_required }
|
59
|
+
p.exec
|
60
|
+
expect(p.params.first.required?).to be true
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'has param optional' do
|
64
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
65
|
+
p.add_block Proc.new { optional :p_optional }
|
66
|
+
p.exec
|
67
|
+
expect(p.params.first.required?).to be false
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'has param string' do
|
71
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
72
|
+
p.add_block Proc.new { string :p_string }
|
73
|
+
p.exec
|
74
|
+
expect(p.params.first.type).to eq(String)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'has param text' do
|
78
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
79
|
+
p.add_block Proc.new { text :p_text }
|
80
|
+
p.exec
|
81
|
+
expect(p.params.first.type).to eq(Text)
|
82
|
+
end
|
83
|
+
|
84
|
+
%i(id integer foreign_key).each do |type|
|
85
|
+
it "has param #{type}" do
|
86
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
87
|
+
p.add_block Proc.new { send(type, :"p_#{type}") }
|
88
|
+
p.exec
|
89
|
+
expect(p.params.first.type).to eq(Integer)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'has param float' do
|
94
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
95
|
+
p.add_block Proc.new { float :p_float }
|
96
|
+
p.exec
|
97
|
+
expect(p.params.first.type).to eq(Float)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'has param bool' do
|
101
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
102
|
+
p.add_block Proc.new { bool :p_bool }
|
103
|
+
p.exec
|
104
|
+
expect(p.params.first.type).to eq(Boolean)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'has param datetime' do
|
108
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
109
|
+
p.add_block Proc.new { datetime :p_datetime }
|
110
|
+
p.exec
|
111
|
+
expect(p.params.first.type).to eq(Datetime)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'has param param' do
|
115
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
116
|
+
p.add_block Proc.new { param :p_param, type: Integer }
|
117
|
+
p.exec
|
118
|
+
expect(p.params.first.type).to eq(Integer)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'has param resource' do
|
122
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
123
|
+
p.add_block Proc.new { resource MyResource }
|
124
|
+
p.exec
|
125
|
+
expect(p.params.first).to be_an_instance_of(HaveAPI::Parameters::Resource)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'patches params' do
|
129
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
130
|
+
p.add_block(Proc.new do
|
131
|
+
string :param1, label: 'Param 1'
|
132
|
+
string :param2, label: 'Param 2', desc: 'Implicit description'
|
133
|
+
end)
|
134
|
+
p.exec
|
135
|
+
p.patch(:param1, label: 'Better param 1')
|
136
|
+
p.patch(:param2, desc: 'Better description')
|
137
|
+
expect(p.params.first.label).to eq('Better param 1')
|
138
|
+
expect(p.params.second.desc).to eq('Better description')
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'validates upon build' do
|
142
|
+
p = HaveAPI::Params.new(:output, MyResource::Index)
|
143
|
+
p.add_block Proc.new { resource MyResource }
|
144
|
+
p.exec
|
145
|
+
expect(p.params.first).to be_an_instance_of(HaveAPI::Parameters::Resource)
|
146
|
+
expect { p.validate_build }.to raise_error(RuntimeError)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'accepts valid input layout' do
|
150
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
151
|
+
p.add_block(Proc.new do
|
152
|
+
string :param1, required: true
|
153
|
+
string :param2
|
154
|
+
end)
|
155
|
+
p.exec
|
156
|
+
|
157
|
+
expect do
|
158
|
+
p.check_layout({
|
159
|
+
my_resource: {}
|
160
|
+
})
|
161
|
+
end.not_to raise_error
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'rejects invalid input layout' do
|
165
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
166
|
+
p.add_block(Proc.new do
|
167
|
+
string :param1, required: true
|
168
|
+
string :param2
|
169
|
+
end)
|
170
|
+
p.exec
|
171
|
+
|
172
|
+
expect do
|
173
|
+
p.check_layout({
|
174
|
+
something_bad: {}
|
175
|
+
})
|
176
|
+
end.to raise_error(HaveAPI::ValidationError)
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'indexes parameters by name' do
|
180
|
+
p = HaveAPI::Params.new(:input, MyResource::Index)
|
181
|
+
p.add_block(Proc.new do
|
182
|
+
string :param1
|
183
|
+
string :param2
|
184
|
+
end)
|
185
|
+
p.exec
|
186
|
+
|
187
|
+
expect(p[:param1]).to eq(p.params.first)
|
188
|
+
expect(p[:param2]).to eq(p.params.second)
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
describe HaveAPI::Resource do
|
2
|
+
class PluralTest < HaveAPI::Resource
|
3
|
+
|
4
|
+
end
|
5
|
+
|
6
|
+
class SingularTest < HaveAPI::Resource
|
7
|
+
singular true
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'has correct obj_type' do
|
11
|
+
expect(PluralTest.obj_type).to eq(:resource)
|
12
|
+
expect(SingularTest.obj_type).to eq(:resource)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'has plural name' do
|
16
|
+
expect(PluralTest.resource_name).to eq('plural_tests')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'has singular name' do
|
20
|
+
expect(SingularTest.resource_name).to eq('singular_test')
|
21
|
+
end
|
22
|
+
|
23
|
+
class ComplexTest < HaveAPI::Resource
|
24
|
+
class Index < HaveAPI::Actions::Default::Index ; end
|
25
|
+
class Show < HaveAPI::Actions::Default::Show ; end
|
26
|
+
class Create < HaveAPI::Actions::Default::Create ; end
|
27
|
+
class Dummy ; end
|
28
|
+
|
29
|
+
class SubResource < HaveAPI::Resource
|
30
|
+
class Index < HaveAPI::Actions::Default::Index ; end
|
31
|
+
class Show < HaveAPI::Actions::Default::Show ; end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'iterates over actions' do
|
36
|
+
actions = []
|
37
|
+
|
38
|
+
ComplexTest.actions do |a|
|
39
|
+
actions << a
|
40
|
+
end
|
41
|
+
|
42
|
+
expect(actions).to contain_exactly(
|
43
|
+
ComplexTest::Index,
|
44
|
+
ComplexTest::Show,
|
45
|
+
ComplexTest::Create
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'iterates over resources' do
|
50
|
+
resources = []
|
51
|
+
|
52
|
+
ComplexTest.resources do |r|
|
53
|
+
resources << r
|
54
|
+
end
|
55
|
+
|
56
|
+
expect(resources).to contain_exactly(ComplexTest::SubResource)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'defines and returns resource-wide params' do
|
60
|
+
ComplexTest.params(:name) { 'executed' }
|
61
|
+
expect(ComplexTest.params(:name).call).to eq('executed')
|
62
|
+
end
|
63
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'require_all'
|
2
|
+
require_relative '../lib/haveapi'
|
3
|
+
require_rel '../lib/haveapi/spec/*.rb'
|
4
|
+
|
5
|
+
module HaveAPI
|
6
|
+
module Spec
|
7
|
+
module API
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
require_rel 'api'
|
14
|
+
|
15
|
+
# Configure specs
|
16
|
+
RSpec.configure do |config|
|
17
|
+
config.order = 'random'
|
18
|
+
|
19
|
+
config.extend HaveAPI::Spec::ApiBuilder
|
20
|
+
config.include HaveAPI::Spec::SpecMethods
|
21
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
describe HaveAPI::Validators::Acceptance do
|
2
|
+
shared_examples(:all) do
|
3
|
+
it 'accepts correct value' do
|
4
|
+
expect(@v.valid?('foo')).to be true
|
5
|
+
end
|
6
|
+
|
7
|
+
it "rejects incorrect value" do
|
8
|
+
expect(@v.valid?('bar')).to be false
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'short form' do
|
13
|
+
before(:each) do
|
14
|
+
@v = HaveAPI::Validators::Acceptance.new(:accept, 'foo')
|
15
|
+
end
|
16
|
+
|
17
|
+
include_examples :all
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'full form' do
|
21
|
+
before(:each) do
|
22
|
+
@v = HaveAPI::Validators::Acceptance.new(:accept, {
|
23
|
+
value: 'foo'
|
24
|
+
})
|
25
|
+
end
|
26
|
+
|
27
|
+
include_examples :all
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
describe HaveAPI::Validators::Confirmation do
|
2
|
+
shared_examples(:all) do
|
3
|
+
it 'accepts the same value' do
|
4
|
+
expect(@v.validate('foo', {other_param: 'foo'})).to be true
|
5
|
+
end
|
6
|
+
|
7
|
+
it "rejects a different value" do
|
8
|
+
expect(@v.validate('bar', {other_param: 'foo'})).to be false
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'short form' do
|
13
|
+
before(:each) do
|
14
|
+
@v = HaveAPI::Validators::Confirmation.new(:confirm, :other_param)
|
15
|
+
end
|
16
|
+
|
17
|
+
include_examples :all
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'full form' do
|
21
|
+
before(:each) do
|
22
|
+
@v = HaveAPI::Validators::Confirmation.new(:confirm, {
|
23
|
+
param: :other_param
|
24
|
+
})
|
25
|
+
end
|
26
|
+
|
27
|
+
include_examples :all
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'with equal = false' do
|
31
|
+
before(:each) do
|
32
|
+
@v = HaveAPI::Validators::Confirmation.new(:confirm, {
|
33
|
+
param: :other_param,
|
34
|
+
equal: false
|
35
|
+
})
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'rejects the same value' do
|
39
|
+
expect(@v.validate('foo', {other_param: 'foo'})).to be false
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'accepts a different value' do
|
43
|
+
expect(@v.validate('bar', {other_param: 'foo'})).to be true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
describe HaveAPI::Validators::Exclusion do
|
2
|
+
shared_examples(:all) do
|
3
|
+
it 'rejects a listed value' do
|
4
|
+
expect(@v.valid?('one')).to be false
|
5
|
+
expect(@v.valid?('two')).to be false
|
6
|
+
expect(@v.valid?('three')).to be false
|
7
|
+
end
|
8
|
+
|
9
|
+
it "accepts an unlisted value" do
|
10
|
+
expect(@v.valid?('zero')).to be true
|
11
|
+
expect(@v.valid?('four')).to be true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'short form' do
|
16
|
+
before(:each) do
|
17
|
+
@v = HaveAPI::Validators::Exclusion.new(:exclude, %w(one two three))
|
18
|
+
end
|
19
|
+
|
20
|
+
include_examples :all
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'full form' do
|
24
|
+
before(:each) do
|
25
|
+
@v = HaveAPI::Validators::Exclusion.new(:exclude, {
|
26
|
+
values: %w(one two three)
|
27
|
+
})
|
28
|
+
end
|
29
|
+
|
30
|
+
include_examples :all
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
describe HaveAPI::Validators::Format do
|
2
|
+
shared_examples(:all) do
|
3
|
+
it 'accepts a value that matches the regexp' do
|
4
|
+
expect(@v.valid?('aab')).to be true
|
5
|
+
expect(@v.valid?('aacacb')).to be true
|
6
|
+
end
|
7
|
+
|
8
|
+
it "rejects a value that does not match the regexp" do
|
9
|
+
expect(@v.valid?('aacac')).to be false
|
10
|
+
expect(@v.valid?('bacacb')).to be false
|
11
|
+
expect(@v.valid?('b')).to be false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'with match = true' do
|
16
|
+
context 'short form' do
|
17
|
+
before(:each) do
|
18
|
+
@v = HaveAPI::Validators::Format.new(:format, /^a[^b]+b$/)
|
19
|
+
end
|
20
|
+
|
21
|
+
include_examples :all
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'full form' do
|
25
|
+
before(:each) do
|
26
|
+
@v = HaveAPI::Validators::Format.new(:format, {
|
27
|
+
rx: /^a[^b]+b$/
|
28
|
+
})
|
29
|
+
end
|
30
|
+
|
31
|
+
include_examples :all
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'with match = false' do
|
36
|
+
before(:each) do
|
37
|
+
@v = HaveAPI::Validators::Format.new(:format, {
|
38
|
+
rx: /^a[^b]+b$/,
|
39
|
+
match: false
|
40
|
+
})
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'rejects a value that matches the regexp' do
|
44
|
+
expect(@v.valid?('aab')).to be false
|
45
|
+
expect(@v.valid?('aacacb')).to be false
|
46
|
+
end
|
47
|
+
|
48
|
+
it "accepts a value if it does not match the regexp" do
|
49
|
+
expect(@v.valid?('aacac')).to be true
|
50
|
+
expect(@v.valid?('bacacb')).to be true
|
51
|
+
expect(@v.valid?('b')).to be true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
describe HaveAPI::Validators::Inclusion do
|
2
|
+
shared_examples(:all) do
|
3
|
+
it 'accepts a listed value' do
|
4
|
+
expect(@v.valid?('one')).to be true
|
5
|
+
expect(@v.valid?('two')).to be true
|
6
|
+
expect(@v.valid?('three')).to be true
|
7
|
+
end
|
8
|
+
|
9
|
+
it "rejects an unlisted value" do
|
10
|
+
expect(@v.valid?('zero')).to be false
|
11
|
+
expect(@v.valid?('four')).to be false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
[
|
16
|
+
%w(one two three),
|
17
|
+
{
|
18
|
+
one: 'Fancy one',
|
19
|
+
two: 'Fancy two',
|
20
|
+
three: 'Fancy three'
|
21
|
+
}
|
22
|
+
].each do |include|
|
23
|
+
context "with include as a '#{include.class}'" do
|
24
|
+
context 'short form' do
|
25
|
+
before(:each) do
|
26
|
+
@v = HaveAPI::Validators::Inclusion.new(:include, %w(one two three))
|
27
|
+
end
|
28
|
+
|
29
|
+
include_examples :all
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'full form' do
|
33
|
+
before(:each) do
|
34
|
+
@v = HaveAPI::Validators::Inclusion.new(:include, {
|
35
|
+
values: %w(one two three)
|
36
|
+
})
|
37
|
+
end
|
38
|
+
|
39
|
+
include_examples :all
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
describe HaveAPI::Validators::Length do
|
2
|
+
it 'does not allow to mix min/max with equals' do
|
3
|
+
expect do
|
4
|
+
HaveAPI::Validators::Length.new(:length, {min: 33, equals: 42})
|
5
|
+
end.to raise_error(RuntimeError)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'requires one of min, max or equals' do
|
9
|
+
expect do
|
10
|
+
HaveAPI::Validators::Length.new(:length, {})
|
11
|
+
end.to raise_error(RuntimeError)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'checks minimum' do
|
15
|
+
v = HaveAPI::Validators::Length.new(:length, {min: 2})
|
16
|
+
expect(v.valid?('a'*1)).to be false
|
17
|
+
expect(v.valid?('a'*2)).to be true
|
18
|
+
expect(v.valid?('a'*33)).to be true
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'checks maximum' do
|
22
|
+
v = HaveAPI::Validators::Length.new(:length, {max: 5})
|
23
|
+
expect(v.valid?('a'*4)).to be true
|
24
|
+
expect(v.valid?('a'*5)).to be true
|
25
|
+
expect(v.valid?('a'*6)).to be false
|
26
|
+
expect(v.valid?('a'*11)).to be false
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'checks range' do
|
30
|
+
v = HaveAPI::Validators::Length.new(:length, {min: 3, max: 6})
|
31
|
+
expect(v.valid?('a'*2)).to be false
|
32
|
+
expect(v.valid?('a'*3)).to be true
|
33
|
+
expect(v.valid?('a'*4)).to be true
|
34
|
+
expect(v.valid?('a'*5)).to be true
|
35
|
+
expect(v.valid?('a'*6)).to be true
|
36
|
+
expect(v.valid?('a'*7)).to be false
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'check a specific length' do
|
40
|
+
v = HaveAPI::Validators::Length.new(:length, {equals: 4})
|
41
|
+
expect(v.valid?('a'*2)).to be false
|
42
|
+
expect(v.valid?('a'*4)).to be true
|
43
|
+
expect(v.valid?('a'*5)).to be false
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
describe HaveAPI::Validators::Numericality do
|
2
|
+
it 'cannot be both even and odd at the same time' do
|
3
|
+
expect do
|
4
|
+
HaveAPI::Validators::Numericality.new(:number, {odd: true, even: true})
|
5
|
+
end.to raise_error(RuntimeError)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'checks minimum' do
|
9
|
+
v = HaveAPI::Validators::Numericality.new(:number, {min: 5})
|
10
|
+
expect(v.valid?(4)).to be false
|
11
|
+
expect(v.valid?(5)).to be true
|
12
|
+
expect(v.valid?(6)).to be true
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'checks maximum' do
|
16
|
+
v = HaveAPI::Validators::Numericality.new(:number, {max: 50})
|
17
|
+
expect(v.valid?(100)).to be false
|
18
|
+
expect(v.valid?(51)).to be false
|
19
|
+
expect(v.valid?(50)).to be true
|
20
|
+
expect(v.valid?(40)).to be true
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'checks that x % y = 0' do
|
24
|
+
v = HaveAPI::Validators::Numericality.new(:number, {mod: 2})
|
25
|
+
expect(v.valid?(3)).to be false
|
26
|
+
expect(v.valid?(15)).to be false
|
27
|
+
expect(v.valid?(0)).to be true
|
28
|
+
expect(v.valid?(2)).to be true
|
29
|
+
expect(v.valid?(48)).to be true
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'checks that the number is in a step' do
|
33
|
+
v = HaveAPI::Validators::Numericality.new(:number, {step: 3})
|
34
|
+
expect(v.valid?(4)).to be false
|
35
|
+
expect(v.valid?(14)).to be false
|
36
|
+
expect(v.valid?(0)).to be true
|
37
|
+
expect(v.valid?(3)).to be true
|
38
|
+
expect(v.valid?(6)).to be true
|
39
|
+
expect(v.valid?(9)).to be true
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'checks that the number is in a step with a minimum' do
|
43
|
+
v = HaveAPI::Validators::Numericality.new(:number, {min: 5, step: 3})
|
44
|
+
expect(v.valid?(0)).to be false
|
45
|
+
expect(v.valid?(3)).to be false
|
46
|
+
expect(v.valid?(4)).to be false
|
47
|
+
expect(v.valid?(12)).to be false
|
48
|
+
expect(v.valid?(15)).to be false
|
49
|
+
expect(v.valid?(5)).to be true
|
50
|
+
expect(v.valid?(8)).to be true
|
51
|
+
expect(v.valid?(11)).to be true
|
52
|
+
expect(v.valid?(14)).to be true
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'checks that the number is even' do
|
56
|
+
v = HaveAPI::Validators::Numericality.new(:number, {even: true})
|
57
|
+
expect(v.valid?(1)).to be false
|
58
|
+
expect(v.valid?(3)).to be false
|
59
|
+
expect(v.valid?(0)).to be true
|
60
|
+
expect(v.valid?(2)).to be true
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'checks that the number is odd' do
|
64
|
+
v = HaveAPI::Validators::Numericality.new(:number, {odd: true})
|
65
|
+
expect(v.valid?(1)).to be true
|
66
|
+
expect(v.valid?(3)).to be true
|
67
|
+
expect(v.valid?(0)).to be false
|
68
|
+
expect(v.valid?(2)).to be false
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
describe HaveAPI::Validators::Presence do
|
2
|
+
shared_examples(:all) do
|
3
|
+
it 'accepts a present value' do
|
4
|
+
expect(@v.valid?('foo')).to be true
|
5
|
+
end
|
6
|
+
|
7
|
+
it 'rejects a missing or empty value' do
|
8
|
+
expect(@v.valid?(nil)).to be false
|
9
|
+
expect(@v.valid?('')).to be false
|
10
|
+
expect(@v.valid?(" \t"*4)).to be false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'with empty = true' do
|
15
|
+
context 'in short form' do
|
16
|
+
before(:each) do
|
17
|
+
@v = HaveAPI::Validators::Presence.new(:required, true)
|
18
|
+
end
|
19
|
+
|
20
|
+
include_examples :all
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'in full form' do
|
24
|
+
before(:each) do
|
25
|
+
@v = HaveAPI::Validators::Presence.new(:required, {})
|
26
|
+
end
|
27
|
+
|
28
|
+
include_examples :all
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with empty = false' do
|
33
|
+
before(:each) do
|
34
|
+
@v = HaveAPI::Validators::Presence.new(:required, {empty: true})
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'accepts a present value' do
|
38
|
+
expect(@v.valid?('foo')).to be true
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'rejects a missing or an empty value' do
|
42
|
+
expect(@v.valid?(nil)).to be false
|
43
|
+
expect(@v.valid?('')).to be true
|
44
|
+
expect(@v.valid?(" \t"*4)).to be true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|