mongo_mapper 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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