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.
- data/lib/mongo_mapper/extensions/boolean.rb +3 -3
- data/lib/mongo_mapper/extensions/object_id.rb +2 -0
- data/lib/mongo_mapper/plugins/accessible.rb +5 -13
- data/lib/mongo_mapper/plugins/associations/proxy.rb +0 -5
- data/lib/mongo_mapper/plugins/dirty.rb +3 -3
- data/lib/mongo_mapper/plugins/equality.rb +7 -1
- data/lib/mongo_mapper/plugins/keys.rb +6 -1
- data/lib/mongo_mapper/plugins/modifiers.rb +8 -0
- data/lib/mongo_mapper/plugins/protected.rb +5 -13
- data/lib/mongo_mapper/plugins/querying.rb +11 -7
- data/lib/mongo_mapper/plugins/querying/decorator.rb +0 -12
- data/lib/mongo_mapper/plugins/rails.rb +3 -7
- data/lib/mongo_mapper/plugins/scopes.rb +5 -1
- data/lib/mongo_mapper/plugins/serialization.rb +10 -0
- data/lib/mongo_mapper/plugins/validations.rb +1 -1
- data/lib/mongo_mapper/version.rb +1 -1
- data/test/functional/test_dirty.rb +7 -0
- data/test/functional/test_equality.rb +20 -0
- data/test/functional/test_modifiers.rb +16 -0
- data/test/functional/test_string_id_compatibility.rb +28 -20
- data/test/functional/test_validations.rb +28 -0
- data/test/unit/associations/test_proxy.rb +1 -6
- data/test/unit/serializers/test_xml_serializer.rb +193 -0
- data/test/unit/test_document.rb +1 -1
- data/test/unit/test_equality.rb +38 -0
- data/test/unit/test_keys.rb +3 -3
- data/test/unit/test_rails.rb +11 -9
- data/test/unit/test_rails_compatibility.rb +1 -15
- metadata +20 -152
@@ -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.
|
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?
|
@@ -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
|
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 &&
|
61
|
+
attribute_changed?(key) == false && attribute_value_changed?(key, old, value)
|
62
62
|
end
|
63
63
|
|
64
|
-
def
|
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.
|
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
|
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
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
-
|
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, :
|
59
|
+
record.errors.add(attribute, :invalid, :message => options[:message], :value => value)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
data/lib/mongo_mapper/version.rb
CHANGED
@@ -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
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
43
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
53
|
-
|
54
|
-
|
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
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
64
|
-
|
65
|
-
|
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
|
data/test/unit/test_document.rb
CHANGED
@@ -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
|
data/test/unit/test_keys.rb
CHANGED
@@ -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
|
data/test/unit/test_rails.rb
CHANGED
@@ -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:
|
5
|
-
prerelease:
|
4
|
+
hash: 57
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
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-
|
19
|
-
default_executable:
|
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
|
-
|
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
|
-
|
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.
|
184
|
-
name: mocha
|
62
|
+
version: 0.3.8
|
185
63
|
prerelease: false
|
186
|
-
|
187
|
-
|
188
|
-
|
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.
|
271
|
+
rubygems_version: 1.4.2
|
404
272
|
signing_key:
|
405
273
|
specification_version: 3
|
406
274
|
summary: A Ruby Object Mapper for Mongo
|