safestruct 1.0.0 → 1.1.0

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: c7bf46e7fc7abcced2da4628ab2640f4f3136482
4
- data.tar.gz: 693e1ad041258390403893df801673955e574c7e
3
+ metadata.gz: 566fae2d8f89cb24afd577666383dd7944811152
4
+ data.tar.gz: 6b72e279ae328f1fdac760691ad57d92e991ab21
5
5
  SHA512:
6
- metadata.gz: 2f548ea0b261a9fe0e829ad2205aa21b46ea6cac99ff082a80bcaaa5418fe75e9684200f31033f099450c3b688240664949ad0bbc70ad4f8abf57f197a33020a
7
- data.tar.gz: 9fc0faf2c9373cfa146a7f7d5d8b18e17c7ea6e419d10b19d9ab95323650d825bbb3e6b7818c475360aa89101c9f17543731bc07dd02f2e17ce102a5ede5e92e
6
+ metadata.gz: f756d180e311fef89fc4325bcb873bcaaaa02e73cba6ce8d34081352ff46a99307e76470dadec5ede89ab7ea7869d8d1f8a70260860c452f4a5a8783165bd5c2
7
+ data.tar.gz: bf9226fd8c07a2f63ee309e5b6ebbd7da7551bcaf350691bf715c9ebb8c7e48250b9b88765ad1dbf8d7c09ee07f46b6e3d39e63684276e759529187e7cbc15e4
data/README.md CHANGED
@@ -168,7 +168,7 @@ hash['0x0000'] #=> 42
168
168
  Note: Safe Hash will ALWAYS return a value.
169
169
  If the key is missing in the hash mapping on lookup,
170
170
  the key gets auto-added with a zero value.
171
- Use `has_key?` or `key?` to check if a key is present.
171
+ Use `has_key?` or `key?` to check if a key is present (or missing).
172
172
 
173
173
 
174
174
  Yes, Safe Hash works with structs (or arrays or nested hash mappings) too. Example:
@@ -180,8 +180,22 @@ hash['0x0000'] #=> #<Vote @weight=0, @voted=false, @vote=0, @dele
180
180
  hash['0x0000'].voted? #=> false
181
181
  hash['0x0000'].voted = true
182
182
  hash['0x0000'].voted? #=> true
183
- ```
184
183
 
184
+ # or
185
+
186
+ allowances = Hash.of( String => Hash.of( String => Integer ) )
187
+
188
+ allowances['0x1111']['0xaaaa'] = 100
189
+ allowances['0x1111']['0xbbbb'] = 200
190
+ allowances['0x2222']['0xaaaa'] = 300
191
+
192
+ allowances['0x1111']['0xaaaa'] #=> 100
193
+ allowances['0x1111']['0xbbbb'] #=> 200
194
+ allowances['0x2222']['0xaaaa'] #=> 300
195
+
196
+ allowances['0x2222'].delete( '0xaaaa' )
197
+ allowances['0x2222']['0xaaaa'] #=> 0
198
+ ```
185
199
 
186
200
 
187
201
 
@@ -43,15 +43,17 @@ class Hash
43
43
  ## e.g. gets passed in [{Address=>Integer}]
44
44
  ## check for Integer - use Hash.new(0)
45
45
  ## check for Bool - use Hash.new(False)
46
- if args[0].is_a? Hash
46
+ if args[0].is_a?( Hash ) && args.size == 1
47
47
  arg = args[0].to_a ## convert to array (for easier access)
48
48
  klass_key = arg[0][0]
49
- klass_value = arg[0][1]
49
+ ## note: for nested Hash.of or Array.of a ("prototype") object
50
+ ## gets passed in (NOT class) - auto-convert to use class
51
+ klass_or_proto_value = arg[0][1]
52
+ klass_value = klass_or_proto_value.is_a?( Class ) ? klass_or_proto_value : klass_or_proto_value.class
50
53
  klass = Safe::SafeHash.build_class( klass_key, klass_value )
51
54
  klass.new
52
55
  else
53
- ## todo/fix: throw argument error/exception
54
- Hash.new ## that is, "plain" {} with all "standard" defaults
56
+ raise ArgumentError.new( "[Hash.of] wrong argument; expected (default) hash e.g. String => Integer" )
55
57
  end
56
58
  end
57
59
  end
@@ -61,7 +63,10 @@ class Array
61
63
  ## "typed" safe array "constructor"
62
64
  ## e.g. Array.of( Address ) or Array.of( Money ) or
63
65
  ## Array.of( Proposal, 2 ) etc.
64
- def self.of( klass_value, size=0 )
66
+ def self.of( klass_or_proto_value, size=0 )
67
+ ## note: for nested Hash.of or Array.of a ("prototype") object
68
+ ## gets passed in (NOT class) - auto-convert to use class
69
+ klass_value = klass_or_proto_value.is_a?( Class ) ? klass_or_proto_value : klass_or_proto_value.class
65
70
  klass = Safe::SafeArray.build_class( klass_value )
66
71
  klass.new( size )
67
72
  end
@@ -98,10 +98,12 @@ RUBY
98
98
  ## note: Address might be a String too (Address | String)
99
99
  ## store Address always as String!!! - why? why not?
100
100
  @ary.push( item )
101
+ ## note: returns array.size (NOT array itself!!!) to keep compatible with solidity - why? why not?
102
+ @ary.size
101
103
  end
102
104
 
103
105
  extend Forwardable
104
- def_delegators :@ary, :size, :length,
106
+ def_delegators :@ary, :size, :length, :clear,
105
107
  :each, :each_with_index
106
108
 
107
109
 
@@ -93,8 +93,10 @@ RUBY
93
93
  end
94
94
 
95
95
  extend Forwardable
96
- def_delegators :@h, :size, :length, ## todo/fix: remove size and length for (safe) hash - why? why not?
97
- :has_key?, :key?
96
+ def_delegators :@h, :has_key?, :key?, :delete, :clear
97
+
98
+ ## note: remove size and length for (safe) hash (for now) - follows solidity convention - why? why not?
99
+ ## :size, :length,
98
100
 
99
101
  end # class SafeHash
100
102
  end # module Safe
@@ -4,7 +4,7 @@
4
4
  module Safe
5
5
 
6
6
  MAJOR = 1
7
- MINOR = 0
7
+ MINOR = 1
8
8
  PATCH = 0
9
9
  VERSION = [MAJOR,MINOR,PATCH].join('.')
10
10
 
@@ -15,6 +15,26 @@ class TestArray < MiniTest::Test
15
15
  Array_Integer = SafeArray.build_class( Integer )
16
16
  Array_Bool = SafeArray.build_class( Bool )
17
17
 
18
+ ## multi-dimensional / nested array
19
+ Array_Array_Integer = SafeArray.build_class( Array_Integer )
20
+
21
+
22
+ def test_push_and_clear
23
+ ary = Array_Integer.new
24
+
25
+ ## note: push returns array.size after adding new item
26
+ ## std ruby returns reference to array itself
27
+ assert_equal 0, ary.size
28
+ assert_equal 1, ary.push( 10 )
29
+ assert_equal 1, ary.size
30
+
31
+ assert_equal 2, ary.push( 20 )
32
+ assert_equal 2, ary.size
33
+
34
+ ary.clear
35
+ assert_equal 0, ary.size
36
+ end
37
+
18
38
  def test_integer
19
39
  pp Array_Integer
20
40
  pp ary = Array_Integer.new(2)
@@ -67,5 +87,55 @@ def test_bool
67
87
  assert_equal Array_Bool, Array.of( Bool ).class
68
88
  end
69
89
 
90
+ def test_array_of
91
+ assert_equal true, Array.is_a?( Class )
92
+
93
+ ary = Array.of( Integer ) # note:Array.of returns a new ("prototype") object and NOT a class
94
+ assert_equal false, ary.is_a?( Class )
95
+ assert_equal true, ary.class.is_a?( Class )
96
+ end
97
+
98
+ def test_multi # nested (multi-dimensional) array
99
+ ## todo/fix: try with size: 3 e.g. 3x3
100
+ ## make it work with size too!!!!!
101
+ ## remember size if passed in in c'tor!!!!!!
102
+
103
+ multi = Array_Array_Integer.new
104
+ multi.push( Array_Integer.new )
105
+ multi[0].push( 100 )
106
+ multi[0].push( 200 )
107
+ multi.push( Array_Integer.new )
108
+ multi[1].push( 300 )
109
+ pp multi
110
+
111
+ assert_equal 100, multi[0][0]
112
+ assert_equal 200, multi[0][1]
113
+ assert_equal 300, multi[1][0]
114
+
115
+ multi[1].clear
116
+ assert_equal 0, multi[1].size
117
+ multi.clear
118
+ assert_equal 0, multi.size
119
+
120
+ ##############################################
121
+ ## try Array.of convenience helper
122
+
123
+ multi = Array.of( Array.of( Integer ) )
124
+ multi.push( Array.of( Integer ) )
125
+ multi[0].push( 100 )
126
+ multi[0].push( 200 )
127
+ multi.push( Array.of( Integer ) )
128
+ multi[1].push( 300 )
129
+ pp multi
130
+
131
+ assert_equal 100, multi[0][0]
132
+ assert_equal 200, multi[0][1]
133
+ assert_equal 300, multi[1][0]
134
+
135
+ multi[1].clear
136
+ assert_equal 0, multi[1].size
137
+ multi.clear
138
+ assert_equal 0, multi.size
139
+ end
70
140
 
71
141
  end # class TestArray
@@ -19,6 +19,9 @@ class TestHash < MiniTest::Test
19
19
  Hash_X_Bool = SafeHash.build_class( String, Bool )
20
20
  Hash_X_Voter = SafeHash.build_class( String, Voter )
21
21
 
22
+ ## nested e.g. String => (String => Integer)
23
+ Hash_Hash_X_Integer = SafeHash.build_class( String, Hash_X_Integer )
24
+
22
25
  def test_integer
23
26
  pp Hash_X_Integer
24
27
  pp h = Hash_X_Integer.new
@@ -27,8 +30,8 @@ def test_integer
27
30
  assert_equal false, h.has_key?( '0x1111' )
28
31
 
29
32
  ## todo/fix: remove size and length for (safe) hash - why? why not?
30
- assert_equal 0, h.size
31
- assert_equal 0, h.length
33
+ assert_equal 0, h.instance_variable_get('@h').size
34
+ assert_equal 0, h.instance_variable_get('@h').length
32
35
 
33
36
  assert_equal Hash_X_Integer.zero, h
34
37
  assert_equal Hash_X_Integer.zero, Hash_X_Integer.new
@@ -38,7 +41,7 @@ def test_integer
38
41
  assert_equal false, Hash_X_Integer.new.frozen?
39
42
  assert_equal false, h.frozen?
40
43
 
41
-
44
+
42
45
  assert_equal Integer, Hash_X_Integer.klass_value
43
46
  assert_equal 0, h['0x1111']
44
47
  assert_equal 0, h['0x2222']
@@ -92,4 +95,47 @@ def test_voter
92
95
  end
93
96
 
94
97
 
98
+ def test_allowances # nested hash
99
+ ## allowances = Hash.of( String => Hash.of( String => Integer ) )
100
+ allowances = Hash_Hash_X_Integer.new
101
+
102
+ allowances['0x1111']['0xaaaa'] = 100
103
+ allowances['0x1111']['0xbbbb'] = 200
104
+ allowances['0x2222']['0xaaaa'] = 300
105
+ pp allowances
106
+
107
+ assert_equal 100, allowances['0x1111']['0xaaaa']
108
+ assert_equal 200, allowances['0x1111']['0xbbbb']
109
+ assert_equal 300, allowances['0x2222']['0xaaaa']
110
+
111
+ allowances['0x2222'].delete( '0xaaaa' )
112
+ assert_equal 0, allowances['0x2222']['0xaaaa']
113
+
114
+ ##############################################
115
+ ## try Hash.of convenience helper
116
+ allowances = Hash.of( String => Hash.of( String => Integer ))
117
+
118
+ allowances['0x1111']['0xaaaa'] = 100
119
+ allowances['0x1111']['0xbbbb'] = 200
120
+ allowances['0x2222']['0xaaaa'] = 300
121
+ pp allowances
122
+
123
+ assert_equal 100, allowances['0x1111']['0xaaaa']
124
+ assert_equal 200, allowances['0x1111']['0xbbbb']
125
+ assert_equal 300, allowances['0x2222']['0xaaaa']
126
+
127
+ allowances['0x2222'].delete( '0xaaaa' )
128
+ assert_equal 0, allowances['0x2222']['0xaaaa']
129
+ end
130
+
131
+
132
+ def test_hash_of
133
+ assert_equal true, Hash.is_a?( Class )
134
+
135
+ h = Hash.of( String => Integer ) # note:Hash.of returns a new ("prototype") object and NOT a class
136
+ assert_equal false, h.is_a?( Class )
137
+ assert_equal true, h.class.is_a?( Class )
138
+ end
139
+
140
+
95
141
  end # class TestHash
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safestruct
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-16 00:00:00.000000000 Z
11
+ date: 2019-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdoc