mongo_mapper 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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