sinatra-cache 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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