mongoid_acts_as_tree 0.1.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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Jakob Vidmar
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = mongoid-acts_as_tree
2
+
3
+ This is an implementation of a tree structure for Mongoid.
4
+
5
+ == Installation
6
+
7
+ Install as gem
8
+
9
+ gem install mongoid_acts_as_tree
10
+
11
+ == Usage
12
+
13
+ Enable the tree functionality by declaring acts_as_tree on your model
14
+
15
+ class Category
16
+ include Mongoid::Document
17
+ include Mongoid::Acts::Tree
18
+
19
+ field :name, String
20
+
21
+ acts_as_tree
22
+ end
23
+
24
+ The method accepts :parent_id_field, :path_field, :depth_field, :order as a hash.
25
+
26
+ :parent_id_field, :path_field, :depth_field => override the default field names
27
+ :order => control the order (format ['value', 'asc'] or [['field_1', 'asc'], ['field_2', 'desc']])
28
+
29
+ Check the test_tree.rb for examples.
30
+
31
+ == About bugs
32
+
33
+ Use it. If you find any bugs, contact me (if possible with a test case) or patch it yourself (see next section).
34
+
35
+ == Note on Patches/Pull Requests
36
+
37
+ * Fork the project.
38
+ * Make your feature addition or bug fix.
39
+ * Add tests for it. This is important so I don't break it in a
40
+ future version unintentionally.
41
+ * Commit, do not mess with rakefile, version, or history.
42
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
43
+ * Send me a pull request. Bonus points for topic branches.
44
+
45
+ == Copyright
46
+
47
+ Copyright (c) 2009 Jakob Vidmar. See LICENSE for details.
48
+
data/Rakefile ADDED
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "mongoid_acts_as_tree"
8
+ gem.summary = %Q{ActsAsTree plugin for Mongoid}
9
+ gem.description = %Q{Port of the old, venerable ActsAsTree with a bit of a twist}
10
+ gem.email = "saksmlz@gmail.com"
11
+ gem.homepage = "http://github.com/saks/mongoid_acts_as_tree"
12
+ gem.authors = ["Jakob Vidmar, Aliaksandr Rahalevich"]
13
+ gem.add_dependency("mongoid", "<= 2.0.0")
14
+
15
+ gem.add_development_dependency "shoulda", ">=2.10.2"
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ require 'rake/testtask'
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << 'lib' << 'test'
25
+ test.pattern = 'test/**/test_*.rb'
26
+ test.verbose = true
27
+ end
28
+
29
+ begin
30
+ require 'rcov/rcovtask'
31
+ Rcov::RcovTask.new do |test|
32
+ test.libs << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+ rescue LoadError
37
+ task :rcov do
38
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
39
+ end
40
+ end
41
+
42
+ task :test => :check_dependencies
43
+
44
+ task :default => :test
45
+
46
+ require 'rake/rdoctask'
47
+ Rake::RDocTask.new do |rdoc|
48
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
+
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = "mongoid_acts_as_tree #{version}"
52
+ rdoc.rdoc_files.include('README*')
53
+ rdoc.rdoc_files.include('lib/**/*.rb')
54
+ end
55
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,224 @@
1
+ require "mongoid"
2
+
3
+ module Mongoid
4
+ module Acts
5
+ module Tree
6
+ def self.included(model)
7
+ model.class_eval do
8
+ extend InitializerMethods
9
+ end
10
+ end
11
+
12
+ module InitializerMethods
13
+ def acts_as_tree(options = {})
14
+ options = {
15
+ :parent_id_field => "parent_id",
16
+ :path_field => "path",
17
+ :depth_field => "depth"
18
+ }.merge(options)
19
+
20
+ write_inheritable_attribute :acts_as_tree_options, options
21
+ class_inheritable_reader :acts_as_tree_options
22
+
23
+ include InstanceMethods
24
+ include Fields
25
+ extend Fields
26
+ extend ClassMethods
27
+
28
+ field parent_id_field, :type => Mongo::ObjectID
29
+ field path_field, :type => Array, :default => [], :index => true
30
+ field depth_field, :type => Integer, :default => 0
31
+
32
+ after_save :move_children
33
+ validate :will_save_tree
34
+ before_destroy :destroy_descendants
35
+ end
36
+ end
37
+
38
+ module ClassMethods
39
+ def roots
40
+ self.where(parent_id_field => nil).order_by tree_order
41
+ end
42
+ end
43
+
44
+ module InstanceMethods
45
+ def [](field_name)
46
+ self.send field_name
47
+ end
48
+
49
+ def []=(field_name, value)
50
+ self.send "#{field_name}=", value
51
+ end
52
+
53
+ def ==(other)
54
+ return true if other.equal?(self)
55
+ return true if other.instance_of?(self.class) and other._id == self._id
56
+ false
57
+ end
58
+
59
+ def will_save_tree
60
+ if @_cyclic
61
+ errors.add(:base, "Can't be children of a descendant")
62
+ end
63
+ end
64
+
65
+ def fix_position
66
+ if parent.nil?
67
+ self[parent_id_field] = nil
68
+ self[path_field] = []
69
+ self[depth_field] = 0
70
+ else
71
+ self[parent_id_field] = parent._id
72
+ self[path_field] = parent[path_field] + [parent._id]
73
+ self[depth_field] = parent[depth_field] + 1
74
+ self.save
75
+ end
76
+ end
77
+
78
+ def parent
79
+ @_parent or (self[parent_id_field].nil? ? nil : self.class.find(self[parent_id_field]))
80
+ end
81
+
82
+ def root?
83
+ self[parent_id_field].nil?
84
+ end
85
+
86
+ def root
87
+ self[path_field].first.nil? ? self : self.class.find(self[path_field].first)
88
+ end
89
+
90
+ def ancestors
91
+ return [] if root?
92
+ self.class.find(self[path_field])
93
+ end
94
+
95
+ def self_and_ancestors
96
+ ancestors << self
97
+ end
98
+
99
+ def siblings
100
+ self.class.where(:_id.ne => self._id, parent_id_field => self[parent_id_field]).order_by tree_order
101
+ end
102
+
103
+ def self_and_siblings
104
+ self.class.where(parent_id_field => self[parent_id_field]).order_by tree_order
105
+ end
106
+
107
+ def children
108
+ Children.new self
109
+ end
110
+
111
+ def descendants
112
+ return [] if new_record?
113
+ self.class.where(path_field => self._id).order_by tree_order
114
+ end
115
+
116
+ def self_and_descendants
117
+ [self] + self.descendants
118
+ end
119
+
120
+ def is_ancestor_of?(other)
121
+ other[path_field].include?(self._id)
122
+ end
123
+
124
+ def is_or_is_ancestor_of?(other)
125
+ (other == self) or is_ancestor_of?(other)
126
+ end
127
+
128
+ def is_descendant_of?(other)
129
+ self[path_field].include?(other._id)
130
+ end
131
+
132
+ def is_or_is_descendant_of?(other)
133
+ (other == self) or is_descendant_of?(other)
134
+ end
135
+
136
+ def is_sibling_of?(other)
137
+ (other != self) and (other[parent_id_field] == self[parent_id_field])
138
+ end
139
+
140
+ def is_or_is_sibling_of?(other)
141
+ (other == self) or is_sibling_of?(other)
142
+ end
143
+
144
+ def move_children
145
+
146
+ if @_will_move
147
+ @_will_move = false
148
+ for child in self.children
149
+ child.fix_position
150
+ child.save
151
+ end
152
+ @_will_move = true
153
+ end
154
+ end
155
+
156
+ def destroy_descendants
157
+ self.descendants.each &:destroy
158
+ end
159
+ end
160
+
161
+ #proxy class
162
+ class Children < Array
163
+
164
+ def initialize(owner)
165
+ @parent = owner
166
+ self.concat find_children_for_owner.to_a
167
+ end
168
+
169
+ def find_children_for_owner
170
+ @parent.class.where(@parent.parent_id_field => @parent.id).
171
+ order_by @parent.tree_order
172
+ end
173
+
174
+ def <<(object)
175
+ if object.descendants.include? @parent
176
+ object.instance_variable_set :@_cyclic, true
177
+ else
178
+ object[object.parent_id_field] = @parent._id
179
+ object[object.path_field] = @parent[@parent.path_field] + [@parent._id]
180
+ object[object.depth_field] = @parent[@parent.depth_field] + 1
181
+ object.instance_variable_set :@_will_move, true
182
+ object.save
183
+ end
184
+
185
+ super(object)
186
+ end
187
+
188
+ def delete(object_or_id)
189
+ object = case object_or_id
190
+ when String
191
+ @parent.class.where(:id => object_or_id)
192
+ else
193
+ object_or_id
194
+ end
195
+
196
+ object._parent_id = nil
197
+ object._parent_ids = (object._parent_ids || []) - [@parent.id]
198
+ object.save
199
+ super(object)
200
+ end
201
+
202
+ end
203
+
204
+ module Fields
205
+ def parent_id_field
206
+ acts_as_tree_options[:parent_id_field]
207
+ end
208
+
209
+ def path_field
210
+ acts_as_tree_options[:path_field]
211
+ end
212
+
213
+ def depth_field
214
+ acts_as_tree_options[:depth_field]
215
+ end
216
+
217
+ def tree_order
218
+ acts_as_tree_options[:order] or []
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
224
+
@@ -0,0 +1,63 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{mongoid_acts_as_tree}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jakob Vidmar, Aliaksandr Rahalevich"]
12
+ s.date = %q{2010-04-04}
13
+ s.description = %q{Port of the old, venerable ActsAsTree with a bit of a twist}
14
+ s.email = %q{saksmlz@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/mongoid_acts_as_tree.rb",
27
+ "mongoid_acts_as_tree.gemspec",
28
+ "test/helper.rb",
29
+ "test/models/category.rb",
30
+ "test/models/ordered_category.rb",
31
+ "test/test_order.rb",
32
+ "test/test_tree.rb"
33
+ ]
34
+ s.homepage = %q{http://github.com/saks/mongoid_acts_as_tree}
35
+ s.rdoc_options = ["--charset=UTF-8"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.3.6}
38
+ s.summary = %q{ActsAsTree plugin for Mongoid}
39
+ s.test_files = [
40
+ "test/test_tree.rb",
41
+ "test/test_order.rb",
42
+ "test/models/category.rb",
43
+ "test/models/ordered_category.rb",
44
+ "test/helper.rb"
45
+ ]
46
+
47
+ if s.respond_to? :specification_version then
48
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
52
+ s.add_runtime_dependency(%q<mongoid>, ["<= 2.0.0"])
53
+ s.add_development_dependency(%q<shoulda>, [">= 2.10.2"])
54
+ else
55
+ s.add_dependency(%q<mongoid>, ["<= 2.0.0"])
56
+ s.add_dependency(%q<shoulda>, [">= 2.10.2"])
57
+ end
58
+ else
59
+ s.add_dependency(%q<mongoid>, ["<= 2.0.0"])
60
+ s.add_dependency(%q<shoulda>, [">= 2.10.2"])
61
+ end
62
+ end
63
+
data/test/helper.rb ADDED
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'mongoid'
8
+
9
+ Mongoid.configure.master = Mongo::Connection.new.db('acts_as_tree-test')
10
+
11
+ Dir["#{File.dirname(__FILE__)}/models/*.rb"].each {|file| require file}
12
+
13
+ class Test::Unit::TestCase
14
+ # Drop all columns after each test case.
15
+ def teardown
16
+ Mongoid.database.collections.each do |coll|
17
+ coll.remove
18
+ end
19
+ end
20
+
21
+ # Make sure that each test case has a teardown
22
+ # method to clear the db after each test.
23
+ def inherited(base)
24
+ base.define_method teardown do
25
+ super
26
+ end
27
+ end
28
+
29
+ def eql_arrays?(first, second)
30
+ first.map{|i| i._id}.to_set == second.map{|i| i._id}.to_set
31
+ end
32
+ end
33
+
@@ -0,0 +1,12 @@
1
+ require "mongoid"
2
+ require "mongoid_acts_as_tree"
3
+
4
+ class Category
5
+ include Mongoid::Document
6
+ include Mongoid::Acts::Tree
7
+
8
+ field :name, :type => String
9
+
10
+ acts_as_tree
11
+ end
12
+
@@ -0,0 +1,13 @@
1
+ require "mongoid"
2
+ require "mongoid_acts_as_tree"
3
+
4
+ class OrderedCategory
5
+ include Mongoid::Document
6
+ include Mongoid::Acts::Tree
7
+
8
+ field :name, :type => String
9
+ field :value, :type => Integer
10
+
11
+ acts_as_tree :order => [['value', 'asc']]
12
+ end
13
+
@@ -0,0 +1,35 @@
1
+ require 'helper'
2
+ require 'set'
3
+
4
+ class TestMongoidActsAsTree < Test::Unit::TestCase
5
+ context "Ordered tree" do
6
+ setup do
7
+ @root_1 = OrderedCategory.create(:name => "Root 1", :value => 2)
8
+ @child_1 = OrderedCategory.create(:name => "Child 1", :value => 1)
9
+ @child_2 = OrderedCategory.create(:name => "Child 2", :value => 9)
10
+ @child_2_1 = OrderedCategory.create(:name => "Child 2.1", :value => 2)
11
+
12
+ @child_3 = OrderedCategory.create(:name => "Child 3", :value => 5)
13
+ @root_2 = OrderedCategory.create(:name => "Root 2", :value => 1)
14
+
15
+ @root_1.children << @child_1
16
+ @root_1.children << @child_2
17
+ @root_1.children << @child_3
18
+
19
+ @child_2.children << @child_2_1
20
+ end
21
+
22
+ should "be in order" do
23
+ assert_equal OrderedCategory.roots.to_a, [@root_2, @root_1]
24
+ assert_equal @root_1.children, [@child_1, @child_3, @child_2]
25
+
26
+ assert_equal @root_1.descendants, [@child_1, @child_2_1, @child_3, @child_2]
27
+ assert_equal @root_1.self_and_descendants, [@root_1, @child_1, @child_2_1, @child_3, @child_2]
28
+
29
+ assert_equal @child_2.siblings, [@child_1, @child_3]
30
+ assert_equal @child_2.self_and_siblings, [@child_1, @child_3, @child_2]
31
+ assert_equal @root_1.self_and_siblings, [@root_2, @root_1]
32
+ end
33
+ end
34
+ end
35
+
data/test/test_tree.rb ADDED
@@ -0,0 +1,155 @@
1
+ require 'helper'
2
+ require 'set'
3
+
4
+ $verbose = false
5
+
6
+ class TestMongoidActsAsTree < Test::Unit::TestCase
7
+ context "Tree" do
8
+ setup do
9
+ @root_1 = Category.create(:name => "Root 1")
10
+ @child_1 = Category.create(:name => "Child 1")
11
+ @child_2 = Category.create(:name => "Child 2")
12
+ @child_2_1 = Category.create(:name => "Child 2.1")
13
+
14
+ @child_3 = Category.create(:name => "Child 3")
15
+ @root_2 = Category.create(:name => "Root 2")
16
+
17
+ @root_1.children << @child_1
18
+ @root_1.children << @child_2
19
+ @root_1.children << @child_3
20
+
21
+ @child_2.children << @child_2_1
22
+ end
23
+
24
+ should "add child via <<" do
25
+ child = Category.create(:name => "Child 2.2")
26
+ @root_1.children << child
27
+ assert child.parent == @root_1
28
+ end
29
+
30
+ should "have roots" do
31
+ assert eql_arrays?(Category.roots, [@root_1, @root_2])
32
+ end
33
+
34
+ context "node" do
35
+ should "have a root" do
36
+ assert_equal @root_1.root, @root_1
37
+ assert_not_equal @root_1.root, @root_2.root
38
+ assert_equal @root_1, @child_2_1.root
39
+ end
40
+
41
+ should "have ancestors" do
42
+ assert_equal @root_1.ancestors, []
43
+ assert_equal @child_2_1.ancestors, [@root_1, @child_2]
44
+ assert_equal @root_1.self_and_ancestors, [@root_1]
45
+ assert_equal @child_2_1.self_and_ancestors, [@root_1, @child_2, @child_2_1]
46
+ end
47
+
48
+ should "have siblings" do
49
+ assert eql_arrays?(@root_1.siblings, [@root_2])
50
+ assert eql_arrays?(@child_2.siblings, [@child_1, @child_3])
51
+ assert eql_arrays?(@child_2_1.siblings, [])
52
+ assert eql_arrays?(@root_1.self_and_siblings, [@root_1, @root_2])
53
+ assert eql_arrays?(@child_2.self_and_siblings, [@child_1, @child_2, @child_3])
54
+ assert eql_arrays?(@child_2_1.self_and_siblings, [@child_2_1])
55
+ end
56
+
57
+ should "set depth" do
58
+ assert_equal 0, @root_1.depth
59
+ assert_equal 1, @child_1.depth
60
+ assert_equal 2, @child_2_1.depth
61
+ end
62
+
63
+ should "have children" do
64
+ assert @child_2_1.children.empty?
65
+ assert eql_arrays?(@root_1.children, [@child_1, @child_2, @child_3])
66
+ end
67
+
68
+ should "have descendants" do
69
+ assert eql_arrays?(@root_1.descendants, [@child_1, @child_2, @child_3, @child_2_1])
70
+ assert eql_arrays?(@child_2.descendants, [@child_2_1])
71
+ assert @child_2_1.descendants.empty?
72
+ assert eql_arrays?(@root_1.self_and_descendants, [@root_1, @child_1, @child_2, @child_3, @child_2_1])
73
+ assert eql_arrays?(@child_2.self_and_descendants, [@child_2, @child_2_1])
74
+ assert eql_arrays?(@child_2_1.self_and_descendants, [@child_2_1])
75
+ end
76
+
77
+ should "be able to tell if ancestor" do
78
+ assert @root_1.is_ancestor_of?(@child_1)
79
+ assert !@root_2.is_ancestor_of?(@child_2_1)
80
+ assert !@child_2.is_ancestor_of?(@child_2)
81
+
82
+ assert @root_1.is_or_is_ancestor_of?(@child_1)
83
+ assert !@root_2.is_or_is_ancestor_of?(@child_2_1)
84
+ assert @child_2.is_or_is_ancestor_of?(@child_2)
85
+ end
86
+
87
+ should "be able to tell if descendant" do
88
+ assert !@root_1.is_descendant_of?(@child_1)
89
+ assert @child_1.is_descendant_of?(@root_1)
90
+ assert !@child_2.is_descendant_of?(@child_2)
91
+
92
+ assert !@root_1.is_or_is_descendant_of?(@child_1)
93
+ assert @child_1.is_or_is_descendant_of?(@root_1)
94
+ assert @child_2.is_or_is_descendant_of?(@child_2)
95
+ end
96
+
97
+ should "be able to tell if sibling" do
98
+ assert !@root_1.is_sibling_of?(@child_1)
99
+ assert !@child_1.is_sibling_of?(@child_1)
100
+ assert !@child_2.is_sibling_of?(@child_2)
101
+
102
+ assert !@root_1.is_or_is_sibling_of?(@child_1)
103
+ assert @child_1.is_or_is_sibling_of?(@child_2)
104
+ assert @child_2.is_or_is_sibling_of?(@child_2)
105
+ end
106
+
107
+ context "when moving" do
108
+ should "recalculate path and depth" do
109
+ @child_2.children << @child_3
110
+ @child_3.save
111
+
112
+ assert @child_2.is_or_is_ancestor_of?(@child_3)
113
+ assert @child_3.is_or_is_descendant_of?(@child_2)
114
+ assert @child_2.children.include?(@child_3)
115
+ assert @child_2.descendants.include?(@child_3)
116
+ assert @child_2_1.is_or_is_sibling_of?(@child_3)
117
+ assert_equal 2, @child_3.depth
118
+ end
119
+
120
+ should "move children on save" do
121
+ @root_2.children << @child_2
122
+
123
+ @child_2_1.reload
124
+
125
+ assert @root_2.is_or_is_ancestor_of?(@child_2_1)
126
+ assert @child_2_1.is_or_is_descendant_of?(@root_2)
127
+ assert @root_2.descendants.include?(@child_2_1)
128
+ end
129
+
130
+ should "check against cyclic graph" do
131
+ @child_2_1.children << @root_1
132
+ assert !@root_1.save
133
+ end
134
+ end
135
+
136
+ should "destroy descendants when destroyed" do
137
+ @child_2.destroy
138
+ assert_nil Category.where(:id => @child_2_1._id).first
139
+ end
140
+ end
141
+
142
+ context "root node" do
143
+ should "not have a parent" do
144
+ assert_nil @root_1.parent
145
+ end
146
+ end
147
+
148
+ context "child_node" do
149
+ should "have a parent" do
150
+ assert_equal @child_2, @child_2_1.parent
151
+ end
152
+ end
153
+ end
154
+ end
155
+
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid_acts_as_tree
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Jakob Vidmar, Aliaksandr Rahalevich
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-04 00:00:00 +03:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: mongoid
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - <=
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 0
30
+ - 0
31
+ version: 2.0.0
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: shoulda
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 2
43
+ - 10
44
+ - 2
45
+ version: 2.10.2
46
+ type: :development
47
+ version_requirements: *id002
48
+ description: Port of the old, venerable ActsAsTree with a bit of a twist
49
+ email: saksmlz@gmail.com
50
+ executables: []
51
+
52
+ extensions: []
53
+
54
+ extra_rdoc_files:
55
+ - LICENSE
56
+ - README.rdoc
57
+ files:
58
+ - .document
59
+ - .gitignore
60
+ - LICENSE
61
+ - README.rdoc
62
+ - Rakefile
63
+ - VERSION
64
+ - lib/mongoid_acts_as_tree.rb
65
+ - mongoid_acts_as_tree.gemspec
66
+ - test/helper.rb
67
+ - test/models/category.rb
68
+ - test/models/ordered_category.rb
69
+ - test/test_order.rb
70
+ - test/test_tree.rb
71
+ has_rdoc: true
72
+ homepage: http://github.com/saks/mongoid_acts_as_tree
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options:
77
+ - --charset=UTF-8
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ segments:
92
+ - 0
93
+ version: "0"
94
+ requirements: []
95
+
96
+ rubyforge_project:
97
+ rubygems_version: 1.3.6
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: ActsAsTree plugin for Mongoid
101
+ test_files:
102
+ - test/test_tree.rb
103
+ - test/test_order.rb
104
+ - test/models/category.rb
105
+ - test/models/ordered_category.rb
106
+ - test/helper.rb