dirty_hashy 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,11 @@
1
1
  = DirtyHashy CHANGELOG
2
2
 
3
+ == Version 0.1.2 (December 24, 2011)
4
+
5
+ * Moved restricted keys logic from MethodMap to DirtyHash and thus being able to restrict keys of a DirtyHashy without dirty mapping ^^
6
+ * Corrected DirtyHashy.replace and DirtyHashy.clear in order to dirty track involved changes
7
+ * Improved :attributes= implementation within DirtyAttributes
8
+
3
9
  == Version 0.1.1 (December 24, 2011)
4
10
 
5
11
  * Added convenience methods (with MethodMap) like +name+, +name=+, +name_changed?+, +name_was+ and +name_change+
data/Gemfile CHANGED
@@ -13,4 +13,5 @@ end
13
13
  group :gem_test do
14
14
  gem "minitest"
15
15
  gem "mocha"
16
+ gem "pry"
16
17
  end
data/README.textile CHANGED
@@ -4,7 +4,7 @@ Dirty tracking within hashes with indifferent access or objects as it is expecte
4
4
 
5
5
  h2. Introduction
6
6
 
7
- "Dirty tracking / objects":http://ryandaigle.com/articles/2008/3/31/what-s-new-in-edge-rails-dirty-objects is a common programming concept. In short, it is the mechanism to track whether or not the attributes of an object have been changed and if so, which ones.
7
+ "Dirty tracking / objects":http://ryandaigle.com/articles/2008/3/31/what-s-new-in-edge-rails-dirty-objects is a common programming concept. In short, it is the concept of tracking whether or not the attributes of an object have been changed and if so, which ones.
8
8
 
9
9
  It is mostly implemented within ORM's, a couple of examples in the Ruby world are "ActiveRecord":http://ar.rubyonrails.org/classes/ActiveRecord/Dirty.html, "DataMapper":http://rubydoc.info/gems/dm-core/1.1.0/file/README.rdoc, "Mongoid":http://mongoid.org/docs/documents/dirty.html and "CouchRest Model":http://www.couchrest.info/model/dirty_tracking.html.
10
10
 
@@ -88,8 +88,35 @@ You can map methods within a DirtyHashy in order to provide convenience methods
88
88
  h.name = "Engel"
89
89
  h.name_was #=> "Paul"
90
90
  h.name_change #=> ["Paul", "Engel"]
91
- h.foo = "Bar"
92
- h.changes #=> {"name"=>["Paul", "Engel"], "foo"=>[nil, "Bar"]}
91
+ h.foo = "bar"
92
+ h.changes #=> {"name"=>["Paul", "Engel"], "foo"=>[nil, "bar"]}
93
+ </pre>
94
+
95
+ h3. Method mapping DirtyHashy with key restriction
96
+
97
+ Along with providing convenience methods, you can also restrict the range of keys you are permitted to read / write / merge / replace of a DirtyHash:
98
+
99
+ <pre>
100
+ require "rubygems"
101
+ require "dirty_hashy"
102
+
103
+ h = DirtyHashy.new({}, true, [:name])
104
+ h.dirty? #=> false
105
+ h.name #=> nil
106
+ h.name = "Paul"
107
+ h.dirty? #=> true
108
+ h.name_changed? #=> true
109
+ h.name_was #=> nil
110
+ h.name_change #=> [nil, "Paul"]
111
+ h.merge! :name => "Engel"
112
+ h.name #=> "Engel"
113
+ h.name_was #=> nil
114
+ h.name_change #=> [nil, "Engel"]
115
+ h.foo #=> NoMethodError: undefined method `foo' for {"name"=>"Engel"}:DirtyHashy
116
+ h.foo = "bar" #=> NoMethodError: undefined method `foo=' for {"name"=>"Engel"}:DirtyHashy
117
+ h.clean_up!
118
+ h.replace :name => "Paul"
119
+ h.changes #=> {"name"=>["Engel", "Paul"]}
93
120
  </pre>
94
121
 
95
122
  h3. Dirty tracking objects (models)
@@ -159,6 +186,7 @@ You can use @Person@ objects as you would expect:
159
186
  p.clean_up!
160
187
  p.dirty? #=> false
161
188
  p.name #=> "Paul"
189
+ p.foo = "bar" #=> NoMethodError: undefined method `foo=' for #<Person:0x00000100d89860>
162
190
  </pre>
163
191
 
164
192
  And last but not least: don't care about specifying the attributes available? Well don't! ;)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
data/dirty_hashy.gemspec CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
12
12
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
13
13
  gem.name = "dirty_hashy"
14
14
  gem.require_paths = ["lib"]
15
- gem.version = "0.1.1"
15
+ gem.version = "0.1.2"
16
16
 
17
17
  gem.add_dependency "activesupport", ">= 3.0.0"
18
18
  end
@@ -12,7 +12,7 @@ module DirtyAttributes
12
12
  end
13
13
 
14
14
  def attributes
15
- @attrs || []
15
+ @attrs
16
16
  end
17
17
  end
18
18
 
@@ -20,15 +20,17 @@ module DirtyAttributes
20
20
  attr_reader :attributes
21
21
 
22
22
  def initialize
23
- attrs = self.class.attributes.inject({}){|h, a| h.merge({a => nil})}
24
- @attributes = DirtyHashy.new(attrs).tap do |hashy|
25
- dirty_map! hashy, attrs.keys
23
+ @attributes = DirtyHashy.new({}, true, self.class.attributes).tap do |hashy|
24
+ dirty_map! hashy
26
25
  clean_up!
27
26
  end
28
27
  end
29
28
 
30
29
  def attributes=(other)
31
- attributes.clear.merge! other
30
+ attributes.replace other
31
+ rescue IndexError => e
32
+ e.message.match /"(.*)"/
33
+ raise NoMethodError, "undefined method `#{$1}=' for #{self.inspect}"
32
34
  end
33
35
  end
34
36
 
data/lib/dirty_hashy.rb CHANGED
@@ -5,18 +5,36 @@ require "method_map"
5
5
 
6
6
  class DirtyHashy < HashWithIndifferentAccess
7
7
 
8
- def self.new(constructor = {}, map_methods = false)
9
- super(constructor).tap do |instance|
10
- if map_methods
11
- instance.extend MethodMap
12
- instance.dirty_map!
13
- end
8
+ def initialize(constructor = {}, map_methods = false, restricted_keys = nil)
9
+ super constructor
10
+ if map_methods
11
+ extend MethodMap
12
+ dirty_map!
14
13
  end
14
+ if restricted_keys
15
+ restricted_keys.each{|key| self[key] ||= nil}
16
+ @restricted_keys = keys
17
+ end
18
+ end
19
+
20
+ def replace(other)
21
+ clear
22
+ merge! other
23
+ end
24
+
25
+ def clear
26
+ keys.each{|key| delete key}
27
+ end
28
+
29
+ def [](key, mapped = false)
30
+ validate_read!(key) if mapped || restricted_keys?
31
+ super(key)
15
32
  end
16
33
 
17
34
  alias :_regular_writer :regular_writer
18
35
  def regular_writer(key, value)
19
- original_value = changes.key?(key) ? was(key) : self[key]
36
+ validate_write!(key)
37
+ original_value = changes.key?(key) ? was(key) : fetch(key, nil)
20
38
  if original_value == value
21
39
  changes.delete key
22
40
  else
@@ -34,17 +52,18 @@ class DirtyHashy < HashWithIndifferentAccess
34
52
  @changes ||= HashWithIndifferentAccess.new
35
53
  end
36
54
 
37
- def changed?(key = nil)
55
+ def changed?(key = nil, mapped = false)
56
+ validate_read!(key) if !key.nil? && (mapped || restricted_keys?)
38
57
  key.nil? ? !changes.empty? : changes.key?(key)
39
58
  end
40
59
  alias :dirty? :changed?
41
60
 
42
- def change(key)
43
- changes[key] if changed?(key)
61
+ def change(key, mapped = false)
62
+ changes[key] if changed?(key, mapped)
44
63
  end
45
64
 
46
- def was(key)
47
- change(key).first if changed?(key)
65
+ def was(key, mapped = false)
66
+ change(key).first if changed?(key, mapped)
48
67
  end
49
68
 
50
69
  def clean_up!
@@ -52,4 +71,18 @@ class DirtyHashy < HashWithIndifferentAccess
52
71
  nil
53
72
  end
54
73
 
74
+ private
75
+
76
+ def restricted_keys?
77
+ !(@restricted_keys || []).empty?
78
+ end
79
+
80
+ def validate_read!(key)
81
+ raise IndexError, "Invalid key: \"#{key}\"" unless (keys + changes.keys).include?(key.to_s)
82
+ end
83
+
84
+ def validate_write!(key)
85
+ raise IndexError, "Invalid key: \"#{key}\"" unless @restricted_keys.nil? || @restricted_keys.empty? || @restricted_keys.include?(key.to_s)
86
+ end
87
+
55
88
  end
@@ -1,7 +1,7 @@
1
1
  class DirtyHashy < HashWithIndifferentAccess
2
2
  MAJOR = 0
3
3
  MINOR = 1
4
- TINY = 1
4
+ TINY = 2
5
5
 
6
6
  VERSION = [MAJOR, MINOR, TINY].join(".")
7
7
  end
data/lib/method_map.rb CHANGED
@@ -1,51 +1,44 @@
1
1
  module MethodMap
2
2
 
3
- def dirty_map!(mapped = nil, restricted_keys = nil)
3
+ def dirty_map!(mapped = nil)
4
4
  @mapped = mapped || self
5
- @restricted_keys = (restricted_keys || []).collect(&:to_s)
6
5
  map_method(:changes)
7
6
  map_method(:dirty?)
8
7
  map_method(:changed?)
9
8
  map_method(:clean_up!)
10
- map_method(/^([\w_]+)_changed\?$/, Proc.new{ |match| :changed? if map_key? match })
11
- map_method(/^([\w_]+)_change$/ , Proc.new{ |match| :change if map_key? match })
12
- map_method(/^([\w_]+)_was$/ , Proc.new{ |match| :was if map_key? match })
13
- map_method(/(^[\w_]+)=$/ , Proc.new{ |match| :[]= if accept_key? match })
14
- map_method(/(^[\w_]+)$/ , Proc.new{ |match| :[] if map_key? match })
9
+ map_method(/^([\w_]+)_changed\?$/, :changed?, true)
10
+ map_method(/^([\w_]+)_change$/, :change, true)
11
+ map_method(/^([\w_]+)_was$/, :was, true)
12
+ map_method(/(^[\w_]+)=$/, :[]=)
13
+ map_method(/(^[\w_]+)$/, :[], true)
15
14
  end
16
15
 
17
- def map_method(pattern, method_or_proc = nil)
16
+ def map_method(pattern, method_or_proc = nil, args = nil)
18
17
  regex = pattern.is_a?(Regexp) ? pattern : Regexp.new("^#{Regexp.escape(pattern.to_s)}$")
19
- method_map[regex] = method_or_proc || pattern
18
+ method_map[regex] = {:method_or_proc => (method_or_proc || pattern), :args => args}
20
19
  end
21
20
 
22
21
  def method_missing(method, *args)
23
22
  if m = match_method(method)
24
- @mapped.send *(m + args)
25
- else
26
- super
23
+ begin
24
+ return @mapped.send *(m + args)
25
+ rescue IndexError; end
27
26
  end
27
+ super
28
28
  end
29
29
 
30
30
  private
31
31
 
32
- def map_key?(key)
33
- (@mapped.keys + @mapped.changes.keys).include?(key.to_s)
34
- end
35
-
36
- def accept_key?(key)
37
- @restricted_keys.empty? || @restricted_keys.include?(key.to_s)
38
- end
39
-
40
32
  def method_map
41
33
  @method_map ||= {}
42
34
  end
43
35
 
44
36
  def match_method(method)
45
- method_map.each do |pattern, method_or_proc|
37
+ method_map.each do |pattern, spec|
38
+ method_or_proc = spec[:method_or_proc]
46
39
  if method.to_s.match pattern
47
40
  m = method_or_proc.is_a?(Proc) ? method_or_proc.call($1 || method) : method_or_proc
48
- return [m, $1].compact if m
41
+ return [m, $1, spec[:args]].compact if m
49
42
  end
50
43
  end
51
44
  nil
@@ -63,6 +63,38 @@ module Unit
63
63
  assert_equal nil, person.name_change
64
64
  assert_equal [nil, "Bar"], person.foo_change
65
65
  assert_equal({"foo" => [nil, "Bar"]}, person.changes)
66
+
67
+ person.attributes.merge! :company => "Internetbureau Holder B.V."
68
+
69
+ assert_equal true, person.dirty?
70
+ assert_equal true, person.changed?
71
+ assert_equal false, person.name_changed?
72
+ assert_equal true, person.foo_changed?
73
+ assert_equal true, person.company_changed?
74
+ assert_equal nil, person.name_change
75
+ assert_equal [nil, "Bar"], person.foo_change
76
+ assert_equal [nil, "Internetbureau Holder B.V."], person.company_change
77
+ assert_equal({"foo" => [nil, "Bar"], "company" => [nil, "Internetbureau Holder B.V."]}, person.changes)
78
+
79
+ person.attributes.delete :foo
80
+ person.clean_up!
81
+
82
+ assert_equal false, person.dirty?
83
+ assert_equal false, person.changed?
84
+ assert_equal({"name" => "Stephan", "company" => "Internetbureau Holder B.V."}, person.attributes)
85
+ assert_equal({}, person.changes)
86
+
87
+ person.attributes = {"name" => "Paul", "city" => "Amsterdam"}
88
+
89
+ assert_equal true, person.dirty?
90
+ assert_equal true, person.changed?
91
+ assert_equal true, person.name_changed?
92
+ assert_equal true, person.company_changed?
93
+ assert_equal true, person.city_changed?
94
+ assert_equal ["Stephan", "Paul"], person.name_change
95
+ assert_equal ["Internetbureau Holder B.V.", nil], person.company_change
96
+ assert_equal [nil, "Amsterdam"], person.city_change
97
+ assert_equal({"name" => ["Stephan", "Paul"], "company" => ["Internetbureau Holder B.V.", nil], "city" => [nil, "Amsterdam"]}, person.changes)
66
98
  end
67
99
 
68
100
  it "should behave as expected with key restriction" do
@@ -119,6 +151,22 @@ module Unit
119
151
  assert_equal false, user.name_changed?
120
152
  assert_equal nil, user.name_change
121
153
  assert_equal({}, user.changes)
154
+
155
+ user.attributes = {"name" => "Paul"}
156
+
157
+ assert_equal true, user.dirty?
158
+ assert_equal true, user.changed?
159
+ assert_equal true, user.name_changed?
160
+ assert_equal ["Stephan", "Paul"], user.name_change
161
+ assert_equal({"name" => ["Stephan", "Paul"]}, user.changes)
162
+
163
+ assert_raises(NoMethodError) do
164
+ user.attributes = {"company" => "Internetbureau Holder B.V."}
165
+ end
166
+
167
+ assert_raises(IndexError) do
168
+ user.attributes.merge! "company" => "Internetbureau Holder B.V."
169
+ end
122
170
  end
123
171
  end
124
172
 
@@ -4,9 +4,10 @@ module Unit
4
4
  class TestDirtyHashy < MiniTest::Unit::TestCase
5
5
 
6
6
  describe DirtyHashy do
7
- it "should behave as expected without method mapping" do
7
+ it "should behave as expected without method mapping and without restricted keys" do
8
8
  hashy = DirtyHashy.new
9
9
 
10
+ assert_equal({}, hashy)
10
11
  assert_equal false, hashy.dirty?
11
12
  assert_equal false, hashy.changed?
12
13
  assert_equal({}, hashy.changes)
@@ -137,11 +138,159 @@ module Unit
137
138
  assert_equal "Holder", hashy.was("company")
138
139
  assert_equal ["Holder", nil], hashy.change(:company)
139
140
  assert_equal ["Holder", nil], hashy.change("company")
141
+
142
+ hashy.merge! :name => "Paul", :company => "Internetbureau Holder B.V."
143
+
144
+ assert_equal true, hashy.dirty?
145
+ assert_equal true, hashy.changed?
146
+ assert_equal true, hashy.changed?(:name)
147
+ assert_equal true, hashy.changed?("name")
148
+ assert_equal true, hashy.changed?(:company)
149
+ assert_equal true, hashy.changed?("company")
150
+ assert_equal ["Tim", "Paul"], hashy.change(:name)
151
+ assert_equal ["Tim", "Paul"], hashy.change("name")
152
+ assert_equal ["Holder", "Internetbureau Holder B.V."], hashy.change(:company)
153
+ assert_equal ["Holder", "Internetbureau Holder B.V."], hashy.change("company")
154
+ assert_equal({"name" => ["Tim", "Paul"], "company" => ["Holder", "Internetbureau Holder B.V."]}, hashy.changes)
155
+ end
156
+
157
+ it "should behave as expected without method mapping, but with restricted keys" do
158
+ hashy = DirtyHashy.new({}, false, [:name])
159
+
160
+ assert_equal({"name" => nil}, hashy)
161
+ assert_equal false, hashy.dirty?
162
+ assert_equal false, hashy.changed?
163
+ assert_equal({}, hashy.changes)
164
+
165
+ assert_raises(NoMethodError) do
166
+ hashy.name = "Paul"
167
+ end
168
+
169
+ hashy["name"] = "Paul"
170
+
171
+ assert_equal true, hashy.dirty?
172
+ assert_equal true, hashy.changed?
173
+ assert_equal true, hashy.changed?(:name)
174
+ assert_equal true, hashy.changed?("name")
175
+ assert_equal [nil, "Paul"], hashy.change(:name)
176
+ assert_equal [nil, "Paul"], hashy.change("name")
177
+ assert_equal({"name" => [nil, "Paul"]}, hashy.changes)
178
+
179
+ hashy[:name] = nil
180
+
181
+ assert_equal false, hashy.dirty?
182
+ assert_equal false, hashy.changed?
183
+ assert_equal false, hashy.changed?(:name)
184
+ assert_equal false, hashy.changed?("name")
185
+ assert_equal nil, hashy.change(:name)
186
+ assert_equal nil, hashy.change("name")
187
+ assert_equal({}, hashy.changes)
188
+
189
+ hashy[:name] = "Stephan"
190
+
191
+ assert_equal true, hashy.dirty?
192
+ assert_equal true, hashy.changed?
193
+ assert_equal true, hashy.changed?(:name)
194
+ assert_equal true, hashy.changed?("name")
195
+ assert_equal [nil, "Stephan"], hashy.change(:name)
196
+ assert_equal [nil, "Stephan"], hashy.change("name")
197
+ assert_equal({"name" => [nil, "Stephan"]}, hashy.changes)
198
+
199
+ hashy.clean_up!
200
+
201
+ assert_equal false, hashy.dirty?
202
+ assert_equal false, hashy.changed?
203
+ assert_equal false, hashy.changed?(:name)
204
+ assert_equal false, hashy.changed?("name")
205
+ assert_equal nil, hashy.change(:name)
206
+ assert_equal nil, hashy.change("name")
207
+ assert_equal({}, hashy.changes)
208
+
209
+ hashy["name"] = "Chris"
210
+
211
+ assert_equal true, hashy.dirty?
212
+ assert_equal true, hashy.changed?
213
+ assert_equal true, hashy.changed?(:name)
214
+ assert_equal true, hashy.changed?("name")
215
+ assert_equal "Stephan", hashy.was("name")
216
+ assert_equal ["Stephan", "Chris"], hashy.change(:name)
217
+ assert_equal ["Stephan", "Chris"], hashy.change("name")
218
+ assert_equal({"name" => ["Stephan", "Chris"]}, hashy.changes)
219
+
220
+ hashy["name"] = "Stephan"
221
+
222
+ assert_equal false, hashy.dirty?
223
+ assert_equal false, hashy.changed?
224
+ assert_equal false, hashy.changed?(:name)
225
+ assert_equal false, hashy.changed?("name")
226
+ assert_equal nil, hashy.change(:name)
227
+ assert_equal nil, hashy.change("name")
228
+ assert_equal({}, hashy.changes)
229
+
230
+ hashy["name"] = "Paul"
231
+
232
+ assert_equal true, hashy.dirty?
233
+ assert_equal true, hashy.changed?
234
+ assert_equal true, hashy.changed?(:name)
235
+ assert_equal true, hashy.changed?("name")
236
+ assert_equal ["Stephan", "Paul"], hashy.change(:name)
237
+ assert_equal ["Stephan", "Paul"], hashy.change("name")
238
+ assert_equal({"name" => ["Stephan", "Paul"]}, hashy.changes)
239
+
240
+ hashy["name"] = "Tim"
241
+
242
+ assert_equal true, hashy.dirty?
243
+ assert_equal true, hashy.changed?
244
+ assert_equal true, hashy.changed?(:name)
245
+ assert_equal true, hashy.changed?("name")
246
+ assert_equal ["Stephan", "Tim"], hashy.change(:name)
247
+ assert_equal ["Stephan", "Tim"], hashy.change("name")
248
+ assert_equal({"name" => ["Stephan", "Tim"]}, hashy.changes)
249
+
250
+ hashy.clean_up!
251
+ hashy.merge! :name => "Paul"
252
+
253
+ assert_equal true, hashy.dirty?
254
+ assert_equal true, hashy.changed?
255
+ assert_equal true, hashy.changed?(:name)
256
+ assert_equal true, hashy.changed?("name")
257
+ assert_equal ["Tim", "Paul"], hashy.change(:name)
258
+ assert_equal ["Tim", "Paul"], hashy.change("name")
259
+ assert_equal({"name" => ["Tim", "Paul"]}, hashy.changes)
260
+
261
+ assert_raises(IndexError) do
262
+ hashy[:company]
263
+ end
264
+
265
+ assert_raises(IndexError) do
266
+ hashy["company"] = "Holder"
267
+ end
268
+
269
+ assert_raises(IndexError) do
270
+ hashy.delete :company
271
+ end
272
+
273
+ assert_raises(IndexError) do
274
+ hashy.changed? :company
275
+ end
276
+
277
+ assert_raises(IndexError) do
278
+ hashy.change :company
279
+ end
280
+
281
+ assert_raises(IndexError) do
282
+ hashy.was :company
283
+ end
284
+
285
+ assert_raises(IndexError) do
286
+ hashy.merge! :name => "Paul", :company => "Internetbureau Holder B.V."
287
+ end
140
288
  end
141
289
 
142
- it "should behave as expected with method mapping" do
290
+ it "should behave as expected with method mapping and without restricted keys" do
143
291
  hashy = DirtyHashy.new({}, true)
144
292
 
293
+ assert_equal({}, hashy)
145
294
  assert_equal false, hashy.dirty?
146
295
  assert_equal false, hashy.changed?
147
296
  assert_equal({}, hashy.changes)
@@ -225,10 +374,125 @@ module Unit
225
374
  hashy.delete :city
226
375
  assert_equal({"name" => ["Stephan", "Tim"]}, hashy.changes)
227
376
 
377
+ hashy.merge! :company => "Internetbureau Holder B.V."
378
+
379
+ assert_equal true, hashy.dirty?
380
+ assert_equal true, hashy.changed?
381
+ assert_equal true, hashy.changed?(:name)
382
+ assert_equal true, hashy.changed?("name")
383
+ assert_equal true, hashy.changed?(:company)
384
+ assert_equal true, hashy.changed?("company")
385
+ assert_equal ["Stephan", "Tim"], hashy.change(:name)
386
+ assert_equal ["Stephan", "Tim"], hashy.change("name")
387
+ assert_equal [nil, "Internetbureau Holder B.V."], hashy.change(:company)
388
+ assert_equal [nil, "Internetbureau Holder B.V."], hashy.change("company")
389
+ assert_equal({"name" => ["Stephan", "Tim"], "company" => [nil, "Internetbureau Holder B.V."]}, hashy.changes)
390
+
391
+ hashy.clean_up!
392
+
393
+ assert_equal false, hashy.dirty?
394
+ assert_equal false, hashy.changed?
395
+ end
396
+
397
+ it "should behave as expected with method mapping and with restricted keys" do
398
+ hashy = DirtyHashy.new({}, true, [:name])
399
+
400
+ assert_equal({"name" => nil}, hashy)
401
+ assert_equal nil, hashy.name
402
+ assert_equal false, hashy.dirty?
403
+ assert_equal false, hashy.changed?
404
+ assert_equal({}, hashy.changes)
405
+
406
+ hashy.name = "Paul"
407
+
408
+ assert_equal "Paul", hashy.name
409
+ assert_equal true, hashy.dirty?
410
+ assert_equal true, hashy.changed?
411
+ assert_equal true, hashy.name_changed?
412
+ assert_equal true, hashy.changed?(:name)
413
+ assert_equal [nil, "Paul"], hashy.name_change
414
+ assert_equal [nil, "Paul"], hashy.change(:name)
415
+ assert_equal({"name" => [nil, "Paul"]}, hashy.changes)
416
+
417
+ hashy.name = nil
418
+
419
+ assert_equal false, hashy.dirty?
420
+ assert_equal false, hashy.changed?
421
+ assert_equal false, hashy.name_changed?
422
+ assert_equal false, hashy.changed?(:name)
423
+ assert_equal nil, hashy.name_change
424
+ assert_equal nil, hashy.change(:name)
425
+ assert_equal({}, hashy.changes)
426
+
427
+ hashy.name = "Stephan"
428
+
429
+ assert_equal true, hashy.dirty?
430
+ assert_equal true, hashy.changed?
431
+ assert_equal true, hashy.name_changed?
432
+ assert_equal true, hashy.changed?(:name)
433
+ assert_equal [nil, "Stephan"], hashy.name_change
434
+ assert_equal [nil, "Stephan"], hashy.change(:name)
435
+ assert_equal({"name" => [nil, "Stephan"]}, hashy.changes)
436
+
228
437
  hashy.clean_up!
229
438
 
230
439
  assert_equal false, hashy.dirty?
231
440
  assert_equal false, hashy.changed?
441
+ assert_equal false, hashy.name_changed?
442
+ assert_equal false, hashy.changed?(:name)
443
+ assert_equal nil, hashy.name_change
444
+ assert_equal nil, hashy.change(:name)
445
+ assert_equal({}, hashy.changes)
446
+
447
+ hashy.name = "Chris"
448
+
449
+ assert_equal true, hashy.dirty?
450
+ assert_equal true, hashy.changed?
451
+ assert_equal true, hashy.name_changed?
452
+ assert_equal true, hashy.changed?(:name)
453
+ assert_equal "Stephan", hashy.name_was
454
+ assert_equal "Stephan", hashy.was(:name)
455
+ assert_equal ["Stephan", "Chris"], hashy.name_change
456
+ assert_equal ["Stephan", "Chris"], hashy.change(:name)
457
+ assert_equal({"name" => ["Stephan", "Chris"]}, hashy.changes)
458
+
459
+ hashy.name = "Stephan"
460
+
461
+ assert_equal false, hashy.dirty?
462
+ assert_equal false, hashy.changed?
463
+ assert_equal false, hashy.name_changed?
464
+ assert_equal false, hashy.changed?(:name)
465
+ assert_equal nil, hashy.name_change
466
+ assert_equal nil, hashy.change(:name)
467
+ assert_equal({}, hashy.changes)
468
+
469
+ assert_raises(NoMethodError) do
470
+ hashy.company
471
+ end
472
+
473
+ assert_raises(NoMethodError) do
474
+ hashy.company = "Holder"
475
+ end
476
+
477
+ assert_raises(IndexError) do
478
+ hashy.delete :company
479
+ end
480
+
481
+ assert_raises(NoMethodError) do
482
+ hashy.company_changed?
483
+ end
484
+
485
+ assert_raises(NoMethodError) do
486
+ hashy.company_change
487
+ end
488
+
489
+ assert_raises(NoMethodError) do
490
+ hashy.company_was
491
+ end
492
+
493
+ assert_raises(IndexError) do
494
+ hashy.merge! :name => "Paul", :company => "Internetbureau Holder B.V."
495
+ end
232
496
  end
233
497
  end
234
498
 
metadata CHANGED
@@ -1,35 +1,39 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: dirty_hashy
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.1
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 0.1.2
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Paul Engel
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-24 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
12
+
13
+ date: 2011-12-24 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
15
17
  name: activesupport
16
- requirement: &2152647000 !ruby/object:Gem::Requirement
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
17
20
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
21
24
  version: 3.0.0
22
25
  type: :runtime
23
- prerelease: false
24
- version_requirements: *2152647000
25
- description: Dirty tracking within hashes with indifferent access or objects as it
26
- is expected to be!
27
- email:
26
+ version_requirements: *id001
27
+ description: Dirty tracking within hashes with indifferent access or objects as it is expected to be!
28
+ email:
28
29
  - paul.engel@holder.nl
29
30
  executables: []
31
+
30
32
  extensions: []
33
+
31
34
  extra_rdoc_files: []
32
- files:
35
+
36
+ files:
33
37
  - .gitignore
34
38
  - CHANGELOG.rdoc
35
39
  - Gemfile
@@ -46,32 +50,35 @@ files:
46
50
  - test/test_helper.rb
47
51
  - test/unit/test_dirty_attributes.rb
48
52
  - test/unit/test_dirty_hashy.rb
53
+ has_rdoc: true
49
54
  homepage: https://github.com/archan937/dirty_hashy
50
55
  licenses: []
56
+
51
57
  post_install_message:
52
58
  rdoc_options: []
53
- require_paths:
59
+
60
+ require_paths:
54
61
  - lib
55
- required_ruby_version: !ruby/object:Gem::Requirement
62
+ required_ruby_version: !ruby/object:Gem::Requirement
56
63
  none: false
57
- requirements:
58
- - - ! '>='
59
- - !ruby/object:Gem::Version
60
- version: '0'
61
- required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
69
  none: false
63
- requirements:
64
- - - ! '>='
65
- - !ruby/object:Gem::Version
66
- version: '0'
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
67
74
  requirements: []
75
+
68
76
  rubyforge_project:
69
- rubygems_version: 1.8.10
77
+ rubygems_version: 1.6.2
70
78
  signing_key:
71
79
  specification_version: 3
72
- summary: Dirty tracking within hashes with indifferent access or objects as it is
73
- expected to be!
74
- test_files:
80
+ summary: Dirty tracking within hashes with indifferent access or objects as it is expected to be!
81
+ test_files:
75
82
  - test/test_helper.rb
76
83
  - test/unit/test_dirty_attributes.rb
77
84
  - test/unit/test_dirty_hashy.rb