restruct 0.0.1

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,8 @@
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ Coveralls::SimpleCov::Formatter
7
+ ]
8
+ SimpleCov.start
@@ -0,0 +1,242 @@
1
+ require 'minitest_helper'
2
+
3
+ [Restruct::Hash, Restruct::MarshalHash].each do |klass|
4
+
5
+ describe klass do
6
+
7
+ let(:hash) { klass.new }
8
+
9
+ def fill(data)
10
+ data.each { |k,v| data[k] = hash.send(:serialize, v) }
11
+ redis.call 'HMSET', hash.id, *data.flatten
12
+ end
13
+
14
+ describe 'Getters' do
15
+
16
+ it '[]' do
17
+ fill a: 'x', b: 'y'
18
+
19
+ hash[:a].must_equal 'x'
20
+ hash[:b].must_equal 'y'
21
+ hash[:c].must_be_nil
22
+ end
23
+
24
+ it 'fetch' do
25
+ fill a: 'x', b: 'y'
26
+
27
+ hash.fetch(:a).must_equal 'x'
28
+ hash.fetch(:b).must_equal 'y'
29
+ hash.fetch(:c, 'z').must_equal 'z'
30
+ hash.fetch(:c) { |k| k.to_s }.must_equal 'c'
31
+
32
+ error = proc { hash.fetch(:c) }.must_raise KeyError
33
+ error.message.must_equal 'key not found: c'
34
+ end
35
+
36
+ it 'key' do
37
+ fill a: 'x', b: 'y', c: 'y'
38
+
39
+ hash.key('x').must_equal 'a'
40
+ hash.key('y').must_equal 'b'
41
+ hash.key('z').must_be_nil
42
+ end
43
+
44
+ it 'keys' do
45
+ fill a: 'x', b: 'y', c: 'z'
46
+ hash.keys.must_equal %w(a b c)
47
+ end
48
+
49
+ it 'values' do
50
+ fill a: 'x', b: 'y', c: 'z'
51
+ hash.values.must_equal %w(x y z)
52
+ end
53
+
54
+ it 'values_at' do
55
+ fill a: 'x', b: 'y', c: 'z'
56
+ hash.values_at(:a, :f, :b, :g, :c).must_equal ['x', nil, 'y', nil, 'z']
57
+ end
58
+
59
+ end
60
+
61
+ describe 'Setters' do
62
+
63
+ %w([]= store).each do |method|
64
+ it method do
65
+ fill a: 'x', b: 'y'
66
+
67
+ hash.send(method, :a, 'a').must_equal 'a'
68
+ hash.to_h.must_equal 'a' => 'a', 'b' => 'y'
69
+
70
+ hash.send(method, :c, 'z').must_equal 'z'
71
+ hash.to_h.must_equal 'a' => 'a', 'b' => 'y', 'c' => 'z'
72
+ end
73
+ end
74
+
75
+ %w(update merge!).each do |method|
76
+ it method do
77
+ fill a: 'x', b: 'y'
78
+
79
+ hash.send(method, a: 'a', c: 'z').must_equal hash
80
+ hash.to_h.must_equal 'a' => 'a', 'b' => 'y', 'c' => 'z'
81
+ end
82
+ end
83
+
84
+ it 'delete' do
85
+ fill a: 'x', b: 'y'
86
+
87
+ hash.delete(:b).must_equal 'y'
88
+ hash.to_h.must_equal 'a' => 'x'
89
+
90
+ hash.delete(:c).must_be_nil
91
+ hash.to_h.must_equal 'a' => 'x'
92
+ end
93
+
94
+ it 'delete_if' do
95
+ fill a: 'x', b: 'y'
96
+
97
+ hash.delete_if { |k,v| v == 'x' }.must_equal hash
98
+ hash.to_h.must_equal 'b' => 'y'
99
+ end
100
+
101
+ %w(keep_if select!).each do |method|
102
+ it method do
103
+ fill a: 'x', b: 'y'
104
+
105
+ hash.send(method) { |k,v| v == 'x' }.must_equal hash
106
+ hash.to_h.must_equal 'a' => 'x'
107
+ end
108
+ end
109
+
110
+ it 'clear' do
111
+ fill a: 'x', b: 'y'
112
+
113
+ hash.clear.must_equal hash
114
+ hash.must_be_empty
115
+ end
116
+
117
+ end
118
+
119
+ describe 'Info' do
120
+
121
+ %w(size count length).each do |method|
122
+ it method do
123
+ fill a: 'x', b: 'y'
124
+ hash.send(method).must_equal 2
125
+ end
126
+ end
127
+
128
+ it 'empty?' do
129
+ hash.must_be :empty?
130
+ fill a: 'x', b: 'y'
131
+ hash.wont_be :empty?
132
+ end
133
+
134
+ %w(key? has_key?).each do |method|
135
+ it method do
136
+ fill a: 'x', b: 'y'
137
+
138
+ assert hash.send(method, :a)
139
+ refute hash.send(method, :c)
140
+ end
141
+ end
142
+
143
+ %w(value? has_value?).each do |method|
144
+ it method do
145
+ fill a: 'x', b: 'y'
146
+
147
+ assert hash.send(method, 'x')
148
+ refute hash.send(method, 'z')
149
+ end
150
+ end
151
+
152
+ end
153
+
154
+ describe 'Transformations' do
155
+
156
+ %w(to_h to_primitive).each do |method|
157
+ it method do
158
+ fill a: 'x', b: 'y'
159
+ hash.send(method).must_equal 'a' => 'x', 'b' => 'y'
160
+ end
161
+ end
162
+
163
+ it 'merge' do
164
+ fill a: 'x', b: 'y'
165
+ hash.merge('c' => 'z', 'a' => 'a').must_equal 'a' => 'a', 'b' => 'y', 'c' => 'z'
166
+ end
167
+
168
+ it 'flatten' do
169
+ fill a: 'x', b: 'y'
170
+ hash.flatten.must_equal %w(a x b y)
171
+ end
172
+
173
+ it 'invert' do
174
+ fill a: 'x', b: 'y'
175
+ hash.invert.must_equal 'x' => 'a', 'y' => 'b'
176
+ end
177
+
178
+ end
179
+
180
+ describe 'Enumerable' do
181
+
182
+ it 'included module' do
183
+ assert Restruct::Hash.included_modules.include? Enumerable
184
+ end
185
+
186
+ %w(each each_pair).each do |method|
187
+ it method do
188
+ fill a: 'x', b: 'y'
189
+
190
+ keys = []
191
+ values = []
192
+ hash.send(method) do |k,v|
193
+ keys << k
194
+ values << v
195
+ end
196
+
197
+ keys.must_equal hash.keys
198
+ values.must_equal hash.values
199
+ end
200
+ end
201
+
202
+ it 'each_key' do
203
+ fill a: 'x', b: 'y'
204
+
205
+ keys = []
206
+ hash.each_key { |k| keys << k }
207
+
208
+ keys.must_equal hash.keys
209
+ end
210
+
211
+ it 'each_value' do
212
+ fill a: 'x', b: 'y'
213
+
214
+ values = []
215
+ hash.each_value { |v| values << v }
216
+
217
+ values.must_equal hash.values
218
+ end
219
+
220
+ end
221
+
222
+ it 'Equality' do
223
+ copy = klass.new id: hash.id
224
+ assert hash == copy
225
+ assert hash.eql? copy
226
+ refute hash.equal? copy
227
+ end
228
+
229
+ it 'Dump/Restore' do
230
+ fill a: 'x', b: 'y'
231
+
232
+ dump = hash.dump
233
+ other = klass.new
234
+ other.restore dump
235
+
236
+ other.id.wont_equal hash.id
237
+ other.to_primitive.must_equal hash.to_primitive
238
+ end
239
+
240
+ end
241
+
242
+ end
@@ -0,0 +1,48 @@
1
+ require 'minitest_helper'
2
+
3
+ describe Restruct::Id do
4
+
5
+ Id = Restruct::Id
6
+
7
+ it 'Return the namespace' do
8
+ id = Id.new 'foo'
9
+ id.must_equal 'foo'
10
+ end
11
+
12
+ it 'Prepend the namespace' do
13
+ id = Id.new 'foo'
14
+ id['bar'].must_equal 'foo:bar'
15
+ end
16
+
17
+ it 'Work in more than one level' do
18
+ id_1 = Id.new 'foo'
19
+ id_2 = Id.new id_1['bar']
20
+ id_2['baz'].must_equal 'foo:bar:baz'
21
+ end
22
+
23
+ it 'Be chainable' do
24
+ id = Id.new 'foo'
25
+ id['bar']['baz'].must_equal 'foo:bar:baz'
26
+ end
27
+
28
+ it 'Accept symbols' do
29
+ id = Id.new :foo
30
+ id[:bar].must_equal 'foo:bar'
31
+ end
32
+
33
+ it 'Accept numbers' do
34
+ id = Id.new 'foo'
35
+ id[3].must_equal 'foo:3'
36
+ end
37
+
38
+ it 'Split in sections' do
39
+ id = Id.new(:foo)[:bar][:buz]
40
+ id.sections.must_equal %w(foo bar buz)
41
+ end
42
+
43
+ it 'Customize separator' do
44
+ id = Id.new('foo', '|')['bar']['buz']
45
+ id.must_equal 'foo|bar|buz'
46
+ end
47
+
48
+ end
@@ -0,0 +1,21 @@
1
+ require 'coverage_helper'
2
+ require 'restruct'
3
+ require 'minitest/autorun'
4
+ require 'turn'
5
+ require 'pry-nav'
6
+
7
+ Turn.config do |c|
8
+ c.format = :pretty
9
+ c.natural = true
10
+ c.ansi = true
11
+ end
12
+
13
+ class Minitest::Spec
14
+ def redis
15
+ Restruct.redis
16
+ end
17
+
18
+ after do
19
+ redis.call('KEYS', Restruct::Id.new(:restruct)['*']).each { |k| redis.call 'DEL', k }
20
+ end
21
+ end
@@ -0,0 +1,205 @@
1
+ require 'minitest_helper'
2
+
3
+ class Counter < Restruct::Structure
4
+ def current
5
+ (redis.call('GET', id) || 0).to_i
6
+ end
7
+ alias_method :to_primitive, :current
8
+
9
+ def incr
10
+ redis.call 'SET', id, current + 1
11
+ self
12
+ end
13
+ end
14
+
15
+ CounterHash = Restruct::NestedHash.new(Counter)
16
+
17
+
18
+ describe Restruct::NestedHash do
19
+
20
+ let(:hash) { CounterHash.new }
21
+
22
+ describe 'Getters' do
23
+
24
+ it '[]' do
25
+ hash[:a].current.must_equal 0
26
+ end
27
+
28
+ it 'fetch' do
29
+ hash[:a].incr
30
+
31
+ hash.fetch(:a).current.must_equal 1
32
+
33
+ error = proc { hash.fetch(:c) }.must_raise KeyError
34
+ error.message.must_equal 'key not found: c'
35
+ end
36
+
37
+ it 'keys' do
38
+ hash[:a].incr
39
+ hash[:b].incr
40
+
41
+ hash.keys.must_equal %w(a b)
42
+ end
43
+
44
+ it 'values' do
45
+ hash[:a].incr.incr
46
+ hash[:b].incr
47
+
48
+ hash.values.map(&:current).must_equal [2, 1]
49
+ end
50
+
51
+ it 'values_at' do
52
+ hash[:a].incr.incr
53
+ hash[:b].incr
54
+
55
+ hash.values_at(:a, :f, :b, :g).map(&:current).must_equal [2, 0, 1, 0]
56
+ end
57
+
58
+ end
59
+
60
+ describe 'Setters' do
61
+
62
+ it 'delete' do
63
+ hash[:a].incr.incr
64
+ hash[:b].incr
65
+
66
+ hash.delete(:a)
67
+
68
+ hash.keys.must_equal %w(b)
69
+ end
70
+
71
+ it 'delete_if' do
72
+ hash[:a].incr.incr
73
+ hash[:b].incr
74
+
75
+ hash.delete_if { |k,v| v.current > 1 }.must_equal hash
76
+ hash.keys.must_equal %w(b)
77
+ end
78
+
79
+ %w(keep_if select!).each do |method|
80
+ it method do
81
+ hash[:a].incr.incr
82
+ hash[:b].incr
83
+
84
+ hash.send(method) { |k,v| v.current > 1 }.must_equal hash
85
+ hash.keys.must_equal %w(a)
86
+ end
87
+ end
88
+
89
+ it 'clear' do
90
+ hash[:a].incr.incr
91
+ hash[:b].incr
92
+
93
+ hash.clear.must_equal hash
94
+ hash.must_be_empty
95
+ end
96
+
97
+ end
98
+
99
+ describe 'Info' do
100
+
101
+ %w(size count length).each do |method|
102
+ it method do
103
+ hash[:a].incr.incr
104
+ hash[:b].incr
105
+
106
+ hash.send(method).must_equal 2
107
+ end
108
+ end
109
+
110
+ it 'empty?' do
111
+ hash.must_be :empty?
112
+ hash[:a].incr
113
+ hash.wont_be :empty?
114
+ end
115
+
116
+ %w(key? has_key?).each do |method|
117
+ it method do
118
+ hash[:a].incr.incr
119
+ hash[:b].incr
120
+
121
+ assert hash.send(method, :a)
122
+ refute hash.send(method, :c)
123
+ end
124
+ end
125
+
126
+ end
127
+
128
+ describe 'Transformations' do
129
+
130
+ %w(to_h to_primitive).each do |method|
131
+ it method do
132
+ hash[:a].incr.incr
133
+ hash[:b].incr
134
+
135
+ hash.send(method).must_equal 'a' => 2, 'b' => 1
136
+ end
137
+ end
138
+
139
+ end
140
+
141
+ describe 'Enumerable' do
142
+
143
+ it 'included module' do
144
+ assert Restruct::Hash.included_modules.include? Enumerable
145
+ end
146
+
147
+ %w(each each_pair).each do |method|
148
+ it method do
149
+ hash[:a].incr.incr
150
+ hash[:b].incr
151
+
152
+ keys = []
153
+ values = []
154
+ hash.send(method) do |k,v|
155
+ keys << k
156
+ values << v
157
+ end
158
+
159
+ keys.must_equal hash.keys
160
+ values.must_equal hash.values
161
+ end
162
+ end
163
+
164
+ it 'each_key' do
165
+ hash[:a].incr.incr
166
+ hash[:b].incr
167
+
168
+ keys = []
169
+ hash.each_key { |k| keys << k }
170
+
171
+ keys.must_equal hash.keys
172
+ end
173
+
174
+ it 'each_value' do
175
+ hash[:a].incr.incr
176
+ hash[:b].incr
177
+
178
+ values = []
179
+ hash.each_value { |v| values << v }
180
+
181
+ values.must_equal hash.values
182
+ end
183
+
184
+ end
185
+
186
+ it 'Equality' do
187
+ copy = CounterHash.new id: hash.id
188
+ assert hash == copy
189
+ assert hash.eql? copy
190
+ refute hash.equal? copy
191
+ end
192
+
193
+ it 'Dump/Restore' do
194
+ hash[:a].incr.incr
195
+ hash[:b].incr
196
+
197
+ dump = hash.dump
198
+ other = CounterHash.new
199
+ other.restore dump
200
+
201
+ other.id.wont_equal hash.id
202
+ other.to_primitive.must_equal hash.to_primitive
203
+ end
204
+
205
+ end