bbenezech-acts-as-taggable-on 0.0.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.
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "Group Helper" do
4
+
5
+ describe "grouped_column_names_for method" do
6
+ before(:each) do
7
+ @taggable = TaggableModel.new(:name => "Bob Jones")
8
+ end
9
+
10
+ it "should return all column names joined for Tag GROUP clause" do
11
+ @taggable.grouped_column_names_for(Tag).should == "#{Tag.table_name}.id, #{Tag.table_name}.name"
12
+ end
13
+
14
+ it "should return all column names joined for TaggableModel GROUP clause" do
15
+ @taggable.grouped_column_names_for(TaggableModel).should == "taggable_models.id, taggable_models.name, taggable_models.type"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,64 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe TagList do
4
+ before(:each) do
5
+ @tag_list = TagList.new("awesome","radical")
6
+ end
7
+
8
+ it "should be an array" do
9
+ @tag_list.is_a?(Array).should be_true
10
+ end
11
+
12
+ it "should be able to be add a new tag word" do
13
+ @tag_list.add("cool")
14
+ @tag_list.include?("cool").should be_true
15
+ end
16
+
17
+ it "should be able to add delimited lists of words" do
18
+ @tag_list.add("cool, wicked", :parse => true)
19
+ @tag_list.include?("cool").should be_true
20
+ @tag_list.include?("wicked").should be_true
21
+ end
22
+
23
+ it "should be able to add delimited list of words with quoted delimiters" do
24
+ @tag_list.add("'cool, wicked', \"really cool, really wicked\"", :parse => true)
25
+ @tag_list.include?("cool, wicked").should be_true
26
+ @tag_list.include?("really cool, really wicked").should be_true
27
+ end
28
+
29
+ it "should be able to handle other uses of quotation marks correctly" do
30
+ @tag_list.add("john's cool car, mary's wicked toy", :parse => true)
31
+ @tag_list.include?("john's cool car").should be_true
32
+ @tag_list.include?("mary's wicked toy").should be_true
33
+ end
34
+
35
+ it "should be able to add an array of words" do
36
+ @tag_list.add(["cool", "wicked"], :parse => true)
37
+ @tag_list.include?("cool").should be_true
38
+ @tag_list.include?("wicked").should be_true
39
+ end
40
+
41
+ it "should be able to remove words" do
42
+ @tag_list.remove("awesome")
43
+ @tag_list.include?("awesome").should be_false
44
+ end
45
+
46
+ it "should be able to remove delimited lists of words" do
47
+ @tag_list.remove("awesome, radical", :parse => true)
48
+ @tag_list.should be_empty
49
+ end
50
+
51
+ it "should be able to remove an array of words" do
52
+ @tag_list.remove(["awesome", "radical"], :parse => true)
53
+ @tag_list.should be_empty
54
+ end
55
+
56
+ it "should give a delimited list of words when converted to string" do
57
+ @tag_list.to_s.should == "awesome, radical"
58
+ end
59
+
60
+ it "should quote escape tags with commas in them" do
61
+ @tag_list.add("cool","rad,bodacious")
62
+ @tag_list.to_s.should == "awesome, radical, cool, \"rad,bodacious\""
63
+ end
64
+ end
@@ -0,0 +1,73 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Tag do
4
+ before(:each) do
5
+ @tag = Tag.new
6
+ @user = TaggableModel.create(:name => "Pablo")
7
+ Tag.delete_all
8
+ end
9
+
10
+ describe "named like any" do
11
+ before(:each) do
12
+ Tag.create(:name => "awesome")
13
+ Tag.create(:name => "epic")
14
+ end
15
+
16
+ it "should find both tags" do
17
+ Tag.named_like_any(["awesome", "epic"]).should have(2).items
18
+ end
19
+ end
20
+
21
+ describe "find or create by name" do
22
+ before(:each) do
23
+ @tag.name = "awesome"
24
+ @tag.save
25
+ end
26
+
27
+ it "should find by name" do
28
+ Tag.find_or_create_with_like_by_name("awesome").should == @tag
29
+ end
30
+
31
+ it "should find by name case insensitive" do
32
+ Tag.find_or_create_with_like_by_name("AWESOME").should == @tag
33
+ end
34
+
35
+ it "should create by name" do
36
+ lambda {
37
+ Tag.find_or_create_with_like_by_name("epic")
38
+ }.should change(Tag, :count).by(1)
39
+ end
40
+ end
41
+
42
+ it "should require a name" do
43
+ @tag.valid?
44
+ @tag.errors.on(:name).should == "can't be blank"
45
+ @tag.name = "something"
46
+ @tag.valid?
47
+ @tag.errors.on(:name).should be_nil
48
+ end
49
+
50
+ it "should equal a tag with the same name" do
51
+ @tag.name = "awesome"
52
+ new_tag = Tag.new(:name => "awesome")
53
+ new_tag.should == @tag
54
+ end
55
+
56
+ it "should return its name when to_s is called" do
57
+ @tag.name = "cool"
58
+ @tag.to_s.should == "cool"
59
+ end
60
+
61
+ it "have named_scope named(something)" do
62
+ @tag.name = "cool"
63
+ @tag.save!
64
+ Tag.named('cool').should include(@tag)
65
+ end
66
+
67
+ it "have named_scope named_like(something)" do
68
+ @tag.name = "cool"
69
+ @tag.save!
70
+ @another_tag = Tag.create!(:name => "coolip")
71
+ Tag.named_like('cool').should include(@tag, @another_tag)
72
+ end
73
+ end
@@ -0,0 +1,252 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "Taggable" do
4
+ before(:each) do
5
+ [TaggableModel, Tag, Tagging, TaggableUser].each(&:delete_all)
6
+ @taggable = TaggableModel.new(:name => "Bob Jones")
7
+ end
8
+
9
+ it "should have tag types" do
10
+ TaggableModel.tag_types.should == [:tags, :languages, :skills, :needs, :offerings]
11
+ @taggable.tag_types.should == TaggableModel.tag_types
12
+ end
13
+
14
+ it "should have tag_counts_on" do
15
+ TaggableModel.tag_counts_on(:tags).should be_empty
16
+
17
+ @taggable.tag_list = ["awesome", "epic"]
18
+ @taggable.save
19
+
20
+ TaggableModel.tag_counts_on(:tags).count.should == 2
21
+ @taggable.tag_counts_on(:tags).count.should == 2
22
+ end
23
+
24
+ it "should be able to create tags" do
25
+ @taggable.skill_list = "ruby, rails, css"
26
+ @taggable.instance_variable_get("@skill_list").instance_of?(TagList).should be_true
27
+ @taggable.save
28
+
29
+ Tag.find(:all).size.should == 3
30
+ end
31
+
32
+ it "should be able to create tags through the tag list directly" do
33
+ @taggable.tag_list_on(:test).add("hello")
34
+ @taggable.save
35
+ @taggable.reload
36
+ @taggable.tag_list_on(:test).should == ["hello"]
37
+ end
38
+
39
+ it "should differentiate between contexts" do
40
+ @taggable.skill_list = "ruby, rails, css"
41
+ @taggable.tag_list = "ruby, bob, charlie"
42
+ @taggable.save
43
+ @taggable.reload
44
+ @taggable.skill_list.include?("ruby").should be_true
45
+ @taggable.skill_list.include?("bob").should be_false
46
+ end
47
+
48
+ it "should have ordered tags and reorder them" do
49
+ # decoy to show that scope on context is working
50
+ @taggable.tag_list = "ruby, rails, css"
51
+ @taggable2 = TaggableModel.new(:name => "Bob Jones2")
52
+
53
+ # decoy to show that scope on taggable is working
54
+ @taggable2.skill_list = "ruby, rails, css"
55
+ @taggable2.save
56
+
57
+ @taggable.skill_list = "ruby, rails, css"
58
+ @taggable.save
59
+ @taggable.reload
60
+ @taggable.skill_taggings.map(&:position).should == [1,2,3]
61
+ @taggable.skill_list.should == ["ruby", "rails", "css"]
62
+
63
+ @taggable.skill_list = "rails, ruby, css"
64
+ @taggable.save
65
+ @taggable.reload
66
+ @taggable.skill_list.should == ["rails", "ruby", "css"]
67
+
68
+ @taggable.skill_taggings.last.move_to_top
69
+ @taggable.reload
70
+
71
+ # tags should be fetched ordered when accessed from taggings
72
+ @taggable.skill_taggings.map(&:position).should == [1,2,3]
73
+ @taggable.skill_taggings.map{|tagging| tagging.tag.name }.should == ["css", "rails", "ruby"]
74
+ # when accessed from has_many :through association
75
+ @taggable.skills.map{|t| t.taggings.select{|tagging| tagging.taggable == @taggable }.first}.map(&:position).should == [1,2,3]
76
+ @taggable.skill_list.should == ["css", "rails", "ruby"]
77
+ end
78
+
79
+ it "should be able to remove tags through list alone" do
80
+ @taggable.skill_list = "ruby, rails, css"
81
+ @taggable.save
82
+ @taggable.reload
83
+ @taggable.should have(3).skills
84
+ @taggable.skill_list = "ruby, rails"
85
+ @taggable.save
86
+ @taggable.reload
87
+ @taggable.should have(2).skills
88
+ end
89
+
90
+ it "should be able to find by tag" do
91
+ @taggable.skill_list = "ruby, rails, css"
92
+ @taggable.save
93
+ TaggableModel.find_tagged_with("ruby").first.should == @taggable
94
+ end
95
+
96
+ it "should be able to find by tag with context" do
97
+ @taggable.skill_list = "ruby, rails, css"
98
+ @taggable.tag_list = "bob, charlie"
99
+ @taggable.save
100
+ TaggableModel.find_tagged_with("ruby").first.should == @taggable
101
+ TaggableModel.find_tagged_with("bob", :on => :skills).first.should_not == @taggable
102
+ TaggableModel.find_tagged_with("bob", :on => :tags).first.should == @taggable
103
+ end
104
+
105
+ it "should be able to use the tagged_with named scope" do
106
+ @taggable.skill_list = "ruby, rails, css"
107
+ @taggable.tag_list = "bob, charlie"
108
+ @taggable.save
109
+
110
+ TaggableModel.tagged_with("ruby").first.should == @taggable
111
+ TaggableModel.tagged_with("ruby, css").first.should == @taggable
112
+ TaggableModel.tagged_with("ruby, nonexistingtag").should be_empty
113
+ TaggableModel.tagged_with("bob", :on => :skills).first.should_not == @taggable
114
+ TaggableModel.tagged_with("bob", :on => :tags).first.should == @taggable
115
+ end
116
+
117
+ it "should not care about case" do
118
+ bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby")
119
+ frank = TaggableModel.create(:name => "Frank", :tag_list => "Ruby")
120
+
121
+ Tag.find(:all).size.should == 1
122
+ TaggableModel.find_tagged_with("ruby").should == TaggableModel.find_tagged_with("Ruby")
123
+ end
124
+
125
+ it "should be able to get tag counts on model as a whole" do
126
+ bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
127
+ frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
128
+ charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby")
129
+ TaggableModel.tag_counts.should_not be_empty
130
+ TaggableModel.skill_counts.should_not be_empty
131
+ end
132
+
133
+ it "should be able to get all tag counts on model as whole" do
134
+ bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
135
+ frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
136
+ charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby")
137
+
138
+ TaggableModel.all_tag_counts.should_not be_empty
139
+ TaggableModel.all_tag_counts.first.count.should == 3 # ruby
140
+ end
141
+
142
+ it "should be able to get scoped tag counts" do
143
+ bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
144
+ frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
145
+ charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby")
146
+
147
+ TaggableModel.tagged_with("ruby").tag_counts.first.count.should == 2 # ruby
148
+ TaggableModel.tagged_with("ruby").skill_counts.first.count.should == 1 # ruby
149
+ end
150
+
151
+ it "should be able to get all scoped tag counts" do
152
+ bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
153
+ frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
154
+ charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby")
155
+
156
+ TaggableModel.tagged_with("ruby").all_tag_counts.first.count.should == 3 # ruby
157
+ end
158
+
159
+ it "should be able to set a custom tag context list" do
160
+ bob = TaggableModel.create(:name => "Bob")
161
+ bob.set_tag_list_on(:rotors, "spinning, jumping")
162
+ bob.tag_list_on(:rotors).should == ["spinning","jumping"]
163
+ bob.save
164
+ bob.reload
165
+ bob.tags_on(:rotors).should_not be_empty
166
+ end
167
+
168
+ it "should be able to find tagged" do
169
+ bob = TaggableModel.create(:name => "Bob", :tag_list => "fitter, happier, more productive", :skill_list => "ruby, rails, css")
170
+ frank = TaggableModel.create(:name => "Frank", :tag_list => "weaker, depressed, inefficient", :skill_list => "ruby, rails, css")
171
+ steve = TaggableModel.create(:name => 'Steve', :tag_list => 'fitter, happier, more productive', :skill_list => 'c++, java, ruby')
172
+
173
+ TaggableModel.find_tagged_with("ruby", :order => 'taggable_models.name').should == [bob, frank, steve]
174
+ TaggableModel.find_tagged_with("ruby, rails", :order => 'taggable_models.name').should == [bob, frank]
175
+ TaggableModel.find_tagged_with(["ruby", "rails"], :order => 'taggable_models.name').should == [bob, frank]
176
+ end
177
+
178
+ it "should be able to find tagged on a custom tag context" do
179
+ bob = TaggableModel.create(:name => "Bob")
180
+ bob.set_tag_list_on(:rotors, "spinning, jumping")
181
+ bob.tag_list_on(:rotors).should == ["spinning","jumping"]
182
+ bob.save
183
+ TaggableModel.find_tagged_with("spinning", :on => :rotors).should == [bob]
184
+ end
185
+
186
+ it "should be able to use named scopes to chain tag finds" do
187
+ bob = TaggableModel.create(:name => "Bob", :tag_list => "fitter, happier, more productive", :skill_list => "ruby, rails, css")
188
+ frank = TaggableModel.create(:name => "Frank", :tag_list => "weaker, depressed, inefficient", :skill_list => "ruby, rails, css")
189
+ steve = TaggableModel.create(:name => 'Steve', :tag_list => 'fitter, happier, more productive', :skill_list => 'c++, java, python')
190
+
191
+ # Let's only find those productive Rails developers
192
+ TaggableModel.tagged_with('rails', :on => :skills, :order => 'taggable_models.name').should == [bob, frank]
193
+ TaggableModel.tagged_with('happier', :on => :tags, :order => 'taggable_models.name').should == [bob, steve]
194
+ TaggableModel.tagged_with('rails', :on => :skills).tagged_with('happier', :on => :tags).should == [bob]
195
+ TaggableModel.tagged_with('rails').tagged_with('happier', :on => :tags).should == [bob]
196
+ end
197
+
198
+ it "should be able to find tagged with only the matching tags" do
199
+ bob = TaggableModel.create(:name => "Bob", :tag_list => "lazy, happier")
200
+ frank = TaggableModel.create(:name => "Frank", :tag_list => "fitter, happier, inefficient")
201
+ steve = TaggableModel.create(:name => 'Steve', :tag_list => "fitter, happier")
202
+
203
+ TaggableModel.find_tagged_with("fitter, happier", :match_all => true).should == [steve]
204
+ end
205
+
206
+ it "should be able to find tagged with some excluded tags" do
207
+ bob = TaggableModel.create(:name => "Bob", :tag_list => "happier, lazy")
208
+ frank = TaggableModel.create(:name => "Frank", :tag_list => "happier")
209
+ steve = TaggableModel.create(:name => 'Steve', :tag_list => "happier")
210
+
211
+ TaggableModel.find_tagged_with("lazy", :exclude => true).should == [frank, steve]
212
+ end
213
+
214
+ describe "Single Table Inheritance" do
215
+ before do
216
+ [TaggableModel, Tag, Tagging, TaggableUser].each(&:delete_all)
217
+ @taggable = TaggableModel.new(:name => "taggable")
218
+ @inherited_same = InheritingTaggableModel.new(:name => "inherited same")
219
+ @inherited_different = AlteredInheritingTaggableModel.new(:name => "inherited different")
220
+ end
221
+
222
+ it "should be able to save tags for inherited models" do
223
+ @inherited_same.tag_list = "bob, kelso"
224
+ @inherited_same.save
225
+ InheritingTaggableModel.find_tagged_with("bob").first.should == @inherited_same
226
+ end
227
+
228
+ it "should find STI tagged models on the superclass" do
229
+ @inherited_same.tag_list = "bob, kelso"
230
+ @inherited_same.save
231
+ TaggableModel.find_tagged_with("bob").first.should == @inherited_same
232
+ end
233
+
234
+ it "should be able to add on contexts only to some subclasses" do
235
+ @inherited_different.part_list = "fork, spoon"
236
+ @inherited_different.save
237
+ InheritingTaggableModel.find_tagged_with("fork", :on => :parts).should be_empty
238
+ AlteredInheritingTaggableModel.find_tagged_with("fork", :on => :parts).first.should == @inherited_different
239
+ end
240
+
241
+ it "should have different tag_counts_on for inherited models" do
242
+ @inherited_same.tag_list = "bob, kelso"
243
+ @inherited_same.save!
244
+ @inherited_different.tag_list = "fork, spoon"
245
+ @inherited_different.save!
246
+
247
+ InheritingTaggableModel.tag_counts_on(:tags).map(&:name).should == %w(bob kelso)
248
+ AlteredInheritingTaggableModel.tag_counts_on(:tags).map(&:name).should == %w(fork spoon)
249
+ TaggableModel.tag_counts_on(:tags).map(&:name).should == %w(bob kelso fork spoon)
250
+ end
251
+ end
252
+ end
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "Tagger" do
4
+ before(:each) do
5
+ [TaggableModel, Tag, Tagging, TaggableUser].each(&:delete_all)
6
+ @user = TaggableUser.new
7
+ @taggable = TaggableModel.new(:name => "Bob Jones")
8
+ end
9
+
10
+ it "should have taggings" do
11
+ @user.tag(@taggable, :with=>'ruby,scheme', :on=>:tags)
12
+ @user.owned_taggings.size == 2
13
+ end
14
+
15
+ it "should have tags" do
16
+ @user.tag(@taggable, :with=>'ruby,scheme', :on=>:tags)
17
+ @user.owned_tags.size == 2
18
+ end
19
+
20
+ it "is tagger" do
21
+ @user.is_tagger?.should(be_true)
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Tagging do
4
+ before(:each) do
5
+ @tagging = Tagging.new
6
+ end
7
+
8
+ it "should not be valid with a invalid tag" do
9
+ @tagging.taggable = TaggableModel.create(:name => "Bob Jones")
10
+ @tagging.tag = Tag.new(:name => "")
11
+ @tagging.context = "tags"
12
+
13
+ @tagging.should_not be_valid
14
+ @tagging.errors.on(:tag_id).should == "can't be blank"
15
+ end
16
+
17
+ it "should not create duplicate taggings" do
18
+ @taggable = TaggableModel.create(:name => "Bob Jones")
19
+ @tag = Tag.create(:name => "awesome")
20
+
21
+ lambda {
22
+ 2.times { Tagging.create(:taggable => @taggable, :tag => @tag, :context => 'tags') }
23
+ }.should change(Tagging, :count).by(1)
24
+ end
25
+ end