acts-as-taggable-on 2.0.0 → 3.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 (86) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.travis.yml +23 -0
  4. data/Appraisals +20 -0
  5. data/CHANGELOG.md +112 -0
  6. data/CONTRIBUTING.md +44 -0
  7. data/Gemfile +9 -5
  8. data/Guardfile +5 -0
  9. data/{MIT-LICENSE → LICENSE.md} +1 -1
  10. data/README.md +385 -0
  11. data/Rakefile +13 -53
  12. data/UPGRADING.md +13 -0
  13. data/acts-as-taggable-on.gemspec +38 -0
  14. data/{lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb → db/migrate/1_acts_as_taggable_on_migration.rb} +5 -3
  15. data/db/migrate/2_add_missing_unique_indices.rb +19 -0
  16. data/db/migrate/3_add_taggings_counter_cache_to_tags.rb +14 -0
  17. data/gemfiles/activerecord_3.2.gemfile +15 -0
  18. data/gemfiles/activerecord_4.0.gemfile +15 -0
  19. data/gemfiles/activerecord_4.1.gemfile +15 -0
  20. data/gemfiles/activerecord_edge.gemfile +16 -0
  21. data/lib/acts-as-taggable-on.rb +65 -22
  22. data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +53 -24
  23. data/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb +120 -42
  24. data/lib/acts_as_taggable_on/acts_as_taggable_on/compatibility.rb +35 -0
  25. data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +309 -124
  26. data/lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb +36 -0
  27. data/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb +96 -72
  28. data/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb +43 -36
  29. data/lib/acts_as_taggable_on/engine.rb +5 -0
  30. data/lib/acts_as_taggable_on/tag.rb +133 -63
  31. data/lib/acts_as_taggable_on/tag_list.rb +162 -81
  32. data/lib/acts_as_taggable_on/taggable.rb +101 -0
  33. data/lib/acts_as_taggable_on/{acts_as_tagger.rb → tagger.rb} +34 -13
  34. data/lib/acts_as_taggable_on/tagging.rb +28 -18
  35. data/lib/acts_as_taggable_on/tags_helper.rb +12 -14
  36. data/lib/acts_as_taggable_on/utils.rb +62 -0
  37. data/lib/acts_as_taggable_on/version.rb +4 -0
  38. data/lib/acts_as_taggable_on.rb +6 -0
  39. data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +189 -195
  40. data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +78 -81
  41. data/spec/acts_as_taggable_on/caching_spec.rb +76 -0
  42. data/spec/acts_as_taggable_on/related_spec.rb +89 -0
  43. data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +210 -0
  44. data/spec/acts_as_taggable_on/tag_list_spec.rb +149 -61
  45. data/spec/acts_as_taggable_on/tag_spec.rb +245 -65
  46. data/spec/acts_as_taggable_on/taggable_spec.rb +776 -187
  47. data/spec/acts_as_taggable_on/tagger_spec.rb +119 -70
  48. data/spec/acts_as_taggable_on/tagging_spec.rb +17 -21
  49. data/spec/acts_as_taggable_on/tags_helper_spec.rb +38 -22
  50. data/spec/acts_as_taggable_on/utils_spec.rb +15 -0
  51. data/spec/internal/app/models/altered_inheriting_taggable_model.rb +3 -0
  52. data/spec/internal/app/models/cached_model.rb +3 -0
  53. data/spec/internal/app/models/cached_model_with_array.rb +5 -0
  54. data/spec/internal/app/models/company.rb +15 -0
  55. data/spec/internal/app/models/inheriting_taggable_model.rb +2 -0
  56. data/spec/internal/app/models/market.rb +2 -0
  57. data/spec/internal/app/models/models.rb +90 -0
  58. data/spec/internal/app/models/non_standard_id_taggable_model.rb +8 -0
  59. data/spec/internal/app/models/ordered_taggable_model.rb +4 -0
  60. data/spec/internal/app/models/other_cached_model.rb +3 -0
  61. data/spec/internal/app/models/other_taggable_model.rb +4 -0
  62. data/spec/internal/app/models/student.rb +2 -0
  63. data/spec/internal/app/models/taggable_model.rb +13 -0
  64. data/spec/internal/app/models/untaggable_model.rb +3 -0
  65. data/spec/internal/app/models/user.rb +3 -0
  66. data/spec/internal/config/database.yml.sample +19 -0
  67. data/spec/internal/db/schema.rb +97 -0
  68. data/spec/schema.rb +57 -18
  69. data/spec/spec_helper.rb +12 -47
  70. data/spec/support/array.rb +9 -0
  71. data/spec/support/database.rb +42 -0
  72. data/spec/support/database_cleaner.rb +21 -0
  73. metadata +286 -63
  74. data/CHANGELOG +0 -25
  75. data/README.rdoc +0 -221
  76. data/VERSION +0 -1
  77. data/generators/acts_as_taggable_on_migration/acts_as_taggable_on_migration_generator.rb +0 -7
  78. data/generators/acts_as_taggable_on_migration/templates/migration.rb +0 -29
  79. data/lib/acts_as_taggable_on/acts_as_taggable_on.rb +0 -53
  80. data/lib/acts_as_taggable_on/compatibility/Gemfile +0 -6
  81. data/lib/acts_as_taggable_on/compatibility/active_record_backports.rb +0 -17
  82. data/lib/generators/acts_as_taggable_on/migration/migration_generator.rb +0 -31
  83. data/rails/init.rb +0 -1
  84. data/spec/bm.rb +0 -52
  85. data/spec/models.rb +0 -30
  86. /data/{spec/spec.opts → .rspec} +0 -0
@@ -1,265 +1,259 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ # coding: utf-8
2
+ require 'spec_helper'
2
3
 
3
- describe "Acts As Taggable On" do
4
- before(:each) do
5
- clean_database!
6
- end
4
+ describe 'Acts As Taggable On' do
7
5
 
8
6
  it "should provide a class method 'taggable?' that is false for untaggable models" do
9
- UntaggableModel.should_not be_taggable
7
+ expect(UntaggableModel).to_not be_taggable
8
+ end
9
+
10
+ describe 'Taggable Method Generation To Preserve Order' do
11
+ before(:each) do
12
+ TaggableModel.tag_types = []
13
+ TaggableModel.preserve_tag_order = false
14
+ TaggableModel.acts_as_ordered_taggable_on(:ordered_tags)
15
+ @taggable = TaggableModel.new(name: 'Bob Jones')
16
+ end
17
+
18
+ it "should respond 'true' to preserve_tag_order?" do
19
+ expect(@taggable.class.preserve_tag_order?).to be_truthy
20
+ end
10
21
  end
11
22
 
12
- describe "Taggable Method Generation" do
23
+ describe 'Taggable Method Generation' do
13
24
  before(:each) do
14
- [TaggableModel, Tag, Tagging, TaggableUser].each(&:delete_all)
15
- @taggable = TaggableModel.new(:name => "Bob Jones")
25
+ TaggableModel.tag_types = []
26
+ TaggableModel.acts_as_taggable_on(:tags, :languages, :skills, :needs, :offerings)
27
+ @taggable = TaggableModel.new(name: 'Bob Jones')
16
28
  end
17
29
 
18
30
  it "should respond 'true' to taggable?" do
19
- @taggable.class.should be_taggable
31
+ expect(@taggable.class).to be_taggable
20
32
  end
21
33
 
22
- it "should create a class attribute for tag types" do
23
- @taggable.class.should respond_to(:tag_types)
34
+ it 'should create a class attribute for tag types' do
35
+ expect(@taggable.class).to respond_to(:tag_types)
24
36
  end
25
37
 
26
- it "should create an instance attribute for tag types" do
27
- @taggable.should respond_to(:tag_types)
38
+ it 'should create an instance attribute for tag types' do
39
+ expect(@taggable).to respond_to(:tag_types)
28
40
  end
29
-
30
- it "should have all tag types" do
31
- @taggable.tag_types.should == [:tags, :languages, :skills, :needs, :offerings]
41
+
42
+ it 'should have all tag types' do
43
+ expect(@taggable.tag_types).to eq([:tags, :languages, :skills, :needs, :offerings])
32
44
  end
33
45
 
34
- it "should generate an association for each tag type" do
35
- @taggable.should respond_to(:tags, :skills, :languages)
46
+ it 'should create a class attribute for preserve tag order' do
47
+ expect(@taggable.class).to respond_to(:preserve_tag_order?)
36
48
  end
37
49
 
38
- it "should add tagged_with and tag_counts to singleton" do
39
- TaggableModel.should respond_to(:tagged_with, :tag_counts)
50
+ it 'should create an instance attribute for preserve tag order' do
51
+ expect(@taggable).to respond_to(:preserve_tag_order?)
40
52
  end
41
53
 
42
- it "should generate a tag_list accessor/setter for each tag type" do
43
- @taggable.should respond_to(:tag_list, :skill_list, :language_list)
44
- @taggable.should respond_to(:tag_list=, :skill_list=, :language_list=)
54
+ it "should respond 'false' to preserve_tag_order?" do
55
+ expect(@taggable.class.preserve_tag_order?).to be_falsy
45
56
  end
46
-
47
- it "should generate a tag_list accessor, that includes owned tags, for each tag type" do
48
- @taggable.should respond_to(:all_tags_list, :all_skills_list, :all_languages_list)
57
+
58
+ it 'should generate an association for each tag type' do
59
+ expect(@taggable).to respond_to(:tags, :skills, :languages)
49
60
  end
50
- end
51
61
 
52
- describe "Single Table Inheritance" do
53
- before do
54
- @taggable = TaggableModel.new(:name => "taggable")
55
- @inherited_same = InheritingTaggableModel.new(:name => "inherited same")
56
- @inherited_different = AlteredInheritingTaggableModel.new(:name => "inherited different")
62
+ it 'should add tagged_with and tag_counts to singleton' do
63
+ expect(TaggableModel).to respond_to(:tagged_with, :tag_counts)
57
64
  end
58
-
59
- it "should pass on tag contexts to STI-inherited models" do
60
- @inherited_same.should respond_to(:tag_list, :skill_list, :language_list)
61
- @inherited_different.should respond_to(:tag_list, :skill_list, :language_list)
65
+
66
+ it 'should generate a tag_list accessor/setter for each tag type' do
67
+ expect(@taggable).to respond_to(:tag_list, :skill_list, :language_list)
68
+ expect(@taggable).to respond_to(:tag_list=, :skill_list=, :language_list=)
62
69
  end
63
-
64
- it "should have tag contexts added in altered STI models" do
65
- @inherited_different.should respond_to(:part_list)
70
+
71
+ it 'should generate a tag_list accessor, that includes owned tags, for each tag type' do
72
+ expect(@taggable).to respond_to(:all_tags_list, :all_skills_list, :all_languages_list)
66
73
  end
67
74
  end
68
-
69
- describe "Reloading" do
70
- it "should save a model instantiated by Model.find" do
71
- taggable = TaggableModel.create!(:name => "Taggable")
75
+
76
+ describe 'Reloading' do
77
+ it 'should save a model instantiated by Model.find' do
78
+ taggable = TaggableModel.create!(name: 'Taggable')
72
79
  found_taggable = TaggableModel.find(taggable.id)
73
80
  found_taggable.save
74
81
  end
75
82
  end
76
83
 
77
- describe "Related Objects" do
78
- it "should find related objects based on tag names on context" do
79
- taggable1 = TaggableModel.create!(:name => "Taggable 1")
80
- taggable2 = TaggableModel.create!(:name => "Taggable 2")
81
- taggable3 = TaggableModel.create!(:name => "Taggable 3")
82
-
83
- taggable1.tag_list = "one, two"
84
- taggable1.save
85
-
86
- taggable2.tag_list = "three, four"
87
- taggable2.save
88
-
89
- taggable3.tag_list = "one, four"
90
- taggable3.save
91
-
92
- taggable1.find_related_tags.should include(taggable3)
93
- taggable1.find_related_tags.should_not include(taggable2)
94
- end
95
-
96
- it "should find other related objects based on tag names on context" do
97
- taggable1 = TaggableModel.create!(:name => "Taggable 1")
98
- taggable2 = OtherTaggableModel.create!(:name => "Taggable 2")
99
- taggable3 = OtherTaggableModel.create!(:name => "Taggable 3")
100
-
101
- taggable1.tag_list = "one, two"
102
- taggable1.save
103
-
104
- taggable2.tag_list = "three, four"
105
- taggable2.save
106
-
107
- taggable3.tag_list = "one, four"
108
- taggable3.save
109
-
110
- taggable1.find_related_tags_for(OtherTaggableModel).should include(taggable3)
111
- taggable1.find_related_tags_for(OtherTaggableModel).should_not include(taggable2)
112
- end
113
-
114
- it "should not include the object itself in the list of related objects" do
115
- taggable1 = TaggableModel.create!(:name => "Taggable 1")
116
- taggable2 = TaggableModel.create!(:name => "Taggable 2")
117
-
118
- taggable1.tag_list = "one"
119
- taggable1.save
120
-
121
- taggable2.tag_list = "one, two"
122
- taggable2.save
123
-
124
- taggable1.find_related_tags.should include(taggable2)
125
- taggable1.find_related_tags.should_not include(taggable1)
126
- end
127
- end
84
+ describe 'Matching Contexts' do
85
+ it 'should find objects with tags of matching contexts' do
86
+ taggable1 = TaggableModel.create!(name: 'Taggable 1')
87
+ taggable2 = TaggableModel.create!(name: 'Taggable 2')
88
+ taggable3 = TaggableModel.create!(name: 'Taggable 3')
128
89
 
129
- describe "Matching Contexts" do
130
- it "should find objects with tags of matching contexts" do
131
- taggable1 = TaggableModel.create!(:name => "Taggable 1")
132
- taggable2 = TaggableModel.create!(:name => "Taggable 2")
133
- taggable3 = TaggableModel.create!(:name => "Taggable 3")
134
-
135
- taggable1.offering_list = "one, two"
90
+ taggable1.offering_list = 'one, two'
136
91
  taggable1.save!
137
-
138
- taggable2.need_list = "one, two"
92
+
93
+ taggable2.need_list = 'one, two'
139
94
  taggable2.save!
140
-
141
- taggable3.offering_list = "one, two"
95
+
96
+ taggable3.offering_list = 'one, two'
142
97
  taggable3.save!
143
-
144
- taggable1.find_matching_contexts(:offerings, :needs).should include(taggable2)
145
- taggable1.find_matching_contexts(:offerings, :needs).should_not include(taggable3)
98
+
99
+ expect(taggable1.find_matching_contexts(:offerings, :needs)).to include(taggable2)
100
+ expect(taggable1.find_matching_contexts(:offerings, :needs)).to_not include(taggable3)
146
101
  end
147
-
148
- it "should find other related objects with tags of matching contexts" do
149
- taggable1 = TaggableModel.create!(:name => "Taggable 1")
150
- taggable2 = OtherTaggableModel.create!(:name => "Taggable 2")
151
- taggable3 = OtherTaggableModel.create!(:name => "Taggable 3")
152
-
153
- taggable1.offering_list = "one, two"
102
+
103
+ it 'should find other related objects with tags of matching contexts' do
104
+ taggable1 = TaggableModel.create!(name: 'Taggable 1')
105
+ taggable2 = OtherTaggableModel.create!(name: 'Taggable 2')
106
+ taggable3 = OtherTaggableModel.create!(name: 'Taggable 3')
107
+
108
+ taggable1.offering_list = 'one, two'
154
109
  taggable1.save
155
-
156
- taggable2.need_list = "one, two"
110
+
111
+ taggable2.need_list = 'one, two'
157
112
  taggable2.save
158
-
159
- taggable3.offering_list = "one, two"
113
+
114
+ taggable3.offering_list = 'one, two'
160
115
  taggable3.save
161
-
162
- taggable1.find_matching_contexts_for(OtherTaggableModel, :offerings, :needs).should include(taggable2)
163
- taggable1.find_matching_contexts_for(OtherTaggableModel, :offerings, :needs).should_not include(taggable3)
116
+
117
+ expect(taggable1.find_matching_contexts_for(OtherTaggableModel, :offerings, :needs)).to include(taggable2)
118
+ expect(taggable1.find_matching_contexts_for(OtherTaggableModel, :offerings, :needs)).to_not include(taggable3)
164
119
  end
165
-
166
- it "should not include the object itself in the list of related objects" do
167
- taggable1 = TaggableModel.create!(:name => "Taggable 1")
168
- taggable2 = TaggableModel.create!(:name => "Taggable 2")
169
-
170
- taggable1.tag_list = "one"
120
+
121
+ it 'should not include the object itself in the list of related objects with tags of matching contexts' do
122
+ taggable1 = TaggableModel.create!(name: 'Taggable 1')
123
+ taggable2 = TaggableModel.create!(name: 'Taggable 2')
124
+
125
+ taggable1.offering_list = 'one, two'
126
+ taggable1.need_list = 'one, two'
171
127
  taggable1.save
172
-
173
- taggable2.tag_list = "one, two"
128
+
129
+ taggable2.need_list = 'one, two'
174
130
  taggable2.save
175
-
176
- taggable1.find_related_tags.should include(taggable2)
177
- taggable1.find_related_tags.should_not include(taggable1)
131
+
132
+ expect(taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to include(taggable2)
133
+ expect(taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to_not include(taggable1)
178
134
  end
135
+
179
136
  end
180
137
 
181
138
  describe 'Tagging Contexts' do
182
139
  it 'should eliminate duplicate tagging contexts ' do
183
140
  TaggableModel.acts_as_taggable_on(:skills, :skills)
184
- TaggableModel.tag_types.freq[:skills].should_not == 3
141
+ expect(TaggableModel.tag_types.freq[:skills]).to_not eq(3)
185
142
  end
186
143
 
187
- it "should not contain embedded/nested arrays" do
144
+ it 'should not contain embedded/nested arrays' do
188
145
  TaggableModel.acts_as_taggable_on([:array], [:array])
189
- TaggableModel.tag_types.freq[[:array]].should == 0
146
+ expect(TaggableModel.tag_types.freq[[:array]]).to eq(0)
190
147
  end
191
148
 
192
- it "should _flatten_ the content of arrays" do
149
+ it 'should _flatten_ the content of arrays' do
193
150
  TaggableModel.acts_as_taggable_on([:array], [:array])
194
- TaggableModel.tag_types.freq[:array].should == 1
151
+ expect(TaggableModel.tag_types.freq[:array]).to eq(1)
195
152
  end
196
153
 
197
- it "should not raise an error when passed nil" do
198
- lambda {
199
- TaggableModel.acts_as_taggable_on()
200
- }.should_not raise_error
154
+ it 'should not raise an error when passed nil' do
155
+ expect(-> {
156
+ TaggableModel.acts_as_taggable_on
157
+ }).to_not raise_error
201
158
  end
202
159
 
203
- it "should not raise an error when passed [nil]" do
204
- lambda {
160
+ it 'should not raise an error when passed [nil]' do
161
+ expect(-> {
205
162
  TaggableModel.acts_as_taggable_on([nil])
206
- }.should_not raise_error
163
+ }).to_not raise_error
207
164
  end
208
165
  end
209
-
210
- describe 'Caching' do
211
- before(:each) do
212
- @taggable = CachedModel.new(:name => "Bob Jones")
213
- end
214
-
215
- it "should add saving of tag lists and cached tag lists to the instance" do
216
- @taggable.should respond_to(:save_cached_tag_list)
217
- @taggable.should respond_to(:save_tags)
218
- end
219
-
220
- it "should generate a cached column checker for each tag type" do
221
- CachedModel.should respond_to(:caching_tag_list?)
222
- end
223
-
224
- it 'should not have cached tags' do
225
- @taggable.cached_tag_list.should be_blank
226
- end
227
-
228
- it 'should cache tags' do
229
- @taggable.update_attributes(:tag_list => 'awesome, epic')
230
- @taggable.cached_tag_list.should == 'awesome, epic'
166
+
167
+ context 'when tagging context ends in an "s" when singular (ex. "status", "glass", etc.)' do
168
+ describe 'caching' do
169
+ before { @taggable = OtherCachedModel.new(name: 'John Smith') }
170
+ subject { @taggable }
171
+
172
+ it { should respond_to(:save_cached_tag_list) }
173
+ its(:cached_language_list) { should be_blank }
174
+ its(:cached_status_list) { should be_blank }
175
+ its(:cached_glass_list) { should be_blank }
176
+
177
+ context 'language taggings cache after update' do
178
+ before { @taggable.update_attributes(language_list: 'ruby, .net') }
179
+ subject { @taggable }
180
+
181
+ its(:language_list) { should == ['ruby', '.net']}
182
+ its(:cached_language_list) { should == 'ruby, .net' } # passes
183
+ its(:instance_variables) { should include((RUBY_VERSION < '1.9' ? '@language_list' : :@language_list)) }
184
+ end
185
+
186
+ context 'status taggings cache after update' do
187
+ before { @taggable.update_attributes(status_list: 'happy, married') }
188
+ subject { @taggable }
189
+
190
+ its(:status_list) { should == ['happy', 'married'] }
191
+ its(:cached_status_list) { should == 'happy, married' } # fails
192
+ its(:cached_status_list) { should_not == '' } # fails, is blank
193
+ its(:instance_variables) { should include((RUBY_VERSION < '1.9' ? '@status_list' : :@status_list)) }
194
+ its(:instance_variables) { should_not include((RUBY_VERSION < '1.9' ? '@statu_list' : :@statu_list)) } # fails, note: one "s"
195
+
196
+ end
197
+
198
+ context 'glass taggings cache after update' do
199
+ before do
200
+ @taggable.update_attributes(glass_list: 'rectangle, aviator')
201
+ end
202
+
203
+ subject { @taggable }
204
+ its(:glass_list) { should == ['rectangle', 'aviator'] }
205
+ its(:cached_glass_list) { should == 'rectangle, aviator' } # fails
206
+ its(:cached_glass_list) { should_not == '' } # fails, is blank
207
+ if RUBY_VERSION < '1.9'
208
+ its(:instance_variables) { should include('@glass_list') }
209
+ its(:instance_variables) { should_not include('@glas_list') } # fails, note: one "s"
210
+ else
211
+ its(:instance_variables) { should include(:@glass_list) }
212
+ its(:instance_variables) { should_not include(:@glas_list) } # fails, note: one "s"
213
+ end
214
+
215
+ end
231
216
  end
232
-
233
- it 'should keep the cache' do
234
- @taggable.update_attributes(:tag_list => 'awesome, epic')
235
- @taggable = CachedModel.find(@taggable)
236
- @taggable.save!
237
- @taggable.cached_tag_list.should == 'awesome, epic'
217
+ end
218
+
219
+ describe 'taggings' do
220
+ before(:each) do
221
+ @taggable = TaggableModel.new(name: 'Art Kram')
238
222
  end
239
-
240
- it 'should update the cache' do
241
- @taggable.update_attributes(:tag_list => 'awesome, epic')
242
- @taggable.update_attributes(:tag_list => 'awesome')
243
- @taggable.cached_tag_list.should == 'awesome'
223
+
224
+ it 'should return no taggings' do
225
+ expect(@taggable.taggings).to be_empty
244
226
  end
245
-
246
- it 'should remove the cache' do
247
- @taggable.update_attributes(:tag_list => 'awesome, epic')
248
- @taggable.update_attributes(:tag_list => '')
249
- @taggable.cached_tag_list.should be_blank
227
+ end
228
+
229
+ describe '@@remove_unused_tags' do
230
+ before do
231
+ @taggable = TaggableModel.create(name: 'Bob Jones')
232
+ @tag = ActsAsTaggableOn::Tag.create(name: 'awesome')
233
+
234
+ @tagging = ActsAsTaggableOn::Tagging.create(taggable: @taggable, tag: @tag, context: 'tags')
250
235
  end
251
-
252
- it 'should have a tag list' do
253
- @taggable.update_attributes(:tag_list => 'awesome, epic')
254
- @taggable = CachedModel.find(@taggable.id)
255
- @taggable.tag_list.sort.should == %w(awesome epic).sort
236
+
237
+ context 'if set to true' do
238
+ before do
239
+ ActsAsTaggableOn.remove_unused_tags = true
240
+ end
241
+
242
+ it 'should remove unused tags after removing taggings' do
243
+ @tagging.destroy
244
+ expect(ActsAsTaggableOn::Tag.find_by_name('awesome')).to be_nil
245
+ end
256
246
  end
257
-
258
- it 'should keep the tag list' do
259
- @taggable.update_attributes(:tag_list => 'awesome, epic')
260
- @taggable = CachedModel.find(@taggable.id)
261
- @taggable.save!
262
- @taggable.tag_list.sort.should == %w(awesome epic).sort
247
+
248
+ context 'if set to false' do
249
+ before do
250
+ ActsAsTaggableOn.remove_unused_tags = false
251
+ end
252
+
253
+ it 'should not remove unused tags after removing taggings' do
254
+ @tagging.destroy
255
+ expect(ActsAsTaggableOn::Tag.find_by_name('awesome')).to eq(@tag)
256
+ end
263
257
  end
264
258
  end
265
259
 
@@ -1,114 +1,111 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require 'spec_helper'
2
2
 
3
- describe "acts_as_tagger" do
4
- before(:each) do
5
- clean_database!
6
- end
7
-
8
- context "Tagger Method Generation" do
3
+ describe 'acts_as_tagger' do
4
+
5
+ describe 'Tagger Method Generation' do
9
6
  before(:each) do
10
- @tagger = TaggableUser.new()
7
+ @tagger = User.new
11
8
  end
12
9
 
13
- it "should add #is_tagger? query method to the class-side" do
14
- TaggableUser.should respond_to(:is_tagger?)
10
+ it 'should add #is_tagger? query method to the class-side' do
11
+ expect(User).to respond_to(:is_tagger?)
15
12
  end
16
-
17
- it "should return true from the class-side #is_tagger?" do
18
- TaggableUser.is_tagger?.should be_true
13
+
14
+ it 'should return true from the class-side #is_tagger?' do
15
+ expect(User.is_tagger?).to be_truthy
19
16
  end
20
-
21
- it "should return false from the base #is_tagger?" do
22
- ActiveRecord::Base.is_tagger?.should be_false
17
+
18
+ it 'should return false from the base #is_tagger?' do
19
+ expect(ActiveRecord::Base.is_tagger?).to be_falsy
23
20
  end
24
-
25
- it "should add #is_tagger? query method to the singleton" do
26
- @tagger.should respond_to(:is_tagger?)
21
+
22
+ it 'should add #is_tagger? query method to the singleton' do
23
+ expect(@tagger).to respond_to(:is_tagger?)
27
24
  end
28
-
29
- it "should add #tag method on the instance-side" do
30
- @tagger.should respond_to(:tag)
25
+
26
+ it 'should add #tag method on the instance-side' do
27
+ expect(@tagger).to respond_to(:tag)
31
28
  end
32
-
33
- it "should generate an association for #owned_taggings and #owned_tags" do
34
- @tagger.should respond_to(:owned_taggings, :owned_tags)
29
+
30
+ it 'should generate an association for #owned_taggings and #owned_tags' do
31
+ expect(@tagger).to respond_to(:owned_taggings, :owned_tags)
35
32
  end
36
33
  end
37
-
38
- describe "#tag" do
34
+
35
+ describe '#tag' do
39
36
  context 'when called with a non-existent tag context' do
40
37
  before(:each) do
41
- @tagger = TaggableUser.new()
42
- @taggable = TaggableModel.new(:name=>"Richard Prior")
38
+ @tagger = User.new
39
+ @taggable = TaggableModel.new(name: 'Richard Prior')
43
40
  end
44
-
45
- it "should by default not throw an exception " do
46
- @taggable.tag_list_on(:foo).should be_empty
47
- lambda {
48
- @tagger.tag(@taggable, :with=>'this, and, that', :on=>:foo)
49
- }.should_not raise_error
41
+
42
+ it 'should by default not throw an exception ' do
43
+ expect(@taggable.tag_list_on(:foo)).to be_empty
44
+ expect(-> {
45
+ @tagger.tag(@taggable, with: 'this, and, that', on: :foo)
46
+ }).to_not raise_error
50
47
  end
51
-
48
+
52
49
  it 'should by default create the tag context on-the-fly' do
53
- @taggable.tag_list_on(:here_ond_now).should be_empty
54
- @tagger.tag(@taggable, :with=>'that', :on => :here_ond_now)
55
- @taggable.tag_list_on(:here_ond_now).should_not include('that')
56
- @taggable.all_tags_list_on(:here_ond_now).should include('that')
50
+ expect(@taggable.tag_list_on(:here_ond_now)).to be_empty
51
+ @tagger.tag(@taggable, with: 'that', on: :here_ond_now)
52
+ expect(@taggable.tag_list_on(:here_ond_now)).to_not include('that')
53
+ expect(@taggable.all_tags_list_on(:here_ond_now)).to include('that')
57
54
  end
58
-
59
- it "should show all the tag list when both public and owned tags exist" do
55
+
56
+ it 'should show all the tag list when both public and owned tags exist' do
60
57
  @taggable.tag_list = 'ruby, python'
61
- @tagger.tag(@taggable, :with => 'java, lisp', :on => :tags)
62
- @taggable.all_tags_on(:tags).map(&:name).sort.should == %w(ruby python java lisp).sort
58
+ @tagger.tag(@taggable, with: 'java, lisp', on: :tags)
59
+ expect(@taggable.all_tags_on(:tags).map(&:name).sort).to eq(%w(ruby python java lisp).sort)
63
60
  end
64
-
65
- it "should not add owned tags to the common list" do
61
+
62
+ it 'should not add owned tags to the common list' do
66
63
  @taggable.tag_list = 'ruby, python'
67
- @tagger.tag(@taggable, :with => 'java, lisp', :on => :tags)
68
- @taggable.tag_list.should == %w(ruby python)
69
- @tagger.tag(@taggable, :with => '', :on => :tags)
70
- @taggable.tag_list.should == %w(ruby python)
64
+ @tagger.tag(@taggable, with: 'java, lisp', on: :tags)
65
+ expect(@taggable.tag_list).to eq(%w(ruby python))
66
+ @tagger.tag(@taggable, with: '', on: :tags)
67
+ expect(@taggable.tag_list).to eq(%w(ruby python))
71
68
  end
72
-
73
- it "should throw an exception when the default is over-ridden" do
74
- @taggable.tag_list_on(:foo_boo).should be_empty
75
- lambda {
76
- @tagger.tag(@taggable, :with=>'this, and, that', :on=>:foo_boo, :force=>false)
77
- }.should raise_error
69
+
70
+ it 'should throw an exception when the default is over-ridden' do
71
+ expect(@taggable.tag_list_on(:foo_boo)).to be_empty
72
+ expect(-> {
73
+ @tagger.tag(@taggable, with: 'this, and, that', on: :foo_boo, force: false)
74
+ }).to raise_error
78
75
  end
79
76
 
80
- it "should not create the tag context on-the-fly when the default is over-ridden" do
81
- @taggable.tag_list_on(:foo_boo).should be_empty
82
- @tagger.tag(@taggable, :with=>'this, and, that', :on=>:foo_boo, :force=>false) rescue
83
- @taggable.tag_list_on(:foo_boo).should be_empty
77
+ it 'should not create the tag context on-the-fly when the default is over-ridden' do
78
+ expect(@taggable.tag_list_on(:foo_boo)).to be_empty
79
+ @tagger.tag(@taggable, with: 'this, and, that', on: :foo_boo, force: false) rescue
80
+ expect(@taggable.tag_list_on(:foo_boo)).to be_empty
84
81
  end
85
82
  end
86
-
87
- context "when called by multiple tagger's" do
83
+
84
+ describe "when called by multiple tagger's" do
88
85
  before(:each) do
89
- @user_x = TaggableUser.create(:name => "User X")
90
- @user_y = TaggableUser.create(:name => "User Y")
91
- @taggable = TaggableModel.create(:name => 'acts_as_taggable_on', :tag_list => 'plugin')
92
-
93
- @user_x.tag(@taggable, :with => 'ruby, rails', :on => :tags)
94
- @user_y.tag(@taggable, :with => 'ruby, plugin', :on => :tags)
95
-
96
- @user_y.tag(@taggable, :with => '', :on => :tags)
97
- @user_y.tag(@taggable, :with => '', :on => :tags)
86
+ @user_x = User.create(name: 'User X')
87
+ @user_y = User.create(name: 'User Y')
88
+ @taggable = TaggableModel.create(name: 'acts_as_taggable_on', tag_list: 'plugin')
89
+
90
+ @user_x.tag(@taggable, with: 'ruby, rails', on: :tags)
91
+ @user_y.tag(@taggable, with: 'ruby, plugin', on: :tags)
92
+
93
+ @user_y.tag(@taggable, with: '', on: :tags)
94
+ @user_y.tag(@taggable, with: '', on: :tags)
98
95
  end
99
-
100
- it "should delete owned tags" do
101
- @user_y.owned_tags.should == []
96
+
97
+ it 'should delete owned tags' do
98
+ expect(@user_y.owned_tags).to be_empty
102
99
  end
103
-
104
- it "should not delete other taggers tags" do
105
- @user_x.owned_tags.should have(2).items
100
+
101
+ it 'should not delete other taggers tags' do
102
+ expect(@user_x.owned_tags.count).to eq(2)
106
103
  end
107
-
108
- it "should not delete original tags" do
109
- @taggable.all_tags_list_on(:tags).should include('plugin')
104
+
105
+ it 'should not delete original tags' do
106
+ expect(@taggable.all_tags_list_on(:tags)).to include('plugin')
110
107
  end
111
108
  end
112
109
  end
113
110
 
114
- end
111
+ end