hatch 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NWM5Y2NiNzZiYjYzYWQ5MWVhOWJkMjYyYTZjMWYyOThkY2JkNzg4Yg==
4
+ MzJjNWMxMjRlMzM0OGM0YTk2YWY3MmQ5YjAyZWNiMDZjYjg1YWQ0OA==
5
5
  data.tar.gz: !binary |-
6
- YmVkMjEwZjRhZTEwMDY1MmRjMzNjZWUxZmJiYTdlOWZlMTgzNjFhMA==
6
+ NzJhNTQyYjJhMTUyOWZmOWE1OTdjMzY2ZDZmMDQ0MmViY2Y5ODEzZA==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ZDYxZTI3ODQ5MzZmNjBhNTczNjdkMzgwZWY4MGU0ZThkNzdmNzFmMDc1MmRm
10
- NzNjNWEwYTU3YjZhNGY5ZjM0OGE1NDU4NjlmNzRmOTIyZTE4NWY4Mjc5ZTI1
11
- Y2U3NDk5OTJlM2ZjYjQ3MjkzMzFjZmIxOWRmYzc2MTk3MTE5M2Q=
9
+ MTY4NzUzN2Y3OGYyMWFlYmVmNGVjMTI1NDg5Yjc0Y2JiOGY2YmM4NWQyY2Fm
10
+ OTFlMTc0Y2Q5ZWE0YmFhODJkNTc4YWY3YjNhMmQ1MDU3ZWQyNzI1ZmIxZmFk
11
+ ZjA4ZDNlODYwMmY0NTgzMmQyYTY1YTFiMzQwNDc3YzBkMTVlYzY=
12
12
  data.tar.gz: !binary |-
13
- MTI3ZjFmNWQwY2Q3MmU3ZDAwMjM4ZDNlMDZjNGIxZmQxZTRhZDMzYTY0N2Zm
14
- N2FmNzM4ZjVmZjY1NmI1ZjI3OTM2MDI2NTY2MjU0ZDhhNTgwYWZjYzY3N2Uz
15
- NTllYjk0OTBkYzhmMmYxZjA0MTE1OTRmZTQ2ZjI1OTM4MDNmOGQ=
13
+ M2E5M2QyNzE3YjE1NDRmZWM4MDAzNDg2ZjU1ZmY4YTNhMjRkODcxZjc1Yzg2
14
+ MmQyMGM4NzY0ZTU1NjIwNGQzNDlkNzc5MmQ4NTFhNjY5MzY3NjhiYmFiMTBk
15
+ ODQ5M2IwNjI0ZjYzNDdhN2MyMzQ5MWMzODBiNDg1ZWI5M2JjNTU=
data/README.md CHANGED
@@ -1,11 +1,19 @@
1
1
  Hatch
2
2
  =====
3
3
 
4
+ Installation
5
+ ------------
6
+
7
+ $ gem install hatch
8
+
9
+ Usage
10
+ -----
11
+
4
12
  An address without a street? A person without a name? Those are not valid objects!
5
13
  Why should you have them hanging around your system?
6
14
 
7
- Tell ```Hatch``` how to certify the attributes of your models, and he will give you
8
- the appropiate object.
15
+ Tell `Hatch` how to certify the attributes of your models, and he will give you
16
+ the appropriate object.
9
17
 
10
18
  If you don't hatch your model with all the correct attributes, it will give you
11
19
  an object representing an invalid instance of it.
@@ -29,38 +37,66 @@ end
29
37
  address = Address.hatch(street: 'Fake St', number: 1234)
30
38
  address.class
31
39
  # => Address
40
+ address.valid?
41
+ # => true
32
42
 
33
43
  not_an_address = Address.hatch(street: '', number: 1234)
34
44
  not_an_address.class
35
45
  # => Address::InvalidAddress
46
+ not_an_address.valid?
47
+ # => false
36
48
  ```
37
49
 
38
- You declare your attributes to ```Hatch``` with the ```attributes``` message and
39
- then use ```certify(:attribute, 'error message', &validation)``` to verify when an
50
+ You declare your attributes to `Hatch` with the `attributes` message and
51
+ then use `certify(:attribute, 'error message', &validation)` to verify when an
40
52
  attribute is valid.
41
53
 
42
- You'll also get some handy ```errors``` and ```valid?``` methods for both your valid
43
- and invalid model instances.
54
+ In case you're wondering, the `Model::InvalidModel` is polymorphic with your
55
+ `Model` in all the reader methods declared by `attr_reader` or `attr_accessor`
56
+
57
+ `Hatch` also supports some common validations we all like to have! You can pass an error
58
+ of your own or just use the default.
59
+
60
+ ```ruby
61
+ class Address
62
+ include Hatch
63
+ attributes :street, :number
64
+
65
+ certifies(:street, :presence, "This is an error! Where's my street?!")
66
+ certifies(:number, :positive_number)
67
+ end
68
+ ```
69
+
70
+ Common validations come in the following flavours (along with default errors)
71
+
72
+ * `:presence` - `"must be present"`
73
+ * `:positive_number` - `"must be a positive number"`
74
+
75
+ Aaand that's it for the moment. I'll keep on adding more as they come to my mind. If they come
76
+ to yours first, feel free to add them and PR.
77
+
78
+ Errors
79
+ ------
80
+
81
+ You'll also get a handy `errors` hash with a couple of super powers.
44
82
 
45
83
  ```ruby
46
84
  not_an_address = Address.hatch(street: '', number: 1234)
47
85
  not_an_address.class
48
86
  # => Address::InvalidAddress
49
87
 
50
- not_an_address.errors
88
+ not_an_address.errors.full_messages
51
89
  # => ['Address must have a street']
52
90
 
53
- not_an_address.valid?
54
- # => false
55
- ```
56
-
57
- In case you're wondering, the ```Model::InvalidModel``` is polymorphic with your
58
- ```Model``` in all the reader methods declared by ```attr_reader``` or ```attr_accessor```
91
+ not_an_address.errors.on(:street)
92
+ # => 'Address must have a street'
59
93
 
60
- Installation
61
- ------------
94
+ not_an_address.errors[:number]
95
+ # => []
62
96
 
63
- $ gem install hatch
97
+ not_an_address.errors.empty?
98
+ # => false
99
+ ```
64
100
 
65
101
  Thanks
66
102
  ------
data/hatch.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'hatch'
3
- s.version = '0.0.6'
3
+ s.version = '0.0.7'
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
@@ -58,7 +58,7 @@ module Hatch
58
58
 
59
59
  def initialize(*validated_attributes)
60
60
  @validated_attributes = validated_attributes
61
- select_errors
61
+ @errors = Errors.build(@validated_attributes)
62
62
  respond_to_instance_methods
63
63
  end
64
64
 
@@ -80,12 +80,6 @@ module Hatch
80
80
  self.class.send :define_method, attribute.attr, -> {attribute.value}
81
81
  end
82
82
  end
83
-
84
- def select_errors
85
- @errors = @validated_attributes.select do |validated_attribute|
86
- validated_attribute.invalid?
87
- end.map(&:error)
88
- end
89
83
  end
90
84
 
91
85
  private
@@ -151,5 +145,34 @@ module Hatch
151
145
  new(error || "must be a positive number") {|value| !value.nil? && value > 0}
152
146
  end
153
147
  end
148
+
149
+ class Errors < Hash
150
+ def self.build(validated_attributes)
151
+ errors = new
152
+ validated_attributes.each do |validated_attribute|
153
+ if validated_attribute.invalid?
154
+ errors[validated_attribute.attr] = validated_attribute.error
155
+ else
156
+ errors[validated_attribute.attr] = []
157
+ end
158
+ end
159
+
160
+ errors
161
+ end
162
+
163
+ def on(attr)
164
+ self[attr]
165
+ end
166
+
167
+ def full_messages
168
+ messages = []
169
+ values.each {|value| messages << value unless value.empty?}
170
+ messages
171
+ end
172
+
173
+ def empty?
174
+ full_messages.empty?
175
+ end
176
+ end
154
177
  end
155
178
 
@@ -13,13 +13,11 @@ end
13
13
  class CommonValidationsTest < Test::Unit::TestCase
14
14
  def test_presence
15
15
  common_stuff = CommonStuff.hatch(present: nil, positive: 1)
16
- assert common_stuff.is_a?(CommonStuff::InvalidCommonStuff)
17
- assert common_stuff.errors.include?("must be present")
16
+ assert_equal 'must be present', common_stuff.errors.on(:present)
18
17
  end
19
18
 
20
19
  def test_positive_number
21
- common_stuff = CommonStuff.hatch(present: "here", positive: -1)
22
- assert common_stuff.is_a?(CommonStuff::InvalidCommonStuff)
23
- assert common_stuff.errors.include?("must be a positive number")
20
+ common_stuff = CommonStuff.hatch(present: 'here', positive: -1)
21
+ assert_equal 'must be a positive number', common_stuff.errors.on(:positive)
24
22
  end
25
23
  end
@@ -0,0 +1,27 @@
1
+ require_relative 'support/helper'
2
+ require_relative 'support/address'
3
+
4
+ class ErrorsTest < Test::Unit::TestCase
5
+ def initialize(*args)
6
+ @address = Address.hatch(city: 'Buenos Aires', street: '', number: -1)
7
+ super
8
+ end
9
+
10
+ def test_errors_on
11
+ assert @address.errors.on(:city).empty?
12
+ assert_equal 'Address must have a street', @address.errors.on(:street)
13
+ assert_equal 'Address must have a positive number', @address.errors.on(:number)
14
+ end
15
+
16
+ def test_hash_accessor
17
+ assert @address.errors[:city].empty?
18
+ assert_equal 'Address must have a street', @address.errors[:street]
19
+ assert_equal 'Address must have a positive number', @address.errors[:number]
20
+ end
21
+
22
+ def test_errors_full_messages
23
+ assert @address.errors.full_messages.include?('Address must have a street')
24
+ assert @address.errors.full_messages.include?('Address must have a positive number')
25
+ end
26
+ end
27
+
@@ -1,33 +1,17 @@
1
1
  require_relative 'support/helper'
2
2
  require_relative 'support/address'
3
3
 
4
- class ValidTest < Test::Unit::TestCase
4
+ class ValidationTest < Test::Unit::TestCase
5
5
  def test_valid
6
- address = Address.hatch(street: "Fake St", city: "Buenos Aires", number: 1234)
6
+ address = Address.hatch(street: 'Fake St', city: 'Buenos Aires', number: 1234)
7
7
  assert address.is_a?(Address)
8
- assert_equal address.instance_variable_get("@street"), "Fake St"
9
- assert_equal address.instance_variable_get("@number"), 1234
10
- assert_equal address.instance_variable_get("@city"), "Buenos Aires"
11
-
12
- assert address.respond_to?(:errors)
13
- assert address.errors.empty?
14
8
  assert address.respond_to?(:valid?)
15
9
  assert address.valid?
16
10
  end
17
11
 
18
12
  def test_invalid
19
- address = Address.hatch(city: "Buenos Aires", street: "", number: 1234)
20
- assert address.is_a?(Address::InvalidAddress)
21
- assert address.errors.include?("Address must have a street")
22
- assert !address.errors.include?("Address must have a positive number")
23
- assert !address.errors.include?("Address must have a city")
24
-
25
- address = Address.hatch(street: "", number: -4)
13
+ address = Address.hatch(city: 'Buenos Aires', street: '', number: 1234)
26
14
  assert address.is_a?(Address::InvalidAddress)
27
- assert address.errors.include?("Address must have a street")
28
- assert address.errors.include?("Address must have a positive number")
29
- assert address.errors.include?("Address must have a city")
30
-
31
15
  assert address.respond_to?(:valid?)
32
16
  assert !address.valid?
33
17
  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.0.6
4
+ version: 0.0.7
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-05-21 00:00:00.000000000 Z
11
+ date: 2013-05-31 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!
@@ -22,6 +22,7 @@ files:
22
22
  - hatch.gemspec
23
23
  - Rakefile
24
24
  - test/common_validations_test.rb
25
+ - test/errors_test.rb
25
26
  - test/polymorphism_test.rb
26
27
  - test/validation_test.rb
27
28
  - lib/hatch.rb