taxonomy 0.0.1
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/MIT-LICENSE +20 -0
- data/README.rdoc +28 -0
- data/Rakefile +31 -0
- data/lib/generators/taxonomy/migration/migration_generator.rb +39 -0
- data/lib/generators/taxonomy/migration/templates/active_record/migration.rb +36 -0
- data/lib/tasks/taxonomy_tasks.rake +4 -0
- data/lib/taxonomy.rb +25 -0
- data/lib/taxonomy/group_helper.rb +12 -0
- data/lib/taxonomy/has_tagger.rb +52 -0
- data/lib/taxonomy/has_taxonomy.rb +502 -0
- data/lib/taxonomy/tag.rb +485 -0
- data/lib/taxonomy/tag_list.rb +97 -0
- data/lib/taxonomy/tagging.rb +12 -0
- data/lib/taxonomy/tags_helper.rb +13 -0
- data/lib/taxonomy/version.rb +3 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/altered_inheriting_taggable_model.rb +3 -0
- data/spec/dummy/app/models/inheriting_taggable_model.rb +2 -0
- data/spec/dummy/app/models/other_taggable_model.rb +4 -0
- data/spec/dummy/app/models/post.rb +2 -0
- data/spec/dummy/app/models/taggable_model.rb +6 -0
- data/spec/dummy/app/models/taggable_user.rb +3 -0
- data/spec/dummy/app/models/treed_model.rb +3 -0
- data/spec/dummy/app/models/untaggable_model.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +19 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +30 -0
- data/spec/dummy/config/environments/production.rb +60 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/db/migrate/20111221004133_create_posts.rb +8 -0
- data/spec/dummy/db/migrate/20111221023928_taxonomy_migration.rb +35 -0
- data/spec/dummy/db/migrate/20111221024100_create_bulk.rb +18 -0
- data/spec/dummy/db/schema.rb +65 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +100915 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/factories/posts.rb +6 -0
- data/spec/generators/taxonomy/migration/migration_generator_spec.rb +22 -0
- data/spec/models/post_spec.rb +5 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/taxonomy/group_helper_spec.rb +21 -0
- data/spec/taxonomy/has_tagger_spec.rb +113 -0
- data/spec/taxonomy/has_taxonomy_spec.rb +226 -0
- data/spec/taxonomy/tag_list_spec.rb +70 -0
- data/spec/taxonomy/tag_spec.rb +462 -0
- data/spec/taxonomy/taggable_spec.rb +262 -0
- data/spec/taxonomy/tagger_spec.rb +40 -0
- data/spec/taxonomy/tagging_spec.rb +25 -0
- data/spec/taxonomy/tags_helper_spec.rb +29 -0
- metadata +225 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe TagList do
|
4
|
+
before(:each) do
|
5
|
+
@tag_list = TagList.new("awesome","radical")
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should be an array" do
|
9
|
+
@tag_list.is_a?(Array).should be_true
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should be able to be add a new tag word" do
|
13
|
+
@tag_list.add("cool")
|
14
|
+
@tag_list.include?("cool").should be_true
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be able to add delimited lists of words" do
|
18
|
+
@tag_list.add("cool, wicked", :parse => true)
|
19
|
+
@tag_list.include?("cool").should be_true
|
20
|
+
@tag_list.include?("wicked").should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be able to add delimited list of words with quoted delimiters" do
|
24
|
+
@tag_list.add("'cool, wicked', \"really cool, really wicked\"", :parse => true)
|
25
|
+
@tag_list.include?("cool, wicked").should be_true
|
26
|
+
@tag_list.include?("really cool, really wicked").should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should be able to handle other uses of quotation marks correctly" do
|
30
|
+
@tag_list.add("john's cool car, mary's wicked toy", :parse => true)
|
31
|
+
@tag_list.include?("john's cool car").should be_true
|
32
|
+
@tag_list.include?("mary's wicked toy").should be_true
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should be able to add an array of words" do
|
36
|
+
@tag_list.add(["cool", "wicked"], :parse => true)
|
37
|
+
@tag_list.include?("cool").should be_true
|
38
|
+
@tag_list.include?("wicked").should be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should be able to remove words" do
|
42
|
+
@tag_list.remove("awesome")
|
43
|
+
@tag_list.include?("awesome").should be_false
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should be able to remove delimited lists of words" do
|
47
|
+
@tag_list.remove("awesome, radical", :parse => true)
|
48
|
+
@tag_list.should be_empty
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should be able to remove an array of words" do
|
52
|
+
@tag_list.remove(["awesome", "radical"], :parse => true)
|
53
|
+
@tag_list.should be_empty
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should give a delimited list of words when converted to string" do
|
57
|
+
@tag_list.to_s.should == "awesome, radical"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should quote escape tags with commas in them" do
|
61
|
+
@tag_list.add("cool","rad,bodacious")
|
62
|
+
@tag_list.to_s.should == "awesome, radical, cool, \"rad,bodacious\""
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should be able to call to_s on a frozen tag list" do
|
66
|
+
@tag_list.freeze
|
67
|
+
lambda { @tag_list.add("cool","rad,bodacious") }.should raise_error
|
68
|
+
lambda { @tag_list.to_s }.should_not raise_error
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,462 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Tag do
|
4
|
+
before(:each) do
|
5
|
+
# clean_database!
|
6
|
+
@tag = Tag.new
|
7
|
+
@user = TaggableModel.create(:name => "Pablo")
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "named like any" do
|
11
|
+
before(:each) do
|
12
|
+
Tag.create(:context => "skills", :name => "awesome")
|
13
|
+
Tag.create(:context => "skills", :name => "epic")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should find both tags" do
|
17
|
+
Tag.named_like_any("skills", ["awesome", "epic"]).should have(2).items
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "find or create by name" do
|
22
|
+
before(:each) do
|
23
|
+
@tag.name = "awesome"
|
24
|
+
@tag.save
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should find by name" do
|
28
|
+
Tag.find_or_create_with_like_by_name("skills", "awesome").should == @tag
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should find by name case insensitive" do
|
32
|
+
Tag.find_or_create_with_like_by_name("skills", "AWESOME").should == @tag
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should create by name" do
|
36
|
+
lambda {
|
37
|
+
Tag.find_or_create_with_like_by_name("skills", "epic")
|
38
|
+
}.should change(Tag, :count).by(1)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "find or create all by any name" do
|
43
|
+
before(:each) do
|
44
|
+
@tag.name = "awesome"
|
45
|
+
@tag.context = "skills"
|
46
|
+
@tag.save
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should find by name" do
|
50
|
+
Tag.find_or_create_all_with_like_by_name("skills", "awesome").should == [@tag]
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should find by name case insensitive" do
|
54
|
+
Tag.find_or_create_all_with_like_by_name("skills", "AWESOME").should == [@tag]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should create by name" do
|
58
|
+
lambda {
|
59
|
+
Tag.find_or_create_all_with_like_by_name("skills", "epic")
|
60
|
+
}.should change(Tag, :count).by(1)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should find or create by name" do
|
64
|
+
lambda {
|
65
|
+
Tag.find_or_create_all_with_like_by_name("skills", "awesome", "epic").map(&:name).should == ["awesome", "epic"]
|
66
|
+
}.should change(Tag, :count).by(1)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should return an empty array if no tags are specified" do
|
70
|
+
Tag.find_or_create_all_with_like_by_name("skills", []).should == []
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should require a name" do
|
75
|
+
@tag.valid?
|
76
|
+
@tag.errors[:name].should == ["can't be blank"]
|
77
|
+
@tag.name = "something"
|
78
|
+
@tag.valid?
|
79
|
+
@tag.errors[:name].should be_blank
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should equal a tag with the same name" do
|
83
|
+
@tag.name = "awesome"
|
84
|
+
new_tag = Tag.new(:name => "awesome")
|
85
|
+
new_tag.should == @tag
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should return its name when to_s is called" do
|
89
|
+
@tag.name = "cool"
|
90
|
+
@tag.to_s.should == "cool"
|
91
|
+
end
|
92
|
+
|
93
|
+
it "have scope named(context, something)" do
|
94
|
+
@tag.name = "cool"
|
95
|
+
@tag.context = "foo"
|
96
|
+
@tag.save!
|
97
|
+
Tag.named('foo', 'cool').should include(@tag)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "have scope named_like(something)" do
|
101
|
+
@tag.name = "cool"
|
102
|
+
@tag.context = "foo"
|
103
|
+
@tag.save!
|
104
|
+
@another_tag = Tag.create!(:context => "foo", :name => "coolip")
|
105
|
+
Tag.named_like('foo', 'cool').should include(@tag, @another_tag)
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "treed tags" do
|
109
|
+
before(:each) do
|
110
|
+
[TreedModel, Tag, Tagging].each(&:delete_all)
|
111
|
+
@taggable = TreedModel.new(:name => "Tyler Durden")
|
112
|
+
@taggable.save
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should respond to treed_taggings_for" do
|
116
|
+
Tag.should respond_to(:treed_taggings_for)
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should have scope named treed_taggings_for(categories)" do
|
120
|
+
@tag.name = "foo"
|
121
|
+
@tag.save
|
122
|
+
@taggable.category_list = "foo, bar"
|
123
|
+
@taggable.save
|
124
|
+
Tag.treed_taggings_for(:categories).all.should include(@tag)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should on creation, set automatically lft and rgt to the end of the tree" do
|
128
|
+
t = Tag.create(:name => "Movies")
|
129
|
+
t.save
|
130
|
+
@taggable.category_list = "FightClub"
|
131
|
+
@taggable.save
|
132
|
+
t = Tag.find_by_name("FightClub")
|
133
|
+
t.lft.should == Tag.maximum(:lft)
|
134
|
+
t.rgt.should == Tag.maximum(:rgt)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should move to child of" do
|
138
|
+
t = Tag.create(:name => "Movies")
|
139
|
+
t.save
|
140
|
+
@taggable.category_list = "FightClub"
|
141
|
+
@taggable.save
|
142
|
+
fc = Tag.find_by_name("FightClub")
|
143
|
+
fc.move_to_child_of(t.id)
|
144
|
+
fc.parent.should == t
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should find self and descendants" do
|
148
|
+
t = Tag.create(:name => "Trees")
|
149
|
+
t.save
|
150
|
+
f = Tag.create(:name => "Fern")
|
151
|
+
f.save
|
152
|
+
f.move_to_child_of(t.id)
|
153
|
+
t.self_and_descendants.all.should == [t,f]
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should find descendants" do
|
157
|
+
t = Tag.create(:name => "Trees")
|
158
|
+
t.save
|
159
|
+
f = Tag.create(:name => "Fern")
|
160
|
+
f.save
|
161
|
+
f.move_to_child_of(t.id)
|
162
|
+
t.self_and_descendants.all.should == [t,f]
|
163
|
+
t.descendants.all.should == [f]
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should destroy descendants" do
|
167
|
+
t = Tag.create(:name => "Trees")
|
168
|
+
t.save
|
169
|
+
@taggable.category_list = "Fern"
|
170
|
+
@taggable.save
|
171
|
+
f = Tag.find_by_name("Fern")
|
172
|
+
f.move_to_child_of(t.id)
|
173
|
+
t.destroy
|
174
|
+
Tag.find_by_name("Fern").should be_nil
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should find roots and leaves without overlap" do
|
178
|
+
t = Tag.create(:name => "Books")
|
179
|
+
t.save
|
180
|
+
@taggable.category_list = "One, Two"
|
181
|
+
@taggable.save
|
182
|
+
@taggable.categories.each do |cat|
|
183
|
+
cat.move_to_child_of(t.id)
|
184
|
+
cat.save
|
185
|
+
end
|
186
|
+
Tag.leaves.should_not include(t)
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should find leaves" do
|
190
|
+
t = Tag.create(:name => "Books")
|
191
|
+
t.save
|
192
|
+
@taggable.category_list = "BendersGame"
|
193
|
+
@taggable.save
|
194
|
+
cat = Tag.find_by_name("BendersGame")
|
195
|
+
cat.move_to_child_of(t.id)
|
196
|
+
cat.should be_leaf
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should return child correctly" do
|
200
|
+
t = Tag.create(:name => "Games")
|
201
|
+
t.save
|
202
|
+
@taggable.category_list = "Shooter"
|
203
|
+
@taggable.save
|
204
|
+
cat = Tag.find_by_name("Shooter")
|
205
|
+
cat.move_to_child_of(t.id)
|
206
|
+
cat.should be_child
|
207
|
+
t.should_not be_child
|
208
|
+
end
|
209
|
+
|
210
|
+
it "should default to root" do
|
211
|
+
t = Tag.create(:name => "Gum")
|
212
|
+
t.save
|
213
|
+
t.should be_root
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should find self and ancestors when two deep" do
|
217
|
+
r = Tag.create(:name => "Root")
|
218
|
+
r.save
|
219
|
+
s = Tag.create(:name => "otherRoot")
|
220
|
+
s.save
|
221
|
+
c = Tag.create(:name => "child")
|
222
|
+
c.save
|
223
|
+
c.move_to_child_of(r.id)
|
224
|
+
c.self_and_ancestors.all.should == [r,c]
|
225
|
+
end
|
226
|
+
|
227
|
+
it "should find self and siblings with two siblings" do
|
228
|
+
root = Tag.create(:name => "root")
|
229
|
+
root.save
|
230
|
+
l = Tag.create(:name => "left")
|
231
|
+
l.save
|
232
|
+
r = Tag.create(:name => "right")
|
233
|
+
r.save
|
234
|
+
l.move_to_child_of(root.id)
|
235
|
+
r.move_to_child_of(root.id)
|
236
|
+
r.self_and_siblings.all.should == [l,r]
|
237
|
+
end
|
238
|
+
|
239
|
+
it "should find ancestors with self" do
|
240
|
+
root = Tag.create(:name => "root")
|
241
|
+
root.save
|
242
|
+
child = Tag.create(:name => "child")
|
243
|
+
child.save
|
244
|
+
child.move_to_child_of(root.id)
|
245
|
+
child.self_and_ancestors.all.should == [root, child]
|
246
|
+
end
|
247
|
+
|
248
|
+
it "should find ancestors without self" do
|
249
|
+
root = Tag.create(:name => "root")
|
250
|
+
root.save
|
251
|
+
child = Tag.create(:name => "child")
|
252
|
+
child.save
|
253
|
+
child.move_to_child_of(root.id)
|
254
|
+
child.ancestors.all.should == [root]
|
255
|
+
end
|
256
|
+
|
257
|
+
it "should find siblings without self" do
|
258
|
+
root = Tag.create(:name => "parent")
|
259
|
+
root.save
|
260
|
+
l = Tag.create(:name => "child1")
|
261
|
+
l.save
|
262
|
+
r = Tag.create(:name => "child2")
|
263
|
+
r.save
|
264
|
+
l.move_to_child_of(root.id)
|
265
|
+
r.move_to_child_of(root.id)
|
266
|
+
r.siblings.all.should == [l]
|
267
|
+
l.siblings.all.should == [r]
|
268
|
+
end
|
269
|
+
|
270
|
+
it "should find leaf nodes" do
|
271
|
+
root = Tag.create(:name => "root")
|
272
|
+
root.save
|
273
|
+
l = Tag.create(:name => "left")
|
274
|
+
l.save
|
275
|
+
r = Tag.create(:name => "right")
|
276
|
+
r.save
|
277
|
+
l.move_to_child_of(root.id)
|
278
|
+
r.move_to_child_of(root.id)
|
279
|
+
root.leaves.all.should == [l,r]
|
280
|
+
end
|
281
|
+
|
282
|
+
it "should count level 0" do
|
283
|
+
a = Tag.create(:name => "one")
|
284
|
+
a.save
|
285
|
+
a.level.should == 0
|
286
|
+
end
|
287
|
+
|
288
|
+
it "should count level 1 and 2" do
|
289
|
+
a = Tag.create(:name => "one")
|
290
|
+
a.save
|
291
|
+
b = Tag.create(:name => "b")
|
292
|
+
b.move_to_child_of(a.id)
|
293
|
+
c = Tag.create(:name => "c")
|
294
|
+
c.move_to_child_of(b.id)
|
295
|
+
|
296
|
+
b.level.should == 1
|
297
|
+
c.level.should == 2
|
298
|
+
end
|
299
|
+
|
300
|
+
describe "sibblings" do
|
301
|
+
before(:each) do
|
302
|
+
root = Tag.create(:name => "root")
|
303
|
+
root.save
|
304
|
+
@b = Tag.create(:name => "b")
|
305
|
+
@b.move_to_child_of(root.id)
|
306
|
+
@c = Tag.create(:name => "c")
|
307
|
+
@c.move_to_child_of(root.id)
|
308
|
+
end
|
309
|
+
|
310
|
+
it "left_siblings should find left siblings" do
|
311
|
+
@c.left_sibling.should == @b
|
312
|
+
end
|
313
|
+
|
314
|
+
it "right_siblings should find right siblings" do
|
315
|
+
@b.right_sibling.should == @c
|
316
|
+
end
|
317
|
+
|
318
|
+
it "left_siblings should return nil when no left sibling" do
|
319
|
+
@b.left_sibling.should be_nil
|
320
|
+
end
|
321
|
+
|
322
|
+
it "right_siblings should return nil when no right sibling" do
|
323
|
+
@c.right_sibling.should be_nil
|
324
|
+
end
|
325
|
+
|
326
|
+
it "should move right of given tag" do
|
327
|
+
@b.move_to_right_of(@c)
|
328
|
+
@b.left_sibling.should == @c
|
329
|
+
end
|
330
|
+
|
331
|
+
it "should move left of given tag" do
|
332
|
+
@c.move_to_left_of(@b)
|
333
|
+
@c.right_sibling.should == @b
|
334
|
+
end
|
335
|
+
|
336
|
+
it "should move right" do
|
337
|
+
@b.move_right
|
338
|
+
@b.left_sibling.should == @c
|
339
|
+
end
|
340
|
+
|
341
|
+
it "should move left" do
|
342
|
+
@c.move_left
|
343
|
+
@c.right_sibling.should == @b
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
describe "with invalid tree" do
|
348
|
+
before(:each) do
|
349
|
+
@root = Tag.create(:name => "root")
|
350
|
+
@root.save
|
351
|
+
@b = Tag.create(:name => "b")
|
352
|
+
@b.move_to_child_of(@root.id)
|
353
|
+
@c = Tag.create(:name => "c")
|
354
|
+
@c.move_to_child_of(@root.id)
|
355
|
+
@orphan = Tag.create(:name => "orphan")
|
356
|
+
@orphan.save
|
357
|
+
end
|
358
|
+
it "should not be valid when lft arbitrarily set to zero" do
|
359
|
+
Tag.update_all "lft = 0", "id = #{@c.id}" # have to work to break things
|
360
|
+
Tag.should_not be_valid
|
361
|
+
end
|
362
|
+
it "rebuild! should make valid when lft arbitrarily set to zero" do
|
363
|
+
Tag.update_all "lft = 0", "id = #{@c.id}" # have to work to break things
|
364
|
+
Tag.rebuild!
|
365
|
+
Tag.should be_valid
|
366
|
+
end
|
367
|
+
it "should not be valid when parents wrongly set to nil" do
|
368
|
+
Tag.update_all "parent_id = null", "id = #{@c.id}"
|
369
|
+
Tag.should_not be_valid
|
370
|
+
end
|
371
|
+
it "rebuild! should make valid when parents wrongly set to nil" do
|
372
|
+
Tag.update_all "parent_id = null", "id = #{@c.id}"
|
373
|
+
Tag.rebuild!
|
374
|
+
Tag.should be_valid
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
describe "" do
|
379
|
+
before(:each) do
|
380
|
+
@root = Tag.create(:name => "root")
|
381
|
+
@root.save
|
382
|
+
@b = Tag.create(:name => "b")
|
383
|
+
@b.move_to_child_of(@root.id)
|
384
|
+
@c = Tag.create(:name => "c")
|
385
|
+
@c.move_to_child_of(@root.id)
|
386
|
+
@orphan = Tag.create(:name => "orphan")
|
387
|
+
@orphan.save
|
388
|
+
end
|
389
|
+
describe "simple tree" do
|
390
|
+
it "should be letf and right valid" do
|
391
|
+
Tag.should be_left_and_rights_valid
|
392
|
+
end
|
393
|
+
it "should not have duplicates in the left and right columns" do
|
394
|
+
Tag.should be_no_duplicates_for_columns
|
395
|
+
end
|
396
|
+
it "should have all valid roots" do
|
397
|
+
Tag.should be_all_roots_valid
|
398
|
+
end
|
399
|
+
it "should be valid" do
|
400
|
+
Tag.should be_valid
|
401
|
+
end
|
402
|
+
end
|
403
|
+
describe "descendant" do
|
404
|
+
it "is_descendant_of should find descendant" do
|
405
|
+
@b.is_descendant_of?(@root).should == true
|
406
|
+
end
|
407
|
+
|
408
|
+
it "is_descendant_of should not find descendant when its self" do
|
409
|
+
@root.is_descendant_of?(@root).should == false
|
410
|
+
end
|
411
|
+
|
412
|
+
it "is_descendant_of should not find descendant when its orphan" do
|
413
|
+
@orphan.is_descendant_of?(@root).should == false
|
414
|
+
end
|
415
|
+
|
416
|
+
it "is_or_is_descendant_of should find descendant" do
|
417
|
+
@b.is_or_is_descendant_of?(@root).should == true
|
418
|
+
end
|
419
|
+
|
420
|
+
it "is_or_is_descendant_of sholud find self" do
|
421
|
+
@root.is_or_is_descendant_of?(@root).should == true
|
422
|
+
end
|
423
|
+
|
424
|
+
it "is_or_is_descendant_of should not find descendant when its orphan" do
|
425
|
+
@orphan.is_or_is_descendant_of?(@root).should == false
|
426
|
+
end
|
427
|
+
end
|
428
|
+
describe "ancestor" do
|
429
|
+
it "is_ancestor_of should find ancestor" do
|
430
|
+
@root.is_ancestor_of?(@b).should == true
|
431
|
+
end
|
432
|
+
|
433
|
+
it "is_ancestor_of should not find ancestor when its an orphan" do
|
434
|
+
@orphan.is_ancestor_of?(@root).should == false
|
435
|
+
end
|
436
|
+
|
437
|
+
it "is_or_is_ancestor_of should find ancestor" do
|
438
|
+
@root.is_or_is_ancestor_of?(@b).should == true
|
439
|
+
end
|
440
|
+
|
441
|
+
it "is_or_is_ancestor_of should not find ancestor when its an orphan" do
|
442
|
+
@orphan.is_or_is_ancestor_of?(@root).should == false
|
443
|
+
end
|
444
|
+
|
445
|
+
it "is_or_is_ancestor_of should find self" do
|
446
|
+
@root.is_or_is_ancestor_of?(@root).should == true
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
describe "without tree" do
|
453
|
+
before(:each) do
|
454
|
+
[TaggableModel, Tag, Tagging].each(&:delete_all)
|
455
|
+
@taggable = TaggableModel.new(:name => "Bob Jones")
|
456
|
+
end
|
457
|
+
|
458
|
+
# it "should not add lft, rgt or parent id for untreed contexts" do
|
459
|
+
# fail
|
460
|
+
# end
|
461
|
+
end
|
462
|
+
end
|