mongo_mapper 0.9.0 → 0.9.1

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.
@@ -39,6 +39,6 @@ module MongoMapper
39
39
  end
40
40
  end
41
41
 
42
- class Boolean
43
- extend MongoMapper::Extensions::Boolean
44
- end
42
+ class Boolean; end unless defined?(Boolean)
43
+
44
+ Boolean.extend MongoMapper::Extensions::Boolean
@@ -27,4 +27,6 @@ class BSON::ObjectId
27
27
  def to_json(options = nil)
28
28
  as_json.to_json
29
29
  end
30
+
31
+ alias to_str to_s
30
32
  end
@@ -3,18 +3,14 @@ module MongoMapper
3
3
  module Accessible
4
4
  extend ActiveSupport::Concern
5
5
 
6
+ included do
7
+ class_attribute :accessible_attributes
8
+ end
9
+
6
10
  module ClassMethods
7
11
  def attr_accessible(*attrs)
8
12
  raise AccessibleOrProtected.new(name) if try(:protected_attributes?)
9
- self.write_inheritable_attribute(:attr_accessible, Set.new(attrs) + (accessible_attributes || []))
10
- end
11
-
12
- def accessible_attributes?
13
- !accessible_attributes.nil?
14
- end
15
-
16
- def accessible_attributes
17
- self.read_inheritable_attribute(:attr_accessible)
13
+ self.accessible_attributes = Set.new(attrs) + (accessible_attributes || [])
18
14
  end
19
15
  end
20
16
 
@@ -31,10 +27,6 @@ module MongoMapper
31
27
  super(filter_inaccessible_attrs(attrs))
32
28
  end
33
29
 
34
- def accessible_attributes
35
- self.class.accessible_attributes
36
- end
37
-
38
30
  protected
39
31
  def filter_inaccessible_attrs(attrs)
40
32
  return attrs if accessible_attributes.blank? || attrs.blank?
@@ -98,11 +98,6 @@ module MongoMapper
98
98
  end
99
99
  end
100
100
 
101
- def ===(other)
102
- load_target
103
- other === target
104
- end
105
-
106
101
  protected
107
102
  def method_missing(method, *args, &block)
108
103
  if load_target
@@ -53,15 +53,15 @@ module MongoMapper
53
53
  key = key.to_s
54
54
  old = read_key(key)
55
55
  attribute_will_change!(key) if attribute_should_change?(key, old, value)
56
- changed_attributes.delete(key) unless value_changed?(key, attribute_was(key), value)
56
+ changed_attributes.delete(key) unless attribute_value_changed?(key, attribute_was(key), value)
57
57
  super(key, value)
58
58
  end
59
59
 
60
60
  def attribute_should_change?(key, old, value)
61
- attribute_changed?(key) == false && value_changed?(key, old, value)
61
+ attribute_changed?(key) == false && attribute_value_changed?(key, old, value)
62
62
  end
63
63
 
64
- def value_changed?(key_name, old, value)
64
+ def attribute_value_changed?(key_name, old, value)
65
65
  value = nil if keys[key_name.to_s].number? && value.blank?
66
66
  old != value
67
67
  end
@@ -4,6 +4,12 @@ module MongoMapper
4
4
  module Equality
5
5
  extend ActiveSupport::Concern
6
6
 
7
+ module ClassMethods
8
+ def ===(other)
9
+ other.is_a?(self)
10
+ end
11
+ end
12
+
7
13
  module InstanceMethods
8
14
  def eql?(other)
9
15
  other.is_a?(self.class) && _id == other._id
@@ -16,4 +22,4 @@ module MongoMapper
16
22
  end
17
23
  end
18
24
  end
19
- end
25
+ end
@@ -8,7 +8,7 @@ module MongoMapper
8
8
 
9
9
  included do
10
10
  extend ActiveSupport::DescendantsTracker
11
- key :_id, ObjectId
11
+ key :_id, ObjectId, :default => lambda { BSON::ObjectId.new }
12
12
  end
13
13
 
14
14
  module ClassMethods
@@ -269,6 +269,11 @@ module MongoMapper
269
269
  def default_id_value(attrs={})
270
270
  id_provided = !attrs.nil? && attrs.keys.map { |k| k.to_s }.detect { |k| k == 'id' || k == '_id' }
271
271
  if !id_provided && self.class.can_default_id?
272
+ unless keys['_id'].default_value
273
+ warn "[DEPRECATED] Custom IDs will no longer be automatically populated. If you definte your own :_id key, set a default:\n key :_id, String, :default => lambda { BSON::ObjectId.new }"
274
+ warn caller.grep(/test/).join("\n")
275
+ end
276
+
272
277
  write_key :_id, BSON::ObjectId.new
273
278
  end
274
279
  end
@@ -95,10 +95,18 @@ module MongoMapper
95
95
  def push(hash)
96
96
  self.class.push(id, hash)
97
97
  end
98
+
99
+ def push_all(hash)
100
+ self.class.push_all(id, hash)
101
+ end
98
102
 
99
103
  def pull(hash)
100
104
  self.class.pull(id, hash)
101
105
  end
106
+
107
+ def pull_all(hash)
108
+ self.class.pull_all(id, hash)
109
+ end
102
110
 
103
111
  def add_to_set(hash)
104
112
  self.class.push_uniq(id, hash)
@@ -6,18 +6,14 @@ module MongoMapper
6
6
  module Protected
7
7
  extend ActiveSupport::Concern
8
8
 
9
+ included do
10
+ class_attribute :protected_attributes
11
+ end
12
+
9
13
  module ClassMethods
10
14
  def attr_protected(*attrs)
11
15
  raise AccessibleOrProtected.new(name) if try(:accessible_attributes?)
12
- self.write_inheritable_attribute(:attr_protected, Set.new(attrs) + (protected_attributes || []))
13
- end
14
-
15
- def protected_attributes
16
- self.read_inheritable_attribute(:attr_protected)
17
- end
18
-
19
- def protected_attributes?
20
- !protected_attributes.nil?
16
+ self.protected_attributes = Set.new(attrs) + (protected_attributes || [])
21
17
  end
22
18
 
23
19
  def key(*args)
@@ -40,10 +36,6 @@ module MongoMapper
40
36
  super(filter_protected_attrs(attrs))
41
37
  end
42
38
 
43
- def protected_attributes
44
- self.class.protected_attributes
45
- end
46
-
47
39
  protected
48
40
  def filter_protected_attrs(attrs)
49
41
  return attrs if protected_attributes.blank? || attrs.blank?
@@ -11,7 +11,7 @@ module MongoMapper
11
11
  include PluckyMethods
12
12
 
13
13
  def find_each(opts={})
14
- super(opts).each { |doc| yield load(doc) }
14
+ super(opts).each { |doc| yield(doc) }
15
15
  end
16
16
 
17
17
  def find_by_id(id)
@@ -61,12 +61,12 @@ module MongoMapper
61
61
 
62
62
  # @api private for now
63
63
  def query(options={})
64
- Plucky::Query.new(collection).tap do |query|
65
- query.extend(Decorator)
66
- query.object_ids(object_id_keys)
67
- query.update(options)
68
- query.model(self)
69
- end
64
+ query = Plucky::Query.new(collection, :transformer => transformer)
65
+ query.extend(Decorator)
66
+ query.object_ids(object_id_keys)
67
+ query.update(options)
68
+ query.model(self)
69
+ query
70
70
  end
71
71
 
72
72
  # @api private for now
@@ -75,6 +75,10 @@ module MongoMapper
75
75
  end
76
76
 
77
77
  private
78
+ def transformer
79
+ @transformer ||= lambda { |doc| load(doc) }
80
+ end
81
+
78
82
  def find_some(ids, options={})
79
83
  query = query(options).update(:_id => ids.flatten.compact.uniq)
80
84
  find_many(query.to_hash).compact
@@ -21,18 +21,6 @@ module MongoMapper
21
21
  end
22
22
  end
23
23
 
24
- def all(opts={})
25
- super.map { |doc| model.load(doc) }
26
- end
27
-
28
- def first(opts={})
29
- model.load(super)
30
- end
31
-
32
- def last(opts={})
33
- model.load(super)
34
- end
35
-
36
24
  private
37
25
  def method_missing(method, *args, &block)
38
26
  return super unless model.respond_to?(method)
@@ -39,18 +39,14 @@ module MongoMapper
39
39
  one(*args)
40
40
  end
41
41
 
42
- def has_many(*args)
43
- many(*args)
42
+ def has_many(*args, &extension)
43
+ many(*args, &extension)
44
44
  end
45
45
 
46
46
  def column_names
47
47
  keys.keys
48
48
  end
49
-
50
- def human_name
51
- self.name.demodulize.titleize
52
- end
53
49
  end
54
50
  end
55
51
  end
56
- end
52
+ end
@@ -4,6 +4,10 @@ module MongoMapper
4
4
  module Scopes
5
5
  extend ActiveSupport::Concern
6
6
 
7
+ included do
8
+ class_attribute :_scopes
9
+ end
10
+
7
11
  module ClassMethods
8
12
  def scope(name, scope_options={})
9
13
  scopes[name] = lambda do |*args|
@@ -15,7 +19,7 @@ module MongoMapper
15
19
  end
16
20
 
17
21
  def scopes
18
- read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
22
+ self._scopes || self._scopes = {}
19
23
  end
20
24
  end
21
25
  end
@@ -57,6 +57,10 @@ module MongoMapper
57
57
  hash
58
58
  end
59
59
 
60
+ def to_xml(options = {}, &block)
61
+ XmlSerializer.new(self, options).serialize(&block)
62
+ end
63
+
60
64
  private
61
65
 
62
66
  def serializable_add_includes(options = {})
@@ -91,7 +95,13 @@ module MongoMapper
91
95
  self.new.from_xml(xml)
92
96
  end
93
97
  end
98
+ end
94
99
 
100
+ # Override default Serializer to use #serializable_hash
101
+ class XmlSerializer < ::ActiveModel::Serializers::Xml::Serializer
102
+ def attributes_hash
103
+ @serializable.serializable_hash(options)
104
+ end
95
105
  end
96
106
  end
97
107
  end
@@ -56,7 +56,7 @@ module MongoMapper
56
56
  class AssociatedValidator < ::ActiveModel::EachValidator
57
57
  def validate_each(record, attribute, value)
58
58
  if !Array.wrap(value).all? { |c| c.nil? || c.valid? }
59
- record.errors.add(attribute, :invalid, :default => options[:message], :value => value)
59
+ record.errors.add(attribute, :invalid, :message => options[:message], :value => value)
60
60
  end
61
61
  end
62
62
  end
@@ -1,4 +1,4 @@
1
1
  # encoding: UTF-8
2
2
  module MongoMapper
3
- Version = '0.9.0'
3
+ Version = '0.9.1'
4
4
  end
@@ -99,6 +99,13 @@ class DirtyTest < Test::Unit::TestCase
99
99
  should "be false if no keys changed" do
100
100
  @document.new.changed?.should be_false
101
101
  end
102
+
103
+ should "not raise when key name is 'value'" do
104
+ @document.key :value, Integer
105
+
106
+ doc = @document.new
107
+ doc.value_changed?.should be_false
108
+ end
102
109
  end
103
110
 
104
111
  context "changes" do
@@ -0,0 +1,20 @@
1
+ require 'test_helper'
2
+
3
+ class EqualityTest < Test::Unit::TestCase
4
+ context "Case equality" do
5
+ setup do
6
+ @person = Doc()
7
+ @address = Doc()
8
+
9
+ @person.one :address, :class => @address, :foreign_key => :person_id
10
+ @address.belongs_to :person, :class => @person
11
+ end
12
+
13
+ should "work with proxies" do
14
+ person = @person.create!
15
+ address = @address.create!(:person => person)
16
+ @person.should === address.person
17
+ @address.should === person.address
18
+ end
19
+ end
20
+ end
@@ -368,6 +368,14 @@ class ModifierTest < Test::Unit::TestCase
368
368
  page.reload
369
369
  page.tags.should == %w(foo)
370
370
  end
371
+
372
+ should "be able to push_all with modifier hashes" do
373
+ page = @page_class.create
374
+ page.push_all(:tags => %w(foo bar))
375
+
376
+ page.reload
377
+ page.tags.should == %w(foo bar)
378
+ end
371
379
 
372
380
  should "be able to pull with criteria and modifier hashes" do
373
381
  page = @page_class.create(:tags => %w(foo bar))
@@ -376,6 +384,14 @@ class ModifierTest < Test::Unit::TestCase
376
384
  page.reload
377
385
  page.tags.should == %w(bar)
378
386
  end
387
+
388
+ should "be able to pull_all with criteria and modifier hashes" do
389
+ page = @page_class.create(:tags => %w(foo bar baz))
390
+ page.pull_all(:tags => %w(foo bar))
391
+
392
+ page.reload
393
+ page.tags.should == %w(baz)
394
+ end
379
395
 
380
396
  should "be able to add_to_set with criteria and modifier hash" do
381
397
  page = @page_class.create(:tags => 'foo')
@@ -23,7 +23,7 @@ class StringIdCompatibilityTest < Test::Unit::TestCase
23
23
  end
24
24
 
25
25
  should "assign correct _id for documents" do
26
- project = @project_class.create
26
+ project = silence_stderr { @project_class.create }
27
27
  project._id.should == project.id
28
28
  project._id.should be_instance_of(String)
29
29
  project.id.size.should == 24
@@ -33,35 +33,43 @@ class StringIdCompatibilityTest < Test::Unit::TestCase
33
33
  end
34
34
 
35
35
  should "assign correct _id for embedded documents" do
36
- note = @note_class.new
37
- note.id.should == note._id
38
- note.id.size.should == 24
36
+ silence_stderr do
37
+ note = @note_class.new
38
+ note.id.should == note._id
39
+ note.id.size.should == 24
40
+ end
39
41
  end
40
42
 
41
43
  should "find records" do
42
- project = @project_class.create
43
- @project_class.find(project.id).should == project
44
+ silence_stderr do
45
+ project = @project_class.create
46
+ @project_class.find(project.id).should == project
47
+ end
44
48
  end
45
49
 
46
50
  should "save embedded docs" do
47
- n1 = @note_class.new
48
- n2 = @note_class.new
49
- n3 = @note_class.new
50
- project = @project_class.create(:notes => [n1, n2, n3])
51
+ silence_stderr do
52
+ n1 = @note_class.new
53
+ n2 = @note_class.new
54
+ n3 = @note_class.new
55
+ project = @project_class.create(:notes => [n1, n2, n3])
51
56
 
52
- project = project.reload
53
- project.notes.size.should == 3
54
- project.notes.should == [n1, n2, n3]
57
+ project = project.reload
58
+ project.notes.size.should == 3
59
+ project.notes.should == [n1, n2, n3]
60
+ end
55
61
  end
56
62
 
57
63
  should "be able to associate records" do
58
- t1 = @task_class.new(:body => 'First task', :position => 1)
59
- t2 = @task_class.new(:body => 'Second task', :position => 2)
60
- t3 = @task_class.new(:body => 'Third task', :position => 3)
61
- project = @project_class.create(:name => 'MM', :tasks => [t1, t2, t3])
64
+ silence_stderr do
65
+ t1 = @task_class.new(:body => 'First task', :position => 1)
66
+ t2 = @task_class.new(:body => 'Second task', :position => 2)
67
+ t3 = @task_class.new(:body => 'Third task', :position => 3)
68
+ project = @project_class.create(:name => 'MM', :tasks => [t1, t2, t3])
62
69
 
63
- project = project.reload
64
- project.tasks.count.should == 3
65
- project.tasks.should == [t1, t2, t3]
70
+ project = project.reload
71
+ project.tasks.count.should == 3
72
+ project.tasks.should == [t1, t2, t3]
73
+ end
66
74
  end
67
75
  end
@@ -323,6 +323,34 @@ class ValidationsTest < Test::Unit::TestCase
323
323
  end
324
324
  end
325
325
 
326
+ context "validating associated docs" do
327
+ setup do
328
+ @child_class = EDoc do
329
+ key :name, :required => true
330
+ end
331
+
332
+ @root_class = Doc { }
333
+ @root_class.many :children, :class => @child_class
334
+ @root_class.validates_associated :children, :message => 'are invalid'
335
+ end
336
+
337
+ should "pass if there are no associated docs" do
338
+ doc = @root_class.new
339
+ doc.save.should be_true
340
+ end
341
+
342
+ should "pass if the associated doc is valid" do
343
+ doc = @root_class.new
344
+ doc.children.build(:name => 'Joe')
345
+ doc.save.should be_true
346
+ end
347
+
348
+ should "fail if the associated doc is invalid" do
349
+ doc = @root_class.new
350
+ doc.children.build
351
+ doc.should have_error_on(:children, 'are invalid')
352
+ end
353
+ end
326
354
  # context "validates uniqueness of with :unique shortcut" do
327
355
  # should "work" do
328
356
  # @document = Doc do
@@ -28,11 +28,6 @@ class ProxyTest < Test::Unit::TestCase
28
28
  @blank_proxy = FakeBlankProxy.new(@owner, @association)
29
29
  end
30
30
 
31
- should 'return true for === target' do
32
- @proxy = FakeProxy.new(@owner, @association)
33
- @proxy.should === Array
34
- end
35
-
36
31
  should "set target to nil when reset is called" do
37
32
  @proxy.reset
38
33
  @proxy.target.should be_nil
@@ -102,4 +97,4 @@ class ProxyTest < Test::Unit::TestCase
102
97
  lambda { @proxy.send(:gsub) }.should raise_error
103
98
  end
104
99
  end
105
- end
100
+ end
@@ -0,0 +1,193 @@
1
+ require 'test_helper'
2
+
3
+ class XmlSerializationTest < Test::Unit::TestCase
4
+ class Tag
5
+ include MongoMapper::EmbeddedDocument
6
+ key :name, String
7
+ end
8
+
9
+ class Contact
10
+ include MongoMapper::Document
11
+ key :name, String
12
+ key :age, Integer
13
+ key :created_at, Time
14
+ key :awesome, Boolean
15
+ key :preferences, Hash
16
+
17
+ many :tags, :class_name => 'XmlSerializationTest::Tag'
18
+ end
19
+
20
+ def setup
21
+ Kernel.const_set('TopLevelContact', Doc('TopLevelContact'))
22
+ TopLevelContact.key :name, String
23
+
24
+ Contact.include_root_in_json = false
25
+ @contact = Contact.new(
26
+ :name => 'Konata Izumi',
27
+ :age => 16,
28
+ :created_at => Time.utc(2006, 8, 1),
29
+ :awesome => true,
30
+ :preferences => { :shows => 'anime' }
31
+ )
32
+ @top_level_contact = TopLevelContact.new(
33
+ :name => 'Konata Izumi'
34
+ )
35
+ end
36
+
37
+ def teardown
38
+ Kernel.send(:remove_const, 'TopLevelContact') if Object.const_defined?('TopLevelContact')
39
+ end
40
+
41
+ should "include root for class with no module" do
42
+ assert_match %r{<top-level-contact>}, @top_level_contact.to_xml
43
+ end
44
+
45
+ should "include demodulized root" do
46
+ assert_match %r{<contact>}, @contact.to_xml
47
+ end
48
+
49
+ should "encode all encodable attributes" do
50
+ xml = @contact.to_xml
51
+
52
+ assert_no_match %r{_id}, xml
53
+ assert_match %r{<id>#{@contact.id}</id>}, xml
54
+ assert_match %r{<name>Konata Izumi</name>}, xml
55
+ assert_match %r{<age.*>16</age>}, xml
56
+ assert_match %r(<created-at type="datetime">), xml
57
+ assert_match %r{<awesome type="boolean">true</awesome>}, xml
58
+ assert_match %r{<preferences>}, xml
59
+ assert_match %r{<shows>anime</shows>}, xml
60
+ end
61
+
62
+ should "allow attribute filtering with only" do
63
+ xml = @contact.to_xml(:only => [:name, :age])
64
+
65
+ assert_no_match %r{<id>}, xml
66
+ assert_match %r{<name>Konata Izumi</name>}, xml
67
+ assert_match %r{<age type="integer">16</age>}, xml
68
+ assert_no_match %r{awesome}, xml
69
+ assert_no_match %r{created-at}, xml
70
+ assert_no_match %r{preferences}, xml
71
+ end
72
+
73
+ should "allow attribute filtering with except" do
74
+ xml = @contact.to_xml(:except => [:name, :age])
75
+
76
+ assert_no_match %r{<name>Konata Izumi</name>}, xml
77
+ assert_no_match %r{<age type="integer">16</age>}, xml
78
+ assert_match %r{<id>}, xml
79
+ assert_match %r{awesome}, xml
80
+ assert_match %r{created-at}, xml
81
+ assert_match %r{preferences}, xml
82
+ end
83
+
84
+ context "_id key" do
85
+ should "not be included by default" do
86
+ assert_no_match %r{_id}, @contact.to_xml
87
+ end
88
+
89
+ should "not be included even if :except is used" do
90
+ assert_no_match %r{_id}, @contact.to_xml(:except => :name)
91
+ end
92
+ end
93
+
94
+ context "id method" do
95
+ setup do
96
+ def @contact.label; "Has cheezburger"; end
97
+ def @contact.favorite_quote; "Constraints are liberating"; end
98
+ end
99
+
100
+ should "be included by default" do
101
+ assert_match %r{<id>#{@contact.id}</id>}, @contact.to_xml
102
+ end
103
+
104
+ should "be included when single method included" do
105
+ xml = @contact.to_xml(:methods => :label)
106
+ assert_match %r{<id>}, xml
107
+ assert_match %r{<label>Has cheezburger</label>}, xml
108
+ assert_match %r{<name>Konata Izumi</name>}, xml
109
+ assert_no_match %r{favorite_quote}, xml
110
+ end
111
+
112
+ should "be included when multiple methods included" do
113
+ xml = @contact.to_xml(:methods => [:label, :favorite_quote])
114
+ assert_match %r{<id>}, xml
115
+ assert_match %r{<label>Has cheezburger</label>}, xml
116
+ assert_match %r{<name>Konata Izumi</name>}, xml
117
+ assert_match %r{<favorite-quote>Constraints are liberating</favorite-quote>}, xml
118
+ end
119
+
120
+ should "not be included if :only is present" do
121
+ assert_no_match %r{<id}, @contact.to_xml(:only => :name)
122
+ end
123
+
124
+ should "be represented by a string" do
125
+ assert_match %r{<id>}, @contact.to_xml
126
+ end
127
+ end
128
+
129
+ context "including methods" do
130
+ setup do
131
+ def @contact.label; "Has cheezburger"; end
132
+ def @contact.favorite_quote; "Constraints are liberating"; end
133
+ end
134
+
135
+ should "include single method" do
136
+ assert_match %r{<label>Has cheezburger</label>}, @contact.to_xml(:methods => :label)
137
+ end
138
+
139
+ should "include multiple methods" do
140
+ xml = @contact.to_xml(:only => :name, :methods => [:label, :favorite_quote])
141
+ assert_match %r{<label>Has cheezburger</label>}, xml
142
+ assert_match %r{<favorite-quote>Constraints are liberating</favorite-quote>}, xml
143
+ assert_match %r{<name>Konata Izumi</name>}, xml
144
+ assert_no_match %r{age}, xml
145
+ assert_no_match %r{awesome}, xml
146
+ assert_no_match %r{created-at}, xml
147
+ assert_no_match %r{preferences}, xml
148
+ end
149
+ end
150
+
151
+ context "array of records" do
152
+ setup do
153
+ @contacts = [
154
+ Contact.new(:name => 'David', :age => 39),
155
+ Contact.new(:name => 'Mary', :age => 14)
156
+ ]
157
+ end
158
+
159
+ should "allow attribute filtering with only" do
160
+ xml = @contacts.to_xml(:only => :name)
161
+ assert_match %r{<name>David</name>}, xml
162
+ assert_match %r{<name>Mary</name>}, xml
163
+ end
164
+
165
+ should "allow attribute filtering with except" do
166
+ xml = @contacts.to_xml(:except => [:name, :preferences, :awesome, :created_at, :updated_at])
167
+ assert_match %r{<age type="integer">39</age>}, xml
168
+ assert_match %r{<age type="integer">14</age>}, xml
169
+ assert_no_match %r{name}, xml
170
+ assert_no_match %r{preferences}, xml
171
+ assert_no_match %r{awesome}, xml
172
+ assert_no_match %r{created-at}, xml
173
+ assert_no_match %r{updated-at}, xml
174
+ end
175
+ end
176
+
177
+ should "include embedded attributes" do
178
+ contact = Contact.new(:name => 'John', :age => 27)
179
+ contact.tags = [Tag.new(:name => 'awesome'), Tag.new(:name => 'ruby')]
180
+ xml = contact.to_xml
181
+ assert_match %r{<tags type="array">}, xml
182
+ assert_match %r{<id>#{contact.tags[0].id}</id>}, xml
183
+ assert_match %r{<id>#{contact.tags[1].id}</id>}, xml
184
+ assert_match %r{<name>awesome</name>}, xml
185
+ assert_match %r{<name>ruby</name>}, xml
186
+ end
187
+
188
+ should "include dynamic attributes" do
189
+ contact = Contact.new(:name => 'John', :age => 27, :foo => 'bar')
190
+ contact['smell'] = 'stinky'
191
+ assert_match %r{<smell>stinky</smell>}, contact.to_xml
192
+ end
193
+ end
@@ -152,7 +152,7 @@ class DocumentTest < Test::Unit::TestCase
152
152
 
153
153
  should "be true if id but using custom id and not saved yet" do
154
154
  @document.key :_id, String
155
- doc = @document.new
155
+ doc = silence_stderr { @document.new }
156
156
  doc.id = '1234'
157
157
  doc.new?.should be_true
158
158
  end
@@ -0,0 +1,38 @@
1
+ require 'test_helper'
2
+
3
+ class EqualityTest < Test::Unit::TestCase
4
+ context "Case equality" do
5
+ setup do
6
+ @klass = Class.new do
7
+ include MongoMapper::Plugins::Equality
8
+ end
9
+ @subklass = Class.new(@klass)
10
+
11
+ @faker = Class.new do
12
+ def initialize(faked)
13
+ @faked = faked
14
+ end
15
+
16
+ def is_a?(klass)
17
+ @faked.is_a? klass
18
+ end
19
+ end
20
+ end
21
+
22
+ should "work with regular instance" do
23
+ @klass.should === @klass.new
24
+ end
25
+
26
+ should "work with instances of subclasses" do
27
+ @klass.should === @subklass.new
28
+ end
29
+
30
+ should "work with a faker class" do
31
+ @klass.should === @faker.new(@klass.new)
32
+ end
33
+
34
+ should "not work with other instances" do
35
+ @klass.should_not === 1
36
+ end
37
+ end
38
+ end
@@ -9,7 +9,7 @@ class KeyTest < Test::Unit::TestCase
9
9
  key :_id, Integer
10
10
  end
11
11
  # No sensible default id for integer, people better pass them in if they user this
12
- klass.new.id.should be_nil
12
+ silence_stderr { klass.new.id.should be_nil }
13
13
  }.should_not raise_error
14
14
  end
15
15
  end
@@ -20,7 +20,7 @@ class KeyTest < Test::Unit::TestCase
20
20
  klass = Doc() do
21
21
  key :_id, String
22
22
  end
23
- klass.new.id.should_not be_nil
23
+ silence_stderr { klass.new.id.should_not be_nil }
24
24
  }.should_not raise_error
25
25
  end
26
26
  end
@@ -31,7 +31,7 @@ class KeyTest < Test::Unit::TestCase
31
31
  klass = Doc() do
32
32
  key :_id, ObjectId
33
33
  end
34
- klass.new.should_not be_nil
34
+ silence_stderr { klass.new.should_not be_nil }
35
35
  }.should_not raise_error
36
36
  end
37
37
  end
@@ -13,6 +13,16 @@ class TestRails < Test::Unit::TestCase
13
13
  @klass.should respond_to(:has_many)
14
14
  end
15
15
 
16
+ should 'pass on block given in has_many' do
17
+ @klass.class_eval do
18
+ has_many :posts do
19
+ def foo_bars; true; end
20
+ end
21
+ end
22
+
23
+ @klass.new.posts.should respond_to(:foo_bars)
24
+ end
25
+
16
26
  should "alias has_one to one" do
17
27
  @klass.should respond_to(:has_one)
18
28
  end
@@ -20,10 +30,6 @@ class TestRails < Test::Unit::TestCase
20
30
  should "have column names" do
21
31
  @klass.column_names.sort.should == ['_id', 'foo']
22
32
  end
23
-
24
- should "implement human_name" do
25
- @klass.human_name.should == 'Post'
26
- end
27
33
  end
28
34
 
29
35
  context "Instance methods" do
@@ -107,10 +113,6 @@ class TestRails < Test::Unit::TestCase
107
113
  should "have column names" do
108
114
  @klass.column_names.sort.should == ['_id', 'foo']
109
115
  end
110
-
111
- should "implement human_name" do
112
- @klass.human_name.should == 'Post'
113
- end
114
116
  end
115
117
 
116
118
  context "Instance methods" do
@@ -178,4 +180,4 @@ class TestRails < Test::Unit::TestCase
178
180
  end
179
181
  end
180
182
  end
181
- end
183
+ end
@@ -1,10 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class TestRailsCompatibility < Test::Unit::TestCase
4
- class BigStuff
5
- include MongoMapper::Document
6
- end
7
-
8
4
  class Item
9
5
  include MongoMapper::EmbeddedDocument
10
6
  key :for_all, String
@@ -38,15 +34,5 @@ class TestRailsCompatibility < Test::Unit::TestCase
38
34
  instance = Item.new
39
35
  instance.new_record?.should == instance.new?
40
36
  end
41
-
42
- should "implement human_name" do
43
- Item.human_name.should == 'Item'
44
- end
45
- end
46
-
47
- context "Document" do
48
- should "implement human_name" do
49
- BigStuff.human_name.should == 'Big Stuff'
50
- end
51
37
  end
52
- end
38
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo_mapper
3
3
  version: !ruby/object:Gem::Version
4
- hash: 59
5
- prerelease: false
4
+ hash: 57
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 0
10
- version: 0.9.0
9
+ - 1
10
+ version: 0.9.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - John Nunemaker
@@ -15,8 +15,8 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-12 00:00:00 -04:00
19
- default_executable: mmconsole
18
+ date: 2011-05-17 00:00:00 -04:00
19
+ default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  requirement: &id001 !ruby/object:Gem::Requirement
@@ -28,12 +28,11 @@ dependencies:
28
28
  segments:
29
29
  - 3
30
30
  - 0
31
- - 0
32
- version: 3.0.0
33
- name: activemodel
31
+ version: "3.0"
34
32
  prerelease: false
35
- type: :runtime
36
33
  version_requirements: *id001
34
+ type: :runtime
35
+ name: activemodel
37
36
  - !ruby/object:Gem::Dependency
38
37
  requirement: &id002 !ruby/object:Gem::Requirement
39
38
  none: false
@@ -44,161 +43,27 @@ dependencies:
44
43
  segments:
45
44
  - 3
46
45
  - 0
47
- - 0
48
- version: 3.0.0
49
- name: activesupport
46
+ version: "3.0"
50
47
  prerelease: false
51
- type: :runtime
52
48
  version_requirements: *id002
49
+ type: :runtime
50
+ name: activesupport
53
51
  - !ruby/object:Gem::Dependency
54
52
  requirement: &id003 !ruby/object:Gem::Requirement
55
53
  none: false
56
54
  requirements:
57
55
  - - ~>
58
- - !ruby/object:Gem::Version
59
- hash: 31
60
- segments:
61
- - 0
62
- - 3
63
- - 6
64
- version: 0.3.6
65
- name: plucky
66
- prerelease: false
67
- type: :runtime
68
- version_requirements: *id003
69
- - !ruby/object:Gem::Dependency
70
- requirement: &id004 !ruby/object:Gem::Requirement
71
- none: false
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- hash: 3
76
- segments:
77
- - 0
78
- version: "0"
79
- name: rake
80
- prerelease: false
81
- type: :development
82
- version_requirements: *id004
83
- - !ruby/object:Gem::Dependency
84
- requirement: &id005 !ruby/object:Gem::Requirement
85
- none: false
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- hash: 3
90
- segments:
91
- - 0
92
- version: "0"
93
- name: tzinfo
94
- prerelease: false
95
- type: :development
96
- version_requirements: *id005
97
- - !ruby/object:Gem::Dependency
98
- requirement: &id006 !ruby/object:Gem::Requirement
99
- none: false
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- hash: 3
104
- segments:
105
- - 0
106
- version: "0"
107
- name: json
108
- prerelease: false
109
- type: :development
110
- version_requirements: *id006
111
- - !ruby/object:Gem::Dependency
112
- requirement: &id007 !ruby/object:Gem::Requirement
113
- none: false
114
- requirements:
115
- - - ">="
116
56
  - !ruby/object:Gem::Version
117
57
  hash: 3
118
58
  segments:
119
59
  - 0
120
- version: "0"
121
- name: log_buddy
122
- prerelease: false
123
- type: :development
124
- version_requirements: *id007
125
- - !ruby/object:Gem::Dependency
126
- requirement: &id008 !ruby/object:Gem::Requirement
127
- none: false
128
- requirements:
129
- - - ~>
130
- - !ruby/object:Gem::Version
131
- hash: 15
132
- segments:
133
- - 0
134
- - 4
135
- - 0
136
- version: 0.4.0
137
- name: jnunemaker-matchy
138
- prerelease: false
139
- type: :development
140
- version_requirements: *id008
141
- - !ruby/object:Gem::Dependency
142
- requirement: &id009 !ruby/object:Gem::Requirement
143
- none: false
144
- requirements:
145
- - - ~>
146
- - !ruby/object:Gem::Version
147
- hash: 21
148
- segments:
149
- - 2
150
- - 11
151
- version: "2.11"
152
- name: shoulda
153
- prerelease: false
154
- type: :development
155
- version_requirements: *id009
156
- - !ruby/object:Gem::Dependency
157
- requirement: &id010 !ruby/object:Gem::Requirement
158
- none: false
159
- requirements:
160
- - - ~>
161
- - !ruby/object:Gem::Version
162
- hash: 17
163
- segments:
164
- - 0
165
60
  - 3
166
- - 1
167
- version: 0.3.1
168
- name: timecop
169
- prerelease: false
170
- type: :development
171
- version_requirements: *id010
172
- - !ruby/object:Gem::Dependency
173
- requirement: &id011 !ruby/object:Gem::Requirement
174
- none: false
175
- requirements:
176
- - - ~>
177
- - !ruby/object:Gem::Version
178
- hash: 43
179
- segments:
180
- - 0
181
- - 9
182
61
  - 8
183
- version: 0.9.8
184
- name: mocha
62
+ version: 0.3.8
185
63
  prerelease: false
186
- type: :development
187
- version_requirements: *id011
188
- - !ruby/object:Gem::Dependency
189
- requirement: &id012 !ruby/object:Gem::Requirement
190
- none: false
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- hash: 3
195
- segments:
196
- - 0
197
- version: "0"
198
- name: rack-test
199
- prerelease: false
200
- type: :development
201
- version_requirements: *id012
64
+ version_requirements: *id003
65
+ type: :runtime
66
+ name: plucky
202
67
  description:
203
68
  email:
204
69
  - nunemaker@gmail.com
@@ -325,6 +190,7 @@ files:
325
190
  - test/functional/test_document.rb
326
191
  - test/functional/test_dynamic_querying.rb
327
192
  - test/functional/test_embedded_document.rb
193
+ - test/functional/test_equality.rb
328
194
  - test/functional/test_identity_map.rb
329
195
  - test/functional/test_indexes.rb
330
196
  - test/functional/test_logger.rb
@@ -348,11 +214,13 @@ files:
348
214
  - test/unit/associations/test_one_association.rb
349
215
  - test/unit/associations/test_proxy.rb
350
216
  - test/unit/serializers/test_json_serializer.rb
217
+ - test/unit/serializers/test_xml_serializer.rb
351
218
  - test/unit/test_clone.rb
352
219
  - test/unit/test_descendant_appends.rb
353
220
  - test/unit/test_document.rb
354
221
  - test/unit/test_dynamic_finder.rb
355
222
  - test/unit/test_embedded_document.rb
223
+ - test/unit/test_equality.rb
356
224
  - test/unit/test_extensions.rb
357
225
  - test/unit/test_identity_map_middleware.rb
358
226
  - test/unit/test_inspect.rb
@@ -400,7 +268,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
400
268
  requirements: []
401
269
 
402
270
  rubyforge_project:
403
- rubygems_version: 1.3.7
271
+ rubygems_version: 1.4.2
404
272
  signing_key:
405
273
  specification_version: 3
406
274
  summary: A Ruby Object Mapper for Mongo