valligator 1.0.1 → 1.0.2
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/HISTORY.md +4 -0
- data/README.md +20 -19
- data/VERSION +1 -1
- data/lib/valligator.rb +18 -0
- data/test/lib/valligator/errors_test.rb +1 -1
- data/test/lib/valligator/is_instance_of_test.rb +45 -31
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4c57e3ef079cd6494f2b67e9abe8b5e46336805d
|
4
|
+
data.tar.gz: a6bfdaad97a85777458cc6219b901cea77269b74
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95a39fb2d9a3b89483587da462de9c593841e2963b8ed4a36ab076182b833ef4f1e360afac7188bbef3b68ebd98a5b837792e699f30c239b6c670962195307f5
|
7
|
+
data.tar.gz: d821f39b08f9974b2fa6ec2793a7d5b53dcadee4aaf936bfb4a32e9c87641af9e8fe44452841947d9361722934e58eaa12d2b06fe5ffc8a9cb197a0e22883e64
|
data/HISTORY.md
ADDED
data/README.md
CHANGED
@@ -40,7 +40,7 @@ There are 3 validations (a.k.a. statements) that the Valligator supports:
|
|
40
40
|
|
41
41
|
The validations passes when testee responds to all (or none in negative case) the methods from the list.
|
42
42
|
|
43
|
-
#### is_instance_of
|
43
|
+
#### is_instance_of, is_a
|
44
44
|
```
|
45
45
|
testee.is_instance_of(*classes)
|
46
46
|
testee.is_not_instance_of(*classes)
|
@@ -49,7 +49,9 @@ The validations passes when testee responds to all (or none in negative case) th
|
|
49
49
|
|
50
50
|
The validations passes when testee is an instance of any class (or not an instance of all the classes in negative case).
|
51
51
|
|
52
|
-
|
52
|
+
**is_instance_of** and **is_not_instance_of** have aliases **is_a** and **is_not_a**
|
53
|
+
|
54
|
+
#### asserts, is, has
|
53
55
|
```
|
54
56
|
testee.asserts(method, *method_args, &block)
|
55
57
|
testee.asserts_not(method, *method_args, &block)
|
@@ -82,38 +84,37 @@ I use _instance_eval_ so that the _value_ could be assessed as _self_, and one w
|
|
82
84
|
Each statement, if it does not fail, returns an instance of the Valligator, so that they can be chained:
|
83
85
|
|
84
86
|
```
|
85
|
-
testee.
|
87
|
+
testee.is_a(String).is_not(:empty?).has(:size){self > 10}.speaks(:to_s)
|
86
88
|
```
|
87
89
|
|
88
90
|
## Errors
|
89
91
|
|
90
92
|
When validation fails a Valligator::ValidationError is raised. The error message contains the full path of the
|
91
|
-
passed validations. If the validation above would fail on
|
93
|
+
passed validations. If the validation above would fail on _is_a_ statement the error message wold look like:
|
92
94
|
|
93
95
|
```
|
94
|
-
Valligator::ValidationError: at testee#1.
|
96
|
+
Valligator::ValidationError: at testee#1.is_a
|
95
97
|
```
|
96
98
|
|
97
|
-
but if it would fail on _has_ then the
|
98
|
-
|
99
|
+
but if it would fail on _has_ then the error would be
|
99
100
|
|
100
101
|
```
|
101
|
-
Valligator::ValidationError: at testee#1.
|
102
|
+
Valligator::ValidationError: at testee#1.is_a.is_not.has
|
102
103
|
```
|
103
104
|
|
104
105
|
You can provide a testee name when you instantiate a Valligator instance, and the name will be used in the error message instead of 'testee#x'
|
105
106
|
|
106
107
|
```
|
107
108
|
testee = Valligator.new('Very long string', 'Short', names: ['long', 'short'])
|
108
|
-
testee.
|
109
|
-
#=> Valligator::ValidationError: at `short.
|
109
|
+
testee.is_a(String).has(:size){self > 10}
|
110
|
+
#=> Valligator::ValidationError: at `short.is_a.has'
|
110
111
|
```
|
111
112
|
|
112
113
|
## Examples
|
113
114
|
|
114
115
|
Validate that testee is an instance of String
|
115
116
|
```
|
116
|
-
Valligator.new('foo').
|
117
|
+
Valligator.new('foo').is_a(String) #=> OK
|
117
118
|
```
|
118
119
|
|
119
120
|
Validate that all testees respond to :to_s and :upcase methods
|
@@ -125,15 +126,15 @@ Valligator.new(*testees).speaks(:to_s, :upcase) #=> OK
|
|
125
126
|
Validate that all testees have size == 3 and start with 'b' and they are Strings
|
126
127
|
```
|
127
128
|
testees = ['boo', 'bar', :baz]
|
128
|
-
Valligator.new(*testees).has(:size){self == 3}.has(:[], 0){self == 'b'}.
|
129
|
-
#=> Valligator::ValidationError: at testee#3.has.has.
|
129
|
+
Valligator.new(*testees).has(:size){self == 3}.has(:[], 0){self == 'b'}.is_a(String)
|
130
|
+
#=> Valligator::ValidationError: at testee#3.has.has.is_a'
|
130
131
|
```
|
131
132
|
|
132
133
|
Validate that all hash values are Integers <= 2
|
133
134
|
```
|
134
135
|
h = { foo: 1, bar: 2, baz: 3 }
|
135
|
-
Valligator.new(*h.values, names: h.keys).
|
136
|
-
#=> Valligator::ValidationError: at `baz.
|
136
|
+
Valligator.new(*h.values, names: h.keys).is_a(Integer).asserts(:<= , 2)
|
137
|
+
#=> Valligator::ValidationError: at `baz.is_a.asserts'
|
137
138
|
```
|
138
139
|
|
139
140
|
## More examples
|
@@ -208,11 +209,11 @@ Using the Valligator we can write all above as:
|
|
208
209
|
require 'valligator'
|
209
210
|
|
210
211
|
def charge!(payee, payment_gateway, order, currency, logger)
|
211
|
-
Valligator.new(user).
|
212
|
+
Valligator.new(user).is_a(User, RemoteSystem).is_not(:blocked?).is(:confirmed?).has(:payment_method).asserts(:can_pay_in?, currency)
|
212
213
|
Valligator.new(payment_gateway).is(:active?).speaks(payee.payment_method)
|
213
214
|
Valligator.new(order).is_not(:deleted?).has(:status) { self == :pending }.does_not_have(:order_items) { empty? }
|
214
215
|
Valligator.new(*order.items).has(:currency){ self == currency }.has(:price) { self > 0 }
|
215
|
-
Valligator.new(logger).
|
216
|
+
Valligator.new(logger).is_a(IO).is_not(:closed?).has(:path) { self != 'dev/null'}
|
216
217
|
Valligator.new(currency).asserts(:==, :usd)
|
217
218
|
|
218
219
|
charge(payee, payment_gateway, order, currency, logger)
|
@@ -227,11 +228,11 @@ require 'valligator'
|
|
227
228
|
include Valligator::Helper
|
228
229
|
|
229
230
|
def charge!(payee, payment_gateway, order, logger, currency)
|
230
|
-
v(user).
|
231
|
+
v(user).is_a(User, RemoteSystem).is_not_blocked?.is_confirmed?.has_payment_method.asserts_can_pay_in?(currency)
|
231
232
|
v(payment_gateway).is_active?.speaks(payee.payment_method)
|
232
233
|
v(order).is_not_deleted?.has_status{ self == :pending }.does_not_have_order_items { empty? }
|
233
234
|
v(*order.items).has_currency{ self == :usd }.has_price { self > 0 }
|
234
|
-
v(logger).
|
235
|
+
v(logger).is_a(IO).is_not_closed?.has_path { self != 'dev/null'}
|
235
236
|
v(currency).asserts(:==, :usd)
|
236
237
|
|
237
238
|
charge(payee, payment_gateway, order, currency, logger)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.2
|
data/lib/valligator.rb
CHANGED
@@ -70,6 +70,8 @@ class Valligator
|
|
70
70
|
# Valligator.new('foo').is_instance_of(Integer, String) #=> OK
|
71
71
|
# Valligator.new('foo').is_instance_of(Integer, Array) #=> Valligator::ValidationError
|
72
72
|
#
|
73
|
+
# @see #is_a
|
74
|
+
#
|
73
75
|
def is_instance_of(*classes)
|
74
76
|
clone._is_instance_of(__method__, *classes)
|
75
77
|
end
|
@@ -85,11 +87,27 @@ class Valligator
|
|
85
87
|
# Valligator.new('foo').is_not_instance_of(Integer, String) #=> Valligator::ValidationError
|
86
88
|
# Valligator.new('foo').is_not_instance_of(Integer, Array) #=> OK
|
87
89
|
#
|
90
|
+
# @see #is_not_a
|
91
|
+
#
|
88
92
|
def is_not_instance_of(*classes)
|
89
93
|
clone._is_instance_of(__method__, *classes)
|
90
94
|
end
|
91
95
|
|
92
96
|
|
97
|
+
# Is an alias for {#is_instance_of} method
|
98
|
+
#
|
99
|
+
def is_a(*classes)
|
100
|
+
clone._is_instance_of(__method__, *classes)
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
# Is an alias for {#is_not_instance_of} method
|
105
|
+
#
|
106
|
+
def is_not_a(*classes)
|
107
|
+
clone._is_instance_of(__method__, *classes)
|
108
|
+
end
|
109
|
+
|
110
|
+
|
93
111
|
# Passes when the testee responds to all the methods
|
94
112
|
#
|
95
113
|
# @param [Array<Symbols>] methods
|
@@ -8,51 +8,65 @@ class TestIsInstanceOf < Minitest::Test
|
|
8
8
|
Valligator::ValidationError
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
positive_statements = [:is_instance_of, :is_a]
|
12
|
+
negative_statements = [:is_not_instance_of, :is_not_a]
|
13
|
+
all_statements = positive_statements + negative_statements
|
14
|
+
|
15
|
+
all_statements.each do |method|
|
16
|
+
define_method 'test_that__%s__fails_on_wrong_number_of_arguments' % method do
|
17
|
+
expected = "wrong number of arguments (0 for 1..Infinity) at `testee#1.%s'" % method
|
18
|
+
err = assert_raises(ArgumentError) { v(:a).send(method) }
|
19
|
+
assert_equal expected, err.message
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
define_method 'test_that__%s__fails_on_wrong_argument_type' % method do
|
24
|
+
expected = "wrong argument type (arg#1 is a Fixnum instead of Class) at `testee#1.%s'" % method
|
25
|
+
err = assert_raises(ArgumentError) { v(:a).send(method, 1) }
|
26
|
+
assert_equal expected, err.message
|
27
|
+
end
|
16
28
|
end
|
17
29
|
|
18
30
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
31
|
+
positive_statements.each do |method|
|
32
|
+
define_method 'test_that__%s__returns_an_instance_of_valligator' % method do
|
33
|
+
assert_instance_of Valligator, v(:a).send(method, Symbol)
|
34
|
+
end
|
24
35
|
|
25
36
|
|
26
|
-
|
27
|
-
|
28
|
-
|
37
|
+
define_method 'test_that__%s__passes_when_there_is_a_match' % method do
|
38
|
+
v(:a).send(method, Symbol)
|
39
|
+
v(:a).send(method, String, Symbol)
|
40
|
+
v(:a).send(method, Symbol).send(method, Symbol)
|
41
|
+
end
|
29
42
|
|
30
43
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
44
|
+
define_method 'test_that__%s__fails_when_there_is_no_match' % method do
|
45
|
+
assert_raises(error) { v(:a).send(method, String) }
|
46
|
+
assert_raises(error) { v(:a).send(method, String, Integer) }
|
47
|
+
assert_raises(error) { v(:a).send(method, Symbol).send(method, String) }
|
48
|
+
end
|
35
49
|
end
|
36
50
|
|
37
51
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
52
|
+
negative_statements.each do |method|
|
53
|
+
define_method 'test_that__%s__returns_an_instance_of_valligator' % method do
|
54
|
+
assert_instance_of Valligator, v(:a).send(method, String)
|
55
|
+
end
|
43
56
|
|
44
57
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
58
|
+
define_method 'test_that__%s__passes_when_there_is_no_match' % method do
|
59
|
+
v(:a).send(method, String)
|
60
|
+
v(:a).send(method, String, Integer)
|
61
|
+
v(:a).send(method, String).send(method, NilClass)
|
62
|
+
end
|
50
63
|
|
51
64
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
65
|
+
define_method 'test_that__%s__fails_when_there_is_a_match' % method do
|
66
|
+
assert_raises(error) { v(:a).send(method, Symbol) }
|
67
|
+
assert_raises(error) { v(:a).send(method, String, Symbol) }
|
68
|
+
assert_raises(error) { v(:a).send(method, String).send(method, Symbol) }
|
69
|
+
end
|
56
70
|
end
|
57
71
|
|
58
72
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: valligator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Dzreev
|
@@ -45,6 +45,7 @@ extensions: []
|
|
45
45
|
extra_rdoc_files: []
|
46
46
|
files:
|
47
47
|
- Gemfile
|
48
|
+
- HISTORY.md
|
48
49
|
- README.md
|
49
50
|
- Rakefile
|
50
51
|
- VERSION
|