mongoid_alize 0.1.0 → 0.2.0

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 (30) hide show
  1. data/config/locales/en.yml +10 -0
  2. data/lib/mongoid/alize/callback.rb +47 -3
  3. data/lib/mongoid/alize/callbacks/from/many.rb +6 -8
  4. data/lib/mongoid/alize/callbacks/from/one.rb +21 -9
  5. data/lib/mongoid/alize/callbacks/to/many_from_many.rb +2 -1
  6. data/lib/mongoid/alize/callbacks/to/many_from_one.rb +1 -1
  7. data/lib/mongoid/alize/callbacks/to/one_from_many.rb +1 -1
  8. data/lib/mongoid/alize/callbacks/to/one_from_one.rb +1 -1
  9. data/lib/mongoid/alize/errors/alize_error.rb +13 -0
  10. data/lib/mongoid/alize/errors/already_defined_field.rb +15 -0
  11. data/lib/mongoid/alize/errors/invalid_field.rb +15 -0
  12. data/lib/mongoid/alize/from_callback.rb +16 -3
  13. data/lib/mongoid/alize/to_callback.rb +29 -5
  14. data/lib/mongoid/alize/to_many_callback.rb +26 -21
  15. data/lib/mongoid/alize/to_one_callback.rb +2 -3
  16. data/lib/mongoid_alize.rb +6 -1
  17. data/spec/app/models/head.rb +4 -0
  18. data/spec/app/models/person.rb +3 -0
  19. data/spec/mongoid/alize/callback_spec.rb +46 -8
  20. data/spec/mongoid/alize/callbacks/from/many_spec.rb +92 -18
  21. data/spec/mongoid/alize/callbacks/from/one_spec.rb +106 -23
  22. data/spec/mongoid/alize/callbacks/to/many_from_many_spec.rb +9 -16
  23. data/spec/mongoid/alize/callbacks/to/many_from_one_spec.rb +8 -15
  24. data/spec/mongoid/alize/callbacks/to/one_from_many_spec.rb +14 -17
  25. data/spec/mongoid/alize/callbacks/to/one_from_one_spec.rb +12 -15
  26. data/spec/mongoid/alize/from_callback_spec.rb +44 -0
  27. data/spec/mongoid/alize/to_callback_spec.rb +74 -0
  28. data/spec/mongoid_alize_spec.rb +152 -16
  29. data/spec/spec_helper.rb +6 -0
  30. metadata +27 -21
@@ -6,16 +6,17 @@ describe Mongoid::Alize::Callbacks::To::ManyFromOne do
6
6
  end
7
7
 
8
8
  def args
9
- [Person, :seen_by, [:name, :created_at]]
9
+ [Person, :seen_by, [:name, :location, :created_at]]
10
10
  end
11
11
 
12
- def new_unit
12
+ def new_callback
13
13
  klass.new(*args)
14
14
  end
15
15
 
16
16
  def sees_fields
17
17
  { "_id" => @person.id,
18
18
  "name"=> "Bob",
19
+ "location" => "Paris",
19
20
  "created_at"=> @now.to_s(:utc) }
20
21
  end
21
22
 
@@ -32,20 +33,16 @@ describe Mongoid::Alize::Callbacks::To::ManyFromOne do
32
33
  :sees => [@person = Person.create(:name => "Bob",
33
34
  :created_at => @now = Time.now)])
34
35
  @person.seen_by = @head
35
- @unit = new_unit
36
+ @callback = new_callback
36
37
  end
37
38
 
38
39
  describe "#define_callback" do
39
40
  before do
40
- @unit.send(:define_callback)
41
+ @callback.send(:define_callback)
41
42
  end
42
43
 
43
44
  def run_callback
44
- @person.send(callback_name)
45
- end
46
-
47
- def callback_name
48
- "denormalize_to_seen_by"
45
+ @person.send(:_denormalize_to_seen_by)
49
46
  end
50
47
 
51
48
  it "should push the fields to the relation" do
@@ -75,15 +72,11 @@ describe Mongoid::Alize::Callbacks::To::ManyFromOne do
75
72
 
76
73
  describe "#define_destroy_callback" do
77
74
  before do
78
- @unit.send(:define_destroy_callback)
75
+ @callback.send(:define_destroy_callback)
79
76
  end
80
77
 
81
78
  def run_destroy_callback
82
- @person.send(destroy_callback_name)
83
- end
84
-
85
- def destroy_callback_name
86
- "denormalize_destroy_to_seen_by"
79
+ @person.send(:_denormalize_destroy_to_seen_by)
87
80
  end
88
81
 
89
82
  it "should pull first any existing array entries matching the _id" do
@@ -6,16 +6,17 @@ describe Mongoid::Alize::Callbacks::To::OneFromMany do
6
6
  end
7
7
 
8
8
  def args
9
- [Person, :heads, [:name, :created_at]]
9
+ [Person, :heads, [:name, :location, :created_at]]
10
10
  end
11
11
 
12
- def new_unit
12
+ def new_callback
13
13
  klass.new(*args)
14
14
  end
15
15
 
16
16
  before do
17
17
  Head.class_eval do
18
18
  field :captor_name, :type => String
19
+ field :captor_location, :type => String
19
20
  field :captor_created_at, :type => Time
20
21
  end
21
22
 
@@ -24,49 +25,45 @@ describe Mongoid::Alize::Callbacks::To::OneFromMany do
24
25
  :created_at => @now = Time.now))
25
26
  @person.heads = [@head]
26
27
 
27
- @unit = new_unit
28
+ @callback = new_callback
28
29
  end
29
30
 
30
31
  describe "#define_callback" do
31
32
  before do
32
- @unit.send(:define_callback)
33
+ @callback.send(:define_callback)
33
34
  end
34
35
 
35
36
  def run_callback
36
- @person.send(callback_name)
37
- end
38
-
39
- def callback_name
40
- "denormalize_to_heads"
37
+ @person.send(:_denormalize_to_heads)
41
38
  end
42
39
 
43
40
  it "should push the fields to the relation" do
44
41
  @head.captor_name.should be_nil
42
+ @head.captor_location.should be_nil
45
43
  @head.captor_created_at.should be_nil
46
44
  run_callback
47
45
  @head.captor_name.should == "Bob"
46
+ @head.captor_location.should == "Paris"
48
47
  @head.captor_created_at.to_i.should == @now.to_i
49
48
  end
50
49
  end
51
50
 
52
51
  describe "#define_destroy_callback" do
53
52
  def run_destroy_callback
54
- @person.send(destroy_callback_name)
55
- end
56
-
57
- def destroy_callback_name
58
- "denormalize_destroy_to_heads"
53
+ @person.send(:_denormalize_destroy_to_heads)
59
54
  end
60
55
 
61
56
  before do
62
- @unit.send(:define_destroy_callback)
57
+ @callback.send(:define_destroy_callback)
63
58
  end
64
59
 
65
60
  it "should remove the fields from the relation" do
66
- @head.captor_name.should be_nil
67
- @head.captor_created_at.should be_nil
61
+ @head.captor_name = "Chuck"
62
+ @head.captor_location = "Paris"
63
+ @head.captor_created_at = Time.now
68
64
  run_destroy_callback
69
65
  @head.captor_name.should be_nil
66
+ @head.captor_location.should be_nil
70
67
  @head.captor_created_at.should be_nil
71
68
  end
72
69
  end
@@ -6,16 +6,17 @@ describe Mongoid::Alize::Callbacks::To::OneFromOne do
6
6
  end
7
7
 
8
8
  def args
9
- [Person, :head, [:name, :created_at]]
9
+ [Person, :head, [:name, :location, :created_at]]
10
10
  end
11
11
 
12
- def new_unit
12
+ def new_callback
13
13
  klass.new(*args)
14
14
  end
15
15
 
16
16
  before do
17
17
  Head.class_eval do
18
18
  field :person_name, :type => String
19
+ field :person_location, :type => String
19
20
  field :person_created_at, :type => Time
20
21
  end
21
22
 
@@ -23,27 +24,25 @@ describe Mongoid::Alize::Callbacks::To::OneFromOne do
23
24
  :person => @person = Person.create(:name => "Bob",
24
25
  :created_at => @now = Time.now))
25
26
 
26
- @unit = new_unit
27
+ @callback = new_callback
27
28
  end
28
29
 
29
30
  describe "define_callback" do
30
31
  before do
31
- @unit.send(:define_callback)
32
+ @callback.send(:define_callback)
32
33
  end
33
34
 
34
35
  def run_callback
35
- @person.send(callback_name)
36
- end
37
-
38
- def callback_name
39
- "denormalize_to_head"
36
+ @person.send(:_denormalize_to_head)
40
37
  end
41
38
 
42
39
  it "should push the fields to the relation" do
43
40
  @head.person_name.should be_nil
41
+ @head.person_location.should be_nil
44
42
  @head.person_created_at.should be_nil
45
43
  run_callback
46
44
  @head.person_name.should == "Bob"
45
+ @head.person_location.should == "Paris"
47
46
  @head.person_created_at.to_i.should == @now.to_i
48
47
  end
49
48
 
@@ -55,22 +54,20 @@ describe Mongoid::Alize::Callbacks::To::OneFromOne do
55
54
 
56
55
  describe "define_destroy_callback" do
57
56
  before do
58
- @unit.send(:define_destroy_callback)
57
+ @callback.send(:define_destroy_callback)
59
58
  end
60
59
 
61
60
  def run_destroy_callback
62
- @person.send(destroy_callback_name)
63
- end
64
-
65
- def destroy_callback_name
66
- "denormalize_destroy_to_head"
61
+ @person.send(:_denormalize_destroy_to_head)
67
62
  end
68
63
 
69
64
  it "should nillify the fields in the relation" do
70
65
  @head.person_name = "Chuck"
66
+ @head.person_location = "Paris"
71
67
  @head.person_created_at = Time.now
72
68
  run_destroy_callback
73
69
  @head.person_name.should be_nil
70
+ @head.person_location.should be_nil
74
71
  @head.person_created_at.should be_nil
75
72
  end
76
73
 
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ class Mongoid::Alize::SpecFromCallback < Mongoid::Alize::FromCallback
4
+ def define_fields
5
+ end
6
+
7
+ def define_callback
8
+ klass.class_eval <<-CALLBACK
9
+ def _denormalize_from_person
10
+ end
11
+ CALLBACK
12
+ end
13
+ end
14
+
15
+ describe Mongoid::Alize::FromCallback do
16
+ def klass
17
+ Mongoid::Alize::SpecFromCallback
18
+ end
19
+
20
+ def args
21
+ [Head, :person, [:name, :location, :created_at]]
22
+ end
23
+
24
+ def new_callback
25
+ klass.new(*args)
26
+ end
27
+
28
+ before do
29
+ @callback = new_callback
30
+ end
31
+
32
+ describe "#set_callback" do
33
+ it "should set a callback on the klass" do
34
+ mock(@callback.klass).set_callback(:save, :before, "denormalize_from_person")
35
+ @callback.send(:set_callback)
36
+ end
37
+
38
+ it "should not set the callback if it's already set" do
39
+ @callback.send(:attach)
40
+ dont_allow(@callback.klass).set_callback
41
+ @callback.send(:set_callback)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ class Mongoid::Alize::SpecToCallback < Mongoid::Alize::ToCallback
4
+ def define_callback
5
+ klass.class_eval <<-CALLBACK
6
+ def _denormalize_to_head
7
+ end
8
+ CALLBACK
9
+ end
10
+
11
+ def define_destroy_callback
12
+ klass.class_eval <<-CALLBACK
13
+ def _denormalize_destroy_to_head
14
+ end
15
+ CALLBACK
16
+ end
17
+ end
18
+
19
+ describe Mongoid::Alize::ToCallback do
20
+ def klass
21
+ Mongoid::Alize::SpecToCallback
22
+ end
23
+
24
+ def args
25
+ [Person, :head, [:name, :location, :created_at]]
26
+ end
27
+
28
+ def new_callback
29
+ klass.new(*args)
30
+ end
31
+
32
+ before do
33
+ @callback = new_callback
34
+ end
35
+
36
+ describe "#set_callback" do
37
+ it "should set a callback on the klass" do
38
+ mock(@callback.klass).set_callback(:save, :after, "denormalize_to_head")
39
+ @callback.send(:set_callback)
40
+ end
41
+
42
+ it "should not set the callback if it's already set" do
43
+ @callback.send(:attach)
44
+ dont_allow(@callback.klass).set_callback
45
+ @callback.send(:set_callback)
46
+ end
47
+ end
48
+
49
+ describe "#set_destroy_callback" do
50
+ it "should set a destroy callback on the klass" do
51
+ mock(@callback.klass).set_callback(:destroy, :after, "denormalize_destroy_to_head")
52
+ @callback.send(:set_destroy_callback)
53
+ end
54
+
55
+ it "should not set the destroy callback if it's already set" do
56
+ @callback.send(:attach)
57
+ dont_allow(@callback.klass).set_callback
58
+ @callback.send(:set_destroy_callback)
59
+ end
60
+ end
61
+
62
+ describe "#alias_destroy_callback" do
63
+ it "should alias the destroy callback on the klass" do
64
+ mock(@callback.klass).alias_method("denormalize_destroy_to_head", "_denormalize_destroy_to_head")
65
+ @callback.send(:alias_destroy_callback)
66
+ end
67
+
68
+ it "should not alias the destroy callback if it's already set" do
69
+ @callback.send(:attach)
70
+ dont_allow(@callback.klass).alias_method
71
+ @callback.send(:alias_destroy_callback)
72
+ end
73
+ end
74
+ end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Mongoid::Alize do
4
4
  def person_fields
5
- [:name]
5
+ [:name, :location]
6
6
  end
7
7
 
8
8
  def head_fields
@@ -10,8 +10,10 @@ describe Mongoid::Alize do
10
10
  end
11
11
 
12
12
  before do
13
- @head = Head.new(:size => @size = 10)
14
- @person = Person.new(:name => @name = "Bob")
13
+ @now = Time.now
14
+ stub(Time).now { @now }
15
+ @head = Head.new(:size => @size = 10, created_at: @now)
16
+ @person = Person.new(:name => @name = "Bob", created_at: @now)
15
17
  end
16
18
 
17
19
  describe "one-to-one" do
@@ -23,14 +25,29 @@ describe Mongoid::Alize do
23
25
 
24
26
  def assert_head
25
27
  @head.person_name.should == @name
28
+ @head.person_location.should == "Paris"
26
29
  end
27
30
 
28
- it "should pull attributes from person" do
31
+ it "should pull data from person on create" do
29
32
  @head.save!
30
33
  assert_head
31
34
  end
32
35
 
33
- it "should push attributes to head" do
36
+ it "should pull data from a changed person on save" do
37
+ @head.save!
38
+ @head.person = Person.create(:name => @name = "Bill")
39
+ @head.save!
40
+ assert_head
41
+ end
42
+
43
+ it "should not pull data from an unchanged person on save" do
44
+ @head.save!
45
+ @head.person_name = "Cowboy"
46
+ @head.save!
47
+ @head.person_name.should == "Cowboy"
48
+ end
49
+
50
+ it "should push data to head" do
34
51
  @person.update_attributes!(:name => @name = "Bill")
35
52
  assert_head
36
53
  end
@@ -39,6 +56,7 @@ describe Mongoid::Alize do
39
56
  @head.update_attributes!(:person_name => "Old Gregg")
40
57
  @person.destroy
41
58
  @head.person_name.should be_nil
59
+ @head.person_location.should be_nil
42
60
  end
43
61
  end
44
62
 
@@ -52,12 +70,19 @@ describe Mongoid::Alize do
52
70
  @person.head_size.should == @size
53
71
  end
54
72
 
55
- it "should pull attributes from head" do
73
+ it "should pull data from head on create" do
56
74
  @person.save!
57
75
  assert_person
58
76
  end
59
77
 
60
- it "should push attributes to person" do
78
+ it "should pull data from head on save" do
79
+ @person.save!
80
+ @person.head = Head.create(:size => @size = 18)
81
+ @person.save!
82
+ assert_person
83
+ end
84
+
85
+ it "should push data to person" do
61
86
  @head.update_attributes!(:size => @size = "20lbs")
62
87
  assert_person
63
88
  end
@@ -81,17 +106,24 @@ describe Mongoid::Alize do
81
106
  @head.captor_name.should == @name
82
107
  end
83
108
 
84
- it "should pull attributes from head" do
109
+ it "should pull data from captor on create" do
85
110
  @head.save!
86
111
  assert_captor
87
112
  end
88
113
 
89
- it "should push attributes to person" do
114
+ it "should pull data from captor on save" do
115
+ @head.save!
116
+ @head.captor = Person.create(:name => @name = "Bill")
117
+ @head.save!
118
+ assert_captor
119
+ end
120
+
121
+ it "should push data to person" do
90
122
  @person.update_attributes!(:name => @name = "Bill")
91
123
  assert_captor
92
124
  end
93
125
 
94
- it "should nillify captor fieds when person is destroyed" do
126
+ it "should nillify captor fields when person is destroyed" do
95
127
  @head.update_attributes!(:captor_name => "Old Gregg")
96
128
  @person.destroy
97
129
  @head.captor_name.should be_nil
@@ -107,15 +139,23 @@ describe Mongoid::Alize do
107
139
  def assert_sees
108
140
  @head.sees_fields.should == [{
109
141
  "_id" => @person.id,
142
+ "location" => "Paris",
110
143
  "name" => @name }]
111
144
  end
112
145
 
113
- it "should pull attributes from sees" do
146
+ it "should pull data from sees on create" do
147
+ @head.save!
148
+ assert_sees
149
+ end
150
+
151
+ it "should pull data from a sees on save" do
152
+ @head.save!
153
+ @head.sees = [@person = Person.create(:name => @name = "Bill")]
114
154
  @head.save!
115
155
  assert_sees
116
156
  end
117
157
 
118
- it "should push attributes to seen_by" do
158
+ it "should push data to seen_by" do
119
159
  @person.update_attributes!(:name => @name = "Bill")
120
160
  assert_sees
121
161
  end
@@ -134,33 +174,129 @@ describe Mongoid::Alize do
134
174
  describe "has_and_belongs_to_many" do
135
175
  before do
136
176
  Head.send(:alize, :wanted_by, *person_fields)
137
- @head.wanted_by = [@person]
138
- @person.wants = [@head]
139
177
  end
140
178
 
141
179
  def assert_wanted_by
142
180
  @head.wanted_by_fields.should == [{
143
181
  "_id" => @person.id,
182
+ "location" => "Paris",
144
183
  "name" => @name }]
145
184
  end
146
185
 
147
- it "should pull attributes from wanted_by" do
186
+ it "should pull data from wanted_by on create" do
187
+ @head.wanted_by = [@person]
188
+ @head.save!
189
+ assert_wanted_by
190
+ end
191
+
192
+ it "should pull data from wanted_by on save" do
193
+ @head.save!
194
+ @person = Person.create(:name => @name = "Bill")
195
+ @head.wanted_by = [@person]
148
196
  @head.save!
149
197
  assert_wanted_by
150
198
  end
151
199
 
152
- it "should push attributes to wanted_by" do
200
+ it "should push data to wants" do
201
+ @person.wants = [@head]
153
202
  @person.update_attributes!(:name => @name = "Bill")
154
203
  assert_wanted_by
155
204
  end
156
205
 
157
206
  it "should remove wanted_by_fields entries in head when person is destroyed" do
207
+ @head.wanted_by = [@person]
158
208
  @head.save!
159
209
  assert_wanted_by
160
210
  @person.destroy
211
+ @head.reload
161
212
  @head.wanted_by_fields.should == []
162
213
  @head.reload.wanted_by_fields.should == []
163
214
  end
164
215
  end
165
216
  end
217
+
218
+ describe "without specifying fields" do
219
+ before do
220
+ Head.send(:alize, :person)
221
+ @head.person = @person
222
+ end
223
+
224
+ it "should denormalize all non-internal fields" do
225
+ @head.save!
226
+ @head.person_name.should == @name
227
+ @head.person_created_at.to_i.should == @now.to_i
228
+ end
229
+ end
230
+
231
+ describe "overriding denormalize methods for custom behavior on the from side" do
232
+ before do
233
+ class Person
234
+ def denormalize_update_name_first
235
+ self.name = "Overrider"
236
+ end
237
+ end
238
+
239
+ class Head
240
+ def denormalize_from_person
241
+ self.person.denormalize_update_name_first
242
+ _denormalize_from_person
243
+ end
244
+ end
245
+
246
+ Head.send(:alize, :person, *person_fields)
247
+ @head.person = @person
248
+ end
249
+
250
+ it "should be possible to define a method before alize and call the alize version within it" do
251
+ @head.save!
252
+ @head.person_name.should == "Overrider"
253
+ end
254
+ end
255
+
256
+ describe "overriding denormalize methods for custom behavior on the to side" do
257
+ before do
258
+ class Person
259
+ def denormalize_to_head
260
+ self.name = "Overrider"
261
+ _denormalize_to_head
262
+ end
263
+ end
264
+
265
+ Head.send(:alize, :person, *person_fields)
266
+ @head.person = @person
267
+ @head.save!
268
+ end
269
+
270
+ it "should be possible to define a method before alize and call the alize version within it" do
271
+ @person.update_attributes!(:name => @name = "Bill")
272
+ @head.person_name.should == "Overrider"
273
+ end
274
+ end
275
+
276
+ describe "forcing denormalization" do
277
+ before do
278
+ Head.send(:alize, :person, *person_fields)
279
+ @head.person = @person
280
+ @head.save!
281
+ end
282
+
283
+ it "should allow using the force flag to force denormalization" do
284
+ class Head
285
+ def denormalize_from_person
286
+ _denormalize_from_person(true)
287
+ end
288
+ end
289
+
290
+ @head.person_name = "Misty"
291
+ @head.save!
292
+ @head.person_name.should == @name
293
+ end
294
+
295
+ it "should allow using the force_denormalization attribute to force denormalization" do
296
+ @head.person_name = "Misty"
297
+ @head.force_denormalization = true
298
+ @head.save!
299
+ @head.person_name.should == @name
300
+ end
301
+ end
166
302
  end