mongo_mapper 0.12.0 → 0.13.0.beta1

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.
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