safestruct 1.0.0 → 1.1.0

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: 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