Skip to content

Commit

Permalink
Finalizing removal of Hash inheritance
Browse files Browse the repository at this point in the history
  • Loading branch information
samlown committed Jun 8, 2011
1 parent 74f24bd commit 145233b
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 20 deletions.
2 changes: 1 addition & 1 deletion history.txt
Expand Up @@ -2,7 +2,7 @@

* Major changes
* CouchRest::Response removed
* CouchRest::Document now delegates to Hash (instead of inherits)
* CouchRest::Document now forwards key Hash methods (instead of inheritance)
* Support multiple JSON gems with multi_json

== 1.1.0.pre2 - 2011-04-08
Expand Down
2 changes: 1 addition & 1 deletion lib/couchrest.rb
Expand Up @@ -25,7 +25,7 @@
require 'couchrest/support/inheritable_attributes'
require 'couchrest/version'

require 'delegate'
require 'forwardable'

# = CouchDB, close to the metal
module CouchRest
Expand Down
21 changes: 11 additions & 10 deletions lib/couchrest/design.rb
@@ -1,16 +1,17 @@
module CouchRest
class Design < Document

def view_by *keys
opts = keys.pop if keys.last.is_a?(Hash)
opts ||= {}
self[:views] ||= {}
self['views'] ||= {}
method_name = "by_#{keys.join('_and_')}"

if opts[:map]
view = {}
view['map'] = opts.delete(:map)
view['reduce'] = opts.delete(:reduce) if opts[:reduce]
self[:views][method_name] = view
self['views'][method_name] = view
else
doc_keys = keys.collect{|k| "doc['#{k}']"}
key_emit = doc_keys.length == 1 ? "#{doc_keys.first}" : "[#{doc_keys.join(', ')}]"
Expand All @@ -24,14 +25,14 @@ def view_by *keys
}
}
JAVASCRIPT
self[:views][method_name] = {
self['views'][method_name] = {
'map' => map_function
}
end
self[:views][method_name]['couchrest-defaults'] = opts unless opts.empty?
self['views'][method_name]['couchrest-defaults'] = opts unless opts.empty?
method_name
end

# Dispatches to any named view.
# (using the database where this design doc was saved)
def view view_name, query={}, &block
Expand All @@ -56,7 +57,7 @@ def name
end

def name= newname
self[:_id] = "_design/#{newname}"
self['_id'] = "_design/#{newname}"
end

def save
Expand All @@ -67,17 +68,17 @@ def save
# Return the hash of default values to include in all queries sent
# to a view from couchrest.
def view_defaults(name)
(self[:views][name.to_s] && self[:views][name.to_s]["couchrest-defaults"]) || {}
(self['views'][name.to_s] && self['views'][name.to_s]["couchrest-defaults"]) || {}
end

# Returns true or false if the view is available.
def has_view?(name)
!self[:views][name.to_s].nil?
!self['views'][name.to_s].nil?
end

# Check if the view has a reduce method defined.
def can_reduce_view?(name)
has_view?(name) && !self[:views][name.to_s]['reduce'].to_s.empty?
has_view?(name) && !self['views'][name.to_s]['reduce'].to_s.empty?
end

private
Expand Down
37 changes: 32 additions & 5 deletions lib/couchrest/document.rb
Expand Up @@ -16,30 +16,57 @@
#

module CouchRest
class Document < DelegateClass(Hash)
class Document
extend Forwardable
include CouchRest::Attachments
extend CouchRest::InheritableAttributes

couchrest_inheritable_accessor :database
attr_accessor :database

# Initialize a new CouchRest Document and prepare
# a hidden attributes hash.
#
# When inherting a Document, it is essential that the
# super method is called before you own changes to ensure
# that the attributes hash has been initialized before
# you attempt to use it.
def initialize(attrs = nil)
@_attributes = {}
attrs.each{|k,v| self[k] = v} unless attrs.nil?
super(@_attributes)
end

# Hash equivilent methods to access the attributes

def_delegators :@_attributes, :to_a, :==, :eql?, :keys, :values, :each,
:reject, :reject!, :empty?, :clear, :merge, :merge!,
:as_json, :to_json

def []=(key, value)
@_attributes[key.to_s] = value
end
def store(key, value)
@_attributes[key.to_s] = value
end
def [](key)
@_attributes[key.to_s]
end
def has_key?(key)
@_attributes.has_key?(key.to_s)
end
def delete(key)
@_attributes.delete(key.to_s)
end
def dup
new = super
@_attributes = @_attributes.dup
new
end
def clone
new = super
@_attributes = @_attributes.dup
new
end
def to_hash
@_attributes
end

def id
self['_id']
Expand Down
42 changes: 39 additions & 3 deletions spec/couchrest/document_spec.rb
Expand Up @@ -17,9 +17,24 @@ class Video < CouchRest::Document; end
end

it "should be possible to initialize a new Document with attributes" do
@rsp = CouchRest::Document.new('foo' => 'bar', :test => 'foo')
@rsp['foo'].should eql('bar')
@rsp['test'].should eql('foo')
@doc = CouchRest::Document.new('foo' => 'bar', :test => 'foo')
@doc['foo'].should eql('bar')
@doc['test'].should eql('foo')
end

it "should accept new with _id" do
@doc = CouchRest::Document.new('_id' => 'sample', 'foo' => 'bar')
@doc['_id'].should eql('sample')
@doc['foo'].should eql('bar')
end
end

describe "hash methods" do
it "should respond to forwarded hash methods" do
@doc = CouchRest::Document.new(:foo => 'bar')
[:to_a, :==, :eql?, :keys, :values, :each, :reject, :reject!, :empty?, :clear, :merge, :merge!, :as_json, :to_json].each do |call|
@doc.should respond_to(call)
end
end
end

Expand Down Expand Up @@ -58,6 +73,27 @@ class Video < CouchRest::Document; end
end
end

describe "#dup" do
it "should also clone the attributes" do
@doc = CouchRest::Document.new('foo' => 'bar')
@doc2 = @doc.dup
@doc2.delete('foo')
@doc2['foo'].should be_nil
@doc['foo'].should eql('bar')
end
end

describe "#clone" do
it "should also clone the attributes" do
@doc = CouchRest::Document.new('foo' => 'bar')
@doc2 = @doc.clone
@doc2.delete('foo')
@doc2['foo'].should be_nil
@doc['foo'].should eql('bar')
end
end


describe "#inspect" do
it "should provide a string of keys and values of the Response" do
@doc = CouchRest::Document.new('foo' => 'bar')
Expand Down

0 comments on commit 145233b

Please sign in to comment.