bchiu-merb_cache_more 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ namespace :merb_cache_more do
2
+ desc "Do something for merb_cache_more"
3
+ task :default do
4
+ puts "merb_cache_more doesn't do anything"
5
+ end
6
+ end
@@ -0,0 +1,59 @@
1
+ module Merb
2
+ class Request
3
+ class << self
4
+ # ==== Parameters
5
+ # value<Array, Hash, Dictionary ~to_s>:: The value for the query string.
6
+ # prefix<~to_s>:: The prefix to add to the query string keys.
7
+ #
8
+ # ==== Returns
9
+ # String:: The query string.
10
+ #
11
+ # ==== Alternatives
12
+ # If the value is a string, the prefix will be used as the key.
13
+ #
14
+ # ==== Examples
15
+ # params_to_query_string(10, "page")
16
+ # # => "page=10"
17
+ # params_to_query_string({ :page => 10, :word => "ruby" })
18
+ # # => "page=10&word=ruby"
19
+ # params_to_query_string({ :page => 10, :word => "ruby" }, "search")
20
+ # # => "search[page]=10&search[word]=ruby"
21
+ # params_to_query_string([ "ice-cream", "cake" ], "shopping_list")
22
+ # # => "shopping_list[]=ice-cream&shopping_list[]=cake"
23
+ def params_to_query_string(value, prefix = nil)
24
+ case value
25
+ when Array
26
+ value.map { |v|
27
+ params_to_query_string(v, "#{prefix}[]")
28
+ } * "&"
29
+ when Hash, Dictionary
30
+ value.map { |k, v|
31
+ params_to_query_string(v, prefix ? "#{prefix}[#{Merb::Request.escape(k)}]" : Merb::Request.escape(k))
32
+ } * "&"
33
+ else
34
+ "#{prefix}=#{Merb::Request.escape(value)}"
35
+ end
36
+ end
37
+
38
+ # ==== Parameters
39
+ # qs<String>:: The query string.
40
+ # d<String>:: The query string divider. Defaults to "&".
41
+ # preserve_order<Boolean>:: Preserve order of args. Defaults to false.
42
+ #
43
+ # ==== Returns
44
+ # Mash:: The parsed query string (Dictionary if preserve_order is set).
45
+ #
46
+ # ==== Examples
47
+ # query_parse("bar=nik&post[body]=heya")
48
+ # # => { :bar => "nik", :post => { :body => "heya" } }
49
+ def query_parse(qs, d = '&;', preserve_order = false)
50
+ qh = preserve_order ? Dictionary.new : {}
51
+ (qs||'').split(/[#{d}] */n).inject(qh) { |h,p|
52
+ key, value = unescape(p).split('=',2)
53
+ normalize_params(h, key, value)
54
+ }
55
+ preserve_order ? qh : qh.to_mash
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,40 @@
1
+ module Merb
2
+ module Test
3
+ module RequestHelper
4
+ # Dispatches an action to the given class. This bypasses the router and is
5
+ # suitable for unit testing of controllers.
6
+ #
7
+ # ==== Parameters
8
+ # controller_klass<Controller>::
9
+ # The controller class object that the action should be dispatched to.
10
+ # action<Symbol>:: The action name, as a symbol.
11
+ # params<Hash>::
12
+ # An optional hash that will end up as params in the controller instance.
13
+ # env<Hash>::
14
+ # An optional hash that is passed to the fake request. Any request options
15
+ # should go here (see +fake_request+), including :req or :post_body
16
+ # for setting the request body itself.
17
+ # &blk::
18
+ # The controller is yielded to the block provided for actions *prior* to
19
+ # the action being dispatched.
20
+ #
21
+ # ==== Example
22
+ # dispatch_to(MyController, :create, :name => 'Homer' ) do
23
+ # self.stub!(:current_user).and_return(@user)
24
+ # end
25
+ #
26
+ # ==== Notes
27
+ # Does not use routes.
28
+ #
29
+ #---
30
+ # @public
31
+ def dispatch_to(controller_klass, action, params = {}, env = {}, &blk)
32
+ action = action.to_s
33
+ request_body = { :post_body => env[:post_body], :req => env[:req] }
34
+ env = env.merge(:query_string => Merb::Request.params_to_query_string(params)) unless env.key?('QUERY_STRING')
35
+ request = fake_request(env, request_body)
36
+ dispatch_request(request, controller_klass, action, &blk)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,76 @@
1
+ describe "cache_action with params" do
2
+
3
+ qs = "p1=abc&p2=456&p3=ghi"
4
+
5
+ it "should cache action (action3) with params in default format" do
6
+ c = get("/cache_controller/action3", {}, {:query_string => qs})
7
+ c.body.strip.should == "test action3"
8
+ c.cached?(:key => "/cache_controller/action3/p1_abc_p2_456_p3_ghi").should be_true
9
+ c.cache_get(:key => "/cache_controller/action3/p1_abc_p2_456_p3_ghi").should == "test action3"
10
+ end
11
+
12
+ it "should expire action (action3) with params in default format" do
13
+ c = get("/cache_controller/action3", {}, {:query_string => qs})
14
+ c.expire_action(:key => "/cache_controller/action3/p1_abc_p2_456_p3_ghi")
15
+ c.cache_get(:key => "/cache_controller/action3/p1_abc_p2_456_p3_ghi").should be_nil
16
+ end
17
+
18
+ it "should cache action (action3) with full path and params in default format" do
19
+ c = get("/cache_controller/action3/foo/bar", {}, {:query_string => qs})
20
+ c.body.strip.should == "test action3"
21
+ c.cached?(:key => "/cache_controller/action3/foo/bar/p1_abc_p2_456_p3_ghi").should be_true
22
+ c.cache_get(:key => "/cache_controller/action3/foo/bar/p1_abc_p2_456_p3_ghi").should == "test action3"
23
+ end
24
+
25
+ it "should expire action (action3) with full path and params in default format" do
26
+ c = get("/cache_controller/action3/foo/bar", {}, {:query_string => qs})
27
+ c.expire_action(:key => "/cache_controller/action3/foo/bar/p1_abc_p2_456_p3_ghi")
28
+ c.cache_get(:key => "/cache_controller/action3/foo/bar/p1_abc_p2_456_p3_ghi").should be_nil
29
+ end
30
+
31
+ it "should cache action (action12) with specific params" do
32
+ c = get("/cache_controller/action12", {}, {:query_string => qs})
33
+ c.cached?(:key => "/cache_controller/action12/p1_abc_p2_456").should be_true
34
+ c.cache_get(:key => "/cache_controller/action12/p1_abc_p2_456").should == "test action12"
35
+ end
36
+
37
+ it "should expire action (action12) with specific params" do
38
+ c = get("/cache_controller/action12", {}, {:query_string => qs})
39
+ c.expire_action(:key => "/cache_controller/action12/p1_abc_p2_456")
40
+ c.cache_get(:key => "/cache_controller/action12/p1_abc_p2_456").should be_nil
41
+ end
42
+
43
+ it "should cache actions with params in every key format" do
44
+ c = get("/cache_controller/action13", {}, {:query_string => qs}) # snake
45
+ c.cached?(:key => "/cache_controller/action13/abc_456_ghi").should be_true
46
+
47
+ c = get("/cache_controller/action14", {}, {:query_string => qs}) # tree
48
+ c.cached?(:key => "/cache_controller/action14/abc/456/ghi").should be_true
49
+
50
+ c = get("/cache_controller/action15", {}, {:query_string => qs}) # hash
51
+ c.cached?(:key => "/cache_controller/action15/" + Digest::MD5.hexdigest("p1abcp2456p3ghi")).should be_true
52
+
53
+ c = get("/cache_controller/action16", {}, {:query_string => qs}) # query
54
+ c.cached?(:key => "/cache_controller/action16/p1=abc&p2=456&p3=ghi").should be_true
55
+
56
+ c = get("/cache_controller/action17", {}, {:query_string => qs}) # custom
57
+ c.cached?(:key => "/cache_controller/action17/abc/456_and_ghi").should be_true
58
+ end
59
+
60
+ it "should expire actions with params in every key format" do
61
+ CACHE.expire_action(:key => "/cache_controller/action13/abc_456_ghi")
62
+ CACHE.cached?(:key => "/cache_controller/action13/abc_456_ghi").should be_false
63
+
64
+ CACHE.expire_action(:key => "/cache_controller/action14/abc/456/ghi")
65
+ CACHE.cached?(:key => "/cache_controller/action14/abc/456/ghi").should be_false
66
+
67
+ CACHE.expire_action(:key => "/cache_controller/action15/" + Digest::MD5.hexdigest("p1abcp2456p3ghi"))
68
+ CACHE.cached?(:key => "/cache_controller/action15/" + Digest::MD5.hexdigest("p1abcp2456p3ghi")).should be_false
69
+
70
+ CACHE.expire_action(:key => "/cache_controller/action16/p1=abc&p2=456&p3=ghi")
71
+ CACHE.cached?(:key => "/cache_controller/action16/p1=abc&p2=456&p3=ghi").should be_false
72
+
73
+ CACHE.expire_action(:key => "/cache_controller/action17/abc/456_and_ghi")
74
+ CACHE.cached?(:key => "/cache_controller/action17/abc/456_and_ghi").should be_false
75
+ end
76
+ end
@@ -0,0 +1,137 @@
1
+ describe "cache_action" do
2
+
3
+ it "should cache action (action3)" do
4
+ c = get("/cache_controller/action3")
5
+ c.body.strip.should == "test action3"
6
+ c.cached?("/cache_controller/action3").should be_true
7
+ c.cached_action?("action3").should be_true
8
+ c.cache_get("/cache_controller/action3").should == "test action3"
9
+ end
10
+
11
+ it "should expire action (action3)" do
12
+ CACHE.expire_action "action3"
13
+ CACHE.cache_get("/cache_controller/action3").should be_nil
14
+ end
15
+
16
+ it "should cache action (action3) with full path" do
17
+ c = get("/cache_controller/action3/abc/456/ghi")
18
+ c.body.strip.should == "test action3"
19
+ c.cached?(c.request.path).should be_true
20
+ c.cache_get(c.request.path).should == "test action3"
21
+ end
22
+
23
+ it "should expire action (action3) with full path" do
24
+ c = get("/cache_controller/action3/abc/456/ghi")
25
+ c.expire_action(:key => c.request.path)
26
+ c.cache_get(c.request.path).should be_nil
27
+ end
28
+
29
+ it "should expire action (action4) after 3 seconds" do
30
+ c = get("/cache_controller/action4")
31
+ c.body.strip.should == "test action4"
32
+ c.cached?("/cache_controller/action4").should be_true
33
+ c.cache_get("/cache_controller/action4").should == "test action4"
34
+ sleep 4
35
+ c.cache_get("/cache_controller/action4").should be_nil
36
+ c.cached_action?(:action => "action4").should be_false
37
+ end
38
+
39
+ it "should cache action with full path (action4) and expire in 3 seconds" do
40
+ CACHE.expire_action :match => true, :action => "action4"
41
+ CACHE.cached_action?(:action => "action4", :params => %w(path to nowhere), :format => :tree).should be_false
42
+ c = get("/cache_controller/action4/path/to/nowhere/")
43
+ c.cached_action?(:action => "action4", :params => %w(path to nowhere), :format => :tree).should be_true
44
+ sleep 3.5
45
+ c.cache_get("/cache_controller/action4/path/to/nowhere").should be_nil
46
+ c.cached_action?(:action => "action4", :params => %w(path to nowhere), :format => :tree).should be_false
47
+ end
48
+
49
+ it "should expire action in many ways" do
50
+ c = get("/cache_controller/action4")
51
+ CACHE.expire_action("action4")
52
+ CACHE.cached_action?("action4").should be_false
53
+
54
+ c = get("/cache_controller/action4")
55
+ CACHE.expire_action(:match => "/cache_control")
56
+ CACHE.cached_action?(:action => "action4").should be_false
57
+
58
+ c = get("/cache_controller/action4")
59
+ CACHE.expire_action(:action => "action4")
60
+ CACHE.cached_action?(:action => "action4").should be_false
61
+
62
+ c = get("/cache_controller/action4/id1/id2")
63
+ CACHE.expire_action(:action => "action4", :params => %w(id1 id2), :format => :tree)
64
+ CACHE.cached_action?(:action => "action4", :params => %w(id1 id2), :format => :tree).should be_false
65
+
66
+ c = get("/cache_controller/action4/id1/id2")
67
+ CACHE.expire_action(:action => "action4", :match => true, :format => :tree)
68
+ CACHE.cached_action?(:action => "action4", :params => %w(id1 id2), :format => :tree).should be_false
69
+
70
+ c = get("/cache_controller/action4")
71
+ CACHE.expire_action(:action => "action4", :controller => "cache_controller")
72
+ CACHE.cached_action?(:action => "action4", :controller => "cache_controller").should be_false
73
+
74
+ c = get("/cache_controller/action4/id1/id2")
75
+ CACHE.expire_action(:action => "action4", :params => %w(id1), :match => true)
76
+ CACHE.cached_action?(:action => "action4", :params => %w(id1 id2), :format => :tree).should be_false
77
+
78
+ c = get("/cache_controller/action4/id1/id2")
79
+ CACHE.expire_action(:action => "action4", :controller => "cache_controller", :match => true)
80
+ CACHE.cached_action?(:action => "action4", :params => %w(id1 id2), :format => :tree).should be_false
81
+
82
+ c = get("/cache_controller/action4/id1/id2")
83
+ CACHE.expire_action(:action => "action4", :controller => "cache_controller", :params => %w(id1), :match => true)
84
+ CACHE.cached_action?(:action => "action4", :params => %w(id1 id2), :format => :tree).should be_false
85
+
86
+ c = get("/cache_controller/action4/id1/id2")
87
+ CACHE.expire_action(:action => "action4", :controller => "cache_controller", :params => %w(id1 id2), :format => :tree)
88
+ CACHE.cached_action?(:action => "action4", :controller => "cache_controller", :params => %w(id1 id2), :format => :tree).should be_false
89
+
90
+ c = get("/cache_controller/action4")
91
+ CACHE.expire_action(:key => "/cache_controller/action4")
92
+ CACHE.cached_action?(:key => "/cache_controller/action4").should be_false
93
+ c = get("/cache_controller/action4/id1/id2")
94
+ CACHE.expire_action(:key => "/cache_controller/action4", :params => %w(id1 id2), :format => :tree)
95
+ CACHE.cached_action?(:key => "/cache_controller/action4", :params => %w(id1 id2), :format => :tree).should be_false
96
+
97
+ c = get("/cache_controller/action4/id1/id2")
98
+ CACHE.expire_action(:key => "/cache_controller/action4/id1", :match => true)
99
+ CACHE.cached_action?(:key => "/cache_controller/action4/id1/id2").should be_false
100
+
101
+ c = get("/cache_controller/action4/id1/id2")
102
+ CACHE.expire_action(:key => "/cache_controller/action4", :params => %w(id1), :match => true)
103
+ CACHE.cached_action?(:key => "/cache_controller/action4/id1/id2").should be_false
104
+ end
105
+
106
+ it "should allow :if conditions with procs" do
107
+ c = get("/cache_controller/action8")
108
+ CACHE.cached_action?(:key => "/cache_controller/action8").should be_false
109
+
110
+ c = get("/cache_controller/action8/cache")
111
+ CACHE.cached_action?(:key => "/cache_controller/action8/cache").should be_true
112
+ end
113
+
114
+ it "should allow :unless conditions with procs" do
115
+ c = get("/cache_controller/action9")
116
+ CACHE.cached_action?(:key => "/cache_controller/action9").should be_false
117
+
118
+ c = get("/cache_controller/action9/cache")
119
+ CACHE.cached_action?(:key => "/cache_controller/action9/cache").should be_true
120
+ end
121
+
122
+ it "should allow :if conditions with symbols" do
123
+ c = get("/cache_controller/action10")
124
+ CACHE.cached_action?(:key => "/cache_controller/action10").should be_false
125
+
126
+ c = get("/cache_controller/action10/cache")
127
+ CACHE.cached_action?(:key => "/cache_controller/action10/cache").should be_true
128
+ end
129
+
130
+ it "should allow :unless conditions with symbols" do
131
+ c = get("/cache_controller/action11")
132
+ CACHE.cached_action?(:key => "/cache_controller/action11").should be_false
133
+
134
+ c = get("/cache_controller/action11/cache")
135
+ CACHE.cached_action?(:key => "/cache_controller/action11/cache").should be_true
136
+ end
137
+ end
@@ -0,0 +1,85 @@
1
+ class CacheController < Merb::Controller
2
+ self._template_root = File.dirname(__FILE__) / "views"
3
+ before :fix_query_string
4
+
5
+ cache_action :action3
6
+ cache_action :action4, 0.05
7
+ #cache_actions :action3, [:action4, 0.05]
8
+
9
+ cache_page :action5
10
+ cache_page :action6, 0.05
11
+ #cache_pages :action5, [:action6, 0.05]
12
+ cache_page :action7
13
+
14
+ cache_action :action8, 0.05, :if => proc {|controller| !controller.params[:id].empty?}
15
+ cache_action :action9, 0.05, :unless => proc {|controller| controller.params[:id].empty?}
16
+ cache_action :action10, :if => :non_empty_id?
17
+ cache_action :action11, :unless => :empty_id?
18
+
19
+ cache_action :action12, :params => [:p1, :p2]
20
+ cache_action :action13, :format => :snake
21
+ cache_action :action14, :format => :tree
22
+ cache_action :action15, :format => :hash
23
+ cache_action :action16, :format => :query
24
+ cache_action :action17, :format => ":p1/:p2_and_:p3"
25
+
26
+ cache_page :action18, :params => [:p1, :p2]
27
+ cache_page :action19, :format => :snake
28
+ cache_page :action20, :format => :tree
29
+ cache_page :action21, :format => :hash
30
+ cache_page :action22, :format => :query
31
+ cache_page :action23, :format => ":p1/:p2_and_:p3"
32
+
33
+ def fix_query_string
34
+ params[:id] ||= ''
35
+ p = Merb::Request.query_parse(request.query_string, '&', true)
36
+ p.delete_if {|k,v| [:id,:format].include?(k.to_sym) }
37
+ request.env['QUERY_STRING'] = Merb::Request.params_to_query_string(p)
38
+ end
39
+
40
+ def index; "test index" end
41
+ def action1; render end
42
+ def action2; render end
43
+ def action3; "test action3" end
44
+ def action4; "test action4" end
45
+ def action5; "test action5" end
46
+ def action6; Time.now.to_s end
47
+ def action8; "test action8" end
48
+ def action9; "test action9" end
49
+ def action10; "test action10" end
50
+ def action11; "test action11" end
51
+ def action12; "test action12" end
52
+ def action13; "test action13" end
53
+ def action14; "test action14" end
54
+ def action15; "test action15" end
55
+ def action16; "test action16" end
56
+ def action17; "test action17" end
57
+ def action18; "test action18" end
58
+ def action19; "test action19" end
59
+ def action20; "test action20" end
60
+ def action21; "test action21" end
61
+ def action22; "test action22" end
62
+ def action23; "test action23" end
63
+
64
+ def action7
65
+ provides :js, :css, :html, :xml, :jpg
66
+ case params[:format]
67
+ when "css"
68
+ "CSS"
69
+ when "js"
70
+ "JS"
71
+ when "html"
72
+ "HTML"
73
+ when "xml"
74
+ "XML"
75
+ when "jpg"
76
+ "JPG"
77
+ else
78
+ raise "BAD FORMAT: #{params[:format].inspect}"
79
+ end
80
+ end
81
+
82
+ def empty_id?; params[:id].empty? end
83
+
84
+ def non_empty_id?; !empty_id? end
85
+ end
@@ -0,0 +1,100 @@
1
+ # TODO
2
+ # more specs for fragment caching:
3
+ # cache_get, cache_set, cached?, cache, expire
4
+
5
+ describe "cache_fragment" do
6
+
7
+ it "should render index" do
8
+ c = dispatch_to(CacheController, :index)
9
+ c.body.should == "test index"
10
+ end
11
+
12
+ it "should cache the fragment (erb capture/concat)" do
13
+ c = dispatch_to(CacheController, :action1)
14
+ NOW = c.body.strip
15
+ c.cache_get("key1").strip.should == NOW
16
+ end
17
+
18
+ it "should cache the fragment (haml capture/concat)" do
19
+ c = dispatch_to(CacheController, :action2)
20
+ now = c.body.strip
21
+ c.cache_get("key11").strip.should == now
22
+ sleep 1
23
+ c = dispatch_to(CacheController, :action2)
24
+ c.cache_get("key11").strip.should == now
25
+ c.expire("key11")
26
+ c.cache_get("key11").should be_nil
27
+ end
28
+
29
+ it "should use the fragment" do
30
+ sleep 1
31
+ c = dispatch_to(CacheController, :action1)
32
+ c.body.strip.should == NOW
33
+ end
34
+
35
+ it "should expire the fragment" do
36
+ CACHE.expire("key1")
37
+ CACHE.cache_get("key1").should be_nil
38
+ end
39
+
40
+ it "should refresh the template" do
41
+ c = dispatch_to(CacheController, :action1)
42
+ c.body.strip.should_not == NOW
43
+ end
44
+
45
+ it "should return nil for unknown keys" do
46
+ CACHE.cache_get("unknown_key").should be_nil
47
+ end
48
+
49
+ it "should expire matching keys" do
50
+ CACHE.cache_set("test1", "test1")
51
+ CACHE.cache_get("test1").should == "test1"
52
+ CACHE.cache_set("test2", "test2")
53
+ CACHE.cache_get("test2").should == "test2"
54
+ CACHE.cache_set("test3", "test3")
55
+ CACHE.cache_get("test3").should == "test3"
56
+ CACHE.expire(:match => "test")
57
+ CACHE.cache_get("test1").should be_nil
58
+ CACHE.cache_get("test2").should be_nil
59
+ CACHE.cache_get("test3").should be_nil
60
+ end
61
+
62
+ it "should expire entry after 3 seconds" do
63
+ CACHE.cache_set("timed_key", "vanish in 3 seconds", 0.05)
64
+ CACHE.cache_get("timed_key").should == "vanish in 3 seconds"
65
+ sleep 3.5
66
+ CACHE.cache_get("timed_key").should be_nil
67
+ end
68
+
69
+ it "should expire in many ways" do
70
+ CACHE.cache_set("test1", "test1")
71
+ CACHE.expire("test1")
72
+ CACHE.cache_get("test1").should be_nil
73
+
74
+ CACHE.cache_set("test2/id1", "test2")
75
+ CACHE.expire(:key => "test2", :params => %w(id1))
76
+ CACHE.cache_get("test2/id1").should be_nil
77
+
78
+ CACHE.cache_set("test3", "test3")
79
+ CACHE.expire(:key => "test3")
80
+ CACHE.cache_get("test3").should be_nil
81
+
82
+ CACHE.cache_set("test4/id1", "test4")
83
+ CACHE.expire(:key => "test4", :params => %w(id1), :match => true)
84
+ CACHE.cache_get("test4/id1/id2").should be_nil
85
+ end
86
+
87
+ it "should expire all keys" do
88
+ CACHE.expire_all
89
+ CACHE.cache_get("key1").should be_nil
90
+ end
91
+
92
+ it "should cache/restore ruby objects" do
93
+ now = Time.now
94
+ data = {:key1 => "key1", :key2 => "key2", :now => Time.now }
95
+ CACHE.cache_set("key1", data)
96
+ _data = CACHE.cache_get("key1")
97
+ data.should == _data
98
+ end
99
+
100
+ end