document_hash 0.0.4 → 0.0.5

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.
@@ -0,0 +1,7 @@
1
+ module DocumentHash
2
+ class Core
3
+ def after_change &block
4
+ @after_change = block
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,76 @@
1
+ module DocumentHash
2
+ class Core < Hash
3
+ def self.[] *attr
4
+ super(*attr).tap do|new|
5
+ new.each do |k,v|
6
+ new[k] = new.class[v] if v.is_a?(Hash) && ! v.is_a?(self.class)
7
+ end
8
+
9
+ symbolize_keys new
10
+ end
11
+ end
12
+
13
+ def changed
14
+ changed_attributes.dup.freeze
15
+ end
16
+
17
+ def changed?
18
+ ! changed.empty?
19
+ end
20
+
21
+ def [] key
22
+ super key.to_sym
23
+ end
24
+
25
+ def []= key, val
26
+ key = key.to_sym
27
+
28
+ if val.is_a? Hash
29
+ val = self.class[val]
30
+ val.__send__ :parent=, self;
31
+ val.__send__ :parent_key=, key;
32
+ end
33
+
34
+ super key, val
35
+ changed_key key
36
+ end
37
+
38
+ def reset!
39
+ changed_attributes.clear
40
+
41
+ values.select{|v| v.is_a? self.class }.each{ |v| v.reset! }
42
+ end
43
+
44
+ def merge other
45
+ self.class.symbolize_keys other
46
+ super other
47
+ end
48
+
49
+ def merge! other
50
+ self.class.symbolize_keys other
51
+ super other
52
+ end
53
+
54
+ private
55
+
56
+ attr_accessor :parent, :parent_key
57
+
58
+ def changed_key key
59
+ path = Array(key)
60
+
61
+ @after_change.call path if @after_change
62
+ changed_attributes << path.first
63
+ parent.__send__ :changed_key, path.unshift(parent_key) if parent
64
+ end
65
+
66
+ def changed_attributes
67
+ @changed ||= ::Set.new
68
+ end
69
+
70
+ def self.symbolize_keys hash
71
+ hash.keys.each do |key|
72
+ hash[(key.to_sym rescue key) || key] = hash.delete(key)
73
+ end
74
+ end
75
+ end
76
+ end
@@ -1,3 +1,3 @@
1
1
  module DocumentHash
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/lib/document_hash.rb CHANGED
@@ -1,77 +1,7 @@
1
1
  require "set"
2
2
  require "document_hash/version"
3
+ require "document_hash/core"
4
+ require "document_hash/callbacks"
3
5
 
4
6
  module DocumentHash
5
- class Core < Hash
6
- def self.[] *attr
7
- super(*attr).tap do|new|
8
- new.each do |k,v|
9
- new[k] = new.class[v] if v.is_a?(Hash) && ! v.is_a?(self.class)
10
- end
11
-
12
- symbolize_keys new
13
- end
14
- end
15
-
16
- def changed
17
- changed_attributes.dup.freeze
18
- end
19
-
20
- def changed?
21
- ! changed.empty?
22
- end
23
-
24
- def [] key
25
- super key.to_sym
26
- end
27
-
28
- def []= key, val
29
- key = key.to_sym
30
-
31
- if val.is_a? Hash
32
- val = self.class[val]
33
- val.__send__ :parent=, self;
34
- val.__send__ :parent_key=, key;
35
- end
36
-
37
- super key, val
38
- changed_key key
39
-
40
- parent.__send__ :changed_key, parent_key if parent
41
- end
42
-
43
- def reset!
44
- changed_attributes.clear
45
-
46
- values.select{|v| v.is_a? self.class }.each{ |v| v.reset! }
47
- end
48
-
49
- def merge other
50
- self.class.symbolize_keys other
51
- super other
52
- end
53
-
54
- def merge! other
55
- self.class.symbolize_keys other
56
- super other
57
- end
58
-
59
- private
60
-
61
- attr_accessor :parent, :parent_key
62
-
63
- def changed_key key
64
- changed_attributes << key
65
- end
66
-
67
- def changed_attributes
68
- @changed ||= ::Set.new
69
- end
70
-
71
- def self.symbolize_keys hash
72
- hash.keys.each do |key|
73
- hash[(key.to_sym rescue key) || key] = hash.delete(key)
74
- end
75
- end
76
- end
77
7
  end
@@ -82,4 +82,33 @@ describe DocumentHash::Core do
82
82
  subject = subject.merge "test2" => "value2"
83
83
  subject.keys.should include :test2
84
84
  end
85
+
86
+ it "receives an after change method" do
87
+ subject = DocumentHash::Core.new
88
+ subject.should respond_to :after_change
89
+ end
90
+
91
+ it "triggers the after change block" do
92
+ subject = DocumentHash::Core.new
93
+ test_mock = mock("test")
94
+ test_mock.should_receive(:callback_mock).with([:test])
95
+
96
+ subject.after_change do |path|
97
+ test_mock.callback_mock path
98
+ end
99
+
100
+ subject["test"] = "value"
101
+ end
102
+
103
+ it "receives the right path when multilevel" do
104
+ subject = DocumentHash::Core[ { inner: { attribute: "value" } } ]
105
+ test_mock = mock("test")
106
+ test_mock.should_receive(:callback_mock).with([:inner, :attribute])
107
+
108
+ subject.after_change do |path|
109
+ test_mock.callback_mock path
110
+ end
111
+
112
+ subject[:inner][:attribute] = "hello"
113
+ end
85
114
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: document_hash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-28 00:00:00.000000000 Z
12
+ date: 2013-05-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -43,6 +43,8 @@ files:
43
43
  - Rakefile
44
44
  - document_hash.gemspec
45
45
  - lib/document_hash.rb
46
+ - lib/document_hash/callbacks.rb
47
+ - lib/document_hash/core.rb
46
48
  - lib/document_hash/version.rb
47
49
  - spec/lib/document_spec.rb
48
50
  - spec/spec_helper.rb