sinatra-cache 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,147 @@
1
+
2
+ # :stopdoc:
3
+ unless Object.new.respond_to?(:blank?)
4
+
5
+ class Object
6
+ def blank?
7
+ respond_to?(:empty?) ? empty? : !self
8
+ end
9
+ def present?
10
+ !blank?
11
+ end
12
+ end
13
+ end
14
+ # :startdoc:
15
+
16
+
17
+ module Sinatra
18
+
19
+ # Sinatra::Output Extension
20
+ #
21
+ # Provides support for the :cache_fragment() functionality.
22
+ #
23
+ # Thank You very much Nathan. Much appreciated!
24
+ #
25
+ #
26
+ # The code within this extension is almost in its interity copied from:
27
+ #
28
+ # sinatra_more gem [ http://github.com/nesquena/sinatra_more/ ] by Nathan Esquenazi.
29
+ #
30
+ #
31
+ # Copyright (c) 2009 Nathan Esquenazi
32
+ #
33
+ # Permission is hereby granted, free of charge, to any person obtaining
34
+ # a copy of this software and associated documentation files (the
35
+ # "Software"), to deal in the Software without restriction, including
36
+ # without limitation the rights to use, copy, modify, merge, publish,
37
+ # distribute, sublicense, and/or sell copies of the Software, and to
38
+ # permit persons to whom the Software is furnished to do so, subject to
39
+ # the following conditions:
40
+ #
41
+ # The above copyright notice and this permission notice shall be
42
+ # included in all copies or substantial portions of the Software.
43
+ #
44
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
45
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
46
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
47
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
48
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
49
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
50
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
51
+ #
52
+ #
53
+ module Output
54
+
55
+ VERSION = Sinatra::Cache::VERSION
56
+ ##
57
+ # Returns the version string for this extension
58
+ #
59
+ # ==== Examples
60
+ #
61
+ # Sinatra::Output.version => 'Sinatra::Output v0.9.9'
62
+ #
63
+ def self.version; "Sinatra::Output v#{VERSION}"; end
64
+
65
+
66
+ module Helpers
67
+
68
+ # Captures the html from a block of template code for erb or haml
69
+ # capture_html(&block) => "...html..."
70
+ def capture_html(*args, &block)
71
+ if self.respond_to?(:is_haml?) && is_haml?
72
+ block_is_haml?(block) ? capture_haml(*args, &block) : block.call
73
+ elsif has_erb_buffer?
74
+ result_text = capture_erb(*args, &block)
75
+ result_text.present? ? result_text : (block_given? && block.call(*args))
76
+ else # theres no template to capture, invoke the block directly
77
+ block.call(*args)
78
+ end
79
+ end
80
+
81
+ # Outputs the given text to the templates buffer directly
82
+ # concat_content("This will be output to the template buffer in erb or haml")
83
+ def concat_content(text="")
84
+ if self.respond_to?(:is_haml?) && is_haml?
85
+ haml_concat(text)
86
+ elsif has_erb_buffer?
87
+ erb_concat(text)
88
+ else # theres no template to concat, return the text directly
89
+ text
90
+ end
91
+ end
92
+
93
+ # Returns true if the block is from an ERB or HAML template; false otherwise.
94
+ # Used to determine if html should be returned or concatted to view
95
+ # block_is_template?(block)
96
+ def block_is_template?(block)
97
+ block && (block_is_erb?(block) || (self.respond_to?(:block_is_haml?) && block_is_haml?(block)))
98
+ end
99
+
100
+
101
+ protected
102
+
103
+ # Used to capture the html from a block of erb code
104
+ # capture_erb(&block) => '...html...'
105
+ def capture_erb(*args, &block)
106
+ erb_with_output_buffer { block_given? && block.call(*args) }
107
+ end
108
+
109
+ # Concats directly to an erb template
110
+ # erb_concat("Direct to buffer")
111
+ def erb_concat(text)
112
+ @_out_buf << text if has_erb_buffer?
113
+ end
114
+
115
+ # Returns true if an erb buffer is detected
116
+ # has_erb_buffer? => true
117
+ def has_erb_buffer?
118
+ !@_out_buf.nil?
119
+ end
120
+
121
+ # Used to determine if a block is called from ERB.
122
+ # NOTE: This doesn't actually work yet because the variable __in_erb_template
123
+ # hasn't been defined in ERB. We need to find a way to fix this.
124
+ def block_is_erb?(block)
125
+ has_erb_buffer? || block && eval('defined? __in_erb_template', block)
126
+ end
127
+
128
+ # Used to direct the buffer for the erb capture
129
+ def erb_with_output_buffer(buf = '') #:nodoc:
130
+ @_out_buf, old_buffer = buf, @_out_buf
131
+ yield
132
+ @_out_buf
133
+ ensure
134
+ @_out_buf = old_buffer
135
+ end
136
+
137
+ end #/ Helpers
138
+
139
+ # def self.registered(app)
140
+ # app.helpers Sinatra::Output::Helpers
141
+ # end #/ self.registered
142
+
143
+ end #/ Output
144
+
145
+ helpers Sinatra::Output::Helpers
146
+
147
+ end #/ Sinatra
@@ -0,0 +1,55 @@
1
+
2
+ module Sinatra
3
+
4
+ ##
5
+ # Sinatra::Templates
6
+ #
7
+ # Monkey-patches the private <tt>#render</tt> method,
8
+ # in order to support 'auto-magic' cache functionality.
9
+ #
10
+ #
11
+ module Templates
12
+
13
+ private
14
+
15
+ def render(engine, data, options={}, locals={}, &block)
16
+ # merge app-level options
17
+ options = settings.send(engine).merge(options) if settings.respond_to?(engine)
18
+
19
+ # extract generic options
20
+ locals = options.delete(:locals) || locals || {}
21
+ views = options.delete(:views) || settings.views || "./views"
22
+ layout = options.delete(:layout)
23
+ layout = :layout if layout.nil? || layout == true
24
+
25
+ # set the cache related options
26
+ cache_enabled = settings.respond_to?(:cache_enabled) ? settings.send(:cache_enabled) : false
27
+ cache_output_dir = settings.send(:cache_output_dir) if settings.respond_to?(:cache_output_dir)
28
+ # raise Exception, "The Sinatra::Cache cache_output_dir variable is pointing to a non-existant directory cache_output_dir=[#{cache_output_dir}]" unless test(?d, cache_output_dir)
29
+ cache_option = options.delete(:cache)
30
+ cache_option = true if cache_option.nil?
31
+
32
+ # compile and render template
33
+ template = compile_template(engine, data, options, views)
34
+ output = template.render(self, locals, &block)
35
+
36
+ # render layout
37
+ if layout
38
+ begin
39
+ options = options.merge(:views => views, :layout => false)
40
+ output = render(engine, layout, options, locals) { output }
41
+ # Cache the content or just return it
42
+ (cache_enabled && settings.send(:environment) == settings.cache_environment) ?
43
+ cache_write_file(cache_file_path, output.gsub(/\n\r?$/,"")) : output
44
+ rescue Errno::ENOENT
45
+ end
46
+ end
47
+
48
+ # rendering without a layout
49
+ (cache_enabled && cache_option && settings.send(:environment) == settings.cache_environment) ?
50
+ cache_write_file(cache_file_path, output.gsub(/\n\r?$/,"") ) : output
51
+ end
52
+
53
+ end #/module Templates
54
+
55
+ end #/module Sinatra
@@ -5,44 +5,45 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sinatra-cache}
8
- s.version = "0.2.3"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["kematzy"]
12
- s.date = %q{2010-02-13}
13
- s.description = %q{Simple Page Caching for Sinatra [www.sinatrarb.com]}
12
+ s.date = %q{2010-02-25}
13
+ s.description = %q{A Sinatra Extension that makes Page and Fragment Caching easy.}
14
14
  s.email = %q{kematzy@gmail.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
- "README.md"
17
+ "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
20
  ".gitignore",
21
21
  "LICENSE",
22
- "README.md",
22
+ "README.rdoc",
23
23
  "Rakefile",
24
- "VERSION.yml",
24
+ "VERSION",
25
25
  "lib/sinatra/cache.rb",
26
+ "lib/sinatra/cache/helpers.rb",
27
+ "lib/sinatra/output.rb",
28
+ "lib/sinatra/templates.rb",
26
29
  "sinatra-cache.gemspec",
27
- "test/SPECS.rdoc",
28
- "test/cache_test.rb",
29
- "test/fixtures/classic.rb",
30
- "test/fixtures/myapp.rb",
31
- "test/fixtures/myapp_default.rb",
32
- "test/fixtures/views/index.erb",
33
- "test/helper.rb"
30
+ "spec/fixtures/apps/base/views/css.sass",
31
+ "spec/fixtures/apps/base/views/fragments.erb",
32
+ "spec/fixtures/apps/base/views/fragments_shared.erb",
33
+ "spec/fixtures/apps/base/views/index.erb",
34
+ "spec/fixtures/apps/base/views/layout.erb",
35
+ "spec/fixtures/apps/base/views/params.erb",
36
+ "spec/sinatra/cache_spec.rb",
37
+ "spec/spec_helper.rb"
34
38
  ]
35
39
  s.homepage = %q{http://github.com/kematzy/sinatra-cache}
36
40
  s.rdoc_options = ["--charset=UTF-8"]
37
41
  s.require_paths = ["lib"]
38
- s.rubygems_version = %q{1.3.5}
39
- s.summary = %q{Simple Page Caching for Sinatra [www.sinatrarb.com]}
42
+ s.rubygems_version = %q{1.3.6}
43
+ s.summary = %q{A Sinatra Extension that makes Page and Fragment Caching easy.}
40
44
  s.test_files = [
41
- "test/fixtures/myapp_default.rb",
42
- "test/fixtures/classic.rb",
43
- "test/fixtures/myapp.rb",
44
- "test/cache_test.rb",
45
- "test/helper.rb"
45
+ "spec/sinatra/cache_spec.rb",
46
+ "spec/spec_helper.rb"
46
47
  ]
47
48
 
48
49
  if s.respond_to? :specification_version then
@@ -50,9 +51,18 @@ Gem::Specification.new do |s|
50
51
  s.specification_version = 3
51
52
 
52
53
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
54
+ s.add_runtime_dependency(%q<sinatra>, [">= 1.0.a"])
55
+ s.add_development_dependency(%q<sinatra-tests>, [">= 0.1.6"])
56
+ s.add_development_dependency(%q<rspec>, [">= 1.3.0"])
53
57
  else
58
+ s.add_dependency(%q<sinatra>, [">= 1.0.a"])
59
+ s.add_dependency(%q<sinatra-tests>, [">= 0.1.6"])
60
+ s.add_dependency(%q<rspec>, [">= 1.3.0"])
54
61
  end
55
62
  else
63
+ s.add_dependency(%q<sinatra>, [">= 1.0.a"])
64
+ s.add_dependency(%q<sinatra-tests>, [">= 0.1.6"])
65
+ s.add_dependency(%q<rspec>, [">= 1.3.0"])
56
66
  end
57
67
  end
58
68
 
@@ -0,0 +1,2 @@
1
+ body
2
+ :color red
@@ -0,0 +1,11 @@
1
+ <h1>FRAGMENTS</h1>
2
+
3
+ <% cache_fragment(:test_fragment) do %>
4
+ <div id="cache-fragment">
5
+ <p><%= "Fragment created: #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}" %></p>
6
+ </div>
7
+ <% sleep 1 %>
8
+ <% end %>
9
+
10
+ <h2>Content After Sleep</h2>
11
+ <p><%= "Time is now: #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}" %></p>
@@ -0,0 +1,11 @@
1
+ <h1>FRAGMENTS - SHARED</h1>
2
+
3
+ <% cache_fragment(:test_fragment, :shared) do %>
4
+ <div id="cache-fragment">
5
+ <p><%= "Shared Fragment created: #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}" %></p>
6
+ </div>
7
+ <% sleep 1 %>
8
+ <% end %>
9
+
10
+ <h2>Content After Sleep</h2>
11
+ <p><%= "Time is now: #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}" %></p>
@@ -0,0 +1,9 @@
1
+ <html>
2
+ <head>
3
+ <title>Sinatra::Cache</title>
4
+ <%= cache_timestamp %>
5
+ </head>
6
+ <body>
7
+ <%= yield %>
8
+ </body>
9
+ </html>
@@ -0,0 +1,3 @@
1
+ <h1>PARAMS</h1>
2
+ <p><%= @captures.join(" | ") %></p>
3
+ <pre><%= params.inspect %></pre>
@@ -0,0 +1,593 @@
1
+
2
+ require "#{File.dirname(File.dirname(File.expand_path(__FILE__)))}/spec_helper"
3
+
4
+ describe "Sinatra" do
5
+
6
+ before(:each) do
7
+ @delete_cached_test_files = true #convenience toggle
8
+ end
9
+ describe "Cache" do
10
+
11
+ class MyDefaultsTestApp < MyTestApp
12
+ register(Sinatra::Cache)
13
+ end
14
+
15
+
16
+ class MyTestApp
17
+ register(Sinatra::Cache)
18
+
19
+ # need to set the root of the app for the default :cache_fragments_output_dir to work
20
+ set :root, ::APP_ROOT
21
+
22
+ set :cache_enabled, true
23
+ set :cache_environment, :test
24
+ set :cache_output_dir, "#{public_fixtures_path}/system/cache"
25
+ set :cache_fragments_output_dir, "#{public_fixtures_path}/system/cache_fragments"
26
+
27
+ get('/') { erb(:index) }
28
+ get('/erb/?') { erb(:index, :layout => false) }
29
+
30
+ # complex regex URL, matches
31
+ get %r{^/params/?([\s\w-]+)?/?([\w-]+)?/?([\w-]+)?/?([\w-]+)?/?([\w-]+)?/?([\w-]+)?} do
32
+ @captures = params[:captures].nil? ? [] : params[:captures].compact
33
+ erb(:params)
34
+ end
35
+ get('/file-extensions.*') do
36
+ @vars = { :framework => "Sinatra", :url => "www.sinatrarb.com" }
37
+ case params[:splat].first.to_sym
38
+ when :json
39
+ erb(@vars.to_json, :layout => false )
40
+ when :yaml
41
+ erb(@vars.to_yaml,:layout => false)
42
+ else
43
+ # direct output, should NOT be Cached
44
+ @vars.inspect
45
+ # @vars.inspect
46
+ end
47
+ end
48
+
49
+ get '/css/screen.css' do
50
+ content_type 'text/css'
51
+ sass(:css, :style => :compact)
52
+ end
53
+ get '/css/no/cache.css' do
54
+ content_type 'text/css'
55
+ sass(:css, :style => :compact, :cache => false)
56
+ end
57
+
58
+ # enable :method_override
59
+ post('/post/?') { erb("POST", :layout => false) }
60
+ put('/put/?') { erb('PUT', :layout => false) }
61
+ delete('/delete/?') { erb('DELETE', :layout => false) }
62
+
63
+ get %r{^/fragments/?([\s\w-]+)?/?([\w-]+)?/?([\w-]+)?/?([\w-]+)?/?([\w-]+)?/?([\w-]+)?} do
64
+ erb(:fragments, :layout => false, :cache => false)
65
+ end
66
+ get %r{^/sharedfragments/?([\s\w-]+)?/?([\w-]+)?/?([\w-]+)?/?([\w-]+)?/?([\w-]+)?/?([\w-]+)?} do
67
+ erb(:fragments_shared, :layout => false, :cache => false)
68
+ end
69
+
70
+
71
+ end
72
+
73
+
74
+ it_should_behave_like "MyTestApp"
75
+
76
+ # it_should_behave_like "debug => app.methods"
77
+
78
+ describe "VERSION" do
79
+
80
+ it "should return the VERSION string" do
81
+ Sinatra::Cache::VERSION.should be_a_kind_of(String)
82
+ Sinatra::Cache::VERSION.should match(/\d\.\d+\.\d+(\.\d)?/)
83
+ end
84
+
85
+ end #/ VERSION
86
+
87
+ describe "#self.version" do
88
+
89
+ it "should return a version of the Sinatra::Cache VERSION string" do
90
+ Sinatra::Cache.version.should be_a_kind_of(String)
91
+ Sinatra::Cache.version.should match(/Sinatra::Cache v\d\.\d+\.\d+(\.\d)?/)
92
+ end
93
+
94
+ end #/ #self.version
95
+
96
+
97
+ describe "Configuration" do
98
+
99
+ describe "with Default Settings" do
100
+
101
+ it "should set :cache_enabled to false" do
102
+ MyDefaultsTestApp.cache_enabled.should == false
103
+ end
104
+
105
+ it "should set :cache_environment to :production" do
106
+ MyDefaultsTestApp.cache_environment.should == :production
107
+ end
108
+
109
+ it "should set :cache_page_extension to '.html'" do
110
+ MyDefaultsTestApp.cache_page_extension.should == '.html'
111
+ end
112
+
113
+ it "should set :cache_output_dir to '../public'" do
114
+ MyDefaultsTestApp.cache_output_dir.should == "#{public_fixtures_path}"
115
+ end
116
+
117
+ it "should set :cache_fragments_output_dir to '../tmp/cache_fragments'" do
118
+ MyDefaultsTestApp.cache_fragments_output_dir.should == "#{fixtures_path}/tmp/cache_fragments"
119
+ end
120
+
121
+ it "should set :cache_logging to true" do
122
+ MyDefaultsTestApp.cache_logging.should == true
123
+ end
124
+
125
+ it "should set :cache_logging_level to :info" do
126
+ MyDefaultsTestApp.cache_logging_level.should == :info
127
+ end
128
+
129
+ end #/ with Default Settings
130
+
131
+ describe "with Custom Settings" do
132
+
133
+ it "should set :cache_enabled to true" do
134
+ MyTestApp.cache_enabled.should == true
135
+ end
136
+
137
+ it "should set :cache_environment to :test" do
138
+ MyTestApp.cache_environment.should == :test
139
+ end
140
+
141
+ it "should set :cache_page_extension to '.html'" do
142
+ MyTestApp.cache_page_extension.should == '.html'
143
+ end
144
+
145
+ it "should set :cache_output_dir to '../public/system/cache'" do
146
+ MyTestApp.cache_output_dir.should == "#{public_fixtures_path}/system/cache"
147
+ end
148
+
149
+ it "should set :cache_fragments_output_dir to '../public/system/cache_fragments'" do
150
+ MyTestApp.cache_fragments_output_dir.should == "#{public_fixtures_path}/system/cache_fragments"
151
+ end
152
+
153
+ it "should set :cache_logging to true" do
154
+ MyTestApp.cache_logging.should == true
155
+ end
156
+
157
+ it "should set :cache_logging_level to :info" do
158
+ MyTestApp.cache_logging_level.should == :info
159
+ end
160
+
161
+ end #/ Custom
162
+
163
+ end #/ Configuration
164
+
165
+
166
+ describe "Helpers" do
167
+
168
+ describe "#cache_timestamp" do
169
+
170
+ it "should return an HTML comment with the current timestamp" do
171
+ erb_app "<%= cache_timestamp %>"
172
+ body.should match(/\<\!-- page cached\: #{Regexp.escape(Time.now.strftime("%Y-%m-%d %H:%M:%S"))} -->/)
173
+ end
174
+
175
+ end #/ #cache_timestamp
176
+
177
+ module Sinatra::Cache::Helpers
178
+ public :cache_file_path, :cache_write_file, :cache_file_name, :cache_page_path
179
+ end
180
+
181
+ describe "#cache_file_path" do
182
+
183
+ it "should have some tests"
184
+
185
+ end #/ #cache_file_path
186
+
187
+ describe "#cache_write_file" do
188
+
189
+ it "should have some tests"
190
+
191
+ end #/ #cache_write_file
192
+
193
+ describe "#cache_file_name" do
194
+
195
+ it "should have some tests"
196
+
197
+ end #/ #cache_file_name
198
+
199
+ describe "#cache_page_path" do
200
+
201
+ it "should have some tests"
202
+
203
+ end #/ #cache_page_path
204
+
205
+ end #/ Helpers
206
+
207
+
208
+ describe "with caching enabled" do
209
+
210
+ describe "basic Page caching" do
211
+
212
+ describe "GET requests for" do
213
+
214
+ describe "the Home page - ['/' => /index.html] (with layout)" do
215
+
216
+ before(:each) do
217
+ @cache_file = "#{public_fixtures_path}/system/cache/index.html"
218
+ get('/')
219
+ end
220
+
221
+ after(:each) do
222
+ FileUtils.rm(@cache_file) if @delete_cached_test_files
223
+ end
224
+
225
+ it "should render the expected output" do
226
+ body.should have_tag('html > head > title', 'Sinatra::Cache')
227
+ body.should match(/<!-- page cached: #{Regexp.escape(Time.now.strftime("%Y-%m-%d %H:%M:%S"))} -->/)
228
+ body.should have_tag('html > body > h1', 'HOME')
229
+ end
230
+
231
+ it "should create a cached file in the cache output directory" do
232
+ test(?f, @cache_file).should == true
233
+ end
234
+
235
+ end #/ GET ['/' => /index.html]
236
+
237
+ describe "a basic URL without a trailing slash - ['/erb' => /erb.html] (ERB without layout)" do
238
+
239
+ before(:each) do
240
+ @cache_file = "#{public_fixtures_path}/system/cache/erb.html"
241
+ get('/erb')
242
+ end
243
+
244
+ after(:each) do
245
+ FileUtils.rm(@cache_file) if @delete_cached_test_files
246
+ end
247
+
248
+ it "should render the expected output" do
249
+ body.should == "<h1>HOME</h1>"
250
+ end
251
+
252
+ it "should create a cached file in the cache output directory" do
253
+ test(?f, @cache_file).should == true
254
+ end
255
+
256
+ end #/ GET ['/erb' => /erb.html]
257
+
258
+ describe "a basic URL with a trailing slash - ['/erb/' => /erb/index.html]" do
259
+
260
+ before(:each) do
261
+ @cache_file = "#{public_fixtures_path}/system/cache/erb/index.html"
262
+ get('/erb/')
263
+ end
264
+
265
+ after(:each) do
266
+ FileUtils.rm(@cache_file) if @delete_cached_test_files
267
+ end
268
+
269
+ it "should render the expected output" do
270
+ body.should == "<h1>HOME</h1>"
271
+ end
272
+
273
+ it "should create a cached file at ../cache/< URL >/index.html" do
274
+ test(?f, @cache_file).should == true
275
+ end
276
+
277
+ end #/ GET ['/erb/' => /erb/index.html]
278
+
279
+ describe "a URL with file extension - ['/file-extensions.EXT' => /file-extensions.EXT]" do
280
+
281
+ before(:each) do
282
+ ext = '.yaml'
283
+ @cache_file = "#{public_fixtures_path}/system/cache/file-extensions#{ext}"
284
+ get("/file-extensions#{ext}")
285
+ end
286
+
287
+ after(:each) do
288
+ FileUtils.rm(@cache_file) if @delete_cached_test_files
289
+ end
290
+
291
+ it "should render the expected output" do
292
+ body.should_not == ""
293
+ end
294
+
295
+ it "should create the cached file with the extension" do
296
+ test(?f, @cache_file).should == true
297
+ end
298
+
299
+ end #/ GET ['/file-extensions.EXT' => /file-extensions.EXT]
300
+
301
+ describe "URLs with multiple levels and/or with ?params attached" do
302
+
303
+ %w(
304
+ /params/? /params/1.xml?p=2 /params/page/?page=2 /params/page/?page=99
305
+ /params/a/ /params/a/b /params/a/b/c /params/a/b/c/d
306
+ ).each do |url|
307
+
308
+ # does the URL contain a ? or not
309
+ params_free_url = url =~ /\?/ ? url.split('?').first.chomp('?') : url
310
+ file_url = (params_free_url[-1,1] =~ /\//) ? "#{params_free_url}index" : params_free_url
311
+
312
+ # create the string for the test output below
313
+ file_url_str = File.extname(file_url) == '' ? file_url << '.html' : file_url
314
+
315
+ describe "the URL ['#{url}' => #{file_url_str}]" do
316
+
317
+ before(:each) do
318
+ @file_url = file_url
319
+ @cache_file = "#{public_fixtures_path}/system/cache#{file_url}"
320
+ @cache_file << ".html" if File.extname(@file_url) == ''
321
+ # puts "when the URL=[#{url}] the @cache_file=[#{@cache_file}] [#{__FILE__}:#{__LINE__}]"
322
+ get(url)
323
+ end
324
+
325
+ after(:each) do
326
+ FileUtils.remove_dir("#{public_fixtures_path}/system/cache/params") if @delete_cached_test_files
327
+ end
328
+
329
+ it "should render the expected output" do
330
+ body.should have_tag('html > head > title', 'Sinatra::Cache')
331
+ body.should have_tag('html > body > h1', 'PARAMS')
332
+ body.should have_tag('html > body > p' )
333
+ end
334
+
335
+ it "should create a cached file at [../public/system/cache#{file_url_str}]" do
336
+ test(?f, @cache_file).should == true
337
+ end
338
+
339
+ end #/ GET 'url' -
340
+
341
+ end #/ end loop
342
+
343
+ end #/ URLs with multiple levels and/or with ?params attached
344
+
345
+ describe "CSS URLs with dynamic .sass files" do
346
+
347
+ describe "the URL ['/css/screen.css' => /css/screen.css]" do
348
+
349
+ before(:each) do
350
+ @cache_file = "#{public_fixtures_path}/system/cache/css/screen.css"
351
+ FileUtils.remove_dir(File.dirname(@cache_file), :force => true )
352
+ get('/css/screen.css')
353
+ end
354
+
355
+ after(:each) do
356
+ FileUtils.rm(@cache_file) if @delete_cached_test_files
357
+ FileUtils.remove_dir(File.dirname(@cache_file), :force => true ) if @delete_cached_test_files
358
+ end
359
+
360
+ it "should output the correct CSS as expected" do
361
+ body.should == "body { color: red; }"
362
+ end
363
+
364
+ it "should automatically create the cache /css output directory" do
365
+ test(?d, File.dirname(@cache_file) ).should == true
366
+ end
367
+
368
+ it "should create a cached file at [../public/system/cache/css/screen.css]" do
369
+ test(?f, @cache_file).should == true
370
+ end
371
+
372
+ end #/ GET ['/css/screen.css' => /css/screen.css]
373
+
374
+ describe "URLs with ':cache => false' - ['/css/no/cache.css' => /css/no/cache.css]" do
375
+
376
+ before(:each) do
377
+ @cache_file = "#{public_fixtures_path}/system/cache/css/no/cache.css"
378
+ get('/css/no/cache.css')
379
+ end
380
+
381
+ it "should output the correct CSS as expected" do
382
+ body.should == "body { color: red; }\n"
383
+ end
384
+
385
+ it "should NOT cache the output" do
386
+ test(?d, File.dirname(@cache_file) ).should == false # testing for directory
387
+ test(?f, @cache_file).should == false
388
+ end
389
+
390
+ end #/ GET ['/css/no/cache.css' => /css/no/cache.css]
391
+
392
+ end #/ CSS URLs with dynamic .sass files
393
+
394
+ end #/ GET requests
395
+
396
+ describe "POST, PUT, DELETE requests" do
397
+
398
+ describe "POST '/post'" do
399
+
400
+ before(:each) do
401
+ @cache_file = "#{public_fixtures_path}/system/cache/post.html"
402
+ post('/post', :test => {:name => "test-#{Time.now.strftime("%Y-%d-%m %H:%M:%S")}", :content => "with content" })
403
+ end
404
+
405
+ it "should render any output as normal" do
406
+ body.should == 'POST'
407
+ end
408
+
409
+ it "should NOT cache the output" do
410
+ test(?f, @cache_file).should == false
411
+ end
412
+
413
+ end #/ POST '/post'
414
+
415
+ describe "PUT '/put'" do
416
+
417
+ before(:each) do
418
+ @cache_file = "#{public_fixtures_path}/system/cache/put.html"
419
+ put('/put', { :test => { :name => "test" }, :_method => "put" })
420
+ end
421
+
422
+ it "should render any output as normal" do
423
+ body.should == 'PUT'
424
+ end
425
+
426
+ it "should NOT cache the output" do
427
+ test(?f, @cache_file).should == false
428
+ end
429
+
430
+ end #/ PUT '/put'
431
+
432
+ describe "DELETE '/delete'" do
433
+
434
+ before(:each) do
435
+ @cache_file = "#{public_fixtures_path}/system/cache/delete.html"
436
+ delete('/delete') #, { :test => { :name => "test" }, :_method => "put" })
437
+ end
438
+
439
+ it "should render any output as normal" do
440
+ body.should == 'DELETE'
441
+ end
442
+
443
+ it "should NOT cache the output" do
444
+ test(?f, @cache_file).should == false
445
+ end
446
+
447
+ end #/ DELETE '/delete'
448
+
449
+ end #/ POST, PUT, DELETE requests
450
+
451
+ end #/ basic Page caching
452
+
453
+ describe "and Fragment caching" do
454
+
455
+ describe "using NOT shared fragments" do
456
+
457
+ after(:all) do
458
+ FileUtils.rm_r("#{public_fixtures_path}/system/cache_fragments/fragments") if @delete_cached_test_files
459
+ end
460
+
461
+ %w(
462
+ /fragments /fragments/a/b/ /fragments/with/param/?page=1
463
+ /fragments/dasherised-urls/works-as-well
464
+ ).each do |url|
465
+
466
+ params_free_url = url =~ /\?/ ? url.split('?').first.chomp('?') : url
467
+ dir_structure = params_free_url.gsub(/^\//,'').gsub(/\/$/,'')
468
+
469
+ it "should cache the fragments from the URL [#{url}] as [#{dir_structure}/test_fragment.html]" do
470
+ get(url)
471
+ # body.should have_tag(:debug)
472
+ body.should have_tag('h1','FRAGMENTS', :count => 1)
473
+ body.should_not match(/<!-- cache fragment:(.+)test_fragment -->/)
474
+ body.should_not match(/<!-- \/cache fragment: test_fragment cached at \[ \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\] -->/)
475
+
476
+ # render the page a 2nd time from cache
477
+ get(url)
478
+ body.should have_tag('h1','FRAGMENTS', :count => 1)
479
+ body.should match(/<!-- cache fragment:(.+)test_fragment -->/)
480
+ body.should match(/<!-- \/cache fragment: test_fragment cached at \[ \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\] -->/)
481
+
482
+ # the cached fragment has already been found if we get this far,
483
+ # but just for good measure do we check for the existence of the fragment file.
484
+ test(?f, "#{public_fixtures_path}/system/cache_fragments/#{dir_structure}/test_fragment.html").should == true
485
+ end
486
+ end
487
+
488
+ end #/ using NOT shared fragments
489
+
490
+ describe "using shared fragments" do
491
+
492
+ after(:all) do
493
+ FileUtils.rm_r("#{public_fixtures_path}/system/cache_fragments/sharedfragments") if @delete_cached_test_files
494
+ end
495
+
496
+ describe "when requesting the first URL" do
497
+
498
+ # FIXME:: work out some clever way to split all of these tests into single items instead of in one big blob
499
+
500
+ it "should cache the fragment based on the URL and use it on subsequent requests by URLs sharing the same root URL" do
501
+ url = '/sharedfragments/2010/02/some-article-01'
502
+ params_free_url = url =~ /\?/ ? url.split('?').first.chomp('?') : url
503
+ dir_structure = params_free_url.gsub(/^\//,'').gsub(/\/$/,'')
504
+ dirs = dir_structure.split('/')
505
+ dir_structure = dirs.first(dirs.length-1).join('/')
506
+
507
+ get(url)
508
+ # body.should have_tag(:debug)
509
+ body.should have_tag('h1','FRAGMENTS - SHARED', :count => 1)
510
+ body.should_not match(/<!-- cache fragment:(.+)test_fragment -->/)
511
+ body.should_not match(/<!-- \/cache fragment: test_fragment cached at \[ \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\] -->/)
512
+
513
+ get(url)
514
+ body.should have_tag('h1','FRAGMENTS - SHARED', :count => 1)
515
+ body.should match(/<!-- cache fragment:(.+)test_fragment -->/)
516
+ body.should match(/<!-- \/cache fragment: test_fragment cached at \[ \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\] -->/)
517
+
518
+ # the cached fragment has already been found if we get this far,
519
+ # but just for good measure do we check for the existence of the fragment file.
520
+ test(?f, "#{public_fixtures_path}/system/cache_fragments/#{dir_structure}/test_fragment.html").should == true
521
+
522
+ # should use the cached fragment rather than cache a new fragment
523
+ url = '/sharedfragments/2010/02/another-article-02'
524
+ get(url)
525
+ body.should have_tag('h1','FRAGMENTS - SHARED', :count => 1)
526
+ body.should match(/<!-- cache fragment:(.+)test_fragment -->/)
527
+ body.should match(/<!-- \/cache fragment: test_fragment cached at \[ \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\] -->/)
528
+ end
529
+
530
+ end #/ when requesting the first URL
531
+
532
+ end #/ using shared fragments
533
+
534
+ end #/ and Fragment caching
535
+
536
+ describe "basic Cache Expiring" do
537
+
538
+ describe "Pages" do
539
+
540
+ it "should expire the page ['/params/cache/expire/' => ../cache/params/cache/expire/index.html]" do
541
+ get('/params/cache/expire/')
542
+ test(?f,"#{public_fixtures_path}/system/cache/params/cache/expire/index.html" ).should == true
543
+ lambda {
544
+ erb_app "<% cache_expire('/params/cache/expire/') %>"
545
+ }.should_not raise_error(Exception)
546
+
547
+ test(?f,"#{public_fixtures_path}/system/cache/params/cache/expire/index.html" ).should == false
548
+
549
+ end
550
+
551
+ it "should expire the page ['/params/cache/expired' => ../cache/params/cache/expired.html]" do
552
+ get('/params/cache/expired')
553
+ test(?f,"#{public_fixtures_path}/system/cache/params/cache/expired.html" ).should == true
554
+ lambda {
555
+ erb_app "<% cache_expire('/params/cache/expired') %>"
556
+ }.should_not raise_error(Exception)
557
+
558
+ test(?f,"#{public_fixtures_path}/system/cache/params/cache/expired.html" ).should == false
559
+
560
+ end
561
+
562
+ end #/ Pages
563
+
564
+ describe "Fragments" do
565
+
566
+ it "should expire the fragment ['/fragments/cache/expire/' => ../cache_fragments/fragments/cache/expire/test_fragment.html]" do
567
+ get('/fragments/cache/expire/')
568
+ test(?f,"#{public_fixtures_path}/system/cache_fragments/fragments/cache/expire/test_fragment.html" ).should == true
569
+ lambda {
570
+ erb_app "<% cache_expire('/fragments/cache/expire/',:fragment => :test_fragment) %>"
571
+ }.should_not raise_error(Exception)
572
+ test(?f,"#{public_fixtures_path}/system/cache/params/cache_fragments/expire/test_fragment.html" ).should == false
573
+ end
574
+
575
+ it "should expire the fragment ['/fragments/cache/expired' => ../cache_fragments/fragments/cache/expired/test_fragment.html]" do
576
+ get('/fragments/cache/expired')
577
+ test(?f,"#{public_fixtures_path}/system/cache_fragments/fragments/cache/expired/test_fragment.html" ).should == true
578
+ lambda {
579
+ erb_app "<% cache_expire('/fragments/cache/expired',:fragment => :test_fragment) %>"
580
+ }.should_not raise_error(Exception)
581
+ test(?f,"#{public_fixtures_path}/system/cache/params/cache_fragments/expired/test_fragment.html" ).should == false
582
+ end
583
+
584
+ end #/ Pages
585
+
586
+ end #/ basic Cache Expiring
587
+
588
+
589
+ end #/ with caching enabled
590
+
591
+ end #/ Cache
592
+
593
+ end #/ Sinatra