mongo_mapper 0.5.2 → 0.5.3

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,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
+ 0.5.3
@@ -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 = {}
@@ -32,7 +32,17 @@ module MongoMapper
32
32
  def replace(v)
33
33
  raise NotImplementedError
34
34
  end
35
-
35
+
36
+ def inspect
37
+ load_target
38
+ @target.inspect
39
+ end
40
+
41
+ def nil?
42
+ load_target
43
+ @target.nil?
44
+ end
45
+
36
46
  protected
37
47
  def method_missing(method, *args)
38
48
  if load_target
@@ -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)
@@ -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,8 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
9
9
 
10
10
  should "default to nil" do
11
11
  status = Status.new
12
- status.target.should be_nil
12
+ status.target.nil?.should be_true
13
+ status.target.inspect.should == "nil"
13
14
  end
14
15
 
15
16
  should "be able to replace the association" do
@@ -19,7 +20,7 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
19
20
  status.save.should be_true
20
21
 
21
22
  from_db = Status.find(status.id)
22
- from_db.target.should_not be_nil
23
+ from_db.target.nil?.should be_false
23
24
  from_db.target_id.should == project.id
24
25
  from_db.target_type.should == "Project"
25
26
  from_db.target.name.should == "mongomapper"
@@ -33,9 +34,9 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
33
34
 
34
35
  from_db = Status.find(status.id)
35
36
  from_db.target = nil
36
- from_db.target_type.should be_nil
37
- from_db.target_id.should be_nil
38
- from_db.target.should be_nil
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
39
40
  end
40
41
 
41
42
  context "association id set but document not found" do
@@ -48,7 +49,7 @@ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
48
49
  end
49
50
 
50
51
  should "return nil instead of raising error" do
51
- @status.target.should be_nil
52
+ @status.target.nil?.should be_true
52
53
  end
53
54
  end
54
55
  end
@@ -9,7 +9,8 @@ class BelongsToProxyTest < Test::Unit::TestCase
9
9
 
10
10
  should "default to nil" do
11
11
  status = Status.new
12
- status.project.should be_nil
12
+ status.project.nil?.should == true
13
+ status.project.inspect.should == 'nil'
13
14
  end
14
15
 
15
16
  should "be able to replace the association" do
@@ -19,7 +20,7 @@ class BelongsToProxyTest < Test::Unit::TestCase
19
20
  status.save.should be_true
20
21
 
21
22
  from_db = Status.find(status.id)
22
- from_db.project.should_not be_nil
23
+ from_db.project.nil?.should be_false
23
24
  from_db.project.name.should == "mongomapper"
24
25
  end
25
26
 
@@ -31,7 +32,8 @@ class BelongsToProxyTest < Test::Unit::TestCase
31
32
 
32
33
  from_db = Status.find(status.id)
33
34
  from_db.project = nil
34
- from_db.project.should be_nil
35
+ from_db.project.nil?.should be_true
36
+ from_db.project.inspect.should == 'nil'
35
37
  end
36
38
 
37
39
  context "association id set but document not found" do
@@ -40,7 +42,8 @@ class BelongsToProxyTest < Test::Unit::TestCase
40
42
  end
41
43
 
42
44
  should "return nil instead of raising error" do
43
- @status.project.should be_nil
45
+ @status.project.nil?.should be_true
46
+ @status.project.inspect.should == 'nil'
44
47
  end
45
48
  end
46
49
  end
@@ -141,6 +141,27 @@ class DocumentTest < Test::Unit::TestCase
141
141
  end
142
142
  end
143
143
 
144
+ context "Using key with custom type with default" do
145
+ setup do
146
+ @document.key :window, WindowSize, :default => WindowSize.new(600, 480)
147
+ end
148
+
149
+ should "default to default" do
150
+ doc = @document.new
151
+ doc.window.should == WindowSize.new(600, 480)
152
+
153
+ end
154
+
155
+ should "save and load from mongo" do
156
+ doc = @document.new
157
+ doc.save
158
+
159
+ from_db = @document.find(doc.id)
160
+ from_db.window.should == WindowSize.new(600, 480)
161
+ end
162
+ end
163
+
164
+
144
165
  context "Creating a single document" do
145
166
  setup do
146
167
  @doc_instance = @document.create({:first_name => 'John', :last_name => 'Nunemaker', :age => '27'})
@@ -294,7 +315,12 @@ class DocumentTest < Test::Unit::TestCase
294
315
  @document.find([@doc1.id]).should == [@doc1]
295
316
  end
296
317
  end
297
-
318
+
319
+ should "be able to find using condition auto-detection" do
320
+ @document.first(:first_name => 'John').should == @doc1
321
+ @document.all(:last_name => 'Nunemaker', :order => 'age desc').should == [@doc1, @doc3]
322
+ end
323
+
298
324
  context "with :all" do
299
325
  should "find all documents" do
300
326
  @document.find(:all, :order => 'first_name').should == [@doc1, @doc3, @doc2]
@@ -693,39 +719,31 @@ class DocumentTest < Test::Unit::TestCase
693
719
  end
694
720
 
695
721
  should "allow creating index for a key" do
696
- index_name = nil
697
- lambda {
698
- index_name = @document.ensure_index :first_name
699
- }.should change { @document.collection.index_information.size }.by(1)
700
-
701
- index_name.should == 'first_name_1'
702
- index = @document.collection.index_information[index_name]
703
- index.should_not be_nil
704
- index.should include(['first_name', 1])
722
+ @document.ensure_index :first_name
723
+ MongoMapper.ensure_indexes!
724
+
725
+ @document.should have_index('first_name_1')
705
726
  end
706
727
 
707
728
  should "allow creating unique index for a key" do
708
- @document.collection.expects(:create_index).with(:first_name, true)
709
729
  @document.ensure_index :first_name, :unique => true
730
+ MongoMapper.ensure_indexes!
731
+
732
+ @document.should have_index('first_name_1')
710
733
  end
711
734
 
712
735
  should "allow creating index on multiple keys" do
713
- index_name = nil
714
- lambda {
715
- index_name = @document.ensure_index [[:first_name, 1], [:last_name, -1]]
716
- }.should change { @document.collection.index_information.size }.by(1)
717
-
718
- [ 'first_name_1_last_name_-1', 'last_name_-1_first_name_1' ].should include(index_name)
719
-
720
- index = @document.collection.index_information[index_name]
721
- index.should_not be_nil
722
- index.should include(['first_name', 1])
723
- index.should include(['last_name', -1])
736
+ @document.ensure_index [[:first_name, 1], [:last_name, -1]]
737
+ MongoMapper.ensure_indexes!
738
+
739
+ @document.should have_index('last_name_-1_first_name_1')
724
740
  end
725
741
 
726
742
  should "work with :index shortcut when defining key" do
727
- @document.expects(:ensure_index).with('father').returns(nil)
728
743
  @document.key :father, String, :index => true
744
+ MongoMapper.ensure_indexes!
745
+
746
+ @document.should have_index('father_1')
729
747
  end
730
748
  end
731
749
  end # Document Class Methods
@@ -918,6 +936,57 @@ class DocumentTest < Test::Unit::TestCase
918
936
  end
919
937
  end
920
938
  end
939
+
940
+ context "Single collection inheritance" do
941
+ setup do
942
+ class ::DocParent
943
+ include MongoMapper::Document
944
+ key :_type, String
945
+ end
946
+
947
+ class ::DocChild < ::DocParent; end
948
+ DocParent.collection.clear
949
+
950
+ @parent = DocParent.new({:name => "Daddy Warbucks"})
951
+ @child = DocChild.new({:name => "Little Orphan Annie"})
952
+ end
953
+
954
+ teardown do
955
+ Object.send :remove_const, 'DocParent' if defined?(::DocParent)
956
+ Object.send :remove_const, 'DocChild' if defined?(::DocChild)
957
+ end
958
+
959
+ should "use the same collection in the subclass" do
960
+ DocChild.collection.name.should == DocParent.collection.name
961
+ end
962
+
963
+ should "assign the class name into the _type property" do
964
+ @parent._type.should == 'DocParent'
965
+ @child._type.should == 'DocChild'
966
+ end
967
+
968
+ should "load the document with the assigned type" do
969
+ @parent.save
970
+ @child.save
971
+
972
+ collection = DocParent.find(:all)
973
+ collection.size.should == 2
974
+ collection.first.should be_kind_of(DocParent)
975
+ collection.first.name.should == "Daddy Warbucks"
976
+ collection.last.should be_kind_of(DocChild)
977
+ collection.last.name.should == "Little Orphan Annie"
978
+ end
979
+
980
+ should "gracefully handle when the type can't be constantized" do
981
+ doc = DocParent.new(:name => 'Nunes')
982
+ doc._type = 'FoobarBaz'
983
+ doc.save
984
+
985
+ collection = DocParent.all
986
+ collection.last.should == doc
987
+ collection.last.should be_kind_of(DocParent)
988
+ end
989
+ end
921
990
 
922
991
  context "timestamping" do
923
992
  setup do
@@ -956,4 +1025,27 @@ class DocumentTest < Test::Unit::TestCase
956
1025
  from_db.updated_at.to_i.should_not == old_updated_at.to_i
957
1026
  end
958
1027
  end
1028
+
1029
+ context "#exist?" do
1030
+ setup do
1031
+ @doc = @document.create(:first_name => "James", :age => 27)
1032
+ end
1033
+
1034
+ should "be true when at least one document exists" do
1035
+ @document.exists?.should == true
1036
+ end
1037
+
1038
+ should "be false when no documents exist" do
1039
+ @doc.destroy
1040
+ @document.exists?.should == false
1041
+ end
1042
+
1043
+ should "be true when at least one document exists that matches the conditions" do
1044
+ @document.exists?(:first_name => "James").should == true
1045
+ end
1046
+
1047
+ should "be false when no documents exist with the provided conditions" do
1048
+ @document.exists?(:first_name => "Jean").should == false
1049
+ end
1050
+ end
959
1051
  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
@@ -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: mongo_mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
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-08 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