jnunemaker-mongomapper 0.1.2 → 0.2.0

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.
@@ -2,51 +2,148 @@ require 'test_helper'
2
2
 
3
3
  class Address
4
4
  include MongoMapper::EmbeddedDocument
5
-
5
+
6
6
  key :address, String
7
7
  key :city, String
8
8
  key :state, String
9
9
  key :zip, Integer
10
10
  end
11
11
 
12
+ class Project
13
+ include MongoMapper::Document
14
+
15
+ key :name, String
16
+
17
+ many :statuses
18
+ many :addresses
19
+ end
20
+
21
+ class Status
22
+ include MongoMapper::Document
23
+
24
+ belongs_to :project
25
+ belongs_to :target, :polymorphic => true
26
+
27
+ key :name, String
28
+ end
29
+
12
30
  class AssociationsTest < Test::Unit::TestCase
13
31
  def setup
14
- @document = Class.new do
15
- include MongoMapper::Document
32
+ Project.collection.clear
33
+ Status.collection.clear
34
+ end
35
+
36
+ context "Polymorphic Belongs To" do
37
+ should "default to nil" do
38
+ status = Status.new
39
+ status.target.should be_nil
40
+ end
41
+
42
+ should "store the association" do
43
+ status = Status.new
44
+ project = Project.new(:name => "mongomapper")
45
+ status.target = project
46
+ status.save.should be_true
47
+
48
+ from_db = Status.find(status.id)
49
+ from_db.target.should_not be_nil
50
+ from_db.target_id.should == project.id
51
+ from_db.target_type.should == "Project"
52
+ from_db.target.name.should == "mongomapper"
53
+ end
54
+
55
+ should "unset the association" do
56
+ status = Status.new
57
+ project = Project.new(:name => "mongomapper")
58
+ status.target = project
59
+ status.save.should be_true
60
+
61
+ from_db = Status.find(status.id)
62
+ from_db.target = nil
63
+ from_db.target_type.should be_nil
64
+ from_db.target_id.should be_nil
65
+ from_db.target.should be_nil
16
66
  end
17
67
  end
18
-
19
- context "Many embedded documents" do
20
- setup do
21
- @document.class_eval do
22
- many :addresses
23
- end
68
+
69
+ context "Belongs To" do
70
+ should "default to nil" do
71
+ status = Status.new
72
+ status.project.should be_nil
24
73
  end
25
74
 
75
+ should "store the association" do
76
+ status = Status.new
77
+ project = Project.new(:name => "mongomapper")
78
+ status.project = project
79
+ status.save.should be_true
80
+
81
+ from_db = Status.find(status.id)
82
+ from_db.project.should_not be_nil
83
+ from_db.project.name.should == "mongomapper"
84
+ end
85
+
86
+ should "unset the association" do
87
+ status = Status.new
88
+ project = Project.new(:name => "mongomapper")
89
+ status.project = project
90
+ status.save.should be_true
91
+
92
+ from_db = Status.find(status.id)
93
+ from_db.project = nil
94
+ from_db.project.should be_nil
95
+ end
96
+ end
97
+
98
+ context "Many documents" do
99
+ should "default reader to empty array" do
100
+ project = Project.new
101
+ project.statuses.should == []
102
+ end
103
+
104
+ should "allow adding to association like it was an array" do
105
+ project = Project.new
106
+ project.statuses << Status.new
107
+ project.statuses.push Status.new
108
+ project.statuses.size.should == 2
109
+ end
110
+
111
+ should "store the association" do
112
+ project = Project.new
113
+ project.statuses = [Status.new("name" => "ready")]
114
+ project.save.should be_true
115
+
116
+ from_db = Project.find(project.id)
117
+ from_db.statuses.size.should == 1
118
+ from_db.statuses[0].name.should == "ready"
119
+ end
120
+ end
121
+
122
+ context "Many embedded documents" do
26
123
  should "default reader to empty array" do
27
- instance = @document.new
28
- instance.addresses.should == []
124
+ project = Project.new
125
+ project.addresses.should == []
29
126
  end
30
-
127
+
31
128
  should "allow adding to association like it was an array" do
32
- instance = @document.new
33
- instance.addresses << Address.new
34
- instance.addresses.push Address.new
35
- instance.addresses.size.should == 2
129
+ project = Project.new
130
+ project.addresses << Address.new
131
+ project.addresses.push Address.new
132
+ project.addresses.size.should == 2
36
133
  end
37
-
134
+
38
135
  should "be embedded in document on save" do
39
136
  sb = Address.new(:city => 'South Bend', :state => 'IN')
40
137
  chi = Address.new(:city => 'Chicago', :state => 'IL')
41
- instance = @document.new
42
- instance.addresses << sb
43
- instance.addresses << chi
44
- instance.save
45
-
46
- from_db = @document.find(instance.id)
138
+ project = Project.new
139
+ project.addresses << sb
140
+ project.addresses << chi
141
+ project.save
142
+
143
+ from_db = Project.find(project.id)
47
144
  from_db.addresses.size.should == 2
48
145
  from_db.addresses[0].should == sb
49
146
  from_db.addresses[1].should == chi
50
- end
147
+ end
51
148
  end
52
149
  end
@@ -1,7 +1,5 @@
1
1
  require 'test_helper'
2
2
 
3
- include ActiveSupport::Callbacks
4
-
5
3
  class CallbacksTest < Test::Unit::TestCase
6
4
  context "Defining and running callbacks" do
7
5
  setup do
@@ -15,8 +13,7 @@ class CallbacksTest < Test::Unit::TestCase
15
13
  :before_create, :after_create,
16
14
  :before_update, :after_update,
17
15
  :before_save, :after_save,
18
- :before_destroy, :after_destroy,
19
- :validate, :validate_on_create, :validate_on_update].each do |callback|
16
+ :before_destroy, :after_destroy].each do |callback|
20
17
  callback_method = "#{callback}_callback"
21
18
  send(callback, callback_method)
22
19
  define_method(callback_method) do
@@ -37,7 +34,7 @@ class CallbacksTest < Test::Unit::TestCase
37
34
 
38
35
  should "get the order right for creating documents" do
39
36
  doc = @document.create(:name => 'John Nunemaker')
40
- doc.history.should == [:before_validation, :before_validation_on_create, :validate, :validate_on_create, :after_validation, :before_save, :before_create, :after_create, :after_save]
37
+ doc.history.should == [:before_validation, :before_validation_on_create, :after_validation, :before_save, :before_create, :after_create, :after_save]
41
38
  end
42
39
 
43
40
  should "get the order right for updating documents" do
@@ -45,7 +42,7 @@ class CallbacksTest < Test::Unit::TestCase
45
42
  doc.clear_history
46
43
  doc.name = 'John'
47
44
  doc.save
48
- doc.history.should == [:before_validation, :before_validation_on_update, :validate, :validate_on_update, :after_validation, :before_save, :before_update, :after_update, :after_save]
45
+ doc.history.should == [:before_validation, :before_validation_on_update, :after_validation, :before_save, :before_update, :after_update, :after_save]
49
46
  end
50
47
 
51
48
  should "work for before and after validation" do
@@ -13,8 +13,12 @@ class DocumentTest < Test::Unit::TestCase
13
13
  include MongoMapper::Document
14
14
  end
15
15
  end
16
-
17
- should "should be able to define a key" do
16
+
17
+ should "track its descendants" do
18
+ MongoMapper::Document.descendants.should include(@document)
19
+ end
20
+
21
+ should "be able to define a key" do
18
22
  key = @document.key(:name, String)
19
23
  key.name.should == 'name'
20
24
  key.type.should == String
@@ -380,6 +384,11 @@ class DocumentTest < Test::Unit::TestCase
380
384
  @document.delete_all({:fname => 'John'})
381
385
  @document.count.should == 2
382
386
  end
387
+
388
+ should "convert the conditions to mongo criteria" do
389
+ @document.delete_all(:age => [26, 27])
390
+ @document.count.should == 1
391
+ end
383
392
  end
384
393
 
385
394
  context "Destroying a document" do
@@ -436,6 +445,11 @@ class DocumentTest < Test::Unit::TestCase
436
445
  @document.destroy_all(:age => 26)
437
446
  @document.count.should == 1
438
447
  end
448
+
449
+ should "convert the conditions to mongo criteria" do
450
+ @document.destroy_all(:age => [26, 27])
451
+ @document.count.should == 1
452
+ end
439
453
  end
440
454
 
441
455
  context "Counting documents in collection" do
@@ -466,6 +480,10 @@ class DocumentTest < Test::Unit::TestCase
466
480
  should "return count for matching documents if conditions provided" do
467
481
  @document.count(:age => 27).should == 1
468
482
  end
483
+
484
+ should "convert the conditions to mongo criteria" do
485
+ @document.count(:age => [26, 27]).should == 2
486
+ end
469
487
  end
470
488
 
471
489
  context "Indexing" do
@@ -561,18 +579,6 @@ class DocumentTest < Test::Unit::TestCase
561
579
  end
562
580
  end
563
581
 
564
- context "when initialized" do
565
- should "accept a hash that sets keys and values" do
566
- doc = @document.new(:name => 'John', :age => 23)
567
- doc.attributes.should == {'name' => 'John', 'age' => 23}
568
- end
569
-
570
- should "silently reject keys that have not been defined" do
571
- doc = @document.new(:foobar => 'baz')
572
- doc.attributes.should == {}
573
- end
574
- end
575
-
576
582
  context "mass assigning keys" do
577
583
  should "update values for keys provided" do
578
584
  doc = @document.new(:name => 'foobar', :age => 10)
@@ -29,9 +29,8 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
29
29
  doc.attributes.should == {'name' => 'John', 'age' => 23}
30
30
  end
31
31
 
32
- should "silently reject keys that have not been defined" do
33
- doc = @document.new(:foobar => 'baz')
34
- doc.attributes.should == {}
32
+ should "not throw error if initialized with nil" do
33
+ doc = @document.new(nil)
35
34
  end
36
35
  end
37
36
 
@@ -14,26 +14,41 @@ class FinderOptionsTest < Test::Unit::TestCase
14
14
  end
15
15
  end
16
16
 
17
+ context "#criteria" do
18
+ should "convert conditions to criteria" do
19
+ FinderOptions.expects(:to_mongo_criteria).with(:foo => 1).returns({})
20
+ FinderOptions.new(:conditions => {:foo => 1}).criteria
21
+ end
22
+ end
23
+
24
+ context "#options" do
25
+ should "convert options to mongo options" do
26
+ FinderOptions.expects(:to_mongo_options).with(:order => 'foo asc', :select => 'foo,bar').returns({})
27
+ FinderOptions.new(:order => 'foo asc', :select => 'foo,bar').options
28
+ end
29
+ end
30
+
31
+
17
32
  context "Converting conditions to criteria" do
18
33
  should "work with simple criteria" do
19
- FinderOptions.new(:conditions => {:foo => 'bar'}).criteria.should == {
34
+ FinderOptions.to_mongo_criteria(:foo => 'bar').should == {
20
35
  :foo => 'bar'
21
36
  }
22
37
 
23
- FinderOptions.new(:conditions => {:foo => 'bar', :baz => 'wick'}).criteria.should == {
38
+ FinderOptions.to_mongo_criteria(:foo => 'bar', :baz => 'wick').should == {
24
39
  :foo => 'bar',
25
40
  :baz => 'wick'
26
41
  }
27
42
  end
28
43
 
29
44
  should "use $in for arrays" do
30
- FinderOptions.new(:conditions => {:foo => [1,2,3]}).criteria.should == {
45
+ FinderOptions.to_mongo_criteria(:foo => [1,2,3]).should == {
31
46
  :foo => {'$in' => [1,2,3]}
32
47
  }
33
48
  end
34
49
 
35
50
  should "work arbitrarily deep" do
36
- FinderOptions.new(:conditions => {:foo => {:bar => [1,2,3]}}).criteria.should == {
51
+ FinderOptions.to_mongo_criteria(:foo => {:bar => [1,2,3]}).should == {
37
52
  :foo => {:bar => {'$in' => [1,2,3]}}
38
53
  }
39
54
  end
@@ -43,21 +58,21 @@ class FinderOptionsTest < Test::Unit::TestCase
43
58
  should "single field with ascending direction" do
44
59
  hash = OrderedHash.new
45
60
  hash[:foo] = 1
46
- FinderOptions.new(:order => 'foo asc').options[:sort].should == hash
47
- FinderOptions.new(:order => 'foo ASC').options[:sort].should == hash
61
+ FinderOptions.to_mongo_options(:order => 'foo asc')[:sort].should == hash
62
+ FinderOptions.to_mongo_options(:order => 'foo ASC')[:sort].should == hash
48
63
  end
49
64
 
50
65
  should "single field with descending direction" do
51
66
  hash = OrderedHash.new
52
67
  hash[:foo] = -1
53
- FinderOptions.new(:order => 'foo desc').options[:sort].should == hash
54
- FinderOptions.new(:order => 'foo DESC').options[:sort].should == hash
68
+ FinderOptions.to_mongo_options(:order => 'foo desc')[:sort].should == hash
69
+ FinderOptions.to_mongo_options(:order => 'foo DESC')[:sort].should == hash
55
70
  end
56
71
 
57
72
  should "convert field without direction to ascending" do
58
73
  hash = OrderedHash.new
59
74
  hash[:foo] = 1
60
- FinderOptions.new(:order => 'foo').options[:sort].should == hash
75
+ FinderOptions.to_mongo_options(:order => 'foo')[:sort].should == hash
61
76
  end
62
77
 
63
78
  should "convert multiple fields with directions" do
@@ -65,7 +80,7 @@ class FinderOptionsTest < Test::Unit::TestCase
65
80
  hash[:foo] = -1
66
81
  hash[:bar] = 1
67
82
  hash[:baz] = -1
68
- options = FinderOptions.new(:order => 'foo desc, bar asc, baz desc').options[:sort].should == hash
83
+ FinderOptions.to_mongo_options(:order => 'foo desc, bar asc, baz desc')[:sort].should == hash
69
84
  end
70
85
 
71
86
  should "convert multiple fields with some missing directions" do
@@ -73,57 +88,57 @@ class FinderOptionsTest < Test::Unit::TestCase
73
88
  hash[:foo] = -1
74
89
  hash[:bar] = 1
75
90
  hash[:baz] = 1
76
- options = FinderOptions.new(:order => 'foo desc, bar, baz').options[:sort].should == hash
91
+ FinderOptions.to_mongo_options(:order => 'foo desc, bar, baz')[:sort].should == hash
77
92
  end
78
93
  end
79
94
 
80
95
  context "offset" do
81
96
  should "default to 0" do
82
- FinderOptions.new({}).options[:offset].should == 0
97
+ FinderOptions.to_mongo_options({})[:offset].should == 0
83
98
  end
84
99
 
85
100
  should "use offset provided" do
86
- FinderOptions.new(:offset => 2).options[:offset].should == 2
101
+ FinderOptions.to_mongo_options(:offset => 2)[:offset].should == 2
87
102
  end
88
103
 
89
104
  should "covert string to integer" do
90
- FinderOptions.new(:offset => '2').options[:offset].should == 2
105
+ FinderOptions.to_mongo_options(:offset => '2')[:offset].should == 2
91
106
  end
92
107
  end
93
108
 
94
109
  context "limit" do
95
110
  should "default to 0" do
96
- FinderOptions.new({}).options[:limit].should == 0
111
+ FinderOptions.to_mongo_options({})[:limit].should == 0
97
112
  end
98
113
 
99
114
  should "use offset provided" do
100
- FinderOptions.new(:limit => 2).options[:limit].should == 2
115
+ FinderOptions.to_mongo_options(:limit => 2)[:limit].should == 2
101
116
  end
102
117
 
103
118
  should "covert string to integer" do
104
- FinderOptions.new(:limit => '2').options[:limit].should == 2
119
+ FinderOptions.to_mongo_options(:limit => '2')[:limit].should == 2
105
120
  end
106
121
  end
107
122
 
108
123
  context "fields" do
109
124
  should "default to nil" do
110
- FinderOptions.new({}).options[:fields].should be(nil)
125
+ FinderOptions.to_mongo_options({})[:fields].should be(nil)
111
126
  end
112
127
 
113
128
  should "be converted to nil if empty string" do
114
- FinderOptions.new(:fields => '').options[:fields].should be(nil)
129
+ FinderOptions.to_mongo_options(:fields => '')[:fields].should be(nil)
115
130
  end
116
131
 
117
132
  should "be converted to nil if []" do
118
- FinderOptions.new(:fields => []).options[:fields].should be(nil)
133
+ FinderOptions.to_mongo_options(:fields => [])[:fields].should be(nil)
119
134
  end
120
135
 
121
136
  should "should work with array" do
122
- FinderOptions.new({:fields => %w(a b)}).options[:fields].should == %w(a b)
137
+ FinderOptions.to_mongo_options({:fields => %w(a b)})[:fields].should == %w(a b)
123
138
  end
124
139
 
125
140
  should "convert comma separated list to array" do
126
- FinderOptions.new({:fields => 'a, b'}).options[:fields].should == %w(a b)
141
+ FinderOptions.to_mongo_options({:fields => 'a, b'})[:fields].should == %w(a b)
127
142
  end
128
143
 
129
144
  should "also work as select" do
data/test/test_key.rb CHANGED
@@ -2,7 +2,7 @@ require 'test_helper'
2
2
 
3
3
  class Address
4
4
  include MongoMapper::EmbeddedDocument
5
-
5
+
6
6
  key :address, String
7
7
  key :city, String
8
8
  key :state, String
@@ -11,65 +11,65 @@ end
11
11
 
12
12
  class KeyTest < Test::Unit::TestCase
13
13
  include MongoMapper
14
-
14
+
15
15
  context "The Key Class" do
16
16
  should "have the native types defined" do
17
- Key::NativeTypes.should == [String, Float, Time, Integer, Boolean, Array, Hash]
17
+ Key::NativeTypes.should == [String, Float, Time, Integer, Boolean, Array, Hash, Ref]
18
18
  end
19
19
  end
20
-
20
+
21
21
  context "Initializing a new key" do
22
22
  should "allow setting the name" do
23
23
  Key.new(:foo, String).name.should == 'foo'
24
24
  end
25
-
25
+
26
26
  should "allow setting the type" do
27
27
  Key.new(:foo, Integer).type.should be(Integer)
28
28
  end
29
-
29
+
30
30
  should "allow setting options" do
31
31
  Key.new(:foo, Integer, :required => true).options[:required].should be(true)
32
32
  end
33
-
33
+
34
34
  should "symbolize option keys" do
35
35
  Key.new(:foo, Integer, 'required' => true).options[:required].should be(true)
36
36
  end
37
37
  end
38
-
38
+
39
39
  context "A key" do
40
40
  should "be equal to another key with same name and type" do
41
41
  Key.new(:name, String).should == Key.new(:name, String)
42
42
  end
43
-
43
+
44
44
  should "not be equal to another key with different name" do
45
45
  Key.new(:name, String).should_not == Key.new(:foo, String)
46
46
  end
47
-
47
+
48
48
  should "not be equal to another key with different type" do
49
49
  Key.new(:name, String).should_not == Key.new(:name, Integer)
50
50
  end
51
-
51
+
52
52
  should "know if it is native" do
53
53
  Key.new(:name, String).native?.should be_true
54
54
  end
55
-
55
+
56
56
  should "know if it is not native" do
57
57
  klass = Class.new
58
58
  Key.new(:name, klass).native?.should be_false
59
59
  end
60
-
60
+
61
61
  should "know if it is a embedded_document" do
62
62
  klass = Class.new do
63
63
  include MongoMapper::EmbeddedDocument
64
64
  end
65
65
  Key.new(:name, klass).embedded_document?.should be_true
66
66
  end
67
-
67
+
68
68
  should "know if it is not a embedded_document" do
69
69
  Key.new(:name, String).embedded_document?.should be_false
70
70
  end
71
71
  end
72
-
72
+
73
73
  context "setting a value" do
74
74
  should "correctly typecast Strings" do
75
75
  key = Key.new(:foo, String)
@@ -101,25 +101,25 @@ class KeyTest < Test::Unit::TestCase
101
101
  key = Key.new(:foo, Date)
102
102
  key.set('2000-01-01').should == Date.new(2000, 1, 1)
103
103
  end
104
-
104
+
105
105
  should "correctly typecast Boolean" do
106
106
  key = Key.new(:foo, Boolean)
107
107
  ['false', false, 'f', '0', 0].each do |b|
108
108
  key.set(b).should == false
109
109
  end
110
-
110
+
111
111
  ['true', true, 't', '1', 1].each do |b|
112
112
  key.set(b).should == true
113
113
  end
114
114
  end
115
-
115
+
116
116
  should "correctly typecast Array" do
117
117
  key = Key.new(:foo, Array)
118
118
  key.set([1,2,3,4]).should == [1,2,3,4]
119
119
  key.set({'1' => '2', '3' => '4'}).should == [['1', '2'], ['3', '4']]
120
120
  key.set('1').should == ['1']
121
121
  end
122
-
122
+
123
123
  should "correctly typecast Hash using indifferent access" do
124
124
  key = Key.new(:foo, Hash)
125
125
  key.set(:foo => 'bar')[:foo].should == 'bar'
@@ -128,13 +128,13 @@ class KeyTest < Test::Unit::TestCase
128
128
  key.set(:foo => {:bar => 'baz'})['foo']['bar'].should == 'baz'
129
129
  end
130
130
  end
131
-
131
+
132
132
  context "getting a value" do
133
133
  should "work" do
134
134
  key = Key.new(:foo, String)
135
135
  key.get('bar').should == 'bar'
136
136
  end
137
-
137
+
138
138
  context "for a key with a default value set" do
139
139
  setup do
140
140
  @key = Key.new(:foo, String, :default => 'baz')
@@ -143,34 +143,34 @@ class KeyTest < Test::Unit::TestCase
143
143
  should "return default value if value nil" do
144
144
  @key.get(nil).should == 'baz'
145
145
  end
146
-
146
+
147
147
  should "return value if not blank" do
148
148
  @key.get('foobar').should == 'foobar'
149
149
  end
150
150
  end
151
-
151
+
152
152
  context "for a boolean key" do
153
153
  should "allow setting default to false" do
154
154
  Key.new(:active, Boolean, :default => false).get(nil).should be_false
155
155
  end
156
-
156
+
157
157
  should "allow setting default to true" do
158
158
  Key.new(:active, Boolean, :default => true).get(nil).should be_true
159
159
  end
160
160
  end
161
-
161
+
162
162
  context "for an array" do
163
163
  should "return array" do
164
164
  key = Key.new(:foo, Array)
165
165
  key.get([1,2]).should == [1,2]
166
166
  end
167
-
167
+
168
168
  should "default to empty array" do
169
169
  key = Key.new(:foo, Array)
170
170
  key.get(nil).should == []
171
171
  end
172
172
  end
173
-
173
+
174
174
  context "for a hash" do
175
175
  should "default to empty hash" do
176
176
  key = Key.new(:foo, Hash)
@@ -183,13 +183,13 @@ class KeyTest < Test::Unit::TestCase
183
183
  key.get({:foo => 'bar'})[:foo].should == 'bar'
184
184
  end
185
185
  end
186
-
186
+
187
187
  context "for a embedded_document" do
188
- should "default to nil" do
188
+ should "default to nil" do
189
189
  key = Key.new(:foo, Address)
190
190
  key.get(nil).should be_nil
191
191
  end
192
-
192
+
193
193
  should "return instance if instance" do
194
194
  address = Address.new(:city => 'South Bend', :state => 'IN', :zip => 46544)
195
195
  key = Key.new(:foo, Address)