metahash-rb 1.1.0 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c50e809216c3a73ef2046daea65464fa70523202
4
- data.tar.gz: 24b5731caac076b56137652e1aef1811eb7af6e3
3
+ metadata.gz: b21c51283eacfaf1a20c154f7999eb8843e310e6
4
+ data.tar.gz: a9e649da99e7b72785265b348d1534907bd74262
5
5
  SHA512:
6
- metadata.gz: 229d38b0eb040f5bc90e6eed6f2e173411647b1195d5544c0aeb1f3dc632f0f81dfb7d7a637b5b879f2de74c7d8dece3f71bf1e53e981df03799a962b024397d
7
- data.tar.gz: d4c9b695e64e7ebb188997f1b0491e5e27268a838c9e1f7b902c8837f6801faa31c14cfed2727a4bb068209ffa3fda762996b33df5caed284bb328236144046a
6
+ metadata.gz: c36be5a77381a5bcab17dc5bf313c35ddfb239ef67b27f00358d530cf4f2dc38722bd54db466f859dc906cc2616b4ee1d9b3414a6f7bb0f306394e6a6c042966
7
+ data.tar.gz: 007622bcea83aea25e888c798885333ae35d1af3c50bb315f1665cc3a42552f2aa57f7da49607ab84a81e554286b162b8e56dabb49f6297c8d4b955fd3a12111
data/README.md CHANGED
@@ -17,9 +17,9 @@ Provides a subclass of Hash and a wrapper around Rails' serialize attribute for
17
17
  Arand new Metadata objects act just like hashes:
18
18
 
19
19
  h = Metadata.new
20
- h
20
+ h
21
21
  => {}
22
-
22
+
23
23
  Accessing nested data requires no wrapping conditions checking for existence of the rquested data:
24
24
 
25
25
  h.outer.inner
@@ -29,18 +29,23 @@ Possible real-word example:
29
29
 
30
30
  if (min_numbers = h.password_rules.formats.numbers.minimum).present?
31
31
  # some code using min_numbers
32
- else
32
+ else
33
33
  # data doesn't exist in h
34
-
34
+
35
35
  h.password_rules.formats.numbers.minimum = 1
36
- # h
36
+ # h
37
37
  # => { password_rules: { formats: { numbers: { minimum: 1 } } } }
38
38
  end
39
39
 
40
+ Convert an existing hash to metadata
41
+
42
+ {a: 1}.to_metadata.a
43
+ # => 1
44
+
40
45
  #### Access to values stored in nested hashes via method call syntax
41
46
 
42
47
  h = Metadata.new( { outer: { inner: { hash_key: "value" } } } )
43
-
48
+
44
49
  h.outer.inner.hash_key
45
50
  => "value"
46
51
 
@@ -49,7 +54,7 @@ Possible real-word example:
49
54
  h = Metadata.new
50
55
  h
51
56
  => {}
52
-
57
+
53
58
  h.outer.inner = 2
54
59
  h
55
60
  => { outer: { inner: 2 } }
@@ -2,30 +2,32 @@
2
2
  # allows the adding of methods to instances,
3
3
  # but not the entire set of instances for a
4
4
  # particular class
5
- module Metaclass
6
- # The hidden singleton lurks behind everyone
7
- def metaclass
8
- class << self
9
- self
5
+ module MetaHash
6
+ module Metaclass
7
+ # The hidden singleton lurks behind everyone
8
+ def metaclass
9
+ class << self
10
+ self
11
+ end
10
12
  end
11
- end
12
13
 
13
- def meta_eval(&block)
14
- metaclass.instance_eval(&block)
15
- end
14
+ def meta_eval(&block)
15
+ metaclass.instance_eval(&block)
16
+ end
16
17
 
17
- # Adds methods to a metaclass
18
- def meta_def(name, &block)
19
- meta_eval {
20
- define_method(name, &block)
21
- }
22
- end
18
+ # Adds methods to a metaclass
19
+ def meta_def(name, &block)
20
+ meta_eval {
21
+ define_method(name, &block)
22
+ }
23
+ end
23
24
 
24
- # unused
25
- # Defines an instance method within a class
26
- # def class_def(name, &block)
27
- # class_eval {
28
- # define_method(name, &block)
29
- # }
30
- # end
25
+ # unused
26
+ # Defines an instance method within a class
27
+ # def class_def(name, &block)
28
+ # class_eval {
29
+ # define_method(name, &block)
30
+ # }
31
+ # end
32
+ end
31
33
  end
@@ -20,7 +20,7 @@
20
20
  # h[:inner][:key] == "value"
21
21
  #
22
22
  class Metadata < Hash
23
- include Metaclass
23
+ include MetaHash::Metaclass
24
24
  # in the event we are overriding a method, have a way to
25
25
  # get back to the original
26
26
  METHOD_BACKUP_KEY = "metadata_original_"
@@ -67,14 +67,12 @@ class Metadata < Hash
67
67
  # @raise [ArgumentError] if one of the keys is method of Hash
68
68
  def method_missing(method_name, *args)
69
69
  # check for assignment
70
- if (key = method_name.to_s).include?("=")
71
- key = key.chop.to_sym
72
-
73
- assign_value(key, args[0])
70
+ if method_name.to_s[-1] == "="
71
+ assign_value(method_name, args[0])
74
72
  else
75
73
  value = self[method_name]
76
- if not value
77
- @empty_nested_hashes << method_name.to_sym
74
+ if value.nil?
75
+ @empty_nested_hashes << method_name
78
76
  value = self
79
77
  end
80
78
  value
@@ -84,19 +82,23 @@ class Metadata < Hash
84
82
 
85
83
  # Metdata has indifferent access
86
84
  def [](key)
85
+ # self.send(key)
87
86
  super(key.to_sym)
88
87
  end
89
88
 
90
89
  # # Metadata has indifferent access,
91
90
  # # so just say that all the keys are symbols.
92
91
  def []=(key, value)
92
+ if value.is_a?(Hash) && !value.is_a?(Metadata)
93
+ value = Metadata.new(value)
94
+ end
93
95
  super(key.to_sym, value)
94
96
  end
95
97
 
96
98
  # tests the ability to use this key as a key in a hash
97
99
  # @param [Symbol] key
98
100
  # @return [Boolean] whether or not this can be used as a hash key
99
- def valid_key?(key)
101
+ def key_not_in_use?(key)
100
102
  not self.respond_to?(key)
101
103
  end
102
104
 
@@ -126,9 +128,13 @@ class Metadata < Hash
126
128
 
127
129
  private
128
130
 
131
+ # @param [Symbol] key "field_name=""
129
132
  def assign_value(key, value)
133
+ key = key.to_s.chop
130
134
  deepest_metadata = self
131
135
 
136
+ value = Metadata.new(value) if value.is_a?(Hash)
137
+
132
138
  if not @empty_nested_hashes.empty?
133
139
  @empty_nested_hashes.each do |key|
134
140
  deepest_metadata = deepest_metadata[key] = Metadata.new
@@ -1,3 +1,3 @@
1
1
  module MetaHash
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.2"
3
3
  end
@@ -4,6 +4,13 @@ describe Hash do
4
4
  context "to_metadata" do
5
5
  subject(:h){ { a: 1 }.to_metadata }
6
6
 
7
- it { is_expected.to be_a Metadata }
7
+ it "is a Metadata" do
8
+ expect(h).to be_a Metadata
9
+ end
10
+
11
+ it "behaves like a Metdata" do
12
+ expect(h.a).to eq 1
13
+ end
8
14
  end
15
+
9
16
  end
@@ -33,16 +33,21 @@ describe Metadata do
33
33
  expect(m["b"]).to eq 2
34
34
  end
35
35
 
36
+ it "converts a hash to metadata" do
37
+ m[:h] = { a: 2 }
38
+ expect(m.h).to be_a Metadata
39
+ end
40
+
36
41
  end
37
42
 
38
- describe "valid_key?" do
43
+ describe "key_not_in_use?" do
39
44
 
40
45
  it "is true for keys that aren't methods" do
41
- expect(m.valid_key?(:b)).to eq true
46
+ expect(m.key_not_in_use?(:b)).to eq true
42
47
  end
43
48
 
44
49
  it "is false for existing methods" do
45
- expect(m.valid_key?(:to_hash)).to eq false
50
+ expect(m.key_not_in_use?(:to_hash)).to eq false
46
51
  end
47
52
  end
48
53
 
@@ -122,35 +127,69 @@ describe Metadata do
122
127
  context "assigns values" do
123
128
  let(:m){Metadata.new}
124
129
 
125
- it "sets a non-exsiting deep value" do
126
- m.a.b = 2
127
- expect(m.a.b).to eq 2
128
- end
129
130
 
130
- it "sets with specific keys" do
131
- m.a.min = 2
132
- m.a.max = 3
133
- expect(m.a.min).to eq 2
134
- expect(m.a.max).to eq 3
131
+ it "allows multiple ways of assigning the same key" do
132
+ m.a = "1"
133
+ m[:a] = "2"
134
+ expect(m.a).to eq "1"
135
135
  end
136
136
 
137
- it "overrides existing methods if set" do
138
- m.keys = 2
139
- expect(m.keys).to eq 2
140
- end
137
+ context "via attribute assignment style" do
138
+ it "sets a non-exsiting deep value" do
139
+ m.a.b = 2
140
+ expect(m.a.b).to eq 2
141
+ end
141
142
 
142
- it "overrides existing methods if set to non-simple objects" do
143
- m.a.b = 2
144
- m.a.keys = 3
145
- expect(m.a.keys).to eq 3
143
+ it "sets with specific keys" do
144
+ m.a.min = 2
145
+ m.a.max = 3
146
+ expect(m.a.min).to eq 2
147
+ expect(m.a.max).to eq 3
148
+ end
149
+
150
+ it "overrides existing methods if set" do
151
+ m.keys = 2
152
+ expect(m.keys).to eq 2
153
+ end
154
+
155
+ it "overrides existing methods if set to non-simple objects" do
156
+ m.a.b = 2
157
+ m.a.keys = 3
158
+ expect(m.a.keys).to eq 3
159
+ end
160
+
161
+ it "can overrid min and max of deeply nested hashes" do
162
+ m.password_rules.formats.digits.max = 3
163
+ m.password_rules.formats.digits.min = 2
164
+
165
+ expect(m.password_rules.formats.digits.min).to eq 2
166
+ expect(m.password_rules.formats.digits.max).to eq 3
167
+ end
168
+
169
+ it "handles falsy values" do
170
+ m.a = false
171
+ expect(m.a).to eq false
172
+ end
173
+
174
+ it "converts hashes to metadata" do
175
+ m.a = { sub: 2 }
176
+ expect(m.a.sub).to eq 2
177
+ end
146
178
  end
147
179
 
148
- it "can overrid min and max of deeply nested hashes" do
149
- m.password_rules.formats.digits.max = 3
150
- m.password_rules.formats.digits.min = 2
180
+ context "via hash style" do
181
+ it "handels falsy values" do
182
+ m[:a] = false
183
+ expect(m[:a]).to eq false
184
+ expect(m.a).to eq false
185
+ end
151
186
 
152
- expect(m.password_rules.formats.digits.min).to eq 2
153
- expect(m.password_rules.formats.digits.max).to eq 3
187
+ it "sets a non-existing deep value" do
188
+ pending "not yet supported"
189
+ m[:a][:b] = 2
190
+ expect(m[:a][:b]).to eq 2
191
+ expect(m.a.b).to eq 2
192
+ end
154
193
  end
155
194
  end
156
195
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metahash-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - L. Preston Sego III
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-12 00:00:00.000000000 Z
11
+ date: 2014-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -144,7 +144,7 @@ rubyforge_project:
144
144
  rubygems_version: 2.4.1
145
145
  signing_key:
146
146
  specification_version: 4
147
- summary: MetaHash-1.1.0
147
+ summary: MetaHash-1.1.2
148
148
  test_files:
149
149
  - spec/hash_spec.rb
150
150
  - spec/metadata_spec.rb