Permalink
Browse files

test argument handling and simplify cache keys

  • Loading branch information...
1 parent 9999ca8 commit 94bfb6dafa28c9274f681ef96fc0221bcba7ad1c @seamusabshere committed Feb 22, 2011
Showing with 112 additions and 28 deletions.
  1. +2 −10 lib/cache_method.rb
  2. +8 −3 lib/cache_method/cached_result.rb
  3. +7 −4 lib/cache_method/epoch.rb
  4. +1 −1 lib/cache_method/version.rb
  5. +26 −2 test/helper.rb
  6. +68 −8 test/test_cache_method.rb
View
@@ -20,15 +20,7 @@ def self.method_delimiter(obj) #:nodoc:
def self.method_signature(obj, method_id) #:nodoc:
[ klass_name(obj), method_id ].join method_delimiter(obj)
end
-
- # What gets called to determine the hashcode of an object.
- #
- # * If the object is a Class, then it just does Class.to_s (otherwise Class hash codes change too often)
- # * Otherwise, call #hash
- def self.hashcode(obj)
- obj.is_a?(::Class) ? obj.to_s : obj.hash
- end
-
+
# All Objects, including instances and Classes, get the <tt>#clear_method_cache</tt> method.
module InstanceMethods
# Clear the cache for a particular method.
@@ -65,7 +57,7 @@ def cache_method(method_id, ttl = nil)
original_method_id = "_uncached_#{method_id}"
alias_method original_method_id, method_id
define_method method_id do |*args|
- ::CacheMethod::CachedResult.fetch :obj => self, :method_id => method_id, :original_method_id => original_method_id, :args => args, :ttl => ttl
+ ::CacheMethod::CachedResult.fetch :obj => self, :method_id => method_id, :original_method_id => original_method_id, :ttl => ttl, :args => args
end
end
end
@@ -19,6 +19,7 @@ def initialize(options = {})
attr_reader :original_method_id
attr_reader :args
+ # Store things wrapped in an Array so that nil is accepted
def fetch
if v = Config.instance.storage.get(cache_key) and v.is_a?(::Array)
v[0]
@@ -34,19 +35,23 @@ def ttl
end
def cache_key
- [ 'CacheMethod', 'CachedResult', method_signature, current_epoch, obj_hash, args_digest ].join ','
+ if obj.is_a? ::Class
+ [ 'CacheMethod', 'CachedResult', method_signature, current_epoch, args_digest ].join ','
+ else
+ [ 'CacheMethod', 'CachedResult', method_signature, obj_hash, current_epoch, args_digest ].join ','
+ end
end
def method_signature
@method_signature ||= ::CacheMethod.method_signature(obj, method_id)
end
def obj_hash
- @obj_hash ||= ::CacheMethod.hashcode(obj)
+ @obj_hash ||= obj.hash
end
def args_digest
- @args_digest ||= ::Digest::MD5.hexdigest(args.flatten.join)
+ @args_digest ||= args.empty? ? 'empty' : ::Digest::MD5.hexdigest(args.join)
end
def current_epoch
View
@@ -1,4 +1,3 @@
-require 'digest/md5'
module CacheMethod
class Epoch #:nodoc: all
class << self
@@ -13,7 +12,7 @@ def mark_passing(options = {})
end
def random_name
- ::Digest::MD5.hexdigest rand.to_s
+ rand(1_000_000).to_s
end
end
@@ -31,11 +30,15 @@ def method_signature
end
def obj_hash
- @obj_hash ||= ::CacheMethod.hashcode(obj)
+ @obj_hash ||= obj.hash
end
def cache_key
- [ 'CacheMethod', 'Epoch', method_signature, obj_hash ].join ','
+ if obj.is_a? ::Class
+ [ 'CacheMethod', 'Epoch', method_signature ].join ','
+ else
+ [ 'CacheMethod', 'Epoch', method_signature, obj_hash ].join ','
+ end
end
def current
@@ -1,3 +1,3 @@
module CacheMethod
- VERSION = "0.0.3"
+ VERSION = "0.1.0"
end
View
@@ -19,9 +19,23 @@ def initialize(name)
def echo_count
@echo_count ||= 0
end
+ # http://www.ruby-forum.com/topic/98106
+ # matz: "In 1.9, values (i.e. result of splat) are always represented by array,
+ # so that we won't confuse array as an value with array as values
+ # representation."
def echo(*args)
self.echo_count += 1
- return *args
+ if RUBY_VERSION >= '1.9'
+ if args.empty?
+ return nil
+ elsif args.length == 1
+ return args[0]
+ else
+ return args
+ end
+ else
+ return *args
+ end
end
def hash
name.hash
@@ -37,7 +51,17 @@ def echo_count
end
def echo(*args)
self.echo_count += 1
- return *args
+ if RUBY_VERSION >= '1.9'
+ if args.empty?
+ return nil
+ elsif args.length == 1
+ return args[0]
+ else
+ return args
+ end
+ else
+ return *args
+ end
end
cache_method :echo
end
View
@@ -6,14 +6,39 @@ class TestCacheMethod < Test::Unit::TestCase
def setup
Blog2.request_count = 0
CopyCat2.echo_count = 0
- my_cache = Memcached.new '127.0.0.1:11211'
- CacheMethod.config.storage = my_cache
+ my_cache = Memcached.new '127.0.0.1:11211', :binary => false
my_cache.flush
+ CacheMethod.config.storage = my_cache
end
def test_cache_instance_method_with_args
a = CopyCat1.new 'mimo'
+ assert_equal 'hi', a.echo('hi')
+ assert_equal 1, a.echo_count
+
+ assert_equal 'hi', a.echo('hi')
+ assert_equal 1, a.echo_count
+ end
+
+ def test_cache_instance_method_with_nil_args
+ a = CopyCat1.new 'mimo'
+ assert_equal nil, a.echo
+ assert_equal 1, a.echo_count
+
+ assert_equal nil, a.echo
+ assert_equal 1, a.echo_count
+
+ assert_equal nil, a.echo(nil)
+ assert_equal 2, a.echo_count
+
+ assert_equal nil, a.echo(nil)
+ assert_equal 2, a.echo_count
+ end
+
+ def test_cache_instance_method_with_array_args
+ a = CopyCat1.new 'mimo'
+
assert_equal ['hi'], a.echo(['hi'])
assert_equal 1, a.echo_count
@@ -26,14 +51,43 @@ def test_cache_instance_method_with_args
assert_equal ['bye'], a.echo(['bye'])
assert_equal 2, a.echo_count
- assert_equal nil, a.echo
+ assert_equal ['hi', 'there'], a.echo(['hi', 'there'])
assert_equal 3, a.echo_count
- assert_equal nil, a.echo
+ # same as previous
+ assert_equal ['hi', 'there'], a.echo('hi', 'there')
assert_equal 3, a.echo_count
+
+ assert_equal [], a.echo([])
+ assert_equal 4, a.echo_count
+
+ assert_equal [], a.echo([])
+ assert_equal 4, a.echo_count
end
-
+
def test_cache_class_method_with_args
+ assert_equal 'hi', CopyCat2.echo('hi')
+ assert_equal 1, CopyCat2.echo_count
+
+ assert_equal 'hi', CopyCat2.echo('hi')
+ assert_equal 1, CopyCat2.echo_count
+ end
+
+ def test_cache_class_method_with_nil_args
+ assert_equal nil, CopyCat2.echo
+ assert_equal 1, CopyCat2.echo_count
+
+ assert_equal nil, CopyCat2.echo
+ assert_equal 1, CopyCat2.echo_count
+
+ assert_equal nil, CopyCat2.echo(nil)
+ assert_equal 2, CopyCat2.echo_count
+
+ assert_equal nil, CopyCat2.echo(nil)
+ assert_equal 2, CopyCat2.echo_count
+ end
+
+ def test_cache_class_method_with_array_args
assert_equal ['hi'], CopyCat2.echo(['hi'])
assert_equal 1, CopyCat2.echo_count
@@ -46,13 +100,19 @@ def test_cache_class_method_with_args
assert_equal ['bye'], CopyCat2.echo(['bye'])
assert_equal 2, CopyCat2.echo_count
- assert_equal nil, CopyCat2.echo
+ assert_equal ['hi', 'there'], CopyCat2.echo(['hi', 'there'])
assert_equal 3, CopyCat2.echo_count
- assert_equal nil, CopyCat2.echo
+ assert_equal ['hi', 'there'], CopyCat2.echo('hi', 'there')
assert_equal 3, CopyCat2.echo_count
+
+ assert_equal [], CopyCat2.echo([])
+ assert_equal 4, CopyCat2.echo_count
+
+ assert_equal [], CopyCat2.echo([])
+ assert_equal 4, CopyCat2.echo_count
end
-
+
def test_cache_instance_method
a = new_instance_of_my_blog
assert_equal ["hello from #{a.name}"], a.get_latest_entries

0 comments on commit 94bfb6d

Please sign in to comment.