mock_redis 0.5.5 → 0.6.0
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.
- 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:
|