jchris-couchrest 0.17.0 → 0.22
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.
- data/lib/couchrest.rb +13 -5
- data/lib/couchrest/core/database.rb +0 -20
- data/lib/couchrest/core/document.rb +2 -2
- data/lib/couchrest/mixins/callbacks.rb +3 -3
- data/lib/couchrest/mixins/properties.rb +9 -5
- data/lib/couchrest/mixins/validation.rb +8 -3
- data/lib/couchrest/mixins/views.rb +3 -3
- data/lib/couchrest/monkeypatches.rb +1 -1
- data/lib/couchrest/more/extended_document.rb +5 -8
- data/lib/couchrest/support/class.rb +136 -151
- data/lib/couchrest/validation/validation_errors.rb +1 -1
- data/lib/couchrest/validation/validators/format_validator.rb +1 -1
- data/lib/couchrest/validation/validators/length_validator.rb +1 -1
- data/spec/couchrest/core/database_spec.rb +0 -44
- data/spec/couchrest/core/document_spec.rb +0 -45
- data/spec/couchrest/more/extended_doc_subclass_spec.rb +54 -0
- metadata +22 -3
- data/spec/couchrest/support/class_spec.rb +0 -59
    
        data/lib/couchrest.rb
    CHANGED
    
    | @@ -28,7 +28,7 @@ require 'couchrest/monkeypatches' | |
| 28 28 |  | 
| 29 29 | 
             
            # = CouchDB, close to the metal
         | 
| 30 30 | 
             
            module CouchRest
         | 
| 31 | 
            -
              VERSION    = '0. | 
| 31 | 
            +
              VERSION    = '0.22' unless self.const_defined?("VERSION")
         | 
| 32 32 |  | 
| 33 33 | 
             
              autoload :Server,       'couchrest/core/server'
         | 
| 34 34 | 
             
              autoload :Database,     'couchrest/core/database'
         | 
| @@ -69,6 +69,18 @@ module CouchRest | |
| 69 69 | 
             
                  Object.module_eval("::#{$1}", __FILE__, __LINE__)
         | 
| 70 70 | 
             
                end
         | 
| 71 71 |  | 
| 72 | 
            +
                # extracted from Extlib
         | 
| 73 | 
            +
                #    
         | 
| 74 | 
            +
                # Capitalizes the first word and turns underscores into spaces and strips _id.
         | 
| 75 | 
            +
                # Like titleize, this is meant for creating pretty output.
         | 
| 76 | 
            +
                #
         | 
| 77 | 
            +
                # @example
         | 
| 78 | 
            +
                #   "employee_salary" #=> "Employee salary"
         | 
| 79 | 
            +
                #   "author_id" #=> "Author"
         | 
| 80 | 
            +
                def humanize(lower_case_and_underscored_word)
         | 
| 81 | 
            +
                  lower_case_and_underscored_word.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
                
         | 
| 72 84 | 
             
                # todo, make this parse the url and instantiate a Server or Database instance
         | 
| 73 85 | 
             
                # depending on the specificity.
         | 
| 74 86 | 
             
                def new(*opts)
         | 
| @@ -171,10 +183,6 @@ module CouchRest | |
| 171 183 | 
             
                def copy uri, destination
         | 
| 172 184 | 
             
                  JSON.parse(RestClient.copy(uri, {'Destination' => destination}))
         | 
| 173 185 | 
             
                end
         | 
| 174 | 
            -
                
         | 
| 175 | 
            -
                def move uri, destination
         | 
| 176 | 
            -
                  JSON.parse(RestClient.move(uri, {'Destination' => destination}))
         | 
| 177 | 
            -
                end
         | 
| 178 186 |  | 
| 179 187 | 
             
                def paramify_url url, params = {}
         | 
| 180 188 | 
             
                  if params && !params.empty?
         | 
| @@ -224,26 +224,6 @@ module CouchRest | |
| 224 224 | 
             
                  copy_doc(doc, dest)
         | 
| 225 225 | 
             
                end
         | 
| 226 226 |  | 
| 227 | 
            -
                # MOVE an existing document to a new id. If the destination id currently exists, a rev must be provided.
         | 
| 228 | 
            -
                # <tt>dest</tt> can take one of two forms if overwriting: "id_to_overwrite?rev=revision" or the actual doc
         | 
| 229 | 
            -
                # hash with a '_rev' key
         | 
| 230 | 
            -
                def move_doc(doc, dest)
         | 
| 231 | 
            -
                  raise ArgumentError, "_id and _rev are required for moving" unless doc['_id'] && doc['_rev']
         | 
| 232 | 
            -
                  slug = escape_docid(doc['_id'])        
         | 
| 233 | 
            -
                  destination = if dest.respond_to?(:has_key?) && dest['_id'] && dest['_rev']
         | 
| 234 | 
            -
                    "#{dest['_id']}?rev=#{dest['_rev']}"
         | 
| 235 | 
            -
                  else
         | 
| 236 | 
            -
                    dest
         | 
| 237 | 
            -
                  end
         | 
| 238 | 
            -
                  CouchRest.move "#{@uri}/#{slug}?rev=#{doc['_rev']}", destination
         | 
| 239 | 
            -
                end
         | 
| 240 | 
            -
                
         | 
| 241 | 
            -
                ### DEPRECATION NOTICE
         | 
| 242 | 
            -
                def move(doc, dest)
         | 
| 243 | 
            -
                  puts "CouchRest::Database's move method is being deprecated, please use move_doc instead"
         | 
| 244 | 
            -
                  move_doc(doc, dest)
         | 
| 245 | 
            -
                end
         | 
| 246 | 
            -
                
         | 
| 247 227 | 
             
                # Compact the database, removing old document revisions and optimizing space use.
         | 
| 248 228 | 
             
                def compact!
         | 
| 249 229 | 
             
                  CouchRest.post "#{@uri}/_compact"
         | 
| @@ -5,10 +5,10 @@ module CouchRest | |
| 5 5 | 
             
                include CouchRest::Mixins::Attachments
         | 
| 6 6 |  | 
| 7 7 | 
             
                # def self.inherited(subklass)
         | 
| 8 | 
            -
                #   subklass.send(: | 
| 8 | 
            +
                #   subklass.send(:extlib_inheritable_accessor, :database)
         | 
| 9 9 | 
             
                # end
         | 
| 10 10 |  | 
| 11 | 
            -
                 | 
| 11 | 
            +
                extlib_inheritable_accessor :database
         | 
| 12 12 | 
             
                attr_accessor :database
         | 
| 13 13 |  | 
| 14 14 | 
             
                # override the CouchRest::Model-wide default_database
         | 
| @@ -426,10 +426,10 @@ module CouchRest | |
| 426 426 | 
             
                  def define_callbacks(*symbols)
         | 
| 427 427 | 
             
                    terminator = symbols.pop if symbols.last.is_a?(String)
         | 
| 428 428 | 
             
                    symbols.each do |symbol|
         | 
| 429 | 
            -
                      self. | 
| 429 | 
            +
                      self.extlib_inheritable_accessor("_#{symbol}_terminator")
         | 
| 430 430 | 
             
                      self.send("_#{symbol}_terminator=", terminator)
         | 
| 431 431 | 
             
                      self.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
         | 
| 432 | 
            -
                         | 
| 432 | 
            +
                        extlib_inheritable_accessor :_#{symbol}_callbacks
         | 
| 433 433 | 
             
                        self._#{symbol}_callbacks = CallbackChain.new(:#{symbol})
         | 
| 434 434 |  | 
| 435 435 | 
             
                        def self.#{symbol}_callback(*filters, &blk)
         | 
| @@ -480,4 +480,4 @@ module CouchRest | |
| 480 480 | 
             
                  end
         | 
| 481 481 | 
             
                end
         | 
| 482 482 | 
             
              end
         | 
| 483 | 
            -
            end
         | 
| 483 | 
            +
            end
         | 
| @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            require 'time'
         | 
| 1 2 | 
             
            require File.join(File.dirname(__FILE__), '..', 'more', 'property')
         | 
| 2 3 |  | 
| 3 4 | 
             
            module CouchRest
         | 
| @@ -7,10 +8,10 @@ module CouchRest | |
| 7 8 | 
             
                  class IncludeError < StandardError; end
         | 
| 8 9 |  | 
| 9 10 | 
             
                  def self.included(base)
         | 
| 10 | 
            -
                    base. | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 11 | 
            +
                    base.class_eval <<-EOS, __FILE__, __LINE__
         | 
| 12 | 
            +
                        extlib_inheritable_accessor(:properties)
         | 
| 13 | 
            +
                        self.properties ||= []
         | 
| 14 | 
            +
                    EOS
         | 
| 14 15 | 
             
                    base.extend(ClassMethods)
         | 
| 15 16 | 
             
                    raise CouchRest::Mixins::Properties::IncludeError, "You can only mixin Properties in a class responding to [] and []=, if you tried to mixin CastedModel, make sure your class inherits from Hash or responds to the proper methods" unless (base.new.respond_to?(:[]) && base.new.respond_to?(:[]=))
         | 
| 16 17 | 
             
                  end
         | 
| @@ -70,7 +71,10 @@ module CouchRest | |
| 70 71 | 
             
                  module ClassMethods
         | 
| 71 72 |  | 
| 72 73 | 
             
                    def property(name, options={})
         | 
| 73 | 
            -
                       | 
| 74 | 
            +
                      existing_property = self.properties.find{|p| p.name == name.to_s}
         | 
| 75 | 
            +
                      if existing_property.nil? || (existing_property.default != options[:default])
         | 
| 76 | 
            +
                        define_property(name, options)
         | 
| 77 | 
            +
                      end
         | 
| 74 78 | 
             
                    end
         | 
| 75 79 |  | 
| 76 80 | 
             
                    protected
         | 
| @@ -49,10 +49,10 @@ module CouchRest | |
| 49 49 | 
             
              module Validation
         | 
| 50 50 |  | 
| 51 51 | 
             
                def self.included(base)
         | 
| 52 | 
            -
                  base. | 
| 52 | 
            +
                  base.extlib_inheritable_accessor(:auto_validation)
         | 
| 53 53 | 
             
                  base.class_eval <<-EOS, __FILE__, __LINE__
         | 
| 54 54 | 
             
                      # Turn off auto validation by default
         | 
| 55 | 
            -
                       | 
| 55 | 
            +
                      self.auto_validation ||= false
         | 
| 56 56 |  | 
| 57 57 | 
             
                      # Force the auto validation for the class properties
         | 
| 58 58 | 
             
                      # This feature is still not fully ported over,
         | 
| @@ -60,6 +60,11 @@ module CouchRest | |
| 60 60 | 
             
                      def self.auto_validate!
         | 
| 61 61 | 
             
                        self.auto_validation = true
         | 
| 62 62 | 
             
                      end
         | 
| 63 | 
            +
                      
         | 
| 64 | 
            +
                      # share the validations with subclasses
         | 
| 65 | 
            +
                      def self.inherited(subklass)
         | 
| 66 | 
            +
                        subklass.instance_variable_set(:@validations, self.validators.dup)
         | 
| 67 | 
            +
                      end
         | 
| 63 68 | 
             
                  EOS
         | 
| 64 69 |  | 
| 65 70 | 
             
                  base.extend(ClassMethods)
         | 
| @@ -71,7 +76,7 @@ module CouchRest | |
| 71 76 | 
             
                  base.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
         | 
| 72 77 | 
             
                    def self.define_property(name, options={})
         | 
| 73 78 | 
             
                      super
         | 
| 74 | 
            -
                      auto_generate_validations(properties.last)
         | 
| 79 | 
            +
                      auto_generate_validations(properties.last) if properties && properties.size > 0
         | 
| 75 80 | 
             
                      autovalidation_check = true
         | 
| 76 81 | 
             
                    end
         | 
| 77 82 | 
             
                  RUBY_EVAL
         | 
| @@ -4,9 +4,9 @@ module CouchRest | |
| 4 4 |  | 
| 5 5 | 
             
                  def self.included(base)
         | 
| 6 6 | 
             
                    base.extend(ClassMethods)
         | 
| 7 | 
            -
                    base.send(: | 
| 8 | 
            -
                    base.send(: | 
| 9 | 
            -
                    base.send(: | 
| 7 | 
            +
                    base.send(:extlib_inheritable_accessor, :design_doc)
         | 
| 8 | 
            +
                    base.send(:extlib_inheritable_accessor, :design_doc_slug_cache)
         | 
| 9 | 
            +
                    base.send(:extlib_inheritable_accessor, :design_doc_fresh)
         | 
| 10 10 | 
             
                  end
         | 
| 11 11 |  | 
| 12 12 | 
             
                  module ClassMethods
         | 
| @@ -1,11 +1,3 @@ | |
| 1 | 
            -
            begin
         | 
| 2 | 
            -
              # still required for Time parsing and pluralization in the validation
         | 
| 3 | 
            -
              require 'extlib'
         | 
| 4 | 
            -
            rescue 
         | 
| 5 | 
            -
              puts "CouchRest::ExtendedDocument still requires extlib (not for much longer). This is left out of the gemspec on purpose."
         | 
| 6 | 
            -
              raise
         | 
| 7 | 
            -
            end
         | 
| 8 | 
            -
             | 
| 9 1 | 
             
            require 'mime/types'
         | 
| 10 2 | 
             
            require File.join(File.dirname(__FILE__), "property")
         | 
| 11 3 | 
             
            require File.join(File.dirname(__FILE__), '..', 'mixins', 'extended_document_mixins')
         | 
| @@ -22,6 +14,11 @@ module CouchRest | |
| 22 14 |  | 
| 23 15 | 
             
                def self.inherited(subklass)
         | 
| 24 16 | 
             
                  subklass.send(:include, CouchRest::Mixins::Properties)
         | 
| 17 | 
            +
                  subklass.class_eval <<-EOS, __FILE__, __LINE__
         | 
| 18 | 
            +
                    def self.inherited(subklass)
         | 
| 19 | 
            +
                      subklass.properties = self.properties.dup
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
                  EOS
         | 
| 25 22 | 
             
                end
         | 
| 26 23 |  | 
| 27 24 | 
             
                # Accessors
         | 
| @@ -25,167 +25,152 @@ | |
| 25 25 | 
             
            # example, an array without those additions being shared with either their
         | 
| 26 26 | 
             
            # parent, siblings, or children, which is unlike the regular class-level
         | 
| 27 27 | 
             
            # attributes that are shared across the entire hierarchy.
         | 
| 28 | 
            -
             | 
| 29 | 
            -
               | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
                
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                   | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
                  # @return <Array[#to_s]> List of attributes that were made into cattr_readers
         | 
| 45 | 
            -
                  #
         | 
| 46 | 
            -
                  # @api public
         | 
| 47 | 
            -
                  #
         | 
| 48 | 
            -
                  # @todo Is this inconsistent in that it does not allow you to prevent
         | 
| 49 | 
            -
                  # an instance_reader via :instance_reader => false
         | 
| 50 | 
            -
                  def cattr_reader(*syms)
         | 
| 51 | 
            -
                    syms.flatten.each do |sym|
         | 
| 52 | 
            -
                      next if sym.is_a?(Hash)
         | 
| 53 | 
            -
                      class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
         | 
| 54 | 
            -
                unless defined? @@#{sym}
         | 
| 55 | 
            -
                @@#{sym} = nil
         | 
| 56 | 
            -
                end
         | 
| 57 | 
            -
             
         | 
| 58 | 
            -
                def self.#{sym}
         | 
| 59 | 
            -
                @@#{sym}
         | 
| 60 | 
            -
                end
         | 
| 61 | 
            -
             
         | 
| 62 | 
            -
                def #{sym}
         | 
| 63 | 
            -
                @@#{sym}
         | 
| 64 | 
            -
                end
         | 
| 65 | 
            -
                RUBY
         | 
| 28 | 
            +
            class Class
         | 
| 29 | 
            +
              # Defines class-level and instance-level attribute reader.
         | 
| 30 | 
            +
              #
         | 
| 31 | 
            +
              # @param *syms<Array> Array of attributes to define reader for.
         | 
| 32 | 
            +
              # @return <Array[#to_s]> List of attributes that were made into cattr_readers
         | 
| 33 | 
            +
              #
         | 
| 34 | 
            +
              # @api public
         | 
| 35 | 
            +
              #
         | 
| 36 | 
            +
              # @todo Is this inconsistent in that it does not allow you to prevent
         | 
| 37 | 
            +
              #   an instance_reader via :instance_reader => false
         | 
| 38 | 
            +
              def cattr_reader(*syms)
         | 
| 39 | 
            +
                syms.flatten.each do |sym|
         | 
| 40 | 
            +
                  next if sym.is_a?(Hash)
         | 
| 41 | 
            +
                  class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
         | 
| 42 | 
            +
                    unless defined? @@#{sym}
         | 
| 43 | 
            +
                      @@#{sym} = nil
         | 
| 66 44 | 
             
                    end
         | 
| 67 | 
            -
             | 
| 68 | 
            -
             
         | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
                   | 
| 76 | 
            -
                  def cattr_writer(*syms)
         | 
| 77 | 
            -
                    options = syms.last.is_a?(Hash) ? syms.pop : {}
         | 
| 78 | 
            -
                    syms.flatten.each do |sym|
         | 
| 79 | 
            -
                      class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
         | 
| 80 | 
            -
                unless defined? @@#{sym}
         | 
| 81 | 
            -
                @@#{sym} = nil
         | 
| 82 | 
            -
                end
         | 
| 83 | 
            -
             
         | 
| 84 | 
            -
                def self.#{sym}=(obj)
         | 
| 85 | 
            -
                @@#{sym} = obj
         | 
| 86 | 
            -
                end
         | 
| 87 | 
            -
                RUBY
         | 
| 88 | 
            -
             
         | 
| 89 | 
            -
                      unless options[:instance_writer] == false
         | 
| 90 | 
            -
                        class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
         | 
| 91 | 
            -
                def #{sym}=(obj)
         | 
| 92 | 
            -
                @@#{sym} = obj
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                    def self.#{sym}
         | 
| 47 | 
            +
                      @@#{sym}
         | 
| 48 | 
            +
                    end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                    def #{sym}
         | 
| 51 | 
            +
                      @@#{sym}
         | 
| 52 | 
            +
                    end
         | 
| 53 | 
            +
                  RUBY
         | 
| 93 54 | 
             
                end
         | 
| 94 | 
            -
             | 
| 95 | 
            -
             | 
| 55 | 
            +
              end unless Class.respond_to?(:cattr_reader)
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              # Defines class-level (and optionally instance-level) attribute writer.
         | 
| 58 | 
            +
              #
         | 
| 59 | 
            +
              # @param <Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to define writer for.
         | 
| 60 | 
            +
              # @option syms :instance_writer<Boolean> if true, instance-level attribute writer is defined.
         | 
| 61 | 
            +
              # @return <Array[#to_s]> List of attributes that were made into cattr_writers
         | 
| 62 | 
            +
              #
         | 
| 63 | 
            +
              # @api public
         | 
| 64 | 
            +
              def cattr_writer(*syms)
         | 
| 65 | 
            +
                options = syms.last.is_a?(Hash) ? syms.pop : {}
         | 
| 66 | 
            +
                syms.flatten.each do |sym|
         | 
| 67 | 
            +
                  class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
         | 
| 68 | 
            +
                    unless defined? @@#{sym}
         | 
| 69 | 
            +
                      @@#{sym} = nil
         | 
| 96 70 | 
             
                    end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                    def self.#{sym}=(obj)
         | 
| 73 | 
            +
                      @@#{sym} = obj
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
                  RUBY
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  unless options[:instance_writer] == false
         | 
| 78 | 
            +
                    class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
         | 
| 79 | 
            +
                      def #{sym}=(obj)
         | 
| 80 | 
            +
                        @@#{sym} = obj
         | 
| 81 | 
            +
                      end
         | 
| 82 | 
            +
                    RUBY
         | 
| 97 83 | 
             
                  end
         | 
| 98 | 
            -
             
         | 
| 99 | 
            -
                  # Defines class-level (and optionally instance-level) attribute accessor.
         | 
| 100 | 
            -
                  #
         | 
| 101 | 
            -
                  # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to define accessor for.
         | 
| 102 | 
            -
                  # @option syms :instance_writer<Boolean> if true, instance-level attribute writer is defined.
         | 
| 103 | 
            -
                  # @return <Array[#to_s]> List of attributes that were made into accessors
         | 
| 104 | 
            -
                  #
         | 
| 105 | 
            -
                  # @api public
         | 
| 106 | 
            -
                  def cattr_accessor(*syms)
         | 
| 107 | 
            -
                    cattr_reader(*syms)
         | 
| 108 | 
            -
                    cattr_writer(*syms)
         | 
| 109 | 
            -
                  end
         | 
| 110 | 
            -
             
         | 
| 111 | 
            -
                  # Defines class-level inheritable attribute reader. Attributes are available to subclasses,
         | 
| 112 | 
            -
                  # each subclass has a copy of parent's attribute.
         | 
| 113 | 
            -
                  #
         | 
| 114 | 
            -
                  # @param *syms<Array[#to_s]> Array of attributes to define inheritable reader for.
         | 
| 115 | 
            -
                  # @return <Array[#to_s]> Array of attributes converted into inheritable_readers.
         | 
| 116 | 
            -
                  #
         | 
| 117 | 
            -
                  # @api public
         | 
| 118 | 
            -
                  #
         | 
| 119 | 
            -
                  # @todo Do we want to block instance_reader via :instance_reader => false
         | 
| 120 | 
            -
                  # @todo It would be preferable that we do something with a Hash passed in
         | 
| 121 | 
            -
                  # (error out or do the same as other methods above) instead of silently
         | 
| 122 | 
            -
                  # moving on). In particular, this makes the return value of this function
         | 
| 123 | 
            -
                  # less useful.
         | 
| 124 | 
            -
                  def class_inheritable_reader(*ivars)
         | 
| 125 | 
            -
                    instance_reader = ivars.pop[:reader] if ivars.last.is_a?(Hash)
         | 
| 126 | 
            -
             
         | 
| 127 | 
            -
                    ivars.each do |ivar|
         | 
| 128 | 
            -
                      self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         | 
| 129 | 
            -
                def self.#{ivar}
         | 
| 130 | 
            -
                return @#{ivar} if self.object_id == #{self.object_id} || defined?(@#{ivar})
         | 
| 131 | 
            -
                ivar = superclass.#{ivar}
         | 
| 132 | 
            -
                return nil if ivar.nil? && !#{self}.instance_variable_defined?("@#{ivar}")
         | 
| 133 | 
            -
                @#{ivar} = ivar && !ivar.is_a?(Module) && !ivar.is_a?(Numeric) && !ivar.is_a?(TrueClass) && !ivar.is_a?(FalseClass) && !ivar.is_a?(Symbol) ? ivar.dup : ivar
         | 
| 134 84 | 
             
                end
         | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
             | 
| 139 | 
            -
             | 
| 140 | 
            -
             | 
| 141 | 
            -
             | 
| 142 | 
            -
             | 
| 85 | 
            +
              end unless Class.respond_to?(:cattr_writer)
         | 
| 86 | 
            +
             | 
| 87 | 
            +
              # Defines class-level (and optionally instance-level) attribute accessor.
         | 
| 88 | 
            +
              #
         | 
| 89 | 
            +
              # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to define accessor for.
         | 
| 90 | 
            +
              # @option syms :instance_writer<Boolean> if true, instance-level attribute writer is defined.
         | 
| 91 | 
            +
              # @return <Array[#to_s]> List of attributes that were made into accessors
         | 
| 92 | 
            +
              #
         | 
| 93 | 
            +
              # @api public
         | 
| 94 | 
            +
              def cattr_accessor(*syms)
         | 
| 95 | 
            +
                cattr_reader(*syms)
         | 
| 96 | 
            +
                cattr_writer(*syms)
         | 
| 97 | 
            +
              end unless Class.respond_to?(:cattr_accessor)
         | 
| 98 | 
            +
              
         | 
| 99 | 
            +
              # Defines class-level inheritable attribute reader. Attributes are available to subclasses,
         | 
| 100 | 
            +
              # each subclass has a copy of parent's attribute.
         | 
| 101 | 
            +
              #
         | 
| 102 | 
            +
              # @param *syms<Array[#to_s]> Array of attributes to define inheritable reader for.
         | 
| 103 | 
            +
              # @return <Array[#to_s]> Array of attributes converted into inheritable_readers.
         | 
| 104 | 
            +
              #
         | 
| 105 | 
            +
              # @api public
         | 
| 106 | 
            +
              #
         | 
| 107 | 
            +
              # @todo Do we want to block instance_reader via :instance_reader => false
         | 
| 108 | 
            +
              # @todo It would be preferable that we do something with a Hash passed in
         | 
| 109 | 
            +
              #   (error out or do the same as other methods above) instead of silently
         | 
| 110 | 
            +
              #   moving on). In particular, this makes the return value of this function
         | 
| 111 | 
            +
              #   less useful.
         | 
| 112 | 
            +
              def extlib_inheritable_reader(*ivars)
         | 
| 113 | 
            +
                instance_reader = ivars.pop[:reader] if ivars.last.is_a?(Hash)
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                ivars.each do |ivar|
         | 
| 116 | 
            +
                  self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         | 
| 117 | 
            +
                    def self.#{ivar}
         | 
| 118 | 
            +
                      return @#{ivar} if self.object_id == #{self.object_id} || defined?(@#{ivar})
         | 
| 119 | 
            +
                      ivar = superclass.#{ivar}
         | 
| 120 | 
            +
                      return nil if ivar.nil? && !#{self}.instance_variable_defined?("@#{ivar}")
         | 
| 121 | 
            +
                      @#{ivar} = ivar && !ivar.is_a?(Module) && !ivar.is_a?(Numeric) && !ivar.is_a?(TrueClass) && !ivar.is_a?(FalseClass) ? ivar.dup : ivar
         | 
| 143 122 | 
             
                    end
         | 
| 123 | 
            +
                  RUBY
         | 
| 124 | 
            +
                  unless instance_reader == false
         | 
| 125 | 
            +
                    self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         | 
| 126 | 
            +
                      def #{ivar}
         | 
| 127 | 
            +
                        self.class.#{ivar}
         | 
| 128 | 
            +
                      end
         | 
| 129 | 
            +
                    RUBY
         | 
| 144 130 | 
             
                  end
         | 
| 145 | 
            -
             
         | 
| 146 | 
            -
                  # Defines class-level inheritable attribute writer. Attributes are available to subclasses,
         | 
| 147 | 
            -
                  # each subclass has a copy of parent's attribute.
         | 
| 148 | 
            -
                  #
         | 
| 149 | 
            -
                  # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
         | 
| 150 | 
            -
                  # define inheritable writer for.
         | 
| 151 | 
            -
                  # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
         | 
| 152 | 
            -
                  # @return <Array[#to_s]> An Array of the attributes that were made into inheritable writers.
         | 
| 153 | 
            -
                  #
         | 
| 154 | 
            -
                  # @api public
         | 
| 155 | 
            -
                  #
         | 
| 156 | 
            -
                  # @todo We need a style for class_eval <<-HEREDOC. I'd like to make it
         | 
| 157 | 
            -
                  # class_eval(<<-RUBY, __FILE__, __LINE__), but we should codify it somewhere.
         | 
| 158 | 
            -
                  def class_inheritable_writer(*ivars)
         | 
| 159 | 
            -
                    instance_writer = ivars.pop[:instance_writer] if ivars.last.is_a?(Hash)
         | 
| 160 | 
            -
                    ivars.each do |ivar|
         | 
| 161 | 
            -
                      self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         | 
| 162 | 
            -
                def self.#{ivar}=(obj)
         | 
| 163 | 
            -
                @#{ivar} = obj
         | 
| 164 131 | 
             
                end
         | 
| 165 | 
            -
             | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 168 | 
            -
             | 
| 169 | 
            -
             | 
| 170 | 
            -
             | 
| 132 | 
            +
              end unless Class.respond_to?(:extlib_inheritable_reader)
         | 
| 133 | 
            +
             | 
| 134 | 
            +
              # Defines class-level inheritable attribute writer. Attributes are available to subclasses,
         | 
| 135 | 
            +
              # each subclass has a copy of parent's attribute.
         | 
| 136 | 
            +
              #
         | 
| 137 | 
            +
              # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
         | 
| 138 | 
            +
              #   define inheritable writer for.
         | 
| 139 | 
            +
              # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
         | 
| 140 | 
            +
              # @return <Array[#to_s]> An Array of the attributes that were made into inheritable writers.
         | 
| 141 | 
            +
              #
         | 
| 142 | 
            +
              # @api public
         | 
| 143 | 
            +
              #
         | 
| 144 | 
            +
              # @todo We need a style for class_eval <<-HEREDOC. I'd like to make it
         | 
| 145 | 
            +
              #   class_eval(<<-RUBY, __FILE__, __LINE__), but we should codify it somewhere.
         | 
| 146 | 
            +
              def extlib_inheritable_writer(*ivars)
         | 
| 147 | 
            +
                instance_writer = ivars.pop[:writer] if ivars.last.is_a?(Hash)
         | 
| 148 | 
            +
                ivars.each do |ivar|
         | 
| 149 | 
            +
                  self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         | 
| 150 | 
            +
                    def self.#{ivar}=(obj)
         | 
| 151 | 
            +
                      @#{ivar} = obj
         | 
| 171 152 | 
             
                    end
         | 
| 172 | 
            -
                   | 
| 173 | 
            -
             
         | 
| 174 | 
            -
             | 
| 175 | 
            -
             | 
| 176 | 
            -
             | 
| 177 | 
            -
                  # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
         | 
| 178 | 
            -
                  # define inheritable accessor for.
         | 
| 179 | 
            -
                  # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
         | 
| 180 | 
            -
                  # @return <Array[#to_s]> An Array of attributes turned into inheritable accessors.
         | 
| 181 | 
            -
                  #
         | 
| 182 | 
            -
                  # @api public
         | 
| 183 | 
            -
                  def class_inheritable_accessor(*syms)
         | 
| 184 | 
            -
                    class_inheritable_reader(*syms)
         | 
| 185 | 
            -
                    class_inheritable_writer(*syms)
         | 
| 153 | 
            +
                  RUBY
         | 
| 154 | 
            +
                  unless instance_writer == false
         | 
| 155 | 
            +
                    self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
         | 
| 156 | 
            +
                      def #{ivar}=(obj) self.class.#{ivar} = obj end
         | 
| 157 | 
            +
                    RUBY
         | 
| 186 158 | 
             
                  end
         | 
| 187 159 | 
             
                end
         | 
| 188 | 
            -
              end
         | 
| 160 | 
            +
              end unless Class.respond_to?(:extlib_inheritable_writer)
         | 
| 161 | 
            +
             | 
| 162 | 
            +
              # Defines class-level inheritable attribute accessor. Attributes are available to subclasses,
         | 
| 163 | 
            +
              # each subclass has a copy of parent's attribute.
         | 
| 164 | 
            +
              #
         | 
| 165 | 
            +
              # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
         | 
| 166 | 
            +
              #   define inheritable accessor for.
         | 
| 167 | 
            +
              # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
         | 
| 168 | 
            +
              # @return <Array[#to_s]> An Array of attributes turned into inheritable accessors.
         | 
| 169 | 
            +
              #
         | 
| 170 | 
            +
              # @api public
         | 
| 171 | 
            +
              def extlib_inheritable_accessor(*syms)
         | 
| 172 | 
            +
                extlib_inheritable_reader(*syms)
         | 
| 173 | 
            +
                extlib_inheritable_writer(*syms)
         | 
| 174 | 
            +
              end unless Class.respond_to?(:extlib_inheritable_accessor)
         | 
| 189 175 | 
             
            end
         | 
| 190 176 |  | 
| 191 | 
            -
            Class.send(:include, CouchRest::ClassExtension)
         | 
| @@ -60,7 +60,7 @@ module CouchRest | |
| 60 60 | 
             
                  cattr_writer :default_error_messages
         | 
| 61 61 |  | 
| 62 62 | 
             
                  def self.default_error_message(key, field, *values)
         | 
| 63 | 
            -
                    field =  | 
| 63 | 
            +
                    field = CouchRest.humanize(field)
         | 
| 64 64 | 
             
                    @@default_error_messages[key] % [field, *values].flatten
         | 
| 65 65 | 
             
                  end
         | 
| 66 66 |  | 
| @@ -64,7 +64,7 @@ module CouchRest | |
| 64 64 |  | 
| 65 65 | 
             
                    error_message = @options[:message] || ValidationErrors.default_error_message(:invalid, field_name)
         | 
| 66 66 |  | 
| 67 | 
            -
                    field =  | 
| 67 | 
            +
                    field = CouchRest.humanize(field_name)
         | 
| 68 68 | 
             
                    error_message = error_message.call(field, value) if error_message.respond_to?(:call)
         | 
| 69 69 |  | 
| 70 70 | 
             
                    add_error(target, error_message, field_name)
         | 
| @@ -54,7 +54,7 @@ module CouchRest | |
| 54 54 |  | 
| 55 55 | 
             
                    # XXX: HACK seems hacky to do this on every validation, probably should
         | 
| 56 56 | 
             
                    #      do this elsewhere?
         | 
| 57 | 
            -
                    field =  | 
| 57 | 
            +
                    field = CouchRest.humanize(field_name)
         | 
| 58 58 | 
             
                    min = @range ? @range.min : @min
         | 
| 59 59 | 
             
                    max = @range ? @range.max : @max
         | 
| 60 60 | 
             
                    equal = @equal
         | 
| @@ -554,50 +554,6 @@ describe CouchRest::Database do | |
| 554 554 | 
             
                end
         | 
| 555 555 | 
             
              end
         | 
| 556 556 |  | 
| 557 | 
            -
              describe "MOVE existing document" do
         | 
| 558 | 
            -
                before :each do
         | 
| 559 | 
            -
                  @r = @db.save_doc({'artist' => 'Zappa', 'title' => 'Muffin Man'})
         | 
| 560 | 
            -
                  @docid = 'tracks/zappa/muffin-man'
         | 
| 561 | 
            -
                  @doc = @db.get(@r['id'])
         | 
| 562 | 
            -
                end
         | 
| 563 | 
            -
                describe "to a new location" do
         | 
| 564 | 
            -
                  it "should work" do
         | 
| 565 | 
            -
                    @db.move_doc @doc, @docid
         | 
| 566 | 
            -
                    newdoc = @db.get(@docid)
         | 
| 567 | 
            -
                    newdoc['artist'].should == 'Zappa'
         | 
| 568 | 
            -
                    lambda {@db.get(@r['id'])}.should raise_error(RestClient::ResourceNotFound)
         | 
| 569 | 
            -
                  end
         | 
| 570 | 
            -
                  it "should fail without an _id or _rev" do
         | 
| 571 | 
            -
                    lambda{@db.move({"not"=>"a real doc"})}.should raise_error(ArgumentError)
         | 
| 572 | 
            -
                    lambda{@db.move({"_id"=>"not a real doc"})}.should raise_error(ArgumentError)
         | 
| 573 | 
            -
                  end
         | 
| 574 | 
            -
                end
         | 
| 575 | 
            -
                describe "to an existing location" do
         | 
| 576 | 
            -
                  before :each do
         | 
| 577 | 
            -
                    @db.save_doc({'_id' => @docid, 'will-exist' => 'here'})
         | 
| 578 | 
            -
                  end
         | 
| 579 | 
            -
                  it "should fail without a rev" do
         | 
| 580 | 
            -
                    @doc.delete("_rev")
         | 
| 581 | 
            -
                    lambda{@db.move_doc @doc, @docid}.should raise_error(ArgumentError)
         | 
| 582 | 
            -
                    lambda{@db.get(@r['id'])}.should_not raise_error
         | 
| 583 | 
            -
                  end
         | 
| 584 | 
            -
                  it "should succeed with a rev" do
         | 
| 585 | 
            -
                    @to_be_overwritten = @db.get(@docid)
         | 
| 586 | 
            -
                    @db.move_doc @doc, "#{@docid}?rev=#{@to_be_overwritten['_rev']}"
         | 
| 587 | 
            -
                    newdoc = @db.get(@docid)
         | 
| 588 | 
            -
                    newdoc['artist'].should == 'Zappa'
         | 
| 589 | 
            -
                    lambda {@db.get(@r['id'])}.should raise_error(RestClient::ResourceNotFound)
         | 
| 590 | 
            -
                  end
         | 
| 591 | 
            -
                  it "should succeed given the doc to overwrite" do
         | 
| 592 | 
            -
                    @to_be_overwritten = @db.get(@docid)
         | 
| 593 | 
            -
                    @db.move_doc @doc, @to_be_overwritten
         | 
| 594 | 
            -
                    newdoc = @db.get(@docid)
         | 
| 595 | 
            -
                    newdoc['artist'].should == 'Zappa'
         | 
| 596 | 
            -
                    lambda {@db.get(@r['id'])}.should raise_error(RestClient::ResourceNotFound)
         | 
| 597 | 
            -
                  end
         | 
| 598 | 
            -
                end
         | 
| 599 | 
            -
              end
         | 
| 600 | 
            -
              
         | 
| 601 557 |  | 
| 602 558 | 
             
              it "should list documents" do
         | 
| 603 559 | 
             
                5.times do
         | 
| @@ -199,51 +199,6 @@ describe CouchRest::Document do | |
| 199 199 | 
             
                  end
         | 
| 200 200 | 
             
                end
         | 
| 201 201 | 
             
              end
         | 
| 202 | 
            -
             | 
| 203 | 
            -
              describe "MOVE existing document" do
         | 
| 204 | 
            -
                before :each do
         | 
| 205 | 
            -
                  @db = reset_test_db!
         | 
| 206 | 
            -
                  @resp = @db.save_doc({'key' => 'value'})
         | 
| 207 | 
            -
                  @docid = 'new-location'
         | 
| 208 | 
            -
                  @doc = @db.get(@resp['id'])
         | 
| 209 | 
            -
                end
         | 
| 210 | 
            -
                describe "to a new location" do
         | 
| 211 | 
            -
                  it "should work" do
         | 
| 212 | 
            -
                    @doc.move @docid
         | 
| 213 | 
            -
                    newdoc = @db.get(@docid)
         | 
| 214 | 
            -
                    newdoc['key'].should == 'value'
         | 
| 215 | 
            -
                    lambda {@db.get(@resp['id'])}.should raise_error(RestClient::ResourceNotFound)
         | 
| 216 | 
            -
                  end
         | 
| 217 | 
            -
                  it "should fail without a database" do
         | 
| 218 | 
            -
                    lambda{CouchRest::Document.new({"not"=>"a real doc"}).move}.should raise_error(ArgumentError)
         | 
| 219 | 
            -
                    lambda{CouchRest::Document.new({"_id"=>"not a real doc"}).move}.should raise_error(ArgumentError)
         | 
| 220 | 
            -
                  end
         | 
| 221 | 
            -
                end
         | 
| 222 | 
            -
                describe "to an existing location" do
         | 
| 223 | 
            -
                  before :each do
         | 
| 224 | 
            -
                    @db.save_doc({'_id' => @docid, 'will-exist' => 'here'})
         | 
| 225 | 
            -
                  end
         | 
| 226 | 
            -
                  it "should fail without a rev" do
         | 
| 227 | 
            -
                    @doc.delete("_rev")
         | 
| 228 | 
            -
                    lambda{@doc.move @docid}.should raise_error(ArgumentError)
         | 
| 229 | 
            -
                    lambda{@db.get(@resp['id'])}.should_not raise_error
         | 
| 230 | 
            -
                  end
         | 
| 231 | 
            -
                  it "should succeed with a rev" do
         | 
| 232 | 
            -
                    @to_be_overwritten = @db.get(@docid)
         | 
| 233 | 
            -
                    @doc.move "#{@docid}?rev=#{@to_be_overwritten['_rev']}"
         | 
| 234 | 
            -
                    newdoc = @db.get(@docid)
         | 
| 235 | 
            -
                    newdoc['key'].should == 'value'
         | 
| 236 | 
            -
                    lambda {@db.get(@resp['id'])}.should raise_error(RestClient::ResourceNotFound)
         | 
| 237 | 
            -
                  end
         | 
| 238 | 
            -
                  it "should succeed given the doc to overwrite" do
         | 
| 239 | 
            -
                    @to_be_overwritten = @db.get(@docid)
         | 
| 240 | 
            -
                    @doc.move @to_be_overwritten
         | 
| 241 | 
            -
                    newdoc = @db.get(@docid)
         | 
| 242 | 
            -
                    newdoc['key'].should == 'value'
         | 
| 243 | 
            -
                    lambda {@db.get(@resp['id'])}.should raise_error(RestClient::ResourceNotFound)
         | 
| 244 | 
            -
                  end
         | 
| 245 | 
            -
                end
         | 
| 246 | 
            -
              end
         | 
| 247 202 | 
             
            end
         | 
| 248 203 |  | 
| 249 204 | 
             
            describe "dealing with attachments" do
         | 
| @@ -0,0 +1,54 @@ | |
| 1 | 
            +
            require File.dirname(__FILE__) + '/../../spec_helper'
         | 
| 2 | 
            +
            require File.join(FIXTURE_PATH, 'more', 'card')
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            # add a default value
         | 
| 5 | 
            +
            Card.property :bg_color, :default => '#ccc'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class BusinessCard < Card
         | 
| 8 | 
            +
              property :extension_code
         | 
| 9 | 
            +
              property :job_title
         | 
| 10 | 
            +
            end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            class DesignBusinessCard < BusinessCard
         | 
| 13 | 
            +
              property :bg_color, :default => '#eee'
         | 
| 14 | 
            +
            end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
             | 
| 17 | 
            +
            describe "Subclassing an ExtendedDocument" do
         | 
| 18 | 
            +
              
         | 
| 19 | 
            +
              before(:each) do
         | 
| 20 | 
            +
                @card = BusinessCard.new
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
              
         | 
| 23 | 
            +
              it "shouldn't messup the parent's properties" do
         | 
| 24 | 
            +
                Card.properties.should_not == BusinessCard.properties
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
              
         | 
| 27 | 
            +
              it "should share the same db default" do
         | 
| 28 | 
            +
                @card.database.uri.should == Card.database.uri
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
              
         | 
| 31 | 
            +
              it "should share the same autovalidation details" do
         | 
| 32 | 
            +
                @card.auto_validation.should be_true
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
              
         | 
| 35 | 
            +
              it "should have kept the validation details" do
         | 
| 36 | 
            +
                @card.should_not be_valid
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
              
         | 
| 39 | 
            +
              it "should have added the new validation details" do
         | 
| 40 | 
            +
                validated_fields = @card.class.validators.contexts[:default].map{|v| v.field_name}
         | 
| 41 | 
            +
                validated_fields.should include(:extension_code) 
         | 
| 42 | 
            +
                validated_fields.should include(:job_title)
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
              
         | 
| 45 | 
            +
              it "should inherit default property values" do
         | 
| 46 | 
            +
                @card.bg_color.should == '#ccc'
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
              
         | 
| 49 | 
            +
              it "should be able to overwrite a default property" do
         | 
| 50 | 
            +
                DesignBusinessCard.new.bg_color.should == '#eee'
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
              
         | 
| 53 | 
            +
            end
         | 
| 54 | 
            +
             | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification 
         | 
| 2 2 | 
             
            name: jchris-couchrest
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: "0.22"
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors: 
         | 
| 7 7 | 
             
            - J. Chris Anderson
         | 
| @@ -141,15 +141,34 @@ files: | |
| 141 141 | 
             
            - spec/couchrest/more/casted_model_spec.rb
         | 
| 142 142 | 
             
            - spec/couchrest/more/extended_doc_attachment_spec.rb
         | 
| 143 143 | 
             
            - spec/couchrest/more/extended_doc_spec.rb
         | 
| 144 | 
            +
            - spec/couchrest/more/extended_doc_subclass_spec.rb
         | 
| 144 145 | 
             
            - spec/couchrest/more/extended_doc_view_spec.rb
         | 
| 145 146 | 
             
            - spec/couchrest/more/property_spec.rb
         | 
| 146 | 
            -
            - spec/couchrest/support
         | 
| 147 | 
            -
            - spec/couchrest/support/class_spec.rb
         | 
| 148 147 | 
             
            - spec/fixtures
         | 
| 149 148 | 
             
            - spec/fixtures/attachments
         | 
| 150 149 | 
             
            - spec/fixtures/attachments/couchdb.png
         | 
| 151 150 | 
             
            - spec/fixtures/attachments/README
         | 
| 152 151 | 
             
            - spec/fixtures/attachments/test.html
         | 
| 152 | 
            +
            - spec/fixtures/couchapp
         | 
| 153 | 
            +
            - spec/fixtures/couchapp/_attachments
         | 
| 154 | 
            +
            - spec/fixtures/couchapp/_attachments/index.html
         | 
| 155 | 
            +
            - spec/fixtures/couchapp/doc.json
         | 
| 156 | 
            +
            - spec/fixtures/couchapp/foo
         | 
| 157 | 
            +
            - spec/fixtures/couchapp/foo/bar.txt
         | 
| 158 | 
            +
            - spec/fixtures/couchapp/foo/test.json
         | 
| 159 | 
            +
            - spec/fixtures/couchapp/test.json
         | 
| 160 | 
            +
            - spec/fixtures/couchapp/views
         | 
| 161 | 
            +
            - spec/fixtures/couchapp/views/example-map.js
         | 
| 162 | 
            +
            - spec/fixtures/couchapp/views/example-reduce.js
         | 
| 163 | 
            +
            - spec/fixtures/couchapp-test
         | 
| 164 | 
            +
            - spec/fixtures/couchapp-test/my-app
         | 
| 165 | 
            +
            - spec/fixtures/couchapp-test/my-app/_attachments
         | 
| 166 | 
            +
            - spec/fixtures/couchapp-test/my-app/_attachments/index.html
         | 
| 167 | 
            +
            - spec/fixtures/couchapp-test/my-app/foo
         | 
| 168 | 
            +
            - spec/fixtures/couchapp-test/my-app/foo/bar.txt
         | 
| 169 | 
            +
            - spec/fixtures/couchapp-test/my-app/views
         | 
| 170 | 
            +
            - spec/fixtures/couchapp-test/my-app/views/example-map.js
         | 
| 171 | 
            +
            - spec/fixtures/couchapp-test/my-app/views/example-reduce.js
         | 
| 153 172 | 
             
            - spec/fixtures/more
         | 
| 154 173 | 
             
            - spec/fixtures/more/article.rb
         | 
| 155 174 | 
             
            - spec/fixtures/more/card.rb
         | 
| @@ -1,59 +0,0 @@ | |
| 1 | 
            -
            require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
         | 
| 2 | 
            -
            require File.join(File.dirname(__FILE__), '..', '..', '..', 'lib', 'couchrest', 'support', 'class')
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            describe CouchRest::ClassExtension do
         | 
| 5 | 
            -
              
         | 
| 6 | 
            -
              before :all do
         | 
| 7 | 
            -
                class FullyDefinedClassExtensions
         | 
| 8 | 
            -
                  def self.respond_to?(method)
         | 
| 9 | 
            -
                    if CouchRest::ClassExtension::InstanceMethods.instance_methods.include?(method)
         | 
| 10 | 
            -
                      true
         | 
| 11 | 
            -
                    else
         | 
| 12 | 
            -
                      super
         | 
| 13 | 
            -
                    end
         | 
| 14 | 
            -
                  end
         | 
| 15 | 
            -
                end
         | 
| 16 | 
            -
                
         | 
| 17 | 
            -
                class PartDefinedClassExtensions
         | 
| 18 | 
            -
                  def self.respond_to?(method)
         | 
| 19 | 
            -
                    methods = CouchRest::ClassExtension::InstanceMethods.instance_methods
         | 
| 20 | 
            -
                    methods.delete('cattr_reader')
         | 
| 21 | 
            -
                    
         | 
| 22 | 
            -
                    if methods.include?(method)
         | 
| 23 | 
            -
                      false
         | 
| 24 | 
            -
                    else
         | 
| 25 | 
            -
                      super
         | 
| 26 | 
            -
                    end
         | 
| 27 | 
            -
                  end
         | 
| 28 | 
            -
                end
         | 
| 29 | 
            -
                
         | 
| 30 | 
            -
                class NoClassExtensions
         | 
| 31 | 
            -
                  def self.respond_to?(method)
         | 
| 32 | 
            -
                    if CouchRest::ClassExtension::InstanceMethods.instance_methods.include?(method)
         | 
| 33 | 
            -
                      false
         | 
| 34 | 
            -
                    else
         | 
| 35 | 
            -
                      super
         | 
| 36 | 
            -
                    end
         | 
| 37 | 
            -
                  end
         | 
| 38 | 
            -
                end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
              end
         | 
| 42 | 
            -
              
         | 
| 43 | 
            -
              it "should not include InstanceMethods if the class extensions are already defined" do
         | 
| 44 | 
            -
                FullyDefinedClassExtensions.send(:include, CouchRest::ClassExtension)
         | 
| 45 | 
            -
                FullyDefinedClassExtensions.ancestors.should_not include(CouchRest::ClassExtension::InstanceMethods)
         | 
| 46 | 
            -
              end
         | 
| 47 | 
            -
              
         | 
| 48 | 
            -
              it "should raise RuntimeError if the class extensions are only partially defined" do
         | 
| 49 | 
            -
                lambda {
         | 
| 50 | 
            -
                  PartDefinedClassExtensions.send(:include, CouchRest::ClassExtension)
         | 
| 51 | 
            -
                }.should raise_error(RuntimeError)
         | 
| 52 | 
            -
              end
         | 
| 53 | 
            -
              
         | 
| 54 | 
            -
              it "should include class extensions if they are not already defined" do
         | 
| 55 | 
            -
                NoClassExtensions.send(:include, CouchRest::ClassExtension)
         | 
| 56 | 
            -
                NoClassExtensions.ancestors.should include(CouchRest::ClassExtension::InstanceMethods)
         | 
| 57 | 
            -
              end
         | 
| 58 | 
            -
              
         | 
| 59 | 
            -
            end
         |