redis-store-json 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +15 -0
- data/.travis.yml +7 -0
- data/CHANGELOG +450 -0
- data/README.md +23 -0
- data/redis-actionpack-json/.gitignore +4 -0
- data/redis-actionpack-json/Gemfile +6 -0
- data/redis-actionpack-json/MIT-LICENSE +20 -0
- data/redis-actionpack-json/Rakefile +8 -0
- data/redis-actionpack-json/lib/action_dispatch/middleware/session/redis_store_json.rb +24 -0
- data/redis-actionpack-json/lib/redis-actionpack-json.rb +4 -0
- data/redis-actionpack-json/lib/redis/actionpack/version.rb +5 -0
- data/redis-actionpack-json/redis-actionpack-json.gemspec +32 -0
- data/redis-actionpack-json/test/dummy/.gitignore +1 -0
- data/redis-actionpack-json/test/dummy/Rakefile +7 -0
- data/redis-actionpack-json/test/dummy/app/controllers/test_controller.rb +37 -0
- data/redis-actionpack-json/test/dummy/config.ru +4 -0
- data/redis-actionpack-json/test/dummy/config/application.rb +29 -0
- data/redis-actionpack-json/test/dummy/config/boot.rb +10 -0
- data/redis-actionpack-json/test/dummy/config/environment.rb +5 -0
- data/redis-actionpack-json/test/dummy/config/initializers/secret_token.rb +7 -0
- data/redis-actionpack-json/test/dummy/config/initializers/session_store.rb +11 -0
- data/redis-actionpack-json/test/dummy/config/routes.rb +3 -0
- data/redis-actionpack-json/test/dummy/script/rails +6 -0
- data/redis-actionpack-json/test/fixtures/session_autoload_test/session_autoload_test/foo.rb +10 -0
- data/redis-actionpack-json/test/integration/redis_store_integration_test.rb +130 -0
- data/redis-actionpack-json/test/integration/redis_store_json_integration_test.rb +130 -0
- data/redis-actionpack-json/test/redis/actionpack/version_test.rb +7 -0
- data/redis-actionpack-json/test/test_helper.rb +23 -0
- data/redis-rack-json/.gitignore +5 -0
- data/redis-rack-json/Gemfile +5 -0
- data/redis-rack-json/MIT-LICENSE +20 -0
- data/redis-rack-json/Rakefile +8 -0
- data/redis-rack-json/lib/rack/session/redis.rb +69 -0
- data/redis-rack-json/lib/redis-rack-json.rb +3 -0
- data/redis-rack-json/lib/redis/rack/version.rb +6 -0
- data/redis-rack-json/redis-rack-json.gemspec +29 -0
- data/redis-rack-json/test/rack/session/redis_test.rb +289 -0
- data/redis-rack-json/test/redis/rack/version_test.rb +7 -0
- data/redis-rack-json/test/test_helper.rb +7 -0
- data/redis-store-json/Gemfile +4 -0
- data/redis-store-json/MIT-LICENSE +20 -0
- data/redis-store-json/Rakefile +7 -0
- data/redis-store-json/lib/redis-store-json.rb +11 -0
- data/redis-store-json/lib/redis/distributed_store.rb +46 -0
- data/redis-store-json/lib/redis/factory.rb +41 -0
- data/redis-store-json/lib/redis/store.rb +47 -0
- data/redis-store-json/lib/redis/store/interface.rb +21 -0
- data/redis-store-json/lib/redis/store/namespace.rb +66 -0
- data/redis-store-json/lib/redis/store/strategy.rb +60 -0
- data/redis-store-json/lib/redis/store/strategy/json.rb +49 -0
- data/redis-store-json/lib/redis/store/strategy/json_session.rb +67 -0
- data/redis-store-json/lib/redis/store/strategy/marshal.rb +16 -0
- data/redis-store-json/lib/redis/store/strategy/yaml.rb +16 -0
- data/redis-store-json/lib/redis/store/ttl.rb +37 -0
- data/redis-store-json/lib/redis/store/version.rb +5 -0
- data/redis-store-json/lib/tasks/redis.tasks.rb +167 -0
- data/redis-store-json/redis-store-json.gemspec +29 -0
- data/redis-store-json/test/config/node-one.conf +46 -0
- data/redis-store-json/test/config/node-two.conf +46 -0
- data/redis-store-json/test/config/redis.conf +46 -0
- data/redis-store-json/test/redis/distributed_store_test.rb +53 -0
- data/redis-store-json/test/redis/factory_test.rb +120 -0
- data/redis-store-json/test/redis/store/interface_test.rb +27 -0
- data/redis-store-json/test/redis/store/namespace_test.rb +103 -0
- data/redis-store-json/test/redis/store/strategy/json_session_test.rb +160 -0
- data/redis-store-json/test/redis/store/strategy/json_test.rb +108 -0
- data/redis-store-json/test/redis/store/strategy/marshal_test.rb +121 -0
- data/redis-store-json/test/redis/store/strategy/yaml_test.rb +105 -0
- data/redis-store-json/test/redis/store/ttl_test.rb +107 -0
- data/redis-store-json/test/redis/store/version_test.rb +7 -0
- data/redis-store-json/test/redis/store_test.rb +45 -0
- data/redis-store-json/test/test_helper.rb +22 -0
- metadata +215 -0
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe "Redis::Factory" do
|
4
|
+
describe ".create" do
|
5
|
+
describe "when not given any arguments" do
|
6
|
+
it "instantiates Redis::Store" do
|
7
|
+
store = Redis::Factory.create
|
8
|
+
store.must_be_kind_of(Redis::Store)
|
9
|
+
store.to_s.must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "when given a Hash" do
|
14
|
+
it "uses specified host" do
|
15
|
+
store = Redis::Factory.create :host => "localhost"
|
16
|
+
store.to_s.must_equal("Redis Client connected to localhost:6379 against DB 0")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "uses specified port" do
|
20
|
+
store = Redis::Factory.create :host => "localhost", :port => 6380
|
21
|
+
store.to_s.must_equal("Redis Client connected to localhost:6380 against DB 0")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "uses specified db" do
|
25
|
+
store = Redis::Factory.create :host => "localhost", :port => 6380, :db => 13
|
26
|
+
store.to_s.must_equal("Redis Client connected to localhost:6380 against DB 13")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "uses specified namespace" do
|
30
|
+
store = Redis::Factory.create :namespace => "theplaylist"
|
31
|
+
store.to_s.must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "uses specified key_prefix as namespace" do
|
35
|
+
store = Redis::Factory.create :key_prefix => "theplaylist"
|
36
|
+
store.to_s.must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "uses specified password" do
|
40
|
+
store = Redis::Factory.create :password => "secret"
|
41
|
+
store.instance_variable_get(:@client).password.must_equal("secret")
|
42
|
+
end
|
43
|
+
|
44
|
+
it "allows json strategy option" do
|
45
|
+
store = Redis::Factory.create :strategy => :json
|
46
|
+
store.must_be_kind_of(Redis::Store::Strategy::Json)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "allows marshal strategy option" do
|
50
|
+
store = Redis::Factory.create :strategy => :marshal
|
51
|
+
store.must_be_kind_of(Redis::Store::Strategy::Marshal)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "allows yaml strategy option" do
|
55
|
+
store = Redis::Factory.create :strategy => :yaml
|
56
|
+
store.must_be_kind_of(Redis::Store::Strategy::Yaml)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "allows false strategy option" do
|
60
|
+
store = Redis::Factory.create :strategy => false
|
61
|
+
store.wont_be_kind_of(Redis::Store::Strategy::Json)
|
62
|
+
store.wont_be_kind_of(Redis::Store::Strategy::Marshal)
|
63
|
+
store.wont_be_kind_of(Redis::Store::Strategy::Yaml)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "defaults to marshal strategy" do
|
67
|
+
store = Redis::Factory.create
|
68
|
+
store.must_be_kind_of(Redis::Store::Strategy::Marshal)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should instantiate a Redis::DistributedStore store" do
|
72
|
+
store = Redis::Factory.create(
|
73
|
+
{:host => "localhost", :port => 6379},
|
74
|
+
{:host => "localhost", :port => 6380}
|
75
|
+
)
|
76
|
+
store.must_be_kind_of(Redis::DistributedStore)
|
77
|
+
store.nodes.map {|node| node.to_s }.must_equal([
|
78
|
+
"Redis Client connected to localhost:6379 against DB 0",
|
79
|
+
"Redis Client connected to localhost:6380 against DB 0",
|
80
|
+
])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "when given a String" do
|
85
|
+
it "uses specified host" do
|
86
|
+
store = Redis::Factory.create "redis://127.0.0.1"
|
87
|
+
store.to_s.must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0")
|
88
|
+
end
|
89
|
+
|
90
|
+
it "uses specified port" do
|
91
|
+
store = Redis::Factory.create "redis://127.0.0.1:6380"
|
92
|
+
store.to_s.must_equal("Redis Client connected to 127.0.0.1:6380 against DB 0")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "uses specified db" do
|
96
|
+
store = Redis::Factory.create "redis://127.0.0.1:6380/13"
|
97
|
+
store.to_s.must_equal("Redis Client connected to 127.0.0.1:6380 against DB 13")
|
98
|
+
end
|
99
|
+
|
100
|
+
it "uses specified namespace" do
|
101
|
+
store = Redis::Factory.create "redis://127.0.0.1:6379/0/theplaylist"
|
102
|
+
store.to_s.must_equal("Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist")
|
103
|
+
end
|
104
|
+
|
105
|
+
it "uses specified password" do
|
106
|
+
store = Redis::Factory.create "redis://:secret@127.0.0.1:6379/0/theplaylist"
|
107
|
+
store.instance_variable_get(:@client).password.must_equal("secret")
|
108
|
+
end
|
109
|
+
|
110
|
+
it "instantiates Redis::DistributedStore" do
|
111
|
+
store = Redis::Factory.create "redis://127.0.0.1:6379", "redis://127.0.0.1:6380"
|
112
|
+
store.must_be_kind_of(Redis::DistributedStore)
|
113
|
+
store.nodes.map {|node| node.to_s }.must_equal([
|
114
|
+
"Redis Client connected to 127.0.0.1:6379 against DB 0",
|
115
|
+
"Redis Client connected to 127.0.0.1:6380 against DB 0",
|
116
|
+
])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class InterfacedRedis < Redis
|
4
|
+
include Redis::Store::Interface
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Redis::Store::Interface do
|
8
|
+
before do
|
9
|
+
@r = InterfacedRedis.new
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should get an element" do
|
13
|
+
lambda { @r.get("key", :option => true) } #.wont_raise ArgumentError
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should set an element" do
|
17
|
+
lambda { @r.set("key", "value", :option => true) } #.wont_raise ArgumentError
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should setnx an element" do
|
21
|
+
lambda { @r.setnx("key", "value", :option => true) } #.wont_raise ArgumentError
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should setex an element" do
|
25
|
+
lambda { @r.setex("key", 1, "value", :option => true) } #.wont_raise ArgumentError
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe "Redis::Store::Namespace" do
|
4
|
+
def setup
|
5
|
+
@namespace = "theplaylist"
|
6
|
+
@store = Redis::Store.new :namespace => @namespace, :strategy => false
|
7
|
+
@client = @store.instance_variable_get(:@client)
|
8
|
+
@rabbit = "bunny"
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
@store.quit
|
13
|
+
end
|
14
|
+
|
15
|
+
it "only decorates instances that need to be namespaced" do
|
16
|
+
store = Redis::Store.new
|
17
|
+
client = store.instance_variable_get(:@client)
|
18
|
+
client.expects(:call).with([:get, "rabbit"])
|
19
|
+
store.get("rabbit")
|
20
|
+
end
|
21
|
+
|
22
|
+
it "doesn't namespace a key which is already namespaced" do
|
23
|
+
@store.send(:interpolate, "#{@namespace}:rabbit").must_equal("#{@namespace}:rabbit")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should only delete namespaced keys" do
|
27
|
+
other_store = Redis::Store.new
|
28
|
+
|
29
|
+
other_store.set 'abc', 'cba'
|
30
|
+
@store.set 'def', 'fed'
|
31
|
+
|
32
|
+
@store.flushdb
|
33
|
+
@store.get('def').must_equal(nil)
|
34
|
+
other_store.get('abc').must_equal('cba')
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should not try to delete missing namespaced keys" do
|
38
|
+
empty_store = Redis::Store.new :namespace => 'empty'
|
39
|
+
empty_store.flushdb
|
40
|
+
empty_store.keys.must_be_empty
|
41
|
+
end
|
42
|
+
|
43
|
+
it "namespaces get"
|
44
|
+
it "namespaces set"
|
45
|
+
it "namespaces setnx"
|
46
|
+
it "namespaces del with single key"
|
47
|
+
it "namespaces del with multiple keys"
|
48
|
+
it "namespaces keys"
|
49
|
+
it "namespaces exists"
|
50
|
+
it "namespaces incrby"
|
51
|
+
it "namespaces decrby"
|
52
|
+
it "namespaces mget"
|
53
|
+
|
54
|
+
# it "should namespace get" do
|
55
|
+
# @client.expects(:call).with([:get, "#{@namespace}:rabbit"]).once
|
56
|
+
# @store.get("rabbit")
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# it "should namespace set" do
|
60
|
+
# @client.should_receive(:call).with([:set, "#{@namespace}:rabbit", @rabbit])
|
61
|
+
# @store.set "rabbit", @rabbit
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# it "should namespace setnx" do
|
65
|
+
# @client.should_receive(:call).with([:setnx, "#{@namespace}:rabbit", @rabbit])
|
66
|
+
# @store.setnx "rabbit", @rabbit
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# it "should namespace del with single key" do
|
70
|
+
# @client.should_receive(:call).with([:del, "#{@namespace}:rabbit"])
|
71
|
+
# @store.del "rabbit"
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# it "should namespace del with multiple keys" do
|
75
|
+
# @client.should_receive(:call).with([:del, "#{@namespace}:rabbit", "#{@namespace}:white_rabbit"])
|
76
|
+
# @store.del "rabbit", "white_rabbit"
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# it "should namespace keys" do
|
80
|
+
# @store.set "rabbit", @rabbit
|
81
|
+
# @store.keys("rabb*").should == [ "rabbit" ]
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# it "should namespace exists" do
|
85
|
+
# @client.should_receive(:call).with([:exists, "#{@namespace}:rabbit"])
|
86
|
+
# @store.exists "rabbit"
|
87
|
+
# end
|
88
|
+
#
|
89
|
+
# it "should namespace incrby" do
|
90
|
+
# @client.should_receive(:call).with([:incrby, "#{@namespace}:counter", 1])
|
91
|
+
# @store.incrby "counter", 1
|
92
|
+
# end
|
93
|
+
#
|
94
|
+
# it "should namespace decrby" do
|
95
|
+
# @client.should_receive(:call).with([:decrby, "#{@namespace}:counter", 1])
|
96
|
+
# @store.decrby "counter", 1
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
# it "should namespace mget" do
|
100
|
+
# @client.should_receive(:call).with([:mget, "#{@namespace}:rabbit", "#{@namespace}:white_rabbit"])
|
101
|
+
# @store.mget "rabbit", "white_rabbit"
|
102
|
+
# end
|
103
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
# For faking rails flash objects retrieved from session
|
4
|
+
module FakeActionDispatch
|
5
|
+
class Flash
|
6
|
+
class FlashHash < Hash
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "Redis::Store::Strategy::JsonSession" do
|
12
|
+
def setup
|
13
|
+
@marshal_store = Redis::Store.new :strategy => :marshal
|
14
|
+
@store = Redis::Store.new :strategy => :json_session
|
15
|
+
@rabbit = {:name => "rabbit", :legs => 4}
|
16
|
+
@peter = { :name => "Peter Cottontail",
|
17
|
+
:race => @rabbit }
|
18
|
+
@bunnicula = { :name => "Bunnicula",
|
19
|
+
:race => @rabbit,
|
20
|
+
:friends => [@peter],
|
21
|
+
:age => 3.1,
|
22
|
+
:alive => true }
|
23
|
+
@store.set "rabbit", @bunnicula
|
24
|
+
@store.del "rabbit2"
|
25
|
+
end
|
26
|
+
|
27
|
+
def teardown
|
28
|
+
@store.quit
|
29
|
+
end
|
30
|
+
|
31
|
+
it "unmarshals on get" do
|
32
|
+
@store.get("rabbit").must_equal(@bunnicula)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "marshals on set" do
|
36
|
+
@store.set "rabbit", @peter
|
37
|
+
@store.get("rabbit").must_equal(@peter)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "doesn't unmarshal on get if raw option is true" do
|
41
|
+
race = @rabbit.to_json
|
42
|
+
@store.get("rabbit", :raw => true).must_equal(%({"name":"Bunnicula","race":#{race},"friends":[{"name":"Peter Cottontail","race":#{race}}],"age":3.1,"alive":true}))
|
43
|
+
end
|
44
|
+
|
45
|
+
it "doesn't marshal on set if raw option is true" do
|
46
|
+
race = @rabbit
|
47
|
+
@store.set "rabbit", @peter, :raw => true
|
48
|
+
@store.get("rabbit", :raw => true).must_equal(%({:name=>"Peter Cottontail", :race=>#{race.inspect}}))
|
49
|
+
end
|
50
|
+
|
51
|
+
it "doesn't set an object if already exist" do
|
52
|
+
@store.setnx "rabbit", @peter
|
53
|
+
@store.get("rabbit").must_equal(@bunnicula)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "marshals on set unless exists" do
|
57
|
+
@store.setnx "rabbit2", @peter
|
58
|
+
@store.get("rabbit2").must_equal(@peter)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "doesn't marshal on set unless exists if raw option is true" do
|
62
|
+
@store.setnx "rabbit2", @peter, :raw => true
|
63
|
+
race = @rabbit
|
64
|
+
@store.get("rabbit2", :raw => true).must_equal(%({:name=>"Peter Cottontail", :race=>#{race.inspect}}))
|
65
|
+
end
|
66
|
+
|
67
|
+
it "doesn't unmarshal on multi get" do
|
68
|
+
@store.set "rabbit2", @peter
|
69
|
+
rabbit, rabbit2 = @store.mget "rabbit", "rabbit2"
|
70
|
+
rabbit.must_equal(@bunnicula)
|
71
|
+
rabbit2.must_equal(@peter)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "doesn't unmarshal on multi get if raw option is true" do
|
75
|
+
@store.set "rabbit", @bunnicula
|
76
|
+
@store.set "rabbit2", @peter
|
77
|
+
rabbit, rabbit2 = @store.mget "rabbit", "rabbit2", :raw => true
|
78
|
+
race = @rabbit.to_json
|
79
|
+
rabbit.must_equal(%({"name":"Bunnicula","race":#{race},"friends":[{"name":"Peter Cottontail","race":#{race}}],"age":3.1,"alive":true}))
|
80
|
+
rabbit2.must_equal(%({"name":"Peter Cottontail","race":#{race}}))
|
81
|
+
end
|
82
|
+
|
83
|
+
it "will throw an error if an object isn't supported" do
|
84
|
+
lambda{
|
85
|
+
@store.set "rabbit2", OpenStruct.new(foo:'bar')
|
86
|
+
}.must_raise Redis::Store::Strategy::JsonSession::SerializationError
|
87
|
+
end
|
88
|
+
|
89
|
+
it "is able to bring out data that is marshalled using Ruby" do
|
90
|
+
@marshal_store.set "rabbit", @peter
|
91
|
+
rabbit = @store.get "rabbit"
|
92
|
+
rabbit.must_equal(@peter)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "can set a Set object" do
|
96
|
+
@store.set "set_object", Set.new([1,2])
|
97
|
+
set_object = @store.get("set_object")
|
98
|
+
set_object.must_equal([1,2])
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "flash key value" do
|
102
|
+
|
103
|
+
before do
|
104
|
+
@flash_value = {:show_login => true }
|
105
|
+
@flash_data = {:flash => @flash_value}
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "when ActionDispatch is available" do
|
109
|
+
|
110
|
+
before do
|
111
|
+
ActionDispatch = FakeActionDispatch
|
112
|
+
@store.class.send(:include, ActionDispatch)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "returns a flash object instead of a hash" do
|
116
|
+
@store.set "flash", @flash_data
|
117
|
+
flash_store = @store.get "flash"
|
118
|
+
flash_hash = flash_store[:flash]
|
119
|
+
flash_hash.class.must_equal(FakeActionDispatch::Flash::FlashHash)
|
120
|
+
flash_hash.must_equal(@flash_value)
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
it "returns a hash" do
|
126
|
+
@store.set "flash", @flash_data
|
127
|
+
flash = @store.get "flash"
|
128
|
+
flash.must_equal(@flash_data)
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "binary safety" do
|
134
|
+
before do
|
135
|
+
@utf8_key = [51339].pack("U*")
|
136
|
+
@ascii_string = [128].pack("C*")
|
137
|
+
@ascii_rabbit = {:name => "rabbit", :legs => 4, :ascii_string => @ascii_string}
|
138
|
+
end
|
139
|
+
|
140
|
+
it "gets and sets raw values" do
|
141
|
+
@store.set(@utf8_key, @ascii_string, :raw => true)
|
142
|
+
@store.get(@utf8_key, :raw => true).bytes.to_a.must_equal(@ascii_string.bytes.to_a)
|
143
|
+
end
|
144
|
+
|
145
|
+
it "marshals objects on setnx" do
|
146
|
+
@store.del(@utf8_key)
|
147
|
+
@store.setnx(@utf8_key, @ascii_rabbit)
|
148
|
+
retrievied_ascii_rabbit = @store.get(@utf8_key)
|
149
|
+
JSON.load(JSON.generate(retrievied_ascii_rabbit.delete(:ascii_string))).must_equal(@ascii_string)
|
150
|
+
@ascii_rabbit.delete(:ascii_string)
|
151
|
+
retrievied_ascii_rabbit.must_equal(@ascii_rabbit)
|
152
|
+
end
|
153
|
+
|
154
|
+
it "gets and sets raw values on setnx" do
|
155
|
+
@store.del(@utf8_key)
|
156
|
+
@store.setnx(@utf8_key, @ascii_string, :raw => true)
|
157
|
+
@store.get(@utf8_key, :raw => true).bytes.to_a.must_equal(@ascii_string.bytes.to_a)
|
158
|
+
end
|
159
|
+
end if defined?(Encoding)
|
160
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe "Redis::Store::Strategy::Json" do
|
4
|
+
def setup
|
5
|
+
@store = Redis::Store.new :strategy => :json
|
6
|
+
@rabbit = OpenStruct.new :name => 'rabbit', :legs => 4
|
7
|
+
@peter = { :name => "Peter Cottontail",
|
8
|
+
:race => @rabbit }
|
9
|
+
@bunnicula = { :name => "Bunnicula",
|
10
|
+
:race => @rabbit,
|
11
|
+
:friends => [@peter],
|
12
|
+
:age => 3.1,
|
13
|
+
:alive => true }
|
14
|
+
@store.set "rabbit", @bunnicula
|
15
|
+
@store.del "rabbit2"
|
16
|
+
end
|
17
|
+
|
18
|
+
def teardown
|
19
|
+
@store.quit
|
20
|
+
end
|
21
|
+
|
22
|
+
it "unmarshals on get" do
|
23
|
+
@store.get("rabbit").must_equal(@bunnicula)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "marshals on set" do
|
27
|
+
@store.set "rabbit", @peter
|
28
|
+
@store.get("rabbit").must_equal(@peter)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "doesn't unmarshal on get if raw option is true" do
|
32
|
+
race = Marshal.dump(@rabbit).to_json
|
33
|
+
@store.get("rabbit", :raw => true).must_equal(%({"name":"Bunnicula","race":#{race},"friends":[{"name":"Peter Cottontail","race":#{race}}],"age":3.1,"alive":true}))
|
34
|
+
end
|
35
|
+
|
36
|
+
it "doesn't marshal on set if raw option is true" do
|
37
|
+
race = Marshal.dump(@rabbit)
|
38
|
+
@store.set "rabbit", @peter, :raw => true
|
39
|
+
@store.get("rabbit", :raw => true).must_equal(%({:name=>"Peter Cottontail", :race=>#{race.inspect}}))
|
40
|
+
end
|
41
|
+
|
42
|
+
it "doesn't set an object if already exist" do
|
43
|
+
@store.setnx "rabbit", @peter
|
44
|
+
@store.get("rabbit").must_equal(@bunnicula)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "marshals on set unless exists" do
|
48
|
+
@store.setnx "rabbit2", @peter
|
49
|
+
@store.get("rabbit2").must_equal(@peter)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "doesn't marshal on set unless exists if raw option is true" do
|
53
|
+
@store.setnx "rabbit2", @peter, :raw => true
|
54
|
+
race = Marshal.dump(@rabbit)
|
55
|
+
@store.get("rabbit2", :raw => true).must_equal(%({:name=>"Peter Cottontail", :race=>#{race.inspect}}))
|
56
|
+
end
|
57
|
+
|
58
|
+
it "marshals on set expire" do
|
59
|
+
@store.setex "rabbit2", 1, @peter
|
60
|
+
@store.get("rabbit2").must_equal(@peter)
|
61
|
+
sleep 2
|
62
|
+
@store.get("rabbit2").must_be_nil
|
63
|
+
end
|
64
|
+
|
65
|
+
it "doesn't unmarshal on multi get" do
|
66
|
+
@store.set "rabbit2", @peter
|
67
|
+
rabbit, rabbit2 = @store.mget "rabbit", "rabbit2"
|
68
|
+
rabbit.must_equal(@bunnicula)
|
69
|
+
rabbit2.must_equal(@peter)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "doesn't unmarshal on multi get if raw option is true" do
|
73
|
+
@store.set "rabbit", @bunnicula
|
74
|
+
@store.set "rabbit2", @peter
|
75
|
+
rabbit, rabbit2 = @store.mget "rabbit", "rabbit2", :raw => true
|
76
|
+
race = Marshal.dump(@rabbit).to_json
|
77
|
+
rabbit.must_equal(%({"name":"Bunnicula","race":#{race},"friends":[{"name":"Peter Cottontail","race":#{race}}],"age":3.1,"alive":true}))
|
78
|
+
rabbit2.must_equal(%({"name":"Peter Cottontail","race":#{race}}))
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "binary safety" do
|
82
|
+
before do
|
83
|
+
@utf8_key = [51339].pack("U*")
|
84
|
+
@ascii_string = [128].pack("C*")
|
85
|
+
@ascii_rabbit = OpenStruct.new(:name => @ascii_string)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "marshals objects"
|
89
|
+
# @store.set(@utf8_key, @ascii_rabbit)
|
90
|
+
# @store.get(@utf8_key).must_equal(@ascii_rabbit)
|
91
|
+
|
92
|
+
it "gets and sets raw values" do
|
93
|
+
@store.set(@utf8_key, @ascii_string, :raw => true)
|
94
|
+
@store.get(@utf8_key, :raw => true).bytes.to_a.must_equal(@ascii_string.bytes.to_a)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "marshals objects on setnx"
|
98
|
+
# @store.del(@utf8_key)
|
99
|
+
# @store.setnx(@utf8_key, @ascii_rabbit)
|
100
|
+
# @store.get(@utf8_key).must_equal(@ascii_rabbit)
|
101
|
+
|
102
|
+
it "gets and sets raw values on setnx" do
|
103
|
+
@store.del(@utf8_key)
|
104
|
+
@store.setnx(@utf8_key, @ascii_string, :raw => true)
|
105
|
+
@store.get(@utf8_key, :raw => true).bytes.to_a.must_equal(@ascii_string.bytes.to_a)
|
106
|
+
end
|
107
|
+
end if defined?(Encoding)
|
108
|
+
end
|