Permalink
Browse files

added logging and more tests

  • Loading branch information...
1 parent ca19327 commit 0d203e47646de6db7018187d2d4130db22fc8de0 @deadlyicon committed Dec 3, 2011
Showing with 101 additions and 54 deletions.
  1. +30 −19 lib/redis/document.rb
  2. +0 −20 lib/redis/document/logger.rb
  3. +50 −13 spec/redis/document_spec.rb
  4. +21 −2 spec/spec_helper.rb
View
@@ -9,27 +9,24 @@
require 'active_model'
-
module Redis::Document
- autoload :Logger, 'redis/document/logger'
-
extend ActiveSupport::Concern
class << self
- def redis= redis
- @redis = redis
+ def redis
+ @redis or self.redis = ::Redis.current and @redis
end
+ attr_writer :redis
- def redis
- @redis or self.redis = ::Redis.new and @redis
+ def logger= logger
+ @logger = logger.respond_to?(:info) ? logger : ActiveSupport::BufferedLogger.new(logger)
end
def logger
- @logger ||= ActiveSupport::BufferedLogger.new(STDOUT)
+ @logger or self.logger = STDOUT and @logger
end
- attr_writer :logger
end
@@ -49,6 +46,7 @@ def redis
end
def keys
+ @keys ||= []
@keys + (superclass.respond_to?(:keys) ? superclass.keys : [])
end
@@ -67,19 +65,22 @@ def #{name}= value
end
def find id
- document = new
- document.instance_variable_set(:@id, id)
- return document.new_record? ? nil : document
+ benchmark(:find, id){
+ document = new
+ document.instance_variable_set(:@id, id)
+ document.new_record? ? nil : document
+ }
end
def all
redis.keys.map{ |id| find id }
end
- def benchmark name
+ def benchmark action, id=nil
+ name = id.nil? ? self.name : "#{self.name}(#{id})"
result = nil
ms = Benchmark.ms { result = yield }
- Redis::Document.logger.info('%s (%.1fms)' % [ name, ms ])
+ Redis::Document.logger.info('%s %s (%.1fms)' % [ name, action, ms ])
result
end
@@ -109,35 +110,45 @@ def write_key key, value
end
def new_record?
- @new_record = _get_.empty? if @new_record.nil?
+ @new_record = !_exists_ if @new_record.nil?
@new_record
end
+ alias_method :exists?, :new_record?
def keys
self.class.keys
end
def inspect
- content = keys.map{|key| "#{key}: #{read_key(key).inspect}"}.join(', ')
- "#<#{self.class} id: #{id}, #{content}>"
+ content = ["id: #{id}"] + keys.map{|key| "#{key}: #{read_key(key).inspect}"}
+ "#<#{self.class} #{content.join(', ')}>"
end
def reload
@cache = nil or cache and self
end
+ def benchmark action, &block
+ self.class.benchmark(action, id, &block)
+ end
+
protected
def cache
@cache ||= _get_.inject({}){ |cache,(field,value)| cache.update field => Marshal.load(value) }
end
def _get_
- self.class.benchmark('GetAll'){ self.class.redis.hgetall(id) }
+ return {} if @new_record == true
+ benchmark(:load){ self.class.redis.hgetall(id) }
end
def _set_ key, value
- self.class.benchmark("Set #{key}"){ self.class.redis.hset(id, key, value) }
+ benchmark("write :#{key}"){ self.class.redis.hset(id, key, value) }
+ end
+
+ def _exists_
+ benchmark(:exists?){ self.class.redis.exists(id) }
end
end
@@ -1,20 +0,0 @@
-require 'active_support/core_ext/benchmark'
-
-class Redis::Document::Logger
-
- def initialize document, redis
- @document, @redis = document, redis
- end
-
- def respond_to?(*args)
- super or @redis.respond_to?(*args)
- end
-
- def method_missing method, *args, &block
- result = nil
- ms = Benchmark.ms { result = @redis.send(method, *args, &block) }
- @document.logger.info('%s (%.1fms)' % [ method, ms ])
- result
- end
-
-end
@@ -2,39 +2,41 @@
describe Redis::Document do
+ before do
+ Redis::Document.instance_variable_set(:@redis, nil)
+ Post.instance_variable_set(:@redis, nil)
+ end
+
describe ".redis" do
subject { Redis::Document.redis }
it { should be_a Redis }
end
describe ".redis=" do
it "should set Redis::Document.redis" do
- thing = stub
- Redis::Document.redis = thing
- Redis::Document.redis.should == thing
+ redis = stub
+ Redis::Document.redis = redis
+ Redis::Document.redis.should == redis
end
end
context "when included into a class" do
- class Post
- include ActiveModel::AttributeMethods
- include Redis::Document
- end
-
subject{ Post.new }
+ alias_method :post, :subject
describe ".redis" do
subject { Post.redis }
- it { should be_a Redis }
+ it { should be_a Redis::Namespace }
end
describe ".redis=" do
it "should set Redis::Document.redis" do
- thing = stub
- Post.redis = thing
- Post.redis.should == thing
+ redis = stub
+ Post.redis = redis
+ Post.redis.should be_a Redis::Namespace
+ Post.redis.instance_variable_get(:@redis).should == redis
end
end
@@ -43,8 +45,43 @@ class Post
it { should be_a Redis }
end
+ describe "#inspect" do
+ subject { Post.new.inspect }
+ it { should be_a String }
+ end
- it "should "
+ describe "#new_record?" do
+ it "should return true if our key exists in redis" do
+ post = Post.new
+ post.new_record?.should be_true
+ post.title = 'My Second Post'
+ post.new_record?.should be_false
+ end
+ end
+
+ it "should store all of its data in a single redis hash" do
+ post.id.should_not be_nil
+ post.new_record?
+ end
+
+ it "should log to Redis::Document.logger" do
+ post = Post.new
+ log_lines.should be_empty
+
+ post.new_record?
+ log_lines.length.should == 1
+ log_lines.first.should include "Post(#{post.id}) exists?"
+
+ empty_log!
+ post.title = "my first post"
+ log_lines.length.should == 1
+ log_lines.first.should include "Post(#{post.id}) write :title"
+
+ empty_log!
+ Post.find(post.id)
+ log_lines.length.should == 2
+ log_lines.last.should include "Post(#{post.id}) find"
+ end
end
View
@@ -1,12 +1,31 @@
require 'redis/document'
+SPEC_ROOT = Pathname.new(File.expand_path('..', __FILE__))
+SPEC_ROOT.join('support').children.each{ |support| require support.to_s }
+
RSpec.configure do |config|
config.color_enabled = true
config.before :each do
- Redis::Document.instance_variables.each{|i| Redis::Document.send :remove_instance_variable, i }
- Redis.new.flushall
+ @log = StringIO.new
+ Redis::Document.logger = @log
+ Redis.current.client.db = 10
+ Redis.current.flushdb
end
+ config.include(Module.new{
+ def log
+ @log.string ||= ""
+ end
+
+ def log_lines
+ log.split("\n")
+ end
+
+ def empty_log!
+ @log.string = ""
+ end
+ })
+
end

0 comments on commit 0d203e4

Please sign in to comment.