haveapi 0.4.2 → 0.5.0
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 +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
|