<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>spec/couchrest/more/extended_doc_attachment_spec.rb</filename>
    </added>
    <added>
      <filename>spec/couchrest/more/extended_doc_view_spec.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -59,13 +59,7 @@ Creating and Querying Views:
 
 ## CouchRest::Model
 
-CouchRest::Model is a module designed along the lines of DataMapper::Resource.
-By subclassing, suddenly you get all sorts of powerful sugar, so that working
-with CouchDB in your Rails or Merb app is no harder than working with the
-standard SQL alternatives. See the CouchRest::Model documentation for an
-example article class that illustrates usage.
-
-CouchRest::Model will be removed from this package.
+CouchRest::Model has been deprecated and replaced by CouchRest::ExtendedDocument
 
 
 ## CouchRest::ExtendedDocument</diff>
      <filename>README.md</filename>
    </modified>
    <modified>
      <diff>@@ -2,7 +2,7 @@
 
 Gem::Specification.new do |s|
   s.name = %q{couchrest}
-  s.version = &quot;0.14.2&quot;
+  s.version = &quot;0.15&quot;
 
   s.required_rubygems_version = Gem::Requirement.new(&quot;&gt;= 0&quot;) if s.respond_to? :required_rubygems_version=
   s.authors = [&quot;J. Chris Anderson&quot;, &quot;Matt Aimonetti&quot;]
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
   s.description = %q{CouchRest provides a simple interface on top of CouchDB's RESTful HTTP API, as well as including some utility scripts for managing views and attachments.}
   s.email = %q{jchris@apache.org}
   s.extra_rdoc_files = [&quot;README.md&quot;, &quot;LICENSE&quot;, &quot;THANKS.md&quot;]
-  s.files = [&quot;LICENSE&quot;, &quot;README.md&quot;, &quot;Rakefile&quot;, &quot;THANKS.md&quot;, &quot;examples/model&quot;, &quot;examples/model/example.rb&quot;, &quot;examples/word_count&quot;, &quot;examples/word_count/markov&quot;, &quot;examples/word_count/views&quot;, &quot;examples/word_count/views/books&quot;, &quot;examples/word_count/views/books/chunked-map.js&quot;, &quot;examples/word_count/views/books/united-map.js&quot;, &quot;examples/word_count/views/markov&quot;, &quot;examples/word_count/views/markov/chain-map.js&quot;, &quot;examples/word_count/views/markov/chain-reduce.js&quot;, &quot;examples/word_count/views/word_count&quot;, &quot;examples/word_count/views/word_count/count-map.js&quot;, &quot;examples/word_count/views/word_count/count-reduce.js&quot;, &quot;examples/word_count/word_count.rb&quot;, &quot;examples/word_count/word_count_query.rb&quot;, &quot;examples/word_count/word_count_views.rb&quot;, &quot;lib/couchrest&quot;, &quot;lib/couchrest/commands&quot;, &quot;lib/couchrest/commands/generate.rb&quot;, &quot;lib/couchrest/commands/push.rb&quot;, &quot;lib/couchrest/core&quot;, &quot;lib/couchrest/core/database.rb&quot;, &quot;lib/couchrest/core/design.rb&quot;, &quot;lib/couchrest/core/document.rb&quot;, &quot;lib/couchrest/core/model.rb&quot;, &quot;lib/couchrest/core/response.rb&quot;, &quot;lib/couchrest/core/server.rb&quot;, &quot;lib/couchrest/core/view.rb&quot;, &quot;lib/couchrest/helper&quot;, &quot;lib/couchrest/helper/pager.rb&quot;, &quot;lib/couchrest/helper/streamer.rb&quot;, &quot;lib/couchrest/mixins&quot;, &quot;lib/couchrest/mixins/attachments.rb&quot;, &quot;lib/couchrest/mixins/callbacks.rb&quot;, &quot;lib/couchrest/mixins/design_doc.rb&quot;, &quot;lib/couchrest/mixins/document_queries.rb&quot;, &quot;lib/couchrest/mixins/extended_attachments.rb&quot;, &quot;lib/couchrest/mixins/extended_document_mixins.rb&quot;, &quot;lib/couchrest/mixins/properties.rb&quot;, &quot;lib/couchrest/mixins/validation.rb&quot;, &quot;lib/couchrest/mixins/views.rb&quot;, &quot;lib/couchrest/mixins.rb&quot;, &quot;lib/couchrest/monkeypatches.rb&quot;, &quot;lib/couchrest/more&quot;, &quot;lib/couchrest/more/casted_model.rb&quot;, &quot;lib/couchrest/more/extended_document.rb&quot;, &quot;lib/couchrest/more/property.rb&quot;, &quot;lib/couchrest/support&quot;, &quot;lib/couchrest/support/blank.rb&quot;, &quot;lib/couchrest/support/class.rb&quot;, &quot;lib/couchrest/validation&quot;, &quot;lib/couchrest/validation/auto_validate.rb&quot;, &quot;lib/couchrest/validation/contextual_validators.rb&quot;, &quot;lib/couchrest/validation/validation_errors.rb&quot;, &quot;lib/couchrest/validation/validators&quot;, &quot;lib/couchrest/validation/validators/absent_field_validator.rb&quot;, &quot;lib/couchrest/validation/validators/confirmation_validator.rb&quot;, &quot;lib/couchrest/validation/validators/format_validator.rb&quot;, &quot;lib/couchrest/validation/validators/formats&quot;, &quot;lib/couchrest/validation/validators/formats/email.rb&quot;, &quot;lib/couchrest/validation/validators/formats/url.rb&quot;, &quot;lib/couchrest/validation/validators/generic_validator.rb&quot;, &quot;lib/couchrest/validation/validators/length_validator.rb&quot;, &quot;lib/couchrest/validation/validators/method_validator.rb&quot;, &quot;lib/couchrest/validation/validators/numeric_validator.rb&quot;, &quot;lib/couchrest/validation/validators/required_field_validator.rb&quot;, &quot;lib/couchrest.rb&quot;, &quot;spec/couchrest&quot;, &quot;spec/couchrest/core&quot;, &quot;spec/couchrest/core/couchrest_spec.rb&quot;, &quot;spec/couchrest/core/database_spec.rb&quot;, &quot;spec/couchrest/core/design_spec.rb&quot;, &quot;spec/couchrest/core/document_spec.rb&quot;, &quot;spec/couchrest/core/model_spec.rb&quot;, &quot;spec/couchrest/core/server_spec.rb&quot;, &quot;spec/couchrest/helpers&quot;, &quot;spec/couchrest/helpers/pager_spec.rb&quot;, &quot;spec/couchrest/helpers/streamer_spec.rb&quot;, &quot;spec/couchrest/more&quot;, &quot;spec/couchrest/more/casted_model_spec.rb&quot;, &quot;spec/couchrest/more/extended_doc_spec.rb&quot;, &quot;spec/couchrest/more/property_spec.rb&quot;, &quot;spec/fixtures&quot;, &quot;spec/fixtures/attachments&quot;, &quot;spec/fixtures/attachments/couchdb.png&quot;, &quot;spec/fixtures/attachments/README&quot;, &quot;spec/fixtures/attachments/test.html&quot;, &quot;spec/fixtures/couchapp&quot;, &quot;spec/fixtures/couchapp/_attachments&quot;, &quot;spec/fixtures/couchapp/_attachments/index.html&quot;, &quot;spec/fixtures/couchapp/doc.json&quot;, &quot;spec/fixtures/couchapp/foo&quot;, &quot;spec/fixtures/couchapp/foo/bar.txt&quot;, &quot;spec/fixtures/couchapp/foo/test.json&quot;, &quot;spec/fixtures/couchapp/test.json&quot;, &quot;spec/fixtures/couchapp/views&quot;, &quot;spec/fixtures/couchapp/views/example-map.js&quot;, &quot;spec/fixtures/couchapp/views/example-reduce.js&quot;, &quot;spec/fixtures/couchapp-test&quot;, &quot;spec/fixtures/couchapp-test/my-app&quot;, &quot;spec/fixtures/couchapp-test/my-app/_attachments&quot;, &quot;spec/fixtures/couchapp-test/my-app/_attachments/index.html&quot;, &quot;spec/fixtures/couchapp-test/my-app/foo&quot;, &quot;spec/fixtures/couchapp-test/my-app/foo/bar.txt&quot;, &quot;spec/fixtures/couchapp-test/my-app/views&quot;, &quot;spec/fixtures/couchapp-test/my-app/views/example-map.js&quot;, &quot;spec/fixtures/couchapp-test/my-app/views/example-reduce.js&quot;, &quot;spec/fixtures/more&quot;, &quot;spec/fixtures/more/card.rb&quot;, &quot;spec/fixtures/more/invoice.rb&quot;, &quot;spec/fixtures/more/service.rb&quot;, &quot;spec/fixtures/views&quot;, &quot;spec/fixtures/views/lib.js&quot;, &quot;spec/fixtures/views/test_view&quot;, &quot;spec/fixtures/views/test_view/lib.js&quot;, &quot;spec/fixtures/views/test_view/only-map.js&quot;, &quot;spec/fixtures/views/test_view/test-map.js&quot;, &quot;spec/fixtures/views/test_view/test-reduce.js&quot;, &quot;spec/spec.opts&quot;, &quot;spec/spec_helper.rb&quot;, &quot;utils/remap.rb&quot;, &quot;utils/subset.rb&quot;]
+  s.files = [&quot;LICENSE&quot;, &quot;README.md&quot;, &quot;Rakefile&quot;, &quot;THANKS.md&quot;, &quot;examples/model&quot;, &quot;examples/model/example.rb&quot;, &quot;examples/word_count&quot;, &quot;examples/word_count/markov&quot;, &quot;examples/word_count/views&quot;, &quot;examples/word_count/views/books&quot;, &quot;examples/word_count/views/books/chunked-map.js&quot;, &quot;examples/word_count/views/books/united-map.js&quot;, &quot;examples/word_count/views/markov&quot;, &quot;examples/word_count/views/markov/chain-map.js&quot;, &quot;examples/word_count/views/markov/chain-reduce.js&quot;, &quot;examples/word_count/views/word_count&quot;, &quot;examples/word_count/views/word_count/count-map.js&quot;, &quot;examples/word_count/views/word_count/count-reduce.js&quot;, &quot;examples/word_count/word_count.rb&quot;, &quot;examples/word_count/word_count_query.rb&quot;, &quot;examples/word_count/word_count_views.rb&quot;, &quot;lib/couchrest&quot;, &quot;lib/couchrest/commands&quot;, &quot;lib/couchrest/commands/generate.rb&quot;, &quot;lib/couchrest/commands/push.rb&quot;, &quot;lib/couchrest/core&quot;, &quot;lib/couchrest/core/database.rb&quot;, &quot;lib/couchrest/core/design.rb&quot;, &quot;lib/couchrest/core/document.rb&quot;, &quot;lib/couchrest/core/response.rb&quot;, &quot;lib/couchrest/core/server.rb&quot;, &quot;lib/couchrest/core/view.rb&quot;, &quot;lib/couchrest/helper&quot;, &quot;lib/couchrest/helper/pager.rb&quot;, &quot;lib/couchrest/helper/streamer.rb&quot;, &quot;lib/couchrest/mixins&quot;, &quot;lib/couchrest/mixins/attachments.rb&quot;, &quot;lib/couchrest/mixins/callbacks.rb&quot;, &quot;lib/couchrest/mixins/design_doc.rb&quot;, &quot;lib/couchrest/mixins/document_queries.rb&quot;, &quot;lib/couchrest/mixins/extended_attachments.rb&quot;, &quot;lib/couchrest/mixins/extended_document_mixins.rb&quot;, &quot;lib/couchrest/mixins/properties.rb&quot;, &quot;lib/couchrest/mixins/validation.rb&quot;, &quot;lib/couchrest/mixins/views.rb&quot;, &quot;lib/couchrest/mixins.rb&quot;, &quot;lib/couchrest/monkeypatches.rb&quot;, &quot;lib/couchrest/more&quot;, &quot;lib/couchrest/more/casted_model.rb&quot;, &quot;lib/couchrest/more/extended_document.rb&quot;, &quot;lib/couchrest/more/property.rb&quot;, &quot;lib/couchrest/support&quot;, &quot;lib/couchrest/support/blank.rb&quot;, &quot;lib/couchrest/support/class.rb&quot;, &quot;lib/couchrest/validation&quot;, &quot;lib/couchrest/validation/auto_validate.rb&quot;, &quot;lib/couchrest/validation/contextual_validators.rb&quot;, &quot;lib/couchrest/validation/validation_errors.rb&quot;, &quot;lib/couchrest/validation/validators&quot;, &quot;lib/couchrest/validation/validators/absent_field_validator.rb&quot;, &quot;lib/couchrest/validation/validators/confirmation_validator.rb&quot;, &quot;lib/couchrest/validation/validators/format_validator.rb&quot;, &quot;lib/couchrest/validation/validators/formats&quot;, &quot;lib/couchrest/validation/validators/formats/email.rb&quot;, &quot;lib/couchrest/validation/validators/formats/url.rb&quot;, &quot;lib/couchrest/validation/validators/generic_validator.rb&quot;, &quot;lib/couchrest/validation/validators/length_validator.rb&quot;, &quot;lib/couchrest/validation/validators/method_validator.rb&quot;, &quot;lib/couchrest/validation/validators/numeric_validator.rb&quot;, &quot;lib/couchrest/validation/validators/required_field_validator.rb&quot;, &quot;lib/couchrest.rb&quot;, &quot;spec/couchrest&quot;, &quot;spec/couchrest/core&quot;, &quot;spec/couchrest/core/couchrest_spec.rb&quot;, &quot;spec/couchrest/core/database_spec.rb&quot;, &quot;spec/couchrest/core/design_spec.rb&quot;, &quot;spec/couchrest/core/document_spec.rb&quot;, &quot;spec/couchrest/core/server_spec.rb&quot;, &quot;spec/couchrest/helpers&quot;, &quot;spec/couchrest/helpers/pager_spec.rb&quot;, &quot;spec/couchrest/helpers/streamer_spec.rb&quot;, &quot;spec/couchrest/more&quot;, &quot;spec/couchrest/more/casted_model_spec.rb&quot;, &quot;spec/couchrest/more/extended_doc_attachment_spec.rb&quot;, &quot;spec/couchrest/more/extended_doc_spec.rb&quot;, &quot;spec/couchrest/more/extended_doc_view_spec.rb&quot;, &quot;spec/couchrest/more/property_spec.rb&quot;, &quot;spec/fixtures&quot;, &quot;spec/fixtures/attachments&quot;, &quot;spec/fixtures/attachments/couchdb.png&quot;, &quot;spec/fixtures/attachments/README&quot;, &quot;spec/fixtures/attachments/test.html&quot;, &quot;spec/fixtures/couchapp&quot;, &quot;spec/fixtures/couchapp/_attachments&quot;, &quot;spec/fixtures/couchapp/_attachments/index.html&quot;, &quot;spec/fixtures/couchapp/doc.json&quot;, &quot;spec/fixtures/couchapp/foo&quot;, &quot;spec/fixtures/couchapp/foo/bar.txt&quot;, &quot;spec/fixtures/couchapp/foo/test.json&quot;, &quot;spec/fixtures/couchapp/test.json&quot;, &quot;spec/fixtures/couchapp/views&quot;, &quot;spec/fixtures/couchapp/views/example-map.js&quot;, &quot;spec/fixtures/couchapp/views/example-reduce.js&quot;, &quot;spec/fixtures/couchapp-test&quot;, &quot;spec/fixtures/couchapp-test/my-app&quot;, &quot;spec/fixtures/couchapp-test/my-app/_attachments&quot;, &quot;spec/fixtures/couchapp-test/my-app/_attachments/index.html&quot;, &quot;spec/fixtures/couchapp-test/my-app/foo&quot;, &quot;spec/fixtures/couchapp-test/my-app/foo/bar.txt&quot;, &quot;spec/fixtures/couchapp-test/my-app/views&quot;, &quot;spec/fixtures/couchapp-test/my-app/views/example-map.js&quot;, &quot;spec/fixtures/couchapp-test/my-app/views/example-reduce.js&quot;, &quot;spec/fixtures/more&quot;, &quot;spec/fixtures/more/article.rb&quot;, &quot;spec/fixtures/more/card.rb&quot;, &quot;spec/fixtures/more/course.rb&quot;, &quot;spec/fixtures/more/event.rb&quot;, &quot;spec/fixtures/more/invoice.rb&quot;, &quot;spec/fixtures/more/person.rb&quot;, &quot;spec/fixtures/more/question.rb&quot;, &quot;spec/fixtures/more/service.rb&quot;, &quot;spec/fixtures/views&quot;, &quot;spec/fixtures/views/lib.js&quot;, &quot;spec/fixtures/views/test_view&quot;, &quot;spec/fixtures/views/test_view/lib.js&quot;, &quot;spec/fixtures/views/test_view/only-map.js&quot;, &quot;spec/fixtures/views/test_view/test-map.js&quot;, &quot;spec/fixtures/views/test_view/test-reduce.js&quot;, &quot;spec/spec.opts&quot;, &quot;spec/spec_helper.rb&quot;, &quot;utils/remap.rb&quot;, &quot;utils/subset.rb&quot;]
   s.has_rdoc = true
   s.homepage = %q{http://github.com/jchris/couchrest}
   s.require_paths = [&quot;lib&quot;]</diff>
      <filename>couchrest.gemspec</filename>
    </modified>
    <modified>
      <diff>@@ -1,31 +1,38 @@
-require 'rubygems'
-require 'couchrest'
+require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'couchrest')
 
 def show obj
   puts obj.inspect
   puts
 end
 
-CouchRest::Model.default_database = CouchRest.database!('couchrest-model-example')
+SERVER = CouchRest.new
+SERVER.default_database = 'couchrest-extendeddoc-example'
 
-class Author &lt; CouchRest::Model
-  key_accessor :name
+class Author &lt; CouchRest::ExtendedDocument
+  use_database SERVER.default_database
+  property :name
+  
   def drink_scotch
     puts &quot;... glug type glug ... I'm #{name} ... type glug glug ...&quot;
   end
 end
 
-class Post &lt; CouchRest::Model
-  key_accessor :title, :body, :author
-
-  cast :author, :as =&gt; 'Author'
+class Post &lt; CouchRest::ExtendedDocument
+  use_database SERVER.default_database
+  
+  property :title
+  property :body
+  property :author, :cast_as =&gt; 'Author'
 
   timestamps!
 end
 
-class Comment &lt; CouchRest::Model
-  cast :commenter, :as =&gt; 'Author'
-
+class Comment &lt; CouchRest::ExtendedDocument
+  use_database SERVER.default_database
+  
+  property :commenter, :cast_as =&gt; 'Author'
+  timestamps!
+  
   def post= post
     self[&quot;post_id&quot;] = post.id
   end
@@ -33,7 +40,6 @@ class Comment &lt; CouchRest::Model
     Post.get(self['post_id']) if self['post_id']
   end
   
-  timestamps!
 end
 
 puts &quot;Act I: CRUD&quot;</diff>
      <filename>examples/model/example.rb</filename>
    </modified>
    <modified>
      <diff>@@ -27,7 +27,7 @@ require 'couchrest/monkeypatches'
 
 # = CouchDB, close to the metal
 module CouchRest
-  VERSION = '0.14.2'
+  VERSION = '0.15'
   
   autoload :Server,       'couchrest/core/server'
   autoload :Database,     'couchrest/core/database'</diff>
      <filename>lib/couchrest.rb</filename>
    </modified>
    <modified>
      <diff>@@ -279,7 +279,7 @@ module CouchRest
 
     private
     
-    def uri_for_attachment doc, name
+    def uri_for_attachment(doc, name)
       if doc.is_a?(String)
         puts &quot;CouchRest::Database#fetch_attachment will eventually require a doc as the first argument, not a doc.id&quot;
         docid = doc</diff>
      <filename>lib/couchrest/core/database.rb</filename>
    </modified>
    <modified>
      <diff>@@ -31,6 +31,7 @@ module CouchRest
     
     def initialize(keys={})
       apply_defaults # defined in CouchRest::Mixins::Properties
+      keys ||= {}
       super
       cast_keys      # defined in CouchRest::Mixins::Properties
       unless self['_id'] &amp;&amp; self['_rev']
@@ -100,7 +101,7 @@ module CouchRest
     # missing. In case of error, no attributes are changed.    
     def update_attributes_without_saving(hash)
       hash.each do |k, v|
-        raise NoMethodError, &quot;#{k}= method not available, use key_accessor or key_writer :#{k}&quot; unless self.respond_to?(&quot;#{k}=&quot;)
+        raise NoMethodError, &quot;#{k}= method not available, use property :#{k}&quot; unless self.respond_to?(&quot;#{k}=&quot;)
       end      
       hash.each do |k, v|
         self.send(&quot;#{k}=&quot;,v)</diff>
      <filename>lib/couchrest/more/extended_document.rb</filename>
    </modified>
    <modified>
      <diff>@@ -18,6 +18,8 @@ module CouchRest
       def parse_type(type)
         if type.nil?
           @type = 'String'
+        elsif type.is_a?(Array) &amp;&amp; type.empty?
+          @type = 'Array'
         else
           @type = type.is_a?(Array) ? [type.first.to_s] : type.to_s
         end</diff>
      <filename>lib/couchrest/more/property.rb</filename>
    </modified>
    <modified>
      <diff>@@ -704,7 +704,7 @@ describe CouchRest::Database do
   describe &quot;creating a database&quot; do
     before(:each) do
       @db = @cr.database('couchrest-test-db_to_create')
-      @db.delete!
+      @db.delete! if @cr.databases.include?('couchrest-test-db_to_create')
     end
     
     it &quot;should just work fine&quot; do</diff>
      <filename>spec/couchrest/core/database_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,7 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
+require File.join(FIXTURE_PATH, 'more', 'article')
+require File.join(FIXTURE_PATH, 'more', 'course')
+
 
 describe &quot;ExtendedDocument&quot; do
   
@@ -41,10 +44,86 @@ describe &quot;ExtendedDocument&quot; do
     end
   end
   
+  class WithTemplateAndUniqueID &lt; CouchRest::ExtendedDocument
+    use_database TEST_SERVER.default_database
+    unique_id do |model|
+      model['important-field']
+    end
+    property :preset, :default =&gt; 'value'
+    property :has_no_default
+  end
+  
   before(:each) do
     @obj = WithDefaultValues.new
   end
   
+  describe &quot;instance database connection&quot; do
+    it &quot;should use the default database&quot; do
+      @obj.database.name.should == 'couchrest-test'
+    end
+    
+    it &quot;should override the default db&quot; do
+      @obj.database = TEST_SERVER.database!('couchrest-extendedmodel-test')
+      @obj.database.name.should == 'couchrest-extendedmodel-test'
+      @obj.database.delete!
+    end
+  end
+  
+  describe &quot;a new model&quot; do
+    it &quot;should be a new_record&quot; do
+      @obj = Basic.new
+      @obj.rev.should be_nil
+      @obj.should be_a_new_record
+    end
+    it &quot;should be a new_document&quot; do
+      @obj = Basic.new
+      @obj.rev.should be_nil
+      @obj.should be_a_new_document
+    end
+  end
+  
+  describe &quot;update attributes without saving&quot; do
+    before(:each) do
+      a = Article.get &quot;big-bad-danger&quot; rescue nil
+      a.destroy if a
+      @art = Article.new(:title =&gt; &quot;big bad danger&quot;)
+      @art.save
+    end
+    it &quot;should work for attribute= methods&quot; do
+      @art['title'].should == &quot;big bad danger&quot;
+      @art.update_attributes_without_saving('date' =&gt; Time.now, :title =&gt; &quot;super danger&quot;)
+      @art['title'].should == &quot;super danger&quot;
+    end
+    
+    it &quot;should flip out if an attribute= method is missing&quot; do
+      lambda {
+        @art.update_attributes_without_saving('slug' =&gt; &quot;new-slug&quot;, :title =&gt; &quot;super danger&quot;)        
+      }.should raise_error
+    end
+    
+    it &quot;should not change other attributes if there is an error&quot; do
+      lambda {
+        @art.update_attributes_without_saving('slug' =&gt; &quot;new-slug&quot;, :title =&gt; &quot;super danger&quot;)        
+      }.should raise_error
+      @art['title'].should == &quot;big bad danger&quot;
+    end
+  end
+  
+  describe &quot;update attributes&quot; do
+    before(:each) do
+      a = Article.get &quot;big-bad-danger&quot; rescue nil
+      a.destroy if a
+      @art = Article.new(:title =&gt; &quot;big bad danger&quot;)
+      @art.save
+    end
+    it &quot;should save&quot; do
+      @art['title'].should == &quot;big bad danger&quot;
+      @art.update_attributes('date' =&gt; Time.now, :title =&gt; &quot;super danger&quot;)
+      loaded = Article.get(@art.id)
+      loaded['title'].should == &quot;super danger&quot;
+    end
+  end
+  
   describe &quot;with default&quot; do
     it &quot;should have the default value set at initalization&quot; do
       @obj.preset.should == {:right =&gt; 10, :top_align =&gt; false}
@@ -67,7 +146,137 @@ describe &quot;ExtendedDocument&quot; do
     end
   end
   
+  describe &quot;a doc with template values (CR::Model spec)&quot; do
+    before(:all) do
+      WithTemplateAndUniqueID.all.map{|o| o.destroy(true)}
+      WithTemplateAndUniqueID.database.bulk_delete
+      @tmpl = WithTemplateAndUniqueID.new
+      @tmpl2 = WithTemplateAndUniqueID.new(:preset =&gt; 'not_value', 'important-field' =&gt; '1')
+    end
+    it &quot;should have fields set when new&quot; do
+      @tmpl.preset.should == 'value'
+    end
+    it &quot;shouldn't override explicitly set values&quot; do
+      @tmpl2.preset.should == 'not_value'
+    end
+    it &quot;shouldn't override existing documents&quot; do
+      @tmpl2.save
+      tmpl2_reloaded = WithTemplateAndUniqueID.get(@tmpl2.id)
+      @tmpl2.preset.should == 'not_value'
+      tmpl2_reloaded.preset.should == 'not_value'
+    end
+  end
+  
+  describe &quot;getting a model&quot; do
+    before(:all) do
+      @art = Article.new(:title =&gt; 'All About Getting')
+      @art.save
+    end
+    it &quot;should load and instantiate it&quot; do
+      foundart = Article.get @art.id
+      foundart.title.should == &quot;All About Getting&quot;
+    end
+  end
+
+  describe &quot;getting a model with a subobjects array&quot; do
+    before(:all) do
+      course_doc = {
+        &quot;title&quot; =&gt; &quot;Metaphysics 200&quot;,
+        &quot;questions&quot; =&gt; [
+          {
+            &quot;q&quot; =&gt; &quot;Carve the ___ of reality at the ___.&quot;,
+            &quot;a&quot; =&gt; [&quot;beast&quot;,&quot;joints&quot;]
+          },{
+            &quot;q&quot; =&gt; &quot;Who layed the smack down on Leibniz's Law?&quot;,
+            &quot;a&quot; =&gt; &quot;Willard Van Orman Quine&quot;
+          }
+        ]
+      }
+      r = Course.database.save_doc course_doc
+      @course = Course.get r['id']
+    end
+    it &quot;should load the course&quot; do
+      @course.title.should == &quot;Metaphysics 200&quot;
+    end
+    it &quot;should instantiate them as such&quot; do
+      @course[&quot;questions&quot;][0].a[0].should == &quot;beast&quot;
+    end
+  end
+  
+  describe &quot;finding all instances of a model&quot; do
+    before(:all) do
+      WithTemplateAndUniqueID.all.map{|o| o.destroy(true)}
+      WithTemplateAndUniqueID.database.bulk_delete
+      WithTemplateAndUniqueID.new('important-field' =&gt; '1').save
+      WithTemplateAndUniqueID.new('important-field' =&gt; '2').save
+      WithTemplateAndUniqueID.new('important-field' =&gt; '3').save
+      WithTemplateAndUniqueID.new('important-field' =&gt; '4').save
+    end
+    it &quot;should make the design doc&quot; do
+      WithTemplateAndUniqueID.all
+      d = WithTemplateAndUniqueID.design_doc
+      d['views']['all']['map'].should include('WithTemplateAndUniqueID')
+    end
+    it &quot;should find all&quot; do
+      rs = WithTemplateAndUniqueID.all 
+      rs.length.should == 4
+    end
+  end
+
+  describe &quot;finding the first instance of a model&quot; do
+    before(:each) do      
+      @db = reset_test_db!
+      WithTemplateAndUniqueID.new('important-field' =&gt; '1').save
+      WithTemplateAndUniqueID.new('important-field' =&gt; '2').save
+      WithTemplateAndUniqueID.new('important-field' =&gt; '3').save
+      WithTemplateAndUniqueID.new('important-field' =&gt; '4').save
+    end
+    it &quot;should make the design doc&quot; do
+      WithTemplateAndUniqueID.all
+      d = WithTemplateAndUniqueID.design_doc
+      d['views']['all']['map'].should include('WithTemplateAndUniqueID')
+    end
+    it &quot;should find first&quot; do
+      rs = WithTemplateAndUniqueID.first
+      rs['important-field'].should == &quot;1&quot;
+    end
+    it &quot;should return nil if no instances are found&quot; do
+      WithTemplateAndUniqueID.all.each {|obj| obj.destroy }
+      WithTemplateAndUniqueID.first.should be_nil
+    end
+  end
+  
+  describe &quot;getting a model with a subobject field&quot; do
+    before(:all) do
+      course_doc = {
+        &quot;title&quot; =&gt; &quot;Metaphysics 410&quot;,
+        &quot;professor&quot; =&gt; {
+          &quot;name&quot; =&gt; [&quot;Mark&quot;, &quot;Hinchliff&quot;]
+        },
+        &quot;final_test_at&quot; =&gt; &quot;2008/12/19 13:00:00 +0800&quot;
+      }
+      r = Course.database.save_doc course_doc
+      @course = Course.get r['id']
+    end
+    it &quot;should load the course&quot; do
+      @course[&quot;professor&quot;][&quot;name&quot;][1].should == &quot;Hinchliff&quot;
+    end
+    it &quot;should instantiate the professor as a person&quot; do
+      @course['professor'].last_name.should == &quot;Hinchliff&quot;
+    end
+    it &quot;should instantiate the final_test_at as a Time&quot; do
+      @course['final_test_at'].should == Time.parse(&quot;2008/12/19 13:00:00 +0800&quot;)
+    end
+  end
+  
   describe &quot;timestamping&quot; do
+    before(:each) do
+      oldart = Article.get &quot;saving-this&quot; rescue nil
+      oldart.destroy if oldart
+      @art = Article.new(:title =&gt; &quot;Saving this&quot;)
+      @art.save
+    end
+    
     it &quot;should define the updated_at and created_at getters and set the values&quot; do
       @obj.save
       obj = WithDefaultValues.get(@obj.id)
@@ -76,9 +285,18 @@ describe &quot;ExtendedDocument&quot; do
       obj.updated_at.should be_an_instance_of(Time)
       obj.created_at.to_s.should == @obj.updated_at.to_s
     end 
+    it &quot;should set the time on create&quot; do
+      (Time.now - @art.created_at).should &lt; 2
+      foundart = Article.get @art.id
+      foundart.created_at.should == foundart.updated_at
+    end
+    it &quot;should set the time on update&quot; do
+      @art.save
+      @art.created_at.should &lt; @art.updated_at
+    end
   end
   
-  describe &quot;saving and retrieving&quot; do
+  describe &quot;basic saving and retrieving&quot; do
     it &quot;should work fine&quot; do
       @obj.name = &quot;should be easily saved and retrieved&quot;
       @obj.save
@@ -96,6 +314,145 @@ describe &quot;ExtendedDocument&quot; do
     end
   end
   
+  describe &quot;saving a model&quot; do
+    before(:all) do
+      @sobj = Basic.new
+      @sobj.save.should == true
+    end
+    
+    it &quot;should save the doc&quot; do
+      doc = Basic.get(@sobj.id)
+      doc['_id'].should == @sobj.id
+    end
+    
+    it &quot;should be set for resaving&quot; do
+      rev = @obj.rev
+      @sobj['another-key'] = &quot;some value&quot;
+      @sobj.save
+      @sobj.rev.should_not == rev
+    end
+    
+    it &quot;should set the id&quot; do
+      @sobj.id.should be_an_instance_of(String)
+    end
+    
+    it &quot;should set the type&quot; do
+      @sobj['couchrest-type'].should == 'Basic'
+    end
+  end
+  
+  describe &quot;saving a model with a unique_id configured&quot; do
+    before(:each) do
+      @art = Article.new
+      @old = Article.database.get('this-is-the-title') rescue nil
+      Article.database.delete_doc(@old) if @old
+    end
+    
+    it &quot;should be a new document&quot; do
+      @art.should be_a_new_document
+      @art.title.should be_nil
+    end
+    
+    it &quot;should require the title&quot; do
+      lambda{@art.save}.should raise_error
+      @art.title = 'This is the title'
+      @art.save.should == true
+    end
+    
+    it &quot;should not change the slug on update&quot; do
+      @art.title = 'This is the title'
+      @art.save.should == true
+      @art.title = 'new title'
+      @art.save.should == true
+      @art.slug.should == 'this-is-the-title'
+    end
+    
+    it &quot;should raise an error when the slug is taken&quot; do
+      @art.title = 'This is the title'
+      @art.save.should == true
+      @art2 = Article.new(:title =&gt; 'This is the title!')
+      lambda{@art2.save}.should raise_error
+    end
+    
+    it &quot;should set the slug&quot; do
+      @art.title = 'This is the title'
+      @art.save.should == true
+      @art.slug.should == 'this-is-the-title'
+    end
+    
+    it &quot;should set the id&quot; do
+      @art.title = 'This is the title'
+      @art.save.should == true
+      @art.id.should == 'this-is-the-title'
+    end
+  end
+
+  describe &quot;saving a model with a unique_id lambda&quot; do
+    before(:each) do
+      @templated = WithTemplateAndUniqueID.new
+      @old = WithTemplateAndUniqueID.get('very-important') rescue nil
+      @old.destroy if @old
+    end
+    
+    it &quot;should require the field&quot; do
+      lambda{@templated.save}.should raise_error
+      @templated['important-field'] = 'very-important'
+      @templated.save.should == true
+    end
+    
+    it &quot;should save with the id&quot; do
+      @templated['important-field'] = 'very-important'
+      @templated.save.should == true
+      t = WithTemplateAndUniqueID.get('very-important')
+      t.should == @templated
+    end
+    
+    it &quot;should not change the id on update&quot; do
+      @templated['important-field'] = 'very-important'
+      @templated.save.should == true
+      @templated['important-field'] = 'not-important'
+      @templated.save.should == true
+      t = WithTemplateAndUniqueID.get('very-important')
+      t.should == @templated
+    end
+    
+    it &quot;should raise an error when the id is taken&quot; do
+      @templated['important-field'] = 'very-important'
+      @templated.save.should == true
+      lambda{WithTemplateAndUniqueID.new('important-field' =&gt; 'very-important').save}.should raise_error
+    end
+    
+    it &quot;should set the id&quot; do
+      @templated['important-field'] = 'very-important'
+      @templated.save.should == true
+      @templated.id.should == 'very-important'
+    end
+  end
+  
+  describe &quot;destroying an instance&quot; do
+    before(:each) do
+      @dobj = Basic.new
+      @dobj.save.should == true
+    end
+    it &quot;should return true&quot; do
+      result = @dobj.destroy
+      result.should == true
+    end
+    it &quot;should be resavable&quot; do
+      pending &quot;TO FIX&quot; do
+        @dobj.destroy
+        @dobj.rev.should be_nil
+        @dobj.id.should be_nil
+        @dobj.save.should == true
+      end
+    end
+    it &quot;should make it go away&quot; do
+      @dobj.destroy
+      lambda{Basic.get(@dobj.id)}.should raise_error
+    end
+  end
+  
+  
   describe &quot;callbacks&quot; do
     
     before(:each) do
@@ -103,28 +460,11 @@ describe &quot;ExtendedDocument&quot; do
     end
     
     describe &quot;save&quot; do
-      it &quot;should not run the before filter before saving if the save failed&quot; do
-        @doc.run_before_save.should be_nil
-        @doc.save.should be_true
-        @doc.run_before_save.should be_true
-      end
-      it &quot;should not run the before filter before saving if the save failed&quot; do
-        @doc.should_receive(:save).and_return(false)
-        @doc.run_before_save.should be_nil
-        @doc.save.should be_false
-        @doc.run_before_save.should be_nil
-      end
       it &quot;should run the after filter after saving&quot; do
         @doc.run_after_save.should be_nil
         @doc.save.should be_true
         @doc.run_after_save.should be_true
       end
-      it &quot;should not run the after filter before saving if the save failed&quot; do
-        @doc.should_receive(:save).and_return(false)
-        @doc.run_after_save.should be_nil
-        @doc.save.should be_false
-        @doc.run_after_save.should be_nil
-      end
     end
     describe &quot;create&quot; do
       it &quot;should run the before save filter when creating&quot; do
@@ -132,14 +472,6 @@ describe &quot;ExtendedDocument&quot; do
         @doc.create.should_not be_nil
         @doc.run_before_save.should be_true
       end
-      it &quot;should not run the before save filter when the object creation fails&quot; do
-        pending &quot;need to ask wycats about chainable callbacks&quot; do
-          @doc.should_receive(:create_without_callbacks).and_return(false)
-          @doc.run_before_save.should be_nil
-          @doc.save
-          @doc.run_before_save.should be_nil
-        end
-      end
       it &quot;should run the before create filter&quot; do
         @doc.run_before_create.should be_nil
         @doc.create.should_not be_nil</diff>
      <filename>spec/couchrest/more/extended_doc_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,7 +1,8 @@
 require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
 require File.join(FIXTURE_PATH, 'more', 'card')
 require File.join(FIXTURE_PATH, 'more', 'invoice')
-require File.join(FIXTURE_PATH, 'more', 'service.rb')
+require File.join(FIXTURE_PATH, 'more', 'service')
+require File.join(FIXTURE_PATH, 'more', 'event')
 
 
 describe &quot;ExtendedDocument properties&quot; do
@@ -43,7 +44,6 @@ describe &quot;ExtendedDocument properties&quot; do
   end
   
   describe &quot;validation&quot; do
-    
     before(:each) do
       @invoice = Invoice.new(:client_name =&gt; &quot;matt&quot;, :employee_name =&gt; &quot;Chris&quot;, :location =&gt; &quot;San Diego, CA&quot;)
     end
@@ -79,11 +79,9 @@ describe &quot;ExtendedDocument properties&quot; do
       @invoice.save.should be_false
       @invoice.should be_new_document
     end
-  
   end
   
   describe &quot;autovalidation&quot; do
-    
     before(:each) do
       @service = Service.new(:name =&gt; &quot;Coumpound analysis&quot;, :price =&gt; 3_000)
     end
@@ -112,7 +110,20 @@ describe &quot;ExtendedDocument properties&quot; do
         @service.errors.on(:name).first.should == &quot;Name must be between 4 and 19 characters long&quot;
       end
     end
-    
+  end
+  
+  describe &quot;casting&quot; do
+    describe &quot;cast keys to any type&quot; do
+      before(:all) do
+        event_doc = { :subject =&gt; &quot;Some event&quot;, :occurs_at =&gt; Time.now }
+        e = Event.database.save_doc event_doc
+
+        @event = Event.get e['id']
+      end
+      it &quot;should cast created_at to Time&quot; do
+        @event['occurs_at'].should be_an_instance_of(Time)
+      end
+    end
   end
   
 end
\ No newline at end of file</diff>
      <filename>spec/couchrest/more/property_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -14,6 +14,10 @@ unless defined?(FIXTURE_PATH)
   TEST_SERVER.default_database = TESTDB
 end
 
+class Basic &lt; CouchRest::ExtendedDocument
+  use_database TEST_SERVER.default_database
+end
+
 def reset_test_db!
   cr = TEST_SERVER
   db = cr.database(TESTDB)</diff>
      <filename>spec/spec_helper.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>lib/couchrest/core/model.rb</filename>
    </removed>
    <removed>
      <filename>spec/couchrest/core/model_spec.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>72542dc87688011a67b31aefce75cf499784d179</id>
    </parent>
  </parents>
  <author>
    <name>Matt Aimonetti</name>
    <email>mattaimonetti@gmail.com</email>
  </author>
  <url>http://github.com/mattetti/couchrest/commit/fe489f2d389b34c210fc570e512cfaee20b78068</url>
  <id>fe489f2d389b34c210fc570e512cfaee20b78068</id>
  <committed-date>2009-02-24T22:51:13-08:00</committed-date>
  <authored-date>2009-02-24T22:51:13-08:00</authored-date>
  <message>removed CouchRest::Model, added more specs and fixed a bug with casted CR::ExtendedDocument</message>
  <tree>fc3c68b1e0db65c8d41c5567889bb2228df11de5</tree>
  <committer>
    <name>Matt Aimonetti</name>
    <email>mattaimonetti@gmail.com</email>
  </committer>
</commit>
