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