mongo_doc_rails2 0.6.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/.document +5 -0
- data/.gitignore +8 -0
- data/HISTORY.md +11 -0
- data/LICENSE +20 -0
- data/README.textile +185 -0
- data/Rakefile +188 -0
- data/TODO +40 -0
- data/VERSION +1 -0
- data/data/.gitignore +2 -0
- data/examples/simple_document.rb +46 -0
- data/examples/simple_object.rb +34 -0
- data/features/collections.feature +9 -0
- data/features/embed_hash.feature +16 -0
- data/features/finders.feature +76 -0
- data/features/indexes.feature +28 -0
- data/features/mongodb.yml +7 -0
- data/features/mongodoc_base.feature +128 -0
- data/features/new_record.feature +36 -0
- data/features/partial_updates.feature +95 -0
- data/features/removing_documents.feature +68 -0
- data/features/saving_an_object.feature +15 -0
- data/features/scopes.feature +66 -0
- data/features/step_definitions/collection_steps.rb +17 -0
- data/features/step_definitions/document_steps.rb +149 -0
- data/features/step_definitions/documents.rb +40 -0
- data/features/step_definitions/embed_hash_steps.rb +6 -0
- data/features/step_definitions/finder_steps.rb +15 -0
- data/features/step_definitions/index_steps.rb +10 -0
- data/features/step_definitions/json_steps.rb +9 -0
- data/features/step_definitions/object_steps.rb +50 -0
- data/features/step_definitions/objects.rb +24 -0
- data/features/step_definitions/partial_update_steps.rb +31 -0
- data/features/step_definitions/query_steps.rb +66 -0
- data/features/step_definitions/removing_documents_steps.rb +14 -0
- data/features/step_definitions/scope_steps.rb +18 -0
- data/features/step_definitions/string_casting_steps.rb +29 -0
- data/features/step_definitions/util_steps.rb +7 -0
- data/features/string_casting.feature +10 -0
- data/features/support/support.rb +10 -0
- data/features/using_criteria.feature +142 -0
- data/lib/mongo_doc.rb +12 -0
- data/lib/mongo_doc/associations.rb +109 -0
- data/lib/mongo_doc/associations/collection_proxy.rb +121 -0
- data/lib/mongo_doc/associations/document_proxy.rb +65 -0
- data/lib/mongo_doc/associations/hash_proxy.rb +102 -0
- data/lib/mongo_doc/associations/proxy_base.rb +48 -0
- data/lib/mongo_doc/attributes.rb +84 -0
- data/lib/mongo_doc/bson.rb +31 -0
- data/lib/mongo_doc/collection.rb +82 -0
- data/lib/mongo_doc/connection.rb +88 -0
- data/lib/mongo_doc/contexts.rb +31 -0
- data/lib/mongo_doc/contexts/ids.rb +41 -0
- data/lib/mongo_doc/contexts/mongo.rb +272 -0
- data/lib/mongo_doc/criteria.rb +70 -0
- data/lib/mongo_doc/cursor.rb +32 -0
- data/lib/mongo_doc/document.rb +205 -0
- data/lib/mongo_doc/ext.rb +16 -0
- data/lib/mongo_doc/ext/array.rb +5 -0
- data/lib/mongo_doc/ext/binary.rb +7 -0
- data/lib/mongo_doc/ext/boolean_class.rb +17 -0
- data/lib/mongo_doc/ext/date.rb +19 -0
- data/lib/mongo_doc/ext/date_time.rb +17 -0
- data/lib/mongo_doc/ext/dbref.rb +7 -0
- data/lib/mongo_doc/ext/hash.rb +7 -0
- data/lib/mongo_doc/ext/min_max_keys.rb +13 -0
- data/lib/mongo_doc/ext/nil_class.rb +5 -0
- data/lib/mongo_doc/ext/numeric.rb +17 -0
- data/lib/mongo_doc/ext/object.rb +19 -0
- data/lib/mongo_doc/ext/object_id.rb +7 -0
- data/lib/mongo_doc/ext/regexp.rb +5 -0
- data/lib/mongo_doc/ext/string.rb +5 -0
- data/lib/mongo_doc/ext/symbol.rb +5 -0
- data/lib/mongo_doc/ext/time.rb +9 -0
- data/lib/mongo_doc/finders.rb +38 -0
- data/lib/mongo_doc/index.rb +46 -0
- data/lib/mongo_doc/matchers.rb +35 -0
- data/lib/mongo_doc/root.rb +26 -0
- data/lib/mongo_doc/scope.rb +64 -0
- data/lib/mongo_doc/validations.rb +12 -0
- data/lib/mongo_doc/validations/macros.rb +11 -0
- data/lib/mongo_doc/validations/validates_embedded.rb +13 -0
- data/lib/mongoid/contexts/enumerable.rb +151 -0
- data/lib/mongoid/contexts/paging.rb +42 -0
- data/lib/mongoid/criteria.rb +239 -0
- data/lib/mongoid/criterion/complex.rb +21 -0
- data/lib/mongoid/criterion/exclusion.rb +65 -0
- data/lib/mongoid/criterion/inclusion.rb +93 -0
- data/lib/mongoid/criterion/optional.rb +136 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
- data/lib/mongoid/matchers/all.rb +11 -0
- data/lib/mongoid/matchers/default.rb +26 -0
- data/lib/mongoid/matchers/exists.rb +13 -0
- data/lib/mongoid/matchers/gt.rb +11 -0
- data/lib/mongoid/matchers/gte.rb +11 -0
- data/lib/mongoid/matchers/in.rb +11 -0
- data/lib/mongoid/matchers/lt.rb +11 -0
- data/lib/mongoid/matchers/lte.rb +11 -0
- data/lib/mongoid/matchers/ne.rb +11 -0
- data/lib/mongoid/matchers/nin.rb +11 -0
- data/lib/mongoid/matchers/size.rb +11 -0
- data/mongo_doc_rails2.gemspec +237 -0
- data/mongod.example.yml +2 -0
- data/mongodb.example.yml +14 -0
- data/perf/mongo_doc_object.rb +83 -0
- data/perf/mongo_document.rb +84 -0
- data/perf/ruby_driver.rb +49 -0
- data/script/console +8 -0
- data/spec/array_including_argument_matcher.rb +62 -0
- data/spec/associations/collection_proxy_spec.rb +233 -0
- data/spec/associations/document_proxy_spec.rb +45 -0
- data/spec/associations/hash_proxy_spec.rb +181 -0
- data/spec/associations/proxy_base_spec.rb +92 -0
- data/spec/associations_spec.rb +218 -0
- data/spec/attributes_accessor_spec.rb +33 -0
- data/spec/attributes_spec.rb +145 -0
- data/spec/bson_matchers.rb +54 -0
- data/spec/bson_spec.rb +196 -0
- data/spec/collection_spec.rb +169 -0
- data/spec/connection_spec.rb +147 -0
- data/spec/contexts/ids_spec.rb +49 -0
- data/spec/contexts/mongo_spec.rb +235 -0
- data/spec/contexts_spec.rb +56 -0
- data/spec/criteria_spec.rb +69 -0
- data/spec/cursor_spec.rb +91 -0
- data/spec/document_ext.rb +9 -0
- data/spec/document_spec.rb +553 -0
- data/spec/embedded_save_spec.rb +73 -0
- data/spec/ext_spec.rb +89 -0
- data/spec/finders_spec.rb +61 -0
- data/spec/hash_matchers.rb +27 -0
- data/spec/index_spec.rb +79 -0
- data/spec/matchers_spec.rb +342 -0
- data/spec/mongodb.yml +6 -0
- data/spec/mongodb_pairs.yml +8 -0
- data/spec/new_record_spec.rb +128 -0
- data/spec/root_spec.rb +41 -0
- data/spec/scope_spec.rb +79 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/validations_spec.rb +30 -0
- metadata +346 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
|
2
|
+
|
|
3
|
+
describe "MongoDoc::Associations::DocumentProxy" do
|
|
4
|
+
class Parent
|
|
5
|
+
include MongoDoc::Document
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class Child
|
|
9
|
+
include MongoDoc::Document
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
let(:parent) { Parent.new }
|
|
13
|
+
let(:name) {'association_name'}
|
|
14
|
+
|
|
15
|
+
subject do
|
|
16
|
+
MongoDoc::Associations::DocumentProxy.new(:assoc_name => name, :root => parent, :parent => parent, :assoc_class => Child)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe "#build" do
|
|
20
|
+
it "#build builds a new object" do
|
|
21
|
+
Child.should === subject.build({})
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context "delegated to the document" do
|
|
26
|
+
%w(id to_bson).each do |method|
|
|
27
|
+
it "delegates #{method} to the document" do
|
|
28
|
+
subject.stub(:document => stub)
|
|
29
|
+
subject.document.should_receive(method)
|
|
30
|
+
subject.send(method)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
%w(_modifier_path= _selector_path=).each do |setter|
|
|
36
|
+
describe "##{setter}" do
|
|
37
|
+
it "delegates to the document with our assoc name" do
|
|
38
|
+
subject.stub(:document => stub)
|
|
39
|
+
subject.document.should_receive(setter).with("new.path.#{name}")
|
|
40
|
+
MongoDoc::Associations::ProxyBase.stub(:is_document?).and_return(true)
|
|
41
|
+
subject.send("#{setter}", 'new.path')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '/spec_helper'))
|
|
2
|
+
|
|
3
|
+
describe MongoDoc::Associations::HashProxy do
|
|
4
|
+
class HashProxyTest
|
|
5
|
+
include MongoDoc::Document
|
|
6
|
+
|
|
7
|
+
attr_accessor :name
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
let(:name) { 'embed_hash_name' }
|
|
11
|
+
let(:root) { HashProxyTest.new }
|
|
12
|
+
let(:proxy) { MongoDoc::Associations::HashProxy.new(:assoc_name => name, :assoc_class => HashProxyTest, :root => root, :parent => root) }
|
|
13
|
+
let(:item) { HashProxyTest.new }
|
|
14
|
+
let(:other_item) {[1,2]}
|
|
15
|
+
|
|
16
|
+
%w(_modifier_path= _selector_path=).each do |setter|
|
|
17
|
+
describe "##{setter}" do
|
|
18
|
+
it "delegates to the document with our assoc name and the key" do
|
|
19
|
+
document = stub
|
|
20
|
+
proxy.stub(:hash).and_return(:key => document)
|
|
21
|
+
document.should_receive(setter).with("new.path.#{name}.key")
|
|
22
|
+
MongoDoc::Associations::ProxyBase.stub(:is_document?).and_return(true)
|
|
23
|
+
proxy.send("#{setter}", 'new.path')
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "#[]=" do
|
|
29
|
+
it "adds the item to the hash" do
|
|
30
|
+
proxy['new'] = item
|
|
31
|
+
proxy['new'].should == item
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "key names must be a string or symbol constrained by BSON element name" do
|
|
35
|
+
['$invalid', 'in.valid', :_id, 'query', 1, Object.new].each do |name|
|
|
36
|
+
it "#{name} is invalid" do
|
|
37
|
+
expect do
|
|
38
|
+
proxy[name] = other_item
|
|
39
|
+
end.to raise_error(MongoDoc::InvalidEmbeddedHashKey)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
[:key, 'key'].each do |name|
|
|
44
|
+
it "#{name} is a valid name" do
|
|
45
|
+
expect do
|
|
46
|
+
proxy[name] = other_item
|
|
47
|
+
end.to_not raise_error(MongoDoc::InvalidEmbeddedHashKey)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
context "when the item is not a MongoDoc::Document" do
|
|
53
|
+
|
|
54
|
+
it "does not register a save observer" do
|
|
55
|
+
root.should_not_receive(:register_save_observer)
|
|
56
|
+
proxy['new'] = other_item
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "does not set the root" do
|
|
60
|
+
other_item.should_not_receive(:_root=)
|
|
61
|
+
proxy['new'] = other_item
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "when the item is a MongoDoc::Document" do
|
|
66
|
+
it "registers a save observer" do
|
|
67
|
+
root.should_receive(:register_save_observer)
|
|
68
|
+
proxy['new'] = item
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "sets the root" do
|
|
72
|
+
proxy['new'] = item
|
|
73
|
+
item._root.should == root
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "adds the item through a document proxy" do
|
|
77
|
+
proxy['new'] = item
|
|
78
|
+
MongoDoc::Associations::DocumentProxy.should === proxy['new']
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context "#merge!" do
|
|
84
|
+
context "when the key value is not a MongoDoc::Document" do
|
|
85
|
+
|
|
86
|
+
it "does not register a save observer" do
|
|
87
|
+
root.should_not_receive(:register_save_observer)
|
|
88
|
+
proxy.merge!(:new => other_item)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "does not set the root" do
|
|
92
|
+
other_item.should_not_receive(:_root=)
|
|
93
|
+
proxy.merge!(:new => other_item)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
context "when the key value is a MongoDoc::Document" do
|
|
98
|
+
it "registers a save observer" do
|
|
99
|
+
root.should_receive(:register_save_observer)
|
|
100
|
+
proxy.merge!(:new => item)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "sets the root" do
|
|
104
|
+
proxy.merge!(:new => item)
|
|
105
|
+
item._root.should == root
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
context "with a block" do
|
|
110
|
+
it "calls into the block" do
|
|
111
|
+
proxy.merge!(:new => other_item) {|k, v1, v2| @result = v2}
|
|
112
|
+
@result.should == other_item
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
context "when the key value is not a MongoDoc::Document" do
|
|
116
|
+
|
|
117
|
+
it "does not register a save observer" do
|
|
118
|
+
root.should_not_receive(:register_save_observer)
|
|
119
|
+
proxy.merge!(:new => other_item) {|k, v1, v2| v2}
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "does not set the root" do
|
|
123
|
+
other_item.should_not_receive(:_root=)
|
|
124
|
+
proxy.merge!(:new => other_item) {|k, v1, v2| v2}
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
context "when the key value is a MongoDoc::Document" do
|
|
129
|
+
it "registers a save observer" do
|
|
130
|
+
root.should_receive(:register_save_observer)
|
|
131
|
+
proxy.merge!(:new => item) {|k, v1, v2| v2}
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "sets the root" do
|
|
135
|
+
proxy.merge!(:new => item) {|k, v1, v2| v2}
|
|
136
|
+
item._root.should == root
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
context "#replace" do
|
|
143
|
+
it "clears any existing data" do
|
|
144
|
+
proxy.should_receive(:clear)
|
|
145
|
+
proxy.replace(:new => other_item)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
context "when the key value is not a MongoDoc::Document" do
|
|
149
|
+
|
|
150
|
+
it "does not register a save observer" do
|
|
151
|
+
root.should_not_receive(:register_save_observer)
|
|
152
|
+
proxy.replace(:new => other_item)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it "does not set the root" do
|
|
156
|
+
other_item.should_not_receive(:_root=)
|
|
157
|
+
proxy.replace(:new => other_item)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
context "when the key value is a MongoDoc::Document" do
|
|
162
|
+
it "registers a save observer" do
|
|
163
|
+
root.should_receive(:register_save_observer)
|
|
164
|
+
proxy.replace(:new => item)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "sets the root" do
|
|
168
|
+
proxy.replace(:new => item)
|
|
169
|
+
item._root.should == root
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
context "#build" do
|
|
176
|
+
it "builds an object of the collection class from the hash attrs" do
|
|
177
|
+
name = 'built'
|
|
178
|
+
proxy.build(:key, {:name => name}).name.should == name
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "MongoDoc::Associations::ProxyBase" do
|
|
4
|
+
class ProxyBaseTest
|
|
5
|
+
include MongoDoc::Associations::ProxyBase
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
let(:_assoc_class) { 'ClassOfAssociation' }
|
|
9
|
+
let(:_assoc_name) { 'name_of_association' }
|
|
10
|
+
let(:_root) { 'root of document' }
|
|
11
|
+
let(:path) { 'root.parent' }
|
|
12
|
+
|
|
13
|
+
subject do
|
|
14
|
+
ProxyBaseTest.new({ :path => path, :assoc_class => _assoc_class, :assoc_name => _assoc_name, :root => _root })
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
%w(_assoc_class _assoc_name _modifier_path _root _selector_path).each do |attr|
|
|
18
|
+
it "defines #{attr}" do
|
|
19
|
+
should respond_to(attr)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "#initialize" do
|
|
24
|
+
%w(_assoc_class _assoc_name _root).each do |attr|
|
|
25
|
+
its(attr) { should == send(attr) }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "#_modifier_path" do
|
|
30
|
+
its(:_modifier_path) { should == path + '.' + _assoc_name }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe "#_modifier_path=" do
|
|
34
|
+
it "sets the modifier path to the path + '.' + the assoc name" do
|
|
35
|
+
subject._modifier_path = 'new_path'
|
|
36
|
+
subject._modifier_path.should == "new_path.#{_assoc_name}"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe "#_selector_path" do
|
|
41
|
+
its(:_selector_path) { should == path + '.' + _assoc_name }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe "#_selector_path=" do
|
|
45
|
+
it "sets the selector path to the path + '.' + the assoc name" do
|
|
46
|
+
subject._selector_path = 'new_path'
|
|
47
|
+
subject._selector_path.should == "new_path.#{_assoc_name}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
describe ".is_document" do
|
|
52
|
+
class TestIsDocument
|
|
53
|
+
include MongoDoc::Document
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "returns false for any non-Document" do
|
|
57
|
+
MongoDoc::Associations::ProxyBase.is_document?(Object.new).should be_false
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "returns true for any Document" do
|
|
61
|
+
MongoDoc::Associations::ProxyBase.is_document?(TestIsDocument.new).should be_true
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe "#attach" do
|
|
66
|
+
class AttachDocument
|
|
67
|
+
include MongoDoc::Document
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
let(:doc) { AttachDocument.new }
|
|
71
|
+
let(:object) { Object.new }
|
|
72
|
+
let(:proxy) { ProxyBaseTest.new(:assoc_class => _assoc_class, :assoc_name => _assoc_name, :root => _root) }
|
|
73
|
+
|
|
74
|
+
it "returns the attached object" do
|
|
75
|
+
proxy.send(:attach, object).should == object
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
context "when a Document" do
|
|
79
|
+
it "attaches the Document" do
|
|
80
|
+
proxy.should_receive(:attach_document)
|
|
81
|
+
proxy.send(:attach, doc)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
context "when not a Document" do
|
|
86
|
+
it "does not attach the Document" do
|
|
87
|
+
proxy.should_not_receive(:attach_document)
|
|
88
|
+
proxy.send(:attach, object)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "MongoDoc::Associations" do
|
|
4
|
+
|
|
5
|
+
context ".embed" do
|
|
6
|
+
class TestDoc
|
|
7
|
+
include MongoDoc::Document
|
|
8
|
+
|
|
9
|
+
embed :sub_doc
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class SubDoc
|
|
13
|
+
include MongoDoc::Document
|
|
14
|
+
|
|
15
|
+
attr_accessor :data
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class TestHasOne
|
|
19
|
+
include MongoDoc::Document
|
|
20
|
+
|
|
21
|
+
has_one :sub_doc
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
let(:subdoc) { SubDoc.new }
|
|
25
|
+
let(:doc) { TestDoc.new(:sub_doc => subdoc) }
|
|
26
|
+
|
|
27
|
+
it "uses a proxy" do
|
|
28
|
+
MongoDoc::Associations::DocumentProxy.should === doc.sub_doc
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it ".has_one is an alias for embed" do
|
|
32
|
+
MongoDoc::Associations::DocumentProxy.should === TestHasOne.new(:sub_doc => SubDoc.new).sub_doc
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "set the subdocuments root" do
|
|
36
|
+
doc.should == subdoc._root
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "validations" do
|
|
40
|
+
class EmbedValidationTest
|
|
41
|
+
include MongoDoc::Document
|
|
42
|
+
|
|
43
|
+
attr_accessor :data
|
|
44
|
+
validates_presence_of :data
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "cascades validations down" do
|
|
48
|
+
invalid = EmbedValidationTest.new
|
|
49
|
+
TestDoc.new(:sub_doc => invalid).should have(1).error_on(:sub_doc)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context ".embed_many" do
|
|
55
|
+
|
|
56
|
+
class SubEmbedManyDoc
|
|
57
|
+
include MongoDoc::Document
|
|
58
|
+
|
|
59
|
+
attr_accessor :data
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
class TestEmbedManyDoc
|
|
63
|
+
include MongoDoc::Document
|
|
64
|
+
|
|
65
|
+
embed_many :sub_docs, :class_name => 'SubEmbedManyDoc'
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
class TestEmbedManyDoc2
|
|
69
|
+
include MongoDoc::Document
|
|
70
|
+
|
|
71
|
+
embed_many :sub_docs, :class_name => :sub_embed_many_doc
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
class TestImplicitEmbedManyDoc
|
|
75
|
+
include MongoDoc::Document
|
|
76
|
+
|
|
77
|
+
embed_many :sub_embed_many_docs
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class TestHasManyDoc
|
|
81
|
+
include MongoDoc::Document
|
|
82
|
+
|
|
83
|
+
has_many :sub_docs, :class_name => 'SubEmbedManyDoc'
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
let(:subdoc) { SubEmbedManyDoc.new }
|
|
87
|
+
let(:doc) { TestEmbedManyDoc.new(:sub_docs => [subdoc]) }
|
|
88
|
+
|
|
89
|
+
it "uses a proxy" do
|
|
90
|
+
MongoDoc::Associations::CollectionProxy.should === TestEmbedManyDoc.new.sub_docs
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it ".has_many is an alias for .embed_many" do
|
|
94
|
+
MongoDoc::Associations::CollectionProxy.should === TestHasManyDoc.new.sub_docs
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "set the subdocuments root to the root" do
|
|
98
|
+
doc.should == subdoc._root
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "uses the association name to find the children's class name" do
|
|
102
|
+
TestImplicitEmbedManyDoc.new.sub_embed_many_docs._assoc_class.should == SubEmbedManyDoc
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "uses class_name attribute for the children's class name" do
|
|
106
|
+
TestEmbedManyDoc.new.sub_docs._assoc_class.should == SubEmbedManyDoc
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "uses class_name attribute for the children's class name" do
|
|
110
|
+
TestEmbedManyDoc2.new.sub_docs._assoc_class.should == SubEmbedManyDoc
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context "validations" do
|
|
114
|
+
class EmbedManyValidationChild
|
|
115
|
+
include MongoDoc::Document
|
|
116
|
+
|
|
117
|
+
attr_accessor :data
|
|
118
|
+
validates_presence_of :data
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
class EmbedManyValidationTest
|
|
122
|
+
include MongoDoc::Document
|
|
123
|
+
|
|
124
|
+
embed_many :subdocs, :class_name => 'HasManyValidationChild'
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
let(:invalid_child) { EmbedManyValidationChild.new }
|
|
128
|
+
let(:doc) { EmbedManyValidationTest.new(:subdocs => [invalid_child]) }
|
|
129
|
+
|
|
130
|
+
it "cascades validations and marks it in the parent" do
|
|
131
|
+
doc.should have(1).error_on(:subdocs)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "cascades validations and marks it in the child" do
|
|
135
|
+
invalid_child.should have(1).error_on(:data)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "ignores non-document children" do
|
|
139
|
+
EmbedManyValidationTest.new(:subdocs => ['not a doc']).should be_valid
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
context ".embed_hash" do
|
|
145
|
+
class SubEmbedHashDoc
|
|
146
|
+
include MongoDoc::Document
|
|
147
|
+
|
|
148
|
+
attr_accessor :data
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
class TestEmbedHashDoc
|
|
152
|
+
include MongoDoc::Document
|
|
153
|
+
|
|
154
|
+
embed_hash :sub_docs, :class_name => 'SubEmbedHashDoc'
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
class TestImplicitEmbedHashDoc
|
|
158
|
+
include MongoDoc::Document
|
|
159
|
+
|
|
160
|
+
embed_hash :sub_embed_hash_docs
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
class TestHasHashDoc
|
|
164
|
+
include MongoDoc::Document
|
|
165
|
+
|
|
166
|
+
has_hash :sub_embed_hash_docs
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
let(:subdoc) { SubEmbedHashDoc.new }
|
|
170
|
+
let(:doc) { TestEmbedHashDoc.new(:sub_docs => {:key => subdoc}) }
|
|
171
|
+
|
|
172
|
+
it "uses a proxy" do
|
|
173
|
+
MongoDoc::Associations::HashProxy.should === TestEmbedHashDoc.new.sub_docs
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it ".has_hash is an alias for embed_hash" do
|
|
177
|
+
MongoDoc::Associations::HashProxy.should === TestEmbedHashDoc.new.sub_docs
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "set the subdocuments root to the root" do
|
|
181
|
+
doc.should == subdoc._root
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "uses the association name to find the children's class name" do
|
|
185
|
+
TestImplicitEmbedHashDoc.new.sub_embed_hash_docs._assoc_class.should == SubEmbedHashDoc
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
context "validations" do
|
|
189
|
+
class EmbedHashValidationChild
|
|
190
|
+
include MongoDoc::Document
|
|
191
|
+
|
|
192
|
+
attr_accessor :data
|
|
193
|
+
validates_presence_of :data
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
class EmbedHashValidationTest
|
|
197
|
+
include MongoDoc::Document
|
|
198
|
+
|
|
199
|
+
embed_hash :subdocs, :class_name => 'EmbedHashValidationChild'
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
let(:invalid_child) { EmbedHashValidationChild.new }
|
|
203
|
+
let(:doc) { EmbedHashValidationTest.new(:subdocs => {:key => invalid_child}) }
|
|
204
|
+
|
|
205
|
+
it "cascades validations and marks it in the parent" do
|
|
206
|
+
doc.should have(1).error_on(:subdocs)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
it "cascades validations and marks it in the child" do
|
|
210
|
+
invalid_child.should have(1).error_on(:data)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
it "ignores non-document children" do
|
|
214
|
+
EmbedHashValidationTest.new(:subdocs => {:key => 'data'}).should be_valid
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|