mark_mapper 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.rdoc +39 -0
  4. data/examples/attr_accessible.rb +24 -0
  5. data/examples/attr_protected.rb +24 -0
  6. data/examples/cache_key.rb +26 -0
  7. data/examples/custom_types.rb +26 -0
  8. data/examples/identity_map.rb +30 -0
  9. data/examples/identity_map/automatic.rb +2 -0
  10. data/examples/keys.rb +42 -0
  11. data/examples/modifiers/set.rb +27 -0
  12. data/examples/plugins.rb +40 -0
  13. data/examples/querying.rb +39 -0
  14. data/examples/sample_app.rb +43 -0
  15. data/examples/scopes.rb +56 -0
  16. data/examples/validating/embedded_docs.rb +31 -0
  17. data/lib/mark_mapper.rb +125 -0
  18. data/lib/mark_mapper/config.rb +90 -0
  19. data/lib/mark_mapper/connection.rb +60 -0
  20. data/lib/mark_mapper/criteria_hash.rb +194 -0
  21. data/lib/mark_mapper/document.rb +46 -0
  22. data/lib/mark_mapper/embedded_document.rb +32 -0
  23. data/lib/mark_mapper/exceptions.rb +33 -0
  24. data/lib/mark_mapper/extensions/array.rb +27 -0
  25. data/lib/mark_mapper/extensions/boolean.rb +45 -0
  26. data/lib/mark_mapper/extensions/date.rb +29 -0
  27. data/lib/mark_mapper/extensions/duplicable.rb +86 -0
  28. data/lib/mark_mapper/extensions/float.rb +18 -0
  29. data/lib/mark_mapper/extensions/hash.rb +26 -0
  30. data/lib/mark_mapper/extensions/integer.rb +27 -0
  31. data/lib/mark_mapper/extensions/kernel.rb +11 -0
  32. data/lib/mark_mapper/extensions/nil_class.rb +18 -0
  33. data/lib/mark_mapper/extensions/object.rb +30 -0
  34. data/lib/mark_mapper/extensions/object_id.rb +18 -0
  35. data/lib/mark_mapper/extensions/set.rb +20 -0
  36. data/lib/mark_mapper/extensions/string.rb +31 -0
  37. data/lib/mark_mapper/extensions/symbol.rb +87 -0
  38. data/lib/mark_mapper/extensions/time.rb +29 -0
  39. data/lib/mark_mapper/locale/en.yml +5 -0
  40. data/lib/mark_mapper/middleware/identity_map.rb +41 -0
  41. data/lib/mark_mapper/normalizers/criteria_hash_key.rb +17 -0
  42. data/lib/mark_mapper/normalizers/criteria_hash_value.rb +66 -0
  43. data/lib/mark_mapper/normalizers/fields_value.rb +26 -0
  44. data/lib/mark_mapper/normalizers/hash_key.rb +19 -0
  45. data/lib/mark_mapper/normalizers/integer.rb +19 -0
  46. data/lib/mark_mapper/normalizers/options_hash_value.rb +83 -0
  47. data/lib/mark_mapper/normalizers/sort_value.rb +55 -0
  48. data/lib/mark_mapper/options_hash.rb +103 -0
  49. data/lib/mark_mapper/pagination.rb +6 -0
  50. data/lib/mark_mapper/pagination/collection.rb +32 -0
  51. data/lib/mark_mapper/pagination/paginator.rb +46 -0
  52. data/lib/mark_mapper/plugins.rb +22 -0
  53. data/lib/mark_mapper/plugins/accessible.rb +61 -0
  54. data/lib/mark_mapper/plugins/active_model.rb +18 -0
  55. data/lib/mark_mapper/plugins/associations.rb +96 -0
  56. data/lib/mark_mapper/plugins/associations/base.rb +98 -0
  57. data/lib/mark_mapper/plugins/associations/belongs_to_association.rb +63 -0
  58. data/lib/mark_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +35 -0
  59. data/lib/mark_mapper/plugins/associations/belongs_to_proxy.rb +52 -0
  60. data/lib/mark_mapper/plugins/associations/collection.rb +29 -0
  61. data/lib/mark_mapper/plugins/associations/embedded_collection.rb +44 -0
  62. data/lib/mark_mapper/plugins/associations/in_array_proxy.rb +133 -0
  63. data/lib/mark_mapper/plugins/associations/many_association.rb +63 -0
  64. data/lib/mark_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  65. data/lib/mark_mapper/plugins/associations/many_documents_proxy.rb +142 -0
  66. data/lib/mark_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
  67. data/lib/mark_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
  68. data/lib/mark_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
  69. data/lib/mark_mapper/plugins/associations/one_as_proxy.rb +22 -0
  70. data/lib/mark_mapper/plugins/associations/one_association.rb +48 -0
  71. data/lib/mark_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
  72. data/lib/mark_mapper/plugins/associations/one_embedded_proxy.rb +44 -0
  73. data/lib/mark_mapper/plugins/associations/one_proxy.rb +95 -0
  74. data/lib/mark_mapper/plugins/associations/proxy.rb +138 -0
  75. data/lib/mark_mapper/plugins/associations/single_association.rb +46 -0
  76. data/lib/mark_mapper/plugins/caching.rb +21 -0
  77. data/lib/mark_mapper/plugins/callbacks.rb +42 -0
  78. data/lib/mark_mapper/plugins/clone.rb +24 -0
  79. data/lib/mark_mapper/plugins/counter_cache.rb +97 -0
  80. data/lib/mark_mapper/plugins/dirty.rb +61 -0
  81. data/lib/mark_mapper/plugins/document.rb +41 -0
  82. data/lib/mark_mapper/plugins/dumpable.rb +22 -0
  83. data/lib/mark_mapper/plugins/dynamic_querying.rb +45 -0
  84. data/lib/mark_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
  85. data/lib/mark_mapper/plugins/embedded_callbacks.rb +81 -0
  86. data/lib/mark_mapper/plugins/embedded_document.rb +53 -0
  87. data/lib/mark_mapper/plugins/equality.rb +23 -0
  88. data/lib/mark_mapper/plugins/identity_map.rb +144 -0
  89. data/lib/mark_mapper/plugins/indexable.rb +86 -0
  90. data/lib/mark_mapper/plugins/inspect.rb +16 -0
  91. data/lib/mark_mapper/plugins/keys.rb +470 -0
  92. data/lib/mark_mapper/plugins/keys/key.rb +134 -0
  93. data/lib/mark_mapper/plugins/keys/static.rb +45 -0
  94. data/lib/mark_mapper/plugins/logger.rb +18 -0
  95. data/lib/mark_mapper/plugins/modifiers.rb +140 -0
  96. data/lib/mark_mapper/plugins/pagination.rb +16 -0
  97. data/lib/mark_mapper/plugins/partial_updates.rb +77 -0
  98. data/lib/mark_mapper/plugins/persistence.rb +79 -0
  99. data/lib/mark_mapper/plugins/protected.rb +45 -0
  100. data/lib/mark_mapper/plugins/querying.rb +173 -0
  101. data/lib/mark_mapper/plugins/querying/decorated_markmapper_query.rb +75 -0
  102. data/lib/mark_mapper/plugins/rails.rb +79 -0
  103. data/lib/mark_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
  104. data/lib/mark_mapper/plugins/sci.rb +82 -0
  105. data/lib/mark_mapper/plugins/scopes.rb +28 -0
  106. data/lib/mark_mapper/plugins/serialization.rb +109 -0
  107. data/lib/mark_mapper/plugins/timestamps.rb +29 -0
  108. data/lib/mark_mapper/plugins/touch.rb +18 -0
  109. data/lib/mark_mapper/plugins/userstamps.rb +18 -0
  110. data/lib/mark_mapper/plugins/validations.rb +96 -0
  111. data/lib/mark_mapper/query.rb +278 -0
  112. data/lib/mark_mapper/railtie.rb +52 -0
  113. data/lib/mark_mapper/railtie/database.rake +65 -0
  114. data/lib/mark_mapper/translation.rb +10 -0
  115. data/lib/mark_mapper/version.rb +4 -0
  116. data/lib/rails/generators/mark_mapper/config/config_generator.rb +37 -0
  117. data/lib/rails/generators/mark_mapper/config/templates/marklogic.yml +19 -0
  118. data/lib/rails/generators/mark_mapper/model/model_generator.rb +40 -0
  119. data/lib/rails/generators/mark_mapper/model/templates/model.rb +17 -0
  120. data/spec/config/mark_mapper.yml +6 -0
  121. data/spec/examples_spec.rb +25 -0
  122. data/spec/functional/accessible_spec.rb +198 -0
  123. data/spec/functional/associations/belongs_to_polymorphic_proxy_spec.rb +64 -0
  124. data/spec/functional/associations/belongs_to_proxy_spec.rb +255 -0
  125. data/spec/functional/associations/in_array_proxy_spec.rb +349 -0
  126. data/spec/functional/associations/many_documents_as_proxy_spec.rb +230 -0
  127. data/spec/functional/associations/many_documents_proxy_spec.rb +968 -0
  128. data/spec/functional/associations/many_embedded_polymorphic_proxy_spec.rb +238 -0
  129. data/spec/functional/associations/many_embedded_proxy_spec.rb +288 -0
  130. data/spec/functional/associations/many_polymorphic_proxy_spec.rb +302 -0
  131. data/spec/functional/associations/one_as_proxy_spec.rb +489 -0
  132. data/spec/functional/associations/one_embedded_polymorphic_proxy_spec.rb +207 -0
  133. data/spec/functional/associations/one_embedded_proxy_spec.rb +100 -0
  134. data/spec/functional/associations/one_proxy_spec.rb +406 -0
  135. data/spec/functional/associations_spec.rb +48 -0
  136. data/spec/functional/caching_spec.rb +75 -0
  137. data/spec/functional/callbacks_spec.rb +330 -0
  138. data/spec/functional/counter_cache_spec.rb +235 -0
  139. data/spec/functional/dirty_spec.rb +316 -0
  140. data/spec/functional/document_spec.rb +310 -0
  141. data/spec/functional/dumpable_spec.rb +24 -0
  142. data/spec/functional/dynamic_querying_spec.rb +75 -0
  143. data/spec/functional/embedded_document_spec.rb +316 -0
  144. data/spec/functional/equality_spec.rb +20 -0
  145. data/spec/functional/extensions_spec.rb +16 -0
  146. data/spec/functional/identity_map_spec.rb +483 -0
  147. data/spec/functional/keys_spec.rb +339 -0
  148. data/spec/functional/logger_spec.rb +20 -0
  149. data/spec/functional/modifiers_spec.rb +446 -0
  150. data/spec/functional/options_hash_spec.rb +41 -0
  151. data/spec/functional/pagination_spec.rb +89 -0
  152. data/spec/functional/partial_updates_spec.rb +530 -0
  153. data/spec/functional/protected_spec.rb +199 -0
  154. data/spec/functional/querying_spec.rb +984 -0
  155. data/spec/functional/rails_spec.rb +55 -0
  156. data/spec/functional/sci_spec.rb +374 -0
  157. data/spec/functional/scopes_spec.rb +204 -0
  158. data/spec/functional/static_keys_spec.rb +153 -0
  159. data/spec/functional/timestamps_spec.rb +97 -0
  160. data/spec/functional/touch_spec.rb +125 -0
  161. data/spec/functional/userstamps_spec.rb +46 -0
  162. data/spec/functional/validations_spec.rb +416 -0
  163. data/spec/quality_spec.rb +51 -0
  164. data/spec/spec_helper.rb +150 -0
  165. data/spec/support/matchers.rb +15 -0
  166. data/spec/support/models.rb +256 -0
  167. data/spec/symbol_operator_spec.rb +70 -0
  168. data/spec/symbol_spec.rb +9 -0
  169. data/spec/unit/associations/base_spec.rb +146 -0
  170. data/spec/unit/associations/belongs_to_association_spec.rb +30 -0
  171. data/spec/unit/associations/many_association_spec.rb +64 -0
  172. data/spec/unit/associations/one_association_spec.rb +48 -0
  173. data/spec/unit/associations/proxy_spec.rb +103 -0
  174. data/spec/unit/clone_spec.rb +79 -0
  175. data/spec/unit/config_generator_spec.rb +24 -0
  176. data/spec/unit/criteria_hash_spec.rb +218 -0
  177. data/spec/unit/document_spec.rb +251 -0
  178. data/spec/unit/dynamic_finder_spec.rb +125 -0
  179. data/spec/unit/embedded_document_spec.rb +676 -0
  180. data/spec/unit/equality_spec.rb +38 -0
  181. data/spec/unit/exceptions_spec.rb +12 -0
  182. data/spec/unit/extensions_spec.rb +368 -0
  183. data/spec/unit/identity_map_middleware_spec.rb +134 -0
  184. data/spec/unit/inspect_spec.rb +47 -0
  185. data/spec/unit/key_spec.rb +276 -0
  186. data/spec/unit/keys_spec.rb +155 -0
  187. data/spec/unit/mark_mapper_spec.rb +37 -0
  188. data/spec/unit/model_generator_spec.rb +45 -0
  189. data/spec/unit/normalizers/criteria_hash_key_spec.rb +37 -0
  190. data/spec/unit/normalizers/criteria_hash_value_spec.rb +200 -0
  191. data/spec/unit/normalizers/fields_value_spec.rb +45 -0
  192. data/spec/unit/normalizers/hash_key_spec.rb +15 -0
  193. data/spec/unit/normalizers/integer_spec.rb +24 -0
  194. data/spec/unit/normalizers/options_hash_value_spec.rb +99 -0
  195. data/spec/unit/normalizers/sort_value_spec.rb +98 -0
  196. data/spec/unit/options_hash_spec.rb +64 -0
  197. data/spec/unit/pagination/collection_spec.rb +30 -0
  198. data/spec/unit/pagination/paginator_spec.rb +118 -0
  199. data/spec/unit/pagination_spec.rb +11 -0
  200. data/spec/unit/plugins_spec.rb +89 -0
  201. data/spec/unit/query_spec.rb +837 -0
  202. data/spec/unit/rails_compatibility_spec.rb +40 -0
  203. data/spec/unit/rails_reflect_on_association_spec.rb +118 -0
  204. data/spec/unit/rails_spec.rb +188 -0
  205. data/spec/unit/serialization_spec.rb +169 -0
  206. data/spec/unit/serializers/json_serializer_spec.rb +218 -0
  207. data/spec/unit/serializers/xml_serializer_spec.rb +198 -0
  208. data/spec/unit/time_zones_spec.rb +44 -0
  209. data/spec/unit/translation_spec.rb +27 -0
  210. data/spec/unit/validations_spec.rb +588 -0
  211. metadata +307 -0
@@ -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 MarkMapper::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 MarkMapper::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 MarkMapper::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
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Caching" do
4
+ before do
5
+ @klass = Class.new do
6
+ extend MarkMapper::Plugins
7
+ plugin MarkMapper::Plugins::Caching
8
+ end
9
+ allow(@klass).to receive(:name).and_return('Post')
10
+ allow_any_instance_of(@klass).to receive(:persisted?).and_return(true)
11
+ allow_any_instance_of(@klass).to receive(:[]).and_return(nil)
12
+ allow_any_instance_of(@klass).to receive(:[]=).and_return(nil)
13
+ end
14
+
15
+ context "new" do
16
+ before do
17
+ @doc = @klass.new
18
+ allow(@doc).to receive(: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 = MarkLogic::ObjectId.new
37
+ @doc = @klass.new
38
+ allow(@doc).to receive(:persisted).and_return(true)
39
+ allow(@doc).to receive(: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
+ allow(@doc).to receive(:[]).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
@@ -0,0 +1,330 @@
1
+ require 'spec_helper'
2
+
3
+ module CallbacksSupport
4
+ def self.included base
5
+ base.key :name, String
6
+
7
+ [ :before_validation, :after_validation,
8
+ :before_create, :after_create,
9
+ :before_update, :after_update,
10
+ :before_save, :after_save,
11
+ :before_destroy, :after_destroy
12
+ ].each do |callback|
13
+ base.send(callback) do
14
+ history << callback.to_sym
15
+ end
16
+ end
17
+ end
18
+
19
+ def history
20
+ @history ||= []
21
+ end
22
+
23
+ def clear_history
24
+ embedded_associations.each { |a| self.send(a.name).each(&:clear_history) }
25
+ @history = nil
26
+ end
27
+ end
28
+
29
+ describe "Callbacks" do
30
+ CreateCallbackOrder = [
31
+ :before_validation,
32
+ :after_validation,
33
+ :before_save,
34
+ :before_create,
35
+ :after_create,
36
+ :after_save
37
+ ]
38
+
39
+ UpdateCallbackOrder = [
40
+ :before_validation,
41
+ :after_validation,
42
+ :before_save,
43
+ :before_update,
44
+ :after_update,
45
+ :after_save
46
+ ]
47
+
48
+ context "Defining and running callbacks on documents" do
49
+ before do
50
+ @document = Doc { include CallbacksSupport }
51
+ end
52
+
53
+ it "should get the order right for creating documents" do
54
+ doc = @document.create(:name => 'John Nunemaker')
55
+ doc.history.should == CreateCallbackOrder
56
+ end
57
+
58
+ it "should get the order right for updating documents" do
59
+ doc = @document.create(:name => 'John Nunemaker')
60
+ doc.clear_history
61
+ doc.name = 'John'
62
+ doc.save
63
+ doc.history.should == UpdateCallbackOrder
64
+ end
65
+
66
+ it "should work for before and after validation" do
67
+ doc = @document.new(:name => 'John Nunemaker')
68
+ doc.valid?
69
+ doc.history.should include(:before_validation)
70
+ doc.history.should include(:after_validation)
71
+ end
72
+
73
+ it "should work for before and after create" do
74
+ doc = @document.create(:name => 'John Nunemaker')
75
+ doc.history.should include(:before_create)
76
+ doc.history.should include(:after_create)
77
+ end
78
+
79
+ it "should work for before and after update" do
80
+ doc = @document.create(:name => 'John Nunemaker')
81
+ doc.name = 'John Doe'
82
+ doc.save
83
+ doc.history.should include(:before_update)
84
+ doc.history.should include(:after_update)
85
+ end
86
+
87
+ it "should work for before and after save" do
88
+ doc = @document.new
89
+ doc.name = 'John Doe'
90
+ doc.save
91
+ doc.history.should include(:before_save)
92
+ doc.history.should include(:after_save)
93
+ end
94
+
95
+ it "should work for before and after destroy" do
96
+ doc = @document.create(:name => 'John Nunemaker')
97
+ doc.destroy
98
+ doc.history.should include(:before_destroy)
99
+ doc.history.should include(:after_destroy)
100
+ end
101
+ end
102
+
103
+ context "Defining and running callbacks on many embedded documents" do
104
+ before do
105
+ @root_class = Doc { include CallbacksSupport }
106
+ @child_class = EDoc { include CallbacksSupport }
107
+ @grand_child_class = EDoc { include CallbacksSupport }
108
+
109
+ @root_class.many :children, :class => @child_class
110
+ @child_class.many :children, :class => @grand_child_class
111
+ end
112
+
113
+ it "should get the order right based on root document creation" do
114
+ grand = @grand_child_class.new(:name => 'Grand Child')
115
+ child = @child_class.new(:name => 'Child', :children => [grand])
116
+ root = @root_class.create(:name => 'Parent', :children => [child])
117
+
118
+ root.children.first.history.should == CreateCallbackOrder
119
+ root.children.first.children.first.history.should == CreateCallbackOrder
120
+ end
121
+
122
+ it "should get the order right based on root document updating" do
123
+ grand = @grand_child_class.new(:name => 'Grand Child')
124
+ child = @child_class.new(:name => 'Child', :children => [grand])
125
+ root = @root_class.create(:name => 'Parent', :children => [child])
126
+ root.clear_history
127
+ root.update_attributes(:name => 'Updated Parent')
128
+
129
+ root.children.first.history.should == UpdateCallbackOrder
130
+ root.children.first.children.first.history.should == UpdateCallbackOrder
131
+ end
132
+
133
+ it "should work for before and after destroy" do
134
+ grand = @grand_child_class.new(:name => 'Grand Child')
135
+ child = @child_class.new(:name => 'Child', :children => [grand])
136
+ root = @root_class.create(:name => 'Parent', :children => [child])
137
+ root.destroy
138
+ child = root.children.first
139
+ child.history.should include(:before_destroy)
140
+ child.history.should include(:after_destroy)
141
+
142
+ grand = root.children.first.children.first
143
+ grand.history.should include(:before_destroy)
144
+ grand.history.should include(:after_destroy)
145
+ end
146
+
147
+ it "should not attempt to run callback defined on root that is not defined on embedded association" do
148
+ @root_class.define_callbacks :after_publish
149
+ @root_class.after_save { |d| d.run_callbacks(:after_publish) }
150
+
151
+ expect {
152
+ child = @child_class.new(:name => 'Child')
153
+ root = @root_class.create(:name => 'Parent', :children => [child])
154
+ child.history.should_not include(:after_publish)
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 == []
213
+ end
214
+ end
215
+
216
+ context "Running validation callbacks with conditional execution" do
217
+ let(:document) do
218
+ Doc do
219
+ include CallbacksSupport
220
+ key :message, String
221
+
222
+ before_validation :set_message, :on => :create
223
+
224
+ def set_message
225
+ self['message'] = 'Hi!'
226
+ end
227
+ end
228
+ end
229
+
230
+ it 'should run callback on create' do
231
+ doc = document.create
232
+ doc.history.should include(:before_validation)
233
+ doc.message.should == 'Hi!'
234
+ end
235
+
236
+ it 'should skip callback on update' do
237
+ doc = document.create
238
+ doc.message = 'Ho!'
239
+ doc.save
240
+ doc.message.should == 'Ho!'
241
+ end
242
+ end
243
+
244
+ describe "after_find" do
245
+ before do
246
+ @found_objects = []
247
+ found_objects = @found_objects # use a local for closure
248
+
249
+ @doc_class = Doc("User") do
250
+ after_find :set_found_object
251
+
252
+ define_method :set_found_object do
253
+ found_objects << self
254
+ end
255
+ end
256
+ end
257
+
258
+ it "should run after finding an object with find!" do
259
+ @doc = @doc_class.create!
260
+
261
+ @doc_class.find!(@doc.id)
262
+ @found_objects.should == [@doc]
263
+ end
264
+
265
+ it "should not have run if nothing was queried" do
266
+ @found_objects.should == []
267
+ end
268
+
269
+ it "should run for multiple objects" do
270
+ @doc1 = @doc_class.create!
271
+ @doc2 = @doc_class.create!
272
+
273
+ @doc_class.all
274
+ @found_objects.should =~ [@doc1, @doc2]
275
+ end
276
+
277
+ it "should run after finding an object through the query proxy" do
278
+ @doc = @doc_class.create!
279
+ @doc_class.where(:_id => @doc.id).first
280
+ @found_objects.should == [@doc]
281
+ end
282
+
283
+ it "should still return the object" do
284
+ @doc = @doc_class.create!
285
+ @doc_class.where(:_id => @doc.id).first.should == @doc
286
+ end
287
+
288
+ it "should not bail if the method return false" do
289
+ @doc_class = Doc("User") do
290
+ after_find :set_found_object
291
+
292
+ define_method :set_found_object do
293
+ false
294
+ end
295
+ end
296
+
297
+ @doc = @doc_class.create!
298
+ @doc_class.where(:_id => @doc.id).first.should == @doc
299
+ end
300
+ end
301
+
302
+ describe "after_initialize" do
303
+ before do
304
+ @objects = []
305
+ objects = @objects
306
+
307
+ @doc_class = Doc("User") do
308
+ after_initialize :set_initialized_object
309
+
310
+ define_method :set_initialized_object do
311
+ objects << self
312
+ end
313
+ end
314
+ end
315
+
316
+ it "should be triggered for objects created with new" do
317
+ @objects.should == []
318
+ obj = @doc_class.new
319
+ @objects.should == [obj]
320
+ end
321
+
322
+ it "should be triggered for objects found in the db" do
323
+ @doc = @doc_class.create!
324
+ @objects.clear # don't re-assign as we want the operation to be in place
325
+
326
+ @doc_class.all
327
+ @objects.should == [@doc]
328
+ end
329
+ end
330
+ end