acts-as-taggable-on 2.0.6 → 2.2.2

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 (46) hide show
  1. data/.gitignore +8 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +9 -0
  4. data/CHANGELOG +10 -0
  5. data/Gemfile +2 -9
  6. data/Guardfile +5 -0
  7. data/README.rdoc +47 -63
  8. data/Rakefile +9 -55
  9. data/acts-as-taggable-on.gemspec +28 -0
  10. data/lib/acts-as-taggable-on/version.rb +4 -0
  11. data/lib/acts-as-taggable-on.rb +7 -3
  12. data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +4 -4
  13. data/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb +38 -43
  14. data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +81 -30
  15. data/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb +7 -3
  16. data/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb +23 -15
  17. data/lib/acts_as_taggable_on/tag.rb +21 -12
  18. data/lib/acts_as_taggable_on/{acts_as_taggable_on.rb → taggable.rb} +6 -5
  19. data/lib/acts_as_taggable_on/tagging.rb +12 -2
  20. data/lib/acts_as_taggable_on/tags_helper.rb +2 -2
  21. data/lib/acts_as_taggable_on/utils.rb +34 -0
  22. data/lib/generators/acts_as_taggable_on/migration/migration_generator.rb +9 -2
  23. data/lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb +3 -1
  24. data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +242 -54
  25. data/spec/acts_as_taggable_on/tag_list_spec.rb +4 -0
  26. data/spec/acts_as_taggable_on/tag_spec.rb +52 -13
  27. data/spec/acts_as_taggable_on/taggable_spec.rb +131 -35
  28. data/spec/acts_as_taggable_on/tagger_spec.rb +14 -0
  29. data/spec/acts_as_taggable_on/tagging_spec.rb +2 -5
  30. data/spec/acts_as_taggable_on/tags_helper_spec.rb +16 -0
  31. data/spec/acts_as_taggable_on/utils_spec.rb +21 -0
  32. data/spec/database.yml.sample +4 -2
  33. data/spec/generators/acts_as_taggable_on/migration/migration_generator_spec.rb +22 -0
  34. data/spec/models.rb +14 -1
  35. data/spec/schema.rb +13 -0
  36. data/spec/spec_helper.rb +27 -6
  37. data/uninstall.rb +1 -0
  38. metadata +136 -51
  39. data/VERSION +0 -1
  40. data/generators/acts_as_taggable_on_migration/acts_as_taggable_on_migration_generator.rb +0 -7
  41. data/generators/acts_as_taggable_on_migration/templates/migration.rb +0 -29
  42. data/lib/acts_as_taggable_on/compatibility/Gemfile +0 -8
  43. data/lib/acts_as_taggable_on/compatibility/active_record_backports.rb +0 -17
  44. data/lib/acts_as_taggable_on/compatibility/postgresql.rb +0 -44
  45. data/spec/database.yml +0 -17
  46. /data/lib/acts_as_taggable_on/{acts_as_tagger.rb → tagger.rb} +0 -0
@@ -12,7 +12,7 @@ describe "Acts As Taggable On" do
12
12
  describe "Taggable Method Generation" do
13
13
  before(:each) do
14
14
  clean_database!
15
- TaggableModel.write_inheritable_attribute(:tag_types, [])
15
+ TaggableModel.tag_types = []
16
16
  TaggableModel.acts_as_taggable_on(:tags, :languages, :skills, :needs, :offerings)
17
17
  @taggable = TaggableModel.new(:name => "Bob Jones")
18
18
  end
@@ -28,7 +28,7 @@ describe "Acts As Taggable On" do
28
28
  it "should create an instance attribute for tag types" do
29
29
  @taggable.should respond_to(:tag_types)
30
30
  end
31
-
31
+
32
32
  it "should have all tag types" do
33
33
  @taggable.tag_types.should == [:tags, :languages, :skills, :needs, :offerings]
34
34
  end
@@ -45,7 +45,7 @@ describe "Acts As Taggable On" do
45
45
  @taggable.should respond_to(:tag_list, :skill_list, :language_list)
46
46
  @taggable.should respond_to(:tag_list=, :skill_list=, :language_list=)
47
47
  end
48
-
48
+
49
49
  it "should generate a tag_list accessor, that includes owned tags, for each tag type" do
50
50
  @taggable.should respond_to(:all_tags_list, :all_skills_list, :all_languages_list)
51
51
  end
@@ -57,17 +57,17 @@ describe "Acts As Taggable On" do
57
57
  @inherited_same = InheritingTaggableModel.new(:name => "inherited same")
58
58
  @inherited_different = AlteredInheritingTaggableModel.new(:name => "inherited different")
59
59
  end
60
-
60
+
61
61
  it "should pass on tag contexts to STI-inherited models" do
62
62
  @inherited_same.should respond_to(:tag_list, :skill_list, :language_list)
63
63
  @inherited_different.should respond_to(:tag_list, :skill_list, :language_list)
64
64
  end
65
-
65
+
66
66
  it "should have tag contexts added in altered STI models" do
67
67
  @inherited_different.should respond_to(:part_list)
68
68
  end
69
69
  end
70
-
70
+
71
71
  describe "Reloading" do
72
72
  it "should save a model instantiated by Model.find" do
73
73
  taggable = TaggableModel.create!(:name => "Taggable")
@@ -81,51 +81,121 @@ describe "Acts As Taggable On" do
81
81
  taggable1 = TaggableModel.create!(:name => "Taggable 1")
82
82
  taggable2 = TaggableModel.create!(:name => "Taggable 2")
83
83
  taggable3 = TaggableModel.create!(:name => "Taggable 3")
84
-
84
+
85
85
  taggable1.tag_list = "one, two"
86
86
  taggable1.save
87
-
87
+
88
88
  taggable2.tag_list = "three, four"
89
89
  taggable2.save
90
-
90
+
91
91
  taggable3.tag_list = "one, four"
92
92
  taggable3.save
93
-
93
+
94
94
  taggable1.find_related_tags.should include(taggable3)
95
95
  taggable1.find_related_tags.should_not include(taggable2)
96
96
  end
97
-
97
+
98
+ it "should find related objects based on tag names on context - non standard id" do
99
+ taggable1 = NonStandardIdTaggableModel.create!(:name => "Taggable 1")
100
+ taggable2 = NonStandardIdTaggableModel.create!(:name => "Taggable 2")
101
+ taggable3 = NonStandardIdTaggableModel.create!(:name => "Taggable 3")
102
+
103
+ taggable1.tag_list = "one, two"
104
+ taggable1.save
105
+
106
+ taggable2.tag_list = "three, four"
107
+ taggable2.save
108
+
109
+ taggable3.tag_list = "one, four"
110
+ taggable3.save
111
+
112
+ taggable1.find_related_tags.should include(taggable3)
113
+ taggable1.find_related_tags.should_not include(taggable2)
114
+ end
115
+
98
116
  it "should find other related objects based on tag names on context" do
99
117
  taggable1 = TaggableModel.create!(:name => "Taggable 1")
100
118
  taggable2 = OtherTaggableModel.create!(:name => "Taggable 2")
101
119
  taggable3 = OtherTaggableModel.create!(:name => "Taggable 3")
102
-
120
+
103
121
  taggable1.tag_list = "one, two"
104
122
  taggable1.save
105
-
123
+
106
124
  taggable2.tag_list = "three, four"
107
125
  taggable2.save
108
-
126
+
109
127
  taggable3.tag_list = "one, four"
110
128
  taggable3.save
111
-
129
+
112
130
  taggable1.find_related_tags_for(OtherTaggableModel).should include(taggable3)
113
131
  taggable1.find_related_tags_for(OtherTaggableModel).should_not include(taggable2)
114
132
  end
115
-
133
+
116
134
  it "should not include the object itself in the list of related objects" do
117
135
  taggable1 = TaggableModel.create!(:name => "Taggable 1")
118
136
  taggable2 = TaggableModel.create!(:name => "Taggable 2")
119
-
137
+
120
138
  taggable1.tag_list = "one"
121
139
  taggable1.save
122
-
140
+
123
141
  taggable2.tag_list = "one, two"
124
142
  taggable2.save
125
-
143
+
126
144
  taggable1.find_related_tags.should include(taggable2)
127
145
  taggable1.find_related_tags.should_not include(taggable1)
128
146
  end
147
+
148
+ it "should not include the object itself in the list of related objects - non standard id" do
149
+ taggable1 = NonStandardIdTaggableModel.create!(:name => "Taggable 1")
150
+ taggable2 = NonStandardIdTaggableModel.create!(:name => "Taggable 2")
151
+
152
+ taggable1.tag_list = "one"
153
+ taggable1.save
154
+
155
+ taggable2.tag_list = "one, two"
156
+ taggable2.save
157
+
158
+ taggable1.find_related_tags.should include(taggable2)
159
+ taggable1.find_related_tags.should_not include(taggable1)
160
+ end
161
+
162
+ context "Inherited Models" do
163
+ before do
164
+ @taggable1 = InheritingTaggableModel.create!(:name => "InheritingTaggable 1")
165
+ @taggable2 = InheritingTaggableModel.create!(:name => "InheritingTaggable 2")
166
+ @taggable3 = InheritingTaggableModel.create!(:name => "InheritingTaggable 3")
167
+ @taggable4 = TaggableModel.create!(:name => "Taggable 4")
168
+
169
+ @taggable1.tag_list = "one, two"
170
+ @taggable1.save
171
+
172
+ @taggable2.tag_list = "three, four"
173
+ @taggable2.save
174
+
175
+ @taggable3.tag_list = "one, four"
176
+ @taggable3.save
177
+
178
+ @taggable4.tag_list = "one, two, three, four"
179
+ @taggable4.save
180
+ end
181
+
182
+ it "should find related objects based on tag names on context" do
183
+ @taggable1.find_related_tags.should include(@taggable3)
184
+ @taggable1.find_related_tags.should_not include(@taggable2)
185
+ @taggable1.find_related_tags.should_not include(@taggable4)
186
+
187
+ @taggable1.find_related_tags_for(TaggableModel).should include(@taggable3)
188
+ @taggable1.find_related_tags_for(TaggableModel).should_not include(@taggable2)
189
+ @taggable1.find_related_tags_for(TaggableModel).should include(@taggable4)
190
+ end
191
+
192
+ it "should not include the object itself in the list of related objects" do
193
+ @taggable1.find_related_tags.should_not include(@taggable1)
194
+ @taggable1.find_related_tags_for(InheritingTaggableModel).should_not include(@taggable1)
195
+ @taggable1.find_related_tags_for(TaggableModel).should_not include(@taggable1)
196
+ end
197
+ end
198
+
129
199
  end
130
200
 
131
201
  describe "Matching Contexts" do
@@ -133,50 +203,95 @@ describe "Acts As Taggable On" do
133
203
  taggable1 = TaggableModel.create!(:name => "Taggable 1")
134
204
  taggable2 = TaggableModel.create!(:name => "Taggable 2")
135
205
  taggable3 = TaggableModel.create!(:name => "Taggable 3")
136
-
206
+
137
207
  taggable1.offering_list = "one, two"
138
208
  taggable1.save!
139
-
209
+
140
210
  taggable2.need_list = "one, two"
141
211
  taggable2.save!
142
-
212
+
143
213
  taggable3.offering_list = "one, two"
144
214
  taggable3.save!
145
-
215
+
146
216
  taggable1.find_matching_contexts(:offerings, :needs).should include(taggable2)
147
217
  taggable1.find_matching_contexts(:offerings, :needs).should_not include(taggable3)
148
218
  end
149
-
219
+
150
220
  it "should find other related objects with tags of matching contexts" do
151
221
  taggable1 = TaggableModel.create!(:name => "Taggable 1")
152
222
  taggable2 = OtherTaggableModel.create!(:name => "Taggable 2")
153
223
  taggable3 = OtherTaggableModel.create!(:name => "Taggable 3")
154
-
224
+
155
225
  taggable1.offering_list = "one, two"
156
226
  taggable1.save
157
-
227
+
158
228
  taggable2.need_list = "one, two"
159
229
  taggable2.save
160
-
230
+
161
231
  taggable3.offering_list = "one, two"
162
232
  taggable3.save
163
-
233
+
164
234
  taggable1.find_matching_contexts_for(OtherTaggableModel, :offerings, :needs).should include(taggable2)
165
235
  taggable1.find_matching_contexts_for(OtherTaggableModel, :offerings, :needs).should_not include(taggable3)
166
236
  end
167
-
168
- it "should not include the object itself in the list of related objects" do
237
+
238
+ it "should not include the object itself in the list of related objects with tags of matching contexts" do
169
239
  taggable1 = TaggableModel.create!(:name => "Taggable 1")
170
240
  taggable2 = TaggableModel.create!(:name => "Taggable 2")
171
-
172
- taggable1.tag_list = "one"
241
+
242
+ taggable1.offering_list = "one, two"
243
+ taggable1.need_list = "one, two"
173
244
  taggable1.save
174
-
175
- taggable2.tag_list = "one, two"
245
+
246
+ taggable2.need_list = "one, two"
176
247
  taggable2.save
177
-
178
- taggable1.find_related_tags.should include(taggable2)
179
- taggable1.find_related_tags.should_not include(taggable1)
248
+
249
+ taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should include(taggable2)
250
+ taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(taggable1)
251
+ end
252
+
253
+ context "Inherited Models" do
254
+ before do
255
+ @taggable1 = InheritingTaggableModel.create!(:name => "InheritingTaggable 1")
256
+ @taggable2 = InheritingTaggableModel.create!(:name => "InheritingTaggable 2")
257
+ @taggable3 = InheritingTaggableModel.create!(:name => "InheritingTaggable 3")
258
+ @taggable4 = InheritingTaggableModel.create!(:name => "InheritingTaggable 4")
259
+ @taggable5 = TaggableModel.create!(:name => "Taggable 5")
260
+
261
+ @taggable1.offering_list = "one, two"
262
+ @taggable1.need_list = "one, two"
263
+ @taggable1.save!
264
+
265
+ @taggable2.need_list = "one, two"
266
+ @taggable2.save!
267
+
268
+ @taggable3.offering_list = "one, two"
269
+ @taggable3.save!
270
+
271
+ @taggable4.tag_list = "one, two, three, four"
272
+ @taggable4.save!
273
+
274
+ @taggable5.need_list = "one, two"
275
+ @taggable5.save!
276
+ end
277
+
278
+ it "should find objects with tags of matching contexts" do
279
+ @taggable1.find_matching_contexts(:offerings, :needs).should include(@taggable2)
280
+ @taggable1.find_matching_contexts(:offerings, :needs).should_not include(@taggable3)
281
+ @taggable1.find_matching_contexts(:offerings, :needs).should_not include(@taggable4)
282
+ @taggable1.find_matching_contexts(:offerings, :needs).should_not include(@taggable5)
283
+
284
+ @taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should include(@taggable2)
285
+ @taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(@taggable3)
286
+ @taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(@taggable4)
287
+ @taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should include(@taggable5)
288
+ end
289
+
290
+ it "should not include the object itself in the list of related objects with tags of matching contexts" do
291
+ @taggable1.find_matching_contexts(:offerings, :needs).should_not include(@taggable1)
292
+ @taggable1.find_matching_contexts_for(InheritingTaggableModel, :offerings, :needs).should_not include(@taggable1)
293
+ @taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(@taggable1)
294
+ end
180
295
  end
181
296
  end
182
297
 
@@ -208,55 +323,67 @@ describe "Acts As Taggable On" do
208
323
  }.should_not raise_error
209
324
  end
210
325
  end
211
-
326
+
212
327
  describe 'Caching' do
213
328
  before(:each) do
214
- @taggable = CachedModel.new(:name => "Bob Jones")
329
+ @taggable = CachedModel.new(:name => "Bob Jones")
330
+ @another_taggable = OtherCachedModel.new(:name => "John Smith")
215
331
  end
216
-
332
+
217
333
  it "should add saving of tag lists and cached tag lists to the instance" do
218
334
  @taggable.should respond_to(:save_cached_tag_list)
335
+ @another_taggable.should respond_to(:save_cached_tag_list)
336
+
219
337
  @taggable.should respond_to(:save_tags)
220
- end
338
+ end
339
+
340
+ it "should add cached tag lists to the instance if cached column is not present" do
341
+ TaggableModel.new(:name => "Art Kram").should_not respond_to(:save_cached_tag_list)
342
+ end
221
343
 
222
344
  it "should generate a cached column checker for each tag type" do
223
345
  CachedModel.should respond_to(:caching_tag_list?)
224
- end
225
-
346
+ OtherCachedModel.should respond_to(:caching_language_list?)
347
+ end
348
+
226
349
  it 'should not have cached tags' do
227
- @taggable.cached_tag_list.should be_blank
350
+ @taggable.cached_tag_list.should be_blank
351
+ @another_taggable.cached_language_list.should be_blank
228
352
  end
229
-
353
+
230
354
  it 'should cache tags' do
231
355
  @taggable.update_attributes(:tag_list => 'awesome, epic')
232
356
  @taggable.cached_tag_list.should == 'awesome, epic'
357
+
358
+ @another_taggable.update_attributes(:language_list => 'ruby, .net')
359
+ @another_taggable.cached_language_list.should == 'ruby, .net'
233
360
  end
234
-
361
+
235
362
  it 'should keep the cache' do
236
363
  @taggable.update_attributes(:tag_list => 'awesome, epic')
237
- @taggable = CachedModel.find(@taggable)
364
+ @taggable = CachedModel.find(@taggable)
238
365
  @taggable.save!
239
- @taggable.cached_tag_list.should == 'awesome, epic'
366
+ @taggable.cached_tag_list.should == 'awesome, epic'
240
367
  end
241
-
368
+
242
369
  it 'should update the cache' do
243
370
  @taggable.update_attributes(:tag_list => 'awesome, epic')
244
371
  @taggable.update_attributes(:tag_list => 'awesome')
245
- @taggable.cached_tag_list.should == 'awesome'
372
+ @taggable.cached_tag_list.should == 'awesome'
246
373
  end
247
-
374
+
248
375
  it 'should remove the cache' do
249
376
  @taggable.update_attributes(:tag_list => 'awesome, epic')
250
377
  @taggable.update_attributes(:tag_list => '')
251
- @taggable.cached_tag_list.should be_blank
378
+ @taggable.cached_tag_list.should be_blank
252
379
  end
253
-
380
+
254
381
  it 'should have a tag list' do
255
382
  @taggable.update_attributes(:tag_list => 'awesome, epic')
256
383
  @taggable = CachedModel.find(@taggable.id)
257
384
  @taggable.tag_list.sort.should == %w(awesome epic).sort
258
385
  end
259
-
386
+
260
387
  it 'should keep the tag list' do
261
388
  @taggable.update_attributes(:tag_list => 'awesome, epic')
262
389
  @taggable = CachedModel.find(@taggable.id)
@@ -265,4 +392,65 @@ describe "Acts As Taggable On" do
265
392
  end
266
393
  end
267
394
 
395
+ context 'when tagging context ends in an "s" when singular (ex. "status", "glass", etc.)' do
396
+ describe 'caching' do
397
+ before { @taggable = OtherCachedModel.new(:name => "John Smith") }
398
+ subject { @taggable }
399
+
400
+ it { should respond_to(:save_cached_tag_list) }
401
+ its(:cached_language_list) { should be_blank }
402
+ its(:cached_status_list) { should be_blank }
403
+ its(:cached_glass_list) { should be_blank }
404
+
405
+ context 'language taggings cache after update' do
406
+ before { @taggable.update_attributes(:language_list => 'ruby, .net') }
407
+ subject { @taggable }
408
+
409
+ its(:language_list) { should == ['ruby', '.net']}
410
+ its(:cached_language_list) { should == 'ruby, .net' } # passes
411
+ its(:instance_variables) { should include((RUBY_VERSION < '1.9' ? '@language_list' : :@language_list)) }
412
+ end
413
+
414
+ context 'status taggings cache after update' do
415
+ before { @taggable.update_attributes(:status_list => 'happy, married') }
416
+ subject { @taggable }
417
+
418
+ its(:status_list) { should == ['happy', 'married'] }
419
+ its(:cached_status_list) { should == 'happy, married' } # fails
420
+ its(:cached_status_list) { should_not == '' } # fails, is blank
421
+ its(:instance_variables) { should include((RUBY_VERSION < '1.9' ? '@status_list' : :@status_list)) }
422
+ its(:instance_variables) { should_not include((RUBY_VERSION < '1.9' ? '@statu_list' : :@statu_list)) } # fails, note: one "s"
423
+
424
+ end
425
+
426
+ context 'glass taggings cache after update' do
427
+ before do
428
+ @taggable.update_attributes(:glass_list => 'rectangle, aviator')
429
+ end
430
+
431
+ subject { @taggable }
432
+ its(:glass_list) { should == ['rectangle', 'aviator'] }
433
+ its(:cached_glass_list) { should == 'rectangle, aviator' } # fails
434
+ its(:cached_glass_list) { should_not == '' } # fails, is blank
435
+ if RUBY_VERSION < '1.9'
436
+ its(:instance_variables) { should include('@glass_list') }
437
+ its(:instance_variables) { should_not include('@glas_list') } # fails, note: one "s"
438
+ else
439
+ its(:instance_variables) { should include(:@glass_list) }
440
+ its(:instance_variables) { should_not include(:@glas_list) } # fails, note: one "s"
441
+ end
442
+
443
+ end
444
+ end
445
+ end
446
+
447
+ describe "taggings" do
448
+ before(:each) do
449
+ @taggable = TaggableModel.new(:name => "Art Kram")
450
+ end
451
+
452
+ it 'should return [] taggings' do
453
+ @taggable.taggings.should == []
454
+ end
455
+ end
268
456
  end
@@ -62,6 +62,10 @@ describe ActsAsTaggableOn::TagList do
62
62
  @tag_list.to_s.should == "awesome, radical, cool, \"rad,bodacious\""
63
63
  end
64
64
 
65
+ it "#from should return empty array if empty array is passed" do
66
+ ActsAsTaggableOn::TagList.from([]).should == []
67
+ end
68
+
65
69
  it "should be able to call to_s on a frozen tag list" do
66
70
  @tag_list.freeze
67
71
  lambda { @tag_list.add("cool","rad,bodacious") }.should raise_error
@@ -9,12 +9,13 @@ describe ActsAsTaggableOn::Tag do
9
9
 
10
10
  describe "named like any" do
11
11
  before(:each) do
12
+ ActsAsTaggableOn::Tag.create(:name => "Awesome")
12
13
  ActsAsTaggableOn::Tag.create(:name => "awesome")
13
14
  ActsAsTaggableOn::Tag.create(:name => "epic")
14
15
  end
15
16
 
16
17
  it "should find both tags" do
17
- ActsAsTaggableOn::Tag.named_like_any(["awesome", "epic"]).should have(2).items
18
+ ActsAsTaggableOn::Tag.named_like_any(["awesome", "epic"]).should have(3).items
18
19
  end
19
20
  end
20
21
 
@@ -72,21 +73,13 @@ describe ActsAsTaggableOn::Tag do
72
73
 
73
74
  it "should require a name" do
74
75
  @tag.valid?
75
-
76
- if ActiveRecord::VERSION::MAJOR >= 3
77
- @tag.errors[:name].should == ["can't be blank"]
78
- else
79
- @tag.errors[:name].should == "can't be blank"
80
- end
76
+
77
+ @tag.errors[:name].should == ["can't be blank"]
81
78
 
82
79
  @tag.name = "something"
83
80
  @tag.valid?
84
-
85
- if ActiveRecord::VERSION::MAJOR >= 3
86
- @tag.errors[:name].should == []
87
- else
88
- @tag.errors[:name].should be_nil
89
- end
81
+
82
+ @tag.errors[:name].should == []
90
83
  end
91
84
 
92
85
  it "should equal a tag with the same name" do
@@ -112,4 +105,50 @@ describe ActsAsTaggableOn::Tag do
112
105
  @another_tag = ActsAsTaggableOn::Tag.create!(:name => "coolip")
113
106
  ActsAsTaggableOn::Tag.named_like('cool').should include(@tag, @another_tag)
114
107
  end
108
+
109
+ describe "escape wildcard symbols in like requests" do
110
+ before(:each) do
111
+ @tag.name = "cool"
112
+ @tag.save
113
+ @another_tag = ActsAsTaggableOn::Tag.create!(:name => "coo%")
114
+ @another_tag2 = ActsAsTaggableOn::Tag.create!(:name => "coolish")
115
+ end
116
+
117
+ it "return escaped result when '%' char present in tag" do
118
+ ActsAsTaggableOn::Tag.named_like('coo%').should_not include(@tag)
119
+ ActsAsTaggableOn::Tag.named_like('coo%').should include(@another_tag)
120
+ end
121
+
122
+ end
123
+
124
+ describe ".remove_unused" do
125
+ before do
126
+ @taggable = TaggableModel.create(:name => "Bob Jones")
127
+ @tag = ActsAsTaggableOn::Tag.create(:name => "awesome")
128
+
129
+ @tagging = ActsAsTaggableOn::Tagging.create(:taggable => @taggable, :tag => @tag, :context => 'tags')
130
+ end
131
+
132
+ context "if set to true" do
133
+ before do
134
+ ActsAsTaggableOn::Tag.remove_unused = true
135
+ end
136
+
137
+ it "should remove unused tags after removing taggings" do
138
+ @tagging.destroy
139
+ ActsAsTaggableOn::Tag.find_by_name("awesome").should be_nil
140
+ end
141
+ end
142
+
143
+ context "if set to false" do
144
+ before do
145
+ ActsAsTaggableOn::Tag.remove_unused = false
146
+ end
147
+
148
+ it "should not remove unused tags after removing taggings" do
149
+ @tagging.destroy
150
+ ActsAsTaggableOn::Tag.find_by_name("awesome").should == @tag
151
+ end
152
+ end
153
+ end
115
154
  end