acts-as-taggable-on 2.0.6 → 2.4.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.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/.travis.yml +9 -0
- data/CHANGELOG.md +35 -0
- data/Gemfile +2 -9
- data/Guardfile +5 -0
- data/{MIT-LICENSE → MIT-LICENSE.md} +1 -1
- data/README.md +297 -0
- data/Rakefile +9 -55
- data/UPGRADING +14 -0
- data/acts-as-taggable-on.gemspec +32 -0
- data/lib/acts-as-taggable-on/version.rb +4 -0
- data/lib/acts-as-taggable-on.rb +37 -4
- data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +6 -6
- data/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb +99 -45
- data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +162 -45
- data/lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb +37 -0
- data/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb +40 -15
- data/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb +28 -18
- data/lib/acts_as_taggable_on/tag.rb +41 -16
- data/lib/acts_as_taggable_on/tag_list.rb +19 -14
- data/lib/acts_as_taggable_on/taggable.rb +102 -0
- data/lib/acts_as_taggable_on/{acts_as_tagger.rb → tagger.rb} +3 -3
- data/lib/acts_as_taggable_on/tagging.rb +12 -2
- data/lib/acts_as_taggable_on/tags_helper.rb +2 -2
- data/lib/acts_as_taggable_on/utils.rb +34 -0
- data/lib/generators/acts_as_taggable_on/migration/migration_generator.rb +9 -2
- data/lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb +3 -1
- data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +333 -54
- data/spec/acts_as_taggable_on/tag_list_spec.rb +117 -61
- data/spec/acts_as_taggable_on/tag_spec.rb +111 -14
- data/spec/acts_as_taggable_on/taggable_spec.rb +330 -34
- data/spec/acts_as_taggable_on/tagger_spec.rb +62 -15
- data/spec/acts_as_taggable_on/tagging_spec.rb +2 -5
- data/spec/acts_as_taggable_on/tags_helper_spec.rb +16 -0
- data/spec/acts_as_taggable_on/utils_spec.rb +21 -0
- data/spec/database.yml.sample +4 -2
- data/spec/generators/acts_as_taggable_on/migration/migration_generator_spec.rb +22 -0
- data/spec/models.rb +28 -1
- data/spec/schema.rb +18 -0
- data/spec/spec_helper.rb +30 -7
- data/uninstall.rb +1 -0
- metadata +174 -57
- data/CHANGELOG +0 -25
- data/README.rdoc +0 -221
- data/VERSION +0 -1
- data/generators/acts_as_taggable_on_migration/acts_as_taggable_on_migration_generator.rb +0 -7
- data/generators/acts_as_taggable_on_migration/templates/migration.rb +0 -29
- data/lib/acts_as_taggable_on/acts_as_taggable_on.rb +0 -53
- data/lib/acts_as_taggable_on/compatibility/Gemfile +0 -8
- data/lib/acts_as_taggable_on/compatibility/active_record_backports.rb +0 -17
- data/lib/acts_as_taggable_on/compatibility/postgresql.rb +0 -44
- data/spec/database.yml +0 -17
@@ -8,11 +8,25 @@ describe "Acts As Taggable On" do
|
|
8
8
|
it "should provide a class method 'taggable?' that is false for untaggable models" do
|
9
9
|
UntaggableModel.should_not be_taggable
|
10
10
|
end
|
11
|
+
|
12
|
+
describe "Taggable Method Generation To Preserve Order" do
|
13
|
+
before(:each) do
|
14
|
+
clean_database!
|
15
|
+
TaggableModel.tag_types = []
|
16
|
+
TaggableModel.preserve_tag_order = false
|
17
|
+
TaggableModel.acts_as_ordered_taggable_on(:ordered_tags)
|
18
|
+
@taggable = TaggableModel.new(:name => "Bob Jones")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should respond 'true' to preserve_tag_order?" do
|
22
|
+
@taggable.class.preserve_tag_order?.should be_true
|
23
|
+
end
|
24
|
+
end
|
11
25
|
|
12
26
|
describe "Taggable Method Generation" do
|
13
27
|
before(:each) do
|
14
28
|
clean_database!
|
15
|
-
TaggableModel.
|
29
|
+
TaggableModel.tag_types = []
|
16
30
|
TaggableModel.acts_as_taggable_on(:tags, :languages, :skills, :needs, :offerings)
|
17
31
|
@taggable = TaggableModel.new(:name => "Bob Jones")
|
18
32
|
end
|
@@ -28,10 +42,22 @@ describe "Acts As Taggable On" do
|
|
28
42
|
it "should create an instance attribute for tag types" do
|
29
43
|
@taggable.should respond_to(:tag_types)
|
30
44
|
end
|
31
|
-
|
45
|
+
|
32
46
|
it "should have all tag types" do
|
33
47
|
@taggable.tag_types.should == [:tags, :languages, :skills, :needs, :offerings]
|
34
48
|
end
|
49
|
+
|
50
|
+
it "should create a class attribute for preserve tag order" do
|
51
|
+
@taggable.class.should respond_to(:preserve_tag_order?)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should create an instance attribute for preserve tag order" do
|
55
|
+
@taggable.should respond_to(:preserve_tag_order?)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should respond 'false' to preserve_tag_order?" do
|
59
|
+
@taggable.class.preserve_tag_order?.should be_false
|
60
|
+
end
|
35
61
|
|
36
62
|
it "should generate an association for each tag type" do
|
37
63
|
@taggable.should respond_to(:tags, :skills, :languages)
|
@@ -45,7 +71,7 @@ describe "Acts As Taggable On" do
|
|
45
71
|
@taggable.should respond_to(:tag_list, :skill_list, :language_list)
|
46
72
|
@taggable.should respond_to(:tag_list=, :skill_list=, :language_list=)
|
47
73
|
end
|
48
|
-
|
74
|
+
|
49
75
|
it "should generate a tag_list accessor, that includes owned tags, for each tag type" do
|
50
76
|
@taggable.should respond_to(:all_tags_list, :all_skills_list, :all_languages_list)
|
51
77
|
end
|
@@ -57,17 +83,17 @@ describe "Acts As Taggable On" do
|
|
57
83
|
@inherited_same = InheritingTaggableModel.new(:name => "inherited same")
|
58
84
|
@inherited_different = AlteredInheritingTaggableModel.new(:name => "inherited different")
|
59
85
|
end
|
60
|
-
|
86
|
+
|
61
87
|
it "should pass on tag contexts to STI-inherited models" do
|
62
88
|
@inherited_same.should respond_to(:tag_list, :skill_list, :language_list)
|
63
89
|
@inherited_different.should respond_to(:tag_list, :skill_list, :language_list)
|
64
90
|
end
|
65
|
-
|
91
|
+
|
66
92
|
it "should have tag contexts added in altered STI models" do
|
67
93
|
@inherited_different.should respond_to(:part_list)
|
68
94
|
end
|
69
95
|
end
|
70
|
-
|
96
|
+
|
71
97
|
describe "Reloading" do
|
72
98
|
it "should save a model instantiated by Model.find" do
|
73
99
|
taggable = TaggableModel.create!(:name => "Taggable")
|
@@ -81,51 +107,154 @@ describe "Acts As Taggable On" do
|
|
81
107
|
taggable1 = TaggableModel.create!(:name => "Taggable 1")
|
82
108
|
taggable2 = TaggableModel.create!(:name => "Taggable 2")
|
83
109
|
taggable3 = TaggableModel.create!(:name => "Taggable 3")
|
84
|
-
|
110
|
+
|
85
111
|
taggable1.tag_list = "one, two"
|
86
112
|
taggable1.save
|
87
|
-
|
113
|
+
|
88
114
|
taggable2.tag_list = "three, four"
|
89
115
|
taggable2.save
|
90
|
-
|
116
|
+
|
91
117
|
taggable3.tag_list = "one, four"
|
92
118
|
taggable3.save
|
93
|
-
|
119
|
+
|
94
120
|
taggable1.find_related_tags.should include(taggable3)
|
95
121
|
taggable1.find_related_tags.should_not include(taggable2)
|
96
122
|
end
|
97
|
-
|
123
|
+
|
124
|
+
it "should find related objects based on tag names on context - non standard id" do
|
125
|
+
taggable1 = NonStandardIdTaggableModel.create!(:name => "Taggable 1")
|
126
|
+
taggable2 = NonStandardIdTaggableModel.create!(:name => "Taggable 2")
|
127
|
+
taggable3 = NonStandardIdTaggableModel.create!(:name => "Taggable 3")
|
128
|
+
|
129
|
+
taggable1.tag_list = "one, two"
|
130
|
+
taggable1.save
|
131
|
+
|
132
|
+
taggable2.tag_list = "three, four"
|
133
|
+
taggable2.save
|
134
|
+
|
135
|
+
taggable3.tag_list = "one, four"
|
136
|
+
taggable3.save
|
137
|
+
|
138
|
+
taggable1.find_related_tags.should include(taggable3)
|
139
|
+
taggable1.find_related_tags.should_not include(taggable2)
|
140
|
+
end
|
141
|
+
|
98
142
|
it "should find other related objects based on tag names on context" do
|
99
143
|
taggable1 = TaggableModel.create!(:name => "Taggable 1")
|
100
144
|
taggable2 = OtherTaggableModel.create!(:name => "Taggable 2")
|
101
145
|
taggable3 = OtherTaggableModel.create!(:name => "Taggable 3")
|
102
|
-
|
146
|
+
|
103
147
|
taggable1.tag_list = "one, two"
|
104
148
|
taggable1.save
|
105
|
-
|
149
|
+
|
106
150
|
taggable2.tag_list = "three, four"
|
107
151
|
taggable2.save
|
108
|
-
|
152
|
+
|
109
153
|
taggable3.tag_list = "one, four"
|
110
154
|
taggable3.save
|
111
|
-
|
155
|
+
|
112
156
|
taggable1.find_related_tags_for(OtherTaggableModel).should include(taggable3)
|
113
157
|
taggable1.find_related_tags_for(OtherTaggableModel).should_not include(taggable2)
|
114
158
|
end
|
115
|
-
|
159
|
+
|
116
160
|
it "should not include the object itself in the list of related objects" do
|
117
161
|
taggable1 = TaggableModel.create!(:name => "Taggable 1")
|
118
162
|
taggable2 = TaggableModel.create!(:name => "Taggable 2")
|
119
|
-
|
163
|
+
|
120
164
|
taggable1.tag_list = "one"
|
121
165
|
taggable1.save
|
122
|
-
|
166
|
+
|
123
167
|
taggable2.tag_list = "one, two"
|
124
168
|
taggable2.save
|
125
|
-
|
169
|
+
|
126
170
|
taggable1.find_related_tags.should include(taggable2)
|
127
171
|
taggable1.find_related_tags.should_not include(taggable1)
|
128
172
|
end
|
173
|
+
|
174
|
+
it "should not include the object itself in the list of related objects - non standard id" do
|
175
|
+
taggable1 = NonStandardIdTaggableModel.create!(:name => "Taggable 1")
|
176
|
+
taggable2 = NonStandardIdTaggableModel.create!(:name => "Taggable 2")
|
177
|
+
|
178
|
+
taggable1.tag_list = "one"
|
179
|
+
taggable1.save
|
180
|
+
|
181
|
+
taggable2.tag_list = "one, two"
|
182
|
+
taggable2.save
|
183
|
+
|
184
|
+
taggable1.find_related_tags.should include(taggable2)
|
185
|
+
taggable1.find_related_tags.should_not include(taggable1)
|
186
|
+
end
|
187
|
+
|
188
|
+
context "Ignored Tags" do
|
189
|
+
let(:taggable1) { TaggableModel.create!(:name => "Taggable 1") }
|
190
|
+
let(:taggable2) { TaggableModel.create!(:name => "Taggable 2") }
|
191
|
+
let(:taggable3) { TaggableModel.create!(:name => "Taggable 3") }
|
192
|
+
before(:each) do
|
193
|
+
taggable1.tag_list = "one, two, four"
|
194
|
+
taggable1.save
|
195
|
+
|
196
|
+
taggable2.tag_list = "two, three"
|
197
|
+
taggable2.save
|
198
|
+
|
199
|
+
taggable3.tag_list = "one, three"
|
200
|
+
taggable3.save
|
201
|
+
end
|
202
|
+
it "should not include ignored tags in related search" do
|
203
|
+
taggable1.find_related_tags(:ignore => 'two').should_not include(taggable2)
|
204
|
+
taggable1.find_related_tags(:ignore => 'two').should include(taggable3)
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should accept array of ignored tags" do
|
208
|
+
taggable4 = TaggableModel.create!(:name => "Taggable 4")
|
209
|
+
taggable4.tag_list = "four"
|
210
|
+
taggable4.save
|
211
|
+
|
212
|
+
taggable1.find_related_tags(:ignore => ['two', 'four']).should_not include(taggable2)
|
213
|
+
taggable1.find_related_tags(:ignore => ['two', 'four']).should_not include(taggable4)
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should accept symbols as ignored tags" do
|
217
|
+
taggable1.find_related_tags(:ignore => :two).should_not include(taggable2)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context "Inherited Models" do
|
222
|
+
before do
|
223
|
+
@taggable1 = InheritingTaggableModel.create!(:name => "InheritingTaggable 1")
|
224
|
+
@taggable2 = InheritingTaggableModel.create!(:name => "InheritingTaggable 2")
|
225
|
+
@taggable3 = InheritingTaggableModel.create!(:name => "InheritingTaggable 3")
|
226
|
+
@taggable4 = TaggableModel.create!(:name => "Taggable 4")
|
227
|
+
|
228
|
+
@taggable1.tag_list = "one, two"
|
229
|
+
@taggable1.save
|
230
|
+
|
231
|
+
@taggable2.tag_list = "three, four"
|
232
|
+
@taggable2.save
|
233
|
+
|
234
|
+
@taggable3.tag_list = "one, four"
|
235
|
+
@taggable3.save
|
236
|
+
|
237
|
+
@taggable4.tag_list = "one, two, three, four"
|
238
|
+
@taggable4.save
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should find related objects based on tag names on context" do
|
242
|
+
@taggable1.find_related_tags.should include(@taggable3)
|
243
|
+
@taggable1.find_related_tags.should_not include(@taggable2)
|
244
|
+
@taggable1.find_related_tags.should_not include(@taggable4)
|
245
|
+
|
246
|
+
@taggable1.find_related_tags_for(TaggableModel).should include(@taggable3)
|
247
|
+
@taggable1.find_related_tags_for(TaggableModel).should_not include(@taggable2)
|
248
|
+
@taggable1.find_related_tags_for(TaggableModel).should include(@taggable4)
|
249
|
+
end
|
250
|
+
|
251
|
+
it "should not include the object itself in the list of related objects" do
|
252
|
+
@taggable1.find_related_tags.should_not include(@taggable1)
|
253
|
+
@taggable1.find_related_tags_for(InheritingTaggableModel).should_not include(@taggable1)
|
254
|
+
@taggable1.find_related_tags_for(TaggableModel).should_not include(@taggable1)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
129
258
|
end
|
130
259
|
|
131
260
|
describe "Matching Contexts" do
|
@@ -133,50 +262,95 @@ describe "Acts As Taggable On" do
|
|
133
262
|
taggable1 = TaggableModel.create!(:name => "Taggable 1")
|
134
263
|
taggable2 = TaggableModel.create!(:name => "Taggable 2")
|
135
264
|
taggable3 = TaggableModel.create!(:name => "Taggable 3")
|
136
|
-
|
265
|
+
|
137
266
|
taggable1.offering_list = "one, two"
|
138
267
|
taggable1.save!
|
139
|
-
|
268
|
+
|
140
269
|
taggable2.need_list = "one, two"
|
141
270
|
taggable2.save!
|
142
|
-
|
271
|
+
|
143
272
|
taggable3.offering_list = "one, two"
|
144
273
|
taggable3.save!
|
145
|
-
|
274
|
+
|
146
275
|
taggable1.find_matching_contexts(:offerings, :needs).should include(taggable2)
|
147
276
|
taggable1.find_matching_contexts(:offerings, :needs).should_not include(taggable3)
|
148
277
|
end
|
149
|
-
|
278
|
+
|
150
279
|
it "should find other related objects with tags of matching contexts" do
|
151
280
|
taggable1 = TaggableModel.create!(:name => "Taggable 1")
|
152
281
|
taggable2 = OtherTaggableModel.create!(:name => "Taggable 2")
|
153
282
|
taggable3 = OtherTaggableModel.create!(:name => "Taggable 3")
|
154
|
-
|
283
|
+
|
155
284
|
taggable1.offering_list = "one, two"
|
156
285
|
taggable1.save
|
157
|
-
|
286
|
+
|
158
287
|
taggable2.need_list = "one, two"
|
159
288
|
taggable2.save
|
160
|
-
|
289
|
+
|
161
290
|
taggable3.offering_list = "one, two"
|
162
291
|
taggable3.save
|
163
|
-
|
292
|
+
|
164
293
|
taggable1.find_matching_contexts_for(OtherTaggableModel, :offerings, :needs).should include(taggable2)
|
165
294
|
taggable1.find_matching_contexts_for(OtherTaggableModel, :offerings, :needs).should_not include(taggable3)
|
166
295
|
end
|
167
|
-
|
168
|
-
it "should not include the object itself in the list of related objects" do
|
296
|
+
|
297
|
+
it "should not include the object itself in the list of related objects with tags of matching contexts" do
|
169
298
|
taggable1 = TaggableModel.create!(:name => "Taggable 1")
|
170
299
|
taggable2 = TaggableModel.create!(:name => "Taggable 2")
|
171
|
-
|
172
|
-
taggable1.
|
300
|
+
|
301
|
+
taggable1.offering_list = "one, two"
|
302
|
+
taggable1.need_list = "one, two"
|
173
303
|
taggable1.save
|
174
|
-
|
175
|
-
taggable2.
|
304
|
+
|
305
|
+
taggable2.need_list = "one, two"
|
176
306
|
taggable2.save
|
177
|
-
|
178
|
-
taggable1.
|
179
|
-
taggable1.
|
307
|
+
|
308
|
+
taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should include(taggable2)
|
309
|
+
taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(taggable1)
|
310
|
+
end
|
311
|
+
|
312
|
+
context "Inherited Models" do
|
313
|
+
before do
|
314
|
+
@taggable1 = InheritingTaggableModel.create!(:name => "InheritingTaggable 1")
|
315
|
+
@taggable2 = InheritingTaggableModel.create!(:name => "InheritingTaggable 2")
|
316
|
+
@taggable3 = InheritingTaggableModel.create!(:name => "InheritingTaggable 3")
|
317
|
+
@taggable4 = InheritingTaggableModel.create!(:name => "InheritingTaggable 4")
|
318
|
+
@taggable5 = TaggableModel.create!(:name => "Taggable 5")
|
319
|
+
|
320
|
+
@taggable1.offering_list = "one, two"
|
321
|
+
@taggable1.need_list = "one, two"
|
322
|
+
@taggable1.save!
|
323
|
+
|
324
|
+
@taggable2.need_list = "one, two"
|
325
|
+
@taggable2.save!
|
326
|
+
|
327
|
+
@taggable3.offering_list = "one, two"
|
328
|
+
@taggable3.save!
|
329
|
+
|
330
|
+
@taggable4.tag_list = "one, two, three, four"
|
331
|
+
@taggable4.save!
|
332
|
+
|
333
|
+
@taggable5.need_list = "one, two"
|
334
|
+
@taggable5.save!
|
335
|
+
end
|
336
|
+
|
337
|
+
it "should find objects with tags of matching contexts" do
|
338
|
+
@taggable1.find_matching_contexts(:offerings, :needs).should include(@taggable2)
|
339
|
+
@taggable1.find_matching_contexts(:offerings, :needs).should_not include(@taggable3)
|
340
|
+
@taggable1.find_matching_contexts(:offerings, :needs).should_not include(@taggable4)
|
341
|
+
@taggable1.find_matching_contexts(:offerings, :needs).should_not include(@taggable5)
|
342
|
+
|
343
|
+
@taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should include(@taggable2)
|
344
|
+
@taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(@taggable3)
|
345
|
+
@taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(@taggable4)
|
346
|
+
@taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should include(@taggable5)
|
347
|
+
end
|
348
|
+
|
349
|
+
it "should not include the object itself in the list of related objects with tags of matching contexts" do
|
350
|
+
@taggable1.find_matching_contexts(:offerings, :needs).should_not include(@taggable1)
|
351
|
+
@taggable1.find_matching_contexts_for(InheritingTaggableModel, :offerings, :needs).should_not include(@taggable1)
|
352
|
+
@taggable1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(@taggable1)
|
353
|
+
end
|
180
354
|
end
|
181
355
|
end
|
182
356
|
|
@@ -208,55 +382,67 @@ describe "Acts As Taggable On" do
|
|
208
382
|
}.should_not raise_error
|
209
383
|
end
|
210
384
|
end
|
211
|
-
|
385
|
+
|
212
386
|
describe 'Caching' do
|
213
387
|
before(:each) do
|
214
|
-
@taggable = CachedModel.new(:name => "Bob Jones")
|
388
|
+
@taggable = CachedModel.new(:name => "Bob Jones")
|
389
|
+
@another_taggable = OtherCachedModel.new(:name => "John Smith")
|
215
390
|
end
|
216
|
-
|
391
|
+
|
217
392
|
it "should add saving of tag lists and cached tag lists to the instance" do
|
218
393
|
@taggable.should respond_to(:save_cached_tag_list)
|
394
|
+
@another_taggable.should respond_to(:save_cached_tag_list)
|
395
|
+
|
219
396
|
@taggable.should respond_to(:save_tags)
|
220
|
-
end
|
397
|
+
end
|
398
|
+
|
399
|
+
it "should add cached tag lists to the instance if cached column is not present" do
|
400
|
+
TaggableModel.new(:name => "Art Kram").should_not respond_to(:save_cached_tag_list)
|
401
|
+
end
|
221
402
|
|
222
403
|
it "should generate a cached column checker for each tag type" do
|
223
404
|
CachedModel.should respond_to(:caching_tag_list?)
|
224
|
-
|
225
|
-
|
405
|
+
OtherCachedModel.should respond_to(:caching_language_list?)
|
406
|
+
end
|
407
|
+
|
226
408
|
it 'should not have cached tags' do
|
227
|
-
@taggable.cached_tag_list.should be_blank
|
409
|
+
@taggable.cached_tag_list.should be_blank
|
410
|
+
@another_taggable.cached_language_list.should be_blank
|
228
411
|
end
|
229
|
-
|
412
|
+
|
230
413
|
it 'should cache tags' do
|
231
414
|
@taggable.update_attributes(:tag_list => 'awesome, epic')
|
232
415
|
@taggable.cached_tag_list.should == 'awesome, epic'
|
416
|
+
|
417
|
+
@another_taggable.update_attributes(:language_list => 'ruby, .net')
|
418
|
+
@another_taggable.cached_language_list.should == 'ruby, .net'
|
233
419
|
end
|
234
|
-
|
420
|
+
|
235
421
|
it 'should keep the cache' do
|
236
422
|
@taggable.update_attributes(:tag_list => 'awesome, epic')
|
237
|
-
@taggable = CachedModel.find(@taggable)
|
423
|
+
@taggable = CachedModel.find(@taggable)
|
238
424
|
@taggable.save!
|
239
|
-
@taggable.cached_tag_list.should == 'awesome, epic'
|
425
|
+
@taggable.cached_tag_list.should == 'awesome, epic'
|
240
426
|
end
|
241
|
-
|
427
|
+
|
242
428
|
it 'should update the cache' do
|
243
429
|
@taggable.update_attributes(:tag_list => 'awesome, epic')
|
244
430
|
@taggable.update_attributes(:tag_list => 'awesome')
|
245
|
-
@taggable.cached_tag_list.should == 'awesome'
|
431
|
+
@taggable.cached_tag_list.should == 'awesome'
|
246
432
|
end
|
247
|
-
|
433
|
+
|
248
434
|
it 'should remove the cache' do
|
249
435
|
@taggable.update_attributes(:tag_list => 'awesome, epic')
|
250
436
|
@taggable.update_attributes(:tag_list => '')
|
251
|
-
@taggable.cached_tag_list.should be_blank
|
437
|
+
@taggable.cached_tag_list.should be_blank
|
252
438
|
end
|
253
|
-
|
439
|
+
|
254
440
|
it 'should have a tag list' do
|
255
441
|
@taggable.update_attributes(:tag_list => 'awesome, epic')
|
256
442
|
@taggable = CachedModel.find(@taggable.id)
|
257
443
|
@taggable.tag_list.sort.should == %w(awesome epic).sort
|
258
444
|
end
|
259
|
-
|
445
|
+
|
260
446
|
it 'should keep the tag list' do
|
261
447
|
@taggable.update_attributes(:tag_list => 'awesome, epic')
|
262
448
|
@taggable = CachedModel.find(@taggable.id)
|
@@ -265,4 +451,97 @@ describe "Acts As Taggable On" do
|
|
265
451
|
end
|
266
452
|
end
|
267
453
|
|
454
|
+
context 'when tagging context ends in an "s" when singular (ex. "status", "glass", etc.)' do
|
455
|
+
describe 'caching' do
|
456
|
+
before { @taggable = OtherCachedModel.new(:name => "John Smith") }
|
457
|
+
subject { @taggable }
|
458
|
+
|
459
|
+
it { should respond_to(:save_cached_tag_list) }
|
460
|
+
its(:cached_language_list) { should be_blank }
|
461
|
+
its(:cached_status_list) { should be_blank }
|
462
|
+
its(:cached_glass_list) { should be_blank }
|
463
|
+
|
464
|
+
context 'language taggings cache after update' do
|
465
|
+
before { @taggable.update_attributes(:language_list => 'ruby, .net') }
|
466
|
+
subject { @taggable }
|
467
|
+
|
468
|
+
its(:language_list) { should == ['ruby', '.net']}
|
469
|
+
its(:cached_language_list) { should == 'ruby, .net' } # passes
|
470
|
+
its(:instance_variables) { should include((RUBY_VERSION < '1.9' ? '@language_list' : :@language_list)) }
|
471
|
+
end
|
472
|
+
|
473
|
+
context 'status taggings cache after update' do
|
474
|
+
before { @taggable.update_attributes(:status_list => 'happy, married') }
|
475
|
+
subject { @taggable }
|
476
|
+
|
477
|
+
its(:status_list) { should == ['happy', 'married'] }
|
478
|
+
its(:cached_status_list) { should == 'happy, married' } # fails
|
479
|
+
its(:cached_status_list) { should_not == '' } # fails, is blank
|
480
|
+
its(:instance_variables) { should include((RUBY_VERSION < '1.9' ? '@status_list' : :@status_list)) }
|
481
|
+
its(:instance_variables) { should_not include((RUBY_VERSION < '1.9' ? '@statu_list' : :@statu_list)) } # fails, note: one "s"
|
482
|
+
|
483
|
+
end
|
484
|
+
|
485
|
+
context 'glass taggings cache after update' do
|
486
|
+
before do
|
487
|
+
@taggable.update_attributes(:glass_list => 'rectangle, aviator')
|
488
|
+
end
|
489
|
+
|
490
|
+
subject { @taggable }
|
491
|
+
its(:glass_list) { should == ['rectangle', 'aviator'] }
|
492
|
+
its(:cached_glass_list) { should == 'rectangle, aviator' } # fails
|
493
|
+
its(:cached_glass_list) { should_not == '' } # fails, is blank
|
494
|
+
if RUBY_VERSION < '1.9'
|
495
|
+
its(:instance_variables) { should include('@glass_list') }
|
496
|
+
its(:instance_variables) { should_not include('@glas_list') } # fails, note: one "s"
|
497
|
+
else
|
498
|
+
its(:instance_variables) { should include(:@glass_list) }
|
499
|
+
its(:instance_variables) { should_not include(:@glas_list) } # fails, note: one "s"
|
500
|
+
end
|
501
|
+
|
502
|
+
end
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
describe "taggings" do
|
507
|
+
before(:each) do
|
508
|
+
@taggable = TaggableModel.new(:name => "Art Kram")
|
509
|
+
end
|
510
|
+
|
511
|
+
it 'should return [] taggings' do
|
512
|
+
@taggable.taggings.should == []
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
describe "@@remove_unused_tags" do
|
517
|
+
before do
|
518
|
+
@taggable = TaggableModel.create(:name => "Bob Jones")
|
519
|
+
@tag = ActsAsTaggableOn::Tag.create(:name => "awesome")
|
520
|
+
|
521
|
+
@tagging = ActsAsTaggableOn::Tagging.create(:taggable => @taggable, :tag => @tag, :context => 'tags')
|
522
|
+
end
|
523
|
+
|
524
|
+
context "if set to true" do
|
525
|
+
before do
|
526
|
+
ActsAsTaggableOn.remove_unused_tags = true
|
527
|
+
end
|
528
|
+
|
529
|
+
it "should remove unused tags after removing taggings" do
|
530
|
+
@tagging.destroy
|
531
|
+
ActsAsTaggableOn::Tag.find_by_name("awesome").should be_nil
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
535
|
+
context "if set to false" do
|
536
|
+
before do
|
537
|
+
ActsAsTaggableOn.remove_unused_tags = false
|
538
|
+
end
|
539
|
+
|
540
|
+
it "should not remove unused tags after removing taggings" do
|
541
|
+
@tagging.destroy
|
542
|
+
ActsAsTaggableOn::Tag.find_by_name("awesome").should == @tag
|
543
|
+
end
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
268
547
|
end
|