mock_redis 0.5.5 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +3 -0
- data/README.md +3 -4
- data/lib/mock_redis/database.rb +2 -0
- data/lib/mock_redis/sort_method.rb +82 -0
- data/lib/mock_redis/version.rb +1 -1
- data/spec/commands/setbit_spec.rb +2 -2
- data/spec/commands/sort_list_spec.rb +21 -0
- data/spec/commands/sort_set_spec.rb +21 -0
- data/spec/commands/sort_zset_spec.rb +21 -0
- data/spec/support/shared_examples/sorts_enumerables.rb +56 -0
- metadata +11 -2
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -51,6 +51,9 @@ necessary exceptions.
|
|
51
51
|
|
52
52
|
* `#info` just returns canned values; they don't update over time.
|
53
53
|
|
54
|
+
* `#sort` supports ascending and descending sort. `ALPHA` sort is not yet
|
55
|
+
supported.
|
56
|
+
|
54
57
|
## Unsupported Commands
|
55
58
|
|
56
59
|
Some stuff, we just can't do with a single Ruby object in a single
|
@@ -79,10 +82,6 @@ please submit a pull request with your (tested!) implementation.
|
|
79
82
|
* `#config(:get|:set|:resetstat)` isn't done. They can just return
|
80
83
|
canned values.
|
81
84
|
|
82
|
-
* `#sort` isn't done. We just haven't gotten to it yet. The input
|
83
|
-
validation will be a pain in the butt, but other than that, it
|
84
|
-
shouldn't be too bad.
|
85
|
-
|
86
85
|
## Running the Tests
|
87
86
|
|
88
87
|
If you want to work on this, you'll probably want to run the
|
data/lib/mock_redis/database.rb
CHANGED
@@ -5,6 +5,7 @@ require 'mock_redis/list_methods'
|
|
5
5
|
require 'mock_redis/set_methods'
|
6
6
|
require 'mock_redis/string_methods'
|
7
7
|
require 'mock_redis/zset_methods'
|
8
|
+
require 'mock_redis/sort_method'
|
8
9
|
|
9
10
|
class MockRedis
|
10
11
|
class Database
|
@@ -13,6 +14,7 @@ class MockRedis
|
|
13
14
|
include SetMethods
|
14
15
|
include StringMethods
|
15
16
|
include ZsetMethods
|
17
|
+
include SortMethod
|
16
18
|
|
17
19
|
attr_reader :data, :expire_times
|
18
20
|
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'mock_redis/assertions'
|
2
|
+
|
3
|
+
class MockRedis
|
4
|
+
module SortMethod
|
5
|
+
include Assertions
|
6
|
+
|
7
|
+
def sort(key, options={})
|
8
|
+
return [] if key.nil?
|
9
|
+
|
10
|
+
enumerable = data[key]
|
11
|
+
|
12
|
+
return [] if enumerable.nil?
|
13
|
+
|
14
|
+
by = options[:by]
|
15
|
+
limit = options[:limit] || []
|
16
|
+
store = options[:store]
|
17
|
+
get_patterns = Array(options[:get])
|
18
|
+
order = options[:order] || "ASC"
|
19
|
+
direction = order.split.first
|
20
|
+
|
21
|
+
projected = project(enumerable, by, get_patterns)
|
22
|
+
sorted = sort_by(projected, direction)
|
23
|
+
sliced = slice(sorted, limit)
|
24
|
+
|
25
|
+
store ? rpush(store, sliced) : sliced
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
ASCENDING_SORT = Proc.new { |a, b| a.first <=> b.first }
|
31
|
+
DESCENDING_SORT = Proc.new { |a, b| b.first <=> a.first }
|
32
|
+
|
33
|
+
def project(enumerable, by, get_patterns)
|
34
|
+
enumerable.map do |*elements|
|
35
|
+
element = elements.last
|
36
|
+
weight = by ? lookup_from_pattern(by, element) : element
|
37
|
+
value = element
|
38
|
+
|
39
|
+
if get_patterns.length > 0
|
40
|
+
value = get_patterns.map do |pattern|
|
41
|
+
pattern == "#" ? element : lookup_from_pattern(pattern, element)
|
42
|
+
end
|
43
|
+
value = value.first if value.length == 1
|
44
|
+
end
|
45
|
+
|
46
|
+
[weight, value]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def sort_by(projected, direction)
|
51
|
+
sorter =
|
52
|
+
case direction.upcase
|
53
|
+
when "DESC"
|
54
|
+
DESCENDING_SORT
|
55
|
+
when "ASC", "ALPHA"
|
56
|
+
ASCENDING_SORT
|
57
|
+
else
|
58
|
+
raise "Invalid direction '#{direction}'"
|
59
|
+
end
|
60
|
+
|
61
|
+
projected.sort(&sorter).map(&:last)
|
62
|
+
end
|
63
|
+
|
64
|
+
def slice(sorted, limit)
|
65
|
+
skip = limit.first || 0
|
66
|
+
take = limit.last || sorted.length
|
67
|
+
|
68
|
+
sorted[skip...(skip + take)] || sorted
|
69
|
+
end
|
70
|
+
|
71
|
+
def lookup_from_pattern(pattern, element)
|
72
|
+
key = pattern.sub('*', element)
|
73
|
+
|
74
|
+
if (hash_parts = key.split('->')).length > 1
|
75
|
+
hget hash_parts.first, hash_parts.last
|
76
|
+
else
|
77
|
+
get key
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
data/lib/mock_redis/version.rb
CHANGED
@@ -21,7 +21,7 @@ describe "#setbit(key, offset)" do
|
|
21
21
|
|
22
22
|
it "does the right thing with multibyte characters" do
|
23
23
|
@redises.set(@key, "€99.94") # the euro sign is 3 bytes wide in UTF-8
|
24
|
-
|
24
|
+
@redises.setbit(@key, 63, 1).should == 0
|
25
25
|
@redises.get(@key).should == "€99.95"
|
26
26
|
end
|
27
27
|
|
@@ -43,4 +43,4 @@ describe "#setbit(key, offset)" do
|
|
43
43
|
|
44
44
|
it_should_behave_like "a string-only command"
|
45
45
|
end
|
46
|
-
|
46
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#sort(key, options)' do
|
4
|
+
before do
|
5
|
+
@key = "mock-redis-test:list_sort"
|
6
|
+
|
7
|
+
@redises.rpush(@key, '1')
|
8
|
+
@redises.rpush(@key, '2')
|
9
|
+
|
10
|
+
@redises.set('mock-redis-test:values_1', 'a')
|
11
|
+
@redises.set('mock-redis-test:values_2', 'b')
|
12
|
+
|
13
|
+
@redises.set('mock-redis-test:weight_1', '2')
|
14
|
+
@redises.set('mock-redis-test:weight_2', '1')
|
15
|
+
|
16
|
+
@redises.hset('mock-redis-test:hash_1', 'key', 'x')
|
17
|
+
@redises.hset('mock-redis-test:hash_2', 'key', 'y')
|
18
|
+
end
|
19
|
+
|
20
|
+
it_should_behave_like "a sortable"
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#sort(key, options)' do
|
4
|
+
before do
|
5
|
+
@key = "mock-redis-test:set_sort"
|
6
|
+
|
7
|
+
@redises.sadd(@key, '1')
|
8
|
+
@redises.sadd(@key, '2')
|
9
|
+
|
10
|
+
@redises.set('mock-redis-test:values_1', 'a')
|
11
|
+
@redises.set('mock-redis-test:values_2', 'b')
|
12
|
+
|
13
|
+
@redises.set('mock-redis-test:weight_1', '2')
|
14
|
+
@redises.set('mock-redis-test:weight_2', '1')
|
15
|
+
|
16
|
+
@redises.hset('mock-redis-test:hash_1', 'key', 'x')
|
17
|
+
@redises.hset('mock-redis-test:hash_2', 'key', 'y')
|
18
|
+
end
|
19
|
+
|
20
|
+
it_should_behave_like "a sortable"
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '#sort(key, options)' do
|
4
|
+
before do
|
5
|
+
@key = "mock-redis-test:zset_sort"
|
6
|
+
|
7
|
+
@redises.zadd(@key, 100, '1')
|
8
|
+
@redises.zadd(@key, 99, '2')
|
9
|
+
|
10
|
+
@redises.set('mock-redis-test:values_1', 'a')
|
11
|
+
@redises.set('mock-redis-test:values_2', 'b')
|
12
|
+
|
13
|
+
@redises.set('mock-redis-test:weight_1', '2')
|
14
|
+
@redises.set('mock-redis-test:weight_2', '1')
|
15
|
+
|
16
|
+
@redises.hset('mock-redis-test:hash_1', 'key', 'x')
|
17
|
+
@redises.hset('mock-redis-test:hash_2', 'key', 'y')
|
18
|
+
end
|
19
|
+
|
20
|
+
it_should_behave_like "a sortable"
|
21
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
shared_examples_for "a sortable" do
|
2
|
+
it 'returns empty array on nil' do
|
3
|
+
@redises.sort(nil).should == []
|
4
|
+
end
|
5
|
+
|
6
|
+
context 'ordering' do
|
7
|
+
it 'orders ascending by default' do
|
8
|
+
@redises.sort(@key).should == ['1', '2']
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'orders by descending when specified' do
|
12
|
+
@redises.sort(@key, :order => "DESC").should == ['2', '1']
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'projections' do
|
17
|
+
it 'projects element when :get is "#"' do
|
18
|
+
@redises.sort(@key, :get => '#').should == ['1', '2']
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'projects through a key pattern' do
|
22
|
+
@redises.sort(@key, :get => 'mock-redis-test:values_*').should == ['a', 'b']
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'projects through a key pattern and reflects element' do
|
26
|
+
@redises.sort(@key, :get => ['#', 'mock-redis-test:values_*']).should == [['1', 'a'], ['2', 'b']]
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'projects through a hash key pattern' do
|
30
|
+
@redises.sort(@key, :get => 'mock-redis-test:hash_*->key').should == ['x', 'y']
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'weights' do
|
35
|
+
it 'weights by projecting through a key pattern' do
|
36
|
+
@redises.sort(@key, :by => "mock-redis-test:weight_*").should == ['2', '1']
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'weights by projecting through a key pattern and a specific order' do
|
40
|
+
@redises.sort(@key, :order => "DESC", :by => "mock-redis-test:weight_*").should == ['1', '2']
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'limit' do
|
45
|
+
it 'only returns requested window in the enumerable' do
|
46
|
+
@redises.sort(@key, :limit => [0, 1]).should == ['1']
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'store' do
|
51
|
+
it 'stores into another key' do
|
52
|
+
@redises.sort(@key, :store => "mock-redis-test:some_bucket").should == 2
|
53
|
+
@redises.lrange("mock-redis-test:some_bucket", 0, -1).should == ['1', '2']
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mock_redis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-10-
|
13
|
+
date: 2012-10-30 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rake
|
@@ -86,6 +86,7 @@ files:
|
|
86
86
|
- lib/mock_redis/multi_db_wrapper.rb
|
87
87
|
- lib/mock_redis/pipelined_wrapper.rb
|
88
88
|
- lib/mock_redis/set_methods.rb
|
89
|
+
- lib/mock_redis/sort_method.rb
|
89
90
|
- lib/mock_redis/string_methods.rb
|
90
91
|
- lib/mock_redis/transaction_wrapper.rb
|
91
92
|
- lib/mock_redis/undef_redis_methods.rb
|
@@ -178,6 +179,9 @@ files:
|
|
178
179
|
- spec/commands/sismember_spec.rb
|
179
180
|
- spec/commands/smembers_spec.rb
|
180
181
|
- spec/commands/smove_spec.rb
|
182
|
+
- spec/commands/sort_list_spec.rb
|
183
|
+
- spec/commands/sort_set_spec.rb
|
184
|
+
- spec/commands/sort_zset_spec.rb
|
181
185
|
- spec/commands/spop_spec.rb
|
182
186
|
- spec/commands/srandmember_spec.rb
|
183
187
|
- spec/commands/srem_spec.rb
|
@@ -212,6 +216,7 @@ files:
|
|
212
216
|
- spec/support/shared_examples/only_operates_on_sets.rb
|
213
217
|
- spec/support/shared_examples/only_operates_on_strings.rb
|
214
218
|
- spec/support/shared_examples/only_operates_on_zsets.rb
|
219
|
+
- spec/support/shared_examples/sorts_enumerables.rb
|
215
220
|
- spec/transactions_spec.rb
|
216
221
|
homepage: https://github.com/causes/mock_redis
|
217
222
|
licenses: []
|
@@ -322,6 +327,9 @@ test_files:
|
|
322
327
|
- spec/commands/sismember_spec.rb
|
323
328
|
- spec/commands/smembers_spec.rb
|
324
329
|
- spec/commands/smove_spec.rb
|
330
|
+
- spec/commands/sort_list_spec.rb
|
331
|
+
- spec/commands/sort_set_spec.rb
|
332
|
+
- spec/commands/sort_zset_spec.rb
|
325
333
|
- spec/commands/spop_spec.rb
|
326
334
|
- spec/commands/srandmember_spec.rb
|
327
335
|
- spec/commands/srem_spec.rb
|
@@ -356,5 +364,6 @@ test_files:
|
|
356
364
|
- spec/support/shared_examples/only_operates_on_sets.rb
|
357
365
|
- spec/support/shared_examples/only_operates_on_strings.rb
|
358
366
|
- spec/support/shared_examples/only_operates_on_zsets.rb
|
367
|
+
- spec/support/shared_examples/sorts_enumerables.rb
|
359
368
|
- spec/transactions_spec.rb
|
360
369
|
has_rdoc:
|