hatch 0.1.1 → 0.1.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 +8 -8
- data/README.md +6 -5
- data/hatch.gemspec +1 -1
- data/lib/hatch.rb +10 -10
- data/test/common_validations_test.rb +13 -7
- data/test/errors_test.rb +7 -8
- data/test/polymorphism_test.rb +12 -12
- data/test/validation_test.rb +8 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MDlkZmRlM2ViZDQxZDFiODVlNGY3ZTNmNzcyMTMzZTViZWQ5OTc1Mw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YTk3Nzg0NDk0MGIzMzI4NWNmNzIzZjdkZWM3YjM3YjhkMGEyODA1ZQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NGM4MjIyZmI2MzE3OTgzNmQ5YzI5YjI3OTkwN2I3NDRiNGQ1M2JiNTQzMzgw
|
10
|
+
NzAyYTc1ZmM0OTRiZTg3Y2RmMTNhYzA2OWU2NDBlYjE1MmRiYTMwZGFjYTY5
|
11
|
+
ODA2ZTk2YzA2ZDU2NDI4MDM4MzZhZTIyYTEwNDVmNjg5ZjBmZmU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Y2QyZDkyNjA2Y2Y5YzM5ZjkzNzdiOGU0MDYzNzlkNTJhMTY0NTA3MjE4YjIz
|
14
|
+
Yjc1NTdhYjBiZWMyYjJjYzRkN2I2ZmE0MWU5NjBiOWNjNDdiODBjMWRlOTc3
|
15
|
+
NmJkYzcwYTViZmVjMDFhYmU5YWE2YjFlODRiMzY4YjJmMTczZGY=
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
Hatch
|
2
2
|
=====
|
3
3
|
|
4
|
+
An address without a street? A person without a name? Those are not valid objects! Why should you have them hanging around your system? [](https://travis-ci.org/tonchis/hatch) [](https://codeclimate.com/github/tonchis/hatch)
|
5
|
+
|
4
6
|
Installation
|
5
7
|
------------
|
6
8
|
|
@@ -9,8 +11,6 @@ Installation
|
|
9
11
|
Usage
|
10
12
|
-----
|
11
13
|
|
12
|
-
An address without a street? A person without a name? Those are not valid objects!
|
13
|
-
Why should you have them hanging around your system?
|
14
14
|
|
15
15
|
Tell `Hatch` how to certify the attributes of your models, and it will give you the appropriate object.
|
16
16
|
|
@@ -55,15 +55,16 @@ In case you're wondering, the `Model::InvalidModel` is polymorphic with your `Mo
|
|
55
55
|
class Address
|
56
56
|
include Hatch
|
57
57
|
|
58
|
-
certifies(:street, :
|
58
|
+
certifies(:street, :not_empty, 'This is an error! Where's my street?!')
|
59
59
|
certifies(:number, :positive_number)
|
60
60
|
end
|
61
61
|
```
|
62
62
|
|
63
63
|
Common validations come in the following flavours (along with default error messages)
|
64
64
|
|
65
|
-
* `:
|
66
|
-
* `:positive_number` - `
|
65
|
+
* `:not_nil` - `'must not be nil'`
|
66
|
+
* `:positive_number` - `'must be a positive number'`
|
67
|
+
* `:not_empty` - `'must not be empty'`
|
67
68
|
|
68
69
|
Aaand that's it for the moment. I'll keep on adding more as they come to my mind. If they come to yours first, feel free to add them and PR.
|
69
70
|
|
data/hatch.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'hatch'
|
3
|
-
s.version = '0.1.
|
3
|
+
s.version = '0.1.2'
|
4
4
|
s.date = Time.now.strftime('%Y-%m-%d')
|
5
5
|
s.summary = 'Keep valid objects only'
|
6
6
|
s.description = "An address without a street? A person without a name? You don't need no invalid objects!"
|
data/lib/hatch.rb
CHANGED
@@ -61,12 +61,12 @@ module Hatch
|
|
61
61
|
private
|
62
62
|
|
63
63
|
def respond_to_instance_methods
|
64
|
-
|
64
|
+
attributes_with_reader_method.each do |attribute|
|
65
65
|
self.class.send :define_method, attribute.attr, -> {attribute.value}
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
def
|
69
|
+
def attributes_with_reader_method
|
70
70
|
extended_klass = Kernel.const_get(self.class.to_s.split("Invalid").last)
|
71
71
|
instance_methods = extended_klass.instance_methods(false)
|
72
72
|
|
@@ -79,7 +79,7 @@ module Hatch
|
|
79
79
|
private
|
80
80
|
|
81
81
|
def build(validated_attributes)
|
82
|
-
if
|
82
|
+
if validated_attributes.all? {|validated_attribute| validated_attribute.valid?}
|
83
83
|
set_instance_variables(new, *validated_attributes)
|
84
84
|
else
|
85
85
|
const_get("Invalid#{self}").new(*validated_attributes)
|
@@ -92,10 +92,6 @@ module Hatch
|
|
92
92
|
end
|
93
93
|
instance
|
94
94
|
end
|
95
|
-
|
96
|
-
def all_attributes_valid?(validated_attributes)
|
97
|
-
validated_attributes.map(&:valid?).reduce(true, :&)
|
98
|
-
end
|
99
95
|
end
|
100
96
|
|
101
97
|
class ValidatedAttribute
|
@@ -125,12 +121,16 @@ module Hatch
|
|
125
121
|
@error, @block = error, block
|
126
122
|
end
|
127
123
|
|
128
|
-
def self.
|
129
|
-
new(error ||
|
124
|
+
def self.not_nil(error)
|
125
|
+
new(error || 'must not be nil') {|value| !value.nil?}
|
130
126
|
end
|
131
127
|
|
132
128
|
def self.positive_number(error)
|
133
|
-
new(error ||
|
129
|
+
new(error || 'must be a positive number') {|value| !value.nil? && value > 0}
|
130
|
+
end
|
131
|
+
|
132
|
+
def self.not_empty(error)
|
133
|
+
new(error || 'must not be empty') {|value| !value.nil? && !value.empty?}
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
@@ -1,21 +1,27 @@
|
|
1
|
-
|
1
|
+
require 'minitest/autorun'
|
2
2
|
require_relative '../lib/hatch'
|
3
3
|
|
4
4
|
class CommonStuff
|
5
5
|
include Hatch
|
6
6
|
|
7
|
-
certifies :
|
7
|
+
certifies :not_nil, :not_nil
|
8
8
|
certifies :positive, :positive_number
|
9
|
+
certifies :not_empty, :not_empty
|
9
10
|
end
|
10
11
|
|
11
|
-
class CommonValidationsTest <
|
12
|
-
def
|
13
|
-
common_stuff = CommonStuff.hatch(present: nil
|
14
|
-
assert_equal 'must be
|
12
|
+
class CommonValidationsTest < MiniTest::Unit::TestCase
|
13
|
+
def test_not_nil
|
14
|
+
common_stuff = CommonStuff.hatch(present: nil)
|
15
|
+
assert_equal 'must not be nil', common_stuff.errors.on(:not_nil)
|
15
16
|
end
|
16
17
|
|
17
18
|
def test_positive_number
|
18
|
-
common_stuff = CommonStuff.hatch(
|
19
|
+
common_stuff = CommonStuff.hatch(positive: -1)
|
19
20
|
assert_equal 'must be a positive number', common_stuff.errors.on(:positive)
|
20
21
|
end
|
22
|
+
|
23
|
+
def test_not_empty
|
24
|
+
common_stuff = CommonStuff.hatch(not_empty: [])
|
25
|
+
assert_equal 'must not be empty', common_stuff.errors.on(:not_empty)
|
26
|
+
end
|
21
27
|
end
|
data/test/errors_test.rb
CHANGED
@@ -1,27 +1,26 @@
|
|
1
|
-
|
1
|
+
require 'minitest/autorun'
|
2
2
|
require_relative 'support/address'
|
3
3
|
|
4
|
-
class ErrorsTest <
|
5
|
-
def
|
4
|
+
class ErrorsTest < MiniTest::Unit::TestCase
|
5
|
+
def setup
|
6
6
|
@address = Address.hatch(city: 'Buenos Aires', street: '', number: -1)
|
7
|
-
super
|
8
7
|
end
|
9
8
|
|
10
9
|
def test_errors_on
|
11
|
-
|
10
|
+
assert_empty @address.errors.on(:city)
|
12
11
|
assert_equal 'Address must have a street', @address.errors.on(:street)
|
13
12
|
assert_equal 'Address must have a positive number', @address.errors.on(:number)
|
14
13
|
end
|
15
14
|
|
16
15
|
def test_hash_accessor
|
17
|
-
|
16
|
+
assert_empty @address.errors[:city]
|
18
17
|
assert_equal 'Address must have a street', @address.errors[:street]
|
19
18
|
assert_equal 'Address must have a positive number', @address.errors[:number]
|
20
19
|
end
|
21
20
|
|
22
21
|
def test_errors_full_messages
|
23
|
-
|
24
|
-
|
22
|
+
assert_includes @address.errors.full_messages, 'Address must have a street'
|
23
|
+
assert_includes @address.errors.full_messages, 'Address must have a positive number'
|
25
24
|
end
|
26
25
|
end
|
27
26
|
|
data/test/polymorphism_test.rb
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
|
1
|
+
require 'minitest/autorun'
|
2
2
|
require_relative 'support/address'
|
3
3
|
|
4
|
-
class PolymorphismTest <
|
4
|
+
class PolymorphismTest < MiniTest::Unit::TestCase
|
5
5
|
def test_polymorphism
|
6
|
-
address = Address.hatch(street:
|
7
|
-
|
8
|
-
assert_equal address.street
|
9
|
-
assert_equal address.number
|
10
|
-
assert_equal address.city
|
6
|
+
address = Address.hatch(street: 'Fake St', number: 1234, city: 'Buenos Aires')
|
7
|
+
assert_instance_of Address, address
|
8
|
+
assert_equal 'Fake St', address.street
|
9
|
+
assert_equal 1234, address.number
|
10
|
+
assert_equal 'Buenos Aires', address.city
|
11
11
|
|
12
|
-
address = Address.hatch(street:
|
13
|
-
|
14
|
-
assert_equal address.street
|
15
|
-
assert_equal address.number
|
16
|
-
assert_equal address.city
|
12
|
+
address = Address.hatch(street: 'Fake St', number: -1, city: 'Buenos Aires')
|
13
|
+
assert_instance_of Address::InvalidAddress, address
|
14
|
+
assert_equal 'Fake St', address.street
|
15
|
+
assert_equal -1, address.number
|
16
|
+
assert_equal 'Buenos Aires', address.city
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
data/test/validation_test.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
|
1
|
+
require 'minitest/autorun'
|
2
2
|
require_relative 'support/address'
|
3
3
|
|
4
|
-
class ValidationTest <
|
4
|
+
class ValidationTest < MiniTest::Unit::TestCase
|
5
5
|
def test_valid
|
6
6
|
address = Address.hatch(street: 'Fake St', city: 'Buenos Aires', number: 1234)
|
7
|
-
|
8
|
-
|
7
|
+
assert_instance_of Address, address
|
8
|
+
assert_respond_to address, :valid?
|
9
9
|
assert address.valid?
|
10
10
|
end
|
11
11
|
|
12
12
|
def test_invalid
|
13
13
|
address = Address.hatch(city: 'Buenos Aires', street: '', number: 1234)
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
assert_instance_of Address::InvalidAddress, address
|
15
|
+
assert_respond_to address, :valid?
|
16
|
+
refute address.valid?
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_ignore_attributes
|
20
20
|
address = Address.hatch(street: 'Fake St', city: 'Buenos Aires', number: 1234, sorry: :oops)
|
21
|
-
|
21
|
+
assert_instance_of Address, address
|
22
22
|
assert address.valid?
|
23
23
|
end
|
24
24
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hatch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Tolchinsky
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-08-07 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: An address without a street? A person without a name? You don't need
|
14
14
|
no invalid objects!
|