juno 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +5 -1
- data/Gemfile +27 -21
- data/README.md +41 -2
- data/Rakefile +3 -3
- data/juno.gemspec +12 -12
- data/lib/juno.rb +4 -4
- data/lib/juno/adapters/couch.rb +1 -1
- data/lib/juno/adapters/datamapper.rb +1 -1
- data/lib/juno/adapters/dbm.rb +1 -1
- data/lib/juno/adapters/file.rb +1 -1
- data/lib/juno/adapters/fog.rb +1 -1
- data/lib/juno/adapters/gdbm.rb +1 -1
- data/lib/juno/adapters/localmemcache.rb +1 -1
- data/lib/juno/adapters/pstore.rb +1 -1
- data/lib/juno/adapters/redis.rb +3 -2
- data/lib/juno/adapters/sdbm.rb +1 -1
- data/lib/juno/adapters/sequel.rb +1 -1
- data/lib/juno/adapters/sqlite.rb +1 -1
- data/lib/juno/adapters/tokyocabinet.rb +1 -1
- data/lib/juno/builder.rb +10 -0
- data/lib/juno/cache.rb +1 -0
- data/lib/juno/expires.rb +1 -1
- data/lib/juno/proxy.rb +2 -0
- data/lib/juno/stack.rb +1 -0
- data/lib/juno/transformer.rb +34 -18
- data/lib/juno/version.rb +1 -1
- data/lib/rack/cache/juno.rb +93 -0
- data/lib/rack/session/juno.rb +63 -0
- data/spec/generate.rb +41 -2
- data/spec/{adapter_activerecord_spec.rb → juno/adapter_activerecord_spec.rb} +0 -0
- data/spec/{adapter_cassandra_spec.rb → juno/adapter_cassandra_spec.rb} +0 -0
- data/spec/{adapter_couch_spec.rb → juno/adapter_couch_spec.rb} +0 -0
- data/spec/{adapter_datamapper_spec.rb → juno/adapter_datamapper_spec.rb} +0 -0
- data/spec/{adapter_dbm_spec.rb → juno/adapter_dbm_spec.rb} +0 -0
- data/spec/{adapter_file_spec.rb → juno/adapter_file_spec.rb} +0 -0
- data/spec/{adapter_fog_spec.rb → juno/adapter_fog_spec.rb} +0 -0
- data/spec/{adapter_gdbm_spec.rb → juno/adapter_gdbm_spec.rb} +0 -0
- data/spec/{adapter_localmemcache_spec.rb → juno/adapter_localmemcache_spec.rb} +0 -0
- data/spec/{adapter_lruhash_spec.rb → juno/adapter_lruhash_spec.rb} +0 -0
- data/spec/{adapter_memcached_dalli_spec.rb → juno/adapter_memcached_dalli_spec.rb} +0 -0
- data/spec/{adapter_memcached_native_spec.rb → juno/adapter_memcached_native_spec.rb} +0 -0
- data/spec/{adapter_memcached_spec.rb → juno/adapter_memcached_spec.rb} +0 -0
- data/spec/{adapter_memory_spec.rb → juno/adapter_memory_spec.rb} +0 -0
- data/spec/{adapter_mongo_spec.rb → juno/adapter_mongo_spec.rb} +0 -0
- data/spec/{adapter_pstore_spec.rb → juno/adapter_pstore_spec.rb} +0 -0
- data/spec/{adapter_redis_spec.rb → juno/adapter_redis_spec.rb} +0 -0
- data/spec/{adapter_riak_spec.rb → juno/adapter_riak_spec.rb} +0 -0
- data/spec/{adapter_sdbm_spec.rb → juno/adapter_sdbm_spec.rb} +0 -0
- data/spec/{adapter_sequel_spec.rb → juno/adapter_sequel_spec.rb} +0 -0
- data/spec/{adapter_sqlite_spec.rb → juno/adapter_sqlite_spec.rb} +0 -0
- data/spec/{adapter_tokyocabinet_bdb_spec.rb → juno/adapter_tokyocabinet_bdb_spec.rb} +0 -0
- data/spec/{adapter_tokyocabinet_hdb_spec.rb → juno/adapter_tokyocabinet_hdb_spec.rb} +0 -0
- data/spec/{adapter_yaml_spec.rb → juno/adapter_yaml_spec.rb} +0 -0
- data/spec/{cache_file_memory_spec.rb → juno/cache_file_memory_spec.rb} +0 -0
- data/spec/{cache_memory_null_spec.rb → juno/cache_memory_null_spec.rb} +0 -0
- data/spec/{expires_file_spec.rb → juno/expires_file_spec.rb} +0 -0
- data/spec/{expires_memory_spec.rb → juno/expires_memory_spec.rb} +0 -0
- data/spec/{lock_spec.rb → juno/lock_spec.rb} +0 -0
- data/spec/{null_adapter_spec.rb → juno/null_adapter_spec.rb} +0 -0
- data/spec/{proxy_expires_memory_spec.rb → juno/proxy_expires_memory_spec.rb} +0 -0
- data/spec/{proxy_redis_spec.rb → juno/proxy_redis_spec.rb} +0 -0
- data/spec/{simple_activerecord_spec.rb → juno/simple_activerecord_spec.rb} +0 -0
- data/spec/{simple_activerecord_with_expires_spec.rb → juno/simple_activerecord_with_expires_spec.rb} +0 -0
- data/spec/{simple_cassandra_spec.rb → juno/simple_cassandra_spec.rb} +0 -0
- data/spec/{simple_couch_spec.rb → juno/simple_couch_spec.rb} +0 -0
- data/spec/{simple_couch_with_expires_spec.rb → juno/simple_couch_with_expires_spec.rb} +0 -0
- data/spec/{simple_datamapper_spec.rb → juno/simple_datamapper_spec.rb} +0 -0
- data/spec/{simple_datamapper_with_expires_spec.rb → juno/simple_datamapper_with_expires_spec.rb} +0 -0
- data/spec/{simple_datamapper_with_repository_spec.rb → juno/simple_datamapper_with_repository_spec.rb} +0 -0
- data/spec/{simple_dbm_spec.rb → juno/simple_dbm_spec.rb} +0 -0
- data/spec/{simple_dbm_with_expires_spec.rb → juno/simple_dbm_with_expires_spec.rb} +0 -0
- data/spec/{simple_file_spec.rb → juno/simple_file_spec.rb} +0 -0
- data/spec/{simple_file_with_expires_spec.rb → juno/simple_file_with_expires_spec.rb} +0 -0
- data/spec/{simple_fog_spec.rb → juno/simple_fog_spec.rb} +0 -0
- data/spec/{simple_fog_with_expires_spec.rb → juno/simple_fog_with_expires_spec.rb} +0 -0
- data/spec/{simple_gdbm_spec.rb → juno/simple_gdbm_spec.rb} +0 -0
- data/spec/{simple_gdbm_with_expires_spec.rb → juno/simple_gdbm_with_expires_spec.rb} +0 -0
- data/spec/{simple_hashfile_spec.rb → juno/simple_hashfile_spec.rb} +0 -0
- data/spec/{simple_hashfile_with_expires_spec.rb → juno/simple_hashfile_with_expires_spec.rb} +0 -0
- data/spec/{simple_localmemcache_spec.rb → juno/simple_localmemcache_spec.rb} +0 -0
- data/spec/{simple_localmemcache_with_expires_spec.rb → juno/simple_localmemcache_with_expires_spec.rb} +0 -0
- data/spec/{simple_lruhash_spec.rb → juno/simple_lruhash_spec.rb} +0 -0
- data/spec/{simple_lruhash_with_expires_spec.rb → juno/simple_lruhash_with_expires_spec.rb} +0 -0
- data/spec/{simple_memcached_dalli_spec.rb → juno/simple_memcached_dalli_spec.rb} +0 -0
- data/spec/{simple_memcached_native_spec.rb → juno/simple_memcached_native_spec.rb} +0 -0
- data/spec/{simple_memcached_spec.rb → juno/simple_memcached_spec.rb} +0 -0
- data/spec/{simple_memory_spec.rb → juno/simple_memory_spec.rb} +0 -0
- data/spec/{simple_memory_with_expires_spec.rb → juno/simple_memory_with_expires_spec.rb} +0 -0
- data/spec/{simple_mongo_spec.rb → juno/simple_mongo_spec.rb} +0 -0
- data/spec/{simple_mongo_with_expires_spec.rb → juno/simple_mongo_with_expires_spec.rb} +0 -0
- data/spec/{simple_null_spec.rb → juno/simple_null_spec.rb} +0 -0
- data/spec/{simple_pstore_spec.rb → juno/simple_pstore_spec.rb} +0 -0
- data/spec/{simple_pstore_with_expires_spec.rb → juno/simple_pstore_with_expires_spec.rb} +0 -0
- data/spec/{simple_redis_spec.rb → juno/simple_redis_spec.rb} +0 -0
- data/spec/{simple_riak_spec.rb → juno/simple_riak_spec.rb} +0 -0
- data/spec/{simple_riak_with_expires_spec.rb → juno/simple_riak_with_expires_spec.rb} +0 -0
- data/spec/{simple_sdbm_spec.rb → juno/simple_sdbm_spec.rb} +0 -0
- data/spec/{simple_sdbm_with_expires_spec.rb → juno/simple_sdbm_with_expires_spec.rb} +0 -0
- data/spec/{simple_sequel_spec.rb → juno/simple_sequel_spec.rb} +0 -0
- data/spec/{simple_sequel_with_expires_spec.rb → juno/simple_sequel_with_expires_spec.rb} +0 -0
- data/spec/{simple_sqlite_spec.rb → juno/simple_sqlite_spec.rb} +0 -0
- data/spec/{simple_sqlite_with_expires_spec.rb → juno/simple_sqlite_with_expires_spec.rb} +0 -0
- data/spec/{simple_tokyocabinet_spec.rb → juno/simple_tokyocabinet_spec.rb} +0 -0
- data/spec/{simple_tokyocabinet_with_expires_spec.rb → juno/simple_tokyocabinet_with_expires_spec.rb} +0 -0
- data/spec/{simple_yaml_spec.rb → juno/simple_yaml_spec.rb} +0 -0
- data/spec/{simple_yaml_with_expires_spec.rb → juno/simple_yaml_with_expires_spec.rb} +0 -0
- data/spec/{stack_file_memory_spec.rb → juno/stack_file_memory_spec.rb} +0 -0
- data/spec/{stack_memory_file_spec.rb → juno/stack_memory_file_spec.rb} +0 -0
- data/spec/{transformer_bencode_spec.rb → juno/transformer_bencode_spec.rb} +0 -0
- data/spec/{transformer_bert_spec.rb → juno/transformer_bert_spec.rb} +0 -0
- data/spec/{transformer_bson_spec.rb → juno/transformer_bson_spec.rb} +0 -0
- data/spec/{transformer_compress_spec.rb → juno/transformer_compress_spec.rb} +0 -0
- data/spec/{transformer_json_spec.rb → juno/transformer_json_spec.rb} +0 -0
- data/spec/juno/transformer_lzma_spec.rb +22 -0
- data/spec/juno/transformer_lzo_spec.rb +22 -0
- data/spec/{transformer_marshal_base64_spec.rb → juno/transformer_marshal_base64_spec.rb} +0 -0
- data/spec/{transformer_marshal_escape_spec.rb → juno/transformer_marshal_escape_spec.rb} +0 -0
- data/spec/{transformer_marshal_md5_spec.rb → juno/transformer_marshal_md5_spec.rb} +0 -0
- data/spec/{transformer_marshal_md5_spread_spec.rb → juno/transformer_marshal_md5_spread_spec.rb} +0 -0
- data/spec/juno/transformer_marshal_prefix_spec.rb +41 -0
- data/spec/{transformer_marshal_uuencode_spec.rb → juno/transformer_marshal_uuencode_spec.rb} +0 -0
- data/spec/{transformer_msgpack_spec.rb → juno/transformer_msgpack_spec.rb} +0 -0
- data/spec/{transformer_ox_spec.rb → juno/transformer_ox_spec.rb} +0 -0
- data/spec/juno/transformer_quicklz_spec.rb +22 -0
- data/spec/juno/transformer_snappy_spec.rb +22 -0
- data/spec/{transformer_tnet_spec.rb → juno/transformer_tnet_spec.rb} +0 -0
- data/spec/{transformer_yaml_spec.rb → juno/transformer_yaml_spec.rb} +0 -0
- data/spec/rack/cache_juno_spec.rb +355 -0
- data/spec/rack/session_juno_spec.rb +305 -0
- metadata +206 -190
data/lib/juno/version.rb
CHANGED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'juno'
|
2
|
+
require 'rack/cache/key'
|
3
|
+
require 'rack/cache/metastore'
|
4
|
+
require 'rack/cache/entitystore'
|
5
|
+
|
6
|
+
module Rack
|
7
|
+
module Cache
|
8
|
+
Juno = {}
|
9
|
+
|
10
|
+
module JunoResolver
|
11
|
+
include Rack::Utils
|
12
|
+
|
13
|
+
def resolve(uri)
|
14
|
+
cache = Rack::Cache::Juno[uri.to_s.sub(%r{^juno://}, '')] ||=
|
15
|
+
begin
|
16
|
+
options = parse_query(uri.query)
|
17
|
+
options.keys.each do |key|
|
18
|
+
options[key.to_sym] =
|
19
|
+
case value = options.delete(key)
|
20
|
+
when 'true'; true
|
21
|
+
when 'false'; false
|
22
|
+
else value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
::Juno.new(uri.host.to_sym, options)
|
26
|
+
end
|
27
|
+
new(cache)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class MetaStore
|
32
|
+
class Juno < MetaStore
|
33
|
+
extend JunoResolver
|
34
|
+
|
35
|
+
def initialize(cache)
|
36
|
+
@cache = cache
|
37
|
+
end
|
38
|
+
|
39
|
+
def read(key)
|
40
|
+
@cache[key] || []
|
41
|
+
end
|
42
|
+
|
43
|
+
def write(key, entries)
|
44
|
+
@cache[key] = entries
|
45
|
+
end
|
46
|
+
|
47
|
+
def purge(key)
|
48
|
+
@cache.delete(key)
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
JUNO = Juno
|
54
|
+
end
|
55
|
+
|
56
|
+
class EntityStore
|
57
|
+
class Juno < EntityStore
|
58
|
+
extend JunoResolver
|
59
|
+
|
60
|
+
def initialize(cache)
|
61
|
+
@cache = cache
|
62
|
+
end
|
63
|
+
|
64
|
+
def open(key)
|
65
|
+
data = read(key)
|
66
|
+
data && [data]
|
67
|
+
end
|
68
|
+
|
69
|
+
def exist?(key)
|
70
|
+
@cache.key?(key)
|
71
|
+
end
|
72
|
+
|
73
|
+
def read(key)
|
74
|
+
@cache[key]
|
75
|
+
end
|
76
|
+
|
77
|
+
def write(body, ttl = 0)
|
78
|
+
buf = StringIO.new
|
79
|
+
key, size = slurp(body) { |part| buf.write(part) }
|
80
|
+
@cache.store(key, buf.string, ttl == 0 ? {} : {:expires => ttl})
|
81
|
+
[key, size]
|
82
|
+
end
|
83
|
+
|
84
|
+
def purge(key)
|
85
|
+
@cache.delete(key)
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
JUNO = Juno
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'juno'
|
2
|
+
require 'rack/session/abstract/id'
|
3
|
+
require 'thread'
|
4
|
+
|
5
|
+
module Rack
|
6
|
+
module Session
|
7
|
+
class Juno < Abstract::ID
|
8
|
+
attr_reader :mutex, :pool
|
9
|
+
|
10
|
+
def initialize(app, options = {}, &block)
|
11
|
+
super
|
12
|
+
if block
|
13
|
+
raise 'Use either block or option :store' if options[:store]
|
14
|
+
@pool = ::Juno.build(&block)
|
15
|
+
else
|
16
|
+
raise 'Option :store is required' unless @pool = options[:store]
|
17
|
+
@pool = ::Juno.new(@pool, :expires => true) if Symbol === @pool
|
18
|
+
end
|
19
|
+
@mutex = Mutex.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate_sid
|
23
|
+
loop do
|
24
|
+
sid = super
|
25
|
+
break sid unless @pool.key?(sid)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_session(env, sid)
|
30
|
+
with_lock(env) do
|
31
|
+
unless sid && session = @pool[sid]
|
32
|
+
sid, session = generate_sid, {}
|
33
|
+
@pool[sid] = session
|
34
|
+
end
|
35
|
+
[sid, session]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_session(env, session_id, new_session, options)
|
40
|
+
with_lock(env) do
|
41
|
+
@pool.store(session_id, new_session,
|
42
|
+
options[:expire_after] ? {:expires => options[:expire_after]} : {})
|
43
|
+
session_id
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def destroy_session(env, session_id, options)
|
48
|
+
with_lock(env) do
|
49
|
+
@pool.delete(session_id)
|
50
|
+
generate_sid unless options[:drop]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def with_lock(env)
|
55
|
+
@mutex.lock if env['rack.multithread']
|
56
|
+
yield
|
57
|
+
ensure
|
58
|
+
@mutex.unlock if @mutex.locked?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
data/spec/generate.rb
CHANGED
@@ -336,6 +336,38 @@ end},
|
|
336
336
|
:build => %{Juno.build do
|
337
337
|
use :Transformer, :value => :compress
|
338
338
|
adapter :Memory
|
339
|
+
end},
|
340
|
+
:value => %w(String),
|
341
|
+
:specs => [:null, :store, :returndifferent]
|
342
|
+
},
|
343
|
+
'transformer_lzo' => {
|
344
|
+
:build => %{Juno.build do
|
345
|
+
use :Transformer, :value => :lzo
|
346
|
+
adapter :Memory
|
347
|
+
end},
|
348
|
+
:value => %w(String),
|
349
|
+
:specs => [:null, :store, :returndifferent]
|
350
|
+
},
|
351
|
+
'transformer_lzma' => {
|
352
|
+
:build => %{Juno.build do
|
353
|
+
use :Transformer, :value => :lzma
|
354
|
+
adapter :Memory
|
355
|
+
end},
|
356
|
+
:value => %w(String),
|
357
|
+
:specs => [:null, :store, :returndifferent]
|
358
|
+
},
|
359
|
+
'transformer_snappy' => {
|
360
|
+
:build => %{Juno.build do
|
361
|
+
use :Transformer, :value => :snappy
|
362
|
+
adapter :Memory
|
363
|
+
end},
|
364
|
+
:value => %w(String),
|
365
|
+
:specs => [:null, :store, :returndifferent]
|
366
|
+
},
|
367
|
+
'transformer_quicklz' => {
|
368
|
+
:build => %{Juno.build do
|
369
|
+
use :Transformer, :value => :quicklz
|
370
|
+
adapter :Memory
|
339
371
|
end},
|
340
372
|
:value => %w(String),
|
341
373
|
:specs => [:null, :store, :returndifferent]
|
@@ -412,6 +444,13 @@ end},
|
|
412
444
|
:build => %{Juno.build do
|
413
445
|
use :Transformer, :key => [:marshal, :base64], :value => [:marshal, :base64]
|
414
446
|
adapter :Memory
|
447
|
+
end},
|
448
|
+
:specs => [:null, :store, :returndifferent, :marshallable_key]
|
449
|
+
},
|
450
|
+
'transformer_marshal_prefix' => {
|
451
|
+
:build => %{Juno.build do
|
452
|
+
use :Transformer, :key => [:marshal, :prefix], :value => :marshal, :prefix => 'juno'
|
453
|
+
adapter :Memory
|
415
454
|
end},
|
416
455
|
:specs => [:null, :store, :returndifferent, :marshallable_key]
|
417
456
|
},
|
@@ -831,7 +870,7 @@ SPECS.each do |key, code|
|
|
831
870
|
"shared_examples_for '#{key}' do\n " << code.gsub("\n", "\n ") << "\nend\n\n"
|
832
871
|
end
|
833
872
|
specs_code.gsub!(/\n +\n/, "\n\n")
|
834
|
-
File.open(File.join(File.dirname(__FILE__),
|
873
|
+
File.open(File.join(File.dirname(__FILE__), 'junospecs.rb'), 'w') {|out| out << specs_code }
|
835
874
|
|
836
875
|
TESTS.each do |name, options|
|
837
876
|
build = options.delete(:build)
|
@@ -870,5 +909,5 @@ end
|
|
870
909
|
}
|
871
910
|
|
872
911
|
code.gsub!(/\n +\n/, "\n\n")
|
873
|
-
File.open(File.join(File.dirname(__FILE__), "#{name}_spec.rb"), 'w') {|out| out << code }
|
912
|
+
File.open(File.join(File.dirname(__FILE__), 'juno', "#{name}_spec.rb"), 'w') {|out| out << code }
|
874
913
|
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/spec/{simple_activerecord_with_expires_spec.rb → juno/simple_activerecord_with_expires_spec.rb}
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/spec/{simple_datamapper_with_expires_spec.rb → juno/simple_datamapper_with_expires_spec.rb}
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/spec/{simple_hashfile_with_expires_spec.rb → juno/simple_hashfile_with_expires_spec.rb}
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/spec/{simple_tokyocabinet_with_expires_spec.rb → juno/simple_tokyocabinet_with_expires_spec.rb}
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Generated by generate.rb
|
2
|
+
require 'helper'
|
3
|
+
|
4
|
+
describe_juno "transformer_lzma" do
|
5
|
+
def new_store
|
6
|
+
Juno.build do
|
7
|
+
use :Transformer, :value => :lzma
|
8
|
+
adapter :Memory
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
include_context 'setup_store'
|
13
|
+
it_should_behave_like 'null_objectkey_stringvalue'
|
14
|
+
it_should_behave_like 'null_stringkey_stringvalue'
|
15
|
+
it_should_behave_like 'null_hashkey_stringvalue'
|
16
|
+
it_should_behave_like 'store_objectkey_stringvalue'
|
17
|
+
it_should_behave_like 'store_stringkey_stringvalue'
|
18
|
+
it_should_behave_like 'store_hashkey_stringvalue'
|
19
|
+
it_should_behave_like 'returndifferent_objectkey_stringvalue'
|
20
|
+
it_should_behave_like 'returndifferent_stringkey_stringvalue'
|
21
|
+
it_should_behave_like 'returndifferent_hashkey_stringvalue'
|
22
|
+
end
|