kschrader-sinatra-cache 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,126 @@
1
+ h1. Sinatra::Cache
2
+
3
+ Adds a very *simple* Page Caching functionality to "Sinatra":http://www.sinatrarb.com/
4
+
5
+ <hr>
6
+
7
+ h3. *PLEASE KEEP THIS IN MIND*
8
+
9
+ This is *unfinished work*, so use with care.
10
+
11
+ If you find it lacking or badly coded, please feel free to fork and improve. I'll be very happy :)
12
+
13
+ <hr>
14
+
15
+
16
+ h3. TODO's
17
+
18
+
19
+ = Make caching an option of the normal <tt>erb()/haml()/sass()</tt> methods, sort of like this:
20
+ <pre><code>
21
+ erb(:index, :cache => true/false)
22
+
23
+ # alternatively enable caching by setting a global config like this
24
+ set :cache_enabled_for :all || :only/except => ['/','/contact',...]
25
+
26
+ </code></pre>
27
+
28
+
29
+ = Improve the logging output to the standard Sinatra output (if we are having :logging enabled )
30
+
31
+ = Add fragment caching...
32
+
33
+ = Enable the options functionality for the <tt>:cache</tt> & <tt>:cache_expire</tt> methods, so that they can take custom extensions and more
34
+
35
+
36
+ <hr>
37
+
38
+
39
+ h3. CONFIGURATION
40
+
41
+ *Example 1: Sinatra 'classic' app.*
42
+
43
+ <pre><code>
44
+ <snip....>
45
+ require 'sinatra/cache'
46
+
47
+ # toggle for the cache functionality.
48
+ set :cache_enabled, true
49
+ # sets the default extension for cached files
50
+ set :cache_page_extension, '.html'
51
+ # sets the Cache dir to the root of the /public directory.
52
+ set :cache_output_dir, '' # was :cache_dir
53
+ ...
54
+ </code></pre>
55
+
56
+ *Example 2: Sinatra 'sub-classed' app.*
57
+
58
+ <pre><code>
59
+ <snip....>
60
+ require 'sinatra/cache'
61
+
62
+ class MyApp < Sinatra::Base
63
+
64
+ register Sinatra::Cache
65
+
66
+ # toggle for the cache functionality.
67
+ set :cache_enabled, true
68
+ # sets the default extension for cached files
69
+ set :cache_page_extension, '.html'
70
+ # sets the Cache output dir to the root of the /public directory.
71
+ set :cache_output_dir, '' # was :cache_dir
72
+
73
+ <snip....>
74
+ </code></pre>
75
+
76
+
77
+ <hr>
78
+
79
+
80
+ h3. USAGE
81
+
82
+
83
+ Basic Page Caching into static HTML files
84
+
85
+ <pre><code>
86
+ get '/contact' do
87
+ # NB! options is currently not working
88
+ cache( erb( :contact ), :options => 'should go here' )
89
+ end
90
+ </code></pre>
91
+
92
+ Expiring old pages (ie: after POST or PUT events)
93
+
94
+ <pre><code>
95
+ # not very good example
96
+ post '/contact' do
97
+ cache_expire( '/contact', options )
98
+ end
99
+ </code></pre>
100
+
101
+ See the "test":test/ and "test/fixtures":test/fixtures/ directories for more examples.
102
+
103
+
104
+ <hr>
105
+
106
+
107
+ h3. DEFAULT OPTIONS
108
+
109
+ * <tt>:cache_enabled</tt> => toggle for the cache functionality. Default is: <tt>true</tt>
110
+ * <tt>:cache_page_extension</tt> => sets the default extension for cached files. Default is: <tt>.html</tt>
111
+ * <tt>:cache_output_dir</tt> => sets cache directory where cached files are stored. Default is: ''(empty) == root of /public.<br>
112
+ set to empty, since the ideal 'system/cache/' does not currently work with Passenger & mod_rewrite :(
113
+ * <tt>:cache_logging</tt> => toggle for logging the cache calls. Default is: <tt>true</tt>
114
+ * <tt>:cache_logging_level</tt> => sets the level of the cache logger. Default is: <tt>:info</tt>.<br>
115
+ Options:(unused atm) [:info, :warn, :debug]
116
+
117
+
118
+ <hr>
119
+
120
+ h3. Credits
121
+
122
+ A big *Thank You!* goes to "*rtomayko*":http://github.com/rtomayko/, "*blakemizerany*":http://github.com/blakemizerany/ and others working on the Sinatra framework.
123
+
124
+ Inspired by code from "Rails":http://rubyonrails.com/ &amp; "Merb":http://merbivore.com/
125
+ and "sinatra-mailer":http://github.com/foca/sinatra-mailer/tree/master
126
+
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 2
3
+ :patch: 3
4
+ :major: 0
@@ -0,0 +1,150 @@
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.2'
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 = "#{content}\n#{page_cached_timestamp}"
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, opts)
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
+ # Simple method to see if a file already exists in the cache
79
+ #
80
+ # TODO: Testcases!
81
+
82
+ def cached_file_exists(path, opts={})
83
+ path = (path.nil?) ? cache_page_path(request.path_info) : cache_page_path(path, opts)
84
+ return File.exist?(path)
85
+ end
86
+
87
+ private
88
+
89
+ # Establishes the file name of the cached file from the path given
90
+ #
91
+ # TODO:: implement the opts={} functionality, and support for custom extensions on a per request basis.
92
+ #
93
+ def cache_file_name(path,opts={})
94
+ name = (path.empty? || path == "/") ? "index" : Rack::Utils.unescape(path.sub(/^(\/)/,'').chomp('/'))
95
+ opts.each do |key, value|
96
+ name = name + "." + key.to_s.downcase + "." + value.to_s.downcase
97
+ end
98
+ name << options.cache_page_extension # unless (name.split('/').last || name).include? '.'
99
+ return name
100
+ end
101
+
102
+ # Sets the full path to the cached page/file
103
+ # Dependent upon Sinatra.options .public and .cache_dir variables being present and set.
104
+ #
105
+ def cache_page_path(path,opts={})
106
+ # test if given a full path rather than relative path, otherwise join the public path to cache_dir
107
+ # and ensure it is a full path
108
+ cache_dir = (options.cache_output_dir == File.expand_path(options.cache_output_dir)) ?
109
+ options.cache_output_dir : File.expand_path("#{options.public}/#{options.cache_output_dir}")
110
+ cache_dir = cache_output_dir[0..-2] if cache_dir[-1,1] == '/'
111
+ "#{cache_dir}/#{cache_file_name(path,opts)}"
112
+ end
113
+
114
+ # TODO:: this implementation really stinks, how do I incorporate Sinatra's logger??
115
+ def log(msg,scope=:debug)
116
+ if options.cache_logging
117
+ "Log: msg=[#{msg}]" if scope == options.cache_logging_level
118
+ else
119
+ # just ignore the stuff...
120
+ # puts "just ignoring msg=[#{msg}] since cache_logging => [#{options.cache_logging.to_s}]"
121
+ end
122
+ end
123
+
124
+ end #/module Helpers
125
+
126
+
127
+ # Sets the default options:
128
+ #
129
+ # * +:cache_enabled+ => toggle for the cache functionality. Default is: +true+
130
+ # * +:cache_page_extension+ => sets the default extension for cached files. Default is: +.html+
131
+ # * +:cache_dir+ => sets cache directory where cached files are stored. Default is: ''(empty) == root of /public.<br>
132
+ # set to empty, since the ideal 'system/cache/' does not work with Passenger & mod_rewrite :(
133
+ # * +cache_logging+ => toggle for logging the cache calls. Default is: +true+
134
+ # * +cache_logging_level+ => sets the level of the cache logger. Default is: <tt>:info</tt>.<br>
135
+ # Options:(unused atm) [:info, :warn, :debug]
136
+ #
137
+ def self.registered(app)
138
+ app.helpers(Cache::Helpers)
139
+ app.set :cache_enabled, true
140
+ app.set :cache_page_extension, '.html'
141
+ app.set :cache_output_dir, ''
142
+ app.set :cache_logging, true
143
+ app.set :cache_logging_level, :info
144
+ end
145
+
146
+ end #/module Cache
147
+
148
+ register(Sinatra::Cache)
149
+
150
+ end #/module Sinatra
@@ -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,434 @@
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_output_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_output_dir option should be correct ('') " do
232
+ assert_equal('', @default_app.options.cache_output_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_output_dir option should be correct ('system/cache') " do
256
+ assert_equal('system/cache', @custom_app.options.cache_output_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(/^Hello World from Sinatra Version=\[\d\.\d\.\d(\.\d)?\]\n/, response.body)
292
+ assert(test(?f, "#{public_fixtures_path}/cache.html"))
293
+ assert_match(/^Hello 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_output_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(/^Hello World from Sinatra Version=\[\d\.\d\.\d(\.\d)?\]\n<!-- page cached: \d+-\d+-\d+ \d+:\d+:\d+ -->\n$/, response.body)
364
+ assert(test(?f, "#{public_fixtures_path}/system/cache/cache.cache.html"))
365
+ assert_match(/^Hello World from Sinatra Version=\[\d\.\d\.\d(\.\d)?\]\n<!-- page cached: \d+-\d+-\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_output_dir", "cache_output_dir=","cache_output_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_output_dir", "cache_output_dir=","cache_output_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
+ 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>
@@ -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,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kschrader-sinatra-cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.3
5
+ platform: ruby
6
+ authors:
7
+ - kematzy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-27 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
+
24
+ files:
25
+ - README.textile
26
+ - VERSION.yml
27
+ - lib/sinatra
28
+ - lib/sinatra/cache.rb
29
+ - test/cache_test.rb
30
+ - test/fixtures
31
+ - test/fixtures/classic.rb
32
+ - test/fixtures/myapp.rb
33
+ - test/fixtures/myapp_default.rb
34
+ - test/fixtures/public
35
+ - test/fixtures/public/system
36
+ - test/fixtures/public/system/cache
37
+ - test/fixtures/views
38
+ - test/fixtures/views/index.erb
39
+ - test/helper.rb
40
+ - test/SPECS.rdoc
41
+ has_rdoc: true
42
+ homepage: http://github.com/kematzy/sinatra-cache
43
+ post_install_message:
44
+ rdoc_options:
45
+ - --inline-source
46
+ - --charset=UTF-8
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ requirements: []
62
+
63
+ rubyforge_project:
64
+ rubygems_version: 1.2.0
65
+ signing_key:
66
+ specification_version: 2
67
+ summary: Simple Page Caching for Sinatra [www.sinatrarb.com]
68
+ test_files: []
69
+