strc 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,8 +1,13 @@
1
1
  = STRC - Super Terrible Redis Clone
2
2
 
3
- STRC is a poor attempt to make a native Ruby clone of Redis. Why would you want that? Well, who knows. Maybe you don't feel like installing Redis for some reason. Maybe you need to be able to run tests on a machine without having to install Redis. Maybe you like badly implemented clones.
3
+ STRC is a poor attempt to make a useless Ruby simulation of Redis. Why would you want that? Well, who knows. Maybe you:
4
+ * don't feel like installing Redis for some reason.
5
+ * need to be able to run tests on a machine without having to install Redis.
6
+ * like badly implemented clones.
4
7
 
5
- One thing STRC does kind of have going for it is that it's much more lazy in regards to what you give it. Since you're passing it Ruby objects, that means you could just plop any old object in as a key or a value. If that's something you're into.
8
+ I'll come out and say it, there's little reason for this to exist, and it's not really written in a fashion that is what you'd call good. It's just for shits and giggles. If that's your thing, read on.
9
+
10
+ One thing STRC does kind of have going for it is that it's much more lazy in regards to what you give it. Since you're passing it Ruby objects, that means you could just plop any old object in as a key or a value, instead of just a string. If that's something you're into.
6
11
 
7
12
  == Usage
8
13
 
@@ -41,29 +46,60 @@ Now you could start passing it commands, if they've been implemented.
41
46
  >> strc.smembers "stuff"
42
47
  => ["abc", "123"]
43
48
 
49
+ === Lists!
50
+ >> strc.rpush "poo", "abc", "xyz"
51
+ => 2
52
+ >> strc.lpush "poo", "123"
53
+ => 3
54
+ >> strc.rpop "poo"
55
+ => "xyz"
56
+ >> strc.llen "poo"
57
+ => 2
58
+
44
59
  == Command List
45
60
  Currently, the following commands are implemented:
46
61
  * get
47
62
  * set
63
+ * setnx
48
64
  * del
49
65
  * exists
66
+ * append
67
+ * decr
68
+ * decrby
69
+ * incr
70
+ * incrby
50
71
  * rename
51
72
  * renamenx
52
- * sadd
53
- * srem
54
- * sismember
55
- * smembers
56
- * scard
57
- * sinter
58
- * sinterstore
59
- * sdiff
60
- * sdiffstore
61
- * sunion
62
- * sunionstore
63
- * smove
64
- * srandmember
65
- * spop
73
+ * Sets
74
+ * sadd
75
+ * srem
76
+ * sismember
77
+ * smembers
78
+ * scard
79
+ * sinter
80
+ * sinterstore
81
+ * sdiff
82
+ * sdiffstore
83
+ * sunion
84
+ * sunionstore
85
+ * smove
86
+ * srandmember
87
+ * spop
88
+ * Lists
89
+ * lrange
90
+ * llen
91
+ * lpush
92
+ * lpushx
93
+ * lpop
94
+ * rpush
95
+ * rpushx
96
+ * rpop
97
+ * lindex
98
+ * lset
99
+ * ltrim
100
+ * rpoplpush
66
101
 
67
102
  == History
103
+ * 0.0.3 - Some list commands done.
68
104
  * 0.0.2 - Set commands done. Most general commands done.
69
105
  * 0.0.1 - Initial release. Does some basic things.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
data/lib/strc.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'set'
2
+
1
3
  class STRC
2
4
  Exception = Class.new(StandardError)
3
5
 
@@ -11,11 +13,75 @@ class STRC
11
13
  return "OK"
12
14
  end
13
15
 
16
+ # Set the value of a key only if it doesn't already exist.
17
+ def setnx(key, value)
18
+ unless exists(key)
19
+ set(key, value)
20
+ return true
21
+ end
22
+ return false
23
+ end
24
+
14
25
  # Get the value for the given key
15
26
  def get(key)
16
27
  @dict[key]
17
28
  end
18
29
 
30
+ # Append a value to a key
31
+ def append(key, value)
32
+ if exists(key)
33
+ item = get(key)
34
+ if item.class == String and value.class == String
35
+ set(key, item + value)
36
+ else
37
+ raise STRC::Exception.new "ERR Operation against a key holding the wrong kind of value"
38
+ end
39
+ else
40
+ set(key, value)
41
+ end
42
+ return get(key).length
43
+ end
44
+
45
+ # Decrement an integer
46
+ def decr(key)
47
+ decrby(key, 1)
48
+ end
49
+
50
+ # Decrement an integer by a certain amount
51
+ def decrby(key, decrement)
52
+ unless exists(key)
53
+ set(key, 0)
54
+ end
55
+ value = get(key)
56
+ if value.class == Fixnum
57
+ set(key, value - decrement)
58
+ else
59
+ raise STRC::Exception.new "ERR Operation against a key holding the wrong kind of value"
60
+ end
61
+ get(key)
62
+ end
63
+
64
+ # Increment an integer
65
+ def incr(key)
66
+ incrby(key, 1)
67
+ end
68
+
69
+ # Increment an integer by a certain amount
70
+ def incrby(key, increment)
71
+ unless exists(key)
72
+ set(key, 0)
73
+ end
74
+ value = get(key)
75
+ if value.class == Fixnum
76
+ set(key, value + increment)
77
+ else
78
+ raise STRC::Exception.new "ERR Operation against a key holding the wrong kind of value"
79
+ end
80
+ get(key)
81
+ end
82
+
83
+ # Key commands!
84
+
19
85
  # Delete a key
20
86
  def del(*keys)
21
87
  keys.each do |key|
@@ -54,22 +120,31 @@ class STRC
54
120
  end
55
121
  end
56
122
 
57
- # Set functions!
123
+ # End of key commands~
124
+
125
+ # Set commands!
58
126
 
59
127
  # Add a member to a set
60
128
  def sadd(key, *args)
61
129
  if args.length < 1
62
130
  raise STRC::Exception.new "Wrong number of arguments (1 for 2)"
63
131
  end
64
- set = smembers(key)
65
- @dict[key] = set + args
66
- return args.length
132
+ set = sget(key)
133
+ added = 0
134
+ args.each do |arg|
135
+ unless set.include?(arg)
136
+ set << arg
137
+ added += 1
138
+ end
139
+ end
140
+ @dict[key] = set
141
+ return added
67
142
  end
68
143
 
69
144
  # Remove a member from a set
70
145
  def srem(key, member)
71
146
  if sismember(key, member)
72
- @dict[key].delete_at(@dict[key].index(member))
147
+ @dict[key].delete(member)
73
148
  return true
74
149
  else
75
150
  return false
@@ -80,13 +155,13 @@ class STRC
80
155
  def sinter(*keys)
81
156
  sets = []
82
157
  keys.each do |key|
83
- sets << smembers(key)
158
+ sets << sget(key)
84
159
  end
85
160
  inter = sets.shift
86
161
  sets.each do |set|
87
162
  inter &= set
88
163
  end
89
- return inter
164
+ return inter.to_a
90
165
  end
91
166
 
92
167
  # Similar to SINTER, but stores in destination instead of returning
@@ -100,13 +175,13 @@ class STRC
100
175
  def sdiff(*keys)
101
176
  sets = []
102
177
  keys.each do |key|
103
- sets << smembers(key)
178
+ sets << sget(key)
104
179
  end
105
180
  diff = sets.shift
106
181
  sets.each do |set|
107
182
  diff -= set
108
183
  end
109
- return diff
184
+ return diff.to_a
110
185
  end
111
186
 
112
187
  # Similar to SDIFF, but stores in destination instead of returning
@@ -117,7 +192,7 @@ class STRC
117
192
 
118
193
  # Move an item from one set to another
119
194
  def smove(source, destination, member)
120
- if !sismember(source, member)
195
+ unless sismember(source, member)
121
196
  return false
122
197
  end
123
198
  srem(source, member)
@@ -129,6 +204,15 @@ class STRC
129
204
 
130
205
  # Returs a list of all unique items in the given sets
131
206
  def sunion(*keys)
207
+ sets = []
208
+ keys.each do |key|
209
+ sets << sget(key)
210
+ end
211
+ union = sets.shift
212
+ sets.each do |set|
213
+ union += set
214
+ end
215
+ return union.to_a
132
216
  end
133
217
 
134
218
  # Similar to SUNION, but stores in destination instead of returning
@@ -139,7 +223,7 @@ class STRC
139
223
 
140
224
  # Returns a random element from the set
141
225
  def srandmember(key)
142
- smembers(key).sample
226
+ sget(key).to_a.sample
143
227
  end
144
228
 
145
229
  # Randomly remove and return an item from the set
@@ -151,27 +235,136 @@ class STRC
151
235
 
152
236
  # Determine if the given value is a member of the set at key
153
237
  def sismember(key, member)
154
- set = smembers(key)
155
- return !set.index(member).nil?
238
+ set = sget(key)
239
+ return set.include?(member)
156
240
  end
157
241
 
158
242
  # Returns an array of members of the set
159
243
  def smembers(key)
244
+ sget(key).to_a
245
+ end
246
+
247
+ # Gets the length of a set
248
+ def scard(key)
249
+ set = sget(key)
250
+ return set.length
251
+ end
252
+
253
+ # Gets a set. Private
254
+ def sget(key)
160
255
  if exists(key)
161
256
  value = get(key)
162
- if value.class == Array
257
+ if value.class == Set
163
258
  return value
164
259
  else
165
- raise STRC::Exception .new "ERR Operation against a key holding the wrong kind of value"
260
+ raise STRC::Exception.new "ERR Operation against a key holding the wrong kind of value"
166
261
  end
167
262
  else
168
- return []
263
+ return Set.new
169
264
  end
170
265
  end
171
266
 
172
- # Gets the length of a set
173
- def scard(key)
174
- set = smembers(key)
175
- return set.length
267
+ # End of set commands~
268
+
269
+ # List commands!
270
+
271
+ # Gets a list. Private
272
+ def lget(key)
273
+ list = []
274
+ if exists(key)
275
+ list = get(key)
276
+ unless list.class == Array
277
+ raise STRC::Exception.new "ERR Operation against a key holding the wrong kind of value"
278
+ end
279
+ end
280
+ return list
281
+ end
282
+
283
+ # Returns elements from key in the given range
284
+ def lrange(key, start, stop)
285
+ list = lget(key)[start..stop]
286
+ return list.nil? ? [] : list
287
+ end
288
+
289
+ # Returns length of list
290
+ def llen(key)
291
+ lget(key).length
292
+ end
293
+
294
+ # Append values to a list
295
+ def rpush(key, *values)
296
+ list = lget(key)
297
+ list += values
298
+ set(key, list)
299
+ return list.length
300
+ end
301
+
302
+ # RPUSH if the list exists
303
+ def rpushx(key, *values)
304
+ if exists(key)
305
+ rpush(key, *values)
306
+ end
307
+ end
308
+
309
+ # Remove and get the last element in a list
310
+ def rpop(key)
311
+ list = lget(key)
312
+ element = list.pop
313
+ set(key, list)
314
+ return element
176
315
  end
316
+
317
+ # Prepend values to a list
318
+ def lpush(key, *values)
319
+ list = lget(key)
320
+ list = values + list
321
+ set(key, list)
322
+ return list.length
323
+ end
324
+
325
+ # LPUSH if the list exists
326
+ def lpushx(key, *values)
327
+ if exists(key)
328
+ lpush(key, *values)
329
+ end
330
+ end
331
+
332
+ # Remove and get the first element in a list
333
+ def lpop(key)
334
+ list = lget(key)
335
+ element = list.shift
336
+ set(key, list)
337
+ return element
338
+ end
339
+
340
+ # Get an element from a list by its index
341
+ def lindex(key, index)
342
+ lget(key)[index]
343
+ end
344
+
345
+ # Set value for an element at index in a list
346
+ def lset(key, index, value)
347
+ list = lget(key)
348
+ list[index] = value
349
+ set(key, list)
350
+ end
351
+
352
+ # Trim a list to the specified range
353
+ def ltrim(key, start, stop)
354
+ set(key, lrange(key, start, stop))
355
+ end
356
+
357
+ # Removes an element from the end of one list and puts it at
358
+ # the beginning of another
359
+ def rpoplpush(source, destination)
360
+ lpush(destination, rpop(source))
361
+ end
362
+
363
+ # End of list commands~
364
+
365
+ # Hash commands!
366
+
367
+ # End of hash commands~
368
+
369
+ private :sget, :lget
177
370
  end
data/strc.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{strc}
8
- s.version = "0.0.2"
8
+ s.version = "0.0.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Chris O'Neal"]
12
- s.date = %q{2011-07-14}
12
+ s.date = %q{2011-07-15}
13
13
  s.description = %q{STRC is a terrible Ruby clone of Redis}
14
14
  s.email = %q{ctoneal@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -28,6 +28,8 @@ Gem::Specification.new do |s|
28
28
  "strc.gemspec",
29
29
  "test/helper.rb",
30
30
  "test/test_basic_functions.rb",
31
+ "test/test_keys.rb",
32
+ "test/test_lists.rb",
31
33
  "test/test_sets.rb",
32
34
  "test/test_strc.rb"
33
35
  ]
@@ -39,6 +41,8 @@ Gem::Specification.new do |s|
39
41
  s.test_files = [
40
42
  "test/helper.rb",
41
43
  "test/test_basic_functions.rb",
44
+ "test/test_keys.rb",
45
+ "test/test_lists.rb",
42
46
  "test/test_sets.rb",
43
47
  "test/test_strc.rb"
44
48
  ]
@@ -28,6 +28,21 @@ class TestBasicFunctions < Test::Unit::TestCase
28
28
  end
29
29
  end
30
30
 
31
+ context "setnx" do
32
+ should "be able to set the value of a new key" do
33
+ result = @test.setnx("test", 10)
34
+ assert(result)
35
+ end
36
+
37
+ should "not set value if the key already exists" do
38
+ @test.setnx("test", 10)
39
+ result = @test.setnx("test", 50)
40
+ assert(!result)
41
+ value = @test.get("test")
42
+ assert_equal(10, value)
43
+ end
44
+ end
45
+
31
46
  context "get" do
32
47
  should "be able to get the value of a key" do
33
48
  @test.set("test_key", 15)
@@ -41,79 +56,83 @@ class TestBasicFunctions < Test::Unit::TestCase
41
56
  end
42
57
  end
43
58
 
44
- context "exists" do
45
- should "return true if the key exists" do
46
- @test.set("test", 1)
47
- assert(@test.exists("test"))
59
+ context "append" do
60
+ should "append to a string" do
61
+ @test.set("test", "Hello")
62
+ @test.append("test", " World")
63
+ value = @test.get("test")
64
+ assert_equal("Hello World", value)
48
65
  end
49
66
 
50
- should "return false if the key doesn't exist" do
51
- assert(!@test.exists("test"))
67
+ should "return the new length of the string" do
68
+ @test.set("test", "Hello")
69
+ result = @test.append("test", " World")
70
+ assert_equal("Hello World".length, result)
52
71
  end
53
- end
54
72
 
55
- context "del" do
56
- should "delete a key" do
57
- @test.set("test", 1)
58
- deleted = @test.del("test")
59
- assert_equal(1, deleted)
60
- assert(!@test.exists("test"))
73
+ should "set if key doesn't exist" do
74
+ @test.append("test", "poop")
75
+ result = @test.get("test")
76
+ assert_equal("poop", result)
61
77
  end
62
78
 
63
- should "delete multiple keys" do
64
- @test.set("test", 1)
65
- @test.set("poop", 2)
66
- @test.set("blah", 4)
67
- deleted = @test.del("test", "poop")
68
- assert_equal(2, deleted)
69
- assert(!@test.exists("test"))
70
- assert(!@test.exists("poop"))
71
- assert(@test.exists("blah"))
79
+ should "not work for non string values" do
80
+ @test.set("test", 15)
81
+ assert_raise(STRC::Exception) { @test.append("test", "poop")}
72
82
  end
73
83
  end
74
84
 
75
- context "randomkey" do
76
- should "return a random key from the database" do
77
- keys = ["test", "poop", "blah"]
78
- keys.each do |key|
79
- @test.set(key, 1)
80
- end
81
- random = @test.randomkey
82
- assert_not_nil(keys.index(random))
85
+ context "incr" do
86
+ should "increment integers" do
87
+ @test.set("poop", 10)
88
+ @test.incr("poop")
89
+ assert_equal(11, @test.get("poop"))
83
90
  end
84
- end
85
91
 
86
- context "rename" do
87
- should "rename a key" do
88
- @test.set("poop", 1)
89
- @test.rename("poop", "abc")
90
- value = @test.get("abc")
91
- assert_equal(1, value)
92
+ should "not increment other types" do
93
+ @test.set("poop", "aaa")
94
+ assert_raise(STRC::Exception) { @test.incr("poop")}
92
95
  end
93
96
 
94
- should "overwrite existing keys" do
95
- @test.set("poop", 1)
96
- @test.set("abc", 2)
97
- @test.rename("poop", "abc")
98
- value = @test.get("abc")
99
- assert_equal(1, value)
97
+ should "return new value" do
98
+ @test.set("poop", 10)
99
+ result = @test.incr("poop")
100
+ assert_equal(11, result)
100
101
  end
101
102
  end
102
103
 
103
- context "renamenx" do
104
- should "rename a key" do
105
- @test.set("poop", 1)
106
- @test.renamenx("poop", "abc")
107
- value = @test.get("abc")
108
- assert_equal(1, value)
104
+ context "incrby" do
105
+ should "be able to increment by value" do
106
+ @test.set("poop", 10)
107
+ @test.incrby("poop", 10)
108
+ assert_equal(20, @test.get("poop"))
109
109
  end
110
+ end
111
+
112
+ context "decr" do
113
+ should "decrement integers" do
114
+ @test.set("poop", 10)
115
+ @test.decr("poop")
116
+ assert_equal(9, @test.get("poop"))
117
+ end
118
+
119
+ should "not decrement other types" do
120
+ @test.set("poop", "aaa")
121
+ assert_raise(STRC::Exception) { @test.decr("poop")}
122
+ end
123
+
124
+ should "return new value" do
125
+ @test.set("poop", 10)
126
+ result = @test.decr("poop")
127
+ assert_equal(9, result)
128
+ end
129
+ end
110
130
 
111
- should "not overwrite existing keys" do
112
- @test.set("poop", 1)
113
- @test.set("abc", 2)
114
- @test.renamenx("poop", "abc")
115
- value = @test.get("abc")
116
- assert_equal(2, value)
131
+ context "decrby" do
132
+ should "be able to decrement by value" do
133
+ @test.set("poop", 10)
134
+ @test.decrby("poop", 10)
135
+ assert_equal(0, @test.get("poop"))
117
136
  end
118
137
  end
119
138
  end
data/test/test_keys.rb ADDED
@@ -0,0 +1,83 @@
1
+ require 'helper'
2
+
3
+ class TestKeys < Test::Unit::TestCase
4
+ def setup
5
+ @test = STRC.new
6
+ end
7
+
8
+ context "exists" do
9
+ should "return true if the key exists" do
10
+ @test.set("test", 1)
11
+ assert(@test.exists("test"))
12
+ end
13
+
14
+ should "return false if the key doesn't exist" do
15
+ assert(!@test.exists("test"))
16
+ end
17
+ end
18
+
19
+ context "del" do
20
+ should "delete a key" do
21
+ @test.set("test", 1)
22
+ deleted = @test.del("test")
23
+ assert_equal(1, deleted)
24
+ assert(!@test.exists("test"))
25
+ end
26
+
27
+ should "delete multiple keys" do
28
+ @test.set("test", 1)
29
+ @test.set("poop", 2)
30
+ @test.set("blah", 4)
31
+ deleted = @test.del("test", "poop")
32
+ assert_equal(2, deleted)
33
+ assert(!@test.exists("test"))
34
+ assert(!@test.exists("poop"))
35
+ assert(@test.exists("blah"))
36
+ end
37
+ end
38
+
39
+ context "randomkey" do
40
+ should "return a random key from the database" do
41
+ keys = ["test", "poop", "blah"]
42
+ keys.each do |key|
43
+ @test.set(key, 1)
44
+ end
45
+ random = @test.randomkey
46
+ assert_not_nil(keys.index(random))
47
+ end
48
+ end
49
+
50
+ context "rename" do
51
+ should "rename a key" do
52
+ @test.set("poop", 1)
53
+ @test.rename("poop", "abc")
54
+ value = @test.get("abc")
55
+ assert_equal(1, value)
56
+ end
57
+
58
+ should "overwrite existing keys" do
59
+ @test.set("poop", 1)
60
+ @test.set("abc", 2)
61
+ @test.rename("poop", "abc")
62
+ value = @test.get("abc")
63
+ assert_equal(1, value)
64
+ end
65
+ end
66
+
67
+ context "renamenx" do
68
+ should "rename a key" do
69
+ @test.set("poop", 1)
70
+ @test.renamenx("poop", "abc")
71
+ value = @test.get("abc")
72
+ assert_equal(1, value)
73
+ end
74
+
75
+ should "not overwrite existing keys" do
76
+ @test.set("poop", 1)
77
+ @test.set("abc", 2)
78
+ @test.renamenx("poop", "abc")
79
+ value = @test.get("abc")
80
+ assert_equal(2, value)
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,151 @@
1
+ require 'helper'
2
+
3
+ class TestLists < Test::Unit::TestCase
4
+ def setup
5
+ @test = STRC.new
6
+ @test.rpush("poop", "a", "b", "c")
7
+ end
8
+
9
+ context "lrange" do
10
+ should "return a range of elements" do
11
+ result = @test.lrange("poop", 1, 2)
12
+ assert_equal(["b", "c"], result)
13
+ end
14
+
15
+ should "be zero based" do
16
+ result = @test.lrange("poop", 0, 0)
17
+ assert_equal(["a"], result)
18
+ end
19
+
20
+ should "work with negative numbers" do
21
+ result = @test.lrange("poop", -3, 2)
22
+ assert_equal(["a", "b", "c"], result)
23
+ end
24
+
25
+ should "indexing out should give an empty list" do
26
+ result = @test.lrange("poop", 5, 10)
27
+ assert_equal([], result)
28
+ end
29
+ end
30
+
31
+ context "llen" do
32
+ should "return length of the list" do
33
+ result = @test.llen("poop")
34
+ assert_equal(3, result)
35
+ end
36
+ end
37
+
38
+ context "rpush" do
39
+ should "create a new list" do
40
+ @test.rpush("asdf", "abc")
41
+ assert(@test.exists("asdf"))
42
+ assert_equal(["abc"], @test.lrange("asdf", 0, -1))
43
+ end
44
+
45
+ should "push onto the end of existing lists" do
46
+ @test.rpush("poop", "d", "e")
47
+ assert_equal(["a", "b", "c", "d", "e"], @test.lrange("poop", 0, -1))
48
+ end
49
+
50
+ should "return new length of list" do
51
+ len = @test.rpush("poop", "d", "e")
52
+ assert_equal(@test.lrange("poop", 0, -1).length, len)
53
+ end
54
+ end
55
+
56
+ context "rpushx" do
57
+ should "not be able to create a new list" do
58
+ @test.rpushx("asdf", "abc")
59
+ assert(!@test.exists("asdf"))
60
+ end
61
+ end
62
+
63
+ context "rpop" do
64
+ should "return the last element in the list" do
65
+ element = @test.rpop("poop")
66
+ assert_equal("c", element)
67
+ end
68
+
69
+ should "remove the last element in the list" do
70
+ @test.rpop("poop")
71
+ assert_equal(["a", "b"], @test.lrange("poop", 0, -1))
72
+ end
73
+ end
74
+
75
+ context "lpush" do
76
+ should "create a new list" do
77
+ @test.lpush("asdf", "abc")
78
+ assert(@test.exists("asdf"))
79
+ assert_equal(["abc"], @test.lrange("asdf", 0, -1))
80
+ end
81
+
82
+ should "push onto the beginning of existing lists" do
83
+ @test.lpush("poop", "d", "e")
84
+ assert_equal(["d", "e", "a", "b", "c"], @test.lrange("poop", 0, -1))
85
+ end
86
+
87
+ should "return new length of list" do
88
+ len = @test.lpush("poop", "d", "e")
89
+ assert_equal(@test.lrange("poop", 0, -1).length, len)
90
+ end
91
+ end
92
+
93
+ context "lpushx" do
94
+ should "not be able to create a new list" do
95
+ @test.lpushx("asdf", "abc")
96
+ assert(!@test.exists("asdf"))
97
+ end
98
+ end
99
+
100
+ context "lpop" do
101
+ should "return the first element in the list" do
102
+ element = @test.lpop("poop")
103
+ assert_equal("a", element)
104
+ end
105
+
106
+ should "remove the first element in the list" do
107
+ @test.lpop("poop")
108
+ assert_equal(["b", "c"], @test.lrange("poop", 0, -1))
109
+ end
110
+ end
111
+
112
+ context "lindex" do
113
+ should "return value at index" do
114
+ result = @test.lindex("poop", 1)
115
+ assert_equal("b", result)
116
+ end
117
+
118
+ should "work with negative numbers" do
119
+ result = @test.lindex("poop", -2)
120
+ assert_equal("b", result)
121
+ end
122
+
123
+ should "return nil for out of range" do
124
+ result = @test.lindex("poop", 10)
125
+ assert_nil(result)
126
+ end
127
+ end
128
+
129
+ context "lset" do
130
+ should "set value at index" do
131
+ @test.lset("poop", 2, "test")
132
+ assert_equal("test", @test.lindex("poop", 2))
133
+ end
134
+ end
135
+
136
+ context "ltrim" do
137
+ should "trim the list to the range" do
138
+ @test.ltrim("poop", 1, -1)
139
+ assert_equal(["b", "c"], @test.lrange("poop", 0, -1))
140
+ end
141
+ end
142
+
143
+ context "rpoplpush" do
144
+ should "take an element from the end of one list and put it on the front of another" do
145
+ @test.lpush("asdf", "123")
146
+ @test.rpoplpush("poop", "asdf")
147
+ assert_equal(["a", "b"], @test.lrange("poop", 0, -1))
148
+ assert_equal(["c", "123"], @test.lrange("asdf", 0, -1))
149
+ end
150
+ end
151
+ end
data/test/test_sets.rb CHANGED
@@ -129,6 +129,27 @@ class TestSets < Test::Unit::TestCase
129
129
  end
130
130
  end
131
131
 
132
+ context "sunion" do
133
+ should "give all unique members of given sets" do
134
+ @test.sadd("set1", "a", "b", "c", "d")
135
+ @test.sadd("set2", "c")
136
+ @test.sadd("set3", "a", "c", "e")
137
+ result = @test.sunion("set1", "set2", "set3")
138
+ assert_equal(["a", "b", "c", "d", "e"], result)
139
+ end
140
+ end
141
+
142
+ context "sunionstore" do
143
+ should "work like sunion, but store in destination" do
144
+ @test.sadd("set1", "a", "b", "c", "d")
145
+ @test.sadd("set2", "c")
146
+ @test.sadd("set3", "a", "c", "e")
147
+ @test.sunionstore("new", "set1", "set2", "set3")
148
+ result = @test.smembers("new")
149
+ assert_equal(["a", "b", "c", "d", "e"], result)
150
+ end
151
+ end
152
+
132
153
  context "smove" do
133
154
  should "move an item from one set to another" do
134
155
  @test.sadd("set1", "one" ,"two")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-07-14 00:00:00.000000000 -05:00
12
+ date: 2011-07-15 00:00:00.000000000 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: shoulda
17
- requirement: &9687480 !ruby/object:Gem::Requirement
17
+ requirement: &9732852 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *9687480
25
+ version_requirements: *9732852
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: bundler
28
- requirement: &9686856 !ruby/object:Gem::Requirement
28
+ requirement: &9732216 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 1.0.0
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *9686856
36
+ version_requirements: *9732216
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: jeweler
39
- requirement: &9685920 !ruby/object:Gem::Requirement
39
+ requirement: &9726516 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 1.5.2
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *9685920
47
+ version_requirements: *9726516
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rcov
50
- requirement: &9644496 !ruby/object:Gem::Requirement
50
+ requirement: &9726036 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,7 +55,7 @@ dependencies:
55
55
  version: '0'
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *9644496
58
+ version_requirements: *9726036
59
59
  description: STRC is a terrible Ruby clone of Redis
60
60
  email: ctoneal@gmail.com
61
61
  executables: []
@@ -75,6 +75,8 @@ files:
75
75
  - strc.gemspec
76
76
  - test/helper.rb
77
77
  - test/test_basic_functions.rb
78
+ - test/test_keys.rb
79
+ - test/test_lists.rb
78
80
  - test/test_sets.rb
79
81
  - test/test_strc.rb
80
82
  has_rdoc: true
@@ -93,7 +95,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
93
95
  version: '0'
94
96
  segments:
95
97
  - 0
96
- hash: 876690863
98
+ hash: 230414097
97
99
  required_rubygems_version: !ruby/object:Gem::Requirement
98
100
  none: false
99
101
  requirements:
@@ -109,5 +111,7 @@ summary: Super Terrible Redis Clone
109
111
  test_files:
110
112
  - test/helper.rb
111
113
  - test/test_basic_functions.rb
114
+ - test/test_keys.rb
115
+ - test/test_lists.rb
112
116
  - test/test_sets.rb
113
117
  - test/test_strc.rb