mock_redis 0.4.1 → 0.5.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.
Files changed (54) hide show
  1. data/CHANGELOG.md +11 -0
  2. data/Gemfile +1 -1
  3. data/lib/mock_redis/assertions.rb +2 -2
  4. data/lib/mock_redis/database.rb +16 -8
  5. data/lib/mock_redis/expire_wrapper.rb +2 -2
  6. data/lib/mock_redis/hash_methods.rb +12 -6
  7. data/lib/mock_redis/list_methods.rb +10 -8
  8. data/lib/mock_redis/multi_db_wrapper.rb +3 -3
  9. data/lib/mock_redis/pipelined_wrapper.rb +45 -0
  10. data/lib/mock_redis/set_methods.rb +14 -5
  11. data/lib/mock_redis/string_methods.rb +6 -6
  12. data/lib/mock_redis/transaction_wrapper.rb +13 -8
  13. data/lib/mock_redis/version.rb +1 -1
  14. data/lib/mock_redis/zset_methods.rb +52 -22
  15. data/lib/mock_redis.rb +92 -5
  16. data/mock_redis.gemspec +1 -1
  17. data/spec/cloning_spec.rb +1 -1
  18. data/spec/commands/blpop_spec.rb +3 -3
  19. data/spec/commands/brpop_spec.rb +3 -3
  20. data/spec/commands/brpoplpush_spec.rb +3 -3
  21. data/spec/commands/hdel_spec.rb +5 -0
  22. data/spec/commands/lpush_spec.rb +7 -0
  23. data/spec/commands/mapped_hmset_spec.rb +7 -1
  24. data/spec/commands/move_spec.rb +2 -2
  25. data/spec/commands/msetnx_spec.rb +2 -2
  26. data/spec/commands/pipelined_spec.rb +12 -0
  27. data/spec/commands/rename_spec.rb +7 -0
  28. data/spec/commands/renamenx_spec.rb +7 -0
  29. data/spec/commands/rpush_spec.rb +7 -0
  30. data/spec/commands/sadd_spec.rb +1 -1
  31. data/spec/commands/sdiff_spec.rb +1 -1
  32. data/spec/commands/sdiffstore_spec.rb +3 -3
  33. data/spec/commands/sinterstore_spec.rb +2 -2
  34. data/spec/commands/smembers_spec.rb +4 -4
  35. data/spec/commands/srem_spec.rb +5 -0
  36. data/spec/commands/sunion_spec.rb +2 -2
  37. data/spec/commands/sunionstore_spec.rb +3 -3
  38. data/spec/commands/watch_spec.rb +2 -2
  39. data/spec/commands/zadd_spec.rb +6 -1
  40. data/spec/commands/zcount_spec.rb +8 -0
  41. data/spec/commands/zincrby_spec.rb +4 -4
  42. data/spec/commands/zinterstore_spec.rb +7 -7
  43. data/spec/commands/zrange_spec.rb +6 -2
  44. data/spec/commands/zrangebyscore_spec.rb +2 -2
  45. data/spec/commands/zrem_spec.rb +5 -0
  46. data/spec/commands/zrevrange_spec.rb +2 -2
  47. data/spec/commands/zrevrangebyscore_spec.rb +2 -2
  48. data/spec/commands/zscore_spec.rb +2 -2
  49. data/spec/commands/zunionstore_spec.rb +9 -9
  50. data/spec/mock_redis_spec.rb +21 -0
  51. data/spec/support/redis_multiplexer.rb +23 -19
  52. data/spec/transactions_spec.rb +17 -0
  53. metadata +67 -84
  54. data/lib/mock_redis/distributed.rb +0 -6
@@ -19,12 +19,12 @@ describe "#zrevrange(key, start, stop [, :with_scores => true])" do
19
19
 
20
20
  it "returns the scores when :with_scores is specified" do
21
21
  @redises.zrevrange(@key, 2, 3, :with_scores => true).
22
- should == ["Adams", "2", "Washington", "1"]
22
+ should == [["Adams", 2.0], ["Washington", 1.0]]
23
23
  end
24
24
 
25
25
  it "returns the scores when :withscores is specified" do
26
26
  @redises.zrevrange(@key, 2, 3, :withscores => true).
27
- should == ["Adams", "2", "Washington", "1"]
27
+ should == [["Adams", 2.0], ["Washington", 1.0]]
28
28
  end
29
29
 
30
30
  it_should_behave_like "a zset-only command"
@@ -15,12 +15,12 @@ describe "#zrevrangebyscore(key, start, stop [:with_scores => true] [:limit => [
15
15
 
16
16
  it "returns the scores when :with_scores is specified" do
17
17
  @redises.zrevrangebyscore(@key, 4, 3, :with_scores => true).
18
- should == %w[Madison 4 Jefferson 3]
18
+ should == [["Madison", 4.0], ["Jefferson", 3.0]]
19
19
  end
20
20
 
21
21
  it "returns the scores when :withscores is specified" do
22
22
  @redises.zrevrangebyscore(@key, 4, 3, :withscores => true).
23
- should == %w[Madison 4 Jefferson 3]
23
+ should == [["Madison", 4.0], ["Jefferson", 3.0]]
24
24
  end
25
25
 
26
26
  it "treats +inf as positive infinity" do
@@ -5,13 +5,13 @@ describe "#zscore(key, member)" do
5
5
 
6
6
  it "returns the score as a string" do
7
7
  @redises.zadd(@key, 0.25, 'foo').should be_true
8
- @redises.zscore(@key, 'foo').should == "0.25"
8
+ @redises.zscore(@key, 'foo').should == 0.25
9
9
  end
10
10
 
11
11
  it "handles integer members correctly" do
12
12
  member = 11
13
13
  @redises.zadd(@key, 0.25, member).should be_true
14
- @redises.zscore(@key, member).should == "0.25"
14
+ @redises.zscore(@key, member).should == 0.25
15
15
  end
16
16
 
17
17
  it "returns nil if member is not present in the set" do
@@ -24,7 +24,7 @@ describe "#zunionstore(destination, keys, [:weights => [w,w,], [:aggregate => :s
24
24
  it "sums the members' scores by default" do
25
25
  @redises.zunionstore(@dest, [@set1, @set2, @set3])
26
26
  @redises.zrange(@dest, 0, -1, :with_scores => true).should ==
27
- %w[one 3 three 3 two 4]
27
+ [["one", 3.0], ["three", 3.0], ["two", 4.0]]
28
28
  end
29
29
 
30
30
  it "removes existing elements in destination" do
@@ -32,7 +32,7 @@ describe "#zunionstore(destination, keys, [:weights => [w,w,], [:aggregate => :s
32
32
 
33
33
  @redises.zunionstore(@dest, [@set1])
34
34
  @redises.zrange(@dest, 0, -1, :with_scores => true).should ==
35
- %w[one 1]
35
+ [["one", 1.0]]
36
36
  end
37
37
 
38
38
  it "raises an error if keys is empty" do
@@ -45,7 +45,7 @@ describe "#zunionstore(destination, keys, [:weights => [w,w,], [:aggregate => :s
45
45
  it "multiplies the scores by the weights while aggregating" do
46
46
  @redises.zunionstore(@dest, [@set1, @set2, @set3], :weights => [2, 3, 5])
47
47
  @redises.zrange(@dest, 0, -1, :with_scores => true).should ==
48
- %w[one 10 three 15 two 16]
48
+ [["one", 10.0], ["three", 15.0], ["two", 16.0]]
49
49
  end
50
50
 
51
51
  it "raises an error if the number of weights != the number of keys" do
@@ -69,30 +69,30 @@ describe "#zunionstore(destination, keys, [:weights => [w,w,], [:aggregate => :s
69
69
  it "aggregates scores with min when :aggregate => :min is specified" do
70
70
  @redises.zunionstore(@dest, [@bigs, @smalls], :aggregate => :min)
71
71
  @redises.zrange(@dest, 0, -1, :with_scores => true).should ==
72
- %w[bert 1 ernie 2]
72
+ [["bert", 1.0], ["ernie", 2.0]]
73
73
  end
74
74
 
75
75
  it "aggregates scores with max when :aggregate => :max is specified" do
76
76
  @redises.zunionstore(@dest, [@bigs, @smalls], :aggregate => :max)
77
77
  @redises.zrange(@dest, 0, -1, :with_scores => true).should ==
78
- %w[bert 100 ernie 200]
78
+ [["bert", 100.0], ["ernie", 200.0]]
79
79
  end
80
80
 
81
81
  it "ignores scores for missing members" do
82
82
  @redises.zadd(@smalls, 3, 'grover')
83
83
  @redises.zunionstore(@dest, [@bigs, @smalls], :aggregate => :min)
84
- @redises.zscore(@dest, 'grover').should == '3'
84
+ @redises.zscore(@dest, 'grover').should == 3.0
85
85
 
86
86
  @redises.zunionstore(@dest, [@bigs, @smalls], :aggregate => :max)
87
- @redises.zscore(@dest, 'grover').should == '3'
87
+ @redises.zscore(@dest, 'grover').should == 3.0
88
88
  end
89
89
 
90
90
  it "allows 'min', 'MIN', etc. as aliases for :min" do
91
91
  @redises.zunionstore(@dest, [@bigs, @smalls], :aggregate => 'min')
92
- @redises.zscore(@dest, 'bert').should == '1'
92
+ @redises.zscore(@dest, 'bert').should == 1.0
93
93
 
94
94
  @redises.zunionstore(@dest, [@bigs, @smalls], :aggregate => 'MIN')
95
- @redises.zscore(@dest, 'bert').should == '1'
95
+ @redises.zscore(@dest, 'bert').should == 1.0
96
96
  end
97
97
 
98
98
  it "raises an error for unknown aggregation function" do
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe MockRedis do
4
+
5
+ context "with passed options" do
6
+ before do
7
+ @mock = MockRedis.new(:url => "redis://127.0.0.1:6379/1")
8
+ end
9
+
10
+ it "should correctly parse options" do
11
+ @mock.host.should == "127.0.0.1"
12
+ @mock.port.should == 6379
13
+ @mock.db.should == 1
14
+ end
15
+
16
+ it "should have an id equal to redis url" do
17
+ @mock.id.should == "redis://127.0.0.1:6379/1"
18
+ end
19
+ end
20
+
21
+ end
@@ -11,13 +11,30 @@ class RedisMultiplexer < BlankSlate
11
11
  end
12
12
 
13
13
  def method_missing(method, *args, &blk)
14
- mock_retval, mock_error = catch_errors { @mock_redis.send(method, *args, &blk) }
15
- real_retval, real_error = catch_errors { @real_redis.send(method, *args, &blk) }
14
+ # if we're in a Redis command that accepts a block, and we execute more redis commands, ONLY execute them
15
+ # on the Redis implementation that the block came from.
16
+ # e.g. if a pipelined command is started on a MockRedis object, DON'T send commands inside the pipelined block
17
+ # to the real Redis object, as that one WON'T be inside a pipelined command, and we'll see weird behaviour
18
+ if blk
19
+ @in_mock_block = true
20
+ @in_redis_block = false
21
+ end
22
+ mock_retval, mock_error = catch_errors { @in_redis_block ? :no_op : @mock_redis.send(method, *args, &blk) }
23
+
24
+ if blk
25
+ @in_mock_block = false
26
+ @in_redis_block = true
27
+ end
28
+ real_retval, real_error = catch_errors { @in_mock_block ? :no_op : @real_redis.send(method, *args, &blk) }
16
29
 
17
- mock_retval = handle_special_cases(method, mock_retval)
18
- real_retval = handle_special_cases(method, real_retval)
30
+ if blk
31
+ @in_mock_block = false
32
+ @in_redis_block = false
33
+ end
19
34
 
20
- if (!equalish?(mock_retval, real_retval) && !mock_error && !real_error)
35
+ if (mock_retval == :no_op || real_retval == :no_op)
36
+ # ignore, we were inside a block (like pipelined)
37
+ elsif (!equalish?(mock_retval, real_retval) && !mock_error && !real_error)
21
38
  # no exceptions, just different behavior
22
39
  raise MismatchedResponse,
23
40
  "Mock failure: responses not equal.\n" +
@@ -49,7 +66,7 @@ class RedisMultiplexer < BlankSlate
49
66
  if a == b
50
67
  true
51
68
  elsif a.is_a?(Array) && b.is_a?(Array)
52
- a.zip(b).all? {|(x,y)| equalish?(x,y)}
69
+ a.collect(&:to_s).sort == b.collect(&:to_s).sort
53
70
  elsif a.is_a?(Exception) && b.is_a?(Exception)
54
71
  a.class == b.class && a.message == b.message
55
72
  else
@@ -60,19 +77,6 @@ class RedisMultiplexer < BlankSlate
60
77
  def mock() @mock_redis end
61
78
  def real() @real_redis end
62
79
 
63
- # Some commands require special handling due to nondeterminism in
64
- # the returned values.
65
- def handle_special_cases(method, value)
66
- case method.to_s
67
- when 'keys', 'hkeys', 'sdiff', 'sinter', 'smembers', 'sunion'
68
- # The order is irrelevant, but [a,b] != [b,a] in Ruby, so we
69
- # sort the returned values so we can ignore the order.
70
- value.sort if value
71
- else
72
- value
73
- end
74
- end
75
-
76
80
  # Used in cleanup before() blocks.
77
81
  def send_without_checking(method, *args)
78
82
  @mock_redis.send(method, *args)
@@ -16,6 +16,23 @@ describe 'transactions (multi/exec/discard)' do
16
16
  @redises.multi
17
17
  end.should raise_error(RuntimeError)
18
18
  end
19
+
20
+ it "cleanup the state of tansaction wrapper if an exception occurs while a transaction is being processed" do
21
+ lambda do
22
+ @redises.mock.multi do |r|
23
+ raise "i'm a command that fails"
24
+ end
25
+ end.should raise_error(RuntimeError)
26
+
27
+ # before the fix this used to raised a #<RuntimeError: ERR MULTI calls can not be nested>
28
+ lambda do
29
+ @redises.mock.multi do |r|
30
+ # do stuff that succeed
31
+ s.set(nil, 'string')
32
+ end
33
+ end.should_not raise_error(RuntimeError)
34
+
35
+ end
19
36
  end
20
37
 
21
38
  context "#blocks" do
metadata CHANGED
@@ -1,86 +1,73 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mock_redis
3
- version: !ruby/object:Gem::Version
4
- hash: 13
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 4
9
- - 1
10
- segments_generated: true
11
- version: 0.4.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ prerelease:
12
6
  platform: ruby
13
- authors:
7
+ authors:
14
8
  - Causes Engineering
15
9
  - Samuel Merritt
16
10
  autorequire:
17
11
  bindir: bin
18
12
  cert_chain: []
19
-
20
- date: 2012-03-24 00:00:00 -07:00
21
- default_executable:
22
- dependencies:
23
- - !ruby/object:Gem::Dependency
24
- version_requirements: &id001 !ruby/object:Gem::Requirement
13
+ date: 2012-08-27 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ requirement: !ruby/object:Gem::Requirement
25
18
  none: false
26
- requirements:
19
+ requirements:
27
20
  - - ~>
28
- - !ruby/object:Gem::Version
29
- hash: 63
30
- segments:
31
- - 0
32
- - 9
33
- - 2
34
- segments_generated: true
21
+ - !ruby/object:Gem::Version
35
22
  version: 0.9.2
36
- requirement: *id001
37
- name: rake
38
- prerelease: false
39
23
  type: :development
40
- - !ruby/object:Gem::Dependency
41
- version_requirements: &id002 !ruby/object:Gem::Requirement
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
42
26
  none: false
43
- requirements:
27
+ requirements:
44
28
  - - ~>
45
- - !ruby/object:Gem::Version
46
- hash: 5
47
- segments:
48
- - 2
49
- - 2
50
- - 1
51
- segments_generated: true
52
- version: 2.2.1
53
- requirement: *id002
29
+ - !ruby/object:Gem::Version
30
+ version: 0.9.2
31
+ - !ruby/object:Gem::Dependency
54
32
  name: redis
55
- prerelease: false
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ~>
37
+ - !ruby/object:Gem::Version
38
+ version: 3.0.0
56
39
  type: :development
57
- - !ruby/object:Gem::Dependency
58
- version_requirements: &id003 !ruby/object:Gem::Requirement
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
59
42
  none: false
60
- requirements:
43
+ requirements:
61
44
  - - ~>
62
- - !ruby/object:Gem::Version
63
- hash: 23
64
- segments:
65
- - 2
66
- - 6
67
- - 0
68
- segments_generated: true
69
- version: 2.6.0
70
- requirement: *id003
45
+ - !ruby/object:Gem::Version
46
+ version: 3.0.0
47
+ - !ruby/object:Gem::Dependency
71
48
  name: rspec
72
- prerelease: false
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.6.0
73
55
  type: :development
74
- description: Instantiate one with `redis = MockRedis.new` and treat it like you would a normal Redis object. It supports all the usual Redis operations.
75
- email:
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: 2.6.0
63
+ description: Instantiate one with `redis = MockRedis.new` and treat it like you would
64
+ a normal Redis object. It supports all the usual Redis operations.
65
+ email:
76
66
  - eng@causes.com
77
67
  executables: []
78
-
79
68
  extensions: []
80
-
81
69
  extra_rdoc_files: []
82
-
83
- files:
70
+ files:
84
71
  - .gitignore
85
72
  - .mailmap
86
73
  - .rspec
@@ -92,12 +79,12 @@ files:
92
79
  - lib/mock_redis.rb
93
80
  - lib/mock_redis/assertions.rb
94
81
  - lib/mock_redis/database.rb
95
- - lib/mock_redis/distributed.rb
96
82
  - lib/mock_redis/exceptions.rb
97
83
  - lib/mock_redis/expire_wrapper.rb
98
84
  - lib/mock_redis/hash_methods.rb
99
85
  - lib/mock_redis/list_methods.rb
100
86
  - lib/mock_redis/multi_db_wrapper.rb
87
+ - lib/mock_redis/pipelined_wrapper.rb
101
88
  - lib/mock_redis/set_methods.rb
102
89
  - lib/mock_redis/string_methods.rb
103
90
  - lib/mock_redis/transaction_wrapper.rb
@@ -216,6 +203,7 @@ files:
216
203
  - spec/commands/zrevrank_spec.rb
217
204
  - spec/commands/zscore_spec.rb
218
205
  - spec/commands/zunionstore_spec.rb
206
+ - spec/mock_redis_spec.rb
219
207
  - spec/spec_helper.rb
220
208
  - spec/support/redis_multiplexer.rb
221
209
  - spec/support/shared_examples/only_operates_on_hashes.rb
@@ -224,43 +212,37 @@ files:
224
212
  - spec/support/shared_examples/only_operates_on_strings.rb
225
213
  - spec/support/shared_examples/only_operates_on_zsets.rb
226
214
  - spec/transactions_spec.rb
227
- has_rdoc: true
228
215
  homepage: https://github.com/causes/mock_redis
229
216
  licenses: []
230
-
231
217
  post_install_message:
232
218
  rdoc_options: []
233
-
234
- require_paths:
219
+ require_paths:
235
220
  - lib
236
- required_ruby_version: !ruby/object:Gem::Requirement
221
+ required_ruby_version: !ruby/object:Gem::Requirement
237
222
  none: false
238
- requirements:
239
- - - ">="
240
- - !ruby/object:Gem::Version
241
- hash: 3
242
- segments:
223
+ requirements:
224
+ - - ! '>='
225
+ - !ruby/object:Gem::Version
226
+ version: '0'
227
+ segments:
243
228
  - 0
244
- segments_generated: true
245
- version: "0"
246
- required_rubygems_version: !ruby/object:Gem::Requirement
229
+ hash: 2382509530287634625
230
+ required_rubygems_version: !ruby/object:Gem::Requirement
247
231
  none: false
248
- requirements:
249
- - - ">="
250
- - !ruby/object:Gem::Version
251
- hash: 3
252
- segments:
232
+ requirements:
233
+ - - ! '>='
234
+ - !ruby/object:Gem::Version
235
+ version: '0'
236
+ segments:
253
237
  - 0
254
- segments_generated: true
255
- version: "0"
238
+ hash: 2382509530287634625
256
239
  requirements: []
257
-
258
240
  rubyforge_project:
259
- rubygems_version: 1.3.7
241
+ rubygems_version: 1.8.23
260
242
  signing_key:
261
243
  specification_version: 3
262
244
  summary: Redis mock that just lives in memory; useful for testing.
263
- test_files:
245
+ test_files:
264
246
  - spec/cloning_spec.rb
265
247
  - spec/commands/append_spec.rb
266
248
  - spec/commands/auth_spec.rb
@@ -370,6 +352,7 @@ test_files:
370
352
  - spec/commands/zrevrank_spec.rb
371
353
  - spec/commands/zscore_spec.rb
372
354
  - spec/commands/zunionstore_spec.rb
355
+ - spec/mock_redis_spec.rb
373
356
  - spec/spec_helper.rb
374
357
  - spec/support/redis_multiplexer.rb
375
358
  - spec/support/shared_examples/only_operates_on_hashes.rb
@@ -1,6 +0,0 @@
1
- class MockRedis
2
- def pipelined(options = {})
3
- yield
4
- nil
5
- end
6
- end