bchiu-merb_cache_more 0.9.4

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,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