acts-as-taggable-on 2.3.3 → 2.4.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.
- checksums.yaml +7 -0
- data/.gitignore +3 -3
- data/Appraisals +7 -0
- data/Gemfile +3 -1
- data/{MIT-LICENSE → LICENSE.md} +1 -1
- data/README.md +303 -0
- data/Rakefile +2 -2
- data/acts-as-taggable-on.gemspec +25 -18
- data/gemfiles/rails_3.gemfile +8 -0
- data/gemfiles/rails_4.gemfile +8 -0
- data/lib/acts-as-taggable-on.rb +5 -0
- data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +2 -2
- data/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb +64 -7
- data/lib/acts_as_taggable_on/acts_as_taggable_on/compatibility.rb +34 -0
- data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +86 -55
- data/lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb +3 -3
- data/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb +24 -15
- data/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb +32 -21
- data/lib/acts_as_taggable_on/tag.rb +37 -15
- data/lib/acts_as_taggable_on/tag_list.rb +2 -2
- data/lib/acts_as_taggable_on/taggable.rb +10 -7
- data/lib/acts_as_taggable_on/tagger.rb +12 -3
- data/lib/acts_as_taggable_on/tagging.rb +2 -2
- data/lib/acts_as_taggable_on/tags_helper.rb +0 -2
- data/lib/{acts-as-taggable-on → acts_as_taggable_on}/version.rb +1 -1
- data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +1 -183
- data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +8 -8
- data/spec/acts_as_taggable_on/related_spec.rb +143 -0
- data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +187 -0
- data/spec/acts_as_taggable_on/tag_list_spec.rb +4 -4
- data/spec/acts_as_taggable_on/tag_spec.rb +61 -3
- data/spec/acts_as_taggable_on/taggable_spec.rb +178 -98
- data/spec/acts_as_taggable_on/tagger_spec.rb +32 -33
- data/spec/acts_as_taggable_on/tagging_spec.rb +1 -1
- data/spec/acts_as_taggable_on/tags_helper_spec.rb +2 -2
- data/spec/acts_as_taggable_on/utils_spec.rb +2 -2
- data/spec/models.rb +8 -2
- data/spec/schema.rb +1 -1
- data/spec/spec_helper.rb +7 -4
- metadata +101 -56
- data/CHANGELOG +0 -35
- data/README.rdoc +0 -244
- data/rails/init.rb +0 -1
- data/uninstall.rb +0 -1
@@ -1,6 +1,5 @@
|
|
1
|
-
#encoding: utf-8
|
2
|
-
|
3
|
-
require File.expand_path('../../spec_helper', __FILE__)
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
4
3
|
|
5
4
|
describe ActsAsTaggableOn::Tag do
|
6
5
|
before(:each) do
|
@@ -150,4 +149,63 @@ describe ActsAsTaggableOn::Tag do
|
|
150
149
|
|
151
150
|
end
|
152
151
|
|
152
|
+
describe "when using strict_case_match" do
|
153
|
+
before do
|
154
|
+
ActsAsTaggableOn.strict_case_match = true
|
155
|
+
@tag.name = "awesome"
|
156
|
+
@tag.save!
|
157
|
+
end
|
158
|
+
|
159
|
+
after do
|
160
|
+
ActsAsTaggableOn.strict_case_match = false
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should find by name" do
|
164
|
+
ActsAsTaggableOn::Tag.find_or_create_with_like_by_name("awesome").should == @tag
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should find by name case sensitively" do
|
168
|
+
expect {
|
169
|
+
ActsAsTaggableOn::Tag.find_or_create_with_like_by_name("AWESOME")
|
170
|
+
}.to change(ActsAsTaggableOn::Tag, :count)
|
171
|
+
|
172
|
+
ActsAsTaggableOn::Tag.last.name.should == "AWESOME"
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should have a named_scope named(something) that matches exactly" do
|
176
|
+
uppercase_tag = ActsAsTaggableOn::Tag.create(:name => "Cool")
|
177
|
+
@tag.name = "cool"
|
178
|
+
@tag.save!
|
179
|
+
|
180
|
+
ActsAsTaggableOn::Tag.named('cool').should include(@tag)
|
181
|
+
ActsAsTaggableOn::Tag.named('cool').should_not include(uppercase_tag)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "name uniqeness validation" do
|
186
|
+
let(:duplicate_tag) { ActsAsTaggableOn::Tag.new(:name => 'ror') }
|
187
|
+
|
188
|
+
before { ActsAsTaggableOn::Tag.create(:name => 'ror') }
|
189
|
+
|
190
|
+
context "when don't need unique names" do
|
191
|
+
it "should not run uniqueness validation" do
|
192
|
+
duplicate_tag.stub(:validates_name_uniqueness?).and_return(false)
|
193
|
+
duplicate_tag.save
|
194
|
+
duplicate_tag.should be_persisted
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context "when do need unique names" do
|
199
|
+
it "should run uniqueness validation" do
|
200
|
+
duplicate_tag.should_not be_valid
|
201
|
+
end
|
202
|
+
|
203
|
+
it "add error to name" do
|
204
|
+
duplicate_tag.save
|
205
|
+
|
206
|
+
duplicate_tag.should have(1).errors
|
207
|
+
duplicate_tag.errors.messages[:name].should include('has already been taken')
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
153
211
|
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "Taggable To Preserve Order" do
|
4
4
|
before(:each) do
|
5
5
|
clean_database!
|
6
6
|
@taggable = OrderedTaggableModel.new(:name => "Bob Jones")
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
it "should have tag types" do
|
10
10
|
[:tags, :colours].each do |type|
|
11
11
|
OrderedTaggableModel.tag_types.should include type
|
@@ -13,21 +13,21 @@ describe "Taggable To Preserve Order" do
|
|
13
13
|
|
14
14
|
@taggable.tag_types.should == OrderedTaggableModel.tag_types
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
it "should have tag associations" do
|
18
18
|
[:tags, :colours].each do |type|
|
19
19
|
@taggable.respond_to?(type).should be_true
|
20
20
|
@taggable.respond_to?("#{type.to_s.singularize}_taggings").should be_true
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
24
|
-
it "should have tag associations ordered by id" do
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
23
|
+
|
24
|
+
# it "should have tag associations ordered by id" do
|
25
|
+
# [:tags, :colours].each do |type|
|
26
|
+
# OrderedTaggableModel.reflect_on_association(type).options[:order].should include('id')
|
27
|
+
# OrderedTaggableModel.reflect_on_association("#{type.to_s.singularize}_taggings".to_sym).options[:order].should include('id')
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
|
31
31
|
it "should have tag methods" do
|
32
32
|
[:tags, :colours].each do |type|
|
33
33
|
@taggable.respond_to?("#{type.to_s.singularize}_list").should be_true
|
@@ -40,69 +40,69 @@ describe "Taggable To Preserve Order" do
|
|
40
40
|
# create
|
41
41
|
@taggable.tag_list = "rails, ruby, css"
|
42
42
|
@taggable.instance_variable_get("@tag_list").instance_of?(ActsAsTaggableOn::TagList).should be_true
|
43
|
-
|
43
|
+
|
44
44
|
lambda {
|
45
45
|
@taggable.save
|
46
46
|
}.should change(ActsAsTaggableOn::Tag, :count).by(3)
|
47
|
-
|
47
|
+
|
48
48
|
@taggable.reload
|
49
49
|
@taggable.tag_list.should == %w(rails ruby css)
|
50
|
-
|
50
|
+
|
51
51
|
# update
|
52
52
|
@taggable.tag_list = "pow, ruby, rails"
|
53
53
|
@taggable.save
|
54
|
-
|
54
|
+
|
55
55
|
@taggable.reload
|
56
56
|
@taggable.tag_list.should == %w(pow ruby rails)
|
57
|
-
|
57
|
+
|
58
58
|
# update with no change
|
59
59
|
@taggable.tag_list = "pow, ruby, rails"
|
60
60
|
@taggable.save
|
61
|
-
|
61
|
+
|
62
62
|
@taggable.reload
|
63
63
|
@taggable.tag_list.should == %w(pow ruby rails)
|
64
|
-
|
64
|
+
|
65
65
|
# update to clear tags
|
66
66
|
@taggable.tag_list = ""
|
67
67
|
@taggable.save
|
68
|
-
|
68
|
+
|
69
69
|
@taggable.reload
|
70
70
|
@taggable.tag_list.should == []
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
it "should return tag objects in the order the tags were created" do
|
74
74
|
# create
|
75
75
|
@taggable.tag_list = "pow, ruby, rails"
|
76
76
|
@taggable.instance_variable_get("@tag_list").instance_of?(ActsAsTaggableOn::TagList).should be_true
|
77
|
-
|
77
|
+
|
78
78
|
lambda {
|
79
79
|
@taggable.save
|
80
80
|
}.should change(ActsAsTaggableOn::Tag, :count).by(3)
|
81
|
-
|
81
|
+
|
82
82
|
@taggable.reload
|
83
83
|
@taggable.tags.map{|t| t.name}.should == %w(pow ruby rails)
|
84
|
-
|
84
|
+
|
85
85
|
# update
|
86
86
|
@taggable.tag_list = "rails, ruby, css, pow"
|
87
87
|
@taggable.save
|
88
|
-
|
88
|
+
|
89
89
|
@taggable.reload
|
90
90
|
@taggable.tags.map{|t| t.name}.should == %w(rails ruby css pow)
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
93
|
it "should return tag objects in tagging id order" do
|
94
94
|
# create
|
95
95
|
@taggable.tag_list = "pow, ruby, rails"
|
96
96
|
@taggable.save
|
97
|
-
|
97
|
+
|
98
98
|
@taggable.reload
|
99
99
|
ids = @taggable.tags.map{|t| t.taggings.first.id}
|
100
100
|
ids.should == ids.sort
|
101
|
-
|
101
|
+
|
102
102
|
# update
|
103
103
|
@taggable.tag_list = "rails, ruby, css, pow"
|
104
104
|
@taggable.save
|
105
|
-
|
105
|
+
|
106
106
|
@taggable.reload
|
107
107
|
ids = @taggable.tags.map{|t| t.taggings.first.id}
|
108
108
|
ids.should == ids.sort
|
@@ -125,7 +125,7 @@ describe "Taggable" do
|
|
125
125
|
end
|
126
126
|
|
127
127
|
it "should have tag_counts_on" do
|
128
|
-
TaggableModel.tag_counts_on(:tags).
|
128
|
+
TaggableModel.tag_counts_on(:tags).should be_empty
|
129
129
|
|
130
130
|
@taggable.tag_list = ["awesome", "epic"]
|
131
131
|
@taggable.save
|
@@ -134,6 +134,16 @@ describe "Taggable" do
|
|
134
134
|
@taggable.tag_counts_on(:tags).length.should == 2
|
135
135
|
end
|
136
136
|
|
137
|
+
it "should have tags_on" do
|
138
|
+
TaggableModel.tags_on(:tags).should be_empty
|
139
|
+
|
140
|
+
@taggable.tag_list = ["awesome", "epic"]
|
141
|
+
@taggable.save
|
142
|
+
|
143
|
+
TaggableModel.tags_on(:tags).length.should == 2
|
144
|
+
@taggable.tags_on(:tags).length.should == 2
|
145
|
+
end
|
146
|
+
|
137
147
|
it "should return [] right after create" do
|
138
148
|
blank_taggable = TaggableModel.new(:name => "Bob Jones")
|
139
149
|
blank_taggable.tag_list.should == []
|
@@ -221,7 +231,7 @@ describe "Taggable" do
|
|
221
231
|
bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby")
|
222
232
|
frank = TaggableModel.create(:name => "Frank", :tag_list => "Ruby")
|
223
233
|
|
224
|
-
ActsAsTaggableOn::Tag.
|
234
|
+
ActsAsTaggableOn::Tag.all.size.should == 1
|
225
235
|
TaggableModel.tagged_with("ruby").to_a.should == TaggableModel.tagged_with("Ruby").to_a
|
226
236
|
end
|
227
237
|
|
@@ -229,8 +239,8 @@ describe "Taggable" do
|
|
229
239
|
bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
|
230
240
|
frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
|
231
241
|
charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby")
|
232
|
-
TaggableModel.tag_counts.
|
233
|
-
TaggableModel.skill_counts.
|
242
|
+
TaggableModel.tag_counts.should_not be_empty
|
243
|
+
TaggableModel.skill_counts.should_not be_empty
|
234
244
|
end
|
235
245
|
|
236
246
|
it "should be able to get all tag counts on model as whole" do
|
@@ -238,10 +248,19 @@ describe "Taggable" do
|
|
238
248
|
frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
|
239
249
|
charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby")
|
240
250
|
|
241
|
-
TaggableModel.all_tag_counts.
|
251
|
+
TaggableModel.all_tag_counts.should_not be_empty
|
242
252
|
TaggableModel.all_tag_counts(:order => 'tags.id').first.count.should == 3 # ruby
|
243
253
|
end
|
244
254
|
|
255
|
+
it "should be able to get all tags on model as whole" do
|
256
|
+
bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
|
257
|
+
frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
|
258
|
+
charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby")
|
259
|
+
|
260
|
+
TaggableModel.all_tags.should_not be_empty
|
261
|
+
TaggableModel.all_tags(:order => 'tags.id').first.name.should == "ruby"
|
262
|
+
end
|
263
|
+
|
245
264
|
it "should be able to use named scopes to chain tag finds by any tags by context" do
|
246
265
|
bob = TaggableModel.create(:name => "Bob", :need_list => "rails", :offering_list => "c++")
|
247
266
|
frank = TaggableModel.create(:name => "Frank", :need_list => "css", :offering_list => "css")
|
@@ -273,6 +292,14 @@ describe "Taggable" do
|
|
273
292
|
TaggableModel.tagged_with("ruby").all_tag_counts(:order => 'tags.id').first.count.should == 3 # ruby
|
274
293
|
end
|
275
294
|
|
295
|
+
it "should be able to get all scoped tags" do
|
296
|
+
bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
|
297
|
+
frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
|
298
|
+
charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby")
|
299
|
+
|
300
|
+
TaggableModel.tagged_with("ruby").all_tags(:order => 'tags.id').first.name.should == "ruby"
|
301
|
+
end
|
302
|
+
|
276
303
|
it 'should only return tag counts for the available scope' do
|
277
304
|
bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
|
278
305
|
frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
|
@@ -283,9 +310,24 @@ describe "Taggable" do
|
|
283
310
|
|
284
311
|
# Test specific join syntaxes:
|
285
312
|
frank.untaggable_models.create!
|
286
|
-
TaggableModel.tagged_with('rails').
|
287
|
-
TaggableModel.tagged_with('rails').
|
288
|
-
TaggableModel.tagged_with('rails').
|
313
|
+
TaggableModel.tagged_with('rails').joins(:untaggable_models).all_tag_counts.should have(2).items
|
314
|
+
TaggableModel.tagged_with('rails').joins(:untaggable_models => :taggable_model).all_tag_counts.should have(2).items
|
315
|
+
TaggableModel.tagged_with('rails').joins([:untaggable_models]).all_tag_counts.should have(2).items
|
316
|
+
end
|
317
|
+
|
318
|
+
it 'should only return tags for the available scope' do
|
319
|
+
bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
|
320
|
+
frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
|
321
|
+
charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby, java")
|
322
|
+
|
323
|
+
TaggableModel.tagged_with('rails').all_tags.should have(3).items
|
324
|
+
TaggableModel.tagged_with('rails').all_tags.any? { |tag| tag.name == 'java' }.should be_false
|
325
|
+
|
326
|
+
# Test specific join syntaxes:
|
327
|
+
frank.untaggable_models.create!
|
328
|
+
TaggableModel.tagged_with('rails').joins(:untaggable_models).all_tags.should have(2).items
|
329
|
+
TaggableModel.tagged_with('rails').joins({ :untaggable_models => :taggable_model }).all_tags.should have(2).items
|
330
|
+
TaggableModel.tagged_with('rails').joins([:untaggable_models]).all_tags.should have(2).items
|
289
331
|
end
|
290
332
|
|
291
333
|
it "should be able to set a custom tag context list" do
|
@@ -419,54 +461,6 @@ describe "Taggable" do
|
|
419
461
|
end
|
420
462
|
end
|
421
463
|
|
422
|
-
describe "Single Table Inheritance" do
|
423
|
-
before do
|
424
|
-
@taggable = TaggableModel.new(:name => "taggable")
|
425
|
-
@inherited_same = InheritingTaggableModel.new(:name => "inherited same")
|
426
|
-
@inherited_different = AlteredInheritingTaggableModel.new(:name => "inherited different")
|
427
|
-
end
|
428
|
-
|
429
|
-
it "should be able to save tags for inherited models" do
|
430
|
-
@inherited_same.tag_list = "bob, kelso"
|
431
|
-
@inherited_same.save
|
432
|
-
InheritingTaggableModel.tagged_with("bob").first.should == @inherited_same
|
433
|
-
end
|
434
|
-
|
435
|
-
it "should find STI tagged models on the superclass" do
|
436
|
-
@inherited_same.tag_list = "bob, kelso"
|
437
|
-
@inherited_same.save
|
438
|
-
TaggableModel.tagged_with("bob").first.should == @inherited_same
|
439
|
-
end
|
440
|
-
|
441
|
-
it "should be able to add on contexts only to some subclasses" do
|
442
|
-
@inherited_different.part_list = "fork, spoon"
|
443
|
-
@inherited_different.save
|
444
|
-
InheritingTaggableModel.tagged_with("fork", :on => :parts).should be_empty
|
445
|
-
AlteredInheritingTaggableModel.tagged_with("fork", :on => :parts).first.should == @inherited_different
|
446
|
-
end
|
447
|
-
|
448
|
-
it "should have different tag_counts_on for inherited models" do
|
449
|
-
@inherited_same.tag_list = "bob, kelso"
|
450
|
-
@inherited_same.save!
|
451
|
-
@inherited_different.tag_list = "fork, spoon"
|
452
|
-
@inherited_different.save!
|
453
|
-
|
454
|
-
InheritingTaggableModel.tag_counts_on(:tags, :order => 'tags.id').map(&:name).should == %w(bob kelso)
|
455
|
-
AlteredInheritingTaggableModel.tag_counts_on(:tags, :order => 'tags.id').map(&:name).should == %w(fork spoon)
|
456
|
-
TaggableModel.tag_counts_on(:tags, :order => 'tags.id').map(&:name).should == %w(bob kelso fork spoon)
|
457
|
-
end
|
458
|
-
|
459
|
-
it 'should store same tag without validation conflict' do
|
460
|
-
@taggable.tag_list = 'one'
|
461
|
-
@taggable.save!
|
462
|
-
|
463
|
-
@inherited_same.tag_list = 'one'
|
464
|
-
@inherited_same.save!
|
465
|
-
|
466
|
-
@inherited_same.update_attributes! :name => 'foo'
|
467
|
-
end
|
468
|
-
end
|
469
|
-
|
470
464
|
describe "NonStandardIdTaggable" do
|
471
465
|
before(:each) do
|
472
466
|
clean_database!
|
@@ -483,7 +477,7 @@ describe "Taggable" do
|
|
483
477
|
end
|
484
478
|
|
485
479
|
it "should have tag_counts_on" do
|
486
|
-
NonStandardIdTaggableModel.tag_counts_on(:tags).
|
480
|
+
NonStandardIdTaggableModel.tag_counts_on(:tags).should be_empty
|
487
481
|
|
488
482
|
@taggable.tag_list = ["awesome", "epic"]
|
489
483
|
@taggable.save
|
@@ -492,6 +486,16 @@ describe "Taggable" do
|
|
492
486
|
@taggable.tag_counts_on(:tags).length.should == 2
|
493
487
|
end
|
494
488
|
|
489
|
+
it "should have tags_on" do
|
490
|
+
NonStandardIdTaggableModel.tags_on(:tags).should be_empty
|
491
|
+
|
492
|
+
@taggable.tag_list = ["awesome", "epic"]
|
493
|
+
@taggable.save
|
494
|
+
|
495
|
+
NonStandardIdTaggableModel.tags_on(:tags).length.should == 2
|
496
|
+
@taggable.tags_on(:tags).length.should == 2
|
497
|
+
end
|
498
|
+
|
495
499
|
it "should be able to create tags" do
|
496
500
|
@taggable.skill_list = "ruby, rails, css"
|
497
501
|
@taggable.instance_variable_get("@skill_list").instance_of?(ActsAsTaggableOn::TagList).should be_true
|
@@ -518,24 +522,100 @@ describe "Taggable" do
|
|
518
522
|
end
|
519
523
|
|
520
524
|
describe "Dirty Objects" do
|
521
|
-
|
522
|
-
|
525
|
+
context "with un-contexted tags" do
|
526
|
+
before(:each) do
|
527
|
+
@taggable = TaggableModel.create(:tag_list => "awesome, epic")
|
528
|
+
end
|
529
|
+
|
530
|
+
context "when tag_list changed" do
|
531
|
+
before(:each) do
|
532
|
+
@taggable.changes.should == {}
|
533
|
+
@taggable.tag_list = 'one'
|
534
|
+
end
|
535
|
+
|
536
|
+
it 'should show changes of dirty object' do
|
537
|
+
@taggable.changes.should == {"tag_list"=>["awesome, epic", ["one"]]}
|
538
|
+
end
|
539
|
+
|
540
|
+
it 'flags tag_list as changed' do
|
541
|
+
@taggable.tag_list_changed?.should be_true
|
542
|
+
end
|
543
|
+
|
544
|
+
it 'preserves original value' do
|
545
|
+
@taggable.tag_list_was.should == "awesome, epic"
|
546
|
+
end
|
547
|
+
|
548
|
+
it 'shows what the change was' do
|
549
|
+
@taggable.tag_list_change.should == ["awesome, epic", ["one"]]
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
context 'when tag_list is the same' do
|
554
|
+
before(:each) do
|
555
|
+
@taggable.tag_list = "awesome, epic"
|
556
|
+
end
|
557
|
+
|
558
|
+
it 'is not flagged as changed' do
|
559
|
+
@taggable.tag_list_changed?.should be_false
|
560
|
+
end
|
561
|
+
|
562
|
+
it 'does not show any changes to the taggable item' do
|
563
|
+
@taggable.changes.should == {}
|
564
|
+
end
|
565
|
+
end
|
523
566
|
end
|
524
567
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
568
|
+
context "with context tags" do
|
569
|
+
before(:each) do
|
570
|
+
@taggable = TaggableModel.create(:language_list => "awesome, epic")
|
571
|
+
end
|
572
|
+
|
573
|
+
context "when language_list changed" do
|
574
|
+
before(:each) do
|
575
|
+
@taggable.changes.should == {}
|
576
|
+
@taggable.language_list = 'one'
|
577
|
+
end
|
578
|
+
|
579
|
+
it 'should show changes of dirty object' do
|
580
|
+
@taggable.changes.should == {"language_list"=>["awesome, epic", ["one"]]}
|
581
|
+
end
|
582
|
+
|
583
|
+
it 'flags language_list as changed' do
|
584
|
+
@taggable.language_list_changed?.should be_true
|
585
|
+
end
|
586
|
+
|
587
|
+
it 'preserves original value' do
|
588
|
+
@taggable.language_list_was.should == "awesome, epic"
|
589
|
+
end
|
590
|
+
|
591
|
+
it 'shows what the change was' do
|
592
|
+
@taggable.language_list_change.should == ["awesome, epic", ["one"]]
|
593
|
+
end
|
529
594
|
|
530
|
-
|
531
|
-
|
532
|
-
|
595
|
+
it 'shows what the changes were' do
|
596
|
+
@taggable.language_list_changes.should == ["awesome, epic", ["one"]]
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
context 'when language_list is the same' do
|
601
|
+
before(:each) do
|
602
|
+
@taggable.language_list = "awesome, epic"
|
603
|
+
end
|
604
|
+
|
605
|
+
it 'is not flagged as changed' do
|
606
|
+
@taggable.language_list_changed?.should be_false
|
607
|
+
end
|
608
|
+
|
609
|
+
it 'does not show any changes to the taggable item' do
|
610
|
+
@taggable.changes.should == {}
|
611
|
+
end
|
612
|
+
end
|
533
613
|
end
|
614
|
+
end
|
534
615
|
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
@taggable.changes.should == {}
|
616
|
+
describe "Autogenerated methods" do
|
617
|
+
it "should be overridable" do
|
618
|
+
TaggableModel.create(:tag_list=>'woo').tag_list_submethod_called.should be_true
|
539
619
|
end
|
540
620
|
end
|
541
621
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "Tagger" do
|
4
4
|
before(:each) do
|
5
5
|
clean_database!
|
6
|
-
@user =
|
6
|
+
@user = User.create
|
7
7
|
@taggable = TaggableModel.create(:name => "Bob Jones")
|
8
8
|
end
|
9
9
|
|
@@ -21,18 +21,43 @@ describe "Tagger" do
|
|
21
21
|
@taggable2 = TaggableModel.create(:name => "Jim Jones")
|
22
22
|
@taggable3 = TaggableModel.create(:name => "Jane Doe")
|
23
23
|
|
24
|
-
@user2 =
|
24
|
+
@user2 = User.new
|
25
25
|
@user.tag(@taggable, :with => 'ruby, scheme', :on => :tags)
|
26
26
|
@user2.tag(@taggable2, :with => 'ruby, scheme', :on => :tags)
|
27
27
|
@user2.tag(@taggable3, :with => 'ruby, scheme', :on => :tags)
|
28
28
|
|
29
29
|
TaggableModel.tagged_with(%w(ruby scheme), :owned_by => @user).count.should == 1
|
30
30
|
TaggableModel.tagged_with(%w(ruby scheme), :owned_by => @user2).count.should == 2
|
31
|
+
end
|
32
|
+
|
33
|
+
it "only returns objects tagged by owned_by when any is true" do
|
34
|
+
@user2 = User.new
|
35
|
+
@taggable2 = TaggableModel.create(:name => "Jim Jones")
|
36
|
+
@taggable3 = TaggableModel.create(:name => "Jane Doe")
|
31
37
|
|
38
|
+
@user.tag(@taggable, :with => 'ruby', :on => :tags)
|
39
|
+
@user.tag(@taggable2, :with => 'java', :on => :tags)
|
40
|
+
@user2.tag(@taggable3, :with => 'ruby', :on => :tags)
|
41
|
+
|
42
|
+
tags = TaggableModel.tagged_with(%w(ruby java), :owned_by => @user, :any => true)
|
43
|
+
tags.should match_array [@taggable, @taggable2]
|
44
|
+
end
|
45
|
+
|
46
|
+
it "only returns objects tagged by owned_by when exclude is true" do
|
47
|
+
@user2 = User.new
|
48
|
+
@taggable2 = TaggableModel.create(:name => "Jim Jones")
|
49
|
+
@taggable3 = TaggableModel.create(:name => "Jane Doe")
|
50
|
+
|
51
|
+
@user.tag(@taggable, :with => 'ruby', :on => :tags)
|
52
|
+
@user.tag(@taggable2, :with => 'java', :on => :tags)
|
53
|
+
@user2.tag(@taggable3, :with => 'java', :on => :tags)
|
54
|
+
|
55
|
+
tags = TaggableModel.tagged_with(%w(ruby), :owned_by => @user, :exclude => true)
|
56
|
+
tags.should match_array [@taggable2]
|
32
57
|
end
|
33
58
|
|
34
59
|
it "should not overlap tags from different taggers" do
|
35
|
-
@user2 =
|
60
|
+
@user2 = User.new
|
36
61
|
lambda{
|
37
62
|
@user.tag(@taggable, :with => 'ruby, scheme', :on => :tags)
|
38
63
|
@user2.tag(@taggable, :with => 'java, python, lisp, ruby', :on => :tags)
|
@@ -51,7 +76,7 @@ describe "Tagger" do
|
|
51
76
|
end
|
52
77
|
|
53
78
|
it "should not lose tags from different taggers" do
|
54
|
-
@user2 =
|
79
|
+
@user2 = User.create
|
55
80
|
@user2.tag(@taggable, :with => 'java, python, lisp, ruby', :on => :tags)
|
56
81
|
@user.tag(@taggable, :with => 'ruby, scheme', :on => :tags)
|
57
82
|
|
@@ -69,7 +94,7 @@ describe "Tagger" do
|
|
69
94
|
end
|
70
95
|
|
71
96
|
it "should not lose tags" do
|
72
|
-
@user2 =
|
97
|
+
@user2 = User.create
|
73
98
|
|
74
99
|
@user.tag(@taggable, :with => 'awesome', :on => :tags)
|
75
100
|
@user2.tag(@taggable, :with => 'awesome, epic', :on => :tags)
|
@@ -109,30 +134,4 @@ describe "Tagger" do
|
|
109
134
|
}.should_not change(ActsAsTaggableOn::Tagging, :count)
|
110
135
|
end
|
111
136
|
|
112
|
-
|
113
|
-
before do
|
114
|
-
@user3 = InheritingTaggableUser.create
|
115
|
-
end
|
116
|
-
|
117
|
-
it "should have taggings" do
|
118
|
-
@user3.tag(@taggable, :with=>'ruby,scheme', :on=>:tags)
|
119
|
-
@user3.owned_taggings.size == 2
|
120
|
-
end
|
121
|
-
|
122
|
-
it "should have tags" do
|
123
|
-
@user3.tag(@taggable, :with=>'ruby,scheme', :on=>:tags)
|
124
|
-
@user3.owned_tags.size == 2
|
125
|
-
end
|
126
|
-
|
127
|
-
it "should return tags for the inheriting tagger" do
|
128
|
-
@user3.tag(@taggable, :with => 'ruby, scheme', :on => :tags)
|
129
|
-
@taggable.tags_from(@user3).sort.should == %w(ruby scheme).sort
|
130
|
-
end
|
131
|
-
|
132
|
-
it "should scope objects returned by tagged_with by owners" do
|
133
|
-
@user3.tag(@taggable, :with => 'ruby, scheme', :on => :tags)
|
134
|
-
TaggableModel.tagged_with(%w(ruby scheme), :owned_by => @user3).count.should == 1
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
end
|
137
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ActsAsTaggableOn::TagsHelper do
|
4
4
|
before(:each) do
|
@@ -41,4 +41,4 @@ describe ActsAsTaggableOn::TagsHelper do
|
|
41
41
|
tags["c++"].should == "sucky"
|
42
42
|
tags["php"].should == "sucky"
|
43
43
|
end
|
44
|
-
end
|
44
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe ActsAsTaggableOn::Utils do
|
4
4
|
describe "like_operator" do
|
@@ -18,4 +18,4 @@ describe ActsAsTaggableOn::Utils do
|
|
18
18
|
TaggableModel.send(:like_operator).should == "LIKE"
|
19
19
|
end
|
20
20
|
end
|
21
|
-
end
|
21
|
+
end
|
data/spec/models.rb
CHANGED
@@ -4,6 +4,12 @@ class TaggableModel < ActiveRecord::Base
|
|
4
4
|
acts_as_taggable_on :skills
|
5
5
|
acts_as_taggable_on :needs, :offerings
|
6
6
|
has_many :untaggable_models
|
7
|
+
|
8
|
+
attr_reader :tag_list_submethod_called
|
9
|
+
def tag_list=v
|
10
|
+
@tag_list_submethod_called = true
|
11
|
+
super
|
12
|
+
end
|
7
13
|
end
|
8
14
|
|
9
15
|
class CachedModel < ActiveRecord::Base
|
@@ -26,11 +32,11 @@ class AlteredInheritingTaggableModel < TaggableModel
|
|
26
32
|
acts_as_taggable_on :parts
|
27
33
|
end
|
28
34
|
|
29
|
-
class
|
35
|
+
class User < ActiveRecord::Base
|
30
36
|
acts_as_tagger
|
31
37
|
end
|
32
38
|
|
33
|
-
class
|
39
|
+
class Student < User
|
34
40
|
end
|
35
41
|
|
36
42
|
class UntaggableModel < ActiveRecord::Base
|
data/spec/schema.rb
CHANGED