valligator 1.0.3 → 1.0.4

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 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