juno 0.2.7 → 0.2.8
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/README.md +19 -2
- data/Rakefile +1 -1
- data/juno.gemspec +2 -2
- data/lib/juno.rb +7 -7
- data/lib/juno/adapters/cookie.rb +35 -0
- data/lib/juno/builder.rb +2 -4
- data/lib/juno/cache.rb +1 -2
- data/lib/juno/stack.rb +1 -2
- data/lib/juno/transformer.rb +68 -63
- data/lib/juno/version.rb +1 -1
- data/lib/rack/juno_cookies.rb +62 -0
- data/spec/generate.rb +4 -0
- data/spec/juno/adapter_cookie_spec.rb +13 -0
- data/spec/rack/juno_cookies_spec.rb +81 -0
- metadata +10 -6
data/README.md
CHANGED
@@ -210,6 +210,22 @@ use Rack::Cache,
|
|
210
210
|
:entity_store => 'juno://named_entitystore'
|
211
211
|
~~~
|
212
212
|
|
213
|
+
Use Juno to store cookies in Rack:
|
214
|
+
|
215
|
+
~~~ ruby
|
216
|
+
require 'rack/juno_cookies'
|
217
|
+
|
218
|
+
use Rack::JunoCookies, :domain => 'example.com', :path => '/path'
|
219
|
+
run lambda { |env|
|
220
|
+
req = Rack::Request.new(env)
|
221
|
+
req.cookies #=> is now a Juno store!!
|
222
|
+
req.cookies['key'] #=> retrieves 'key'
|
223
|
+
req.cookies['key'] = 'value' #=> sets 'key'
|
224
|
+
req.cookies.delete('key') #=> removes 'key'
|
225
|
+
[200,{},[]]
|
226
|
+
}
|
227
|
+
~~~
|
228
|
+
|
213
229
|
Alternatives
|
214
230
|
------------
|
215
231
|
|
@@ -221,5 +237,6 @@ Alternatives
|
|
221
237
|
Authors
|
222
238
|
-------
|
223
239
|
|
224
|
-
*
|
225
|
-
*
|
240
|
+
* Daniel Mendler
|
241
|
+
* Hannes Georg
|
242
|
+
* Moneta originally by Yehuda Katz and contributors
|
data/Rakefile
CHANGED
@@ -15,7 +15,7 @@ namespace :test do
|
|
15
15
|
puts 'No tests executed in parallel in JRuby'
|
16
16
|
else
|
17
17
|
specs = Dir['spec/*/*_spec.rb'].reject {|s| s =~ /memcached|redis/ }
|
18
|
-
sh("parallel_rspec -m
|
18
|
+
sh("parallel_rspec -m 5 #{specs.join(' ')}")
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
data/juno.gemspec
CHANGED
@@ -6,8 +6,8 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = 'juno'
|
7
7
|
s.version = Juno::VERSION
|
8
8
|
s.date = Date.today.to_s
|
9
|
-
s.authors = ['Daniel Mendler', '
|
10
|
-
s.email = %w{mail@daniel-mendler.de
|
9
|
+
s.authors = ['Daniel Mendler', 'Hannes Georg']
|
10
|
+
s.email = %w{mail@daniel-mendler.de hannes.georg@googlemail.com}
|
11
11
|
s.description = 'A unified interface to key/value stores (moneta replacement)'
|
12
12
|
s.extra_rdoc_files = %w{README.md SPEC.md LICENSE}
|
13
13
|
s.files = `git ls-files`.split("\n")
|
data/lib/juno.rb
CHANGED
@@ -12,6 +12,7 @@ module Juno
|
|
12
12
|
module Adapters
|
13
13
|
autoload :ActiveRecord, 'juno/adapters/activerecord'
|
14
14
|
autoload :Cassandra, 'juno/adapters/cassandra'
|
15
|
+
autoload :Cookie, 'juno/adapters/cookie'
|
15
16
|
autoload :Couch, 'juno/adapters/couch'
|
16
17
|
autoload :DataMapper, 'juno/adapters/datamapper'
|
17
18
|
autoload :DBM, 'juno/adapters/dbm'
|
@@ -108,13 +109,12 @@ module Juno
|
|
108
109
|
|
109
110
|
# Build your own store chain!
|
110
111
|
#
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
#
|
115
|
-
#
|
116
|
-
# end
|
112
|
+
# @example Juno builder
|
113
|
+
# Juno.build do
|
114
|
+
# use :Expires
|
115
|
+
# adapter :Memory
|
116
|
+
# end
|
117
117
|
def self.build(&block)
|
118
|
-
Builder.new(&block).build
|
118
|
+
Builder.new(&block).build.last
|
119
119
|
end
|
120
120
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Juno
|
2
|
+
module Adapters
|
3
|
+
class Cookie < Memory
|
4
|
+
attr_reader :cookies
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
super
|
8
|
+
@options, @cookies = options, {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def store(key, value, options = {})
|
12
|
+
cookie = @options.merge(options)
|
13
|
+
cookie[:value] = value
|
14
|
+
cookie[:expires] += Time.now.to_i if cookie[:expires]
|
15
|
+
@cookies[key] = cookie
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete(key, options = {})
|
20
|
+
@cookies[key] = nil
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear(options = {})
|
25
|
+
@memory.each_key { |key| @cookies[key] = nil }
|
26
|
+
super
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def reset(cookies)
|
31
|
+
@cookies, @memory = {}, cookies
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/juno/builder.rb
CHANGED
@@ -5,12 +5,10 @@ module Juno
|
|
5
5
|
# @api private
|
6
6
|
def build
|
7
7
|
klass, options, block = @proxies.first
|
8
|
-
|
9
|
-
@proxies[1..-1].each do |proxy|
|
8
|
+
@proxies[1..-1].inject([klass.new(options, &block)]) do |stores, proxy|
|
10
9
|
klass, options, block = proxy
|
11
|
-
|
10
|
+
stores << klass.new(stores.last, options, &block)
|
12
11
|
end
|
13
|
-
store
|
14
12
|
end
|
15
13
|
|
16
14
|
def initialize(&block)
|
data/lib/juno/cache.rb
CHANGED
data/lib/juno/stack.rb
CHANGED
data/lib/juno/transformer.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
module Juno
|
2
2
|
# Transforms keys and values (Marshal, YAML, JSON, Base64, MD5, ...).
|
3
3
|
#
|
4
|
-
#
|
5
|
-
#
|
4
|
+
# @example Add transformer to chain
|
6
5
|
# Juno.build do
|
7
6
|
# transformer :key => [:marshal, :escape], :value => [:marshal]
|
8
7
|
# adapter :File, :dir => 'data'
|
@@ -10,50 +9,6 @@ module Juno
|
|
10
9
|
#
|
11
10
|
# @api public
|
12
11
|
class Transformer < Proxy
|
13
|
-
# Available value transformers (Encoding and decoding)
|
14
|
-
VALUE_TRANSFORMER = {
|
15
|
-
:base64 => { :load => "value.unpack('m').first", :dump => "[value].pack('m').strip" },
|
16
|
-
:bencode => { :load => '::BEncode.load(value)', :dump => '::BEncode.dump(value)', :require => 'bencode' },
|
17
|
-
:bert => { :load => '::BERT.decode(value)', :dump => '::BERT.encode(value)', :require => 'bert' },
|
18
|
-
:bson => { :load => "::BSON.deserialize(value)['v']", :dump => "::BSON.serialize('v'=>value)", :require => 'bson' },
|
19
|
-
:json => { :load => '::MultiJson.load(value).first', :dump => '::MultiJson.dump([value])', :require => 'multi_json' },
|
20
|
-
:lzma => { :load => '::LZMA.decompress(value)', :dump => '::LZMA.compress(value)', :require => 'lzma' },
|
21
|
-
:lzo => { :load => '::LZO.decompress(value)', :dump => '::LZO.compress(value)', :require => 'lzoruby' },
|
22
|
-
:marshal => { :load => '::Marshal.load(value)', :dump => '::Marshal.dump(value)' },
|
23
|
-
:msgpack => { :load => '::MessagePack.unpack(value)', :dump => '::MessagePack.pack(value)', :require => 'msgpack' },
|
24
|
-
:ox => { :load => '::Ox.parse_obj(value)', :dump => '::Ox.dump(value)', :require => 'ox' },
|
25
|
-
:snappy => { :load => '::Snappy.inflate(value)', :dump => '::Snappy.deflate(value)', :require => 'snappy' },
|
26
|
-
:quicklz => { :load => '::QuickLZ.decompress(value)', :dump => '::QuickLZ.compress(value)', :require => 'qlzruby' },
|
27
|
-
:tnet => { :load => '::TNetstring.parse(value).first', :dump => '::TNetstring.dump(value)', :require => 'tnetstring' },
|
28
|
-
:uuencode => { :load => "value.unpack('u').first", :dump => "[value].pack('u').strip" },
|
29
|
-
:yaml => { :load => '::YAML.load(value)', :dump => '::YAML.dump(value)', :require => 'yaml' },
|
30
|
-
:zlib => { :load => '::Zlib::Inflate.inflate(value)', :dump => '::Zlib::Deflate.deflate(value)', :require => 'zlib' },
|
31
|
-
}
|
32
|
-
|
33
|
-
# Available key transformers (Only encoding, one direction)
|
34
|
-
KEY_TRANSFORMER = {
|
35
|
-
:base64 => { :transform => "[key].pack('m').strip" },
|
36
|
-
:bencode => { :transform => '(tmp = key; String === tmp ? tmp : ::BEncode.dump(tmp))', :require => 'bencode' },
|
37
|
-
:bert => { :transform => '(tmp = key; String === tmp ? tmp : ::BERT.encode(tmp))', :require => 'bert' },
|
38
|
-
:bson => { :transform => "(tmp = key; String === tmp ? tmp : ::BSON.serialize('k'=>tmp).to_s)", :require => 'bson' },
|
39
|
-
:escape => { :transform => "key.gsub(/[^a-zA-Z0-9_-]+/) { '%%' + $&.unpack('H2' * $&.bytesize).join('%%').upcase }" },
|
40
|
-
:json => { :transform => '(tmp = key; String === tmp ? tmp : ::MultiJson.dump(tmp))', :require => 'multi_json' },
|
41
|
-
:marshal => { :transform => '(tmp = key; String === tmp ? tmp : ::Marshal.dump(tmp))' },
|
42
|
-
:md5 => { :transform => '::Digest::MD5.hexdigest(key)', :require => 'digest/md5' },
|
43
|
-
:msgpack => { :transform => '(tmp = key; String === tmp ? tmp : ::MessagePack.pack(tmp))', :require => 'msgpack' },
|
44
|
-
:prefix => { :transform => '@prefix+key' },
|
45
|
-
:rmd160 => { :transform => '::Digest::RMD160.hexdigest(key)', :require => 'digest/rmd160' },
|
46
|
-
:ox => { :transform => '(tmp = key; String === tmp ? tmp : ::Ox.dump(tmp))', :require => 'ox' },
|
47
|
-
:sha1 => { :transform => '::Digest::SHA1.hexdigest(key)', :require => 'digest/sha1' },
|
48
|
-
:sha256 => { :transform => '::Digest::SHA256.hexdigest(key)', :require => 'digest/sha2' },
|
49
|
-
:sha384 => { :transform => '::Digest::SHA384.hexdigest(key)', :require => 'digest/sha2' },
|
50
|
-
:sha512 => { :transform => '::Digest::SHA512.hexdigest(key)', :require => 'digest/sha2' },
|
51
|
-
:spread => { :transform => '(tmp = key; ::File.join(tmp[0..1], tmp[2..-1]))' },
|
52
|
-
:tnet => { :transform => '(tmp = key; String === tmp ? tmp : ::TNetstring.dump(tmp))', :require => 'tnetstring' },
|
53
|
-
:uuencode => { :transform => "[key].pack('u').strip" },
|
54
|
-
:yaml => { :transform => '(tmp = key; String === tmp ? tmp : ::YAML.dump(tmp))', :require => 'yaml' },
|
55
|
-
}
|
56
|
-
|
57
12
|
def initialize(adapter, options = {})
|
58
13
|
super
|
59
14
|
@prefix = options[:prefix]
|
@@ -86,13 +41,10 @@ module Juno
|
|
86
41
|
private
|
87
42
|
|
88
43
|
def compile(keys, values)
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
key = t[:transform].gsub('key', key).gsub('tmp', "x#{tmp}")
|
94
|
-
tmp += 1
|
95
|
-
end
|
44
|
+
raise 'Invalid key transformer chain' if KEY_TRANSFORMER !~ keys.map(&:inspect).join
|
45
|
+
raise 'Invalid value transformer chain' if VALUE_TRANSFORMER !~ values.map(&:inspect).join
|
46
|
+
|
47
|
+
key = compile_transformer(keys, 'key')
|
96
48
|
|
97
49
|
klass = Class.new(Transformer)
|
98
50
|
if values.empty?
|
@@ -111,13 +63,8 @@ module Juno
|
|
111
63
|
end
|
112
64
|
end_eval
|
113
65
|
else
|
114
|
-
|
115
|
-
values.
|
116
|
-
raise "Unknown value transformer #{values[i]}" unless t = VALUE_TRANSFORMER[values[i]]
|
117
|
-
require t[:require] if t[:require]
|
118
|
-
dumper = t[:dump].gsub('value', dumper)
|
119
|
-
loader = VALUE_TRANSFORMER[values[-i-1]][:load].gsub('value', loader)
|
120
|
-
end
|
66
|
+
dump = compile_transformer(values, 'value')
|
67
|
+
load = compile_transformer(values.reverse, 'value', 1)
|
121
68
|
|
122
69
|
klass.class_eval <<-end_eval, __FILE__, __LINE__
|
123
70
|
def key?(key, options = {})
|
@@ -125,20 +72,78 @@ module Juno
|
|
125
72
|
end
|
126
73
|
def load(key, options = {})
|
127
74
|
value = @adapter.load(#{key}, options)
|
128
|
-
value && #{
|
75
|
+
value && #{load}
|
129
76
|
end
|
130
77
|
def store(key, value, options = {})
|
131
|
-
@adapter.store(#{key}, #{
|
78
|
+
@adapter.store(#{key}, #{dump}, options)
|
132
79
|
value
|
133
80
|
end
|
134
81
|
def delete(key, options = {})
|
135
82
|
value = @adapter.delete(#{key}, options)
|
136
|
-
value && #{
|
83
|
+
value && #{load}
|
137
84
|
end
|
138
85
|
end_eval
|
139
86
|
end
|
140
87
|
klass
|
141
88
|
end
|
89
|
+
|
90
|
+
# Compile transformer validator regular expression
|
91
|
+
def compile_validator(s)
|
92
|
+
Regexp.new(s.gsub(/\w+/) do
|
93
|
+
'(' + TRANSFORMER.select {|k,v| v.first.to_s == $& }.map {|v| ":#{v.first}" }.join('|') + ')'
|
94
|
+
end.gsub(/\s+/, '').sub(/\A/, '\A').sub(/\Z/, '\Z'))
|
95
|
+
end
|
96
|
+
|
97
|
+
# Returned compiled transformer code string
|
98
|
+
def compile_transformer(transformer, var, i = 2)
|
99
|
+
transformer.inject(var) do |value, name|
|
100
|
+
raise "Unknown transformer #{name}" unless t = TRANSFORMER[name]
|
101
|
+
require t[3] if t[3]
|
102
|
+
code = t[i]
|
103
|
+
if t[0] == :serialize && var == 'key'
|
104
|
+
"(tmp = #{value}; String === tmp ? tmp : #{code.gsub('value', 'tmp')})"
|
105
|
+
else
|
106
|
+
code.gsub('value', value)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
142
110
|
end
|
111
|
+
|
112
|
+
# Available key/value transformers
|
113
|
+
TRANSFORMER = {
|
114
|
+
# Name => [ Type, Load, Dump, Library ],
|
115
|
+
:bencode => [ :serialize, '::BEncode.load(value)', '::BEncode.dump(value)', 'bencode' ],
|
116
|
+
:bert => [ :serialize, '::BERT.decode(value)', '::BERT.encode(value)', 'bert' ],
|
117
|
+
:bson => [ :serialize, "::BSON.deserialize(value)['v']", "::BSON.serialize('v'=>value).to_s", 'bson' ],
|
118
|
+
:json => [ :serialize, '::MultiJson.load(value).first', '::MultiJson.dump([value])', 'multi_json' ],
|
119
|
+
:marshal => [ :serialize, '::Marshal.load(value)', '::Marshal.dump(value)' ],
|
120
|
+
:msgpack => [ :serialize, '::MessagePack.unpack(value)', '::MessagePack.pack(value)', 'msgpack' ],
|
121
|
+
:ox => [ :serialize, '::Ox.parse_obj(value)', '::Ox.dump(value)', 'ox' ],
|
122
|
+
:tnet => [ :serialize, '::TNetstring.parse(value).first', '::TNetstring.dump(value)', 'tnetstring' ],
|
123
|
+
:yaml => [ :serialize, '::YAML.load(value)', '::YAML.dump(value)', 'yaml' ],
|
124
|
+
:lzma => [ :compress, '::LZMA.decompress(value)', '::LZMA.compress(value)', 'lzma' ],
|
125
|
+
:lzo => [ :compress, '::LZO.decompress(value)', '::LZO.compress(value)', 'lzoruby' ],
|
126
|
+
:snappy => [ :compress, '::Snappy.inflate(value)', '::Snappy.deflate(value)', 'snappy' ],
|
127
|
+
:quicklz => [ :compress, '::QuickLZ.decompress(value)', '::QuickLZ.compress(value)', 'qlzruby' ],
|
128
|
+
:zlib => [ :compress, '::Zlib::Inflate.inflate(value)', '::Zlib::Deflate.deflate(value)', 'zlib' ],
|
129
|
+
:base64 => [ :encode, "value.unpack('m').first", "[value].pack('m').strip" ],
|
130
|
+
:uuencode => [ :encode, "value.unpack('u').first", "[value].pack('u').strip" ],
|
131
|
+
:escape => [ :encode, "value.gsub(/((?:%[0-9a-fA-F]{2})+)/){ [$1.delete('%')].pack('H*') }",
|
132
|
+
"value.gsub(/[^a-zA-Z0-9_-]+/){ '%' + $&.unpack('H2' * $&.bytesize).join('%').upcase }" ],
|
133
|
+
:md5 => [ :digest, nil, '::Digest::MD5.hexdigest(value)', 'digest/md5' ],
|
134
|
+
:rmd160 => [ :digest, nil, '::Digest::RMD160.hexdigest(value)', 'digest/rmd160' ],
|
135
|
+
:sha1 => [ :digest, nil, '::Digest::SHA1.hexdigest(value)', 'digest/sha1' ],
|
136
|
+
:sha256 => [ :digest, nil, '::Digest::SHA256.hexdigest(value)', 'digest/sha2' ],
|
137
|
+
:sha384 => [ :digest, nil, '::Digest::SHA384.hexdigest(value)', 'digest/sha2' ],
|
138
|
+
:sha512 => [ :digest, nil, '::Digest::SHA512.hexdigest(value)', 'digest/sha2' ],
|
139
|
+
:prefix => [ :prefix, nil, '@prefix+value' ],
|
140
|
+
:spread => [ :spread, nil, '(tmp = value; ::File.join(tmp[0..1], tmp[2..-1]))' ],
|
141
|
+
}
|
142
|
+
|
143
|
+
# Allowed value transformers (Read it like a regular expression!)
|
144
|
+
VALUE_TRANSFORMER = compile_validator('serialize? compress? encode?')
|
145
|
+
|
146
|
+
# Allowed key transformers (Read it like a regular expression!)
|
147
|
+
KEY_TRANSFORMER = compile_validator('serialize? prefix? (encode | (digest spread?))?')
|
143
148
|
end
|
144
149
|
end
|
data/lib/juno/version.rb
CHANGED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'juno'
|
2
|
+
require 'rack/utils'
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
# A Rack middleware that was made to reuse all juno transformers
|
6
|
+
# on the cookie hash.
|
7
|
+
#
|
8
|
+
# @example config.ru
|
9
|
+
# # Add Rack::JunoCookies somewhere in your rack stack
|
10
|
+
# use Rack::JunoCookies
|
11
|
+
#
|
12
|
+
# run lambda{|env| [200,{},[]] }
|
13
|
+
# # But this doesn't do much
|
14
|
+
#
|
15
|
+
# @example config.ru
|
16
|
+
# # Give it some options
|
17
|
+
# use Rack::JunoCookies, :domain => 'example.com', :path => '/path'
|
18
|
+
#
|
19
|
+
# @example config.ru
|
20
|
+
# # Pass it a block like the one passed to Juno.build
|
21
|
+
# use Rack::JunoCookies do
|
22
|
+
# use :Transformer, :key => :prefix, :prefix => 'juno.'
|
23
|
+
# adapter :Cookie
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# run lambda { |env|
|
27
|
+
# req = Rack::Request.new(env)
|
28
|
+
# req.cookies #=> is now a Juno store!!
|
29
|
+
# req.cookies['key'] #=> retrieves 'juno.key'
|
30
|
+
# req.cookies['key'] = 'value' #=> sets 'juno.key'
|
31
|
+
# req.cookies.delete('key') #=> removes 'juno.key'
|
32
|
+
# [200,{},[]]
|
33
|
+
# }
|
34
|
+
#
|
35
|
+
class JunoCookies
|
36
|
+
def initialize(app, options = {}, &block)
|
37
|
+
@app = app
|
38
|
+
if block
|
39
|
+
raise 'Use either block or options' unless options.empty?
|
40
|
+
@builder = Juno::Builder.new(&block)
|
41
|
+
else
|
42
|
+
@builder = Juno::Builder.new { adapter :Cookie, options }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def call(env)
|
47
|
+
stores = @builder.build
|
48
|
+
env['rack.request.cookie_hash'] = stores.last
|
49
|
+
env['rack.request.cookie_string'] = env['HTTP_COOKIE']
|
50
|
+
stores.first.reset(Rack::Utils.parse_query(env['HTTP_COOKIE']))
|
51
|
+
status, headers, body = @app.call(env)
|
52
|
+
stores.first.cookies.each do |key, cookie|
|
53
|
+
if cookie == nil
|
54
|
+
Rack::Utils.delete_cookie_header!(headers, key)
|
55
|
+
else
|
56
|
+
Rack::Utils.set_cookie_header!(headers, key, cookie)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
[status, headers, body]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/spec/generate.rb
CHANGED
@@ -576,6 +576,10 @@ end
|
|
576
576
|
:build => "Juno::Adapters::Cassandra.new",
|
577
577
|
:specs => ADAPTER_SPECS
|
578
578
|
},
|
579
|
+
'adapter_cookie' => {
|
580
|
+
:build => 'Juno::Adapters::Cookie.new',
|
581
|
+
:specs => ADAPTER_SPECS
|
582
|
+
},
|
579
583
|
'adapter_couch' => {
|
580
584
|
:build => "Juno::Adapters::Couch.new(:db => 'adapter_couch')",
|
581
585
|
:specs => ADAPTER_SPECS
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Generated by generate.rb
|
2
|
+
require 'helper'
|
3
|
+
|
4
|
+
describe_juno "adapter_cookie" do
|
5
|
+
def new_store
|
6
|
+
Juno::Adapters::Cookie.new
|
7
|
+
end
|
8
|
+
|
9
|
+
include_context 'setup_store'
|
10
|
+
it_should_behave_like 'null_stringkey_stringvalue'
|
11
|
+
it_should_behave_like 'store_stringkey_stringvalue'
|
12
|
+
it_should_behave_like 'returndifferent_stringkey_stringvalue'
|
13
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'rack/mock'
|
3
|
+
require 'rack/juno_cookies'
|
4
|
+
|
5
|
+
describe Rack::JunoCookies do
|
6
|
+
def config(options={},&block)
|
7
|
+
@options = options
|
8
|
+
@block = block
|
9
|
+
end
|
10
|
+
|
11
|
+
def app(&block)
|
12
|
+
@app_block ||= block
|
13
|
+
end
|
14
|
+
|
15
|
+
def backend
|
16
|
+
Rack::MockRequest.new(Rack::JunoCookies.new(lambda{|env|
|
17
|
+
@store = env['rack.request.cookie_hash']
|
18
|
+
app.call(env) if app
|
19
|
+
[200,{},[]]
|
20
|
+
}, @options || {}, &@block))
|
21
|
+
end
|
22
|
+
|
23
|
+
def get(cookies = {}, &block)
|
24
|
+
app(&block)
|
25
|
+
@response = backend.get('/','HTTP_COOKIE' => Rack::Utils.build_query(cookies))
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should be able to read a simple key' do
|
29
|
+
get 'key' => 'value' do
|
30
|
+
expect( @store['key'] ).to eql('value')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should be able to set a simple key' do
|
35
|
+
get do
|
36
|
+
@store['key'] = 'value'
|
37
|
+
end
|
38
|
+
expect( @response['Set-Cookie'] ).to eql('key=value')
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should be able to remove a simple key' do
|
42
|
+
get 'key' => 'value' do
|
43
|
+
@store.delete('key')
|
44
|
+
end
|
45
|
+
expect( @response['Set-Cookie'] ).to eql('key=; expires=Thu, 01-Jan-1970 00:00:00 GMT')
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should accept a config block' do
|
49
|
+
config do
|
50
|
+
use :Transformer, :key => :prefix, :prefix => 'juno.'
|
51
|
+
adapter :Cookie
|
52
|
+
end
|
53
|
+
get 'juno.key' => 'right', 'key' => 'wrong' do
|
54
|
+
expect( @store['key'] ).to eql('right')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should accept a :domain option' do
|
59
|
+
config :domain => 'example.com'
|
60
|
+
get do
|
61
|
+
@store['key'] = 'value'
|
62
|
+
end
|
63
|
+
expect(@response['Set-Cookie']).to eql('key=value; domain=example.com')
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should accept a :path option' do
|
67
|
+
config :path => '/path'
|
68
|
+
get do
|
69
|
+
@store['key'] = 'value'
|
70
|
+
end
|
71
|
+
expect(@response['Set-Cookie']).to eql('key=value; path=/path')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should be accessible via Rack::Request' do
|
75
|
+
get 'key' => 'value' do |env|
|
76
|
+
req = Rack::Request.new(env)
|
77
|
+
expect(req.cookies['key']).to eql('value')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
metadata
CHANGED
@@ -1,23 +1,21 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: juno
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Daniel Mendler
|
9
|
-
-
|
10
|
-
- Derek Kastner
|
9
|
+
- Hannes Georg
|
11
10
|
autorequire:
|
12
11
|
bindir: bin
|
13
12
|
cert_chain: []
|
14
|
-
date: 2012-12-
|
13
|
+
date: 2012-12-15 00:00:00.000000000 Z
|
15
14
|
dependencies: []
|
16
15
|
description: A unified interface to key/value stores (moneta replacement)
|
17
16
|
email:
|
18
17
|
- mail@daniel-mendler.de
|
19
|
-
-
|
20
|
-
- dkastner@gmail.com
|
18
|
+
- hannes.georg@googlemail.com
|
21
19
|
executables: []
|
22
20
|
extensions: []
|
23
21
|
extra_rdoc_files:
|
@@ -37,6 +35,7 @@ files:
|
|
37
35
|
- lib/juno.rb
|
38
36
|
- lib/juno/adapters/activerecord.rb
|
39
37
|
- lib/juno/adapters/cassandra.rb
|
38
|
+
- lib/juno/adapters/cookie.rb
|
40
39
|
- lib/juno/adapters/couch.rb
|
41
40
|
- lib/juno/adapters/datamapper.rb
|
42
41
|
- lib/juno/adapters/dbm.rb
|
@@ -70,11 +69,13 @@ files:
|
|
70
69
|
- lib/juno/transformer.rb
|
71
70
|
- lib/juno/version.rb
|
72
71
|
- lib/rack/cache/juno.rb
|
72
|
+
- lib/rack/juno_cookies.rb
|
73
73
|
- lib/rack/session/juno.rb
|
74
74
|
- spec/generate.rb
|
75
75
|
- spec/helper.rb
|
76
76
|
- spec/juno/adapter_activerecord_spec.rb
|
77
77
|
- spec/juno/adapter_cassandra_spec.rb
|
78
|
+
- spec/juno/adapter_cookie_spec.rb
|
78
79
|
- spec/juno/adapter_couch_spec.rb
|
79
80
|
- spec/juno/adapter_datamapper_spec.rb
|
80
81
|
- spec/juno/adapter_dbm_spec.rb
|
@@ -185,6 +186,7 @@ files:
|
|
185
186
|
- spec/juno/transformer_zlib_spec.rb
|
186
187
|
- spec/junospecs.rb
|
187
188
|
- spec/rack/cache_juno_spec.rb
|
189
|
+
- spec/rack/juno_cookies_spec.rb
|
188
190
|
- spec/rack/session_juno_spec.rb
|
189
191
|
homepage: http://github.com/minad/juno
|
190
192
|
licenses: []
|
@@ -216,6 +218,7 @@ test_files:
|
|
216
218
|
- spec/helper.rb
|
217
219
|
- spec/juno/adapter_activerecord_spec.rb
|
218
220
|
- spec/juno/adapter_cassandra_spec.rb
|
221
|
+
- spec/juno/adapter_cookie_spec.rb
|
219
222
|
- spec/juno/adapter_couch_spec.rb
|
220
223
|
- spec/juno/adapter_datamapper_spec.rb
|
221
224
|
- spec/juno/adapter_dbm_spec.rb
|
@@ -326,4 +329,5 @@ test_files:
|
|
326
329
|
- spec/juno/transformer_zlib_spec.rb
|
327
330
|
- spec/junospecs.rb
|
328
331
|
- spec/rack/cache_juno_spec.rb
|
332
|
+
- spec/rack/juno_cookies_spec.rb
|
329
333
|
- spec/rack/session_juno_spec.rb
|