metahash-rb 1.1.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
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