valligator 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 86beebd4198e35c0e7accf7e5ae49e8e100793f7
4
- data.tar.gz: 3d1cf322859147e0c6e238cdc74b7d3a3a32f482
3
+ metadata.gz: b3d8ebc145692776bf7f9420a41868941aa287db
4
+ data.tar.gz: 300432e7de9d78593c799de84373b4921b9225e6
5
5
  SHA512:
6
- metadata.gz: 46e30c31a694e91f20d1488b32b619b08cd0e2aad583f7a6c20cf97d77d245c5f7299f60eccfb972e3ead9a0bdff20377949eae2c15b181de7e998b017b39799
7
- data.tar.gz: 8a794b107f51b596f1bb3de90c280e3d1170db81ee9188b54a434f004fac43744028cc0ffcb46cb3d6718dd2d0388acb6570baa687d3932ec51443c19da74338
6
+ metadata.gz: 7ecb1005fddd355b81c7730ea47ad75ba9b9342221626ed9c38c075d41f34c344b1fc8f377ebbd8657270a190af72d31faf75c96adceb368a122735d4746b1fb
7
+ data.tar.gz: f3de17e331ed5aaf1abfb1d3419133c11d22485106352d4d3cb8ea0f9349b8c214581c4e447b4d4bb33a2f0dffb6800a0be967b2d15ab7e8eb68334d7c53c74b
data/HISTORY.md CHANGED
@@ -1,12 +1,23 @@
1
+ #### 1.0.4
2
+ - Valligator::ValidationError.validation_stack returns the exact position in validation method chain where the validation fails
3
+ - **is_kind_of** got a new alias **is_an**
4
+ - **is_not_kind_of** got a new alias **is_not_an**
5
+ - all alias methods were replaced with ruby's built-in **alias_method**, so error messages will refer to the original method name:
6
+ Example:
7
+ 123.is_a(String)
8
+ # old behavior
9
+ Valligator::ValidationError: wrong number of arguments (0 for 1..Infinity) at `testee#1.is_a
10
+ # new behavior
11
+ Valligator::ValidationError: wrong number of arguments (0 for 1..Infinity) at `testee#1.is_kind_of
12
+
1
13
  #### 1.0.3
2
14
  - **is_instance_of** renamed to **is_kind_of**
3
15
  - **is_not_instance_of** renamed to **is_not_kind_of**
4
16
  - new helper method: Valligator::Helper#vh(Hash)
5
17
 
6
18
  #### 1.0.2
7
- - **is_instance_of** got alias **is_a**
8
- - **is_not_instance_of** got alias **is_not_a**
19
+ - **is_instance_of** got a new alias **is_a**
20
+ - **is_not_instance_of** got a new alias **is_not_a**
9
21
 
10
- #### 1.0.3
11
- - **is_instance_of** renamed to **is_kind_of**
12
- - **is_not_instance_of** renamed to **is_not_kind_of**
22
+ #### 1.0.1
23
+ - couple bug fixes
data/README.md CHANGED
@@ -46,7 +46,7 @@ The validations passes when testee responds to all (or none in negative case) th
46
46
 
47
47
 
48
48
  #### is_kind_of, is_not_kind_of
49
- Aliases: **is_a** and **is_not_a**.
49
+ Aliases: **is_a**, **is_an** and **is_not_a**, **is_not_an**.
50
50
 
51
51
  ```
52
52
  testee.is_kind_of(*classes)
@@ -84,7 +84,7 @@ If it does not sound clear, then it is something like this:
84
84
  # is the same as:
85
85
 
86
86
  value = :foo.size
87
- raise !!value.instance_eval { self == 10 }
87
+ raise if !value.instance_eval { self == 10 }
88
88
  ```
89
89
 
90
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 }.
@@ -103,7 +103,7 @@ Each statement, if it does not fail, returns an instance of the Valligator, so t
103
103
  When validation fails a Valligator::ValidationError is raised.
104
104
 
105
105
  ```
106
- Valligator.new(:foo).is_empty? #=>
106
+ Valligator.new(:foo).is(:empty?) #=>
107
107
  Valligator::ValidationError: `testee#1': method `empty?' returned falsy value
108
108
  ```
109
109
 
@@ -115,6 +115,19 @@ testee.is_a(String).has(:size){self > 10} #=>
115
115
  Valligator::ValidationError: `short': method `size' returned falsy value
116
116
  ```
117
117
 
118
+ If there was a chain of validations, you can get the exact position of the one that failed:
119
+
120
+ ```
121
+ testee = Valligator.new(:foo1)
122
+ begin
123
+ # it should die on :boom
124
+ testee.is_kind_of(Symbol).asserts_not(:empty?).speaks(:boom).has(:to_s){ self == 'foo' }
125
+ rescue => e
126
+ puts e.validation_stack #=> "is_kind_of.asserts_not.speaks"
127
+ end
128
+
129
+ ```
130
+
118
131
  ## Examples
119
132
 
120
133
  Validate that testee is an instance of String
@@ -132,7 +145,7 @@ Validate that all testees have size == 3 and start with 'b' and they are Strings
132
145
  ```
133
146
  testees = ['boo', 'bar', :baz]
134
147
  Valligator.new(*testees).has(:size){self == 3}.has(:[], 0){self == 'b'}.is_a(String) #=>
135
- Valligator::ValidationError: `testee#3': should be Symbol
148
+ Valligator::ValidationError: `testee#3': should not be Symbol
136
149
  ```
137
150
 
138
151
  Validate that all hash values are Integers <= 2
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.3
1
+ 1.0.4
data/lib/valligator.rb CHANGED
@@ -2,12 +2,20 @@ require 'pathname'
2
2
  require_relative 'valligator_helper'
3
3
 
4
4
  class Valligator
5
- VERSION = File.read(Pathname(__FILE__).dirname.join('../VERSION')).strip
5
+ VERSION = File.read(Pathname(__FILE__).dirname.join('../VERSION')).strip
6
+ INFINITY = 1/0.0
7
+ Error = Class.new(StandardError)
6
8
 
7
- Error = Class.new(StandardError)
8
- ValidationError = Class.new(Error)
9
9
 
10
- INFINITY = 1/0.0
10
+ class ValidationError < Error
11
+ attr_reader :validation_stack
12
+
13
+ def initialize(message, stack)
14
+ super(message)
15
+ @validation_stack = stack.join('.')
16
+ end
17
+ end
18
+
11
19
 
12
20
  attr_reader :testees
13
21
  attr_reader :names
@@ -78,7 +86,8 @@ class Valligator
78
86
  def is_kind_of(*classes)
79
87
  clone._is_kind_of(__method__, *classes)
80
88
  end
81
-
89
+ alias_method :is_a, :is_kind_of
90
+ alias_method :is_an, :is_kind_of
82
91
 
83
92
  # Passes when the testee is not an instance of all of the classes
84
93
  #
@@ -95,20 +104,8 @@ class Valligator
95
104
  def is_not_kind_of(*classes)
96
105
  clone._is_kind_of(__method__, *classes)
97
106
  end
98
-
99
-
100
- # Is an alias for {#is_kind_of} method
101
- #
102
- def is_a(*classes)
103
- clone._is_kind_of(__method__, *classes)
104
- end
105
-
106
-
107
- # Is an alias for {#is_not_kind_of} method
108
- #
109
- def is_not_a(*classes)
110
- clone._is_kind_of(__method__, *classes)
111
- end
107
+ alias_method :is_not_a, :is_not_kind_of
108
+ alias_method :is_not_an, :is_not_kind_of
112
109
 
113
110
 
114
111
  # Passes when the testee responds to all the methods
@@ -168,6 +165,8 @@ class Valligator
168
165
  def asserts(method, *args, &block)
169
166
  clone._asserts(__method__, method, *args, &block)
170
167
  end
168
+ alias_method :is, :asserts
169
+ alias_method :has, :asserts
171
170
 
172
171
 
173
172
  # When no block given it passes if the testee, called with a given method and arguments, returns falsy value.
@@ -197,34 +196,8 @@ class Valligator
197
196
  def asserts_not(method, *args, &block)
198
197
  clone._asserts(__method__, method, *args, &block)
199
198
  end
200
-
201
-
202
- # Is an alias for {#asserts} method
203
- #
204
- def is(method, *args, &block)
205
- clone._asserts(__method__, method, *args, &block)
206
- end
207
-
208
-
209
- # Is an alias for {#asserts_not} method
210
- #
211
- def is_not(method, *args, &block)
212
- clone._asserts(__method__, method, *args, &block)
213
- end
214
-
215
-
216
- # Is an alias for {#asserts} method
217
- #
218
- def has(method, *args, &block)
219
- clone._asserts(__method__, method, *args, &block)
220
- end
221
-
222
-
223
- # Is an alias for {#asserts_not} method
224
- #
225
- def does_not_have(method, *args, &block)
226
- clone._asserts(__method__, method, *args, &block)
227
- end
199
+ alias_method :is_not, :asserts_not
200
+ alias_method :does_not_have, :asserts_not
228
201
 
229
202
 
230
203
  protected
@@ -351,7 +324,7 @@ class Valligator
351
324
  # @param option [nil,String] msg Error explanation (when required)
352
325
  #
353
326
  def validation_error(idx, msg)
354
- raise(ValidationError, "`%s': %s" % [name_by_idx(idx), msg])
327
+ raise ValidationError.new("`%s': %s" % [name_by_idx(idx), msg], self.stack)
355
328
  end
356
329
 
357
330
 
@@ -103,4 +103,14 @@ class TestErrors < Minitest::Test
103
103
  assert_equal expected, err.message
104
104
  end
105
105
 
106
+
107
+ #-------------------------------------
108
+ # #validation_stack
109
+ #-------------------------------------
110
+
111
+ def test__stack_attribute
112
+ err = assert_raises(error) { v(:foo).is_a(Symbol).is_not_empty?.speaks(:boom).has(:size) { self > 0 } }
113
+ assert 'is_kind_of.asserts_not.speaks', err.validation_stack
114
+ end
115
+
106
116
  end
@@ -8,27 +8,25 @@ class TestIsInstanceOf < Minitest::Test
8
8
  Valligator::ValidationError
9
9
  end
10
10
 
11
- positive_statements = [:is_kind_of, :is_a]
12
- negative_statements = [:is_not_kind_of, :is_not_a]
13
- all_statements = positive_statements + negative_statements
11
+ positive_statements = [:is_kind_of, :is_a, :is_an]
12
+ negative_statements = [:is_not_kind_of, :is_not_a, :is_not_an]
14
13
 
15
- all_statements.each do |method|
14
+
15
+ positive_statements.each do |method|
16
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
17
+ expected = "wrong number of arguments (0 for 1..Infinity) at `testee#1.is_kind_of'"
18
18
  err = assert_raises(ArgumentError) { v(:a).send(method) }
19
19
  assert_equal expected, err.message
20
20
  end
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 NilClass instead of Class) at `testee#1.%s'" % method
24
+ expected = "wrong argument type (arg#1 is a NilClass instead of Class) at `testee#1.is_kind_of'"
25
25
  err = assert_raises(ArgumentError) { v(:a).send(method, nil) }
26
26
  assert_equal expected, err.message
27
27
  end
28
- end
29
28
 
30
29
 
31
- positive_statements.each do |method|
32
30
  define_method 'test_that__%s__returns_an_instance_of_valligator' % method do
33
31
  assert_instance_of Valligator, v(:a).send(method, Symbol)
34
32
  end
@@ -50,6 +48,19 @@ class TestIsInstanceOf < Minitest::Test
50
48
 
51
49
 
52
50
  negative_statements.each do |method|
51
+ define_method 'test_that__%s__fails_on_wrong_number_of_arguments' % method do
52
+ expected = "wrong number of arguments (0 for 1..Infinity) at `testee#1.is_not_kind_of'"
53
+ err = assert_raises(ArgumentError) { v(:a).send(method) }
54
+ assert_equal expected, err.message
55
+ end
56
+
57
+
58
+ define_method 'test_that__%s__fails_on_wrong_argument_type' % method do
59
+ expected = "wrong argument type (arg#1 is a NilClass instead of Class) at `testee#1.is_not_kind_of'"
60
+ err = assert_raises(ArgumentError) { v(:a).send(method, nil) }
61
+ assert_equal expected, err.message
62
+ end
63
+
53
64
  define_method 'test_that__%s__returns_an_instance_of_valligator' % method do
54
65
  assert_instance_of Valligator, v(:a).send(method, String)
55
66
  end
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.3
4
+ version: 1.0.4
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-10-04 00:00:00.000000000 Z
11
+ date: 2017-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest