kematzy-sinatra-cache 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 kematzy
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,104 @@
1
+ h1. Sinatra::Cache
2
+
3
+ Adds a very *simple* Page Caching functionality to "Sinatra":http://www.sinatrarb.com/
4
+
5
+ <div style="background: #EED367; padding: 10px 5px; border: 1px solid #D7C36C; text-align: center;">
6
+ *NB!* Unfinished work, so use with care.
7
+ <br>
8
+
9
+ If you find it lacking or badly coded, please feel free to fork and improve. I'll be very happy :)
10
+ </div>
11
+
12
+
13
+ h3. TODOs
14
+
15
+ * Improve the logging output to the standard Sinatra output (if we are having :logging enabled )
16
+ * Add fragment and action (?) caching...
17
+ * Enable the options functionality for the <tt>:cache</tt> & <tt>:cache_expire</tt> methods, so that they can take custom extensions and more
18
+
19
+
20
+ h3. Configuration
21
+
22
+ *Example 1:*
23
+
24
+ Sinatra 'classic' app.
25
+
26
+ <pre><code>
27
+ <snip....>
28
+ require 'sinatra/cache'
29
+
30
+ # toggle for the cache functionality.
31
+ set :cache_enabled, true
32
+ # sets the default extension for cached files
33
+ set :cache_page_extension, '.html'
34
+ # sets the Cache dir to the root of the /public directory.
35
+ set :cache_dir, ''
36
+ ...
37
+ </code></pre>
38
+
39
+ *Example 2:*
40
+
41
+ Sinatra 'sub-classed' app.
42
+
43
+ <pre><code>
44
+ <snip....>
45
+ require 'sinatra/cache'
46
+
47
+ class MyApp < Sinatra::Base
48
+
49
+ register Sinatra::Cache
50
+
51
+ # toggle for the cache functionality.
52
+ set :cache_enabled, true
53
+ # sets the default extension for cached files
54
+ set :cache_page_extension, '.html'
55
+ # sets the Cache dir to the root of the /public directory.
56
+ set :cache_dir, ''
57
+
58
+ <snip....>
59
+ </code></pre>
60
+
61
+
62
+ h3. Usage
63
+
64
+ Basic Page Caching into static HTML files
65
+
66
+ <pre><code>
67
+ get '/contact' do
68
+ # NB! options is currently not working
69
+ cache( erb( :contact ), :options => 'go here' )
70
+ end
71
+ </code></pre>
72
+
73
+ Expiring old pages (ie: after POST or PUT events)
74
+
75
+ <pre><code>
76
+ # not very good example
77
+ post '/contact' do
78
+ cache_expire( '/contact', options )
79
+ end
80
+ </code></pre>
81
+
82
+ See the "test":test/ and "test/fixtures":test/fixtures/ directories for more examples.
83
+
84
+
85
+ h3. Default Options
86
+
87
+ * <tt>:cache_enabled</tt> => toggle for the cache functionality. Default is: <tt>true</tt>
88
+ * <tt>:cache_page_extension</tt> => sets the default extension for cached files. Default is: <tt>.html</tt>
89
+ * <tt>:cache_dir</tt> => sets cache directory where cached files are stored. Default is: ''(empty) == root of /public.<br>
90
+ set to empty, since the ideal 'system/cache/' does not currently work with Passenger & mod_rewrite :(
91
+ * <tt>:cache_logging</tt> => toggle for logging the cache calls. Default is: <tt>true</tt>
92
+ * <tt>:cache_logging_level</tt> => sets the level of the cache logger. Default is: <tt>:info</tt>.<br>
93
+ Options:(unused atm) [:info, :warn, :debug]
94
+
95
+
96
+ <hr>
97
+
98
+ h3. Credits
99
+
100
+ A big *Thank You!* goes to "*rtomayko*":http://github.com/rtomayko/, "*blakemizerany*":http://github.com/blakemizerany/ and others working on the Sinatra framework.
101
+
102
+ Inspired by code from "Rails":http://rubyonrails.com/ &amp; "Merb":http://merbivore.com/
103
+ and "sinatra-mailer":http://github.com/foca/sinatra-mailer/tree/master
104
+
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 2
4
+ :patch: 1
@@ -0,0 +1,139 @@
1
+ require 'fileutils'
2
+ # require 'sinatra/base'
3
+
4
+ module Sinatra
5
+
6
+ # Sinatra Caching module
7
+ #
8
+ # TODO:: Need to write documentation here
9
+ #
10
+ module Cache
11
+
12
+ VERSION = 'Sinatra::Cache v0.2.1'
13
+ def self.version; VERSION; end
14
+
15
+
16
+ module Helpers
17
+
18
+ # Caches the given URI to a html file in /public
19
+ #
20
+ # <b>Usage:</b>
21
+ # >> cache( erb(:contact, :layout => :layout))
22
+ # => returns the HTML output written to /public/<CACHE_DIR_PATH>/contact.html
23
+ #
24
+ # Also accepts an Options Hash, with the following options:
25
+ # * :extension => in case you need to change the file extension
26
+ #
27
+ # TODO:: implement the opts={} hash functionality. What other options are needed?
28
+ #
29
+ def cache(content, opts={})
30
+ return content unless options.cache_enabled
31
+
32
+ unless content.nil?
33
+ content = "#{page_cached_timestamp}#{content}\n"
34
+ path = cache_page_path(request.path_info,opts)
35
+ FileUtils.makedirs(File.dirname(path))
36
+ open(path, 'wb+') { |f| f << content }
37
+ log("Cached Page: [#{path}]",:info)
38
+ content
39
+ end
40
+ end
41
+
42
+ # Expires the cached URI (as .html file) in /public
43
+ #
44
+ # <b>Usage:</b>
45
+ # >> cache_expire('/contact')
46
+ # => deletes the /public/<CACHE_DIR_PATH>contact.html page
47
+ #
48
+ # get '/contact' do
49
+ # cache_expire # deletes the /public/<CACHE_DIR_PATH>contact.html page as well
50
+ # end
51
+ #
52
+ # TODO:: implement the options={} hash functionality. What options are really needed ?
53
+ def cache_expire(path = nil, opts={})
54
+ return unless options.cache_enabled
55
+
56
+ path = (path.nil?) ? cache_page_path(request.path_info) : cache_page_path(path)
57
+ if File.exist?(path)
58
+ File.delete(path)
59
+ log("Expired Page deleted at: [#{path}]",:info)
60
+ else
61
+ log("No Expired Page was found at the path: [#{path}]",:info)
62
+ end
63
+ end
64
+
65
+ # Prints a basic HTML comment with a timestamp in it, so that you can see when a file was cached last.
66
+ #
67
+ # *NB!* IE6 does NOT like this to be the first line of a HTML document, so output
68
+ # inside the <head> tag. Many hours wasted on that lesson ;-)
69
+ #
70
+ # <b>Usage:</b>
71
+ # >> <%= page_cached_timestamp %>
72
+ # => <!-- page cached: 2009-02-24 12:00:00 -->
73
+ #
74
+ def page_cached_timestamp
75
+ "<!-- page cached: #{Time.now.strftime("%Y-%d-%m %H:%M:%S")} -->\n" if options.cache_enabled
76
+ end
77
+
78
+
79
+ private
80
+
81
+ # Establishes the file name of the cached file from the path given
82
+ #
83
+ # TODO:: implement the opts={} functionality, and support for custom extensions on a per request basis.
84
+ #
85
+ def cache_file_name(path,opts={})
86
+ name = (path.empty? || path == "/") ? "index" : Rack::Utils.unescape(path.sub(/^(\/)/,'').chomp('/'))
87
+ name << options.cache_page_extension unless (name.split('/').last || name).include? '.'
88
+ return name
89
+ end
90
+
91
+ # Sets the full path to the cached page/file
92
+ # Dependent upon Sinatra.options .public and .cache_dir variables being present and set.
93
+ #
94
+ def cache_page_path(path,opts={})
95
+ # test if given a full path rather than relative path, otherwise join the public path to cache_dir
96
+ # and ensure it is a full path
97
+ cache_dir = (options.cache_dir == File.expand_path(options.cache_dir)) ?
98
+ options.cache_dir : File.expand_path("#{options.public}/#{options.cache_dir}")
99
+ cache_dir = cache_dir[0..-2] if cache_dir[-1,1] == '/'
100
+ "#{cache_dir}/#{cache_file_name(path,opts)}"
101
+ end
102
+
103
+ # TODO:: this implementation really stinks, how do I incorporate Sinatra's logger??
104
+ def log(msg,scope=:debug)
105
+ if options.cache_logging
106
+ "Log: msg=[#{msg}]" if scope == options.cache_logging_level
107
+ else
108
+ # just ignore the stuff...
109
+ # puts "just ignoring msg=[#{msg}] since cache_logging => [#{options.cache_logging.to_s}]"
110
+ end
111
+ end
112
+
113
+ end #/module Helpers
114
+
115
+
116
+ # Sets the default options:
117
+ #
118
+ # * +:cache_enabled+ => toggle for the cache functionality. Default is: +true+
119
+ # * +:cache_page_extension+ => sets the default extension for cached files. Default is: +.html+
120
+ # * +:cache_dir+ => sets cache directory where cached files are stored. Default is: ''(empty) == root of /public.<br>
121
+ # set to empty, since the ideal 'system/cache/' does not work with Passenger & mod_rewrite :(
122
+ # * +cache_logging+ => toggle for logging the cache calls. Default is: +true+
123
+ # * +cache_logging_level+ => sets the level of the cache logger. Default is: <tt>:info</tt>.<br>
124
+ # Options:(unused atm) [:info, :warn, :debug]
125
+ #
126
+ def self.registered(app)
127
+ app.helpers(Cache::Helpers)
128
+ app.set :cache_enabled, true
129
+ app.set :cache_page_extension, '.html'
130
+ app.set :cache_dir, ''
131
+ app.set :cache_logging, true
132
+ app.set :cache_logging_level, :info
133
+ end
134
+
135
+ end #/module Cache
136
+
137
+ register(Sinatra::Cache)
138
+
139
+ end #/module Sinatra
data/test/SPECS.rdoc ADDED
@@ -0,0 +1,95 @@
1
+ Test Suite for [Sinatra::Cache v0.2.0] produced on [2009-25-02 at 00:37]
2
+
3
+ == Sinatra::Cache
4
+ === ClassMethods
5
+ ==== the :version method
6
+ * should have a :version method that returns a String with the version number in it
7
+ * should not interfere with the normal Sinatra VERSION
8
+ === Instance Methods
9
+ ==== Private
10
+ ===== :cache_file_name method
11
+ ====== when using default options
12
+ * should handle '/' and return 'index.html'
13
+ * should handle top level URI's and return the URI plus '.html'
14
+ * should handle sub level URIs and return the directory/file format
15
+ ====== when using customized options
16
+ * should handle '/' and return 'index.html'
17
+ * should handle top level URI's and return the URI plus '.html'
18
+ * should handle sub level URIs and return the directory/file format
19
+ ===== :cache_page_path method
20
+ ====== when using default options
21
+ * should handle '/' and return the full path to 'index.html'
22
+ * should handle top level URI's and return the full path to the URI plus '.html'
23
+ * should handle sub level URIs and return the full path to the URI
24
+ ====== when using customized options
25
+ * should handle '/' and return the full path to 'index.html'
26
+ * should handle top level URI's and return the full path to the URI plus '.html'
27
+ * should handle sub level URIs and return the full path to the URI
28
+ ===== :log method
29
+ * MISSING TESTS =>
30
+ ==== Public
31
+ ===== :cache method
32
+ ====== when using default options
33
+ * is tested below in the Page Caching section
34
+ ====== when using customized options
35
+ * is tested below in the Page Caching section
36
+ === configuration methods
37
+ ==== when using default options
38
+ * the :cache_enabled option should be correct (true)
39
+ * the :cache_page_extension option should be correct (.html)
40
+ * the :cache_dir option should be correct ('')
41
+ * the :cache_logging option should be correct (true)
42
+ * the :cache_logging_level option should be correct (:info)
43
+ ==== when using customized options
44
+ * the :cache_enabled option should be correct (false)
45
+ * the :cache_page_extension option should be correct (.cache.html)
46
+ * the :cache_dir option should be correct ('system/cache')
47
+ * the :cache_logging option should be correct (true)
48
+ * the :cache_logging_level option should be correct (:info)
49
+ === Page Caching
50
+ ==== when using default options
51
+ * should NOT cache the un-cached index page
52
+ * should cache the /cache page
53
+ * should expire the /cache page
54
+ ==== when using customized options
55
+ * should NOT cache the un-cached index page
56
+ * should NOT cache the /cache page since :cache_enabled => false
57
+ ===== and setting cache_enabled => true
58
+ * should cache the /cache page
59
+ * should expire the /cache page
60
+ === Sinatra::Base
61
+ ==== should respond to
62
+ * the :cache_dir method
63
+ * the :cache_dir= method
64
+ * the :cache_dir? method
65
+ * the :cache_enabled method
66
+ * the :cache_enabled= method
67
+ * the :cache_enabled? method
68
+ * the :cache_logging method
69
+ * the :cache_logging= method
70
+ * the :cache_logging? method
71
+ * the :cache_logging_level method
72
+ * the :cache_logging_level= method
73
+ * the :cache_logging_level? method
74
+ * the :cache_page_extension method
75
+ * the :cache_page_extension= method
76
+ * the :cache_page_extension? method
77
+ === Sinatra::Default
78
+ ==== should respond to
79
+ * the :cache_dir method
80
+ * the :cache_dir= method
81
+ * the :cache_dir? method
82
+ * the :cache_enabled method
83
+ * the :cache_enabled= method
84
+ * the :cache_enabled? method
85
+ * the :cache_logging method
86
+ * the :cache_logging= method
87
+ * the :cache_logging? method
88
+ * the :cache_logging_level method
89
+ * the :cache_logging_level= method
90
+ * the :cache_logging_level? method
91
+ * the :cache_page_extension method
92
+ * the :cache_page_extension= method
93
+ * the :cache_page_extension? method
94
+
95
+ 64 specifications (84 requirements), 0 failures
@@ -0,0 +1,450 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+ require "#{File.dirname(File.dirname(File.expand_path(__FILE__)))}/lib/sinatra/cache"
3
+
4
+ class Sinatra::Base
5
+ # include Sinatra::Cache
6
+ end #/class Sinatra::Base
7
+
8
+ puts "Test Suite for [#{Sinatra::Cache.version}] produced on [#{ Time.now.strftime("%Y-%d-%m at %H:%M") }]"
9
+
10
+ describe "Sinatra::Cache" do
11
+
12
+ before(:each) do
13
+
14
+ default_app = mock_app do
15
+ register Sinatra::Cache
16
+
17
+ set :public, "#{File.dirname(File.expand_path(__FILE__))}/fixtures/public"
18
+ set :views, "#{File.dirname(File.expand_path(__FILE__))}/fixtures/views"
19
+
20
+ get '/' do
21
+ erb(:index)
22
+ end
23
+
24
+ get '/cache' do
25
+ # "Hello World from Sinatra Version=[#{Sinatra::VERSION}]"
26
+ cache("Hello World from Sinatra Version=[#{Sinatra::VERSION}]")
27
+ end
28
+ # YES, I know this is NOT ideal, but it's only test ;-)
29
+ get '/cache_expire' do
30
+ cache_expire("/cache")
31
+ end
32
+
33
+ end
34
+
35
+ custom_app = mock_app do
36
+ register Sinatra::Cache
37
+
38
+ set :public, "#{File.dirname(__FILE__)}/fixtures/public"
39
+ set :views, "#{File.dirname(__FILE__)}/fixtures/views"
40
+
41
+ set :cache_enabled, false
42
+ set :cache_page_extension, '.cache.html'
43
+ set :cache_dir, 'system/cache'
44
+ set :cache_logging, false
45
+ set :cache_logging_level, :info
46
+
47
+ get '/' do
48
+ erb :index
49
+ end
50
+
51
+ get '/cache' do
52
+ cache("Hello World from Sinatra Version=[#{Sinatra::VERSION}]")
53
+ end
54
+ # YES, I know this is NOT ideal, but it's only test ;-)
55
+ get '/cache_expire' do
56
+ cache_expire("/cache")
57
+ end
58
+ end
59
+
60
+ @default_app = default_app.new
61
+ @custom_app = custom_app.new
62
+ end
63
+
64
+ describe "ClassMethods" do
65
+
66
+ describe "the :version method" do
67
+
68
+ it "should have a :version method that returns a String with the version number in it" do
69
+ v = Sinatra::Cache.version
70
+ assert_not_nil(v)
71
+ assert_kind_of(String, v)
72
+ assert_match(/Sinatra::Cache v\d\.\d\.\d/, v)
73
+ end
74
+
75
+ it "should not interfere with the normal Sinatra VERSION" do
76
+ assert_not_equal(Sinatra::Cache.version, Sinatra::VERSION)
77
+ end
78
+
79
+ end #/the :version method
80
+
81
+ end #/ClassMethods
82
+
83
+
84
+ describe "Instance Methods" do
85
+
86
+ describe "Private" do
87
+
88
+ describe ":cache_file_name method" do
89
+
90
+ # temporary monkeypatch to enable testing
91
+ module Sinatra::Cache::Helpers
92
+ public :cache_file_name
93
+ end
94
+
95
+ describe "when using default options" do
96
+
97
+ it "should handle '/' and return 'index.html'" do
98
+ expected = "index.html"
99
+ assert_equal(expected, @default_app.cache_file_name("/"))
100
+ end
101
+
102
+ it "should handle top level URI's and return the URI plus '.html'" do
103
+ expected = "cache.html"
104
+ assert_equal(expected, @default_app.cache_file_name("/cache"))
105
+ end
106
+
107
+ it "should handle sub level URIs and return the directory/file format" do
108
+ expected = "cache/test.html"
109
+ assert_equal(expected, @default_app.cache_file_name("/cache/test"))
110
+ end
111
+
112
+ end #/when using default options
113
+
114
+ describe "when using customized options" do
115
+
116
+ it "should handle '/' and return 'index.html'" do
117
+ expected = "index.cache.html"
118
+ assert_equal(expected, @custom_app.cache_file_name("/"))
119
+ end
120
+
121
+ it "should handle top level URI's and return the URI plus '.html'" do
122
+ expected = "cache.cache.html"
123
+ assert_equal(expected, @custom_app.cache_file_name("/cache"))
124
+ end
125
+
126
+ it "should handle sub level URIs and return the directory/file format" do
127
+ expected = "cache/test.cache.html"
128
+ assert_equal(expected, @custom_app.cache_file_name("/cache/test"))
129
+ end
130
+
131
+ end #/when using customized options
132
+
133
+ end #/:cache_page_path method
134
+
135
+ describe ":cache_page_path method" do
136
+
137
+ # temporary monkeypatch to enable testing
138
+ module Sinatra::Cache::Helpers
139
+ public :cache_page_path
140
+ end
141
+
142
+ describe "when using default options" do
143
+
144
+ it "should handle '/' and return the full path to 'index.html'" do
145
+ expected = "#{public_fixtures_path}/index.html"
146
+ assert_equal(expected, @default_app.cache_page_path("/"))
147
+ end
148
+
149
+ it "should handle top level URI's and return the full path to the URI plus '.html'" do
150
+ expected = "#{public_fixtures_path}/cache.html"
151
+ assert_equal(expected, @default_app.cache_page_path("/cache"))
152
+ end
153
+
154
+ it "should handle sub level URIs and return the full path to the URI" do
155
+ expected = "#{public_fixtures_path}/cache/test.html"
156
+ assert_equal(expected, @default_app.cache_page_path("/cache/test"))
157
+ end
158
+
159
+ end #/when using default options
160
+
161
+ describe "when using customized options" do
162
+
163
+ it "should handle '/' and return the full path to 'index.html'" do
164
+ expected = "#{public_fixtures_path}/system/cache/index.cache.html"
165
+ assert_equal(expected, @custom_app.cache_page_path("/"))
166
+ end
167
+
168
+ it "should handle top level URI's and return the full path to the URI plus '.html'" do
169
+ expected = "#{public_fixtures_path}/system/cache/cache.cache.html"
170
+ assert_equal(expected, @custom_app.cache_page_path("/cache"))
171
+ end
172
+
173
+ it "should handle sub level URIs and return the full path to the URI" do
174
+ expected = "#{public_fixtures_path}/system/cache/cache/test.cache.html"
175
+ assert_equal(expected, @custom_app.cache_page_path("/cache/test"))
176
+ end
177
+
178
+ end #/when using customized options
179
+
180
+ end #/:cache_page_path method
181
+
182
+ describe ":log method" do
183
+
184
+ it "MISSING TESTS =>" do
185
+ assert(true)
186
+ end
187
+
188
+ end #/:log method
189
+
190
+ end #/Private
191
+
192
+ describe "Public" do
193
+
194
+ describe ":cache method" do
195
+
196
+ describe "when using default options" do
197
+
198
+ it "is tested below in the Page Caching section" do
199
+ assert true
200
+ end
201
+
202
+ end #/when using default options
203
+
204
+ describe "when using customized options" do
205
+
206
+ it "is tested below in the Page Caching section" do
207
+ assert true
208
+ end
209
+
210
+ end #/when using customized options
211
+
212
+ end #/:cache method
213
+
214
+ end #/Public
215
+
216
+ end #/Instance Methods
217
+
218
+
219
+ describe "configuration methods" do
220
+
221
+ describe "when using default options" do
222
+
223
+ it "the :cache_enabled option should be correct (true)" do
224
+ assert_equal(true, @default_app.options.cache_enabled)
225
+ end
226
+
227
+ it "the :cache_page_extension option should be correct (.html)" do
228
+ assert_equal('.html', @default_app.options.cache_page_extension)
229
+ end
230
+
231
+ it "the :cache_dir option should be correct ('') " do
232
+ assert_equal('', @default_app.options.cache_dir)
233
+ end
234
+
235
+ it "the :cache_logging option should be correct (true)" do
236
+ assert_equal(true, @default_app.options.cache_logging)
237
+ end
238
+
239
+ it "the :cache_logging_level option should be correct (:info)" do
240
+ assert_equal(:info, @default_app.options.cache_logging_level)
241
+ end
242
+
243
+ end #/default options
244
+
245
+ describe "when using customized options" do
246
+
247
+ it "the :cache_enabled option should be correct (false)" do
248
+ assert_equal(false, @custom_app.options.cache_enabled)
249
+ end
250
+
251
+ it "the :cache_page_extension option should be correct (.cache.html)" do
252
+ assert_equal('.cache.html', @custom_app.options.cache_page_extension)
253
+ end
254
+
255
+ it "the :cache_dir option should be correct ('system/cache') " do
256
+ assert_equal('system/cache', @custom_app.options.cache_dir)
257
+ end
258
+
259
+ it "the :cache_logging option should be correct (true)" do
260
+ assert_equal(false, @custom_app.options.cache_logging)
261
+ end
262
+
263
+ it "the :cache_logging_level option should be correct (:info)" do
264
+ assert_equal(:info, @custom_app.options.cache_logging_level)
265
+ end
266
+
267
+ end #/when using customized options
268
+
269
+ end #/configuration methods
270
+
271
+
272
+ describe "Page Caching" do
273
+ after(:each) do
274
+ # FileUtils.rm_r(Dir["#{public_fixtures_path}/*"])
275
+ end
276
+
277
+ describe "when using default options" do
278
+
279
+ it "should NOT cache the un-cached index page" do
280
+ request = Rack::MockRequest.new(@default_app)
281
+ response = request.get('/')
282
+ assert response
283
+ assert_equal '<h1>HOME</h1>', response.body
284
+ assert_equal(false, test(?f, "#{public_fixtures_path}/index.html"))
285
+ end
286
+
287
+ it "should cache the /cache page" do
288
+ request = Rack::MockRequest.new(@default_app)
289
+ response = request.get('/cache')
290
+ assert response
291
+ assert_match(/^<!-- page cached: \d+-\d+-\d+ \d+:\d+:\d+ -->\nHello World from Sinatra Version=\[\d\.\d\.\d(\.\d)?\]\n/, response.body)
292
+ assert(test(?f, "#{public_fixtures_path}/cache.html"))
293
+ assert_match(/^<!-- page cached: \d+-\d+-\d+ \d+:\d+:\d+ -->\nHello World from Sinatra Version=\[\d\.\d\.\d(\.\d)?\]\n/, File.read("#{public_fixtures_path}/cache.html"))
294
+ end
295
+
296
+ it "should expire the /cache page" do
297
+ assert(test(?f, "#{public_fixtures_path}/cache.html"))
298
+ request = Rack::MockRequest.new(@default_app)
299
+ response = request.get('/cache_expire')
300
+ assert response
301
+ # TODO:: this is dodgy stuff, rework
302
+ assert_not_equal('', response.body)
303
+ assert_equal(false, test(?f, "#{public_fixtures_path}/cache.html"))
304
+ end
305
+
306
+ end #/when using default options
307
+
308
+ describe "when using customized options" do
309
+
310
+ it "should NOT cache the un-cached index page" do
311
+ request = Rack::MockRequest.new(@custom_app)
312
+ response = request.get('/')
313
+ assert response
314
+ assert_equal '<h1>HOME</h1>', response.body
315
+ assert_equal(false, test(?f, "#{public_fixtures_path}/index.html"))
316
+ end
317
+
318
+ it "should NOT cache the /cache page since :cache_enabled => false" do
319
+ request = Rack::MockRequest.new(@custom_app)
320
+ response = request.get('/cache')
321
+ assert response
322
+ assert_match(/^Hello World from Sinatra Version=\[\d\.\d\.\d(\.\d)?\]/, response.body)
323
+ assert_equal(false, test(?f, "#{public_fixtures_path}/cache.cache.html"))
324
+ end
325
+
326
+ describe "and setting cache_enabled => true" do
327
+
328
+ before(:each) do
329
+ custom_enabled_app = mock_app do
330
+ register Sinatra::Cache
331
+
332
+ set :public, "#{File.dirname(File.expand_path(__FILE__))}/fixtures/public"
333
+ set :views, "#{File.dirname(File.expand_path(__FILE__))}/fixtures/views"
334
+
335
+ set :cache_enabled, true
336
+ set :cache_page_extension, '.cache.html'
337
+ set :cache_dir, 'system/cache'
338
+ set :cache_logging, true
339
+ set :cache_logging_level, :info
340
+
341
+ get '/' do
342
+ erb :index
343
+ end
344
+
345
+ get '/cache' do
346
+ cache("Hello World from Sinatra Version=[#{Sinatra::VERSION}]")
347
+ end
348
+
349
+ # YES, I know this is NOT ideal, but it's only test ;-)
350
+ get '/cache_expire' do
351
+ cache_expire("/cache")
352
+ end
353
+
354
+ end
355
+
356
+ @custom_enabled_app = custom_enabled_app.new
357
+ end
358
+
359
+ it "should cache the /cache page" do
360
+ request = Rack::MockRequest.new(@custom_enabled_app)
361
+ response = request.get('/cache')
362
+ assert response
363
+ assert_match(/^<!-- page cached: \d+-\d+-\d+ \d+:\d+:\d+ -->\nHello World from Sinatra Version=\[\d\.\d\.\d(\.\d)?\]\n/, response.body)
364
+ assert(test(?f, "#{public_fixtures_path}/system/cache/cache.cache.html"))
365
+ assert_match(/^<!-- page cached: \d+-\d+-\d+ \d+:\d+:\d+ -->\nHello World from Sinatra Version=\[\d\.\d\.\d(\.\d)?\]\n/, File.read("#{public_fixtures_path}/system/cache/cache.cache.html"))
366
+ end
367
+
368
+ it "should expire the /cache page" do
369
+ assert(test(?f, "#{public_fixtures_path}/system/cache/cache.cache.html"))
370
+ request = Rack::MockRequest.new(@custom_enabled_app)
371
+ response = request.get('/cache_expire')
372
+ assert response
373
+ # TODO:: this is dodgy stuff, rework
374
+ assert_not_equal('', response.body)
375
+ assert_equal(false, test(?f, "#{public_fixtures_path}/system/cache/cache.cache.html"))
376
+ end
377
+
378
+ end #/and setting cache_enabled => true
379
+
380
+ end #/when using customized options
381
+
382
+
383
+ end #/Page Caching
384
+
385
+
386
+ describe "Sinatra::Base" do
387
+
388
+ before do
389
+ Sinatra::Base.register(Sinatra::Cache)
390
+ end
391
+
392
+ describe "should respond to" do
393
+
394
+ [
395
+ "cache_dir", "cache_dir=","cache_dir?", "cache_enabled","cache_enabled=", "cache_enabled?",
396
+ "cache_logging","cache_logging=","cache_logging?","cache_logging_level","cache_logging_level=","cache_logging_level?",
397
+ "cache_page_extension","cache_page_extension=","cache_page_extension?"
398
+ ].each do |m|
399
+
400
+ it "the :#{m} method" do
401
+ assert_respond_to(Sinatra::Base, m.to_sym)
402
+ end
403
+
404
+ end
405
+
406
+ end #/should respond to
407
+
408
+ end #/Sinatra::Base
409
+
410
+ describe "Sinatra::Default" do
411
+
412
+ before do
413
+ Sinatra::Base.register(Sinatra::Cache)
414
+ end
415
+
416
+ describe "should respond to" do
417
+
418
+ [
419
+ "cache_dir", "cache_dir=","cache_dir?", "cache_enabled","cache_enabled=", "cache_enabled?",
420
+ "cache_logging","cache_logging=","cache_logging?","cache_logging_level","cache_logging_level=","cache_logging_level?",
421
+ "cache_page_extension","cache_page_extension=","cache_page_extension?"
422
+ ].each do |m|
423
+
424
+ it "the :#{m} method" do
425
+ assert_respond_to(Sinatra::Default, m.to_sym)
426
+ end
427
+
428
+ end
429
+
430
+ end #/should respond to
431
+
432
+ end #/Sinatra::Default
433
+
434
+ # it "should description" do
435
+ # assert_equal('Sinatra::Application', Sinatra::Application.methods.sort)
436
+ # end
437
+ # it "should description1" do
438
+ # assert_equal('Sinatra::Base', Sinatra::Base.methods.sort)
439
+ # end
440
+ # it "should description2" do
441
+ # assert_equal('@default_app', @default_app.methods.sort)
442
+ # end
443
+ #
444
+ # it "should description3" do
445
+ # assert_equal('Sinatra::Default', Sinatra::Default.methods.sort)
446
+ # end
447
+
448
+
449
+
450
+ end #/Sinatra::Cache
@@ -0,0 +1,25 @@
1
+ ## CLASSIC.rb
2
+ ## Simple example app of how to use the Sinatra::Cache plugin in a normal 'Classic' Sinatra app.
3
+
4
+ require "rubygems"
5
+ require "sinatra"
6
+ require 'sinatra/cache'
7
+
8
+ set :public, "#{File.dirname(__FILE__)}/public"
9
+ set :views, "#{File.dirname(__FILE__)}/views"
10
+
11
+
12
+ get '/' do
13
+ erb(:index)
14
+ end
15
+
16
+ get '/cache' do
17
+ cache("Hello World from Sinatra Version=[#{Sinatra::VERSION}]")
18
+ end
19
+
20
+ # YES, I know this is NOT ideal, but it's only a test ;-)
21
+ get '/cache_expire' do
22
+ cache_expire("/cache")
23
+ end
24
+
25
+ #/EOF
@@ -0,0 +1,36 @@
1
+ ## MYAPP.rb
2
+ ## Simple example app of how to use the Sinatra::Cache plugin in a new 'Sub-Classed' Sinatra app
3
+ ## that inherits from Sinatra::Base
4
+
5
+ require "rubygems"
6
+ require "sinatra/base"
7
+ require 'sinatra/cache'
8
+
9
+ class MyApp < Sinatra::Base
10
+
11
+ register Sinatra::Cache
12
+
13
+ enable :logging
14
+ enable :static
15
+
16
+ set :public, "#{File.dirname(__FILE__)}/public"
17
+ set :views, "#{File.dirname(__FILE__)}/views"
18
+
19
+ get '/' do
20
+ erb(:index)
21
+ end
22
+
23
+ get '/cache' do
24
+ cache("Hello World from Sinatra Version=[#{Sinatra::VERSION}]")
25
+ end
26
+
27
+ # YES, I know this is NOT ideal, but it's only a test ;-)
28
+ get '/cache_expire' do
29
+ cache_expire("/cache")
30
+ end
31
+
32
+ end
33
+
34
+ MyApp.run!(:port => 4568) if __FILE__ == $0
35
+
36
+ #/EOF
@@ -0,0 +1,37 @@
1
+ ## MYAPP_DEFAULT.rb
2
+ ## Simple example app of how to use the Sinatra::Cache plugin in a new 'Sub-Classed' Sinatra app
3
+ ## that inherits from Sinatra::Default
4
+
5
+ require "rubygems"
6
+ require "sinatra/base"
7
+ require 'sinatra/cache'
8
+
9
+ class MyAppDefault < Sinatra::Default
10
+
11
+ register Sinatra::Cache
12
+
13
+ # these are enabled by default in Sinatra::Default
14
+ # enable :logging
15
+ # enable :static
16
+
17
+ set :public, "#{File.dirname(__FILE__)}/public"
18
+ set :views, "#{File.dirname(__FILE__)}/views"
19
+
20
+ get '/' do
21
+ erb(:index)
22
+ end
23
+
24
+ get '/cache' do
25
+ cache("Hello World from Sinatra Version=[#{Sinatra::VERSION}]")
26
+ end
27
+
28
+ # YES, I know this is NOT ideal, but it's only a test ;-)
29
+ get '/cache_expire' do
30
+ cache_expire("/cache")
31
+ end
32
+
33
+ end
34
+
35
+ MyAppDefault.run!(:port => 4569) if __FILE__ == $0
36
+
37
+ #/EOF
@@ -0,0 +1 @@
1
+ <h1>HOME</h1>
data/test/helper.rb ADDED
@@ -0,0 +1,62 @@
1
+ # vendor_sinatra = "#{File.dirname(File.dirname(__FILE__))}/vendor/sinatra"
2
+ # puts vendor_sinatra
3
+ # $LOAD_PATH.unshift "#{vendor_sinatra}/lib" if test(?d, vendor_sinatra)
4
+
5
+ path_2_my_lib = File.expand_path('../lib')
6
+ $LOAD_PATH.unshift path_2_my_lib
7
+
8
+ require 'rubygems'
9
+ require 'sinatra/base'
10
+ begin
11
+ require 'test/spec'
12
+ rescue LoadError
13
+ raise "These tests depends upon the Test-Spec gem [sudo gem install test-spec]"
14
+ end
15
+ require 'sinatra/test'
16
+
17
+
18
+ # The code below was lovingly plagiarized from Sinatra.
19
+
20
+ class Sinatra::Base
21
+ # Allow assertions in request context
22
+ include Test::Unit::Assertions
23
+ end
24
+
25
+ class Test::Unit::TestCase
26
+ include Sinatra::Test
27
+
28
+ def setup
29
+ Sinatra::Default.set :environment, :test
30
+ end
31
+
32
+ # Sets up a Sinatra::Base subclass defined with the block
33
+ # given. Used in setup or individual spec methods to establish
34
+ # the application.
35
+ def mock_app(base=Sinatra::Base, &block)
36
+ @app = Sinatra.new(base, &block)
37
+ end
38
+
39
+ def restore_default_options
40
+ Sinatra::Default.set(
41
+ :environment => :development,
42
+ :raise_errors => Proc.new { test? },
43
+ :dump_errors => true,
44
+ :sessions => false,
45
+ :logging => Proc.new { ! test? },
46
+ :methodoverride => true,
47
+ :static => true,
48
+ :run => Proc.new { ! test? }
49
+ )
50
+ end
51
+
52
+ # quick convenience methods..
53
+
54
+ def fixtures_path
55
+ "#{File.dirname(File.expand_path(__FILE__))}/fixtures"
56
+ end
57
+
58
+ def public_fixtures_path
59
+ "#{fixtures_path}/public"
60
+ end
61
+
62
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kematzy-sinatra-cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - kematzy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-14 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Simple Page Caching for Sinatra [www.sinatrarb.com]
17
+ email: kematzy@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.textile
24
+ - LICENSE
25
+ files:
26
+ - Dropbox-Code-Gems-sinatra-cache.tmproj
27
+ - README.textile
28
+ - VERSION.yml
29
+ - lib/sinatra
30
+ - lib/sinatra/cache.rb
31
+ - test/cache_test.rb
32
+ - test/fixtures
33
+ - test/fixtures/classic.rb
34
+ - test/fixtures/myapp.rb
35
+ - test/fixtures/myapp_default.rb
36
+ - test/fixtures/public
37
+ - test/fixtures/public/system
38
+ - test/fixtures/public/system/cache
39
+ - test/fixtures/views
40
+ - test/fixtures/views/index.erb
41
+ - test/helper.rb
42
+ - test/SPECS.rdoc
43
+ - LICENSE
44
+ has_rdoc: true
45
+ homepage: http://github.com/kematzy/sinatra-cache
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --inline-source
49
+ - --charset=UTF-8
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.2.0
68
+ signing_key:
69
+ specification_version: 2
70
+ summary: Simple Page Caching for Sinatra [www.sinatrarb.com]
71
+ test_files: []
72
+