cookies_manager 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,4 +1,8 @@
1
1
  0.1.x (Nov 07, 2011)
2
2
 
3
- * Initial release
3
+ * Initial release + documentation compatibility fixes
4
4
 
5
+ 0.2.0 (Nov 08, 2011)
6
+
7
+ * Simplified usage: in reads operations, unpacks the data by default
8
+ * Added cache management rspecs
data/README.rdoc CHANGED
@@ -29,7 +29,9 @@ To activate the feature, simply call +load_cookies_manager+ on your controller c
29
29
  Next, you can refer the CookiesManager instance by calling the +cookies_manager+ helper method from your controllers and views:
30
30
 
31
31
  len_bytes = cookies_manager.write('a_key', ['an', 'array']) # store the array as is in the cache, and as a base-64 string in the cookies
32
+
32
33
  my_array = cookies_manager.read('a_key') # retrieves the array from the cache (or from the cookies if the cache is not in sync)
34
+
33
35
  my_deleted_array = cookies_manager.delete('a_key') # removes the array from both the cookies and the cache
34
36
 
35
37
  === Supported options
@@ -23,19 +23,16 @@ module CookiesManager
23
23
  end
24
24
 
25
25
  # Reads the data object corresponding to the key.
26
+ # - Reads from the cache, or from the cookies if the cache is not in sync.
27
+ # - Cache desynchronization can occur when the cookies hash has been modified directly, in which case the cache is automatically re-synchronized.
28
+ # - When the data needs to be retrieved from the cookies, it is successively base64-decoded, unzipped, and unmarshalled by default. If you consider your data does not need to be transformed, you can disable this feature by passing the +:skip_unpack+ option.
26
29
  #
27
- # Reads from the cache instance variable, or from the cookies if the cache is not in sync with the cookies.
28
- # Cache desynchronization can occur when the cookies hash is modified directly.
29
- # The cache is automatically re-synchronized if out of sync.
30
- #
31
- # If option +:unpack+ is set to true, data will be successively base64-decoded, unzipped, and unmarshalled. This option is used only when the data
32
- # is retrieved from the cookies hash (i.e. the cache is not in sync with the cookies).
33
- #
34
- # === Example:
30
+ # === Examples:
35
31
  # data = cookies_manager.read('my_key') # reads the data associated with the key 'my_key'
32
+ # raw_data = cookies_manager.read('my_key', :skip_unpack => true) # reads without unpacking
36
33
  #
37
34
  # @param [String or Symbol] key a unique key corresponding to the data to read
38
- # @option opts [Boolean] :unpack if true, successively base64-decode, unzip, and unmarshall the data. Default is false.
35
+ # @option opts [Boolean] :skip_unpack if true, DO NOT base64-decode, unzip, nor unmarshall the data. Default is false. This option is used only when the cache is out of sync.
39
36
  # @return [Object] the data associated with the key
40
37
  #
41
38
  def read(key, opts = {})
@@ -47,10 +44,8 @@ module CookiesManager
47
44
  end
48
45
 
49
46
  # Writes the data object and associates it with the key.
50
- #
51
- # Data is stored in both the cookies and the cache.
52
- #
53
- # By default, before being stored in the cookies, data is marshalled, zipped, and base64-encoded. Although this feature is recommended, you can disable it by passing the option +:skip_pack+ if you consider your data can be stored as is in the cookies (ex: US-ASCII string).
47
+ # - Data is stored in both the cookies and the cache.
48
+ # - By default, before being stored in the cookies, data is marshalled, zipped, and base64-encoded. Although this feature is recommended, you can disable it by passing the option +:skip_pack+ if you consider your data can be stored as is in the cookies (ex: US-ASCII string).
54
49
  #
55
50
  # === Examples:
56
51
  #
@@ -85,14 +80,13 @@ module CookiesManager
85
80
  return result[:value].try(:bytesize) || 0
86
81
  end
87
82
 
88
- # Deletes the data corresponding to the key.
89
- #
90
- # Removes the data from both the cookies and the cache, and return it.
91
- # The returned value is read from the cache if this is in sync with the cookies. Otherwise, the data is read from the cookies, in which case it is successively
92
- # base64-decoded, unzipped, and unmarshalled if option +:unpack+ is set to true.
83
+ # Deletes the data corresponding to the key, and return it.
84
+ # - Removes the data from both the cookies and the cache.
85
+ # - The returned value is read from the cache if this is in sync with the cookies. Otherwise, the data is read from the cookies, in which case it is successively base64-decoded, unzipped, and unmarshalled by default. If you consider your data does not need to be transformed, you can disable this feature by passing the +:skip_unpack+ option.
93
86
  #
94
87
  # === Example:
95
- # data = cookies_manager.delete('my_key') # deletes the data associated with the key 'my_key'
88
+ # data = cookies_manager.delete('my_key') # deletes and returns the data associated with the key 'my_key'
89
+ # raw_data = cookies_manager.delete('my_key', :skip_unpack => true) # same as above except that the returned data is not unpacked
96
90
  #
97
91
  # @param [String or Symbol] key a unique key corresponding to the data to delete
98
92
  # @option opts (see #read)
@@ -132,7 +126,7 @@ module CookiesManager
132
126
  if cache[key][:packed_data] == data_from_cookies # checks whether cache is in sync with cookies
133
127
  result = cache[key][:unpacked_data] # reads from cache
134
128
  else # cache not in sync
135
- result = opts[:unpack] ? unpack(data_from_cookies) : data_from_cookies # read from cookies
129
+ result = opts[:skip_unpack] ? data_from_cookies : unpack(data_from_cookies) # read from cookies
136
130
  # updates the cache
137
131
  cache[key][:packed_data] = data_from_cookies
138
132
  cache[key][:unpacked_data] = result
@@ -1,3 +1,3 @@
1
1
  module CookiesManager
2
- VERSION = "0.1.8"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -86,7 +86,7 @@ describe CookiesManager::Base do
86
86
  describe "#read some data previously stored directly into the cookies hash" do
87
87
  context "when reading non-nil data" do
88
88
  before { cookies['my_key'] = {:value => @complex_data} }
89
- specify { subject.read('my_key').should eql @complex_data }
89
+ specify { subject.read('my_key', :skip_unpack => true).should eql @complex_data }
90
90
  end
91
91
  context "when reading a nil value" do
92
92
  before { cookies['my_key'] = {:value => nil } }
@@ -94,13 +94,13 @@ describe CookiesManager::Base do
94
94
  end
95
95
  context "when reading some data stored with a nil key" do
96
96
  before { cookies[nil] = {:value => @complex_data} }
97
- specify { subject.read(nil).should eql @complex_data }
98
- specify { subject.read('').should eql @complex_data }
97
+ specify { subject.read(nil, :skip_unpack => true).should eql @complex_data }
98
+ specify { subject.read('', :skip_unpack => true).should eql @complex_data }
99
99
  end
100
100
  context "when reading some data stored with an empty string key" do
101
101
  before { cookies[''] = {:value => @complex_data} }
102
- specify { subject.read(nil).should eql @complex_data }
103
- specify { subject.read('').should eql @complex_data }
102
+ specify { subject.read(nil, :skip_unpack => true).should eql @complex_data }
103
+ specify { subject.read('', :skip_unpack => true).should eql @complex_data }
104
104
  end
105
105
  end
106
106
  describe "#read some data previously stored through CookiesManager but later modified directly inside the cookies hash" do
@@ -109,7 +109,7 @@ describe CookiesManager::Base do
109
109
  subject.write('my_key', @simple_data)
110
110
  cookies['my_key'] = {:value => (@new_simple_data = "some new data")}
111
111
  end
112
- specify { subject.read('my_key').should eql @new_simple_data }
112
+ specify { subject.read('my_key', :skip_unpack => true).should eql @new_simple_data }
113
113
  end
114
114
  context "when reading some complex data" do
115
115
  before do
@@ -117,8 +117,8 @@ describe CookiesManager::Base do
117
117
  @new_complex_data = @complex_data.merge(:some_new_item => 'it modifies the data')
118
118
  cookies['my_key'] = {:value => pack(@new_complex_data)}
119
119
  end
120
- specify { subject.read('my_key', :unpack => true).should eql @new_complex_data }
121
- specify { unpack(subject.read('my_key')).should eql @new_complex_data } #if :unpack option is omitted, needs to unpack manually
120
+ specify { subject.read('my_key').should eql @new_complex_data }
121
+ specify { unpack(subject.read('my_key', :skip_unpack => true)).should eql @new_complex_data } #if :skip_unpack option is set, we need to unpack the data manually
122
122
  end
123
123
  end
124
124
  describe "read with key symbol/string indifferent access (ex: :foo, 'foo')" do
@@ -141,7 +141,7 @@ describe CookiesManager::Base do
141
141
  describe "#delete" do
142
142
  describe "#delete existing data" do
143
143
  shared_examples_for "when deleting existing data" do
144
- before { @result = subject.delete('my_key') }
144
+ before { @result = subject.delete('my_key', :skip_unpack => true) }
145
145
  specify { @result.should eql @complex_data }
146
146
  specify { subject.read('my_key').should be_nil }
147
147
  end
@@ -205,6 +205,49 @@ describe CookiesManager::Base do
205
205
  end
206
206
  end
207
207
 
208
+ describe "#cache management" do
209
+ shared_examples_for 'when accessing the data' do
210
+ context 'when reading' do
211
+ specify { subject.read('my_key').should eql @complex_data }
212
+ end
213
+ context 'when deleting' do
214
+ specify { subject.delete('my_key').should eql @complex_data }
215
+ end
216
+ end
217
+ describe "#cache in sync with the cookies" do
218
+ describe "#accessing some data that has been read at least once by the CookiesManager" do
219
+ before do
220
+ cookies['my_key'] = pack(@complex_data)
221
+ subject.read('my_key').should eql @complex_data # this should store the data in the cache, thus sparing the need for future unmarshalling
222
+ dont_allow(Marshal).load # this makes sure unmarshalling is never done (i.e. the cache is used)
223
+ end
224
+ it_should_behave_like 'when accessing the data'
225
+ end
226
+ describe "#accessing some data that has been written through the CookiesManager" do
227
+ before do
228
+ subject.write('my_key', @complex_data) # this should store the data in the cache, thus sparing the need for future unmarshalling
229
+ dont_allow(Marshal).load # this makes sure unmarshalling is never done (i.e. the cache is used)
230
+ end
231
+ it_should_behave_like 'when accessing the data'
232
+ end
233
+ end
234
+ describe "#cache out of sync" do
235
+ before do
236
+ subject.write('my_key', @original_data = ['my', 'original', 'array'])
237
+ cookies['my_key'] = pack(@complex_data) # this causes the cache to be out of sync, thus causing future reads to unmarshall the data from the cookies
238
+ mock.proxy(Marshal).load.with_any_args # this makes sure unmarshalling is invoked
239
+ end
240
+ it_should_behave_like 'when accessing the data'
241
+ describe "#automatic cache resynchronization on read" do
242
+ before do
243
+ subject.read('my_key').should eql @complex_data # this causes unmarshalling, and cache resynchronization
244
+ dont_allow(Marshal).load # this makes sure we don't unmarshall anymore at this point (i.e. the cache is now in sync and can be used)
245
+ end
246
+ specify { subject.read('my_key').should eql @complex_data}
247
+ end
248
+ end
249
+ end
250
+
208
251
  describe "#multi-threading", :slow do
209
252
  def print_inside_critical_section(method_name)
210
253
  p "Inside the critical section, when calling cookies#{method_name}, the #{thread_name} thread pauses for #{sleep(2)} seconds, to make the other thread wait at the entrance of the critical section..."
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cookies_manager
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 8
10
- version: 0.1.8
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Christophe Levand