restruct 0.0.1

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