mongo_mapper-unstable 2010.3.8 → 2010.06.23

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 (143) hide show
  1. data/README.rdoc +4 -8
  2. data/bin/mmconsole +1 -1
  3. data/examples/keys.rb +37 -0
  4. data/examples/plugins.rb +41 -0
  5. data/examples/querying.rb +35 -0
  6. data/examples/scopes.rb +52 -0
  7. data/lib/mongo_mapper/connection.rb +83 -0
  8. data/lib/mongo_mapper/document.rb +11 -329
  9. data/lib/mongo_mapper/embedded_document.rb +9 -38
  10. data/lib/mongo_mapper/exceptions.rb +30 -0
  11. data/lib/mongo_mapper/extensions/array.rb +19 -0
  12. data/lib/mongo_mapper/extensions/binary.rb +22 -0
  13. data/lib/mongo_mapper/extensions/boolean.rb +44 -0
  14. data/lib/mongo_mapper/extensions/date.rb +25 -0
  15. data/lib/mongo_mapper/extensions/float.rb +14 -0
  16. data/lib/mongo_mapper/extensions/hash.rb +14 -0
  17. data/lib/mongo_mapper/extensions/integer.rb +19 -0
  18. data/lib/mongo_mapper/extensions/kernel.rb +9 -0
  19. data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
  20. data/lib/mongo_mapper/extensions/object.rb +27 -0
  21. data/lib/mongo_mapper/extensions/object_id.rb +30 -0
  22. data/lib/mongo_mapper/extensions/set.rb +20 -0
  23. data/lib/mongo_mapper/extensions/string.rb +18 -0
  24. data/lib/mongo_mapper/extensions/time.rb +29 -0
  25. data/lib/mongo_mapper/plugins/accessible.rb +44 -0
  26. data/lib/mongo_mapper/plugins/associations/base.rb +7 -6
  27. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +5 -6
  28. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +5 -6
  29. data/lib/mongo_mapper/plugins/associations/collection.rb +1 -0
  30. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +2 -1
  31. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +25 -39
  32. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +4 -4
  33. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +36 -46
  34. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +1 -0
  35. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +5 -4
  36. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +1 -0
  37. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +40 -0
  38. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +7 -7
  39. data/lib/mongo_mapper/plugins/associations/proxy.rb +16 -8
  40. data/lib/mongo_mapper/plugins/associations.rb +14 -22
  41. data/lib/mongo_mapper/plugins/caching.rb +21 -0
  42. data/lib/mongo_mapper/plugins/callbacks.rb +17 -5
  43. data/lib/mongo_mapper/plugins/clone.rb +10 -4
  44. data/lib/mongo_mapper/plugins/descendants.rb +3 -2
  45. data/lib/mongo_mapper/plugins/dirty.rb +1 -0
  46. data/lib/mongo_mapper/plugins/document.rb +41 -0
  47. data/lib/mongo_mapper/{support/find.rb → plugins/dynamic_querying/dynamic_finder.rb} +3 -36
  48. data/lib/mongo_mapper/plugins/dynamic_querying.rb +43 -0
  49. data/lib/mongo_mapper/plugins/embedded_document.rb +49 -0
  50. data/lib/mongo_mapper/plugins/equality.rb +4 -10
  51. data/lib/mongo_mapper/plugins/identity_map.rb +29 -23
  52. data/lib/mongo_mapper/plugins/indexes.rb +12 -0
  53. data/lib/mongo_mapper/plugins/inspect.rb +1 -0
  54. data/lib/mongo_mapper/plugins/keys/key.rb +55 -0
  55. data/lib/mongo_mapper/plugins/keys.rb +85 -110
  56. data/lib/mongo_mapper/plugins/logger.rb +1 -0
  57. data/lib/mongo_mapper/plugins/modifiers.rb +41 -16
  58. data/lib/mongo_mapper/plugins/pagination.rb +5 -15
  59. data/lib/mongo_mapper/plugins/persistence.rb +69 -0
  60. data/lib/mongo_mapper/plugins/protected.rb +9 -1
  61. data/lib/mongo_mapper/plugins/querying/decorator.rb +46 -0
  62. data/lib/mongo_mapper/plugins/querying/plucky_methods.rb +15 -0
  63. data/lib/mongo_mapper/plugins/querying.rb +176 -0
  64. data/lib/mongo_mapper/plugins/rails.rb +6 -1
  65. data/lib/mongo_mapper/plugins/safe.rb +28 -0
  66. data/lib/mongo_mapper/plugins/sci.rb +32 -0
  67. data/lib/mongo_mapper/plugins/scopes.rb +21 -0
  68. data/lib/mongo_mapper/plugins/serialization.rb +5 -4
  69. data/lib/mongo_mapper/plugins/timestamps.rb +2 -1
  70. data/lib/mongo_mapper/plugins/userstamps.rb +1 -0
  71. data/lib/mongo_mapper/plugins/validations.rb +9 -5
  72. data/lib/mongo_mapper/plugins.rb +1 -20
  73. data/lib/mongo_mapper/support/descendant_appends.rb +5 -6
  74. data/lib/mongo_mapper/version.rb +4 -0
  75. data/lib/mongo_mapper.rb +71 -128
  76. data/test/{NOTE_ON_TESTING → _NOTE_ON_TESTING} +0 -0
  77. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +5 -5
  78. data/test/functional/associations/test_belongs_to_proxy.rb +13 -21
  79. data/test/functional/associations/test_in_array_proxy.rb +7 -9
  80. data/test/functional/associations/test_many_documents_as_proxy.rb +5 -5
  81. data/test/functional/associations/test_many_documents_proxy.rb +186 -64
  82. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +22 -22
  83. data/test/functional/associations/test_many_embedded_proxy.rb +32 -32
  84. data/test/functional/associations/test_many_polymorphic_proxy.rb +47 -47
  85. data/test/functional/associations/test_one_embedded_proxy.rb +67 -0
  86. data/test/functional/associations/test_one_proxy.rb +70 -49
  87. data/test/functional/test_accessible.rb +168 -0
  88. data/test/functional/test_associations.rb +11 -11
  89. data/test/functional/test_binary.rb +5 -5
  90. data/test/functional/test_caching.rb +76 -0
  91. data/test/functional/test_callbacks.rb +104 -34
  92. data/test/functional/test_dirty.rb +16 -16
  93. data/test/functional/test_document.rb +12 -924
  94. data/test/functional/test_dynamic_querying.rb +75 -0
  95. data/test/functional/test_embedded_document.rb +88 -8
  96. data/test/functional/test_identity_map.rb +41 -43
  97. data/test/functional/{test_indexing.rb → test_indexes.rb} +3 -5
  98. data/test/functional/test_logger.rb +1 -1
  99. data/test/functional/test_modifiers.rb +275 -181
  100. data/test/functional/test_pagination.rb +13 -15
  101. data/test/functional/test_protected.rb +25 -11
  102. data/test/functional/test_querying.rb +873 -0
  103. data/test/functional/test_safe.rb +76 -0
  104. data/test/functional/test_sci.rb +230 -0
  105. data/test/functional/test_scopes.rb +171 -0
  106. data/test/functional/test_string_id_compatibility.rb +11 -11
  107. data/test/functional/test_timestamps.rb +0 -2
  108. data/test/functional/test_userstamps.rb +0 -1
  109. data/test/functional/test_validations.rb +44 -31
  110. data/test/models.rb +18 -17
  111. data/test/{active_model_lint_test.rb → test_active_model_lint.rb} +3 -1
  112. data/test/test_helper.rb +59 -16
  113. data/test/unit/associations/test_base.rb +47 -42
  114. data/test/unit/associations/test_proxy.rb +15 -15
  115. data/test/unit/serializers/test_json_serializer.rb +29 -29
  116. data/test/unit/test_clone.rb +69 -0
  117. data/test/unit/test_descendant_appends.rb +3 -3
  118. data/test/unit/test_document.rb +49 -67
  119. data/test/unit/test_dynamic_finder.rb +53 -51
  120. data/test/unit/test_embedded_document.rb +19 -38
  121. data/test/unit/{test_support.rb → test_extensions.rb} +136 -122
  122. data/test/unit/test_key.rb +185 -0
  123. data/test/unit/test_keys.rb +29 -147
  124. data/test/unit/test_mongo_mapper.rb +3 -48
  125. data/test/unit/test_pagination.rb +1 -150
  126. data/test/unit/test_rails.rb +77 -19
  127. data/test/unit/test_rails_compatibility.rb +12 -12
  128. data/test/unit/test_serialization.rb +5 -5
  129. data/test/unit/test_time_zones.rb +9 -9
  130. data/test/unit/test_validations.rb +46 -46
  131. metadata +157 -155
  132. data/.gitignore +0 -10
  133. data/Rakefile +0 -55
  134. data/VERSION +0 -1
  135. data/lib/mongo_mapper/plugins/pagination/proxy.rb +0 -72
  136. data/lib/mongo_mapper/query.rb +0 -130
  137. data/lib/mongo_mapper/support.rb +0 -215
  138. data/mongo_mapper.gemspec +0 -196
  139. data/performance/read_write.rb +0 -52
  140. data/specs.watchr +0 -51
  141. data/test/support/custom_matchers.rb +0 -55
  142. data/test/support/timing.rb +0 -16
  143. data/test/unit/test_query.rb +0 -340
@@ -1,60 +1,68 @@
1
1
  require 'test_helper'
2
2
 
3
+ module CallbacksSupport
4
+ def self.included base
5
+ base.key :name, String
6
+
7
+ [ :before_validation_on_create, :before_validation_on_update,
8
+ :before_validation, :after_validation,
9
+ :before_create, :after_create,
10
+ :before_update, :after_update,
11
+ :before_save, :after_save,
12
+ :before_destroy, :after_destroy].each do |callback|
13
+ callback_method = "#{callback}_callback"
14
+ base.send(callback, callback_method)
15
+ define_method(callback_method) do
16
+ history << callback.to_sym
17
+ end
18
+ end
19
+ end
20
+
21
+ def history
22
+ @history ||= []
23
+ end
24
+
25
+ def clear_history
26
+ embedded_associations.each { |a| self.send(a.name).each(&:clear_history) }
27
+ @history = nil
28
+ end
29
+ end
30
+
3
31
  class CallbacksTest < Test::Unit::TestCase
4
- context "Defining and running callbacks" do
32
+ CreateCallbackOrder = [:before_validation, :before_validation_on_create, :after_validation, :before_save, :before_create, :after_create, :after_save]
33
+ UpdateCallbackOrder = [:before_validation, :before_validation_on_update, :after_validation, :before_save, :before_update, :after_update, :after_save]
34
+
35
+ context "Defining and running callbacks on documents" do
5
36
  setup do
6
- @document = Doc do
7
- key :name, String
8
-
9
- [ :before_validation_on_create, :before_validation_on_update,
10
- :before_validation, :after_validation,
11
- :before_create, :after_create,
12
- :before_update, :after_update,
13
- :before_save, :after_save,
14
- :before_destroy, :after_destroy].each do |callback|
15
- callback_method = "#{callback}_callback"
16
- send(callback, callback_method)
17
- define_method(callback_method) do
18
- history << callback.to_sym
19
- end
20
- end
21
-
22
- def history
23
- @history ||= []
24
- end
25
-
26
- def clear_history
27
- @history = nil
28
- end
29
- end
37
+ @document = Doc { include CallbacksSupport }
30
38
  end
31
-
39
+
32
40
  should "get the order right for creating documents" do
33
41
  doc = @document.create(:name => 'John Nunemaker')
34
- doc.history.should == [:before_validation, :before_validation_on_create, :after_validation, :before_save, :before_create, :after_create, :after_save]
42
+ doc.history.should == CreateCallbackOrder
35
43
  end
36
-
44
+
37
45
  should "get the order right for updating documents" do
38
46
  doc = @document.create(:name => 'John Nunemaker')
39
47
  doc.clear_history
40
48
  doc.name = 'John'
41
49
  doc.save
42
- doc.history.should == [:before_validation, :before_validation_on_update, :after_validation, :before_save, :before_update, :after_update, :after_save]
50
+ doc.history.should == UpdateCallbackOrder
43
51
  end
44
-
52
+
45
53
  should "work for before and after validation" do
46
54
  doc = @document.new(:name => 'John Nunemaker')
47
55
  doc.valid?
48
56
  doc.history.should include(:before_validation)
49
57
  doc.history.should include(:after_validation)
50
58
  end
51
-
59
+
52
60
  should "work for before and after create" do
53
61
  doc = @document.create(:name => 'John Nunemaker')
54
62
  doc.history.should include(:before_create)
55
63
  doc.history.should include(:after_create)
56
64
  end
57
-
65
+
58
66
  should "work for before and after update" do
59
67
  doc = @document.create(:name => 'John Nunemaker')
60
68
  doc.name = 'John Doe'
@@ -62,7 +70,7 @@ class CallbacksTest < Test::Unit::TestCase
62
70
  doc.history.should include(:before_update)
63
71
  doc.history.should include(:after_update)
64
72
  end
65
-
73
+
66
74
  should "work for before and after save" do
67
75
  doc = @document.new
68
76
  doc.name = 'John Doe'
@@ -70,7 +78,7 @@ class CallbacksTest < Test::Unit::TestCase
70
78
  doc.history.should include(:before_save)
71
79
  doc.history.should include(:after_save)
72
80
  end
73
-
81
+
74
82
  should "work for before and after destroy" do
75
83
  doc = @document.create(:name => 'John Nunemaker')
76
84
  doc.destroy
@@ -78,4 +86,66 @@ class CallbacksTest < Test::Unit::TestCase
78
86
  doc.history.should include(:after_destroy)
79
87
  end
80
88
  end
89
+
90
+ context "Defining and running callbacks on many embedded documents" do
91
+ setup do
92
+ @root_class = Doc { include CallbacksSupport }
93
+ @child_class = EDoc { include CallbacksSupport }
94
+ @grand_child_class = EDoc { include CallbacksSupport }
95
+
96
+ @root_class.many :children, :class => @child_class
97
+ @child_class.many :children, :class => @grand_child_class
98
+ end
99
+
100
+ should "get the order right based on root document creation" do
101
+ grand = @grand_child_class.new(:name => 'Grand Child')
102
+ child = @child_class.new(:name => 'Child', :children => [grand])
103
+ root = @root_class.create(:name => 'Parent', :children => [child])
104
+
105
+ child = root.children.first
106
+ child.history.should == CreateCallbackOrder
107
+
108
+ grand = root.children.first.children.first
109
+ grand.history.should == CreateCallbackOrder
110
+ end
111
+
112
+ should "get the order right based on root document updating" do
113
+ grand = @grand_child_class.new(:name => 'Grand Child')
114
+ child = @child_class.new(:name => 'Child', :children => [grand])
115
+ root = @root_class.create(:name => 'Parent', :children => [child])
116
+ root.clear_history
117
+ root.update_attributes(:name => 'Updated Parent')
118
+
119
+ child = root.children.first
120
+ child.history.should == UpdateCallbackOrder
121
+
122
+ grand = root.children.first.children.first
123
+ grand.history.should == UpdateCallbackOrder
124
+ end
125
+
126
+ should "work for before and after destroy" do
127
+ grand = @grand_child_class.new(:name => 'Grand Child')
128
+ child = @child_class.new(:name => 'Child', :children => [grand])
129
+ root = @root_class.create(:name => 'Parent', :children => [child])
130
+ root.destroy
131
+ child = root.children.first
132
+ child.history.should include(:before_destroy)
133
+ child.history.should include(:after_destroy)
134
+
135
+ grand = root.children.first.children.first
136
+ grand.history.should include(:before_destroy)
137
+ grand.history.should include(:after_destroy)
138
+ end
139
+
140
+ should "not attempt to run callback defined on root that is not defined on embedded association" do
141
+ @root_class.define_callbacks :after_publish
142
+ @root_class.after_save { |d| d.run_callbacks(:after_publish) }
143
+
144
+ assert_nothing_raised do
145
+ child = @child_class.new(:name => 'Child')
146
+ root = @root_class.create(:name => 'Parent', :children => [child])
147
+ child.history.should_not include(:after_publish)
148
+ end
149
+ end
150
+ end
81
151
  end
@@ -46,7 +46,7 @@ class DirtyTest < Test::Unit::TestCase
46
46
  should "not happen when loading from database" do
47
47
  doc = @document.create(:phrase => 'Foo')
48
48
  doc = @document.find(doc.id)
49
-
49
+
50
50
  doc.changed?.should be_false
51
51
  doc.phrase = 'Fart'
52
52
  doc.changed?.should be_true
@@ -75,7 +75,7 @@ class DirtyTest < Test::Unit::TestCase
75
75
  end
76
76
  end
77
77
  end
78
-
78
+
79
79
  context "blank new value and type float" do
80
80
  should "not mark changes" do
81
81
  @document.key :amount, Float
@@ -87,73 +87,73 @@ class DirtyTest < Test::Unit::TestCase
87
87
  doc.amount_change.should be_nil
88
88
  end
89
89
  end
90
- end
91
-
90
+ end
91
+
92
92
  context "changed?" do
93
93
  should "be true if key changed" do
94
94
  doc = @document.new
95
95
  doc.phrase = 'A penny saved is a penny earned.'
96
96
  doc.changed?.should be_true
97
97
  end
98
-
98
+
99
99
  should "be false if no keys changed" do
100
100
  @document.new.changed?.should be_false
101
101
  end
102
102
  end
103
-
103
+
104
104
  context "changes" do
105
105
  should "be empty hash if no changes" do
106
106
  @document.new.changes.should == {}
107
107
  end
108
-
108
+
109
109
  should "be hash of keys with values of changes if there are changes" do
110
110
  doc = @document.new
111
111
  doc.phrase = 'A penny saved is a penny earned.'
112
112
  doc.changes['phrase'].should == [nil, 'A penny saved is a penny earned.']
113
113
  end
114
114
  end
115
-
115
+
116
116
  context "changed" do
117
117
  should "be empty array if no changes" do
118
118
  @document.new.changed.should == []
119
119
  end
120
-
120
+
121
121
  should "be array of keys that have changed if there are changes" do
122
122
  doc = @document.new
123
123
  doc.phrase = 'A penny saved is a penny earned.'
124
124
  doc.changed.should == ['phrase']
125
125
  end
126
126
  end
127
-
127
+
128
128
  context "will_change!" do
129
129
  should "mark changes" do
130
130
  doc = @document.create(:phrase => 'Foo')
131
-
131
+
132
132
  doc.phrase << 'bar'
133
133
  doc.phrase_changed?.should be_false
134
-
134
+
135
135
  doc.phrase_will_change!
136
136
  doc.phrase_changed?.should be_true
137
137
  doc.phrase_change.should == ['Foobar', 'Foobar']
138
-
138
+
139
139
  doc.phrase << '!'
140
140
  doc.phrase_changed?.should be_true
141
141
  doc.phrase_change.should == ['Foobar', 'Foobar!']
142
142
  end
143
143
  end
144
-
144
+
145
145
  context "changing a foreign key through association" do
146
146
  should "mark changes" do
147
147
  project_class = Doc do
148
148
  key :name, String
149
149
  end
150
-
150
+
151
151
  milestone_class = Doc do
152
152
  key :project_id, ObjectId
153
153
  key :name, String
154
154
  end
155
155
  milestone_class.belongs_to :project, :class => project_class
156
-
156
+
157
157
  milestone = milestone_class.create(:name => 'Launch')
158
158
  milestone.project = project_class.create(:name => 'Harmony')
159
159
  milestone.changed?.should be_true