vidibus-inheritance 0.3.9 → 0.3.10

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,8 +1,8 @@
1
- require 'rubygems'
2
- require 'rake'
1
+ require "rubygems"
2
+ require "rake"
3
3
 
4
4
  begin
5
- require 'jeweler'
5
+ require "jeweler"
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "vidibus-inheritance"
8
8
  gem.summary = %Q{Provides inheritance for models.}
@@ -12,8 +12,8 @@ begin
12
12
  gem.authors = ["Andre Pankratz"]
13
13
  gem.add_development_dependency "rspec", ">= 1.2.9"
14
14
  gem.add_development_dependency "relevance-rcov"
15
- gem.add_development_dependency "mongoid", "= 2.0.0.beta.15"
16
15
  gem.add_development_dependency "rr"
16
+ gem.add_development_dependency "mongoid", "= 2.0.0.beta.15"
17
17
  gem.add_dependency "vidibus-core_extensions"
18
18
  gem.add_dependency "vidibus-uuid"
19
19
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
@@ -23,16 +23,16 @@ rescue LoadError
23
23
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
24
24
  end
25
25
 
26
- require 'spec/rake/spectask'
26
+ require "spec/rake/spectask"
27
27
  Spec::Rake::SpecTask.new(:spec) do |spec|
28
- spec.libs << 'lib' << 'spec'
29
- spec.spec_files = FileList['spec/**/*_spec.rb']
28
+ spec.libs << "lib" << "spec"
29
+ spec.spec_files = FileList["spec/**/*_spec.rb"]
30
30
  end
31
31
 
32
32
  Spec::Rake::SpecTask.new(:rcov) do |t|
33
- t.spec_files = FileList['spec/vidibus/**/*_spec.rb']
33
+ t.spec_files = FileList["spec/vidibus/**/*_spec.rb"]
34
34
  t.rcov = true
35
- t.rcov_opts = ['--exclude', '^spec,/gems/']
35
+ t.rcov_opts = ["--exclude", "^spec,/gems/"]
36
36
  end
37
37
 
38
38
  task :spec => :check_dependencies
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.9
1
+ 0.3.10
@@ -74,7 +74,7 @@ module Vidibus
74
74
 
75
75
  # Setter for ancestor.
76
76
  def ancestor=(obj)
77
- self.ancestor_uuid = obj.uuid
77
+ self.ancestor_uuid = obj ? obj.uuid : nil
78
78
  @ancestor = obj
79
79
  end
80
80
 
@@ -129,11 +129,15 @@ module Vidibus
129
129
  end
130
130
 
131
131
  # Creates a sibling with identical inheritable attributes.
132
- # Applies inheritance on new object.
132
+ # First it inherits from self and then applies ancestry of self.
133
133
  def clone!
134
- exceptions = ACQUIRED_ATTRIBUTES - ["ancestor_uuid"]
135
- attrs = attributes.except(*exceptions)
136
- self.class.create!(attrs)
134
+ clone = self.class.new
135
+ clone.inherit_from!(self)
136
+ clone.ancestor = ancestor
137
+ clone.mutated_attributes = mutated_attributes
138
+ clone.inherited_attributes = inherited_attributes
139
+ clone.save!
140
+ clone
137
141
  end
138
142
 
139
143
  private
@@ -164,13 +168,16 @@ module Vidibus
164
168
  # embeds_many
165
169
  if inheritable.is_a?(Array)
166
170
  collection = new_record? ? self.send(association) : self.reload.send(association)
167
- existing_ids = collection.map do |a|
168
- begin
169
- a._reference_id
170
- rescue
171
- end
172
- end
171
+ existing_ids = collection.map { |a| a.try!(:_reference_id) }
173
172
 
173
+ obsolete = (existing_ids - inheritable.map { |i| i._id }).compact
174
+ obsolete -= collection.select do |c|
175
+ obsolete.include?(c.try!(:_reference_id)) and c.try!(:mutated?) # Exclude mutated items
176
+ end.map { |c| c.try!(:_reference_id) }
177
+ if obsolete.any?
178
+ collection.delete_all(:conditions => { :_reference_id.in => obsolete })
179
+ end
180
+
174
181
  for obj in inheritable
175
182
  attrs = inheritable_document_attributes(obj)
176
183
  if existing_ids.include?(obj._id)
@@ -180,10 +187,6 @@ module Vidibus
180
187
  doc = collection.create!(attrs)
181
188
  end
182
189
  end
183
- obsolete = (existing_ids - inheritable.map { |i| i._id }).compact
184
- if obsolete.any?
185
- collection.delete_all(:conditions => { :_reference_id.in => obsolete })
186
- end
187
190
 
188
191
  # embeds_one
189
192
  else
@@ -0,0 +1,92 @@
1
+ require "spec_helper"
2
+
3
+ describe "Cloning" do
4
+ let(:ancestor) { Model.create }
5
+ let(:inheritor) { Model.new }
6
+ let(:anna) { Model.create!(:name => "Anna", :age => 35) }
7
+ let(:leah) { Model.create!(:name => "Leah", :age => 30) }
8
+
9
+ it "should create a sibling" do
10
+ twin = anna.clone!
11
+ twin.should_not eql(anna)
12
+ twin.name.should eql(anna.name)
13
+ twin.age.should eql(anna.age)
14
+ end
15
+
16
+ it "should set no ancestor if original did not have one" do
17
+ anna.ancestor_uuid.should be_nil
18
+ anna.ancestor.should be_nil
19
+ twin = anna.clone!
20
+ twin.reload
21
+ twin.ancestor_uuid.should be_nil
22
+ twin.ancestor.should be_nil
23
+ end
24
+
25
+ context "with ancestor" do
26
+ before { anna.inherit_from!(ancestor) }
27
+ let(:twin) { anna.clone! }
28
+
29
+ it "should preserve ancestor relation" do
30
+ twin.ancestor.should eql(ancestor)
31
+ end
32
+
33
+ it "should not clone inheritors (should it?)" do
34
+ twin.inheritors.should be_empty
35
+ end
36
+
37
+ it "should set ancestor of orginal" do
38
+ twin.reload.ancestor.should eql(ancestor)
39
+ end
40
+
41
+ it "should clone mutated_attributes" do
42
+ twin.reload.mutated_attributes.should eql(anna.mutated_attributes)
43
+ end
44
+ end
45
+
46
+ context "with embedded documents" do
47
+ before { anna.children.create(:name => "Lisa") }
48
+
49
+ it "should work for collections" do
50
+ twin = anna.clone!
51
+ twin.children.should have(1).child
52
+ end
53
+
54
+ it "should work for single documents" do
55
+ anna.create_location(:name => "Bathroom")
56
+ twin = anna.clone!
57
+ twin.location.name.should eql("Bathroom")
58
+ end
59
+
60
+ it "should set unique _ids" do
61
+ twin = anna.clone!
62
+ twin.children.first._id.should_not eql(anna.children.first._id)
63
+ end
64
+
65
+ it "should clone children of embedded documents" do
66
+ lisa = anna.children.first
67
+ lisa.puppets.create(:name => "Gonzo")
68
+ twin = anna.clone!
69
+ lisa_twin = twin.children.first
70
+ lisa_twin.puppets.should have(1).puppet
71
+ end
72
+
73
+ it "should set unique _id on children of embedded documents" do
74
+ pending("This is really hard to do! Is it inevitable?")
75
+ lisa = anna.children.first
76
+ lisa.puppets.create(:name => "Gonzo")
77
+ twin = anna.clone!
78
+ lisa_twin = twin.children.first
79
+ lisa_twin.puppets.first._id.should_not eql(lisa_twin.puppets.first._id)
80
+ end
81
+
82
+ context "and ancestor" do
83
+ let(:eva) { Model.create!(:ancestor => anna) }
84
+ let(:twin) { eva.clone!.reload }
85
+
86
+ it "should maintain correct _reference_id" do
87
+ eva.children.first._reference_id.should eql(anna.children.first._id)
88
+ twin.children.first._reference_id.should eql(anna.children.first._id)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -4,6 +4,7 @@ describe "Inheritance" do
4
4
  let(:ancestor) { Model.create }
5
5
  let(:inheritor) { Model.new }
6
6
  let(:anna) { Model.create!(:name => "Anna", :age => 35) }
7
+ let(:leah) { Model.create!(:name => "Leah", :age => 30) }
7
8
 
8
9
  it "should happen when creating objects" do
9
10
  ancestor # trigger object creation before mocking
@@ -199,6 +200,32 @@ describe "Inheritance" do
199
200
  inheritor.reload
200
201
  inheritor.children.first.puppets.should have(1).puppet
201
202
  end
203
+
204
+ context "switching the ancestor" do
205
+ it "should remove previously inherited subobjects" do
206
+ inheritor.inherit_from!(leah)
207
+ inheritor.children.should have(0).children
208
+ end
209
+
210
+ it "should keep previously inherited subobjects if they have been mutated" do
211
+ inheritor.children.first.update_attributes(:mutated => true)
212
+ inheritor.inherit_from!(leah)
213
+ inheritor.children.should have(1).child
214
+ end
215
+
216
+ it "should keep own subobjects" do
217
+ inheritor.children.create(:name => "Ronja")
218
+ inheritor.inherit_from!(leah)
219
+ inheritor.children.should have(1).child
220
+ end
221
+
222
+ it "should add subobjects of new ancestor" do
223
+ leah.children.create(:name => "Luke")
224
+ inheritor.inherit_from!(leah)
225
+ inheritor.children.should have(1).child
226
+ inheritor.children.first.name.should eql("Luke")
227
+ end
228
+ end
202
229
  end
203
230
 
204
231
  context "with embedded items" do
@@ -393,4 +420,5 @@ describe "Inheritance" do
393
420
  end
394
421
  end
395
422
  end
423
+
396
424
  end
@@ -211,45 +211,7 @@ describe "Vidibus::Inheritance::Mongoid" do
211
211
  end
212
212
 
213
213
  describe "#clone!" do
214
- it "should create a sibling" do
215
- twin = anna.clone!
216
- twin.should_not eql(anna)
217
- twin.name.should eql(anna.name)
218
- twin.age.should eql(anna.age)
219
- end
220
-
221
- it "should preserve ancestor relation" do
222
- anna.inherit_from!(ancestor)
223
- twin = anna.clone!
224
- twin.ancestor.should eql(ancestor)
225
- end
226
-
227
- it "should not clone inheritors (should it?)" do
228
- anna.inherit_from!(ancestor)
229
- twin = ancestor.clone!
230
- twin.inheritors.should be_empty
231
- end
232
-
233
- it "should clone embedded documents" do
234
- anna.children.create(:name => "Lisa")
235
- twin = anna.clone!
236
- twin.children.should have(1).child
237
- end
238
-
239
- it "should clone a single embedded document" do
240
- anna.create_location(:name => "Bathroom")
241
- twin = anna.clone!
242
- twin.location.name.should eql("Bathroom")
243
- end
244
-
245
- it "should clone children of embedded documents" do
246
- lisa = anna.children.create(:name => "Lisa")
247
- lisa.puppets.create(:name => "Gonzo")
248
- twin = anna.clone!
249
- lisa_twin = twin.children.first
250
- lisa_twin.puppets.should have(1).puppet
251
- # lisa_twin.puppets.first._id.should_not eql(lisa_twin.puppets.first._id)
252
- end
214
+ # see cloning_spec.rb
253
215
  end
254
216
 
255
217
  describe ".inheritable_documents" do
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{vidibus-inheritance}
8
- s.version = "0.3.9"
8
+ s.version = "0.3.10"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andre Pankratz"]
12
- s.date = %q{2010-08-11}
12
+ s.date = %q{2010-08-16}
13
13
  s.description = %q{This gem allows inheritance of objects for Rails 3 with Mongoid. It will update all attributes and embedded documents of inheritors when ancestor gets changed.}
14
14
  s.email = %q{andre@vidibus.com}
15
15
  s.extra_rdoc_files = [
@@ -33,6 +33,7 @@ Gem::Specification.new do |s|
33
33
  "spec/models.rb",
34
34
  "spec/spec.opts",
35
35
  "spec/spec_helper.rb",
36
+ "spec/vidibus/inheritance/cloning_spec.rb",
36
37
  "spec/vidibus/inheritance/inheritance_spec.rb",
37
38
  "spec/vidibus/inheritance/mongoid_spec.rb",
38
39
  "spec/vidibus/inheritance/validators/ancestor_validator_spec.rb",
@@ -46,6 +47,7 @@ Gem::Specification.new do |s|
46
47
  s.test_files = [
47
48
  "spec/models.rb",
48
49
  "spec/spec_helper.rb",
50
+ "spec/vidibus/inheritance/cloning_spec.rb",
49
51
  "spec/vidibus/inheritance/inheritance_spec.rb",
50
52
  "spec/vidibus/inheritance/mongoid_spec.rb",
51
53
  "spec/vidibus/inheritance/validators/ancestor_validator_spec.rb"
@@ -58,23 +60,23 @@ Gem::Specification.new do |s|
58
60
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
59
61
  s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
60
62
  s.add_development_dependency(%q<relevance-rcov>, [">= 0"])
61
- s.add_development_dependency(%q<mongoid>, ["= 2.0.0.beta.15"])
62
63
  s.add_development_dependency(%q<rr>, [">= 0"])
64
+ s.add_development_dependency(%q<mongoid>, ["= 2.0.0.beta.15"])
63
65
  s.add_runtime_dependency(%q<vidibus-core_extensions>, [">= 0"])
64
66
  s.add_runtime_dependency(%q<vidibus-uuid>, [">= 0"])
65
67
  else
66
68
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
67
69
  s.add_dependency(%q<relevance-rcov>, [">= 0"])
68
- s.add_dependency(%q<mongoid>, ["= 2.0.0.beta.15"])
69
70
  s.add_dependency(%q<rr>, [">= 0"])
71
+ s.add_dependency(%q<mongoid>, ["= 2.0.0.beta.15"])
70
72
  s.add_dependency(%q<vidibus-core_extensions>, [">= 0"])
71
73
  s.add_dependency(%q<vidibus-uuid>, [">= 0"])
72
74
  end
73
75
  else
74
76
  s.add_dependency(%q<rspec>, [">= 1.2.9"])
75
77
  s.add_dependency(%q<relevance-rcov>, [">= 0"])
76
- s.add_dependency(%q<mongoid>, ["= 2.0.0.beta.15"])
77
78
  s.add_dependency(%q<rr>, [">= 0"])
79
+ s.add_dependency(%q<mongoid>, ["= 2.0.0.beta.15"])
78
80
  s.add_dependency(%q<vidibus-core_extensions>, [">= 0"])
79
81
  s.add_dependency(%q<vidibus-uuid>, [">= 0"])
80
82
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vidibus-inheritance
3
3
  version: !ruby/object:Gem::Version
4
- hash: 1
4
+ hash: 7
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 9
10
- version: 0.3.9
9
+ - 10
10
+ version: 0.3.10
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andre Pankratz
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-11 00:00:00 +02:00
18
+ date: 2010-08-16 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -49,35 +49,35 @@ dependencies:
49
49
  type: :development
50
50
  version_requirements: *id002
51
51
  - !ruby/object:Gem::Dependency
52
- name: mongoid
52
+ name: rr
53
53
  prerelease: false
54
54
  requirement: &id003 !ruby/object:Gem::Requirement
55
55
  none: false
56
56
  requirements:
57
- - - "="
57
+ - - ">="
58
58
  - !ruby/object:Gem::Version
59
- hash: 62196477
59
+ hash: 3
60
60
  segments:
61
- - 2
62
- - 0
63
61
  - 0
64
- - beta
65
- - 15
66
- version: 2.0.0.beta.15
62
+ version: "0"
67
63
  type: :development
68
64
  version_requirements: *id003
69
65
  - !ruby/object:Gem::Dependency
70
- name: rr
66
+ name: mongoid
71
67
  prerelease: false
72
68
  requirement: &id004 !ruby/object:Gem::Requirement
73
69
  none: false
74
70
  requirements:
75
- - - ">="
71
+ - - "="
76
72
  - !ruby/object:Gem::Version
77
- hash: 3
73
+ hash: 62196477
78
74
  segments:
75
+ - 2
79
76
  - 0
80
- version: "0"
77
+ - 0
78
+ - beta
79
+ - 15
80
+ version: 2.0.0.beta.15
81
81
  type: :development
82
82
  version_requirements: *id004
83
83
  - !ruby/object:Gem::Dependency
@@ -134,6 +134,7 @@ files:
134
134
  - spec/models.rb
135
135
  - spec/spec.opts
136
136
  - spec/spec_helper.rb
137
+ - spec/vidibus/inheritance/cloning_spec.rb
137
138
  - spec/vidibus/inheritance/inheritance_spec.rb
138
139
  - spec/vidibus/inheritance/mongoid_spec.rb
139
140
  - spec/vidibus/inheritance/validators/ancestor_validator_spec.rb
@@ -175,6 +176,7 @@ summary: Provides inheritance for models.
175
176
  test_files:
176
177
  - spec/models.rb
177
178
  - spec/spec_helper.rb
179
+ - spec/vidibus/inheritance/cloning_spec.rb
178
180
  - spec/vidibus/inheritance/inheritance_spec.rb
179
181
  - spec/vidibus/inheritance/mongoid_spec.rb
180
182
  - spec/vidibus/inheritance/validators/ancestor_validator_spec.rb