mongo_mapper 0.12.0 → 0.13.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. checksums.yaml +7 -0
  2. data/README.rdoc +35 -13
  3. data/bin/mmconsole +1 -1
  4. data/lib/mongo_mapper.rb +4 -0
  5. data/lib/mongo_mapper/connection.rb +17 -6
  6. data/lib/mongo_mapper/document.rb +1 -0
  7. data/lib/mongo_mapper/exceptions.rb +4 -1
  8. data/lib/mongo_mapper/extensions/binary.rb +1 -1
  9. data/lib/mongo_mapper/extensions/boolean.rb +20 -23
  10. data/lib/mongo_mapper/extensions/date.rb +3 -3
  11. data/lib/mongo_mapper/extensions/integer.rb +5 -1
  12. data/lib/mongo_mapper/extensions/kernel.rb +2 -0
  13. data/lib/mongo_mapper/extensions/ordered_hash.rb +23 -0
  14. data/lib/mongo_mapper/extensions/string.rb +2 -2
  15. data/lib/mongo_mapper/extensions/time.rb +7 -5
  16. data/lib/mongo_mapper/middleware/identity_map.rb +3 -4
  17. data/lib/mongo_mapper/plugins.rb +1 -1
  18. data/lib/mongo_mapper/plugins/associations.rb +11 -5
  19. data/lib/mongo_mapper/plugins/associations/base.rb +5 -3
  20. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +0 -0
  21. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +8 -8
  22. data/lib/mongo_mapper/plugins/associations/collection.rb +2 -0
  23. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +32 -7
  24. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +2 -2
  25. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +12 -12
  26. data/lib/mongo_mapper/plugins/associations/proxy.rb +5 -1
  27. data/lib/mongo_mapper/plugins/associations/single_association.rb +6 -6
  28. data/lib/mongo_mapper/plugins/clone.rb +4 -2
  29. data/lib/mongo_mapper/plugins/dirty.rb +22 -21
  30. data/lib/mongo_mapper/plugins/document.rb +4 -4
  31. data/lib/mongo_mapper/plugins/dumpable.rb +22 -0
  32. data/lib/mongo_mapper/plugins/embedded_callbacks.rb +58 -9
  33. data/lib/mongo_mapper/plugins/identity_map.rb +42 -32
  34. data/lib/mongo_mapper/plugins/keys.rb +133 -54
  35. data/lib/mongo_mapper/plugins/keys/key.rb +68 -22
  36. data/lib/mongo_mapper/plugins/modifiers.rb +26 -19
  37. data/lib/mongo_mapper/plugins/persistence.rb +15 -5
  38. data/lib/mongo_mapper/plugins/querying.rb +15 -40
  39. data/lib/mongo_mapper/plugins/querying/{decorator.rb → decorated_plucky_query.rb} +24 -4
  40. data/lib/mongo_mapper/plugins/rails.rb +22 -2
  41. data/lib/mongo_mapper/plugins/safe.rb +8 -5
  42. data/lib/mongo_mapper/plugins/sci.rb +26 -4
  43. data/lib/mongo_mapper/plugins/scopes.rb +5 -4
  44. data/lib/mongo_mapper/plugins/timestamps.rb +11 -4
  45. data/lib/mongo_mapper/plugins/validations.rb +1 -1
  46. data/lib/mongo_mapper/utils.rb +12 -0
  47. data/lib/mongo_mapper/version.rb +1 -1
  48. data/lib/rails/generators/mongo_mapper/config/config_generator.rb +20 -7
  49. data/lib/rails/generators/mongo_mapper/config/templates/mongo.yml +6 -0
  50. data/lib/rails/generators/mongo_mapper/model/model_generator.rb +18 -1
  51. data/lib/rails/generators/mongo_mapper/model/templates/model.rb +9 -5
  52. data/{test/functional/test_accessible.rb → spec/functional/accessible_spec.rb} +29 -29
  53. data/{test/functional/associations/test_belongs_to_polymorphic_proxy.rb → spec/functional/associations/belongs_to_polymorphic_proxy_spec.rb} +10 -10
  54. data/{test/functional/associations/test_belongs_to_proxy.rb → spec/functional/associations/belongs_to_proxy_spec.rb} +82 -64
  55. data/{test/functional/associations/test_in_array_proxy.rb → spec/functional/associations/in_array_proxy_spec.rb} +68 -68
  56. data/{test/functional/associations/test_many_documents_as_proxy.rb → spec/functional/associations/many_documents_as_proxy_spec.rb} +37 -38
  57. data/{test/functional/associations/test_many_documents_proxy.rb → spec/functional/associations/many_documents_proxy_spec.rb} +233 -146
  58. data/{test/functional/associations/test_many_embedded_polymorphic_proxy.rb → spec/functional/associations/many_embedded_polymorphic_proxy_spec.rb} +19 -20
  59. data/{test/functional/associations/test_many_embedded_proxy.rb → spec/functional/associations/many_embedded_proxy_spec.rb} +23 -24
  60. data/{test/functional/associations/test_many_polymorphic_proxy.rb → spec/functional/associations/many_polymorphic_proxy_spec.rb} +45 -46
  61. data/{test/functional/associations/test_one_as_proxy.rb → spec/functional/associations/one_as_proxy_spec.rb} +75 -77
  62. data/{test/functional/associations/test_one_embedded_polymorphic_proxy.rb → spec/functional/associations/one_embedded_polymorphic_proxy_spec.rb} +31 -32
  63. data/{test/functional/associations/test_one_embedded_proxy.rb → spec/functional/associations/one_embedded_proxy_spec.rb} +10 -10
  64. data/{test/functional/associations/test_one_proxy.rb → spec/functional/associations/one_proxy_spec.rb} +125 -102
  65. data/spec/functional/associations_spec.rb +48 -0
  66. data/{test/functional/test_binary.rb → spec/functional/binary_spec.rb} +6 -6
  67. data/spec/functional/caching_spec.rb +75 -0
  68. data/{test/functional/test_callbacks.rb → spec/functional/callbacks_spec.rb} +84 -26
  69. data/{test/functional/test_dirty.rb → spec/functional/dirty_spec.rb} +57 -42
  70. data/{test/functional/test_document.rb → spec/functional/document_spec.rb} +52 -52
  71. data/spec/functional/dumpable_spec.rb +24 -0
  72. data/{test/functional/test_dynamic_querying.rb → spec/functional/dynamic_querying_spec.rb} +14 -14
  73. data/{test/functional/test_embedded_document.rb → spec/functional/embedded_document_spec.rb} +51 -42
  74. data/{test/functional/test_equality.rb → spec/functional/equality_spec.rb} +4 -4
  75. data/spec/functional/extensions_spec.rb +16 -0
  76. data/{test/functional/test_identity_map.rb → spec/functional/identity_map_spec.rb} +73 -61
  77. data/spec/functional/indexes_spec.rb +48 -0
  78. data/spec/functional/keys_spec.rb +224 -0
  79. data/{test/functional/test_logger.rb → spec/functional/logger_spec.rb} +6 -6
  80. data/spec/functional/modifiers_spec.rb +550 -0
  81. data/spec/functional/pagination_spec.rb +89 -0
  82. data/spec/functional/protected_spec.rb +199 -0
  83. data/spec/functional/querying_spec.rb +1003 -0
  84. data/spec/functional/rails_spec.rb +55 -0
  85. data/spec/functional/safe_spec.rb +163 -0
  86. data/{test/functional/test_sci.rb → spec/functional/sci_spec.rb} +123 -34
  87. data/{test/functional/test_scopes.rb → spec/functional/scopes_spec.rb} +59 -26
  88. data/spec/functional/timestamps_spec.rb +97 -0
  89. data/{test/functional/test_touch.rb → spec/functional/touch_spec.rb} +13 -13
  90. data/spec/functional/userstamps_spec.rb +46 -0
  91. data/{test/functional/test_validations.rb → spec/functional/validations_spec.rb} +64 -64
  92. data/spec/spec_helper.rb +81 -0
  93. data/spec/support/matchers.rb +24 -0
  94. data/{test → spec/support}/models.rb +1 -6
  95. data/spec/unit/associations/base_spec.rb +146 -0
  96. data/spec/unit/associations/belongs_to_association_spec.rb +30 -0
  97. data/spec/unit/associations/many_association_spec.rb +64 -0
  98. data/spec/unit/associations/one_association_spec.rb +48 -0
  99. data/{test/unit/associations/test_proxy.rb → spec/unit/associations/proxy_spec.rb} +21 -21
  100. data/{test/unit/test_clone.rb → spec/unit/clone_spec.rb} +21 -11
  101. data/spec/unit/config_generator_spec.rb +24 -0
  102. data/{test/unit/test_document.rb → spec/unit/document_spec.rb} +42 -42
  103. data/{test/unit/test_dynamic_finder.rb → spec/unit/dynamic_finder_spec.rb} +28 -28
  104. data/{test/unit/test_embedded_document.rb → spec/unit/embedded_document_spec.rb} +102 -108
  105. data/{test/unit/test_equality.rb → spec/unit/equality_spec.rb} +7 -7
  106. data/{test/unit/test_exceptions.rb → spec/unit/exceptions_spec.rb} +3 -3
  107. data/{test/unit/test_extensions.rb → spec/unit/extensions_spec.rb} +85 -71
  108. data/spec/unit/identity_map_middleware_spec.rb +134 -0
  109. data/{test/unit/test_inspect.rb → spec/unit/inspect_spec.rb} +8 -8
  110. data/{test/unit/test_key.rb → spec/unit/key_spec.rb} +82 -52
  111. data/spec/unit/keys_spec.rb +155 -0
  112. data/spec/unit/model_generator_spec.rb +47 -0
  113. data/spec/unit/mongo_mapper_spec.rb +184 -0
  114. data/spec/unit/pagination_spec.rb +11 -0
  115. data/{test/unit/test_plugins.rb → spec/unit/plugins_spec.rb} +14 -14
  116. data/spec/unit/rails_compatibility_spec.rb +40 -0
  117. data/{test/unit/test_rails_reflect_on_association.rb → spec/unit/rails_reflect_on_association_spec.rb} +9 -9
  118. data/{test/unit/test_rails.rb → spec/unit/rails_spec.rb} +31 -31
  119. data/spec/unit/serialization_spec.rb +169 -0
  120. data/spec/unit/serializers/json_serializer_spec.rb +218 -0
  121. data/spec/unit/serializers/xml_serializer_spec.rb +198 -0
  122. data/{test/unit/test_time_zones.rb → spec/unit/time_zones_spec.rb} +8 -8
  123. data/{test/unit/test_translation.rb → spec/unit/translation_spec.rb} +6 -6
  124. data/{test/unit/test_validations.rb → spec/unit/validations_spec.rb} +72 -59
  125. metadata +199 -179
  126. data/test/_NOTE_ON_TESTING +0 -1
  127. data/test/functional/test_associations.rb +0 -46
  128. data/test/functional/test_caching.rb +0 -77
  129. data/test/functional/test_indexes.rb +0 -50
  130. data/test/functional/test_modifiers.rb +0 -537
  131. data/test/functional/test_pagination.rb +0 -91
  132. data/test/functional/test_protected.rb +0 -201
  133. data/test/functional/test_querying.rb +0 -935
  134. data/test/functional/test_safe.rb +0 -76
  135. data/test/functional/test_timestamps.rb +0 -62
  136. data/test/functional/test_userstamps.rb +0 -44
  137. data/test/support/railtie.rb +0 -4
  138. data/test/support/railtie/autoloaded.rb +0 -2
  139. data/test/support/railtie/not_autoloaded.rb +0 -3
  140. data/test/support/railtie/parent.rb +0 -3
  141. data/test/test_active_model_lint.rb +0 -18
  142. data/test/test_helper.rb +0 -93
  143. data/test/unit/associations/test_base.rb +0 -146
  144. data/test/unit/associations/test_belongs_to_association.rb +0 -29
  145. data/test/unit/associations/test_many_association.rb +0 -63
  146. data/test/unit/associations/test_one_association.rb +0 -47
  147. data/test/unit/serializers/test_json_serializer.rb +0 -216
  148. data/test/unit/serializers/test_xml_serializer.rb +0 -196
  149. data/test/unit/test_identity_map_middleware.rb +0 -132
  150. data/test/unit/test_keys.rb +0 -65
  151. data/test/unit/test_mongo_mapper.rb +0 -157
  152. data/test/unit/test_pagination.rb +0 -11
  153. data/test/unit/test_rails_compatibility.rb +0 -38
  154. data/test/unit/test_serialization.rb +0 -166
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+ require 'support/models'
3
+
4
+ module AssociationsSpec
5
+ describe "Associations" do
6
+ it "should allow changing class names" do
7
+ class AwesomeUser
8
+ include MongoMapper::Document
9
+
10
+ many :posts, :class_name => 'AssociationsSpec::AwesomePost', :foreign_key => :creator_id
11
+ end
12
+ AwesomeUser.collection.remove
13
+
14
+ class AwesomeTag
15
+ include MongoMapper::EmbeddedDocument
16
+
17
+ key :name, String
18
+ key :post_id, ObjectId
19
+
20
+ belongs_to :post, :class_name => 'AssociationsSpec::AwesomeUser'
21
+ end
22
+
23
+ class AwesomePost
24
+ include MongoMapper::Document
25
+
26
+ key :creator_id, ObjectId
27
+
28
+ belongs_to :creator, :class_name => 'AssociationsSpec::AwesomeUser'
29
+ many :tags, :class_name => 'AssociationsSpec::AwesomeTag', :foreign_key => :post_id
30
+ end
31
+
32
+ AwesomeUser.collection.remove
33
+ AwesomePost.collection.remove
34
+
35
+ user = AwesomeUser.create
36
+ tag1 = AwesomeTag.new(:name => 'awesome')
37
+ tag2 = AwesomeTag.new(:name => 'grand')
38
+ post1 = AwesomePost.create(:creator => user, :tags => [tag1])
39
+ post2 = AwesomePost.create(:creator => user, :tags => [tag2])
40
+
41
+ user.reload
42
+ user.posts.should == [post1, post2]
43
+
44
+ post1 = post1.reload
45
+ post1.tags.should == [tag1]
46
+ end
47
+ end
48
+ end
@@ -1,7 +1,7 @@
1
- require 'test_helper'
1
+ require 'spec_helper'
2
2
 
3
- class BinaryTest < Test::Unit::TestCase
4
- should "serialize and deserialize correctly" do
3
+ describe "Binary" do
4
+ it "should serialize and deserialize correctly" do
5
5
  klass = Doc do
6
6
  key :contents, Binary
7
7
  end
@@ -14,14 +14,14 @@ class BinaryTest < Test::Unit::TestCase
14
14
  end
15
15
 
16
16
  context "Saving a document with a blank binary value" do
17
- setup do
17
+ before do
18
18
  @document = Doc do
19
19
  key :file, Binary
20
20
  end
21
21
  end
22
22
 
23
- should "not fail" do
24
- assert_nothing_raised { @document.new(:file => nil).save }
23
+ it "not fail" do
24
+ expect { @document.new(:file => nil).save }.to_not raise_error
25
25
  end
26
26
  end
27
27
  end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Caching" do
4
+ before do
5
+ @klass = Class.new do
6
+ extend MongoMapper::Plugins
7
+ plugin MongoMapper::Plugins::Caching
8
+ end
9
+ @klass.stub(:name).and_return('Post')
10
+ @klass.any_instance.stub(:persisted?).and_return(true)
11
+ @klass.any_instance.stub(:[]).and_return(nil)
12
+ @klass.any_instance.stub(:[]=).and_return(nil)
13
+ end
14
+
15
+ context "new" do
16
+ before do
17
+ @doc = @klass.new
18
+ @doc.stub(:persisted?).and_return(false)
19
+ end
20
+
21
+ it "should be class/new" do
22
+ @doc.cache_key.should == 'Post/new'
23
+ end
24
+
25
+ it "should work with suffix" do
26
+ @doc.cache_key(:foo).
27
+ should == 'Post/new/foo'
28
+
29
+ @doc.cache_key(:foo, :bar).
30
+ should == 'Post/new/foo/bar'
31
+ end
32
+ end
33
+
34
+ context "not new" do
35
+ before do
36
+ @object_id = BSON::ObjectId.new
37
+ @doc = @klass.new
38
+ @doc.stub(:persisted).and_return(true)
39
+ @doc.stub(:id).and_return(@object_id)
40
+ end
41
+
42
+ context "with updated_at" do
43
+ before do
44
+ time = Time.utc(2010, 6, 20, 8, 10, 7)
45
+ @doc.stub(:[]).with(:updated_at).and_return(time)
46
+ end
47
+
48
+ it "should be class/id-timestamp" do
49
+ @doc.cache_key.should == "Post/#{@object_id}-20100620081007"
50
+ end
51
+
52
+ it "should work with suffix" do
53
+ @doc.cache_key(:foo).
54
+ should == "Post/#{@object_id}-20100620081007/foo"
55
+
56
+ @doc.cache_key(:foo, :bar).
57
+ should == "Post/#{@object_id}-20100620081007/foo/bar"
58
+ end
59
+ end
60
+
61
+ context "without updated_at" do
62
+ it "should be class/id" do
63
+ @doc.cache_key.should == "Post/#{@object_id}"
64
+ end
65
+
66
+ it "should work with suffix" do
67
+ @doc.cache_key(:foo).
68
+ should == "Post/#{@object_id}/foo"
69
+
70
+ @doc.cache_key(:foo, :bar, :baz).
71
+ should == "Post/#{@object_id}/foo/bar/baz"
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,4 +1,4 @@
1
- require 'test_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  module CallbacksSupport
4
4
  def self.included base
@@ -26,7 +26,7 @@ module CallbacksSupport
26
26
  end
27
27
  end
28
28
 
29
- class CallbacksTest < Test::Unit::TestCase
29
+ describe "Callbacks" do
30
30
  CreateCallbackOrder = [
31
31
  :before_validation,
32
32
  :after_validation,
@@ -46,16 +46,16 @@ class CallbacksTest < Test::Unit::TestCase
46
46
  ]
47
47
 
48
48
  context "Defining and running callbacks on documents" do
49
- setup do
49
+ before do
50
50
  @document = Doc { include CallbacksSupport }
51
51
  end
52
52
 
53
- should "get the order right for creating documents" do
53
+ it "should get the order right for creating documents" do
54
54
  doc = @document.create(:name => 'John Nunemaker')
55
55
  doc.history.should == CreateCallbackOrder
56
56
  end
57
57
 
58
- should "get the order right for updating documents" do
58
+ it "should get the order right for updating documents" do
59
59
  doc = @document.create(:name => 'John Nunemaker')
60
60
  doc.clear_history
61
61
  doc.name = 'John'
@@ -63,20 +63,20 @@ class CallbacksTest < Test::Unit::TestCase
63
63
  doc.history.should == UpdateCallbackOrder
64
64
  end
65
65
 
66
- should "work for before and after validation" do
66
+ it "should work for before and after validation" do
67
67
  doc = @document.new(:name => 'John Nunemaker')
68
68
  doc.valid?
69
69
  doc.history.should include(:before_validation)
70
70
  doc.history.should include(:after_validation)
71
71
  end
72
72
 
73
- should "work for before and after create" do
73
+ it "should work for before and after create" do
74
74
  doc = @document.create(:name => 'John Nunemaker')
75
75
  doc.history.should include(:before_create)
76
76
  doc.history.should include(:after_create)
77
77
  end
78
78
 
79
- should "work for before and after update" do
79
+ it "should work for before and after update" do
80
80
  doc = @document.create(:name => 'John Nunemaker')
81
81
  doc.name = 'John Doe'
82
82
  doc.save
@@ -84,7 +84,7 @@ class CallbacksTest < Test::Unit::TestCase
84
84
  doc.history.should include(:after_update)
85
85
  end
86
86
 
87
- should "work for before and after save" do
87
+ it "should work for before and after save" do
88
88
  doc = @document.new
89
89
  doc.name = 'John Doe'
90
90
  doc.save
@@ -92,7 +92,7 @@ class CallbacksTest < Test::Unit::TestCase
92
92
  doc.history.should include(:after_save)
93
93
  end
94
94
 
95
- should "work for before and after destroy" do
95
+ it "should work for before and after destroy" do
96
96
  doc = @document.create(:name => 'John Nunemaker')
97
97
  doc.destroy
98
98
  doc.history.should include(:before_destroy)
@@ -101,16 +101,16 @@ class CallbacksTest < Test::Unit::TestCase
101
101
  end
102
102
 
103
103
  context "Defining and running callbacks on many embedded documents" do
104
- setup do
104
+ before do
105
105
  @root_class = Doc { include CallbacksSupport }
106
106
  @child_class = EDoc { include CallbacksSupport }
107
107
  @grand_child_class = EDoc { include CallbacksSupport }
108
108
 
109
- @root_class.many :children, :class => @child_class
109
+ @root_class.many :children, :class => @child_class
110
110
  @child_class.many :children, :class => @grand_child_class
111
111
  end
112
112
 
113
- should "get the order right based on root document creation" do
113
+ it "should get the order right based on root document creation" do
114
114
  grand = @grand_child_class.new(:name => 'Grand Child')
115
115
  child = @child_class.new(:name => 'Child', :children => [grand])
116
116
  root = @root_class.create(:name => 'Parent', :children => [child])
@@ -119,7 +119,7 @@ class CallbacksTest < Test::Unit::TestCase
119
119
  root.children.first.children.first.history.should == CreateCallbackOrder
120
120
  end
121
121
 
122
- should "get the order right based on root document updating" do
122
+ it "should get the order right based on root document updating" do
123
123
  grand = @grand_child_class.new(:name => 'Grand Child')
124
124
  child = @child_class.new(:name => 'Child', :children => [grand])
125
125
  root = @root_class.create(:name => 'Parent', :children => [child])
@@ -130,7 +130,7 @@ class CallbacksTest < Test::Unit::TestCase
130
130
  root.children.first.children.first.history.should == UpdateCallbackOrder
131
131
  end
132
132
 
133
- should "work for before and after destroy" do
133
+ it "should work for before and after destroy" do
134
134
  grand = @grand_child_class.new(:name => 'Grand Child')
135
135
  child = @child_class.new(:name => 'Child', :children => [grand])
136
136
  root = @root_class.create(:name => 'Parent', :children => [child])
@@ -144,42 +144,100 @@ class CallbacksTest < Test::Unit::TestCase
144
144
  grand.history.should include(:after_destroy)
145
145
  end
146
146
 
147
- should "not attempt to run callback defined on root that is not defined on embedded association" do
147
+ it "should not attempt to run callback defined on root that is not defined on embedded association" do
148
148
  @root_class.define_callbacks :after_publish
149
149
  @root_class.after_save { |d| d.run_callbacks(:after_publish) }
150
150
 
151
- assert_nothing_raised do
151
+ expect {
152
152
  child = @child_class.new(:name => 'Child')
153
153
  root = @root_class.create(:name => 'Parent', :children => [child])
154
154
  child.history.should_not include(:after_publish)
155
- end
155
+ }.to_not raise_error
156
+ end
157
+ end
158
+
159
+ context "By default" do
160
+ it "should not run callbacks when no callbacks were explicitly defined" do
161
+ EDoc { key :name, String }.embedded_callbacks_off?.should == true
162
+ end
163
+
164
+ it "should run callbacks when a callback was explicitly defined" do
165
+ EDoc {
166
+ key :name, String
167
+ before_save :no_op
168
+ def noop; end
169
+ }.embedded_callbacks_on?.should == true
170
+ end
171
+ end
172
+
173
+ context "Turning embedded callbacks off" do
174
+ before do
175
+ @root_class = Doc { include CallbacksSupport; embedded_callbacks_off }
176
+ @child_class = EDoc { include CallbacksSupport; embedded_callbacks_off }
177
+ @grand_child_class = EDoc { include CallbacksSupport; embedded_callbacks_off }
178
+
179
+ @root_class.many :children, :class => @child_class
180
+ @child_class.many :children, :class => @grand_child_class
181
+ end
182
+
183
+ it "should not run create callbacks" do
184
+ grand = @grand_child_class.new(:name => 'Grand Child')
185
+ child = @child_class.new(:name => 'Child', :children => [grand])
186
+ root = @root_class.create(:name => 'Parent', :children => [child])
187
+
188
+ root.children.first.history.should == []
189
+ root.children.first.children.first.history.should == []
190
+ end
191
+
192
+ it "should not run update callbacks" do
193
+ grand = @grand_child_class.new(:name => 'Grand Child')
194
+ child = @child_class.new(:name => 'Child', :children => [grand])
195
+ root = @root_class.create(:name => 'Parent', :children => [child])
196
+ root.clear_history
197
+ root.update_attributes(:name => 'Updated Parent')
198
+
199
+ root.children.first.history.should == []
200
+ root.children.first.children.first.history.should == []
201
+ end
202
+
203
+ it "should not run destroy callbacks" do
204
+ grand = @grand_child_class.new(:name => 'Grand Child')
205
+ child = @child_class.new(:name => 'Child', :children => [grand])
206
+ root = @root_class.create(:name => 'Parent', :children => [child])
207
+ root.destroy
208
+ child = root.children.first
209
+ child.history.should == []
210
+
211
+ grand = root.children.first.children.first
212
+ grand.history.should == []
156
213
  end
157
214
  end
158
215
 
159
216
  context "Running validation callbacks with conditional execution" do
160
- setup do
161
- @document = Doc do
217
+ let(:document) do
218
+ Doc do
162
219
  include CallbacksSupport
163
220
  key :message, String
164
221
 
165
- before_validation :set_message, :on => 'create'
222
+ before_validation :set_message, :on => :create
223
+
166
224
  def set_message
167
225
  self['message'] = 'Hi!'
168
226
  end
169
227
  end
170
228
  end
171
229
 
172
- should 'run callback on create' do
173
- doc = @document.create
230
+ it 'should run callback on create' do
231
+ doc = document.create
174
232
  doc.history.should include(:before_validation)
175
233
  doc.message.should == 'Hi!'
176
234
  end
177
235
 
178
- should 'skip callback on update' do
179
- doc = @document.create
236
+ it 'should skip callback on update' do
237
+ doc = document.create
180
238
  doc.message = 'Ho!'
181
239
  doc.save
182
240
  doc.message.should == 'Ho!'
183
241
  end
184
242
  end
185
- end
243
+ end
@@ -1,18 +1,21 @@
1
- require 'test_helper'
2
-
3
- class DirtyTest < Test::Unit::TestCase
4
- def setup
5
- @document = Doc { key :phrase, String }
1
+ require 'spec_helper'
2
+
3
+ describe "Dirty" do
4
+ before do
5
+ @document = Doc {
6
+ key :phrase, String
7
+ key :paragraph, String, :alias => :para
8
+ }
6
9
  end
7
10
 
8
11
  context "marking changes" do
9
- should "not happen if there are none" do
12
+ it "should not happen if there are none" do
10
13
  doc = @document.new
11
14
  doc.phrase_changed?.should be_false
12
15
  doc.phrase_change.should be_nil
13
16
  end
14
17
 
15
- should "happen when change happens" do
18
+ it "should happen when change happens" do
16
19
  doc = @document.new
17
20
  doc.phrase = 'Golly Gee Willikers Batman'
18
21
  doc.phrase_changed?.should be_true
@@ -20,12 +23,12 @@ class DirtyTest < Test::Unit::TestCase
20
23
  doc.phrase_change.should == [nil, 'Golly Gee Willikers Batman']
21
24
  end
22
25
 
23
- should "happen when initializing" do
26
+ it "should happen when initializing" do
24
27
  doc = @document.new(:phrase => 'Foo')
25
28
  doc.changed?.should be_true
26
29
  end
27
30
 
28
- should "clear changes on save" do
31
+ it "should clear changes on save" do
29
32
  doc = @document.new
30
33
  doc.phrase = 'Golly Gee Willikers Batman'
31
34
  doc.phrase_changed?.should be_true
@@ -34,7 +37,7 @@ class DirtyTest < Test::Unit::TestCase
34
37
  doc.phrase_change.should be_nil
35
38
  end
36
39
 
37
- should "clear changes on save!" do
40
+ it "should clear changes on save!" do
38
41
  doc = @document.new
39
42
  doc.phrase = 'Golly Gee Willikers Batman'
40
43
  doc.phrase_changed?.should be_true
@@ -43,7 +46,15 @@ class DirtyTest < Test::Unit::TestCase
43
46
  doc.phrase_change.should be_nil
44
47
  end
45
48
 
46
- should "not happen when loading from database" do
49
+ it "should not happen when loading from database" do
50
+ doc = @document.create(:phrase => 'Foo')
51
+ @document.any_instance.should_receive(:attribute_will_change!).never
52
+ @document.any_instance.should_receive(:attribute_changed?).never
53
+ doc = @document.find(doc.id)
54
+ doc.changed?.should be_false
55
+ end
56
+
57
+ it "should not happen when reloading from database" do
47
58
  doc = @document.create(:phrase => 'Foo')
48
59
  doc = @document.find(doc.id)
49
60
 
@@ -54,17 +65,24 @@ class DirtyTest < Test::Unit::TestCase
54
65
  doc.changed?.should be_false
55
66
  end
56
67
 
57
- should "happen if changed after loading from database" do
68
+ it "should happen if changed after loading from database" do
58
69
  doc = @document.create(:phrase => 'Foo')
59
70
  doc.reload
60
71
  doc.changed?.should be_false
61
72
  doc.phrase = 'Bar'
62
73
  doc.changed?.should be_true
63
74
  end
75
+
76
+ it "should happen with aliased keys" do
77
+ doc = @document.create(:paragraph => 'Wibbly')
78
+ doc.paragraph = "Wobbly"
79
+ doc.changed?.should be_true
80
+ doc.paragraph_changed?.should be_true
81
+ end
64
82
  end
65
83
 
66
84
  context "blank new value and type integer" do
67
- should "not mark changes" do
85
+ it "should not mark changes" do
68
86
  @document.key :age, Integer
69
87
 
70
88
  [nil, ''].each do |value|
@@ -77,7 +95,7 @@ class DirtyTest < Test::Unit::TestCase
77
95
  end
78
96
 
79
97
  context "blank new value and type float" do
80
- should "not mark changes" do
98
+ it "should not mark changes" do
81
99
  @document.key :amount, Float
82
100
 
83
101
  [nil, ''].each do |value|
@@ -90,24 +108,24 @@ class DirtyTest < Test::Unit::TestCase
90
108
  end
91
109
 
92
110
  context "changed?" do
93
- should "be true if key changed" do
111
+ it "should be true if key changed" do
94
112
  doc = @document.new
95
113
  doc.phrase = 'A penny saved is a penny earned.'
96
114
  doc.changed?.should be_true
97
115
  end
98
116
 
99
- should "be false if no keys changed" do
117
+ it "should be false if no keys changed" do
100
118
  @document.new.changed?.should be_false
101
119
  end
102
120
 
103
- should "not raise when key name is 'value'" do
121
+ it "should not raise when key name is 'value'" do
104
122
  @document.key :value, Integer
105
123
 
106
124
  doc = @document.new
107
125
  doc.value_changed?.should be_false
108
126
  end
109
127
 
110
- should "be false if the same ObjectId was assigned in String format" do
128
+ it "should be false if the same ObjectId was assigned in String format" do
111
129
  @document.key :doc_id, ObjectId
112
130
 
113
131
  doc = @document.create!(:doc_id => BSON::ObjectId.new)
@@ -118,11 +136,11 @@ class DirtyTest < Test::Unit::TestCase
118
136
  end
119
137
 
120
138
  context "changes" do
121
- should "be empty hash if no changes" do
139
+ it "should be empty hash if no changes" do
122
140
  @document.new.changes.should == {}
123
141
  end
124
142
 
125
- should "be hash of keys with values of changes if there are changes" do
143
+ it "should be hash of keys with values of changes if there are changes" do
126
144
  doc = @document.new
127
145
  doc.phrase = 'A penny saved is a penny earned.'
128
146
  doc.changes['phrase'].should == [nil, 'A penny saved is a penny earned.']
@@ -130,11 +148,11 @@ class DirtyTest < Test::Unit::TestCase
130
148
  end
131
149
 
132
150
  context "changed" do
133
- should "be empty array if no changes" do
151
+ it "should be empty array if no changes" do
134
152
  @document.new.changed.should == []
135
153
  end
136
154
 
137
- should "be array of keys that have changed if there are changes" do
155
+ it "should be array of keys that have changed if there are changes" do
138
156
  doc = @document.new
139
157
  doc.phrase = 'A penny saved is a penny earned.'
140
158
  doc.changed.should == ['phrase']
@@ -142,7 +160,7 @@ class DirtyTest < Test::Unit::TestCase
142
160
  end
143
161
 
144
162
  context "will_change!" do
145
- should "mark changes" do
163
+ it "should mark changes" do
146
164
  doc = @document.create(:phrase => 'Foo')
147
165
 
148
166
  doc.phrase << 'bar'
@@ -159,7 +177,7 @@ class DirtyTest < Test::Unit::TestCase
159
177
  end
160
178
 
161
179
  context "changing a foreign key through association" do
162
- should "mark changes" do
180
+ it "should mark changes" do
163
181
  project_class = Doc do
164
182
  key :name, String
165
183
  end
@@ -178,7 +196,7 @@ class DirtyTest < Test::Unit::TestCase
178
196
  end
179
197
 
180
198
  context "save with an invalid document" do
181
- should "not clear changes" do
199
+ it "should not clear changes" do
182
200
  validated_class = Doc do
183
201
  key :name, String
184
202
  key :required, String, :required=>true
@@ -195,14 +213,14 @@ class DirtyTest < Test::Unit::TestCase
195
213
  end
196
214
 
197
215
  context "changing an already changed attribute" do
198
- should "preserve the original value" do
216
+ it "should preserve the original value" do
199
217
  doc = @document.create(:a=>"b")
200
218
  doc.a = "c"
201
219
  doc.a_change.should == ["b","c"]
202
220
  doc.a = "d"
203
221
  doc.a_change.should == ["b","d"]
204
222
  end
205
- should "reset changes when set back to the original value" do
223
+ it "should reset changes when set back to the original value" do
206
224
  doc = @document.create(:a=>"b")
207
225
  doc.a = "c"
208
226
  doc.a = "b"
@@ -211,14 +229,14 @@ class DirtyTest < Test::Unit::TestCase
211
229
  end
212
230
 
213
231
  context "reset_attribute!" do
214
- should "reset the attribute back to the previous value" do
232
+ it "should reset the attribute back to the previous value" do
215
233
  doc = @document.create(:a=>"b")
216
234
  doc.a = "c"
217
235
  doc.reset_a!
218
236
  doc.changed?.should be_false
219
237
  doc.a.should == "b"
220
238
  end
221
- should "reset the attribute back to the original value after several changes" do
239
+ it "should reset the attribute back to the original value after several changes" do
222
240
  doc = @document.create(:a=>"b")
223
241
  doc.a = "c"
224
242
  doc.a = "d"
@@ -230,22 +248,23 @@ class DirtyTest < Test::Unit::TestCase
230
248
  end
231
249
 
232
250
  context "previous_changes" do
233
- should "reflect previously committed change" do
251
+ it "should reflect previously committed change" do
234
252
  doc = @document.create(:a=>"b")
235
253
  doc.a = "c"
236
254
  changes = doc.changes
237
255
  doc.save!
238
256
  doc.previous_changes.should == changes
257
+ doc.previous_changes["a"].should == ["b", "c"]
239
258
  end
240
259
 
241
- should "not include attributes loaded from db" do
260
+ it "should not include attributes loaded from db" do
242
261
  doc = @document.create(:a => "b")
243
262
  @document.find(doc.id).previous_changes.should be_blank
244
263
  end
245
264
  end
246
265
 
247
266
  context "Embedded documents" do
248
- setup do
267
+ before do
249
268
  @edoc = EDoc('Duck') { key :name, String }
250
269
  @edoc.plugin MongoMapper::Plugins::Dirty
251
270
  @document = Doc('Long') { key :name, String }
@@ -254,19 +273,19 @@ class DirtyTest < Test::Unit::TestCase
254
273
  @duck = @doc.ducks.build
255
274
  end
256
275
 
257
- should "track changes" do
276
+ it "should track changes" do
258
277
  @duck.name = "hi"
259
278
  @duck.changed?.should be_true
260
279
  end
261
280
 
262
- should "clear changes when saved" do
281
+ it "should clear changes when saved" do
263
282
  @duck.name = "hi"
264
283
  @duck.changed?.should be_true
265
284
  @duck.save!
266
285
  @duck.changed?.should_not be_true
267
286
  end
268
287
 
269
- should "clear changes when the parent is saved" do
288
+ it "should clear changes when the parent is saved" do
270
289
  @duck.name = "hi"
271
290
  @duck.changed?.should be_true
272
291
  @doc.save!
@@ -274,28 +293,24 @@ class DirtyTest < Test::Unit::TestCase
274
293
  end
275
294
 
276
295
  context "with nested embedded documents" do
277
- setup do
296
+ before do
278
297
  @inner_edoc = EDoc('Dong') {key :name, String}
279
298
  @inner_edoc.plugin MongoMapper::Plugins::Dirty
280
299
  @edoc.many :dongs, :class=>@inner_edoc
281
300
  @dong = @duck.dongs.build
282
301
  end
283
302
 
284
- should "track changes" do
303
+ it "should track changes" do
285
304
  @dong.name = "hi"
286
305
  @dong.changed?.should be_true
287
306
  end
288
307
 
289
- should "clear changes when the root saves" do
308
+ it "should clear changes when the root saves" do
290
309
  @dong.name = "hi"
291
310
  @dong.changed?.should be_true
292
311
  @doc.save!
293
312
  @dong.changed?.should be_false
294
313
  end
295
-
296
314
  end
297
-
298
315
  end
299
-
300
-
301
316
  end