valligator 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -2
- data/HISTORY.md +10 -2
- data/README.md +39 -29
- data/Rakefile +3 -1
- data/VERSION +1 -1
- data/lib/valligator.rb +81 -45
- data/lib/valligator_helper.rb +15 -1
- data/test/lib/valligator/errors_test.rb +82 -16
- data/test/lib/valligator/is_instance_of_test.rb +4 -4
- data/test/lib/valligator/speaks_test.rb +2 -2
- metadata +6 -6
- data/lib/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86beebd4198e35c0e7accf7e5ae49e8e100793f7
|
4
|
+
data.tar.gz: 3d1cf322859147e0c6e238cdc74b7d3a3a32f482
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46e30c31a694e91f20d1488b32b619b08cd0e2aad583f7a6c20cf97d77d245c5f7299f60eccfb972e3ead9a0bdff20377949eae2c15b181de7e998b017b39799
|
7
|
+
data.tar.gz: 8a794b107f51b596f1bb3de90c280e3d1170db81ee9188b54a434f004fac43744028cc0ffcb46cb3d6718dd2d0388acb6570baa687d3932ec51443c19da74338
|
data/Gemfile
CHANGED
data/HISTORY.md
CHANGED
@@ -1,4 +1,12 @@
|
|
1
|
-
#### 1.0.
|
1
|
+
#### 1.0.3
|
2
|
+
- **is_instance_of** renamed to **is_kind_of**
|
3
|
+
- **is_not_instance_of** renamed to **is_not_kind_of**
|
4
|
+
- new helper method: Valligator::Helper#vh(Hash)
|
2
5
|
|
6
|
+
#### 1.0.2
|
3
7
|
- **is_instance_of** got alias **is_a**
|
4
|
-
- **is_not_instance_of** got alias **is_not_a**
|
8
|
+
- **is_not_instance_of** got alias **is_not_a**
|
9
|
+
|
10
|
+
#### 1.0.3
|
11
|
+
- **is_instance_of** renamed to **is_kind_of**
|
12
|
+
- **is_not_instance_of** renamed to **is_not_kind_of**
|
data/README.md
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
# Valligator
|
2
|
-
|
1
|
+
# Valligator [![Build Status](https://travis-ci.org/konstantin-dzreev/valligator.svg?branch=master)](https://travis-ci.org/konstantin-dzreev/valligator) [![Gem Version](https://badge.fury.io/rb/valligator.svg)](https://rubygems.org/gems/valligator)
|
3
2
|
|
4
3
|
## Ruby objects validator
|
5
4
|
|
@@ -28,35 +27,48 @@ gem install valligator
|
|
28
27
|
|
29
28
|
## Statements
|
30
29
|
|
31
|
-
There are 3 validations (a.k.a. statements) that the Valligator supports:
|
30
|
+
There are 3 positive and 3 negative validations (a.k.a. statements) that the Valligator supports:
|
31
|
+
|
32
32
|
|
33
|
-
#### speaks
|
33
|
+
#### speaks, does_not_speak
|
34
34
|
|
35
35
|
```
|
36
36
|
testee.speaks(*methods)
|
37
37
|
testee.does_not_speak(*methods)
|
38
|
+
|
39
|
+
# a method to be tested can be included into the validation name:
|
40
|
+
testee.speaks_<method>
|
41
|
+
testee.does_not_speak_<method>
|
38
42
|
```
|
39
|
-
- _methods_
|
43
|
+
- _methods_ is a list of symbols
|
40
44
|
|
41
45
|
The validations passes when testee responds to all (or none in negative case) the methods from the list.
|
42
46
|
|
43
|
-
|
47
|
+
|
48
|
+
#### is_kind_of, is_not_kind_of
|
49
|
+
Aliases: **is_a** and **is_not_a**.
|
50
|
+
|
44
51
|
```
|
45
|
-
testee.
|
46
|
-
testee.
|
52
|
+
testee.is_kind_of(*classes)
|
53
|
+
testee.is_not_kind_of(*classes)
|
47
54
|
```
|
48
|
-
- _classes_ a list of ruby classes
|
55
|
+
- _classes_ is a list of ruby classes
|
49
56
|
|
50
57
|
The validations passes when testee is an instance of any class (or not an instance of all the classes in negative case).
|
51
58
|
|
52
|
-
**is_instance_of** and **is_not_instance_of** have aliases **is_a** and **is_not_a**
|
53
59
|
|
54
|
-
#### asserts,
|
60
|
+
#### asserts, asserts_not
|
61
|
+
Aliases: **is**, **has** and **is_not**, **does_not_have**. All of them are absolutely identical, you can use what ever sounds more grammatically correct: _is(:active?)_, _has(:apples)_, _asserts(:respond_to?, :foo)_, etc.
|
62
|
+
|
55
63
|
```
|
56
64
|
testee.asserts(method, *method_args, &block)
|
57
65
|
testee.asserts_not(method, *method_args, &block)
|
66
|
+
|
67
|
+
# a method to be tested can be included into the validation name:
|
68
|
+
testee.asserts_<method>(*method_args, &block)
|
69
|
+
testee.asserts_not_<method>(*method_args, &block)
|
58
70
|
```
|
59
|
-
- _method_ a method to be
|
71
|
+
- _method_ a method to be called on testee
|
60
72
|
- _method_args_ (optional) the method arguments
|
61
73
|
- _block_ (optional) a block to be invoked in the context of the _method_ response
|
62
74
|
|
@@ -75,9 +87,8 @@ If it does not sound clear, then it is something like this:
|
|
75
87
|
raise !!value.instance_eval { self == 10 }
|
76
88
|
```
|
77
89
|
|
78
|
-
I use _instance_eval_ so that the _value_ could be assessed as _self_, and one would not need to access it using standard block params definition
|
90
|
+
I use _instance_eval_ so that the _value_ could be assessed as _self_, and one would not need to access it using standard block params definition: {|value| value == 10 }.
|
79
91
|
|
80
|
-
**asserts** has two aliases: **is** and **has**. The negative form **asserts_not** also has its own clones: **is_not**, **does_not_have**. All the methods are absolutely identical, just use what ever sounds more grammatically correct: _is(:active?)_, _has(:apples)_, _asserts(:respond_to?, :foo)_, etc.
|
81
92
|
|
82
93
|
## Method chaining
|
83
94
|
|
@@ -89,25 +100,19 @@ Each statement, if it does not fail, returns an instance of the Valligator, so t
|
|
89
100
|
|
90
101
|
## Errors
|
91
102
|
|
92
|
-
When validation fails a Valligator::ValidationError is raised.
|
93
|
-
passed validations. If the validation above would fail on _is_a_ statement the error message wold look like:
|
103
|
+
When validation fails a Valligator::ValidationError is raised.
|
94
104
|
|
95
105
|
```
|
96
|
-
Valligator
|
97
|
-
|
98
|
-
|
99
|
-
but if it would fail on _has_ then the error would be
|
100
|
-
|
101
|
-
```
|
102
|
-
Valligator::ValidationError: at testee#1.is_a.is_not.has
|
106
|
+
Valligator.new(:foo).is_empty? #=>
|
107
|
+
Valligator::ValidationError: `testee#1': method `empty?' returned falsy value
|
103
108
|
```
|
104
109
|
|
105
110
|
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'
|
106
111
|
|
107
112
|
```
|
108
113
|
testee = Valligator.new('Very long string', 'Short', names: ['long', 'short'])
|
109
|
-
testee.is_a(String).has(:size){self > 10}
|
110
|
-
|
114
|
+
testee.is_a(String).has(:size){self > 10} #=>
|
115
|
+
Valligator::ValidationError: `short': method `size' returned falsy value
|
111
116
|
```
|
112
117
|
|
113
118
|
## Examples
|
@@ -126,15 +131,15 @@ Valligator.new(*testees).speaks(:to_s, :upcase) #=> OK
|
|
126
131
|
Validate that all testees have size == 3 and start with 'b' and they are Strings
|
127
132
|
```
|
128
133
|
testees = ['boo', 'bar', :baz]
|
129
|
-
Valligator.new(*testees).has(:size){self == 3}.has(:[], 0){self == 'b'}.is_a(String)
|
130
|
-
|
134
|
+
Valligator.new(*testees).has(:size){self == 3}.has(:[], 0){self == 'b'}.is_a(String) #=>
|
135
|
+
Valligator::ValidationError: `testee#3': should be Symbol
|
131
136
|
```
|
132
137
|
|
133
138
|
Validate that all hash values are Integers <= 2
|
134
139
|
```
|
135
140
|
h = { foo: 1, bar: 2, baz: 3 }
|
136
|
-
Valligator.new(*h.values, names: h.keys).is_a(Integer).asserts(:<= , 2)
|
137
|
-
|
141
|
+
Valligator.new(*h.values, names: h.keys).is_a(Integer).asserts(:<= , 2) #=>
|
142
|
+
Valligator::ValidationError: `baz': method `<=' returned falsy value
|
138
143
|
```
|
139
144
|
|
140
145
|
## More examples
|
@@ -245,6 +250,11 @@ end
|
|
245
250
|
rake test
|
246
251
|
```
|
247
252
|
|
253
|
+
## API contract
|
254
|
+
|
255
|
+
Until version 1.1.0 API contract is a subject to change
|
256
|
+
|
257
|
+
|
248
258
|
## License
|
249
259
|
|
250
260
|
[MIT](https://opensource.org/licenses/mit-license.php) <br/>
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.3
|
data/lib/valligator.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
+
require 'pathname'
|
1
2
|
require_relative 'valligator_helper'
|
2
3
|
|
3
4
|
class Valligator
|
4
|
-
|
5
|
+
VERSION = File.read(Pathname(__FILE__).dirname.join('../VERSION')).strip
|
6
|
+
|
7
|
+
Error = Class.new(StandardError)
|
5
8
|
ValidationError = Class.new(Error)
|
6
9
|
|
7
10
|
INFINITY = 1/0.0
|
@@ -19,7 +22,7 @@ class Valligator
|
|
19
22
|
#
|
20
23
|
# @example
|
21
24
|
# # validate that testee is an instance of String
|
22
|
-
# Valligator.new('foo').
|
25
|
+
# Valligator.new('foo').is_kind_of(String) #=> OK
|
23
26
|
#
|
24
27
|
# @example
|
25
28
|
# # validate that all testees respond to :to_s and :upcase methods
|
@@ -28,14 +31,14 @@ class Valligator
|
|
28
31
|
# @example
|
29
32
|
# # validate that all testees have size == 3 and start with 'b' and they are Strings
|
30
33
|
# testees = ['boo', 'bar', :baz]
|
31
|
-
# Valligator.new(*testees).has(:size){self == 3}.has(:[], 0){self == 'b'}.
|
32
|
-
# #=> Valligator::ValidationError: at `testee#3.has.has.
|
34
|
+
# Valligator.new(*testees).has(:size){self == 3}.has(:[], 0){self == 'b'}.is_kind_of(String)
|
35
|
+
# #=> Valligator::ValidationError: at `testee#3.has.has.is_kind_of'
|
33
36
|
#
|
34
37
|
# @example
|
35
38
|
# # validate that all hash values are Integers <= 2
|
36
39
|
# h = { foo: 1, bar: 2, baz: 3 }
|
37
|
-
# Valligator.new(*h.values, names: h.keys).
|
38
|
-
# #=> Valligator::ValidationError: at `baz.
|
40
|
+
# Valligator.new(*h.values, names: h.keys).is_kind_of(Integer).asserts(:<= , 2)
|
41
|
+
# #=> Valligator::ValidationError: at `baz.is_kind_of.asserts'
|
39
42
|
#
|
40
43
|
def initialize(*testees, names: nil)
|
41
44
|
@testees = testees
|
@@ -67,13 +70,13 @@ class Valligator
|
|
67
70
|
# @raise [Valligator::ValidationError]
|
68
71
|
#
|
69
72
|
# @example
|
70
|
-
# Valligator.new('foo').
|
71
|
-
# Valligator.new('foo').
|
73
|
+
# Valligator.new('foo').is_kind_of(Integer, String) #=> OK
|
74
|
+
# Valligator.new('foo').is_kind_of(Integer, Array) #=> Valligator::ValidationError
|
72
75
|
#
|
73
76
|
# @see #is_a
|
74
77
|
#
|
75
|
-
def
|
76
|
-
clone.
|
78
|
+
def is_kind_of(*classes)
|
79
|
+
clone._is_kind_of(__method__, *classes)
|
77
80
|
end
|
78
81
|
|
79
82
|
|
@@ -84,27 +87,27 @@ class Valligator
|
|
84
87
|
# @raise [Valligator::ValidationError]
|
85
88
|
#
|
86
89
|
# @example
|
87
|
-
# Valligator.new('foo').
|
88
|
-
# Valligator.new('foo').
|
90
|
+
# Valligator.new('foo').is_not_kind_of(Integer, String) #=> Valligator::ValidationError
|
91
|
+
# Valligator.new('foo').is_not_kind_of(Integer, Array) #=> OK
|
89
92
|
#
|
90
93
|
# @see #is_not_a
|
91
94
|
#
|
92
|
-
def
|
93
|
-
clone.
|
95
|
+
def is_not_kind_of(*classes)
|
96
|
+
clone._is_kind_of(__method__, *classes)
|
94
97
|
end
|
95
98
|
|
96
99
|
|
97
|
-
# Is an alias for {#
|
100
|
+
# Is an alias for {#is_kind_of} method
|
98
101
|
#
|
99
102
|
def is_a(*classes)
|
100
|
-
clone.
|
103
|
+
clone._is_kind_of(__method__, *classes)
|
101
104
|
end
|
102
105
|
|
103
106
|
|
104
|
-
# Is an alias for {#
|
107
|
+
# Is an alias for {#is_not_kind_of} method
|
105
108
|
#
|
106
109
|
def is_not_a(*classes)
|
107
|
-
clone.
|
110
|
+
clone._is_kind_of(__method__, *classes)
|
108
111
|
end
|
109
112
|
|
110
113
|
|
@@ -247,18 +250,6 @@ class Valligator
|
|
247
250
|
end
|
248
251
|
|
249
252
|
|
250
|
-
# Raises requested exception
|
251
|
-
#
|
252
|
-
# @param [Class] exception
|
253
|
-
# @param option [Integer] idx Testee index
|
254
|
-
# @param option [nil,String] msg Error explanation (when required)
|
255
|
-
#
|
256
|
-
def error(exception, idx=0, msg=nil)
|
257
|
-
msg += ' ' if msg
|
258
|
-
raise(exception, "%sat `%s.%s'" % [msg, name_by_idx(idx), @stack.join('.')])
|
259
|
-
end
|
260
|
-
|
261
|
-
|
262
253
|
# Calls the given block for each testee and each item from the list.
|
263
254
|
#
|
264
255
|
# @param optional list [Array]
|
@@ -292,10 +283,21 @@ class Valligator
|
|
292
283
|
|
293
284
|
|
294
285
|
#------------------------------------------
|
295
|
-
# Validations
|
286
|
+
# Validations and Errors
|
296
287
|
#------------------------------------------
|
297
288
|
|
298
289
|
|
290
|
+
# Raises ArgumentError exception
|
291
|
+
#
|
292
|
+
# @param [Class] exception
|
293
|
+
# @param [Integer] idx Testee index
|
294
|
+
# @param [nil,String] msg Error explanation (when required)
|
295
|
+
#
|
296
|
+
def argument_error(exception, idx, msg)
|
297
|
+
raise(exception, "%s at `%s.%s'" % [msg, name_by_idx(idx), @stack.join('.')])
|
298
|
+
end
|
299
|
+
|
300
|
+
|
299
301
|
# Validates number of arguments
|
300
302
|
#
|
301
303
|
# @param [Array<Object>] args
|
@@ -307,7 +309,7 @@ class Valligator
|
|
307
309
|
return if expected === args.size
|
308
310
|
|
309
311
|
expected == expected.first if expected.is_a?(Range) && expected.size == 1
|
310
|
-
|
312
|
+
argument_error(ArgumentError, 0, 'wrong number of arguments (%s for %s)' % [args.size, expected])
|
311
313
|
end
|
312
314
|
|
313
315
|
|
@@ -322,7 +324,7 @@ class Valligator
|
|
322
324
|
def validate_argument_type(classes, arg, arg_idx)
|
323
325
|
return if classes.any? { |klass| arg.is_a?(klass) }
|
324
326
|
classes = classes.map { |klass| klass.inspect }.join(' or ')
|
325
|
-
|
327
|
+
argument_error(ArgumentError, 0, 'wrong argument type (arg#%d is a %s instead of %s)' % [arg_idx, arg.class.name, classes])
|
326
328
|
end
|
327
329
|
|
328
330
|
|
@@ -338,19 +340,53 @@ class Valligator
|
|
338
340
|
return if object.respond_to?(method)
|
339
341
|
str = object.to_s
|
340
342
|
str = str[0..-1] + '...' if str.size > 20
|
341
|
-
|
343
|
+
argument_error(NoMethodError, idx, 'undefined method `%s\' for %s:%s' % [method, str, object.class.name])
|
344
|
+
end
|
345
|
+
|
346
|
+
|
347
|
+
# Raises ValidationError exception
|
348
|
+
#
|
349
|
+
# @param [Class] exception
|
350
|
+
# @param option [Integer] idx Testee index
|
351
|
+
# @param option [nil,String] msg Error explanation (when required)
|
352
|
+
#
|
353
|
+
def validation_error(idx, msg)
|
354
|
+
raise(ValidationError, "`%s': %s" % [name_by_idx(idx), msg])
|
355
|
+
end
|
356
|
+
|
357
|
+
|
358
|
+
def raise_is_kind_of_validation_error(equality, idx, classes)
|
359
|
+
validation_error(idx, "should not be %s" % [@testees[idx].class.name])
|
360
|
+
end
|
361
|
+
|
362
|
+
|
363
|
+
def raise_speaks_validation_error(equality, idx, method)
|
364
|
+
verb = equality ? "should" : "should not"
|
365
|
+
validation_error(idx, "%s respond to method `%s'" % [verb, method])
|
342
366
|
end
|
343
367
|
|
344
368
|
|
369
|
+
def raise_asserts_validation_error(equality, idx, method, args, block, error)
|
370
|
+
msg = "method `%s' " % method
|
371
|
+
if error
|
372
|
+
msg += 'failed: %s: %s' % [error.class.name, error.message]
|
373
|
+
else
|
374
|
+
msg += 'returned %s value' % (equality ? 'falsy' : 'truthy')
|
375
|
+
end
|
376
|
+
validation_error(idx, msg)
|
377
|
+
end
|
378
|
+
|
379
|
+
|
380
|
+
|
345
381
|
#------------------------------------------
|
346
382
|
# Statements
|
347
383
|
#------------------------------------------
|
348
384
|
|
349
385
|
|
350
386
|
# @private
|
351
|
-
# @see #
|
387
|
+
# @see #is_kind_of
|
352
388
|
#
|
353
|
-
def
|
389
|
+
def _is_kind_of(statement, *classes)
|
354
390
|
push(statement)
|
355
391
|
equality = !statement[/not/]
|
356
392
|
|
@@ -360,7 +396,10 @@ class Valligator
|
|
360
396
|
classes.each_with_index { |klass, idx| validate_argument_type([Class], klass, idx+1) }
|
361
397
|
|
362
398
|
each(*classes) { |testee, idx, klass| matches[idx] = true if testee.is_a?(klass) }
|
363
|
-
matches.each_with_index
|
399
|
+
matches.each_with_index do |match, idx|
|
400
|
+
next if matches[idx] == equality
|
401
|
+
raise_is_kind_of_validation_error(equality, idx, classes)
|
402
|
+
end
|
364
403
|
self
|
365
404
|
end
|
366
405
|
|
@@ -380,8 +419,7 @@ class Valligator
|
|
380
419
|
|
381
420
|
each(*methods) do |testee, idx, method|
|
382
421
|
next if testee.respond_to?(method) == equality
|
383
|
-
|
384
|
-
error(ValidationError, idx)
|
422
|
+
raise_speaks_validation_error(equality, idx, method)
|
385
423
|
end
|
386
424
|
self
|
387
425
|
end
|
@@ -396,15 +434,13 @@ class Valligator
|
|
396
434
|
|
397
435
|
each do |testee, idx|
|
398
436
|
validate_respond_to(testee, method, idx)
|
399
|
-
response = testee.__send__(method, *args)
|
400
437
|
begin
|
401
|
-
|
438
|
+
response = testee.__send__(method, *args)
|
402
439
|
response = response.instance_eval(&block) if block
|
403
|
-
rescue
|
404
|
-
|
405
|
-
error(ValidationError, idx)
|
440
|
+
rescue => e
|
441
|
+
response = !equality
|
406
442
|
end
|
407
|
-
|
443
|
+
raise_asserts_validation_error(equality, idx, method, args, block, e) if !!response != equality
|
408
444
|
end
|
409
445
|
self
|
410
446
|
end
|
data/lib/valligator_helper.rb
CHANGED
@@ -1,12 +1,26 @@
|
|
1
1
|
class Valligator
|
2
2
|
module Helper
|
3
3
|
|
4
|
+
# Returns a new Valligator instance
|
5
|
+
#
|
6
|
+
# @param [Array<Object>] testees One or more objects to be tested
|
7
|
+
# @param option [Array<String>] :names Testee names
|
8
|
+
# @return [Valligator]
|
9
|
+
#
|
4
10
|
def valligate(*testees, names: nil)
|
5
11
|
Valligator.new(*testees, names: names)
|
6
12
|
end
|
13
|
+
alias_method :v, :valligate
|
7
14
|
|
8
15
|
|
9
|
-
|
16
|
+
# Returns a new Valligator instance created from a hash, where hash values are testees and hash keys are their names.
|
17
|
+
#
|
18
|
+
# @param [Hash] hash
|
19
|
+
# @return [Valligator]
|
20
|
+
#
|
21
|
+
def vh(hash)
|
22
|
+
Valligator.new(*hash.values, names: hash.keys)
|
23
|
+
end
|
10
24
|
|
11
25
|
end
|
12
26
|
end
|
@@ -10,30 +10,96 @@ class TestErrors < Minitest::Test
|
|
10
10
|
end
|
11
11
|
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
#-------------------------------------
|
14
|
+
# is_kind_of
|
15
|
+
#-------------------------------------
|
16
|
+
|
17
|
+
|
18
|
+
def test__is_kind_of__error__single
|
19
|
+
expected = "`testee#1': should not be Symbol"
|
20
|
+
err = assert_raises(error) { v(:foo).is_kind_of(String) }
|
21
|
+
assert_equal expected, err.message
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
def test__is_kind_of__error__multiple
|
26
|
+
expected = "`testee#1': should not be Symbol"
|
27
|
+
err = assert_raises(error) { v(:foo).is_kind_of(String, Hash, Array) }
|
28
|
+
assert_equal expected, err.message
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def test__is_not_kind_of__error__single
|
33
|
+
expected = "`testee#1': should not be Symbol"
|
34
|
+
err = assert_raises(error) { v(:foo).is_not_kind_of(Symbol) }
|
16
35
|
assert_equal expected, err.message
|
17
36
|
end
|
18
37
|
|
19
38
|
|
20
|
-
def
|
21
|
-
expected = "
|
22
|
-
err = assert_raises(error) { v(:foo,
|
39
|
+
def test__is_not_kind_of__error__multiple
|
40
|
+
expected = "`testee#1': should not be Symbol"
|
41
|
+
err = assert_raises(error) { v(:foo).is_not_kind_of(Symbol, Hash, Array) }
|
23
42
|
assert_equal expected, err.message
|
24
43
|
end
|
25
44
|
|
26
45
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
46
|
+
#-------------------------------------
|
47
|
+
# speaks
|
48
|
+
#-------------------------------------
|
49
|
+
|
50
|
+
|
51
|
+
def test__speaks__error
|
52
|
+
expected = "`testee#1': should respond to method `bar'"
|
53
|
+
err = assert_raises(error) { v(:foo).speaks(:bar) }
|
54
|
+
assert_equal expected, err.message
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
def test__does_not_speak__error
|
59
|
+
expected = "`testee#1': should not respond to method `to_s'"
|
60
|
+
err = assert_raises(error) { v(:foo).does_not_speak(:to_s) }
|
61
|
+
assert_equal expected, err.message
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
#-------------------------------------
|
66
|
+
# asserts
|
67
|
+
#-------------------------------------
|
68
|
+
|
69
|
+
|
70
|
+
def test__asserts__error__without_block
|
71
|
+
expected = "`testee#1': method `empty?' returned falsy value"
|
72
|
+
err = assert_raises(error) { v(:foo).asserts(:empty?) }
|
73
|
+
assert_equal expected, err.message
|
74
|
+
end
|
75
|
+
|
76
|
+
def test__asserts__error__with_block
|
77
|
+
expected = "`testee#1': method `size' returned falsy value"
|
78
|
+
err = assert_raises(error) { v(:foo).asserts(:size) { false } }
|
79
|
+
assert_equal expected, err.message
|
80
|
+
end
|
81
|
+
|
82
|
+
def test__asserts__error__with_block_and_exception
|
83
|
+
expected = "`testee#1': method `size' failed: ZeroDivisionError: divided by 0"
|
84
|
+
err = assert_raises(error) { v(:foo).asserts(:size) { 1/0 } }
|
85
|
+
assert_equal expected, err.message
|
86
|
+
end
|
87
|
+
|
88
|
+
def test__asserts_not__error__without_block
|
89
|
+
expected = "`testee#1': method `size' returned truthy value"
|
90
|
+
err = assert_raises(error) { v(:foo).asserts_not(:size) }
|
91
|
+
assert_equal expected, err.message
|
92
|
+
end
|
93
|
+
|
94
|
+
def test__asserts_not__error__with_block
|
95
|
+
expected = "`testee#1': method `empty?' returned truthy value"
|
96
|
+
err = assert_raises(error) { v(:foo).asserts_not(:empty?) { true } }
|
97
|
+
assert_equal expected, err.message
|
98
|
+
end
|
99
|
+
|
100
|
+
def test__assertsnot__error__with_block_and_exception
|
101
|
+
expected = "`testee#1': method `empty?' failed: ZeroDivisionError: divided by 0"
|
102
|
+
err = assert_raises(error) { v(:foo).asserts_not(:empty?) { 1/0 } }
|
37
103
|
assert_equal expected, err.message
|
38
104
|
end
|
39
105
|
|
@@ -8,8 +8,8 @@ class TestIsInstanceOf < Minitest::Test
|
|
8
8
|
Valligator::ValidationError
|
9
9
|
end
|
10
10
|
|
11
|
-
positive_statements = [:
|
12
|
-
negative_statements = [:
|
11
|
+
positive_statements = [:is_kind_of, :is_a]
|
12
|
+
negative_statements = [:is_not_kind_of, :is_not_a]
|
13
13
|
all_statements = positive_statements + negative_statements
|
14
14
|
|
15
15
|
all_statements.each do |method|
|
@@ -21,8 +21,8 @@ class TestIsInstanceOf < Minitest::Test
|
|
21
21
|
|
22
22
|
|
23
23
|
define_method 'test_that__%s__fails_on_wrong_argument_type' % method do
|
24
|
-
expected = "wrong argument type (arg#1 is a
|
25
|
-
err = assert_raises(ArgumentError) { v(:a).send(method,
|
24
|
+
expected = "wrong argument type (arg#1 is a NilClass instead of Class) at `testee#1.%s'" % method
|
25
|
+
err = assert_raises(ArgumentError) { v(:a).send(method, nil) }
|
26
26
|
assert_equal expected, err.message
|
27
27
|
end
|
28
28
|
end
|
@@ -17,8 +17,8 @@ class TestSpeaks < Minitest::Test
|
|
17
17
|
|
18
18
|
|
19
19
|
def test_that__speaks__fails_on_wrong_argument_type
|
20
|
-
expected = "wrong argument type (arg#1 is a
|
21
|
-
err = assert_raises(ArgumentError) { v(:a).speaks(
|
20
|
+
expected = "wrong argument type (arg#1 is a NilClass instead of Symbol) at `testee#1.speaks'"
|
21
|
+
err = assert_raises(ArgumentError) { v(:a).speaks(nil) }
|
22
22
|
assert_equal expected, err.message
|
23
23
|
end
|
24
24
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Dzreev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -51,7 +51,6 @@ files:
|
|
51
51
|
- VERSION
|
52
52
|
- lib/valligator.rb
|
53
53
|
- lib/valligator_helper.rb
|
54
|
-
- lib/version.rb
|
55
54
|
- test/lib/valligator/asserts_test.rb
|
56
55
|
- test/lib/valligator/errors_test.rb
|
57
56
|
- test/lib/valligator/is_instance_of_test.rb
|
@@ -59,7 +58,8 @@ files:
|
|
59
58
|
- test/lib/valligator/speaks_test.rb
|
60
59
|
- test/test_helper.rb
|
61
60
|
homepage: https://github.com/konstantin-dzreev/valligator
|
62
|
-
licenses:
|
61
|
+
licenses:
|
62
|
+
- MIT
|
63
63
|
metadata: {}
|
64
64
|
post_install_message:
|
65
65
|
rdoc_options: []
|
@@ -67,9 +67,9 @@ require_paths:
|
|
67
67
|
- lib
|
68
68
|
required_ruby_version: !ruby/object:Gem::Requirement
|
69
69
|
requirements:
|
70
|
-
- - "
|
70
|
+
- - "~>"
|
71
71
|
- !ruby/object:Gem::Version
|
72
|
-
version: '0'
|
72
|
+
version: '2.0'
|
73
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
74
|
requirements:
|
75
75
|
- - ">="
|
data/lib/version.rb
DELETED