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 +6 -0
- data/Gemfile +1 -0
- data/README.textile +31 -3
- data/VERSION +1 -1
- data/dirty_hashy.gemspec +1 -1
- data/lib/dirty_attributes.rb +7 -5
- data/lib/dirty_hashy.rb +45 -12
- data/lib/dirty_hashy/version.rb +1 -1
- data/lib/method_map.rb +15 -22
- data/test/unit/test_dirty_attributes.rb +48 -0
- data/test/unit/test_dirty_hashy.rb +266 -2
- metadata +39 -32
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
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
|
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 = "
|
92
|
-
h.changes #=> {"name"=>["Paul", "Engel"], "foo"=>[nil, "
|
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
|
+
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.
|
15
|
+
gem.version = "0.1.2"
|
16
16
|
|
17
17
|
gem.add_dependency "activesupport", ">= 3.0.0"
|
18
18
|
end
|
data/lib/dirty_attributes.rb
CHANGED
@@ -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
|
-
|
24
|
-
|
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.
|
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
|
9
|
-
super
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
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
|
data/lib/dirty_hashy/version.rb
CHANGED
data/lib/method_map.rb
CHANGED
@@ -1,51 +1,44 @@
|
|
1
1
|
module MethodMap
|
2
2
|
|
3
|
-
def dirty_map!(mapped = 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\?$/,
|
11
|
-
map_method(/^([\w_]+)_change
|
12
|
-
map_method(/^([\w_]+)_was
|
13
|
-
map_method(/(^[\w_]+)
|
14
|
-
map_method(/(^[\w_]+)
|
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
|
-
|
25
|
-
|
26
|
-
|
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,
|
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
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
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
|
-
|
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:
|
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:
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
67
74
|
requirements: []
|
75
|
+
|
68
76
|
rubyforge_project:
|
69
|
-
rubygems_version: 1.
|
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
|
-
|
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
|