samlown-couchrest_extended_document 1.0.1 → 1.0.3

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/README.md CHANGED
@@ -11,7 +11,9 @@ Note: CouchRest only supports CouchDB 0.9.0 or newer.
11
11
 
12
12
  ## Usage
13
13
 
14
- require 'couchrest/extended_document'
14
+ ### General
15
+
16
+ require 'couchrest_extended_document'
15
17
 
16
18
  class Cat < CouchRest::ExtendedDocument
17
19
 
@@ -19,6 +21,16 @@ Note: CouchRest only supports CouchDB 0.9.0 or newer.
19
21
 
20
22
  end
21
23
 
24
+ ### Rails
25
+
26
+ In your environment.rb file require the gem as follows:
27
+
28
+ Rails::Initializer.run do |config|
29
+ ....
30
+ config.gem "couchrest_extended_document"
31
+ ....
32
+ end
33
+
22
34
  ## Testing
23
35
 
24
36
  The most complete documentation is the spec/ directory. To validate your
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'rake'
2
2
  require "rake/rdoctask"
3
- require File.join(File.expand_path(File.dirname(__FILE__)),'lib','couchrest','extended_document')
3
+ require File.join(File.expand_path(File.dirname(__FILE__)),'lib','couchrest_extended_document')
4
4
 
5
5
  begin
6
6
  require 'spec/rake/spectask'
data/history.txt CHANGED
@@ -4,11 +4,29 @@
4
4
 
5
5
  * Minor enhancements
6
6
 
7
- == 0.4.0
7
+ == 1.0.3
8
+
9
+ * Minor enhancements
10
+ * Removed Validation by default, requires too many structure changes (FAIL)
11
+ * Added support for instantiation of documents read from database as couchrest-type provided (Sam Lown)
12
+ * Improved attachment handling for detecting file type (Sam Lown)
13
+ * Removing some monkey patches and relying on active_support for constantize and humanize (Sam Lown)
14
+ * Added support for setting type directly on property (Sam Lown)
15
+
16
+
17
+ == 1.0.2
18
+
19
+ * Minor enhancements
20
+ * Enable Validation by default and refactored location (Sam Lown)
21
+
22
+ == 1.0.0
8
23
 
9
24
  * Major enhancements
10
25
  * Separated ExtendedDocument from main CouchRest gem (Sam Lown)
11
26
 
27
+ * Minor enhancements
28
+ * active_support included by default
29
+
12
30
  == 0.37
13
31
 
14
32
  * Minor enhancements
@@ -1,22 +1,14 @@
1
- gem 'samlown-couchrest'
2
- require 'couchrest'
3
- require 'active_support'
4
- require 'mime/types'
5
- require "enumerator"
1
+
6
2
  require File.join(File.dirname(__FILE__), "property")
3
+ require File.join(File.dirname(__FILE__), "validation")
7
4
  require File.join(File.dirname(__FILE__), 'mixins')
8
- require File.join(File.dirname(__FILE__), 'casted_model')
9
-
10
- # Monkey patches
11
- require File.join(File.dirname(__FILE__), 'support', 'couchrest')
12
- require File.join(File.dirname(__FILE__), 'support', 'rails') if defined?(Rails)
13
5
 
14
6
  module CouchRest
15
7
 
16
8
  # Same as CouchRest::Document but with properties and validations
17
9
  class ExtendedDocument < Document
18
10
 
19
- VERSION = "1.0.1"
11
+ VERSION = "1.0.3"
20
12
 
21
13
  include CouchRest::Mixins::Callbacks
22
14
  include CouchRest::Mixins::DocumentQueries
@@ -27,6 +19,9 @@ module CouchRest
27
19
  include CouchRest::Mixins::Collection
28
20
  include CouchRest::Mixins::AttributeProtection
29
21
 
22
+ # Including validation here does not work due to the way inheritance is handled.
23
+ #include CouchRest::Validation
24
+
30
25
  def self.subclasses
31
26
  @subclasses ||= []
32
27
  end
@@ -54,17 +49,19 @@ module CouchRest
54
49
 
55
50
  # Creates a new instance, bypassing attribute protection
56
51
  #
52
+ #
57
53
  # ==== Returns
58
54
  # a document instance
59
- def self.create_from_database(passed_keys={})
60
- new(passed_keys, :directly_set_attributes => true)
55
+ def self.create_from_database(doc = {})
56
+ base = (doc['couchrest-type'].blank? || doc['couchrest-type'] == self.to_s) ? self : doc['couchrest-type'].constantize
57
+ base.new(doc, :directly_set_attributes => true)
61
58
  end
62
59
 
63
- def initialize(passed_keys={}, options={})
60
+ def initialize(doc = {}, options = {})
64
61
  apply_defaults # defined in CouchRest::Mixins::Properties
65
- remove_protected_attributes(passed_keys) unless options[:directly_set_attributes]
66
- directly_set_attributes(passed_keys) unless passed_keys.nil?
67
- super(passed_keys)
62
+ remove_protected_attributes(doc) unless options[:directly_set_attributes]
63
+ directly_set_attributes(doc) unless doc.nil?
64
+ super(doc)
68
65
  cast_keys # defined in CouchRest::Mixins::Properties
69
66
  unless self['_id'] && self['_rev']
70
67
  self['couchrest-type'] = self.class.to_s
@@ -5,7 +5,6 @@ require File.join(mixins_dir, 'properties')
5
5
  require File.join(mixins_dir, 'document_queries')
6
6
  require File.join(mixins_dir, 'views')
7
7
  require File.join(mixins_dir, 'design_doc')
8
- require File.join(mixins_dir, 'validation')
9
8
  require File.join(mixins_dir, 'extended_attachments')
10
9
  require File.join(mixins_dir, 'class_proxy')
11
10
  require File.join(mixins_dir, 'collection')
@@ -2,7 +2,8 @@ module CouchRest
2
2
  module Mixins
3
3
  module ExtendedAttachments
4
4
 
5
- # creates a file attachment to the current doc
5
+ # Add a file attachment to the current document. Expects
6
+ # :file and :name to be included in the arguments.
6
7
  def create_attachment(args={})
7
8
  raise ArgumentError unless args[:file] && args[:name]
8
9
  return if has_attachment?(args[:name])
@@ -52,13 +53,14 @@ module CouchRest
52
53
 
53
54
  private
54
55
 
55
- def get_mime_type(file)
56
- ::MIME::Types.type_for(file.path).empty? ?
57
- 'text\/plain' : MIME::Types.type_for(file.path).first.content_type.gsub(/\//,'\/')
56
+ def get_mime_type(path)
57
+ type = ::MIME::Types.type_for(path)
58
+ type.empty? ? nil : type.first.content_type
58
59
  end
59
60
 
60
61
  def set_attachment_attr(args)
61
- content_type = args[:content_type] ? args[:content_type] : get_mime_type(args[:file])
62
+ content_type = args[:content_type] ? args[:content_type] : get_mime_type(args[:file].path)
63
+ content_type ||= (get_mime_type(args[:name]) || 'text/plain')
62
64
  self['_attachments'][args[:name]] = {
63
65
  'content_type' => content_type,
64
66
  'data' => args[:file].read
@@ -82,10 +82,18 @@ module CouchRest
82
82
 
83
83
  module ClassMethods
84
84
 
85
- def property(name, options={})
85
+ def property(name, *options)
86
+ opts = { }
87
+ type = options.shift
88
+ if type.class != Hash
89
+ opts[:type] = type
90
+ opts.merge!(options.shift || {})
91
+ else
92
+ opts.update(type)
93
+ end
86
94
  existing_property = self.properties.find{|p| p.name == name.to_s}
87
- if existing_property.nil? || (existing_property.default != options[:default])
88
- define_property(name, options)
95
+ if existing_property.nil? || (existing_property.default != opts[:default])
96
+ define_property(name, opts)
89
97
  end
90
98
  end
91
99
 
@@ -26,7 +26,7 @@ module CouchRest
26
26
  base_type = TrueClass
27
27
  else
28
28
  begin
29
- base_type = ::CouchRest.constantize(base_type)
29
+ base_type = base_type.constantize
30
30
  rescue # leave base type as a string and convert in more/typecast
31
31
  end
32
32
  end
@@ -1,43 +1,6 @@
1
1
 
2
2
  module CouchRest
3
3
 
4
-
5
- # The CouchRest module methods handle the basic JSON serialization
6
- # and deserialization, as well as query parameters. The module also includes
7
- # some helpers for tasks like instantiating a new Database or Server instance.
8
- class << self
9
-
10
- # extracted from Extlib
11
- #
12
- # Constantize tries to find a declared constant with the name specified
13
- # in the string. It raises a NameError when the name is not in CamelCase
14
- # or is not initialized.
15
- #
16
- # @example
17
- # "Module".constantize #=> Module
18
- # "Class".constantize #=> Class
19
- def constantize(camel_cased_word)
20
- unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
21
- raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
22
- end
23
-
24
- Object.module_eval("::#{$1}", __FILE__, __LINE__)
25
- end
26
-
27
- # extracted from Extlib
28
- #
29
- # Capitalizes the first word and turns underscores into spaces and strips _id.
30
- # Like titleize, this is meant for creating pretty output.
31
- #
32
- # @example
33
- # "employee_salary" #=> "Employee salary"
34
- # "author_id" #=> "Author"
35
- def humanize(lower_case_and_underscored_word)
36
- lower_case_and_underscored_word.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize
37
- end
38
-
39
- end
40
-
41
4
  class Database
42
5
 
43
6
  alias :delete_old! :delete!
@@ -28,7 +28,7 @@ module CouchRest
28
28
 
29
29
  def typecast_value(value, klass, init_method)
30
30
  return nil if value.nil?
31
- klass = ::CouchRest.constantize(klass) unless klass.is_a?(Class)
31
+ klass = klass.constantize unless klass.is_a?(Class)
32
32
  if value.instance_of?(klass) || klass == Object
33
33
  value
34
34
  elsif [String, TrueClass, Integer, Float, BigDecimal, DateTime, Time, Date, Class].include?(klass)
@@ -164,7 +164,7 @@ module CouchRest
164
164
 
165
165
  # Typecast a value to a Class
166
166
  def typecast_to_class(value)
167
- ::CouchRest.constantize(value.to_s)
167
+ value.to_s.constantize
168
168
  rescue NameError
169
169
  value
170
170
  end
@@ -0,0 +1,245 @@
1
+ # Extracted from dm-validations 0.9.10
2
+ #
3
+ # Copyright (c) 2007 Guy van den Berg
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ class Object
25
+ def validatable?
26
+ false
27
+ end
28
+ end
29
+
30
+ require 'pathname'
31
+
32
+ dir = File.join(Pathname(__FILE__).dirname.expand_path, 'validation')
33
+
34
+ require File.join(dir, 'validation_errors')
35
+ require File.join(dir, 'contextual_validators')
36
+ require File.join(dir, 'auto_validate')
37
+
38
+ require File.join(dir, 'validators', 'generic_validator')
39
+ require File.join(dir, 'validators', 'required_field_validator')
40
+ require File.join(dir, 'validators', 'absent_field_validator')
41
+ require File.join(dir, 'validators', 'format_validator')
42
+ require File.join(dir, 'validators', 'length_validator')
43
+ require File.join(dir, 'validators', 'numeric_validator')
44
+ require File.join(dir, 'validators', 'method_validator')
45
+ require File.join(dir, 'validators', 'confirmation_validator')
46
+
47
+ module CouchRest
48
+ module Validation
49
+
50
+ def self.included(base)
51
+ base.extlib_inheritable_accessor(:auto_validation)
52
+ base.class_eval <<-EOS, __FILE__, __LINE__ + 1
53
+ # Callbacks
54
+ define_callbacks :validate
55
+
56
+ # Turn off auto validation by default
57
+ self.auto_validation ||= false
58
+
59
+ # Force the auto validation for the class properties
60
+ # This feature is still not fully ported over,
61
+ # test are lacking, so please use with caution
62
+ def self.auto_validate!
63
+ self.auto_validation = true
64
+ end
65
+
66
+ # share the validations with subclasses
67
+ def self.inherited(subklass)
68
+ self.validators.contexts.each do |k, v|
69
+ subklass.validators.contexts[k] = v.dup
70
+ end
71
+ super
72
+ end
73
+ EOS
74
+
75
+ base.extend(ClassMethods)
76
+ base.class_eval <<-EOS, __FILE__, __LINE__ + 1
77
+ define_callbacks :validate
78
+ if method_defined?(:_run_save_callbacks)
79
+ set_callback :save, :before, :check_validations
80
+ end
81
+ EOS
82
+ base.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
83
+ def self.define_property(name, options={})
84
+ super
85
+ auto_generate_validations(properties.last) if properties && properties.size > 0
86
+ autovalidation_check = true
87
+ end
88
+ RUBY_EVAL
89
+ end
90
+
91
+ # Ensures the object is valid for the context provided, and otherwise
92
+ # throws :halt and returns false.
93
+ #
94
+ def check_validations(context = :default)
95
+ throw(:halt, false) unless context.nil? || valid?(context)
96
+ end
97
+
98
+ # Return the ValidationErrors
99
+ #
100
+ def errors
101
+ @errors ||= ValidationErrors.new
102
+ end
103
+
104
+ # Mark this resource as validatable. When we validate associations of a
105
+ # resource we can check if they respond to validatable? before trying to
106
+ # recursivly validate them
107
+ #
108
+ def validatable?
109
+ true
110
+ end
111
+
112
+ # Alias for valid?(:default)
113
+ #
114
+ def valid_for_default?
115
+ valid?(:default)
116
+ end
117
+
118
+ # Check if a resource is valid in a given context
119
+ #
120
+ def valid?(context = :default)
121
+ recursive_valid?(self, context, true)
122
+ end
123
+
124
+ # checking on casted objects
125
+ def validate_casted_arrays
126
+ result = true
127
+ array_casted_properties = self.class.properties.select { |property| property.casted && property.type.instance_of?(Array) }
128
+ array_casted_properties.each do |property|
129
+ casted_values = self.send(property.name)
130
+ next unless casted_values.is_a?(Array) && casted_values.first.respond_to?(:valid?)
131
+ casted_values.each do |value|
132
+ result = (result && value.valid?) if value.respond_to?(:valid?)
133
+ end
134
+ end
135
+ result
136
+ end
137
+
138
+ # Do recursive validity checking
139
+ #
140
+ def recursive_valid?(target, context, state)
141
+ valid = state
142
+ target.each do |key, prop|
143
+ if prop.is_a?(Array)
144
+ prop.each do |item|
145
+ if item.validatable?
146
+ valid = recursive_valid?(item, context, valid) && valid
147
+ end
148
+ end
149
+ elsif prop.validatable?
150
+ valid = recursive_valid?(prop, context, valid) && valid
151
+ end
152
+ end
153
+ target._run_validate_callbacks do
154
+ target.class.validators.execute(context, target) && valid
155
+ end
156
+ end
157
+
158
+
159
+ def validation_property_value(name)
160
+ self.respond_to?(name, true) ? self.send(name) : nil
161
+ end
162
+
163
+ # Get the corresponding Object property, if it exists.
164
+ def validation_property(field_name)
165
+ properties.find{|p| p.name == field_name}
166
+ end
167
+
168
+ module ClassMethods
169
+ include CouchRest::Validation::ValidatesPresent
170
+ include CouchRest::Validation::ValidatesAbsent
171
+ include CouchRest::Validation::ValidatesIsConfirmed
172
+ # include CouchRest::Validation::ValidatesIsPrimitive
173
+ # include CouchRest::Validation::ValidatesIsAccepted
174
+ include CouchRest::Validation::ValidatesFormat
175
+ include CouchRest::Validation::ValidatesLength
176
+ # include CouchRest::Validation::ValidatesWithin
177
+ include CouchRest::Validation::ValidatesIsNumber
178
+ include CouchRest::Validation::ValidatesWithMethod
179
+ # include CouchRest::Validation::ValidatesWithBlock
180
+ # include CouchRest::Validation::ValidatesIsUnique
181
+ include CouchRest::Validation::AutoValidate
182
+
183
+ # Return the set of contextual validators or create a new one
184
+ #
185
+ def validators
186
+ @validations ||= ContextualValidators.new
187
+ end
188
+
189
+ # Clean up the argument list and return a opts hash, including the
190
+ # merging of any default opts. Set the context to default if none is
191
+ # provided. Also allow :context to be aliased to :on, :when & group
192
+ #
193
+ def opts_from_validator_args(args, defaults = nil)
194
+ opts = args.last.kind_of?(Hash) ? args.pop : {}
195
+ context = :default
196
+ context = opts[:context] if opts.has_key?(:context)
197
+ context = opts.delete(:on) if opts.has_key?(:on)
198
+ context = opts.delete(:when) if opts.has_key?(:when)
199
+ context = opts.delete(:group) if opts.has_key?(:group)
200
+ opts[:context] = context
201
+ opts.merge!(defaults) unless defaults.nil?
202
+ opts
203
+ end
204
+
205
+ # Given a new context create an instance method of
206
+ # valid_for_<context>? which simply calls valid?(context)
207
+ # if it does not already exist
208
+ #
209
+ def create_context_instance_methods(context)
210
+ name = "valid_for_#{context.to_s}?" # valid_for_signup?
211
+ if !self.instance_methods.include?(name)
212
+ class_eval <<-EOS, __FILE__, __LINE__ + 1
213
+ def #{name} # def valid_for_signup?
214
+ valid?('#{context.to_s}'.to_sym) # valid?('signup'.to_sym)
215
+ end # end
216
+ EOS
217
+ end
218
+ end
219
+
220
+ # Create a new validator of the given klazz and push it onto the
221
+ # requested context for each of the attributes in the fields list
222
+ #
223
+ def add_validator_to_context(opts, fields, klazz)
224
+ fields.each do |field|
225
+ validator = klazz.new(field.to_sym, opts)
226
+ if opts[:context].is_a?(Symbol)
227
+ unless validators.context(opts[:context]).include?(validator)
228
+ validators.context(opts[:context]) << validator
229
+ create_context_instance_methods(opts[:context])
230
+ end
231
+ elsif opts[:context].is_a?(Array)
232
+ opts[:context].each do |c|
233
+ unless validators.context(c).include?(validator)
234
+ validators.context(c) << validator
235
+ create_context_instance_methods(c)
236
+ end
237
+ end
238
+ end
239
+ end
240
+ end
241
+
242
+ end # module ClassMethods
243
+ end # module Validation
244
+
245
+ end # module CouchRest
@@ -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 = CouchRest.humanize(field)
63
+ field = field.to_s.humanize
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 = CouchRest.humanize(field_name)
67
+ field = field_name.to_s.humanize
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 = CouchRest.humanize(field_name)
57
+ field = field_name.to_s.humanize
58
58
  min = @range ? @range.min : @min
59
59
  max = @range ? @range.max : @max
60
60
  equal = @equal
@@ -0,0 +1,21 @@
1
+
2
+ # require File.join(File.dirname(__FILE__), "couchrest", "extended_document")
3
+
4
+ gem 'samlown-couchrest'
5
+
6
+ require 'couchrest'
7
+
8
+ require 'active_support'
9
+ require 'mime/types'
10
+ require "enumerator"
11
+
12
+ # Monkey patches applied to couchrest
13
+ require File.join(File.dirname(__FILE__), 'couchrest', 'support', 'couchrest')
14
+
15
+ # Base libraries
16
+ require File.join(File.dirname(__FILE__), 'couchrest', 'extended_document')
17
+ require File.join(File.dirname(__FILE__), 'couchrest', 'casted_model')
18
+
19
+ # Add rails support *after* everything has loaded
20
+ require File.join(File.dirname(__FILE__), 'couchrest', 'support', 'rails') if defined?(Rails)
21
+
@@ -68,6 +68,19 @@ describe "ExtendedDocument attachments" do
68
68
  @obj.create_attachment(:file => @file_ext, :name => @attachment_name, :content_type => @content_type)
69
69
  @obj['_attachments'][@attachment_name]['content_type'].should == @content_type
70
70
  end
71
+
72
+ it "should detect the content-type automatically" do
73
+ @obj.create_attachment(:file => File.open(FIXTURE_PATH + '/attachments/couchdb.png'), :name => "couchdb.png")
74
+ @obj['_attachments']['couchdb.png']['content_type'].should == "image/png"
75
+ end
76
+
77
+ it "should use name to detect the content-type automatically if no file" do
78
+ file = File.open(FIXTURE_PATH + '/attachments/couchdb.png')
79
+ file.stub!(:path).and_return("badfilname")
80
+ @obj.create_attachment(:file => File.open(FIXTURE_PATH + '/attachments/couchdb.png'), :name => "couchdb.png")
81
+ @obj['_attachments']['couchdb.png']['content_type'].should == "image/png"
82
+ end
83
+
71
84
  end
72
85
 
73
86
  describe 'reading, updating, and deleting an attachment' do
@@ -96,7 +109,7 @@ describe "ExtendedDocument attachments" do
96
109
  reloaded_obj.read_attachment(@attachment_name).should == file.read
97
110
  end
98
111
 
99
- it 'should se the content-type if passed' do
112
+ it 'should set the content-type if passed' do
100
113
  file = File.open(FIXTURE_PATH + '/attachments/README')
101
114
  @file.should_not == file
102
115
  @obj.update_attachment(:file => file, :name => @attachment_name, :content_type => @content_type)
@@ -18,6 +18,14 @@ describe "ExtendedDocument" do
18
18
  property :name
19
19
  timestamps!
20
20
  end
21
+
22
+ class WithSimplePropertyType < CouchRest::ExtendedDocument
23
+ use_database TEST_SERVER.default_database
24
+ property :name, String
25
+ property :preset, String, :default => 'none'
26
+ property :tags, [String]
27
+ timestamps!
28
+ end
21
29
 
22
30
  class WithCallBacks < CouchRest::ExtendedDocument
23
31
  include ::CouchRest::Validation
@@ -164,6 +172,25 @@ describe "ExtendedDocument" do
164
172
  doc.run_after_save.should be_true
165
173
  end
166
174
  end
175
+
176
+ describe "creating a new document from database" do
177
+
178
+ it "should instantialize" do
179
+ doc = Article.create_from_database({'_id' => 'testitem1', '_rev' => 123, 'couchrest-type' => 'Article', 'name' => 'my test'})
180
+ doc.class.should eql(Article)
181
+ end
182
+
183
+ it "should instantialize of same class if no couchrest-type included from DB" do
184
+ doc = Article.create_from_database({'_id' => 'testitem1', '_rev' => 123, 'name' => 'my test'})
185
+ doc.class.should eql(Article)
186
+ end
187
+
188
+ it "should instantialize document of different type" do
189
+ doc = Article.create_from_database({'_id' => 'testitem2', '_rev' => 123, 'couchrest-type' => 'WithCallBacks', 'name' => 'my test'})
190
+ doc.class.should eql(WithCallBacks)
191
+ end
192
+
193
+ end
167
194
 
168
195
  describe "update attributes without saving" do
169
196
  before(:each) do
@@ -258,6 +285,18 @@ describe "ExtendedDocument" do
258
285
  obj.read_only_with_default.should == 'generic'
259
286
  end
260
287
  end
288
+
289
+ describe "simplified way of setting property types" do
290
+ it "should set defaults" do
291
+ obj = WithSimplePropertyType.new
292
+ obj.preset.should eql('none')
293
+ end
294
+
295
+ it "should handle arrays" do
296
+ obj = WithSimplePropertyType.new(:tags => ['spec'])
297
+ obj.tags.should == ['spec']
298
+ end
299
+ end
261
300
 
262
301
  describe "a doc with template values (CR::Model spec)" do
263
302
  before(:all) do
@@ -15,8 +15,8 @@ class Cat < CouchRest::ExtendedDocument
15
15
  use_database DB
16
16
 
17
17
  property :name, :accessible => true
18
- property :toys, :cast_as => [CatToy], :default => [], :accessible => true
19
- property :favorite_toy, :cast_as => CatToy, :accessible => true
18
+ property :toys, [CatToy], :default => [], :accessible => true
19
+ property :favorite_toy, CatToy, :accessible => true
20
20
  property :number
21
21
  end
22
22
 
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require "rubygems"
2
2
  require "spec" # Satisfies Autotest and anyone else not using the Rake tasks
3
3
 
4
- require File.join(File.dirname(__FILE__), '..','lib','couchrest','extended_document')
4
+ require File.join(File.dirname(__FILE__), '..','lib','couchrest_extended_document')
5
5
  # check the following file to see how to use the spec'd features.
6
6
 
7
7
  unless defined?(FIXTURE_PATH)
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 1
7
7
  - 0
8
- - 1
9
- version: 1.0.1
8
+ - 3
9
+ version: 1.0.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - J. Chris Anderson
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2010-05-10 00:00:00 +02:00
20
+ date: 2010-05-13 00:00:00 +02:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
@@ -96,6 +96,7 @@ files:
96
96
  - lib/couchrest/support/couchrest.rb
97
97
  - lib/couchrest/support/rails.rb
98
98
  - lib/couchrest/typecast.rb
99
+ - lib/couchrest/validation.rb
99
100
  - lib/couchrest/validation/auto_validate.rb
100
101
  - lib/couchrest/validation/contextual_validators.rb
101
102
  - lib/couchrest/validation/validation_errors.rb
@@ -109,6 +110,7 @@ files:
109
110
  - lib/couchrest/validation/validators/method_validator.rb
110
111
  - lib/couchrest/validation/validators/numeric_validator.rb
111
112
  - lib/couchrest/validation/validators/required_field_validator.rb
113
+ - lib/couchrest_extended_document.rb
112
114
  - spec/couchrest/attribute_protection_spec.rb
113
115
  - spec/couchrest/casted_extended_doc_spec.rb
114
116
  - spec/couchrest/casted_model_spec.rb