redis-store-pika 1.9.2.1
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.
- checksums.yaml +7 -0
 - data/.codeclimate.yml +6 -0
 - data/.github/auto-assign-issues.yml +2 -0
 - data/.github/workflows/ci.yml +64 -0
 - data/.gitignore +9 -0
 - data/.rubocop.yml +132 -0
 - data/Appraisals +19 -0
 - data/CHANGELOG.md +667 -0
 - data/CODEOWNERS +1 -0
 - data/Gemfile +7 -0
 - data/MIT-LICENSE +20 -0
 - data/README.md +68 -0
 - data/Rakefile +15 -0
 - data/gemfiles/redis_4_0_x.gemfile +7 -0
 - data/gemfiles/redis_4_1_x.gemfile +7 -0
 - data/gemfiles/redis_4_6_x.gemfile +7 -0
 - data/gemfiles/redis_4_x.gemfile +7 -0
 - data/gemfiles/redis_5_x.gemfile +7 -0
 - data/lib/redis/distributed_store.rb +68 -0
 - data/lib/redis/store/factory.rb +111 -0
 - data/lib/redis/store/interface.rb +29 -0
 - data/lib/redis/store/namespace.rb +211 -0
 - data/lib/redis/store/redis_version.rb +13 -0
 - data/lib/redis/store/serialization.rb +67 -0
 - data/lib/redis/store/ttl.rb +47 -0
 - data/lib/redis/store/version.rb +13 -0
 - data/lib/redis/store.rb +85 -0
 - data/lib/redis-store-pika.rb +1 -0
 - data/lib/redis-store.rb +1 -0
 - data/redis-store.gemspec +35 -0
 - data/test/redis/distributed_store_test.rb +111 -0
 - data/test/redis/store/factory_test.rb +273 -0
 - data/test/redis/store/interface_test.rb +27 -0
 - data/test/redis/store/namespace_test.rb +316 -0
 - data/test/redis/store/redis_version_test.rb +28 -0
 - data/test/redis/store/serialization_test.rb +173 -0
 - data/test/redis/store/ttl_test.rb +142 -0
 - data/test/redis/store/version_test.rb +7 -0
 - data/test/redis/store_test.rb +68 -0
 - data/test/test_helper.rb +20 -0
 - metadata +246 -0
 
| 
         @@ -0,0 +1,316 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'test_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe "Redis::Store::Namespace" do
         
     | 
| 
      
 4 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 5 
     | 
    
         
            +
                @namespace = "theplaylist"
         
     | 
| 
      
 6 
     | 
    
         
            +
                @store = Redis::Store.new :namespace => @namespace, :serializer => nil
         
     | 
| 
      
 7 
     | 
    
         
            +
                @client = @store.instance_variable_get(:@client)
         
     | 
| 
      
 8 
     | 
    
         
            +
                @rabbit = "bunny"
         
     | 
| 
      
 9 
     | 
    
         
            +
                @default_store = Redis::Store.new
         
     | 
| 
      
 10 
     | 
    
         
            +
                @other_namespace = 'other'
         
     | 
| 
      
 11 
     | 
    
         
            +
                @other_store = Redis::Store.new :namespace => @other_namespace
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              def teardown
         
     | 
| 
      
 15 
     | 
    
         
            +
                @store.flushdb
         
     | 
| 
      
 16 
     | 
    
         
            +
                @store.quit
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                @default_store.flushdb
         
     | 
| 
      
 19 
     | 
    
         
            +
                @default_store.quit
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                @other_store.flushdb
         
     | 
| 
      
 22 
     | 
    
         
            +
                @other_store.quit
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              it "only decorates instances that need to be namespaced" do
         
     | 
| 
      
 26 
     | 
    
         
            +
                store  = Redis::Store.new
         
     | 
| 
      
 27 
     | 
    
         
            +
                client = store.instance_variable_get(:@client)
         
     | 
| 
      
 28 
     | 
    
         
            +
                # `call_v` used since redis-rb 5.0
         
     | 
| 
      
 29 
     | 
    
         
            +
                client_call_method_name = client.respond_to?(:call_v) ? :call_v : :call
         
     | 
| 
      
 30 
     | 
    
         
            +
                client.expects(client_call_method_name).with([:get, "rabbit"])
         
     | 
| 
      
 31 
     | 
    
         
            +
                store.get("rabbit")
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              it "doesn't namespace a key which is already namespaced" do
         
     | 
| 
      
 35 
     | 
    
         
            +
                _(@store.send(:interpolate, "#{@namespace}:rabbit")).must_equal("#{@namespace}:rabbit")
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
              it "should only delete namespaced keys" do
         
     | 
| 
      
 39 
     | 
    
         
            +
                @default_store.set 'abc', 'cba'
         
     | 
| 
      
 40 
     | 
    
         
            +
                @store.set 'def', 'fed'
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                @store.flushdb
         
     | 
| 
      
 43 
     | 
    
         
            +
                _(@store.get('def')).must_be_nil
         
     | 
| 
      
 44 
     | 
    
         
            +
                _(@default_store.get('abc')).must_equal('cba')
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              it 'should allow to change namespace on the fly' do
         
     | 
| 
      
 48 
     | 
    
         
            +
                @default_store.set 'abc', 'cba'
         
     | 
| 
      
 49 
     | 
    
         
            +
                @other_store.set 'foo', 'bar'
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                _(@default_store.keys.sort).must_equal ['abc', 'other:foo']
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                @default_store.with_namespace(@other_namespace) do
         
     | 
| 
      
 54 
     | 
    
         
            +
                  _(@default_store.keys).must_equal ['foo']
         
     | 
| 
      
 55 
     | 
    
         
            +
                  _(@default_store.get('foo')).must_equal('bar')
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              it "should not try to delete missing namespaced keys" do
         
     | 
| 
      
 60 
     | 
    
         
            +
                empty_store = Redis::Store.new :namespace => 'empty'
         
     | 
| 
      
 61 
     | 
    
         
            +
                empty_store.flushdb
         
     | 
| 
      
 62 
     | 
    
         
            +
                _(empty_store.keys).must_be_empty
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
              it "should work with dynamic namespace" do
         
     | 
| 
      
 66 
     | 
    
         
            +
                $ns = "ns1"
         
     | 
| 
      
 67 
     | 
    
         
            +
                dyn_store = Redis::Store.new :namespace => -> { $ns }
         
     | 
| 
      
 68 
     | 
    
         
            +
                dyn_store.set 'key', 'x'
         
     | 
| 
      
 69 
     | 
    
         
            +
                $ns = "ns2"
         
     | 
| 
      
 70 
     | 
    
         
            +
                dyn_store.set 'key', 'y'
         
     | 
| 
      
 71 
     | 
    
         
            +
                $ns = "ns3"
         
     | 
| 
      
 72 
     | 
    
         
            +
                dyn_store.set 'key', 'z'
         
     | 
| 
      
 73 
     | 
    
         
            +
                dyn_store.flushdb
         
     | 
| 
      
 74 
     | 
    
         
            +
                r3 = dyn_store.get 'key'
         
     | 
| 
      
 75 
     | 
    
         
            +
                $ns = "ns2"
         
     | 
| 
      
 76 
     | 
    
         
            +
                r2 = dyn_store.get 'key'
         
     | 
| 
      
 77 
     | 
    
         
            +
                $ns = "ns1"
         
     | 
| 
      
 78 
     | 
    
         
            +
                r1 = dyn_store.get 'key'
         
     | 
| 
      
 79 
     | 
    
         
            +
                _(r1).must_equal('x') && _(r2).must_equal('y') && _(r3).must_be_nil
         
     | 
| 
      
 80 
     | 
    
         
            +
              end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
              it "namespaces setex and ttl" do
         
     | 
| 
      
 83 
     | 
    
         
            +
                @store.flushdb
         
     | 
| 
      
 84 
     | 
    
         
            +
                @other_store.flushdb
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                @store.setex('foo', 30, 'bar')
         
     | 
| 
      
 87 
     | 
    
         
            +
                _(@store.ttl('foo')).must_be_close_to(30)
         
     | 
| 
      
 88 
     | 
    
         
            +
                _(@store.get('foo')).must_equal('bar')
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                _(@other_store.ttl('foo')).must_equal(-2)
         
     | 
| 
      
 91 
     | 
    
         
            +
                _(@other_store.get('foo')).must_be_nil
         
     | 
| 
      
 92 
     | 
    
         
            +
              end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
              describe 'method calls' do
         
     | 
| 
      
 95 
     | 
    
         
            +
                let(:store) { Redis::Store.new :namespace => @namespace, :serializer => nil }
         
     | 
| 
      
 96 
     | 
    
         
            +
                let(:client) { store.instance_variable_get(:@client) }
         
     | 
| 
      
 97 
     | 
    
         
            +
                let(:client_call_method_name) do
         
     | 
| 
      
 98 
     | 
    
         
            +
                  # `call_v` used since redis-rb 5.0
         
     | 
| 
      
 99 
     | 
    
         
            +
                  client.respond_to?(:call_v) ? :call_v : :call
         
     | 
| 
      
 100 
     | 
    
         
            +
                end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                it "should namespace get" do
         
     | 
| 
      
 103 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:get, "#{@namespace}:rabbit"]).once
         
     | 
| 
      
 104 
     | 
    
         
            +
                  store.get("rabbit")
         
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                it "should namespace set" do
         
     | 
| 
      
 108 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:set, "#{@namespace}:rabbit", @rabbit])
         
     | 
| 
      
 109 
     | 
    
         
            +
                  store.set "rabbit", @rabbit
         
     | 
| 
      
 110 
     | 
    
         
            +
                end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                it "should namespace setnx" do
         
     | 
| 
      
 113 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:setnx, "#{@namespace}:rabbit", @rabbit])
         
     | 
| 
      
 114 
     | 
    
         
            +
                  store.setnx "rabbit", @rabbit
         
     | 
| 
      
 115 
     | 
    
         
            +
                end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                it "should namespace del with single key" do
         
     | 
| 
      
 118 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:del, "#{@namespace}:rabbit"])
         
     | 
| 
      
 119 
     | 
    
         
            +
                  store.del "rabbit"
         
     | 
| 
      
 120 
     | 
    
         
            +
                end
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                it "should namespace del with multiple keys" do
         
     | 
| 
      
 123 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:del, "#{@namespace}:rabbit", "#{@namespace}:white_rabbit"])
         
     | 
| 
      
 124 
     | 
    
         
            +
                  store.del "rabbit", "white_rabbit"
         
     | 
| 
      
 125 
     | 
    
         
            +
                end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                it "should namespace keys" do
         
     | 
| 
      
 128 
     | 
    
         
            +
                  store.set "rabbit", @rabbit
         
     | 
| 
      
 129 
     | 
    
         
            +
                  _(store.keys("rabb*")).must_equal [ "rabbit" ]
         
     | 
| 
      
 130 
     | 
    
         
            +
                end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                it "should namespace scan when a pattern is given" do
         
     | 
| 
      
 133 
     | 
    
         
            +
                  store.set "rabbit", @rabbit
         
     | 
| 
      
 134 
     | 
    
         
            +
                  cursor = "0"
         
     | 
| 
      
 135 
     | 
    
         
            +
                  keys = []
         
     | 
| 
      
 136 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 137 
     | 
    
         
            +
                    cursor, matched_keys = store.scan(cursor, match: "rabb*")
         
     | 
| 
      
 138 
     | 
    
         
            +
                    keys = keys.concat(matched_keys) unless matched_keys.empty?
         
     | 
| 
      
 139 
     | 
    
         
            +
                  end until cursor == "0"
         
     | 
| 
      
 140 
     | 
    
         
            +
                  _(keys).must_equal [ "rabbit" ]
         
     | 
| 
      
 141 
     | 
    
         
            +
                end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                it "should namespace exists" do
         
     | 
| 
      
 144 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:exists, "#{@namespace}:rabbit"])
         
     | 
| 
      
 145 
     | 
    
         
            +
                  store.exists "rabbit"
         
     | 
| 
      
 146 
     | 
    
         
            +
                end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                it "should namespace incrby" do
         
     | 
| 
      
 149 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:incrby, "#{@namespace}:counter", 1])
         
     | 
| 
      
 150 
     | 
    
         
            +
                  store.incrby "counter", 1
         
     | 
| 
      
 151 
     | 
    
         
            +
                end
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
                it "should namespace decrby" do
         
     | 
| 
      
 154 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:decrby, "#{@namespace}:counter", 1])
         
     | 
| 
      
 155 
     | 
    
         
            +
                  store.decrby "counter", 1
         
     | 
| 
      
 156 
     | 
    
         
            +
                end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                it "should namespace mget" do
         
     | 
| 
      
 159 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:mget, "#{@namespace}:rabbit", "#{@namespace}:white_rabbit"]).returns(%w[ foo bar ])
         
     | 
| 
      
 160 
     | 
    
         
            +
                  store.mget "rabbit", "white_rabbit" do |result|
         
     | 
| 
      
 161 
     | 
    
         
            +
                    _(result).must_equal(%w[ foo bar ])
         
     | 
| 
      
 162 
     | 
    
         
            +
                  end
         
     | 
| 
      
 163 
     | 
    
         
            +
                end
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                it "should namespace mapped_mget" do
         
     | 
| 
      
 166 
     | 
    
         
            +
                  if client.respond_to?(:process, true)
         
     | 
| 
      
 167 
     | 
    
         
            +
                    # Redis < 5.0 uses `#process`
         
     | 
| 
      
 168 
     | 
    
         
            +
                    client.expects(:process).with([[:mget, "#{@namespace}:rabbit", "#{@namespace}:white_rabbit"]]).returns(%w[ foo bar ])
         
     | 
| 
      
 169 
     | 
    
         
            +
                  else
         
     | 
| 
      
 170 
     | 
    
         
            +
                    # Redis 5.x calls `#ensure_connected` (private)
         
     | 
| 
      
 171 
     | 
    
         
            +
                    client.send(:ensure_connected).expects(:call).returns(%w[ foo bar ])
         
     | 
| 
      
 172 
     | 
    
         
            +
                  end
         
     | 
| 
      
 173 
     | 
    
         
            +
                  result = store.mapped_mget "rabbit", "white_rabbit"
         
     | 
| 
      
 174 
     | 
    
         
            +
                  _(result.keys).must_equal %w[ rabbit white_rabbit ]
         
     | 
| 
      
 175 
     | 
    
         
            +
                  _(result["rabbit"]).must_equal "foo"
         
     | 
| 
      
 176 
     | 
    
         
            +
                  _(result["white_rabbit"]).must_equal "bar"
         
     | 
| 
      
 177 
     | 
    
         
            +
                end
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                it "should namespace expire" do
         
     | 
| 
      
 180 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:expire, "#{@namespace}:rabbit", 60]).once
         
     | 
| 
      
 181 
     | 
    
         
            +
                  store.expire("rabbit", 60)
         
     | 
| 
      
 182 
     | 
    
         
            +
                end
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
                it "should namespace ttl" do
         
     | 
| 
      
 185 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:ttl, "#{@namespace}:rabbit"]).once
         
     | 
| 
      
 186 
     | 
    
         
            +
                  store.ttl("rabbit")
         
     | 
| 
      
 187 
     | 
    
         
            +
                end
         
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
                it "should namespace watch" do
         
     | 
| 
      
 190 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:watch, "#{@namespace}:rabbit"]).once
         
     | 
| 
      
 191 
     | 
    
         
            +
                  store.watch("rabbit")
         
     | 
| 
      
 192 
     | 
    
         
            +
                end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
                it "wraps flushdb with appropriate KEYS * calls" do
         
     | 
| 
      
 195 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:flushdb]).never
         
     | 
| 
      
 196 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:keys, "#{@namespace}:*"]).once.returns(["rabbit"])
         
     | 
| 
      
 197 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:del, "#{@namespace}:rabbit"]).once
         
     | 
| 
      
 198 
     | 
    
         
            +
                  store.flushdb
         
     | 
| 
      
 199 
     | 
    
         
            +
                end
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
                it "skips flushdb wrapping if the namespace is nil" do
         
     | 
| 
      
 202 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:flushdb])
         
     | 
| 
      
 203 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:keys]).never
         
     | 
| 
      
 204 
     | 
    
         
            +
                  store.with_namespace(nil) do
         
     | 
| 
      
 205 
     | 
    
         
            +
                    store.flushdb
         
     | 
| 
      
 206 
     | 
    
         
            +
                  end
         
     | 
| 
      
 207 
     | 
    
         
            +
                end
         
     | 
| 
      
 208 
     | 
    
         
            +
             
     | 
| 
      
 209 
     | 
    
         
            +
                it "should namespace hdel" do
         
     | 
| 
      
 210 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hdel, "#{@namespace}:rabbit", "key1", "key2"]).once
         
     | 
| 
      
 211 
     | 
    
         
            +
                  store.hdel("rabbit", "key1", "key2")
         
     | 
| 
      
 212 
     | 
    
         
            +
                end
         
     | 
| 
      
 213 
     | 
    
         
            +
             
     | 
| 
      
 214 
     | 
    
         
            +
                it "should namespace hget" do
         
     | 
| 
      
 215 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hget, "#{@namespace}:rabbit", "key"]).once
         
     | 
| 
      
 216 
     | 
    
         
            +
                  store.hget("rabbit", "key")
         
     | 
| 
      
 217 
     | 
    
         
            +
                end
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
                it "should namespace hgetall" do
         
     | 
| 
      
 220 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hgetall, "#{@namespace}:rabbit"]).once
         
     | 
| 
      
 221 
     | 
    
         
            +
                  store.hgetall("rabbit")
         
     | 
| 
      
 222 
     | 
    
         
            +
                end
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
                it "should namespace hexists" do
         
     | 
| 
      
 225 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hexists, "#{@namespace}:rabbit", "key"]).once
         
     | 
| 
      
 226 
     | 
    
         
            +
                  store.hexists("rabbit", "key")
         
     | 
| 
      
 227 
     | 
    
         
            +
                end
         
     | 
| 
      
 228 
     | 
    
         
            +
             
     | 
| 
      
 229 
     | 
    
         
            +
                it "should namespace hincrby" do
         
     | 
| 
      
 230 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hincrby, "#{@namespace}:rabbit", "key", 1]).once
         
     | 
| 
      
 231 
     | 
    
         
            +
                  store.hincrby("rabbit", "key", 1)
         
     | 
| 
      
 232 
     | 
    
         
            +
                end
         
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
                it "should namespace hincrbyfloat" do
         
     | 
| 
      
 235 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hincrbyfloat, "#{@namespace}:rabbit", "key", 1.5]).once
         
     | 
| 
      
 236 
     | 
    
         
            +
                  store.hincrbyfloat("rabbit", "key", 1.5)
         
     | 
| 
      
 237 
     | 
    
         
            +
                end
         
     | 
| 
      
 238 
     | 
    
         
            +
             
     | 
| 
      
 239 
     | 
    
         
            +
                it "should namespace hkeys" do
         
     | 
| 
      
 240 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hkeys, "#{@namespace}:rabbit"])
         
     | 
| 
      
 241 
     | 
    
         
            +
                  store.hkeys("rabbit")
         
     | 
| 
      
 242 
     | 
    
         
            +
                end
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
                it "should namespace hlen" do
         
     | 
| 
      
 245 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hlen, "#{@namespace}:rabbit"])
         
     | 
| 
      
 246 
     | 
    
         
            +
                  store.hlen("rabbit")
         
     | 
| 
      
 247 
     | 
    
         
            +
                end
         
     | 
| 
      
 248 
     | 
    
         
            +
             
     | 
| 
      
 249 
     | 
    
         
            +
                it "should namespace hmget" do
         
     | 
| 
      
 250 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hmget, "#{@namespace}:rabbit", "key1", "key2"])
         
     | 
| 
      
 251 
     | 
    
         
            +
                  store.hmget("rabbit", "key1", "key2")
         
     | 
| 
      
 252 
     | 
    
         
            +
                end
         
     | 
| 
      
 253 
     | 
    
         
            +
             
     | 
| 
      
 254 
     | 
    
         
            +
                it "should namespace hmset" do
         
     | 
| 
      
 255 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hmset, "#{@namespace}:rabbit", "key", @rabbit])
         
     | 
| 
      
 256 
     | 
    
         
            +
                  store.hmset("rabbit", "key", @rabbit)
         
     | 
| 
      
 257 
     | 
    
         
            +
                end
         
     | 
| 
      
 258 
     | 
    
         
            +
             
     | 
| 
      
 259 
     | 
    
         
            +
                it "should namespace hset" do
         
     | 
| 
      
 260 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hset, "#{@namespace}:rabbit", "key", @rabbit])
         
     | 
| 
      
 261 
     | 
    
         
            +
                  store.hset("rabbit", "key", @rabbit)
         
     | 
| 
      
 262 
     | 
    
         
            +
                end
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
                it "should namespace hsetnx" do
         
     | 
| 
      
 265 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hsetnx, "#{@namespace}:rabbit", "key", @rabbit])
         
     | 
| 
      
 266 
     | 
    
         
            +
                  store.hsetnx("rabbit", "key", @rabbit)
         
     | 
| 
      
 267 
     | 
    
         
            +
                end
         
     | 
| 
      
 268 
     | 
    
         
            +
             
     | 
| 
      
 269 
     | 
    
         
            +
                it "should namespace hvals" do
         
     | 
| 
      
 270 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hvals, "#{@namespace}:rabbit"])
         
     | 
| 
      
 271 
     | 
    
         
            +
                  store.hvals("rabbit")
         
     | 
| 
      
 272 
     | 
    
         
            +
                end
         
     | 
| 
      
 273 
     | 
    
         
            +
             
     | 
| 
      
 274 
     | 
    
         
            +
                it "should namespace hscan" do
         
     | 
| 
      
 275 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hscan, "#{@namespace}:rabbit", 0])
         
     | 
| 
      
 276 
     | 
    
         
            +
                  store.hscan("rabbit", 0)
         
     | 
| 
      
 277 
     | 
    
         
            +
                end
         
     | 
| 
      
 278 
     | 
    
         
            +
             
     | 
| 
      
 279 
     | 
    
         
            +
                it "should namespace hscan_each with block" do
         
     | 
| 
      
 280 
     | 
    
         
            +
                  client.public_send(client_call_method_name, [:hset, "#{@namespace}:rabbit", "key1", @rabbit])
         
     | 
| 
      
 281 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hscan, "#{@namespace}:rabbit", 0]).returns(["0", ["key1"]])
         
     | 
| 
      
 282 
     | 
    
         
            +
                  results = []
         
     | 
| 
      
 283 
     | 
    
         
            +
                  store.hscan_each("rabbit") do |key|
         
     | 
| 
      
 284 
     | 
    
         
            +
                    results << key
         
     | 
| 
      
 285 
     | 
    
         
            +
                  end
         
     | 
| 
      
 286 
     | 
    
         
            +
                  _(results).must_equal(["key1"])
         
     | 
| 
      
 287 
     | 
    
         
            +
                end
         
     | 
| 
      
 288 
     | 
    
         
            +
             
     | 
| 
      
 289 
     | 
    
         
            +
                it "should namespace hscan_each without block" do
         
     | 
| 
      
 290 
     | 
    
         
            +
                  client.public_send(client_call_method_name, [:hset, "#{@namespace}:rabbit", "key1", @rabbit])
         
     | 
| 
      
 291 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:hscan, "#{@namespace}:rabbit", 0]).returns(["0", ["key1"]])
         
     | 
| 
      
 292 
     | 
    
         
            +
                  results = store.hscan_each("rabbit").to_a
         
     | 
| 
      
 293 
     | 
    
         
            +
                  _(results).must_equal(["key1"])
         
     | 
| 
      
 294 
     | 
    
         
            +
                end
         
     | 
| 
      
 295 
     | 
    
         
            +
             
     | 
| 
      
 296 
     | 
    
         
            +
                it "should namespace zincrby" do
         
     | 
| 
      
 297 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:zincrby, "#{@namespace}:rabbit", 1.0, "member"])
         
     | 
| 
      
 298 
     | 
    
         
            +
                  store.zincrby("rabbit", 1.0, "member")
         
     | 
| 
      
 299 
     | 
    
         
            +
                end
         
     | 
| 
      
 300 
     | 
    
         
            +
             
     | 
| 
      
 301 
     | 
    
         
            +
                it "should namespace zscore" do
         
     | 
| 
      
 302 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:zscore, "#{@namespace}:rabbit", "member"])
         
     | 
| 
      
 303 
     | 
    
         
            +
                  store.zscore("rabbit", "member")
         
     | 
| 
      
 304 
     | 
    
         
            +
                end
         
     | 
| 
      
 305 
     | 
    
         
            +
             
     | 
| 
      
 306 
     | 
    
         
            +
                it "should namespace zadd" do
         
     | 
| 
      
 307 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:zadd, "#{@namespace}:rabbit", 1.0, "member"])
         
     | 
| 
      
 308 
     | 
    
         
            +
                  store.zadd("rabbit", 1.0, "member")
         
     | 
| 
      
 309 
     | 
    
         
            +
                end
         
     | 
| 
      
 310 
     | 
    
         
            +
             
     | 
| 
      
 311 
     | 
    
         
            +
                it "should namespace zrem" do
         
     | 
| 
      
 312 
     | 
    
         
            +
                  client.expects(client_call_method_name).with([:zrem, "#{@namespace}:rabbit", "member"])
         
     | 
| 
      
 313 
     | 
    
         
            +
                  store.zrem("rabbit", "member")
         
     | 
| 
      
 314 
     | 
    
         
            +
                end
         
     | 
| 
      
 315 
     | 
    
         
            +
              end
         
     | 
| 
      
 316 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'test_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe "Redis::RedisVersion" do
         
     | 
| 
      
 4 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 5 
     | 
    
         
            +
                @store = Redis::Store.new
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def teardown
         
     | 
| 
      
 9 
     | 
    
         
            +
                @store.quit
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              describe '#redis_version' do
         
     | 
| 
      
 13 
     | 
    
         
            +
                it 'returns redis version' do
         
     | 
| 
      
 14 
     | 
    
         
            +
                  _(@store.redis_version.to_s).must_match(/^\d{1}\.\d{1,}\.\d{1,}$/)
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              describe '#supports_redis_version?' do
         
     | 
| 
      
 19 
     | 
    
         
            +
                it 'returns true if redis version is greater or equal to required version' do
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @store.stubs(:redis_version).returns('2.8.19')
         
     | 
| 
      
 21 
     | 
    
         
            +
                  _(@store.supports_redis_version?('2.6.0')).must_equal(true)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  _(@store.supports_redis_version?('2.8.19')).must_equal(true)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  _(@store.supports_redis_version?('2.8.20')).must_equal(false)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  _(@store.supports_redis_version?('2.9.0')).must_equal(false)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  _(@store.supports_redis_version?('3.0.0')).must_equal(false)
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,173 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'test_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe "Redis::Serialization" do
         
     | 
| 
      
 4 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 5 
     | 
    
         
            +
                @store = Redis::Store.new serializer: Marshal
         
     | 
| 
      
 6 
     | 
    
         
            +
                @rabbit = OpenStruct.new :name => "bunny"
         
     | 
| 
      
 7 
     | 
    
         
            +
                @white_rabbit = OpenStruct.new :color => "white"
         
     | 
| 
      
 8 
     | 
    
         
            +
                @store.set "rabbit", @rabbit
         
     | 
| 
      
 9 
     | 
    
         
            +
                @store.del "rabbit2"
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              def teardown
         
     | 
| 
      
 13 
     | 
    
         
            +
                @store.flushdb
         
     | 
| 
      
 14 
     | 
    
         
            +
                @store.quit
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              it "unmarshals on get" do
         
     | 
| 
      
 18 
     | 
    
         
            +
                _(@store.get("rabbit")).must_equal(@rabbit)
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              it "marshals on set" do
         
     | 
| 
      
 22 
     | 
    
         
            +
                @store.set "rabbit", @white_rabbit
         
     | 
| 
      
 23 
     | 
    
         
            +
                _(@store.get("rabbit")).must_equal(@white_rabbit)
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              it "marshals on multi set" do
         
     | 
| 
      
 27 
     | 
    
         
            +
                @store.mset("rabbit", @white_rabbit, "rabbit2", @rabbit)
         
     | 
| 
      
 28 
     | 
    
         
            +
                _(@store.get("rabbit")).must_equal(@white_rabbit)
         
     | 
| 
      
 29 
     | 
    
         
            +
                _(@store.get("rabbit2")).must_equal(@rabbit)
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              if RUBY_VERSION.match(/1\.9/)
         
     | 
| 
      
 33 
     | 
    
         
            +
                it "doesn't unmarshal on get if raw option is true" do
         
     | 
| 
      
 34 
     | 
    
         
            +
                  _(@store.get("rabbit", :raw => true)).must_equal("\x04\bU:\x0FOpenStruct{\x06:\tnameI\"\nbunny\x06:\x06EF")
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              else
         
     | 
| 
      
 37 
     | 
    
         
            +
                it "doesn't unmarshal on get if raw option is true" do
         
     | 
| 
      
 38 
     | 
    
         
            +
                  _(@store.get("rabbit", :raw => true)).must_include("\x04\bU:\x0FOpenStruct{\x06:\tname")
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              it "doesn't marshal set if raw option is true" do
         
     | 
| 
      
 43 
     | 
    
         
            +
                @store.set "rabbit", @white_rabbit, :raw => true
         
     | 
| 
      
 44 
     | 
    
         
            +
                _(@store.get("rabbit", :raw => true)).must_equal(%(#<OpenStruct color="white">))
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              it "doesn't marshal multi set if raw option is true" do
         
     | 
| 
      
 48 
     | 
    
         
            +
                @store.mset("rabbit", @white_rabbit, "rabbit2", @rabbit, :raw => true)
         
     | 
| 
      
 49 
     | 
    
         
            +
                _(@store.get("rabbit", :raw => true)).must_equal(%(#<OpenStruct color="white">))
         
     | 
| 
      
 50 
     | 
    
         
            +
                _(@store.get("rabbit2", :raw => true)).must_equal(%(#<OpenStruct name="bunny">))
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              it "doesn't unmarshal if get returns an empty string" do
         
     | 
| 
      
 54 
     | 
    
         
            +
                @store.set "empty_string", ""
         
     | 
| 
      
 55 
     | 
    
         
            +
                _(@store.get("empty_string")).must_equal("")
         
     | 
| 
      
 56 
     | 
    
         
            +
                # TODO use a meaningful Exception
         
     | 
| 
      
 57 
     | 
    
         
            +
                # lambda { @store.get("empty_string").must_equal("") }.wont_raise Exception
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              it "doesn't set an object if already exist" do
         
     | 
| 
      
 61 
     | 
    
         
            +
                @store.setnx "rabbit", @white_rabbit
         
     | 
| 
      
 62 
     | 
    
         
            +
                _(@store.get("rabbit")).must_equal(@rabbit)
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
              it "marshals on set unless exists" do
         
     | 
| 
      
 66 
     | 
    
         
            +
                @store.setnx "rabbit2", @white_rabbit
         
     | 
| 
      
 67 
     | 
    
         
            +
                _(@store.get("rabbit2")).must_equal(@white_rabbit)
         
     | 
| 
      
 68 
     | 
    
         
            +
              end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
              it "doesn't marshal on set unless exists if raw option is true" do
         
     | 
| 
      
 71 
     | 
    
         
            +
                @store.setnx "rabbit2", @white_rabbit, :raw => true
         
     | 
| 
      
 72 
     | 
    
         
            +
                _(@store.get("rabbit2", :raw => true)).must_equal(%(#<OpenStruct color="white">))
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
              it "marshals on set expire" do
         
     | 
| 
      
 76 
     | 
    
         
            +
                @store.setex "rabbit2", 1, @white_rabbit
         
     | 
| 
      
 77 
     | 
    
         
            +
                _(@store.get("rabbit2")).must_equal(@white_rabbit)
         
     | 
| 
      
 78 
     | 
    
         
            +
                sleep 2
         
     | 
| 
      
 79 
     | 
    
         
            +
                _(@store.get("rabbit2")).must_be_nil
         
     | 
| 
      
 80 
     | 
    
         
            +
              end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
              unless ENV['CI']
         
     | 
| 
      
 83 
     | 
    
         
            +
                it "marshals setex (over a distributed store)" do
         
     | 
| 
      
 84 
     | 
    
         
            +
                  @store = Redis::DistributedStore.new [
         
     | 
| 
      
 85 
     | 
    
         
            +
                    { :host => "localhost", :port => "6380", :db => 0 },
         
     | 
| 
      
 86 
     | 
    
         
            +
                    { :host => "localhost", :port => "6381", :db => 0 }
         
     | 
| 
      
 87 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 88 
     | 
    
         
            +
                  @store.setex "rabbit", 50, @white_rabbit
         
     | 
| 
      
 89 
     | 
    
         
            +
                  _(@store.get("rabbit")).must_equal(@white_rabbit)
         
     | 
| 
      
 90 
     | 
    
         
            +
                end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                it "doesn't marshal setex if raw option is true (over a distributed store)" do
         
     | 
| 
      
 93 
     | 
    
         
            +
                  @store = Redis::DistributedStore.new [
         
     | 
| 
      
 94 
     | 
    
         
            +
                    { :host => "localhost", :port => "6380", :db => 0 },
         
     | 
| 
      
 95 
     | 
    
         
            +
                    { :host => "localhost", :port => "6381", :db => 0 }
         
     | 
| 
      
 96 
     | 
    
         
            +
                  ]
         
     | 
| 
      
 97 
     | 
    
         
            +
                  @store.setex "rabbit", 50, @white_rabbit, :raw => true
         
     | 
| 
      
 98 
     | 
    
         
            +
                  _(@store.get("rabbit", :raw => true)).must_equal(%(#<OpenStruct color="white">))
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
              end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
              it "unmarshals on multi get" do
         
     | 
| 
      
 103 
     | 
    
         
            +
                @store.set "rabbit2", @white_rabbit
         
     | 
| 
      
 104 
     | 
    
         
            +
                @store.mget "rabbit", "rabbit2" do |rabbits|
         
     | 
| 
      
 105 
     | 
    
         
            +
                  rabbit, rabbit2 = rabbits
         
     | 
| 
      
 106 
     | 
    
         
            +
                  _(rabbits.length).must_equal(2)
         
     | 
| 
      
 107 
     | 
    
         
            +
                  _(rabbit).must_equal(@rabbit)
         
     | 
| 
      
 108 
     | 
    
         
            +
                  _(rabbit2).must_equal(@white_rabbit)
         
     | 
| 
      
 109 
     | 
    
         
            +
                end
         
     | 
| 
      
 110 
     | 
    
         
            +
              end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
              it "unmarshals on mapped_mget" do
         
     | 
| 
      
 113 
     | 
    
         
            +
                @store.set "rabbit2", @white_rabbit
         
     | 
| 
      
 114 
     | 
    
         
            +
                result = @store.mapped_mget("rabbit", "rabbit2")
         
     | 
| 
      
 115 
     | 
    
         
            +
                _(result.keys).must_equal %w[ rabbit rabbit2 ]
         
     | 
| 
      
 116 
     | 
    
         
            +
                _(result["rabbit"]).must_equal @rabbit
         
     | 
| 
      
 117 
     | 
    
         
            +
                _(result["rabbit2"]).must_equal @white_rabbit
         
     | 
| 
      
 118 
     | 
    
         
            +
              end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
              if RUBY_VERSION.match(/1\.9/)
         
     | 
| 
      
 121 
     | 
    
         
            +
                it "doesn't unmarshal on multi get if raw option is true" do
         
     | 
| 
      
 122 
     | 
    
         
            +
                  @store.set "rabbit2", @white_rabbit
         
     | 
| 
      
 123 
     | 
    
         
            +
                  @store.mget "rabbit", "rabbit2", :raw => true do |rabbit, rabbit2|
         
     | 
| 
      
 124 
     | 
    
         
            +
                    _(rabbit).must_equal("\x04\bU:\x0FOpenStruct{\x06:\tnameI\"\nbunny\x06:\x06EF")
         
     | 
| 
      
 125 
     | 
    
         
            +
                    _(rabbit2).must_equal("\x04\bU:\x0FOpenStruct{\x06:\ncolorI\"\nwhite\x06:\x06EF")
         
     | 
| 
      
 126 
     | 
    
         
            +
                  end
         
     | 
| 
      
 127 
     | 
    
         
            +
                end
         
     | 
| 
      
 128 
     | 
    
         
            +
              else
         
     | 
| 
      
 129 
     | 
    
         
            +
                it "doesn't unmarshal on multi get if raw option is true" do
         
     | 
| 
      
 130 
     | 
    
         
            +
                  @store.set "rabbit2", @white_rabbit
         
     | 
| 
      
 131 
     | 
    
         
            +
                  @store.mget "rabbit", "rabbit2", :raw => true do |rabbit, rabbit2|
         
     | 
| 
      
 132 
     | 
    
         
            +
                    _(rabbit).must_include("\x04\bU:\x0FOpenStruct{\x06:\tname")
         
     | 
| 
      
 133 
     | 
    
         
            +
                    _(rabbit2).must_include("\x04\bU:\x0FOpenStruct{\x06:\ncolor")
         
     | 
| 
      
 134 
     | 
    
         
            +
                  end
         
     | 
| 
      
 135 
     | 
    
         
            +
                end
         
     | 
| 
      
 136 
     | 
    
         
            +
              end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
              describe "binary safety" do
         
     | 
| 
      
 139 
     | 
    
         
            +
                it "marshals objects" do
         
     | 
| 
      
 140 
     | 
    
         
            +
                  utf8_key = [51339].pack("U*")
         
     | 
| 
      
 141 
     | 
    
         
            +
                  ascii_rabbit = OpenStruct.new(:name => [128].pack("C*"))
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                  @store.set(utf8_key, ascii_rabbit)
         
     | 
| 
      
 144 
     | 
    
         
            +
                  _(@store.get(utf8_key)).must_equal(ascii_rabbit)
         
     | 
| 
      
 145 
     | 
    
         
            +
                end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                it "gets and sets raw values" do
         
     | 
| 
      
 148 
     | 
    
         
            +
                  utf8_key = [51339].pack("U*")
         
     | 
| 
      
 149 
     | 
    
         
            +
                  ascii_string = [128].pack("C*")
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                  @store.set(utf8_key, ascii_string, :raw => true)
         
     | 
| 
      
 152 
     | 
    
         
            +
                  _(@store.get(utf8_key, :raw => true).bytes.to_a).must_equal(ascii_string.bytes.to_a)
         
     | 
| 
      
 153 
     | 
    
         
            +
                end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                it "marshals objects on setnx" do
         
     | 
| 
      
 156 
     | 
    
         
            +
                  utf8_key = [51339].pack("U*")
         
     | 
| 
      
 157 
     | 
    
         
            +
                  ascii_rabbit = OpenStruct.new(:name => [128].pack("C*"))
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                  @store.del(utf8_key)
         
     | 
| 
      
 160 
     | 
    
         
            +
                  @store.setnx(utf8_key, ascii_rabbit)
         
     | 
| 
      
 161 
     | 
    
         
            +
                  _(@store.get(utf8_key)).must_equal(ascii_rabbit)
         
     | 
| 
      
 162 
     | 
    
         
            +
                end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                it "gets and sets raw values on setnx" do
         
     | 
| 
      
 165 
     | 
    
         
            +
                  utf8_key = [51339].pack("U*")
         
     | 
| 
      
 166 
     | 
    
         
            +
                  ascii_string = [128].pack("C*")
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
                  @store.del(utf8_key)
         
     | 
| 
      
 169 
     | 
    
         
            +
                  @store.setnx(utf8_key, ascii_string, :raw => true)
         
     | 
| 
      
 170 
     | 
    
         
            +
                  _(@store.get(utf8_key, :raw => true).bytes.to_a).must_equal(ascii_string.bytes.to_a)
         
     | 
| 
      
 171 
     | 
    
         
            +
                end
         
     | 
| 
      
 172 
     | 
    
         
            +
              end if defined?(Encoding)
         
     | 
| 
      
 173 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,142 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'test_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class MockRedis
         
     | 
| 
      
 4 
     | 
    
         
            +
              def initialize
         
     | 
| 
      
 5 
     | 
    
         
            +
                @sets = []
         
     | 
| 
      
 6 
     | 
    
         
            +
                @setexes = []
         
     | 
| 
      
 7 
     | 
    
         
            +
                @setnxes = []
         
     | 
| 
      
 8 
     | 
    
         
            +
                @expires = []
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def set(*a)
         
     | 
| 
      
 12 
     | 
    
         
            +
                @sets << a
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def has_set?(*a)
         
     | 
| 
      
 16 
     | 
    
         
            +
                @sets.include?(a)
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              def setex(*a)
         
     | 
| 
      
 20 
     | 
    
         
            +
                @setexes << a
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              def has_setex?(*a)
         
     | 
| 
      
 24 
     | 
    
         
            +
                @setexes.include?(a)
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              def setnx(*a)
         
     | 
| 
      
 28 
     | 
    
         
            +
                @setnxes << a
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              def has_setnx?(*a)
         
     | 
| 
      
 32 
     | 
    
         
            +
                @setnxes.include?(a)
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              def multi(&block)
         
     | 
| 
      
 36 
     | 
    
         
            +
                instance_eval do
         
     | 
| 
      
 37 
     | 
    
         
            +
                  def setnx(*a)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    @setnxes << a
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  block.call(self)
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
              alias_method :pipelined, :multi
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
              def expire(*a)
         
     | 
| 
      
 47 
     | 
    
         
            +
                @expires << a
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              def has_expire?(*a)
         
     | 
| 
      
 51 
     | 
    
         
            +
                @expires.include?(a)
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            class MockTtlStore < MockRedis
         
     | 
| 
      
 56 
     | 
    
         
            +
              include Redis::Store::Ttl
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            describe MockTtlStore do
         
     | 
| 
      
 60 
     | 
    
         
            +
              let(:key) { 'hello' }
         
     | 
| 
      
 61 
     | 
    
         
            +
              let(:mock_value) { 'value' }
         
     | 
| 
      
 62 
     | 
    
         
            +
              let(:options) { { :expire_after => 3600 } }
         
     | 
| 
      
 63 
     | 
    
         
            +
              let(:redis) { MockTtlStore.new }
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
              describe '#set' do
         
     | 
| 
      
 66 
     | 
    
         
            +
                describe 'without options' do
         
     | 
| 
      
 67 
     | 
    
         
            +
                  it 'must call super with key and value' do
         
     | 
| 
      
 68 
     | 
    
         
            +
                    redis.set(key, mock_value)
         
     | 
| 
      
 69 
     | 
    
         
            +
                    _(redis.has_set?(key, mock_value, nil)).must_equal true
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                describe 'with options' do
         
     | 
| 
      
 74 
     | 
    
         
            +
                  it 'must call setex with proper expiry and set raw to true' do
         
     | 
| 
      
 75 
     | 
    
         
            +
                    redis.set(key, mock_value, options)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    _(redis.has_setex?(key, options[:expire_after], mock_value, :raw => true)).must_equal true
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                describe 'with nx and ex option' do
         
     | 
| 
      
 81 
     | 
    
         
            +
                  it 'must call super with key and value and options' do
         
     | 
| 
      
 82 
     | 
    
         
            +
                    set_options = { nx: true, ex: 3600 }
         
     | 
| 
      
 83 
     | 
    
         
            +
                    redis.set(key, mock_value, set_options)
         
     | 
| 
      
 84 
     | 
    
         
            +
                    _(redis.has_set?(key, mock_value, set_options)).must_equal true
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
              describe '#setnx' do
         
     | 
| 
      
 90 
     | 
    
         
            +
                describe 'without expiry' do
         
     | 
| 
      
 91 
     | 
    
         
            +
                  it 'must call super with key and value' do
         
     | 
| 
      
 92 
     | 
    
         
            +
                    redis.setnx(key, mock_value)
         
     | 
| 
      
 93 
     | 
    
         
            +
                    redis.has_setnx?(key, mock_value)
         
     | 
| 
      
 94 
     | 
    
         
            +
                  end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                  it 'must not call expire' do
         
     | 
| 
      
 97 
     | 
    
         
            +
                    redis.expects(:expire).never
         
     | 
| 
      
 98 
     | 
    
         
            +
                    redis.setnx(key, mock_value)
         
     | 
| 
      
 99 
     | 
    
         
            +
                  end
         
     | 
| 
      
 100 
     | 
    
         
            +
                end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                describe 'with expiry' do
         
     | 
| 
      
 103 
     | 
    
         
            +
                  it 'uses the mutli command to chain commands' do
         
     | 
| 
      
 104 
     | 
    
         
            +
                    redis.expects(:multi)
         
     | 
| 
      
 105 
     | 
    
         
            +
                    redis.setnx(key, mock_value, options)
         
     | 
| 
      
 106 
     | 
    
         
            +
                  end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                  it 'must call expire' do
         
     | 
| 
      
 109 
     | 
    
         
            +
                    redis.setnx(key, mock_value, options)
         
     | 
| 
      
 110 
     | 
    
         
            +
                    _(redis.has_expire?(key, options[:expire_after])).must_equal true
         
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  describe 'avoiding multi commands' do
         
     | 
| 
      
 114 
     | 
    
         
            +
                    let(:options) { { :expire_after => 3600, :avoid_multi_commands => true } }
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                    it 'uses the redis pipelined feature to chain commands' do
         
     | 
| 
      
 117 
     | 
    
         
            +
                      redis.expects(:pipelined)
         
     | 
| 
      
 118 
     | 
    
         
            +
                      redis.setnx(key, mock_value, options)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    end
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                    it 'must call expire' do
         
     | 
| 
      
 122 
     | 
    
         
            +
                      redis.setnx(key, mock_value, options)
         
     | 
| 
      
 123 
     | 
    
         
            +
                      _(redis.has_expire?(key, options[:expire_after])).must_equal true
         
     | 
| 
      
 124 
     | 
    
         
            +
                    end
         
     | 
| 
      
 125 
     | 
    
         
            +
                  end
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                  describe 'using a redis cluster' do
         
     | 
| 
      
 128 
     | 
    
         
            +
                    let(:options) { { :expire_after => 3600, :cluster => %w[redis://127.0.0.1:6379/0] } }
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                    it 'uses the redis pipelined feature to chain commands' do
         
     | 
| 
      
 131 
     | 
    
         
            +
                      redis.expects(:pipelined)
         
     | 
| 
      
 132 
     | 
    
         
            +
                      redis.setnx(key, mock_value, options)
         
     | 
| 
      
 133 
     | 
    
         
            +
                    end
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                    it 'must call expire' do
         
     | 
| 
      
 136 
     | 
    
         
            +
                      redis.setnx(key, mock_value, options)
         
     | 
| 
      
 137 
     | 
    
         
            +
                      _(redis.has_expire?(key, options[:expire_after])).must_equal true
         
     | 
| 
      
 138 
     | 
    
         
            +
                    end
         
     | 
| 
      
 139 
     | 
    
         
            +
                  end
         
     | 
| 
      
 140 
     | 
    
         
            +
                end
         
     | 
| 
      
 141 
     | 
    
         
            +
              end
         
     | 
| 
      
 142 
     | 
    
         
            +
            end
         
     |