mongo_mapper 0.8.6 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/UPGRADES +10 -0
  2. data/bin/mmconsole +0 -1
  3. data/examples/identity_map/automatic.rb +1 -7
  4. data/examples/plugins.rb +9 -9
  5. data/examples/safe.rb +43 -0
  6. data/lib/mongo_mapper.rb +46 -33
  7. data/lib/mongo_mapper/document.rb +33 -32
  8. data/lib/mongo_mapper/embedded_document.rb +22 -22
  9. data/lib/mongo_mapper/locale/en.yml +5 -0
  10. data/lib/mongo_mapper/middleware/identity_map.rb +16 -0
  11. data/lib/mongo_mapper/plugins.rb +16 -3
  12. data/lib/mongo_mapper/plugins/accessible.rb +2 -0
  13. data/lib/mongo_mapper/plugins/active_model.rb +18 -0
  14. data/lib/mongo_mapper/plugins/associations.rb +37 -42
  15. data/lib/mongo_mapper/plugins/associations/base.rb +14 -50
  16. data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +58 -0
  17. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +6 -1
  18. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +30 -2
  19. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +4 -0
  20. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +12 -6
  21. data/lib/mongo_mapper/plugins/associations/many_association.rb +67 -0
  22. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +5 -5
  23. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +1 -1
  24. data/lib/mongo_mapper/plugins/associations/one_association.rb +20 -0
  25. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +5 -0
  26. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +7 -7
  27. data/lib/mongo_mapper/plugins/associations/proxy.rb +2 -2
  28. data/lib/mongo_mapper/plugins/caching.rb +3 -1
  29. data/lib/mongo_mapper/plugins/callbacks.rb +12 -221
  30. data/lib/mongo_mapper/plugins/clone.rb +3 -1
  31. data/lib/mongo_mapper/plugins/dirty.rb +38 -91
  32. data/lib/mongo_mapper/plugins/document.rb +4 -2
  33. data/lib/mongo_mapper/plugins/dynamic_querying.rb +2 -0
  34. data/lib/mongo_mapper/plugins/embedded_callbacks.rb +43 -0
  35. data/lib/mongo_mapper/plugins/embedded_document.rb +16 -9
  36. data/lib/mongo_mapper/plugins/equality.rb +2 -0
  37. data/lib/mongo_mapper/plugins/identity_map.rb +4 -2
  38. data/lib/mongo_mapper/plugins/indexes.rb +2 -0
  39. data/lib/mongo_mapper/plugins/inspect.rb +3 -1
  40. data/lib/mongo_mapper/plugins/keys.rb +28 -22
  41. data/lib/mongo_mapper/plugins/keys/key.rb +12 -6
  42. data/lib/mongo_mapper/plugins/logger.rb +2 -0
  43. data/lib/mongo_mapper/plugins/modifiers.rb +3 -1
  44. data/lib/mongo_mapper/plugins/pagination.rb +2 -0
  45. data/lib/mongo_mapper/plugins/persistence.rb +2 -0
  46. data/lib/mongo_mapper/plugins/protected.rb +2 -0
  47. data/lib/mongo_mapper/plugins/querying.rb +5 -4
  48. data/lib/mongo_mapper/plugins/rails.rb +3 -5
  49. data/lib/mongo_mapper/plugins/safe.rb +2 -0
  50. data/lib/mongo_mapper/plugins/sci.rb +2 -0
  51. data/lib/mongo_mapper/plugins/scopes.rb +2 -0
  52. data/lib/mongo_mapper/plugins/serialization.rb +67 -46
  53. data/lib/mongo_mapper/plugins/timestamps.rb +3 -1
  54. data/lib/mongo_mapper/plugins/userstamps.rb +2 -0
  55. data/lib/mongo_mapper/plugins/validations.rb +40 -24
  56. data/lib/mongo_mapper/railtie.rb +49 -0
  57. data/lib/mongo_mapper/railtie/database.rake +60 -0
  58. data/lib/mongo_mapper/support/descendant_appends.rb +11 -11
  59. data/lib/mongo_mapper/translation.rb +10 -0
  60. data/lib/mongo_mapper/version.rb +1 -1
  61. data/lib/rails/generators/mongo_mapper/config/config_generator.rb +24 -0
  62. data/lib/rails/generators/mongo_mapper/config/templates/mongo.yml +18 -0
  63. data/lib/rails/generators/mongo_mapper/model/model_generator.rb +23 -0
  64. data/lib/rails/generators/mongo_mapper/model/templates/model.rb +11 -0
  65. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +1 -0
  66. data/test/functional/associations/test_belongs_to_proxy.rb +131 -1
  67. data/test/functional/associations/test_in_array_proxy.rb +30 -0
  68. data/test/functional/associations/test_many_documents_proxy.rb +30 -2
  69. data/test/functional/associations/test_many_embedded_proxy.rb +33 -0
  70. data/test/functional/associations/test_many_polymorphic_proxy.rb +1 -0
  71. data/test/functional/associations/test_one_embedded_proxy.rb +21 -2
  72. data/test/functional/associations/test_one_proxy.rb +49 -9
  73. data/test/functional/test_associations.rb +2 -0
  74. data/test/functional/test_caching.rb +3 -2
  75. data/test/functional/test_callbacks.rb +25 -18
  76. data/test/functional/test_dirty.rb +123 -1
  77. data/test/functional/test_document.rb +26 -2
  78. data/test/functional/test_embedded_document.rb +68 -2
  79. data/test/functional/test_identity_map.rb +3 -4
  80. data/test/functional/test_querying.rb +11 -0
  81. data/test/functional/test_userstamps.rb +2 -2
  82. data/test/functional/test_validations.rb +31 -29
  83. data/test/models.rb +10 -0
  84. data/test/test_active_model_lint.rb +1 -1
  85. data/test/test_helper.rb +9 -10
  86. data/test/unit/associations/test_base.rb +24 -100
  87. data/test/unit/associations/test_belongs_to_association.rb +29 -0
  88. data/test/unit/associations/test_many_association.rb +63 -0
  89. data/test/unit/associations/test_one_association.rb +18 -0
  90. data/test/unit/serializers/test_json_serializer.rb +0 -1
  91. data/test/unit/test_descendant_appends.rb +8 -16
  92. data/test/unit/test_document.rb +4 -9
  93. data/test/unit/test_dynamic_finder.rb +1 -1
  94. data/test/unit/test_embedded_document.rb +51 -18
  95. data/test/unit/test_identity_map_middleware.rb +34 -0
  96. data/test/unit/test_inspect.rb +22 -0
  97. data/test/unit/test_key.rb +21 -1
  98. data/test/unit/test_keys.rb +0 -2
  99. data/test/unit/test_plugins.rb +106 -20
  100. data/test/unit/test_rails.rb +8 -8
  101. data/test/unit/test_serialization.rb +116 -1
  102. data/test/unit/test_translation.rb +27 -0
  103. data/test/unit/test_validations.rb +66 -81
  104. metadata +103 -43
  105. data/examples/identity_map/middleware.rb +0 -14
  106. data/lib/mongo_mapper/plugins/descendants.rb +0 -17
  107. data/rails/init.rb +0 -19
@@ -0,0 +1,29 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class BelongsToAssociationTest < Test::Unit::TestCase
5
+ include MongoMapper::Plugins::Associations
6
+
7
+ context "class_name" do
8
+ should "camelize the name" do
9
+ BelongsToAssociation.new(:user).class_name.should == 'User'
10
+ end
11
+
12
+ should "be changeable using class_name option" do
13
+ association = BelongsToAssociation.new(:user, :class_name => 'Person')
14
+ association.class_name.should == 'Person'
15
+ end
16
+ end
17
+
18
+ context "embeddable?" do
19
+ should "be false even if class is embeddable" do
20
+ base = BelongsToAssociation.new(:address)
21
+ base.embeddable?.should be_false
22
+ end
23
+
24
+ should "be false if class is not embeddable" do
25
+ base = BelongsToAssociation.new(:project)
26
+ base.embeddable?.should be_false
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,63 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class ManyAssociationTest < Test::Unit::TestCase
5
+ include MongoMapper::Plugins::Associations
6
+
7
+ context "class_name" do
8
+ should "camelize the name" do
9
+ ManyAssociation.new(:smart_people).class_name.should == 'SmartPerson'
10
+ end
11
+
12
+ should "be changeable using class_name option" do
13
+ base = ManyAssociation.new(:smart_people, :class_name => 'IntelligentPerson')
14
+ base.class_name.should == 'IntelligentPerson'
15
+ end
16
+ end
17
+
18
+ context "type_key_name" do
19
+ should "be _type" do
20
+ ManyAssociation.new(:foos).type_key_name.should == '_type'
21
+ end
22
+ end
23
+
24
+ context "embeddable?" do
25
+ should "be true if class is embeddable" do
26
+ base = ManyAssociation.new(:medias)
27
+ base.embeddable?.should be_true
28
+ end
29
+
30
+ should "be false if class is not embeddable" do
31
+ base = ManyAssociation.new(:statuses)
32
+ base.embeddable?.should be_false
33
+ end
34
+ end
35
+
36
+ context "proxy_class" do
37
+ should "be ManyDocumentsProxy for many" do
38
+ base = ManyAssociation.new(:statuses)
39
+ base.proxy_class.should == ManyDocumentsProxy
40
+ end
41
+
42
+ should "be ManyPolymorphicProxy for polymorphic many" do
43
+ base = ManyAssociation.new(:messages, :polymorphic => true)
44
+ base.proxy_class.should == ManyPolymorphicProxy
45
+ end
46
+
47
+ should "be ManyEmbeddedProxy for many embedded" do
48
+ base = ManyAssociation.new(:medias)
49
+ base.proxy_class.should == ManyEmbeddedProxy
50
+ end
51
+
52
+ should "be ManyEmbeddedPolymorphicProxy for polymorphic many embedded" do
53
+ base = ManyAssociation.new(:medias, :polymorphic => true)
54
+ base.proxy_class.should == ManyEmbeddedPolymorphicProxy
55
+ end
56
+
57
+ should "be InArrayProxy for many with :in option" do
58
+ base = ManyAssociation.new(:messages, :in => :message_ids)
59
+ base.proxy_class.should == InArrayProxy
60
+ end
61
+ end
62
+
63
+ end
@@ -0,0 +1,18 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class OneAssociationTest < Test::Unit::TestCase
5
+ include MongoMapper::Plugins::Associations
6
+
7
+ context "embeddable?" do
8
+ should "be true if class is embeddable" do
9
+ base = OneAssociation.new(:media)
10
+ base.embeddable?.should be_true
11
+ end
12
+
13
+ should "be false if class is not embeddable" do
14
+ base = OneAssociation.new(:project)
15
+ base.embeddable?.should be_false
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,4 @@
1
1
  require 'test_helper'
2
- require 'active_support/version'
3
2
 
4
3
  class JsonSerializationTest < Test::Unit::TestCase
5
4
 
@@ -2,13 +2,9 @@ require 'test_helper'
2
2
 
3
3
  class DescendantAppendsTest < Test::Unit::TestCase
4
4
  context "Document" do
5
- should "default descendants to a new set" do
6
- MongoMapper::Document.descendants.should be_instance_of(Set)
7
- end
8
-
9
5
  should 'allow extensions to Document to be appended' do
10
6
  module Extension; def test_this_extension; end end
11
- MongoMapper::Document.append_extensions(Extension)
7
+ silence_stderr { MongoMapper::Document.append_extensions(Extension) }
12
8
  article = Doc()
13
9
  article.should respond_to(:test_this_extension)
14
10
  end
@@ -16,13 +12,13 @@ class DescendantAppendsTest < Test::Unit::TestCase
16
12
  should 'add appended extensions to classes that include Document before they are added' do
17
13
  module Extension; def test_this_extension; end end
18
14
  article = Doc()
19
- MongoMapper::Document.append_extensions(Extension)
15
+ silence_stderr { MongoMapper::Document.append_extensions(Extension) }
20
16
  article.should respond_to(:test_this_extension)
21
17
  end
22
18
 
23
19
  should 'allow inclusions to Document to be appended' do
24
20
  module Inclusion; def test_this_inclusion; end end
25
- MongoMapper::Document.append_inclusions(Inclusion)
21
+ silence_stderr { MongoMapper::Document.append_inclusions(Inclusion) }
26
22
  article = Doc()
27
23
  article.new.should respond_to(:test_this_inclusion)
28
24
  end
@@ -30,19 +26,15 @@ class DescendantAppendsTest < Test::Unit::TestCase
30
26
  should 'add appended inclusions to classes that include Document before they are added' do
31
27
  module Inclusion; def test_this_inclusion; end end
32
28
  article = Doc()
33
- MongoMapper::Document.append_inclusions(Inclusion)
29
+ silence_stderr { MongoMapper::Document.append_inclusions(Inclusion) }
34
30
  article.new.should respond_to(:test_this_inclusion)
35
31
  end
36
32
  end
37
33
 
38
34
  context "EmbeddedDocument" do
39
- should "default descendants to a new set" do
40
- MongoMapper::EmbeddedDocument.descendants.should be_instance_of(Set)
41
- end
42
-
43
35
  should 'allow extensions to Document to be appended' do
44
36
  module Extension; def test_this_extension; end end
45
- MongoMapper::EmbeddedDocument.append_extensions(Extension)
37
+ silence_stderr { MongoMapper::EmbeddedDocument.append_extensions(Extension) }
46
38
  article = EDoc()
47
39
  article.should respond_to(:test_this_extension)
48
40
  end
@@ -50,13 +42,13 @@ class DescendantAppendsTest < Test::Unit::TestCase
50
42
  should 'add appended extensions to classes that include Document before they are added' do
51
43
  module Extension; def test_this_extension; end end
52
44
  article = EDoc()
53
- MongoMapper::EmbeddedDocument.append_extensions(Extension)
45
+ silence_stderr { MongoMapper::EmbeddedDocument.append_extensions(Extension) }
54
46
  article.should respond_to(:test_this_extension)
55
47
  end
56
48
 
57
49
  should 'allow inclusions to Document to be appended' do
58
50
  module Inclusion; def test_this_inclusion; end end
59
- MongoMapper::EmbeddedDocument.append_inclusions(Inclusion)
51
+ silence_stderr { MongoMapper::EmbeddedDocument.append_inclusions(Inclusion) }
60
52
  article = EDoc()
61
53
  article.new.should respond_to(:test_this_inclusion)
62
54
  end
@@ -64,7 +56,7 @@ class DescendantAppendsTest < Test::Unit::TestCase
64
56
  should 'add appended inclusions to classes that include Document before they are added' do
65
57
  module Inclusion; def test_this_inclusion; end end
66
58
  article = EDoc()
67
- MongoMapper::EmbeddedDocument.append_inclusions(Inclusion)
59
+ silence_stderr { MongoMapper::EmbeddedDocument.append_inclusions(Inclusion) }
68
60
  article.new.should respond_to(:test_this_inclusion)
69
61
  end
70
62
  end
@@ -75,10 +75,10 @@ class DocumentTest < Test::Unit::TestCase
75
75
  end
76
76
 
77
77
  should "default associations to inherited class" do
78
- Message.associations.keys.should include("room")
79
- Enter.associations.keys.should include("room")
80
- Exit.associations.keys.should include("room")
81
- Chat.associations.keys.should include("room")
78
+ Message.associations.keys.should include(:room)
79
+ Enter.associations.keys.should include(:room)
80
+ Exit.associations.keys.should include(:room)
81
+ Chat.associations.keys.should include(:room)
82
82
  end
83
83
  end
84
84
 
@@ -158,11 +158,6 @@ class DocumentTest < Test::Unit::TestCase
158
158
  end
159
159
  end
160
160
 
161
- should "call inspect on the document's attributes instead of to_s when inspecting the document" do
162
- doc = @document.new(:animals => %w(dog cat))
163
- doc.inspect.should include(%(animals: ["dog", "cat"]))
164
- end
165
-
166
161
  context "equality" do
167
162
  setup do
168
163
  @oid = BSON::ObjectId.new
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class DynamicFinderTest < Test::Unit::TestCase
4
- include MongoMapper::Plugins::DynamicQuerying
4
+ DynamicFinder = MongoMapper::Plugins::DynamicQuerying::DynamicFinder
5
5
 
6
6
  should "initialize with method" do
7
7
  finder = DynamicFinder.new(:foobar)
@@ -34,13 +34,26 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
34
34
 
35
35
  key :other_child, String
36
36
  end
37
+
38
+ class ::EDocWithAValidation
39
+ include MongoMapper::EmbeddedDocument
40
+ key :name, String, :required => true
41
+ end
42
+
43
+ class ::DocWithAValidation
44
+ include MongoMapper::Document
45
+ key :name, String, :required => true
46
+ many :e_doc_with_a_validations
47
+ end
37
48
  end
38
49
 
39
50
  teardown do
40
- Object.send :remove_const, 'Grandparent' if defined?(::Grandparent)
41
- Object.send :remove_const, 'Parent' if defined?(::Parent)
42
- Object.send :remove_const, 'Child' if defined?(::Child)
43
- Object.send :remove_const, 'OtherChild' if defined?(::OtherChild)
51
+ Object.send :remove_const, 'Grandparent' if defined?(::Grandparent)
52
+ Object.send :remove_const, 'Parent' if defined?(::Parent)
53
+ Object.send :remove_const, 'Child' if defined?(::Child)
54
+ Object.send :remove_const, 'OtherChild' if defined?(::OtherChild)
55
+ Object.send :remove_const, 'EDocWithAValidation' if defined?(::EDocWithAValidation)
56
+ Object.send :remove_const, 'DocWithAValidation' if defined?(::DocWithAValidation)
44
57
  end
45
58
 
46
59
  context "Including MongoMapper::EmbeddedDocument in a class" do
@@ -158,10 +171,10 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
158
171
  @document.new.should respond_to(:foo)
159
172
  end
160
173
 
161
- should "create reader before typecast method" do
162
- @document.new.should_not respond_to(:foo_before_typecast)
174
+ should "create reader before type cast method" do
175
+ @document.new.should_not respond_to(:foo_before_type_cast)
163
176
  @document.key(:foo, String)
164
- @document.new.should respond_to(:foo_before_typecast)
177
+ @document.new.should respond_to(:foo_before_type_cast)
165
178
  end
166
179
 
167
180
  should "create writer method" do
@@ -207,7 +220,9 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
207
220
  end
208
221
 
209
222
  should "be recorded" do
210
- Grandparent.descendants.should == [Parent]
223
+ Grandparent.direct_descendants.should == [Parent]
224
+ Grandparent.descendants.to_set.should == [Parent, Child, OtherChild].to_set
225
+
211
226
  Parent.descendants.should == [Child, OtherChild]
212
227
  end
213
228
  end
@@ -339,7 +354,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
339
354
  doc.passwd.should == 'secret'
340
355
  end
341
356
 
342
- should "typecast key values" do
357
+ should "type cast key values" do
343
358
  doc = @document.new(:name => 1234, :age => '21')
344
359
  doc.name.should == '1234'
345
360
  doc.age.should == 21
@@ -463,18 +478,18 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
463
478
  context "reading a key before typcasting" do
464
479
  should "work for defined keys" do
465
480
  doc = @document.new(:name => 12)
466
- doc.name_before_typecast.should == 12
481
+ doc.name_before_type_cast.should == 12
467
482
  end
468
483
 
469
484
  should "raise no method error for undefined keys" do
470
485
  doc = @document.new
471
- lambda { doc.foo_before_typecast }.should raise_error(NoMethodError)
486
+ lambda { doc.foo_before_type_cast }.should raise_error(NoMethodError)
472
487
  end
473
488
 
474
489
  should "be accessible for use in a document" do
475
490
  @document.class_eval do
476
491
  def untypcasted_name
477
- read_key_before_typecast(:name)
492
+ read_key_before_type_cast(:name)
478
493
  end
479
494
  end
480
495
 
@@ -496,7 +511,7 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
496
511
  lambda { doc.fart = 'poof!' }.should raise_error(NoMethodError)
497
512
  end
498
513
 
499
- should "typecast value" do
514
+ should "type cast value" do
500
515
  doc = @document.new
501
516
  doc.name = 1234
502
517
  doc.name.should == '1234'
@@ -548,11 +563,6 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
548
563
  end
549
564
  end
550
565
 
551
- should "call inspect on the document's attributes instead of to_s when inspecting the document" do
552
- doc = @document.new(:animals => %w(dog cat))
553
- doc.inspect.should include(%(animals: ["dog", "cat"]))
554
- end
555
-
556
566
  context "equality" do
557
567
  setup do
558
568
  @oid = BSON::ObjectId.new
@@ -639,6 +649,29 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
639
649
  @doc.options['baz'].should == 'wick'
640
650
  end
641
651
  end
652
+
653
+ context "#save!" do
654
+ setup do
655
+ @root = DocWithAValidation.create(:name => "Root")
656
+ @doc = @root.e_doc_with_a_validations.build :name => "Embedded"
657
+ end
658
+
659
+ should "should save when valid" do
660
+ @doc.save!
661
+ @root.reload.e_doc_with_a_validations.first.should == @doc
662
+ end
663
+
664
+ should "should raise errors when invalid" do
665
+ @doc.name = ''
666
+ lambda{ @doc.save! }.should raise_error(MongoMapper::DocumentNotValid, "Validation failed: Name can't be empty")
667
+ end
668
+
669
+ should "should raise errors when root document is invalid" do
670
+ @root.name = ''
671
+ @root.save(:validate => false)
672
+ lambda{ @doc.save! }.should raise_error(MongoMapper::DocumentNotValid, "Foo")
673
+ end
674
+ end
642
675
  end # instance of a embedded document
643
676
  end
644
677
  end
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+ require 'rack/test'
3
+
4
+ class IdentityMapMiddlewareTest < Test::Unit::TestCase
5
+ include Rack::Test::Methods
6
+
7
+ def app
8
+ @app ||= Rack::Builder.new do
9
+ use MongoMapper::Middleware::IdentityMap
10
+ map "/" do
11
+ run lambda {|env| [200, {}, []] }
12
+ end
13
+ map "/fail" do
14
+ run lambda {|env| raise "FAIL!" }
15
+ end
16
+ end.to_app
17
+ end
18
+
19
+ context "with a successful request" do
20
+ should "clear the identity map" do
21
+ MongoMapper::Plugins::IdentityMap.expects(:clear).twice
22
+ get '/'
23
+ end
24
+ end
25
+
26
+ context "when the request raises an error" do
27
+ should "clear the identity map" do
28
+ MongoMapper::Plugins::IdentityMap.expects(:clear).twice
29
+ get '/fail' rescue nil
30
+ end
31
+ end
32
+
33
+
34
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+
3
+ class InspectTest < Test::Unit::TestCase
4
+ context "#inspect" do
5
+ setup do
6
+ @document = Doc('User') do
7
+ key :name, String
8
+ key :age, Integer
9
+ end
10
+
11
+ @doc = @document.new(:name => 'John', :age => 29)
12
+ end
13
+
14
+ should "print out attributes in alpha sorted order" do
15
+ @doc.inspect.should =~ /_id:.*, age: 29, name: "John"/
16
+ end
17
+
18
+ should "include class name" do
19
+ @doc.inspect.should =~ /^#<User/
20
+ end
21
+ end
22
+ end
@@ -12,7 +12,7 @@ class FooType < Struct.new(:bar)
12
12
  end
13
13
 
14
14
  class KeyTest < Test::Unit::TestCase
15
- include MongoMapper::Plugins::Keys
15
+ Key = MongoMapper::Plugins::Keys::Key
16
16
 
17
17
  context "Initializing a new key" do
18
18
  should "allow setting the name" do
@@ -101,6 +101,21 @@ class KeyTest < Test::Unit::TestCase
101
101
  end
102
102
  end
103
103
 
104
+ context "for an array with :typecast option of Date" do
105
+ setup { @key = Key.new(:dates, Array, :typecast => 'Date') }
106
+ subject { @key }
107
+
108
+ should "cast each element correctly when get" do
109
+ dates = [Date.yesterday, Date.today, Date.tomorrow.to_s]
110
+ subject.get(dates).should == dates.map { |date| Date.from_mongo(date) }
111
+ end
112
+
113
+ should "cast each element correctly when set" do
114
+ dates = [Date.yesterday, Date.today, Date.tomorrow.to_s]
115
+ subject.set(dates).should == dates.map { |date| Date.to_mongo(date) }
116
+ end
117
+ end
118
+
104
119
  context "for a set with :typecast option" do
105
120
  setup { @key = Key.new(:user_ids, Set, :typecast => 'ObjectId') }
106
121
  subject { @key }
@@ -166,6 +181,11 @@ class KeyTest < Test::Unit::TestCase
166
181
  @key.get(nil).should == 'baz'
167
182
  end
168
183
 
184
+ should "return a dup of the default value" do
185
+ @key.get(nil).replace('bar')
186
+ @key.get(nil).should == 'baz'
187
+ end
188
+
169
189
  should "return value if not blank" do
170
190
  @key.get('foobar').should == 'foobar'
171
191
  end