djsun-mongo_mapper 0.5.2.1 → 0.5.3.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/README.rdoc CHANGED
@@ -2,11 +2,7 @@
2
2
 
3
3
  Awesome gem for modeling your domain and storing it in mongo.
4
4
 
5
- Releases are tagged on github and also released as gems on github and rubyforge. Master is pushed to whenever I add a patch or a new feature. To build from master, you can clone the code, generate the updated gemspec, build the gem and install.
6
-
7
- * rake gemspec
8
- * gem build mongo_mapper.gemspec
9
- * gem install the gem that was built
5
+ Releases are tagged on github and released on gemcutter. Master is pushed to whenever I add a patch or a new feature, but I do not release a new gem version each time I push.
10
6
 
11
7
  == Note on Patches/Pull Requests
12
8
 
@@ -16,10 +12,25 @@ Releases are tagged on github and also released as gems on github and rubyforge.
16
12
  * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself in another branch so I can ignore when I pull)
17
13
  * Send me a pull request. Bonus points for topic branches.
18
14
 
15
+ == Install
16
+
17
+ MongoMapper is only released on gemcutter. To install, you can setup gemcutter as your default gem source.
18
+
19
+ $ gem install gemcutter
20
+ $ gem tumble
21
+
22
+ Then you can install MM:
23
+
24
+ $ gem install mongo_mapper
25
+
26
+ You can also just declare the source:
27
+
28
+ $ gem install mongo_mapper -s http://gemcutter.org
29
+
19
30
  == Dependencies
20
31
 
21
- * ActiveSupport (activesupport)
22
- * Mongo Ruby Driver (mongodb-mongo)
32
+ * ActiveSupport (typically the latest version)
33
+ * Mongo Ruby Driver (mongo)
23
34
  * My fork of the validatable gem (jnunemaker-validatable)
24
35
 
25
36
  == Documentation
data/Rakefile CHANGED
@@ -13,7 +13,7 @@ begin
13
13
 
14
14
  gem.add_dependency('activesupport')
15
15
  gem.add_dependency('mongo', '0.15.1')
16
- gem.add_dependency('jnunemaker-validatable', '1.7.3')
16
+ gem.add_dependency('jnunemaker-validatable', '1.7.4')
17
17
 
18
18
  gem.add_development_dependency('mocha', '0.9.4')
19
19
  gem.add_development_dependency('jnunemaker-matchy', '0.4.0')
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.2.1
1
+ 0.5.3.1
@@ -1,15 +1,15 @@
1
- # Generated by jeweler"
2
- # DO NOT EDIT THIS FILE"
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`"
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{djsun-mongo_mapper}
8
- s.version = "0.5.2.1"
8
+ s.version = "0.5.3.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["John Nunemaker"]
12
- s.date = %q{2009-10-09}
12
+ s.date = %q{2009-10-11}
13
13
  s.default_executable = %q{mmconsole}
14
14
  s.email = %q{nunemaker@gmail.com}
15
15
  s.executables = ["mmconsole"]
@@ -143,22 +143,21 @@ Gem::Specification.new do |s|
143
143
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
144
144
  s.add_runtime_dependency(%q<activesupport>, [">= 0"])
145
145
  s.add_runtime_dependency(%q<mongo>, ["= 0.15.1"])
146
- s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.7.3"])
146
+ s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.7.4"])
147
147
  s.add_development_dependency(%q<mocha>, ["= 0.9.4"])
148
148
  s.add_development_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
149
149
  else
150
150
  s.add_dependency(%q<activesupport>, [">= 0"])
151
151
  s.add_dependency(%q<mongo>, ["= 0.15.1"])
152
- s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.3"])
152
+ s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.4"])
153
153
  s.add_dependency(%q<mocha>, ["= 0.9.4"])
154
154
  s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
155
155
  end
156
156
  else
157
157
  s.add_dependency(%q<activesupport>, [">= 0"])
158
158
  s.add_dependency(%q<mongo>, ["= 0.15.1"])
159
- s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.3"])
159
+ s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.4"])
160
160
  s.add_dependency(%q<mocha>, ["= 0.9.4"])
161
161
  s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
162
162
  end
163
163
  end
164
-
data/lib/mongo_mapper.rb CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
 
3
3
  gem 'activesupport'
4
4
  gem 'mongo', '0.15.1'
5
- gem 'jnunemaker-validatable', '1.7.3'
5
+ gem 'jnunemaker-validatable', '1.7.4'
6
6
 
7
7
  require 'activesupport'
8
8
  require 'mongo'
@@ -42,6 +42,21 @@ module MongoMapper
42
42
  @@database ||= MongoMapper.connection.db(@@database_name)
43
43
  end
44
44
 
45
+ def self.ensured_indexes
46
+ @@ensured_indexes ||= []
47
+ end
48
+
49
+ def self.ensure_index(klass, keys, options={})
50
+ ensured_indexes << {:klass => klass, :keys => keys, :options => options}
51
+ end
52
+
53
+ def self.ensure_indexes!
54
+ ensured_indexes.each do |index|
55
+ unique = index[:options].delete(:unique)
56
+ index[:klass].collection.create_index(index[:keys], unique)
57
+ end
58
+ end
59
+
45
60
  module Finders
46
61
  def dynamic_find(finder, args)
47
62
  attributes = {}
@@ -28,6 +28,22 @@ module MongoMapper
28
28
  end
29
29
 
30
30
  module ClassMethods
31
+ def key(*args)
32
+ key = super
33
+ create_indexes_for(key)
34
+ key
35
+ end
36
+
37
+ def ensure_index(name_or_array, options={})
38
+ keys_to_index = if name_or_array.is_a?(Array)
39
+ name_or_array.map { |pair| [pair[0], pair[1]] }
40
+ else
41
+ name_or_array
42
+ end
43
+
44
+ MongoMapper.ensure_index(self, keys_to_index, options)
45
+ end
46
+
31
47
  def find(*args)
32
48
  options = args.extract_options!
33
49
  case args.first
@@ -90,6 +106,10 @@ module MongoMapper
90
106
  collection.find(FinderOptions.to_mongo_criteria(conditions)).count
91
107
  end
92
108
 
109
+ def exists?(conditions={})
110
+ !count(conditions).zero?
111
+ end
112
+
93
113
  def create(*docs)
94
114
  instances = []
95
115
  docs = [{}] if docs.blank?
@@ -187,9 +207,20 @@ module MongoMapper
187
207
  end
188
208
 
189
209
  private
210
+ def create_indexes_for(key)
211
+ ensure_index key.name if key.options[:index]
212
+ end
213
+
190
214
  def find_every(options)
191
215
  criteria, options = FinderOptions.new(options).to_a
192
- collection.find(criteria, options).to_a.map { |doc| new(doc) }
216
+ collection.find(criteria, options).to_a.map do |doc|
217
+ begin
218
+ klass = doc['_type'].present? ? doc['_type'].constantize : self
219
+ klass.new(doc)
220
+ rescue NameError
221
+ new(doc)
222
+ end
223
+ end
193
224
  end
194
225
 
195
226
  def invert_order_clause(order)
@@ -244,7 +275,7 @@ module MongoMapper
244
275
  end
245
276
  end
246
277
 
247
- module InstanceMethods
278
+ module InstanceMethods
248
279
  def collection
249
280
  self.class.collection
250
281
  end
@@ -22,6 +22,10 @@ module MongoMapper
22
22
  end
23
23
 
24
24
  module ClassMethods
25
+ def logger
26
+ MongoMapper.logger
27
+ end
28
+
25
29
  def inherited(subclass)
26
30
  unless subclass.embeddable?
27
31
  subclass.set_collection_name(collection_name)
@@ -49,30 +53,13 @@ module MongoMapper
49
53
  keys[key.name] = key
50
54
 
51
55
  create_accessors_for(key)
52
- add_to_subclasses(*args)
53
- apply_validations_for(key)
54
- create_indexes_for(key)
55
-
56
+ create_key_in_subclasses(*args)
57
+ create_validations_for(key)
58
+
56
59
  key
57
60
  end
58
- end
59
-
60
- def add_to_subclasses(*args)
61
- return if subclasses.blank?
62
-
63
- subclasses.each do |subclass|
64
- subclass.key(*args)
65
- end
66
- end
67
-
68
- def ensure_index(name_or_array, options={})
69
- keys_to_index = if name_or_array.is_a?(Array)
70
- name_or_array.map { |pair| [pair[0], pair[1]] }
71
- else
72
- name_or_array
73
- end
74
-
75
- collection.create_index(keys_to_index, options.delete(:unique))
61
+
62
+ key
76
63
  end
77
64
 
78
65
  def embeddable?
@@ -129,12 +116,16 @@ module MongoMapper
129
116
  end_eval
130
117
  include accessors_module
131
118
  end
119
+
120
+ def create_key_in_subclasses(*args)
121
+ return if subclasses.blank?
132
122
 
133
- def create_indexes_for(key)
134
- ensure_index key.name if key.options[:index]
123
+ subclasses.each do |subclass|
124
+ subclass.key(*args)
125
+ end
135
126
  end
136
127
 
137
- def apply_validations_for(key)
128
+ def create_validations_for(key)
138
129
  attribute = key.name.to_sym
139
130
 
140
131
  if key.options[:required]
@@ -169,6 +160,10 @@ module MongoMapper
169
160
  end
170
161
 
171
162
  module InstanceMethods
163
+ def logger
164
+ self.class.logger
165
+ end
166
+
172
167
  def initialize(attrs={})
173
168
  unless attrs.nil?
174
169
  self.class.associations.each_pair do |name, association|
@@ -42,10 +42,21 @@ module MongoMapper
42
42
  end
43
43
  end
44
44
 
45
+ OptionKeys = [:fields, :select, :skip, :offset, :limit, :sort, :order]
46
+
45
47
  def initialize(options)
46
48
  raise ArgumentError, "FinderOptions must be a hash" unless options.is_a?(Hash)
47
- @options = options.symbolize_keys
48
- @conditions = @options.delete(:conditions) || {}
49
+
50
+ options = options.symbolize_keys
51
+ @options, @conditions = {}, options.delete(:conditions) || {}
52
+
53
+ options.each_pair do |key, value|
54
+ if OptionKeys.include?(key)
55
+ @options[key] = value
56
+ else
57
+ @conditions[key] = value
58
+ end
59
+ end
49
60
  end
50
61
 
51
62
  def criteria
@@ -131,7 +131,11 @@ end
131
131
 
132
132
  class Time
133
133
  def self.to_mongo(value)
134
- to_utc_time(value)
134
+ if value.nil? || value == ''
135
+ nil
136
+ else
137
+ to_utc_time(value)
138
+ end
135
139
  end
136
140
 
137
141
  def self.from_mongo(value)
data/mongo_mapper.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongo_mapper}
8
- s.version = "0.5.2"
8
+ s.version = "0.5.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["John Nunemaker"]
12
- s.date = %q{2009-10-08}
12
+ s.date = %q{2009-10-11}
13
13
  s.default_executable = %q{mmconsole}
14
14
  s.email = %q{nunemaker@gmail.com}
15
15
  s.executables = ["mmconsole"]
@@ -142,20 +142,20 @@ Gem::Specification.new do |s|
142
142
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
143
143
  s.add_runtime_dependency(%q<activesupport>, [">= 0"])
144
144
  s.add_runtime_dependency(%q<mongo>, ["= 0.15.1"])
145
- s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.7.3"])
145
+ s.add_runtime_dependency(%q<jnunemaker-validatable>, ["= 1.7.4"])
146
146
  s.add_development_dependency(%q<mocha>, ["= 0.9.4"])
147
147
  s.add_development_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
148
148
  else
149
149
  s.add_dependency(%q<activesupport>, [">= 0"])
150
150
  s.add_dependency(%q<mongo>, ["= 0.15.1"])
151
- s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.3"])
151
+ s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.4"])
152
152
  s.add_dependency(%q<mocha>, ["= 0.9.4"])
153
153
  s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
154
154
  end
155
155
  else
156
156
  s.add_dependency(%q<activesupport>, [">= 0"])
157
157
  s.add_dependency(%q<mongo>, ["= 0.15.1"])
158
- s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.3"])
158
+ s.add_dependency(%q<jnunemaker-validatable>, ["= 1.7.4"])
159
159
  s.add_dependency(%q<mocha>, ["= 0.9.4"])
160
160
  s.add_dependency(%q<jnunemaker-matchy>, ["= 0.4.0"])
161
161
  end
@@ -45,4 +45,11 @@ module CustomMatchers
45
45
  actual == expected_message
46
46
  end
47
47
  end
48
+
49
+ custom_matcher :have_index do |receiver, matcher, args|
50
+ index_name = args[0]
51
+ matcher.positive_failure_message = "#{receiver} does not have index named #{index_name}, but should"
52
+ matcher.negative_failure_message = "#{receiver} does have index named #{index_name}, but should not"
53
+ !receiver.collection.index_information.detect { |index| index[0] == index_name }.nil?
54
+ end
48
55
  end
@@ -9,7 +9,7 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
9
9
 
10
10
  should "default to nil" do
11
11
  status = Status.new
12
- status.target.nil?.should == true
12
+ status.target.nil?.should be_true
13
13
  status.target.inspect.should == "nil"
14
14
  end
15
15
 
@@ -20,7 +20,7 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
20
20
  status.save.should be_true
21
21
 
22
22
  from_db = Status.find(status.id)
23
- from_db.target.nil?.should == false
23
+ from_db.target.nil?.should be_false
24
24
  from_db.target_id.should == project.id
25
25
  from_db.target_type.should == "Project"
26
26
  from_db.target.name.should == "mongomapper"
@@ -34,9 +34,9 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
34
34
 
35
35
  from_db = Status.find(status.id)
36
36
  from_db.target = nil
37
- from_db.target_type.nil?.should == true
38
- from_db.target_id.nil?.should == true
39
- from_db.target.nil?.should == true
37
+ from_db.target_type.nil?.should be_true
38
+ from_db.target_id.nil?.should be_true
39
+ from_db.target.nil?.should be_true
40
40
  end
41
41
 
42
42
  context "association id set but document not found" do
@@ -49,7 +49,7 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
49
49
  end
50
50
 
51
51
  should "return nil instead of raising error" do
52
- @status.target.nil?.should == true
52
+ @status.target.nil?.should be_true
53
53
  end
54
54
  end
55
55
  end
@@ -10,7 +10,7 @@ class BelongsToProxyTest < Test::Unit::TestCase
10
10
  should "default to nil" do
11
11
  status = Status.new
12
12
  status.project.nil?.should == true
13
- status.project.inspect.should == "nil"
13
+ status.project.inspect.should == 'nil'
14
14
  end
15
15
 
16
16
  should "be able to replace the association" do
@@ -20,7 +20,7 @@ class BelongsToProxyTest < Test::Unit::TestCase
20
20
  status.save.should be_true
21
21
 
22
22
  from_db = Status.find(status.id)
23
- from_db.project.should_not be_nil
23
+ from_db.project.nil?.should be_false
24
24
  from_db.project.name.should == "mongomapper"
25
25
  end
26
26
 
@@ -32,8 +32,8 @@ class BelongsToProxyTest < Test::Unit::TestCase
32
32
 
33
33
  from_db = Status.find(status.id)
34
34
  from_db.project = nil
35
- from_db.project.nil?.should == true
36
- from_db.project.inspect.should == "nil"
35
+ from_db.project.nil?.should be_true
36
+ from_db.project.inspect.should == 'nil'
37
37
  end
38
38
 
39
39
  context "association id set but document not found" do
@@ -42,8 +42,8 @@ class BelongsToProxyTest < Test::Unit::TestCase
42
42
  end
43
43
 
44
44
  should "return nil instead of raising error" do
45
- @status.project.nil?.should == true
46
- @status.project.inspect.should == "nil"
45
+ @status.project.nil?.should be_true
46
+ @status.project.inspect.should == 'nil'
47
47
  end
48
48
  end
49
49
  end
@@ -142,6 +142,27 @@ class DocumentTest < Test::Unit::TestCase
142
142
  end
143
143
  end
144
144
 
145
+ context "Using key with custom type with default" do
146
+ setup do
147
+ @document.key :window, WindowSize, :default => WindowSize.new(600, 480)
148
+ end
149
+
150
+ should "default to default" do
151
+ doc = @document.new
152
+ doc.window.should == WindowSize.new(600, 480)
153
+
154
+ end
155
+
156
+ should "save and load from mongo" do
157
+ doc = @document.new
158
+ doc.save
159
+
160
+ from_db = @document.find(doc.id)
161
+ from_db.window.should == WindowSize.new(600, 480)
162
+ end
163
+ end
164
+
165
+
145
166
  context "Creating a single document" do
146
167
  setup do
147
168
  @doc_instance = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
@@ -295,7 +316,12 @@ class DocumentTest < Test::Unit::TestCase
295
316
  @document.find([@doc1.id]).should == [@doc1]
296
317
  end
297
318
  end
298
-
319
+
320
+ should "be able to find using condition auto-detection" do
321
+ @document.first(:first_name => 'John').should == @doc1
322
+ @document.all(:last_name => 'Nunemaker', :order => 'age desc').should == [@doc1, @doc3]
323
+ end
324
+
299
325
  context "with :all" do
300
326
  should "find all documents" do
301
327
  @document.find(:all, :order => 'first_name').should == [@doc1, @doc3, @doc2]
@@ -694,39 +720,31 @@ class DocumentTest < Test::Unit::TestCase
694
720
  end
695
721
 
696
722
  should "allow creating index for a key" do
697
- index_name = nil
698
- lambda {
699
- index_name = @document.ensure_index :first_name
700
- }.should change { @document.collection.index_information.size }.by(1)
701
-
702
- index_name.should == 'first_name_1'
703
- index = @document.collection.index_information[index_name]
704
- index.should_not be_nil
705
- index.should include(['first_name', 1])
723
+ @document.ensure_index :first_name
724
+ MongoMapper.ensure_indexes!
725
+
726
+ @document.should have_index('first_name_1')
706
727
  end
707
728
 
708
729
  should "allow creating unique index for a key" do
709
- @document.collection.expects(:create_index).with(:first_name, true)
710
730
  @document.ensure_index :first_name, :unique => true
731
+ MongoMapper.ensure_indexes!
732
+
733
+ @document.should have_index('first_name_1')
711
734
  end
712
735
 
713
736
  should "allow creating index on multiple keys" do
714
- index_name = nil
715
- lambda {
716
- index_name = @document.ensure_index [[:first_name, 1], [:last_name, -1]]
717
- }.should change { @document.collection.index_information.size }.by(1)
718
-
719
- [ 'first_name_1_last_name_-1', 'last_name_-1_first_name_1' ].should include(index_name)
720
-
721
- index = @document.collection.index_information[index_name]
722
- index.should_not be_nil
723
- index.should include(['first_name', 1])
724
- index.should include(['last_name', -1])
737
+ @document.ensure_index [[:first_name, 1], [:last_name, -1]]
738
+ MongoMapper.ensure_indexes!
739
+
740
+ @document.should have_index('last_name_-1_first_name_1')
725
741
  end
726
742
 
727
743
  should "work with :index shortcut when defining key" do
728
- @document.expects(:ensure_index).with('father').returns(nil)
729
744
  @document.key :father, String, :index => true
745
+ MongoMapper.ensure_indexes!
746
+
747
+ @document.should have_index('father_1')
730
748
  end
731
749
  end
732
750
  end # Document Class Methods
@@ -923,6 +941,57 @@ class DocumentTest < Test::Unit::TestCase
923
941
  end
924
942
  end
925
943
  end
944
+
945
+ context "Single collection inheritance" do
946
+ setup do
947
+ class ::DocParent
948
+ include MongoMapper::Document
949
+ key :_type, String
950
+ end
951
+
952
+ class ::DocChild < ::DocParent; end
953
+ DocParent.collection.clear
954
+
955
+ @parent = DocParent.new({:name => "Daddy Warbucks"})
956
+ @child = DocChild.new({:name => "Little Orphan Annie"})
957
+ end
958
+
959
+ teardown do
960
+ Object.send :remove_const, 'DocParent' if defined?(::DocParent)
961
+ Object.send :remove_const, 'DocChild' if defined?(::DocChild)
962
+ end
963
+
964
+ should "use the same collection in the subclass" do
965
+ DocChild.collection.name.should == DocParent.collection.name
966
+ end
967
+
968
+ should "assign the class name into the _type property" do
969
+ @parent._type.should == 'DocParent'
970
+ @child._type.should == 'DocChild'
971
+ end
972
+
973
+ should "load the document with the assigned type" do
974
+ @parent.save
975
+ @child.save
976
+
977
+ collection = DocParent.find(:all)
978
+ collection.size.should == 2
979
+ collection.first.should be_kind_of(DocParent)
980
+ collection.first.name.should == "Daddy Warbucks"
981
+ collection.last.should be_kind_of(DocChild)
982
+ collection.last.name.should == "Little Orphan Annie"
983
+ end
984
+
985
+ should "gracefully handle when the type can't be constantized" do
986
+ doc = DocParent.new(:name => 'Nunes')
987
+ doc._type = 'FoobarBaz'
988
+ doc.save
989
+
990
+ collection = DocParent.all
991
+ collection.last.should == doc
992
+ collection.last.should be_kind_of(DocParent)
993
+ end
994
+ end
926
995
 
927
996
  context "timestamping" do
928
997
  setup do
@@ -961,4 +1030,27 @@ class DocumentTest < Test::Unit::TestCase
961
1030
  from_db.updated_at.to_i.should_not == old_updated_at.to_i
962
1031
  end
963
1032
  end
1033
+
1034
+ context "#exist?" do
1035
+ setup do
1036
+ @doc = @document.create(:first_name => "James", :age => 27)
1037
+ end
1038
+
1039
+ should "be true when at least one document exists" do
1040
+ @document.exists?.should == true
1041
+ end
1042
+
1043
+ should "be false when no documents exist" do
1044
+ @doc.destroy
1045
+ @document.exists?.should == false
1046
+ end
1047
+
1048
+ should "be true when at least one document exists that matches the conditions" do
1049
+ @document.exists?(:first_name => "James").should == true
1050
+ end
1051
+
1052
+ should "be false when no documents exist with the provided conditions" do
1053
+ @document.exists?(:first_name => "Jean").should == false
1054
+ end
1055
+ end
964
1056
  end
@@ -12,7 +12,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
12
12
  end
13
13
  @document.collection.clear
14
14
  end
15
-
15
+
16
16
  context "Saving a document with an embedded document" do
17
17
  setup do
18
18
  @document.class_eval do
data/test/models.rb CHANGED
@@ -1,3 +1,29 @@
1
+ # custom type
2
+ class WindowSize
3
+ attr_reader :width, :height
4
+
5
+ def self.to_mongo(value)
6
+ value.to_a
7
+ end
8
+
9
+ def self.from_mongo(value)
10
+ value.is_a?(self) ? value : WindowSize.new(value)
11
+ end
12
+
13
+ def initialize(*args)
14
+ @width, @height = args.flatten
15
+ end
16
+
17
+ def to_a
18
+ [width, height]
19
+ end
20
+
21
+ def ==(other)
22
+ other.is_a?(self.class) && other.width == width && other.height == height
23
+ end
24
+ end
25
+
26
+
1
27
  class Post
2
28
  include MongoMapper::Document
3
29
 
@@ -8,8 +8,14 @@ class DocumentTest < Test::Unit::TestCase
8
8
  include MongoMapper::Document
9
9
  set_collection_name 'test'
10
10
  end
11
+ @document.collection.clear
11
12
  end
12
-
13
+
14
+ should "have logger method" do
15
+ @document.logger.should == MongoMapper.logger
16
+ @document.logger.should be_instance_of(Logger)
17
+ end
18
+
13
19
  should "track its descendants" do
14
20
  MongoMapper::Document.descendants.should include(@document)
15
21
  end
@@ -87,6 +93,12 @@ class DocumentTest < Test::Unit::TestCase
87
93
  end
88
94
  @document.collection.clear
89
95
  end
96
+
97
+ should "have access to logger" do
98
+ doc = @document.new
99
+ doc.logger.should == @document.logger
100
+ doc.logger.should be_instance_of(Logger)
101
+ end
90
102
 
91
103
  should "have access to the class's collection" do
92
104
  doc = @document.new
@@ -99,6 +111,13 @@ class DocumentTest < Test::Unit::TestCase
99
111
  @document.new.active.should be_true
100
112
  @document.new(:active => false).active.should be_false
101
113
  end
114
+
115
+ should "use default values if defined even when custom data type" do
116
+ @document.key :window, WindowSize, :default => WindowSize.new(600, 480)
117
+
118
+ doc = @document.new
119
+ doc.window.should == WindowSize.new(600, 480)
120
+ end
102
121
 
103
122
  context "root document" do
104
123
  should "have a nil _root_document" do
@@ -40,6 +40,11 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
40
40
  end
41
41
  end
42
42
 
43
+ should "give class access to logger" do
44
+ @klass.logger.should == MongoMapper.logger
45
+ @klass.logger.should be_instance_of(Logger)
46
+ end
47
+
43
48
  should "add _id key" do
44
49
  @klass.keys['_id'].should_not be_nil
45
50
  end
@@ -284,6 +289,12 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
284
289
  end
285
290
  end
286
291
 
292
+ should "have access to class logger" do
293
+ doc = @document.new
294
+ doc.logger.should == @document.logger
295
+ doc.logger.should be_instance_of(Logger)
296
+ end
297
+
287
298
  should "automatically have an _id key" do
288
299
  @document.keys.keys.should include('_id')
289
300
  end
@@ -8,7 +8,7 @@ class FinderOptionsTest < Test::Unit::TestCase
8
8
  lambda { FinderOptions.new(1) }.should raise_error(ArgumentError)
9
9
  end
10
10
 
11
- should "have symbolize the keys of the hash provided" do
11
+ should "symbolize the keys of the hash provided" do
12
12
  FinderOptions.new('offset' => 1).options.keys.map do |key|
13
13
  key.should be_instance_of(Symbol)
14
14
  end
@@ -179,4 +179,83 @@ class FinderOptionsTest < Test::Unit::TestCase
179
179
  FinderOptions.new(:select => %w(a b)).options[:fields].should == %w(a b)
180
180
  end
181
181
  end
182
+
183
+ context "Condition auto-detection" do
184
+ should "know :conditions are criteria" do
185
+ finder = FinderOptions.new(:conditions => {:foo => 'bar'})
186
+ finder.criteria.should == {:foo => 'bar'}
187
+ finder.options.keys.should_not include(:conditions)
188
+ end
189
+
190
+ should "know fields is an option" do
191
+ finder = FinderOptions.new(:fields => ['foo'])
192
+ finder.options[:fields].should == ['foo']
193
+ finder.criteria.keys.should_not include(:fields)
194
+ end
195
+
196
+ # select gets converted to fields so just checking keys
197
+ should "know select is an option" do
198
+ finder = FinderOptions.new(:select => 'foo')
199
+ finder.options.keys.should include(:sort)
200
+ finder.criteria.keys.should_not include(:select)
201
+ finder.criteria.keys.should_not include(:fields)
202
+ end
203
+
204
+ should "know skip is an option" do
205
+ finder = FinderOptions.new(:skip => 10)
206
+ finder.options[:skip].should == 10
207
+ finder.criteria.keys.should_not include(:skip)
208
+ end
209
+
210
+ # offset gets converted to skip so just checking keys
211
+ should "know offset is an option" do
212
+ finder = FinderOptions.new(:offset => 10)
213
+ finder.options.keys.should include(:skip)
214
+ finder.criteria.keys.should_not include(:skip)
215
+ finder.criteria.keys.should_not include(:offset)
216
+ end
217
+
218
+ should "know limit is an option" do
219
+ finder = FinderOptions.new(:limit => 10)
220
+ finder.options[:limit].should == 10
221
+ finder.criteria.keys.should_not include(:limit)
222
+ end
223
+
224
+ should "know sort is an option" do
225
+ finder = FinderOptions.new(:sort => [['foo', 1]])
226
+ finder.options[:sort].should == [['foo', 1]]
227
+ finder.criteria.keys.should_not include(:sort)
228
+ end
229
+
230
+ # order gets converted to sort so just checking keys
231
+ should "know order is an option" do
232
+ finder = FinderOptions.new(:order => 'foo')
233
+ finder.options.keys.should include(:sort)
234
+ finder.criteria.keys.should_not include(:sort)
235
+ end
236
+
237
+ should "work with full range of things" do
238
+ finder_options = FinderOptions.new({
239
+ :foo => 'bar',
240
+ :baz => true,
241
+ :sort => [['foo', 1]],
242
+ :fields => ['foo', 'baz'],
243
+ :limit => 10,
244
+ :skip => 10,
245
+ })
246
+
247
+ finder_options.criteria.should == {
248
+ :foo => 'bar',
249
+ :baz => true,
250
+ }
251
+
252
+ finder_options.options.should == {
253
+ :sort => [['foo', 1]],
254
+ :fields => ['foo', 'baz'],
255
+ :limit => 10,
256
+ :skip => 10,
257
+ }
258
+ end
259
+ end
260
+
182
261
  end # FinderOptionsTest
@@ -225,9 +225,12 @@ class SupportTest < Test::Unit::TestCase
225
225
  Time.to_mongo(Time.local(2009, 8, 15, 0, 0, 0)).zone.should == 'UTC'
226
226
  end
227
227
 
228
+ should "be nil if blank string" do
229
+ Time.to_mongo('').should be_nil
230
+ end
231
+
228
232
  should "not be nil if nil" do
229
- # Time.parse actually returns like right now
230
- Time.to_mongo(nil).should_not be_nil
233
+ Time.to_mongo(nil).should be_nil
231
234
  end
232
235
  end
233
236
 
@@ -244,6 +247,12 @@ class SupportTest < Test::Unit::TestCase
244
247
  Time.zone = nil
245
248
  end
246
249
 
250
+ should "be nil if blank string" do
251
+ Time.zone = 'Hawaii'
252
+ Time.to_mongo('').should be_nil
253
+ Time.zone = nil
254
+ end
255
+
247
256
  should "be nil if nil" do
248
257
  Time.zone = 'Hawaii'
249
258
  Time.to_mongo(nil).should be_nil
@@ -256,6 +265,10 @@ class SupportTest < Test::Unit::TestCase
256
265
  time = Time.now
257
266
  Time.from_mongo(time).should == time
258
267
  end
268
+
269
+ should "be nil if nil" do
270
+ Time.from_mongo(nil).should be_nil
271
+ end
259
272
  end
260
273
 
261
274
  context "Time#from_mongo with Time.zone" do
@@ -268,5 +281,11 @@ class SupportTest < Test::Unit::TestCase
268
281
 
269
282
  Time.zone = nil
270
283
  end
284
+
285
+ should "be nil if nil" do
286
+ Time.zone = 'Hawaii'
287
+ Time.from_mongo(nil).should be_nil
288
+ Time.zone = nil
289
+ end
271
290
  end
272
291
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: djsun-mongo_mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2.1
4
+ version: 0.5.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-09 00:00:00 -04:00
12
+ date: 2009-10-11 00:00:00 -04:00
13
13
  default_executable: mmconsole
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -40,7 +40,7 @@ dependencies:
40
40
  requirements:
41
41
  - - "="
42
42
  - !ruby/object:Gem::Version
43
- version: 1.7.3
43
+ version: 1.7.4
44
44
  version:
45
45
  - !ruby/object:Gem::Dependency
46
46
  name: mocha