acts_as_taggable 2.0.1 → 2.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.
- data/CHANGELOG +9 -0
- data/README +14 -0
- data/lib/taggable.rb +67 -8
- data/test/acts_as_taggable_test.rb +573 -375
- data/test/config.yml +10 -0
- data/test/config.yml.sample +6 -0
- data/test/debug.log +1 -0
- metadata +5 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
2.0.2
|
2
|
+
Updated README
|
3
|
+
First release with PostgreSQL compatability (Need feedback)
|
4
|
+
FEATURE: added tagged_with_all? tagged_with_any?
|
5
|
+
FEATURE: added :sort_list option to the tags_counts method - allows you to pass a Proc and get back an ordered list
|
6
|
+
FEATURE: Overhauled the Unit Test suite to make it easier to run
|
7
|
+
BUGFIX: Fixed escaping in find_related_tags
|
8
|
+
BUGFIX: Fixed problem with :limit and find_related_tags being off by 1
|
9
|
+
BUGFIX: Fixed table alias in find_related_tagged
|
1
10
|
2.0.1
|
2
11
|
FEATURE: Source code now available via Subversion
|
3
12
|
BUGFIX: Typo fix in find_related_tags
|
data/README
CHANGED
@@ -87,3 +87,17 @@ becomes
|
|
87
87
|
class Photo < ActiveRecord::Base
|
88
88
|
acts_as_taggable :join_table => "tags_photos"
|
89
89
|
end
|
90
|
+
|
91
|
+
== Testing
|
92
|
+
|
93
|
+
I'm currently working on overhauling the testing system. You now can point the plugin at a database of your choosing by copying config.yml.sample to the main directory and pointing it at a database that exists. I'll be working on making it easier to switch between MySQL & PostgreSQL to simplify testing.
|
94
|
+
|
95
|
+
The tests are still pretty weak. If you really want to help the project - submit tests that show how you are actually using the software so I can confirm that new versions don't break anything.
|
96
|
+
|
97
|
+
== Bugs/Patches
|
98
|
+
|
99
|
+
This plugin has a site at http://rubyforge.org/projects/taggable/. Please go there to submit patches or bug reports. This is also the best place to find the latest version of the software.
|
100
|
+
|
101
|
+
== Authors
|
102
|
+
|
103
|
+
Demetrius Nunes <demetriusnunes@ NoSPAM @gmail.com> is the original creator of acts_as_taggable (originally announced http://dema.ruby.com.br/articles/2005/08/27/easy-tagging-with-rails). He has since moved on to bigger and better things, but the project owes its existance to him. Since 2.0.0, acts_as_taggable has been maintained by Dirk Elmendorf (ruby@ NoSPAM @economysizegeek.com).
|
data/lib/taggable.rb
CHANGED
@@ -5,7 +5,7 @@ module ActiveRecord
|
|
5
5
|
module Acts #:nodoc:
|
6
6
|
module Taggable #:nodoc:
|
7
7
|
|
8
|
-
def self.append_features(base)
|
8
|
+
def self.append_features(base) #:nodoc:
|
9
9
|
super
|
10
10
|
base.extend(ClassMethods)
|
11
11
|
end
|
@@ -268,7 +268,11 @@ module ActiveRecord
|
|
268
268
|
sql << tag_names.collect {|tag| sanitize_sql( ["#{t}.#{tn} = ?",tag])}.join(" OR ")
|
269
269
|
sql << ")"
|
270
270
|
sql << " AND #{sanitize_sql(options[:conditions])}" if options[:conditions]
|
271
|
-
|
271
|
+
if postgresql?
|
272
|
+
sql << " GROUP BY #{model_columns_for_sql}"
|
273
|
+
else
|
274
|
+
sql << " GROUP BY #{o}.#{o_pk}"
|
275
|
+
end
|
272
276
|
sql << " HAVING COUNT(#{o}.#{o_pk}) = #{tag_names.length}" if options[:all]
|
273
277
|
sql << " ORDER BY #{options[:order]} " if options[:order]
|
274
278
|
add_limit!(sql, options)
|
@@ -313,6 +317,9 @@ module ActiveRecord
|
|
313
317
|
# WHERE clause of the SQL. Just like in regular +ActiveRecord::Base#find+ methods.
|
314
318
|
#
|
315
319
|
# +:order+: The same as used in +ActiveRecord::Base#find+ methods. By default, this is 'count DESC'.
|
320
|
+
# This should only be used if you want to modify the SQL - to have sorted result be returned use +:sort_list+:
|
321
|
+
#
|
322
|
+
# +:sort_list+: This is a proc that is used to return a sorted list instead of a hash
|
316
323
|
#
|
317
324
|
# +:count+: Adds a HAVING clause to the SQL statement, where you can set conditions for the 'count' column. For example: '> 50'
|
318
325
|
#
|
@@ -324,12 +331,18 @@ module ActiveRecord
|
|
324
331
|
sql = "SELECT #{t}.#{t_pk} AS id, #{t}.#{tn} AS name, COUNT(*) AS count FROM #{jt}, #{o}, #{t} WHERE #{jt}.#{t_fk} = #{t}.#{t_pk}
|
325
332
|
AND #{jt}.#{o_fk} = #{o}.#{o_pk}"
|
326
333
|
sql << " AND #{sanitize_sql(options[:conditions])}" if options[:conditions]
|
327
|
-
|
334
|
+
|
335
|
+
sql << " GROUP BY #{t}.#{t_pk},#{t}.#{tn}"
|
328
336
|
sql << " HAVING count #{options[:count]} " if options[:count]
|
329
337
|
sql << " ORDER BY #{options[:order]} " if options[:order]
|
330
338
|
add_limit!(sql, options)
|
331
339
|
result = connection.select_all(sql)
|
332
|
-
|
340
|
+
if !options[:raw]
|
341
|
+
count = result.inject({}) { |hsh, row| hsh[row["#{tn}"]] = row['count'].to_i; hsh }
|
342
|
+
if options[:sort_list] && options[:sort_list].is_a?(Proc)
|
343
|
+
count = options[:sort_list].call(count.keys.collect{|key| [key,count[key]]})
|
344
|
+
end
|
345
|
+
end
|
333
346
|
|
334
347
|
count || result
|
335
348
|
end
|
@@ -375,7 +388,7 @@ module ActiveRecord
|
|
375
388
|
AND jt2.#{o_fk} != jt.#{o_fk}
|
376
389
|
AND jt2.#{t_fk}=jt.#{t_fk} AND o.#{o_pk} = jt2.#{o_fk}"
|
377
390
|
sql << " AND #{sanitize_sql(options[:conditions])}" if options[:conditions]
|
378
|
-
sql << " GROUP BY
|
391
|
+
sql << " GROUP BY o.#{o_pk}"
|
379
392
|
sql << " ORDER BY count DESC"
|
380
393
|
add_limit!(sql, options)
|
381
394
|
|
@@ -397,11 +410,13 @@ module ActiveRecord
|
|
397
410
|
def find_related_tags(tags, options = {})
|
398
411
|
tag_names = ActiveRecord::Acts::Taggable.split_tag_names(tags, options[:separator], normalizer)
|
399
412
|
o, o_pk, o_fk, t, tn, t_pk, t_fk, jt = set_locals_for_sql
|
413
|
+
options[:limit] += 1 if options[:limit] # Compensates for the counting of the original argument
|
414
|
+
|
400
415
|
|
401
416
|
sql = "SELECT jt.#{o_fk} AS o_id FROM #{jt} jt, #{t} t
|
402
417
|
WHERE jt.#{t_fk} = t.#{t_pk} "
|
403
418
|
sql << " AND ( t.#{tn} IN ("
|
404
|
-
sql << tag_names
|
419
|
+
sql << quote_bound_value(tag_names)
|
405
420
|
sql << "))"
|
406
421
|
sql << "GROUP BY jt.#{o_fk}
|
407
422
|
HAVING COUNT(jt.#{o_fk})=#{tag_names.length}"
|
@@ -412,7 +427,7 @@ module ActiveRecord
|
|
412
427
|
sql = "SELECT t.#{t_pk} AS id, t.#{tn} AS #{tn}, COUNT(jt.#{o_fk}) AS count FROM #{jt} jt, #{t} t
|
413
428
|
WHERE jt.#{o_fk} IN (#{o_ids.join(",")})
|
414
429
|
AND t.#{t_pk} = jt.#{t_fk}
|
415
|
-
GROUP BY jt.#{t_fk}
|
430
|
+
GROUP BY t.#{t_pk},t.#{tn},jt.#{t_fk}
|
416
431
|
ORDER BY count DESC"
|
417
432
|
add_limit!(sql, options)
|
418
433
|
|
@@ -458,6 +473,18 @@ module ActiveRecord
|
|
458
473
|
end
|
459
474
|
|
460
475
|
private
|
476
|
+
def postgresql?
|
477
|
+
ActiveRecord::Base.connection.adapter_name == "PostgreSQL" ? true : false
|
478
|
+
end
|
479
|
+
def mysql?
|
480
|
+
ActiveRecord::Base.connection.adapter_name == "MySQL" ? true : false
|
481
|
+
end
|
482
|
+
def model_columns_for_sql
|
483
|
+
self.column_names.collect {|c| c = "#{table_name}.#{c}"}.join(',')
|
484
|
+
end
|
485
|
+
def tag_model_columns_for_sql
|
486
|
+
tag_model.column_names.collect {|c| c = "#{tag_model.table_name}.#{c}"}.join(',')
|
487
|
+
end
|
461
488
|
def set_locals_for_sql
|
462
489
|
[ table_name, primary_key, taggable_foreign_key,
|
463
490
|
tag_model.table_name, tag_model_name, tag_model.primary_key, tag_foreign_key,
|
@@ -469,7 +496,11 @@ module ActiveRecord
|
|
469
496
|
module InstanceMethods
|
470
497
|
# Handles clearing all associated tags
|
471
498
|
def clear_tags!
|
472
|
-
|
499
|
+
if tags_join_model
|
500
|
+
tag_collection.each {|x| x.destroy}
|
501
|
+
else
|
502
|
+
tag_collection.clear
|
503
|
+
end
|
473
504
|
end
|
474
505
|
# This method removes tags from the target object, by parsing the tags parameter
|
475
506
|
# into Tag object instances and removing them from the tag collection of the object if they exist.
|
@@ -573,6 +604,34 @@ module ActiveRecord
|
|
573
604
|
def tagged_with?(tag_name, reload = false)
|
574
605
|
tag_names(reload).include?(tag_name)
|
575
606
|
end
|
607
|
+
# Checks to see if this object has been tagged with all +tags+ - they can be a string,or list
|
608
|
+
# The +options+ hash has the following parameters:
|
609
|
+
# +:separator+ => defines the separator (String or Regex) used to split
|
610
|
+
# the tags parameter and defaults to ' ' (space and line breaks).
|
611
|
+
# +:reload+ => That forces the tag names to be reloaded first
|
612
|
+
def tagged_with_all?(tags, options = {})
|
613
|
+
options = { :separator => ' ', :reload => false }.merge(options)
|
614
|
+
requested= ActiveRecord::Acts::Taggable.split_tag_names(tags, options[:separator], normalizer)
|
615
|
+
tag_names(options[:reload]) if options[:reload]
|
616
|
+
requested.each {|tag_name|
|
617
|
+
return false if !tag_names.include?(tag_name)
|
618
|
+
}
|
619
|
+
return true
|
620
|
+
end
|
621
|
+
# Checks to see if this object has been tagged with any +tags+ - they can be a string,or list
|
622
|
+
# The +options+ hash has the following parameters:
|
623
|
+
# +:separator+ => defines the separator (String or Regex) used to split
|
624
|
+
# the tags parameter and defaults to ' ' (space and line breaks).
|
625
|
+
# +:reload+ => That forces the tag names to be reloaded first
|
626
|
+
def tagged_with_any?(tags, options = {})
|
627
|
+
options = { :separator => ' ', :reload => false }.merge(options)
|
628
|
+
requested= ActiveRecord::Acts::Taggable.split_tag_names(tags, options[:separator], normalizer)
|
629
|
+
tag_names(options[:reload]) if options[:reload]
|
630
|
+
requested.each {|tag_name|
|
631
|
+
return true if tag_names.include?(tag_name)
|
632
|
+
}
|
633
|
+
return false
|
634
|
+
end
|
576
635
|
|
577
636
|
# Calls +find_related_tagged+ passing +self+ as the +related+ parameter.
|
578
637
|
def tagged_related(options = {})
|
@@ -1,412 +1,610 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'yaml'
|
3
|
+
require_gem 'activerecord'
|
4
|
+
|
5
|
+
config = open("config.yml") { |f| YAML.load(f.read)}
|
6
|
+
|
7
|
+
ActiveRecord::Base.establish_connection(config["database"])
|
8
|
+
|
9
|
+
|
10
|
+
#AR_PATH = Gem::GemPathSearcher.new.find("active_record").full_gem_path
|
11
|
+
#$:.unshift("#{AR_PATH}/test")
|
12
|
+
#$:.unshift("#{AR_PATH}/test/connections/native_mysql")
|
4
13
|
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
5
14
|
|
6
|
-
require 'abstract_unit'
|
15
|
+
#require 'abstract_unit'
|
7
16
|
require 'taggable'
|
8
17
|
|
9
18
|
@@tag_table_column_name = :name
|
10
19
|
|
11
20
|
ActiveRecord::Base.connection.drop_table :tags rescue nil
|
12
21
|
ActiveRecord::Base.connection.drop_table :tags_topics rescue nil
|
13
|
-
ActiveRecord::Base.connection.drop_table :
|
14
|
-
ActiveRecord::Base.connection.drop_table :
|
15
|
-
ActiveRecord::Base.connection.drop_table :
|
22
|
+
ActiveRecord::Base.connection.drop_table :topics rescue nil
|
23
|
+
ActiveRecord::Base.connection.drop_table :people rescue nil
|
24
|
+
ActiveRecord::Base.connection.drop_table :tag_people rescue nil
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
ActiveRecord::Base.connection.create_table :topics do |t|
|
29
|
+
t.column :name, :string
|
30
|
+
end
|
16
31
|
|
17
32
|
ActiveRecord::Base.connection.create_table :tags do |t|
|
18
|
-
|
33
|
+
t.column @@tag_table_column_name , :string
|
19
34
|
end
|
20
35
|
|
21
36
|
ActiveRecord::Base.connection.create_table :tags_topics, :id => false do |t|
|
22
|
-
|
23
|
-
|
24
|
-
t.column :created_at, :time
|
37
|
+
t.column :tag_id, :integer
|
38
|
+
t.column :topic_id, :integer
|
25
39
|
end
|
26
40
|
|
27
|
-
ActiveRecord::Base.connection.create_table :
|
28
|
-
|
41
|
+
ActiveRecord::Base.connection.create_table :people do |t|
|
42
|
+
t.column :name, :string
|
43
|
+
t.column :email , :string
|
29
44
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
45
|
+
ActiveRecord::Base.connection.create_table :tag_people do |t|
|
46
|
+
t.column :tag_id, :integer
|
47
|
+
t.column :person_id, :integer
|
48
|
+
t.column :created_at, :datetime
|
49
|
+
t.column :created_by_id, :integer
|
50
|
+
t.column :position, :integer
|
34
51
|
end
|
35
52
|
|
36
|
-
ActiveRecord::Base
|
37
|
-
t.column :tag_id, :int
|
38
|
-
t.column :post_id, :int
|
39
|
-
t.column :created_at, :time
|
40
|
-
t.column :created_by_id, :int
|
41
|
-
t.column :position, :int
|
53
|
+
class Tag < ActiveRecord::Base
|
42
54
|
end
|
43
|
-
|
44
|
-
class Tag < ActiveRecord::Base; end
|
45
55
|
class Topic < ActiveRecord::Base
|
46
56
|
acts_as_taggable
|
47
57
|
end
|
48
58
|
|
49
|
-
class
|
50
|
-
|
51
|
-
|
52
|
-
acts_as_taggable :collection => :keywords, :tag_class_name => 'Keyword'
|
59
|
+
class TagPerson < ActiveRecord::Base
|
60
|
+
acts_as_list :scope => :person
|
61
|
+
belongs_to :created_by, :class_name => "Person", :foreign_key => 'created_by_id'
|
53
62
|
end
|
54
63
|
|
55
|
-
class
|
56
|
-
|
57
|
-
|
58
|
-
class Post < ActiveRecord::Base
|
59
|
-
acts_as_taggable :join_class_name => 'TagPost'
|
64
|
+
class Person < ActiveRecord::Base
|
65
|
+
acts_as_taggable :join_class_name => 'TagPerson'
|
60
66
|
end
|
61
67
|
|
62
|
-
class TagPost
|
63
|
-
acts_as_list :scope => :post
|
64
|
-
|
65
|
-
def before_save
|
66
|
-
self.created_by_id = rand(3) + 1
|
67
|
-
end
|
68
|
-
end
|
69
68
|
|
70
|
-
class Order < ActiveRecord::Base
|
71
|
-
end
|
72
69
|
|
73
70
|
class ActAsTaggableTest < Test::Unit::TestCase
|
74
|
-
fixtures :topics
|
75
|
-
|
76
|
-
def test_singleton_methods
|
77
|
-
assert !Order.respond_to?(:find_tagged_with)
|
78
|
-
assert Firm.respond_to?(:find_tagged_with)
|
79
|
-
assert Firm.respond_to?(:cloud)
|
80
|
-
assert Post.respond_to?(:find_tagged_with)
|
81
|
-
assert Post.respond_to?(:cloud)
|
82
|
-
assert Topic.respond_to?(:find_tagged_with)
|
83
|
-
assert Topic.respond_to?(:tag_count)
|
84
|
-
assert Topic.respond_to?(:tags_count)
|
85
|
-
assert Topic.respond_to?(:cloud)
|
86
|
-
end
|
87
|
-
|
88
|
-
def test_with_defaults
|
89
|
-
test_tagging(Topic.find(:first), Tag, :tags)
|
90
|
-
end
|
91
|
-
|
92
|
-
def test_with_non_defaults
|
93
|
-
test_tagging(Company.find(:first), Keyword, :keywords)
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_tag_with_new_object
|
97
|
-
topic = Topic.new
|
98
|
-
topic.tag 'brazil rio beach'
|
99
|
-
topic.save
|
100
|
-
end
|
101
|
-
|
102
|
-
def test_tagging_with_join_model
|
103
|
-
Tag.delete_all
|
104
|
-
TagPost.delete_all
|
105
|
-
post = Post.find(:first)
|
106
|
-
tags = %w(brazil rio beach)
|
107
|
-
|
108
|
-
post.tag(tags)
|
109
|
-
tags.each { |tag| assert post.tagged_with?(tag) }
|
110
|
-
|
111
|
-
post.save
|
112
|
-
post.tags.reload
|
113
|
-
tags.each { |tag| assert post.tagged_with?(tag) }
|
114
|
-
|
115
|
-
posts = Post.find_tagged_with(:any => 'brazil sampa moutain')
|
116
|
-
assert_equal posts[0], post
|
117
|
-
|
118
|
-
posts = Post.find_tagged_with(:all => 'brazil beach')
|
119
|
-
assert_equal posts[0], post
|
120
|
-
|
121
|
-
posts = Post.find_tagged_with(:all => 'brazil rich')
|
122
|
-
assert_equal 0, posts.size
|
123
|
-
|
124
|
-
posts = Post.find_tagged_with(:all => 'brazil', :conditions => [ 'tags_posts.position = ?', 1])
|
125
|
-
assert_equal posts[0], post
|
126
|
-
|
127
|
-
posts = Post.find_tagged_with(:all => 'rio', :conditions => [ 'tags_posts.position = ?', 2])
|
128
|
-
assert_equal posts[0], post
|
129
|
-
|
130
|
-
posts = Post.find_tagged_with(:all => 'beach', :conditions => [ 'tags_posts.position = ?', 3])
|
131
|
-
assert_equal posts[0], post
|
132
|
-
end
|
133
|
-
|
134
|
-
def test_tags_count_with_join_model
|
135
|
-
p1 = Post.create(:title => 'test1')
|
136
|
-
p2 = Post.create(:title => 'test2')
|
137
|
-
p3 = Post.create(:title => 'test3')
|
138
|
-
|
139
|
-
p1.tag 'a b c d'
|
140
|
-
p2.tag 'a c e f'
|
141
|
-
p3.tag 'a c f g'
|
142
|
-
|
143
|
-
counts = Post.tags_count :count => '>= 2', :limit => 2
|
144
|
-
assert_equal counts.keys.size, 2
|
145
|
-
counts.each { |tag, count| assert count >= 2 }
|
146
|
-
assert counts.keys.include?('a')
|
147
|
-
assert counts.keys.include?('c')
|
148
|
-
end
|
149
|
-
|
150
|
-
def test_tags_count
|
151
|
-
t1 = Topic.create(:title => 'test1')
|
152
|
-
t2 = Topic.create(:title => 'test2')
|
153
|
-
t3 = Topic.create(:title => 'test3')
|
154
|
-
|
155
|
-
t1.tag 'a b c d'
|
156
|
-
t2.tag 'a c e f'
|
157
|
-
t3.tag 'a c f g'
|
158
|
-
|
159
|
-
count = Topic.tags_count
|
160
|
-
assert_equal 3, count['a']
|
161
|
-
assert_equal 1, count['b']
|
162
|
-
assert_equal 3, count['c']
|
163
|
-
assert_equal 1, count['d']
|
164
|
-
assert_equal 1, count['e']
|
165
|
-
assert_equal 2, count['f']
|
166
|
-
assert_equal 1, count['g']
|
167
|
-
assert_equal nil, count['h']
|
168
|
-
|
169
|
-
count = Topic.tags_count :count => '>= 2'
|
170
|
-
assert_equal 3, count['a']
|
171
|
-
assert_equal nil, count['b']
|
172
|
-
assert_equal 3, count['c']
|
173
|
-
assert_equal nil, count['d']
|
174
|
-
assert_equal nil, count['e']
|
175
|
-
assert_equal 2, count['f']
|
176
|
-
assert_equal nil, count['g']
|
177
|
-
assert_equal nil, count['h']
|
178
|
-
|
179
|
-
t4 = Topic.create(:title => 'test4')
|
180
|
-
t4.tag 'a f'
|
181
|
-
|
182
|
-
count = Topic.tags_count :limit => 3
|
183
|
-
assert_equal 4, count['a']
|
184
|
-
assert_equal nil, count['b']
|
185
|
-
assert_equal 3, count['c']
|
186
|
-
assert_equal nil, count['d']
|
187
|
-
assert_equal nil, count['e']
|
188
|
-
assert_equal 3, count['f']
|
189
|
-
assert_equal nil, count['g']
|
190
|
-
assert_equal nil, count['h']
|
191
|
-
|
192
|
-
raw = Topic.tags_count :raw => true
|
193
|
-
assert_equal 7, raw.size
|
194
|
-
assert_equal Array, raw.class
|
195
|
-
assert_equal 'a', raw.first[@@tag_table_column_name.to_s]
|
196
|
-
assert_equal '4', raw.first['count']
|
197
|
-
assert_not_nil raw.first['id']
|
198
|
-
assert_equal 'g', raw.last[@@tag_table_column_name.to_s]
|
199
|
-
assert_equal '1', raw.last['count']
|
200
|
-
assert_not_nil raw.last['id']
|
201
|
-
end
|
202
|
-
|
203
|
-
def test_find_related_tagged
|
204
|
-
t1, t2, t3, t4, t5, t6 = create_test_topics
|
205
|
-
|
206
|
-
assert_equal [ t4, t2, t3 ], t1.tagged_related(:limit => 3)
|
207
|
-
assert_equal [ t5, t1, t3 ], t2.tagged_related(:limit => 3)
|
208
|
-
assert_equal [ t1, t4, t6 ], t3.tagged_related(:limit => 3)
|
209
|
-
assert_equal [ t1, t3, t6 ], t4.tagged_related(:limit => 3)
|
210
|
-
assert_equal [ t2, t1, t3 ], t5.tagged_related(:limit => 3)
|
211
|
-
assert_equal [ t1, t3, t4 ], t6.tagged_related(:limit => 3)
|
212
|
-
end
|
213
|
-
|
214
|
-
def test_find_related_tags
|
215
|
-
t1, t2, t3, t4, t5, t6 = create_test_topics
|
216
|
-
|
217
|
-
tags = Topic.find_related_tags('rome walking')
|
218
|
-
assert_equal 2, tags['greatview']
|
219
|
-
assert_equal 4, tags['clean']
|
220
|
-
assert_equal 2, tags['mustsee']
|
221
|
-
end
|
222
|
-
|
223
|
-
def test_find_tagged_with_on_subclasses
|
224
|
-
firm = Firm.find(:first)
|
225
|
-
firm.tag 'law'
|
226
|
-
firms = Firm.find_tagged_with :any => 'law'
|
227
|
-
assert_equal firm, firms[0]
|
228
|
-
assert_equal 1, firms.size
|
229
|
-
end
|
230
|
-
|
231
|
-
def test_find_tagged_with_any
|
232
|
-
topic1 = Topic.create(:title => 'test1')
|
233
|
-
topic2 = Topic.create(:title => 'test2')
|
234
|
-
topic3 = Topic.create(:title => 'test3')
|
235
|
-
|
236
|
-
topic1.tag('a b c'); topic1.save
|
237
|
-
topic2.tag('a c e'); topic2.save
|
238
|
-
topic3.tag('c d e'); topic3.save
|
239
|
-
|
240
|
-
topics = Topic.find_tagged_with(:any => 'x y z')
|
241
|
-
assert_equal 0, topics.size
|
242
|
-
|
243
|
-
topics = Topic.find_tagged_with(:any => 'a b c d e x y z')
|
244
|
-
assert_equal 3, topics.size
|
245
|
-
assert topics.include?(topic1)
|
246
|
-
assert topics.include?(topic2)
|
247
|
-
assert topics.include?(topic3)
|
248
|
-
|
249
|
-
topics = Topic.find_tagged_with(:any => 'a z')
|
250
|
-
assert_equal 2, topics.size
|
251
|
-
assert topics.include?(topic1)
|
252
|
-
assert topics.include?(topic2)
|
253
|
-
|
254
|
-
topics = Topic.find_tagged_with(:any => 'b')
|
255
|
-
assert_equal 1, topics.size
|
256
|
-
assert topics.include?(topic1)
|
257
|
-
|
258
|
-
topics = Topic.find_tagged_with(:any => 'c')
|
259
|
-
assert_equal 3, topics.size
|
260
|
-
assert topics.include?(topic1)
|
261
|
-
assert topics.include?(topic2)
|
262
|
-
assert topics.include?(topic3)
|
263
|
-
|
264
|
-
topics = Topic.find_tagged_with(:any => 'd')
|
265
|
-
assert_equal 1, topics.size
|
266
|
-
assert topics.include?(topic3)
|
267
71
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
72
|
+
#singleton commands = [:replace_tag, :find_related_tagged, :cloud ]
|
73
|
+
#class_commands = tag_names=, tagged_related,tags
|
74
|
+
def setup
|
75
|
+
Tag.delete_all
|
76
|
+
Topic.delete_all
|
77
|
+
Person.delete_all
|
78
|
+
TagPerson.delete_all
|
79
|
+
@topic= Topic.new(:name => "Plugin")
|
80
|
+
@topic.save
|
81
|
+
@first_person = Person.new(:name => "Mike User", :email => "mike@aol.com")
|
82
|
+
@first_person.save
|
83
|
+
@second_person = Person.new(:name => "Sally User", :email => "sally@aol.com")
|
84
|
+
@second_person.save
|
85
|
+
end
|
86
|
+
def test_simple_find_tagged_with
|
87
|
+
@topic.tag "Rails Ruby"
|
88
|
+
assert_equal [@topic], Topic.find_tagged_with(:any => "Rails")
|
89
|
+
assert_equal [@topic], Topic.find_tagged_with(:all => "Rails Ruby")
|
90
|
+
end
|
91
|
+
def test_join_find_tagged_with
|
92
|
+
@first_person.tag "Employee Manager"
|
93
|
+
assert_equal [@first_person], Person.find_tagged_with(:any => "Employee")
|
94
|
+
assert_equal [@first_person], Person.find_tagged_with(:all => "Employee Manager")
|
95
|
+
end
|
96
|
+
def test_simple_find_related_tags
|
97
|
+
@topic.tag "foo'bar,baz", :separator => "," , :clear =>true
|
98
|
+
result = { "baz" => 1}
|
99
|
+
assert_equal result,Topic.find_related_tags("foo'bar")
|
100
|
+
assert_equal result,Topic.find_related_tags("foo'bar", :limit => 1)
|
101
|
+
end
|
102
|
+
def test_tags_count
|
103
|
+
list = []
|
104
|
+
10.times do |x|
|
105
|
+
topic = Topic.new(:name => "Topic #{x}")
|
106
|
+
topic.save
|
107
|
+
list << topic
|
108
|
+
end
|
109
|
+
tags = []
|
110
|
+
10.times do |x|
|
111
|
+
tags << "Tag #{x}"
|
112
|
+
end
|
113
|
+
10.times do |x|
|
114
|
+
list[x].tag tags
|
115
|
+
tags.pop
|
116
|
+
end
|
117
|
+
result = {"Tag 1"=>9, "Tag 2"=>8, "Tag 3"=>7, "Tag 4"=>6,
|
118
|
+
"Tag 5"=>5, "Tag 6"=>4, "Tag 7"=>3, "Tag 8"=>2,
|
119
|
+
"Tag 9"=>1, "Tag 0"=>10}
|
120
|
+
assert_equal result , Topic.tags_count
|
121
|
+
sorted_by_name = result.keys.collect{|key| [key,result[key]]}.sort{|a,b| a[0] <=> b[0]}
|
122
|
+
sorted_by_count = result.keys.collect{|key| [key,result[key]]}.sort{|a,b| a[1] <=> b[1]}
|
123
|
+
assert_equal sorted_by_name, Topic.tags_count(:sort_list => Proc.new {|list| list.sort{|a,b| a[0] <=> b[0]}})
|
124
|
+
assert_equal sorted_by_count, Topic.tags_count(:sort_list => Proc.new {|list| list.sort{|a,b| a[1] <=> b[1]}})
|
125
|
+
|
126
|
+
assert_equal result , Topic.tag_count
|
127
|
+
assert_equal sorted_by_name, Topic.tag_count(:sort_list => Proc.new {|list| list.sort{|a,b| a[0] <=> b[0]}})
|
128
|
+
assert_equal sorted_by_count, Topic.tag_count(:sort_list => Proc.new {|list| list.sort{|a,b| a[1] <=> b[1]}})
|
129
|
+
end
|
130
|
+
def test_simple_tag
|
131
|
+
assert_equal [],@topic.tags
|
132
|
+
@topic.tag "Rails"
|
133
|
+
assert_equal ["Rails"], @topic.tag_names
|
134
|
+
list = ["Mike","John","Sam"]
|
135
|
+
@topic.tag list, :clear => true
|
136
|
+
assert_equal list, @topic.tag_names
|
137
|
+
@topic.tag "foo'bar,baz", :separator => "," , :clear =>true
|
138
|
+
assert_equal ["foo'bar","baz"] , @topic.tag_names
|
139
|
+
|
140
|
+
@topic.tag_remove "foo'bar"
|
141
|
+
assert_equal ["baz"] , @topic.tag_names
|
310
142
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
143
|
+
end
|
144
|
+
def test_join_tag
|
145
|
+
assert_equal [], @first_person.tags
|
146
|
+
@first_person.tag "Employee", :attributes => { :created_by_id => @second_person.id}
|
147
|
+
assert_equal ["Employee"], @first_person.tag_names
|
148
|
+
@topic.tag_remove "Employee"
|
149
|
+
assert_equal [] , @topic.tag_names
|
150
|
+
end
|
151
|
+
def test_join_tag_clear_tags!
|
152
|
+
assert_equal [], @first_person.tags
|
153
|
+
@first_person.tag "Employee", :attributes => { :created_by_id => @second_person.id}
|
154
|
+
assert_equal ["Employee"], @first_person.tag_names
|
155
|
+
@first_person.clear_tags!
|
156
|
+
assert_equal 0 , Topic.count_by_sql("SELECT COUNT(*) FROM tag_people")
|
157
|
+
end
|
158
|
+
def test_simple_clear_tags!
|
159
|
+
assert_equal [],@topic.tags
|
160
|
+
assert_equal 0 , Topic.count_by_sql("SELECT COUNT(*) FROM tags_topics")
|
161
|
+
@topic.tag "Rails"
|
162
|
+
assert_equal 1 , Topic.count_by_sql("SELECT COUNT(*) FROM tags_topics")
|
163
|
+
assert_equal ["Rails"], @topic.tag_names
|
164
|
+
@topic.clear_tags!
|
165
|
+
assert_equal [],@topic.tags
|
166
|
+
assert_equal 0 , Topic.count_by_sql("SELECT COUNT(*) FROM tags_topics")
|
167
|
+
end
|
168
|
+
def test_simple_tagged_with?
|
169
|
+
@topic.tag("Ruby Rails")
|
170
|
+
assert @topic.tagged_with?("Ruby")
|
171
|
+
assert !@topic.tagged_with?("Mike")
|
172
|
+
end
|
173
|
+
def test_simple_tagged_with_all?
|
174
|
+
@topic.tag("Ruby Rails")
|
175
|
+
assert @topic.tagged_with_all?("Ruby")
|
176
|
+
assert @topic.tagged_with_all?("Rails Ruby")
|
177
|
+
end
|
178
|
+
def test_simple_tagged_with_any?
|
179
|
+
@topic.tag("Ruby Rails")
|
180
|
+
assert @topic.tagged_with_any?("Ruby")
|
181
|
+
assert @topic.tagged_with_any?("Rails Ruby")
|
182
|
+
assert @topic.tagged_with_any?("Rails Ruby Mike")
|
183
|
+
assert @topic.tagged_with_any?("Sam Rails Ruby Mike")
|
184
|
+
end
|
185
|
+
def test_join_tagged_with?
|
186
|
+
@first_person.tag("Employee Manager")
|
187
|
+
assert @first_person.tagged_with?("Employee")
|
188
|
+
assert !@first_person.tagged_with?("Mike")
|
189
|
+
end
|
190
|
+
def test_join_tagged_with_all?
|
191
|
+
@first_person.tag("Employee Manager")
|
192
|
+
assert @first_person.tagged_with_all?("Employee")
|
193
|
+
assert @first_person.tagged_with_all?("Manager Employee")
|
194
|
+
end
|
195
|
+
def test_join_tagged_with_any?
|
196
|
+
@first_person.tag("Employee Manager")
|
197
|
+
assert @first_person.tagged_with_any?("Employee")
|
198
|
+
assert @first_person.tagged_with_any?("Manager Employee")
|
199
|
+
assert @first_person.tagged_with_any?("Manager Employee Mike")
|
200
|
+
assert @first_person.tagged_with_any?("Sam Manager Employee Mike")
|
201
|
+
end
|
315
202
|
|
316
|
-
|
317
|
-
t1, t2, t3, t4, t5, t6 = create_test_topics
|
318
|
-
|
319
|
-
tags = Topic.tags_count
|
320
|
-
assert_equal 9, tags.size
|
203
|
+
end
|
321
204
|
|
322
|
-
Topic.cloud(tags, ['1', '2', '3', '4', '5', '6']) do |tag, cat|
|
323
|
-
case tag
|
324
|
-
when 'rome': assert_equal cat, '6'
|
325
|
-
when 'luxury': assert_equal cat, '3'
|
326
|
-
when 'clean': assert_equal cat, '6'
|
327
|
-
when 'mustsee': assert_equal cat, '3'
|
328
|
-
when 'greatview': assert_equal cat, '3'
|
329
|
-
when 'italian': assert_equal cat, '2'
|
330
|
-
when 'spicy': assert_equal cat, '2'
|
331
|
-
when 'goodwine': assert_equal cat, '1'
|
332
|
-
when 'wine': assert_equal cat, '1'
|
333
|
-
else
|
334
|
-
flunk 'Unexpected Tag/Category pair'
|
335
|
-
end
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
|
-
private
|
340
|
-
def test_tagging(tagged_object, tag_model, collection)
|
341
|
-
tag_model.delete_all
|
342
|
-
assert_equal 0, tag_model.count
|
343
|
-
|
344
|
-
tagged_object.tag_names << 'rio brazil'
|
345
|
-
tagged_object.save
|
346
|
-
|
347
|
-
assert_equal 2, tag_model.count
|
348
|
-
assert_equal 2, tagged_object.send(collection).size
|
349
205
|
|
350
|
-
tagged_object.tag_names = 'beach surf'
|
351
|
-
assert_equal 4, tag_model.count
|
352
|
-
assert_equal 2, tagged_object.send(collection).size
|
353
|
-
|
354
|
-
tagged_object.tag_names.concat 'soccer+pele', :separator => '+'
|
355
|
-
assert_equal 6, tag_model.count
|
356
|
-
assert_equal 4, tagged_object.send(collection).size
|
357
|
-
|
358
|
-
tag_model.delete_all
|
359
|
-
assert_equal 0, tag_model.count
|
360
|
-
tagged_object.send(collection).reload
|
361
|
-
|
362
|
-
tagged_object.tag_names = 'dhh'
|
363
|
-
assert_equal 1, tag_model.count
|
364
|
-
assert_equal 1, tagged_object.send(collection).size
|
365
|
-
|
366
|
-
tagged_object.tag 'dhh rails my', :clear => true
|
367
|
-
|
368
|
-
assert_equal 3, tag_model.count
|
369
|
-
assert_equal 3, tagged_object.send(collection).size
|
370
|
-
|
371
|
-
tagged_object.tag 'dhh dhh ruby tags', :clear => true
|
372
|
-
assert_equal 5, tag_model.count
|
373
|
-
assert_equal 3, tagged_object.send(collection).size
|
374
|
-
|
375
|
-
tagged_object.tag 'tagging, hello, ruby', :separator => ','
|
376
|
-
assert_equal 7, tag_model.count
|
377
|
-
assert_equal 5, tagged_object.send(collection).size
|
378
206
|
|
379
|
-
all_tags = %w( dhh rails my ruby tags tagging hello )
|
380
|
-
first_tags = %w( dhh ruby tags tagging hello )
|
381
|
-
|
382
|
-
tagged_object.send(collection).reload
|
383
|
-
assert_equal first_tags, tagged_object.tag_names
|
384
|
-
all_tags.each do |tag_name|
|
385
|
-
tag_record = tag_model.find(:first,:conditions=>["#{@@tag_table_column_name.to_s} = ?",tag_name])
|
386
|
-
assert_not_nil tag_record
|
387
|
-
|
388
|
-
if first_tags.include?(tag_name)
|
389
|
-
assert tagged_object.send(collection).include?(tag_record)
|
390
|
-
assert tagged_object.tagged_with?(tag_name)
|
391
|
-
end
|
392
|
-
end
|
393
|
-
end
|
394
207
|
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
208
|
+
################################
|
209
|
+
########OLD UNIT TEST CODE######
|
210
|
+
################################
|
211
|
+
#ActiveRecord::Base.connection.drop_table :keywords rescue nil
|
212
|
+
#ActiveRecord::Base.connection.drop_table :keywords_companies rescue nil
|
213
|
+
#ActiveRecord::Base.connection.drop_table :tags_posts rescue nil
|
214
|
+
|
215
|
+
#ActiveRecord::Base.connection.create_table :tags do |t|
|
216
|
+
# t.column @@tag_table_column_name , :string
|
217
|
+
#end
|
218
|
+
#
|
219
|
+
#ActiveRecord::Base.connection.create_table :tags_topics, :id => false do |t|
|
220
|
+
# t.column :tag_id, :integer
|
221
|
+
# t.column :topic_id, :integer
|
222
|
+
# t.column :created_at, :datetime
|
223
|
+
#end
|
224
|
+
#
|
225
|
+
#ActiveRecord::Base.connection.create_table :keywords do |t|
|
226
|
+
# t.column :name, :string
|
227
|
+
#end
|
228
|
+
#
|
229
|
+
#ActiveRecord::Base.connection.create_table :keywords_companies, :id => false do |t|
|
230
|
+
# t.column :keyword_id, :integer
|
231
|
+
# t.column :company_id, :integer
|
232
|
+
# acts_as_list :scope => :person
|
233
|
+
#end
|
234
|
+
#
|
235
|
+
#ActiveRecord::Base.connection.create_table :tags_posts do |t|
|
236
|
+
# t.column :tag_id, :integer
|
237
|
+
# t.column :post_id, :integer
|
238
|
+
# t.column :created_at, :datetime
|
239
|
+
# t.column :created_by_id, :integer
|
240
|
+
# t.column :position, :integer
|
241
|
+
#end
|
242
|
+
#
|
243
|
+
#class Tag < ActiveRecord::Base; end
|
244
|
+
#class Topic < ActiveRecord::Base
|
245
|
+
# acts_as_taggable
|
246
|
+
#end
|
247
|
+
#
|
248
|
+
#class Keyword < ActiveRecord::Base; end
|
249
|
+
#
|
250
|
+
#class Company < ActiveRecord::Base
|
251
|
+
# acts_as_taggable :collection => :keywords, :tag_class_name => 'Keyword'
|
252
|
+
#end
|
253
|
+
#
|
254
|
+
#class Firm < Company; end
|
255
|
+
#class Client < Company; end
|
256
|
+
#
|
257
|
+
#class Post < ActiveRecord::Base
|
258
|
+
# acts_as_taggable :join_class_name => 'TagPost'
|
259
|
+
#end
|
260
|
+
#
|
261
|
+
#class TagPost
|
262
|
+
# acts_as_list :scope => :post
|
263
|
+
#
|
264
|
+
# def before_save
|
265
|
+
# self.created_by_id = rand(3) + 1
|
266
|
+
# end
|
267
|
+
#end
|
268
|
+
#
|
269
|
+
#class Order < ActiveRecord::Base
|
270
|
+
#end
|
271
|
+
#
|
272
|
+
#class ActAsTaggableTest < Test::Unit::TestCase
|
273
|
+
#
|
274
|
+
# def test_singleton_methods
|
275
|
+
# assert !Order.respond_to?(:find_tagged_with)
|
276
|
+
# assert Firm.respond_to?(:find_tagged_with)
|
277
|
+
# assert Firm.respond_to?(:cloud)
|
278
|
+
# assert Post.respond_to?(:find_tagged_with)
|
279
|
+
# assert Post.respond_to?(:cloud)
|
280
|
+
# assert Topic.respond_to?(:find_tagged_with)
|
281
|
+
# assert Topic.respond_to?(:tag_count)
|
282
|
+
# assert Topic.respond_to?(:tags_count)
|
283
|
+
# assert Topic.respond_to?(:cloud)
|
284
|
+
# end
|
285
|
+
#
|
286
|
+
# def test_with_defaults
|
287
|
+
# test_tagging(Topic.find(:first), Tag, :tags)
|
288
|
+
# end
|
289
|
+
#
|
290
|
+
# def test_with_non_defaults
|
291
|
+
# test_tagging(Company.find(:first), Keyword, :keywords)
|
292
|
+
# end
|
293
|
+
#
|
294
|
+
# def test_tag_with_new_object
|
295
|
+
# topic = Topic.new
|
296
|
+
# topic.tag 'brazil rio beach'
|
297
|
+
# topic.save
|
298
|
+
# end
|
299
|
+
#
|
300
|
+
# def test_tagging_with_join_model
|
301
|
+
# Tag.delete_all
|
302
|
+
# TagPost.delete_all
|
303
|
+
# post = Post.find(:first)
|
304
|
+
# tags = %w(brazil rio beach)
|
305
|
+
#
|
306
|
+
# post.tag(tags)
|
307
|
+
# tags.each { |tag| assert post.tagged_with?(tag) }
|
308
|
+
#
|
309
|
+
# post.save
|
310
|
+
# post.tags.reload
|
311
|
+
# tags.each { |tag| assert post.tagged_with?(tag) }
|
312
|
+
#
|
313
|
+
# posts = Post.find_tagged_with(:any => 'brazil sampa moutain')
|
314
|
+
# assert_equal posts[0], post
|
315
|
+
#
|
316
|
+
# posts = Post.find_tagged_with(:all => 'brazil beach')
|
317
|
+
# assert_equal posts[0], post
|
318
|
+
#
|
319
|
+
# posts = Post.find_tagged_with(:all => 'brazil rich')
|
320
|
+
# assert_equal 0, posts.size
|
321
|
+
#
|
322
|
+
# posts = Post.find_tagged_with(:all => 'brazil', :conditions => [ 'tags_posts.position = ?', 1])
|
323
|
+
# assert_equal posts[0], post
|
324
|
+
#
|
325
|
+
# posts = Post.find_tagged_with(:all => 'rio', :conditions => [ 'tags_posts.position = ?', 2])
|
326
|
+
# assert_equal posts[0], post
|
327
|
+
#
|
328
|
+
# posts = Post.find_tagged_with(:all => 'beach', :conditions => [ 'tags_posts.position = ?', 3])
|
329
|
+
# assert_equal posts[0], post
|
330
|
+
# end
|
331
|
+
#
|
332
|
+
# def test_tags_count_with_join_model
|
333
|
+
# p1 = Post.create(:title => 'test1')
|
334
|
+
# p2 = Post.create(:title => 'test2')
|
335
|
+
# p3 = Post.create(:title => 'test3')
|
336
|
+
#
|
337
|
+
# p1.tag 'a b c d'
|
338
|
+
# p2.tag 'a c e f'
|
339
|
+
# p3.tag 'a c f g'
|
340
|
+
#
|
341
|
+
# counts = Post.tags_count :count => '>= 2', :limit => 2
|
342
|
+
# assert_equal counts.keys.size, 2
|
343
|
+
# counts.each { |tag, count| assert count >= 2 }
|
344
|
+
# assert counts.keys.include?('a')
|
345
|
+
# assert counts.keys.include?('c')
|
346
|
+
# end
|
347
|
+
#
|
348
|
+
# def test_tags_count
|
349
|
+
# t1 = Topic.create(:title => 'test1')
|
350
|
+
# t2 = Topic.create(:title => 'test2')
|
351
|
+
# t3 = Topic.create(:title => 'test3')
|
352
|
+
#
|
353
|
+
# t1.tag 'a b c d'
|
354
|
+
# t2.tag 'a c e f'
|
355
|
+
# t3.tag 'a c f g'
|
356
|
+
#
|
357
|
+
# count = Topic.tags_count
|
358
|
+
# assert_equal 3, count['a']
|
359
|
+
# assert_equal 1, count['b']
|
360
|
+
# assert_equal 3, count['c']
|
361
|
+
# assert_equal 1, count['d']
|
362
|
+
# assert_equal 1, count['e']
|
363
|
+
# assert_equal 2, count['f']
|
364
|
+
# assert_equal 1, count['g']
|
365
|
+
# assert_equal nil, count['h']
|
366
|
+
#
|
367
|
+
# count = Topic.tags_count :count => '>= 2'
|
368
|
+
# assert_equal 3, count['a']
|
369
|
+
# assert_equal nil, count['b']
|
370
|
+
# assert_equal 3, count['c']
|
371
|
+
# assert_equal nil, count['d']
|
372
|
+
# assert_equal nil, count['e']
|
373
|
+
# assert_equal 2, count['f']
|
374
|
+
# assert_equal nil, count['g']
|
375
|
+
# assert_equal nil, count['h']
|
376
|
+
#
|
377
|
+
# t4 = Topic.create(:title => 'test4')
|
378
|
+
# t4.tag 'a f'
|
379
|
+
#
|
380
|
+
# count = Topic.tags_count :limit => 3
|
381
|
+
# assert_equal 4, count['a']
|
382
|
+
# assert_equal nil, count['b']
|
383
|
+
# assert_equal 3, count['c']
|
384
|
+
# assert_equal nil, count['d']
|
385
|
+
# assert_equal nil, count['e']
|
386
|
+
# assert_equal 3, count['f']
|
387
|
+
# assert_equal nil, count['g']
|
388
|
+
# assert_equal nil, count['h']
|
389
|
+
#
|
390
|
+
# raw = Topic.tags_count :raw => true
|
391
|
+
# assert_equal 7, raw.size
|
392
|
+
# assert_equal Array, raw.class
|
393
|
+
# assert_equal 'a', raw.first[@@tag_table_column_name.to_s]
|
394
|
+
# assert_equal '4', raw.first['count']
|
395
|
+
# assert_not_nil raw.first['id']
|
396
|
+
# assert_equal 'g', raw.last[@@tag_table_column_name.to_s]
|
397
|
+
# assert_equal '1', raw.last['count']
|
398
|
+
# assert_not_nil raw.last['id']
|
399
|
+
# end
|
400
|
+
#
|
401
|
+
# def test_find_related_tagged
|
402
|
+
# t1, t2, t3, t4, t5, t6 = create_test_topics
|
403
|
+
#
|
404
|
+
# assert_equal [ t4, t2, t3 ], t1.tagged_related(:limit => 3)
|
405
|
+
# assert_equal [ t5, t1, t3 ], t2.tagged_related(:limit => 3)
|
406
|
+
# assert_equal [ t1, t4, t6 ], t3.tagged_related(:limit => 3)
|
407
|
+
# assert_equal [ t1, t3, t6 ], t4.tagged_related(:limit => 3)
|
408
|
+
# assert_equal [ t2, t1, t3 ], t5.tagged_related(:limit => 3)
|
409
|
+
# assert_equal [ t1, t3, t4 ], t6.tagged_related(:limit => 3)
|
410
|
+
# end
|
411
|
+
#
|
412
|
+
# def test_find_related_tags
|
413
|
+
# t1, t2, t3, t4, t5, t6 = create_test_topics
|
414
|
+
#
|
415
|
+
# tags = Topic.find_related_tags('rome walking')
|
416
|
+
# assert_equal 2, tags['greatview']
|
417
|
+
# assert_equal 4, tags['clean']
|
418
|
+
# assert_equal 2, tags['mustsee']
|
419
|
+
# end
|
420
|
+
#
|
421
|
+
# def test_find_tagged_with_on_subclasses
|
422
|
+
# firm = Firm.find(:first)
|
423
|
+
# firm.tag 'law'
|
424
|
+
# firms = Firm.find_tagged_with :any => 'law'
|
425
|
+
# assert_equal firm, firms[0]
|
426
|
+
# assert_equal 1, firms.size
|
427
|
+
# end
|
428
|
+
#
|
429
|
+
# def test_find_tagged_with_any
|
430
|
+
# topic1 = Topic.create(:title => 'test1')
|
431
|
+
# topic2 = Topic.create(:title => 'test2')
|
432
|
+
# topic3 = Topic.create(:title => 'test3')
|
433
|
+
#
|
434
|
+
# topic1.tag('a b c'); topic1.save
|
435
|
+
# topic2.tag('a c e'); topic2.save
|
436
|
+
# topic3.tag('c d e'); topic3.save
|
437
|
+
#
|
438
|
+
# topics = Topic.find_tagged_with(:any => 'x y z')
|
439
|
+
# assert_equal 0, topics.size
|
440
|
+
#
|
441
|
+
# topics = Topic.find_tagged_with(:any => 'a b c d e x y z')
|
442
|
+
# assert_equal 3, topics.size
|
443
|
+
# assert topics.include?(topic1)
|
444
|
+
# assert topics.include?(topic2)
|
445
|
+
# assert topics.include?(topic3)
|
446
|
+
#
|
447
|
+
# topics = Topic.find_tagged_with(:any => 'a z')
|
448
|
+
# assert_equal 2, topics.size
|
449
|
+
# assert topics.include?(topic1)
|
450
|
+
# assert topics.include?(topic2)
|
451
|
+
#
|
452
|
+
# topics = Topic.find_tagged_with(:any => 'b')
|
453
|
+
# assert_equal 1, topics.size
|
454
|
+
# assert topics.include?(topic1)
|
455
|
+
#
|
456
|
+
# topics = Topic.find_tagged_with(:any => 'c')
|
457
|
+
# assert_equal 3, topics.size
|
458
|
+
# assert topics.include?(topic1)
|
459
|
+
# assert topics.include?(topic2)
|
460
|
+
# assert topics.include?(topic3)
|
461
|
+
#
|
462
|
+
# topics = Topic.find_tagged_with(:any => 'd')
|
463
|
+
# assert_equal 1, topics.size
|
464
|
+
# assert topics.include?(topic3)
|
465
|
+
#
|
466
|
+
# topics = Topic.find_tagged_with(:any => 'e')
|
467
|
+
# assert_equal 2, topics.size
|
468
|
+
# assert topics.include?(topic2)
|
469
|
+
# assert topics.include?(topic3)
|
470
|
+
# end
|
471
|
+
#
|
472
|
+
# def test_find_tagged_with_all
|
473
|
+
# topic1 = Topic.create(:title => 'test1')
|
474
|
+
# topic2 = Topic.create(:title => 'test2')
|
475
|
+
# topic3 = Topic.create(:title => 'test3')
|
476
|
+
#
|
477
|
+
# topic1.tag('a b c'); topic1.save
|
478
|
+
# topic2.tag('a c e'); topic2.save
|
479
|
+
# topic3.tag('c d e'); topic3.save
|
480
|
+
#
|
481
|
+
# topics = Topic.find_tagged_with(:all => 'a b d')
|
482
|
+
# assert_equal 0, topics.size
|
483
|
+
#
|
484
|
+
# topics = Topic.find_tagged_with(:all => 'a c')
|
485
|
+
# assert_equal 2, topics.size
|
486
|
+
# assert topics.include?(topic1)
|
487
|
+
# assert topics.include?(topic2)
|
488
|
+
#
|
489
|
+
# topics = Topic.find_tagged_with(:all => 'a+c', :separator => '+')
|
490
|
+
# assert_equal 2, topics.size
|
491
|
+
# assert topics.include?(topic1)
|
492
|
+
# assert topics.include?(topic2)
|
493
|
+
#
|
494
|
+
# topics = Topic.find_tagged_with(:all => 'c e')
|
495
|
+
# assert_equal 2, topics.size
|
496
|
+
# assert topics.include?(topic2)
|
497
|
+
# assert topics.include?(topic3)
|
498
|
+
#
|
499
|
+
# topics = Topic.find_tagged_with(:all => 'c')
|
500
|
+
# assert_equal 3, topics.size
|
501
|
+
# assert topics.include?(topic1)
|
502
|
+
# assert topics.include?(topic2)
|
503
|
+
# assert topics.include?(topic3)
|
504
|
+
#
|
505
|
+
# topics = Topic.find_tagged_with(:all => 'a b c')
|
506
|
+
# assert_equal 1, topics.size
|
507
|
+
# assert topics.include?(topic1)
|
508
|
+
#
|
509
|
+
# topics = Topic.find_tagged_with(:all => 'a c e')
|
510
|
+
# assert_equal 1, topics.size
|
511
|
+
# assert topics.include?(topic2)
|
512
|
+
# end
|
513
|
+
#
|
514
|
+
# def test_tag_cloud
|
515
|
+
# t1, t2, t3, t4, t5, t6 = create_test_topics
|
516
|
+
#
|
517
|
+
# tags = Topic.tags_count
|
518
|
+
# assert_equal 9, tags.size
|
519
|
+
#
|
520
|
+
# Topic.cloud(tags, ['1', '2', '3', '4', '5', '6']) do |tag, cat|
|
521
|
+
# case tag
|
522
|
+
# when 'rome': assert_equal cat, '6'
|
523
|
+
# when 'luxury': assert_equal cat, '3'
|
524
|
+
# when 'clean': assert_equal cat, '6'
|
525
|
+
# when 'mustsee': assert_equal cat, '3'
|
526
|
+
# when 'greatview': assert_equal cat, '3'
|
527
|
+
# when 'italian': assert_equal cat, '2'
|
528
|
+
# when 'spicy': assert_equal cat, '2'
|
529
|
+
# when 'goodwine': assert_equal cat, '1'
|
530
|
+
# when 'wine': assert_equal cat, '1'
|
531
|
+
# else
|
532
|
+
# flunk 'Unexpected Tag/Category pair'
|
533
|
+
# end
|
534
|
+
# end
|
535
|
+
# end
|
536
|
+
#
|
537
|
+
# private
|
538
|
+
# def test_tagging(tagged_object, tag_model, collection)
|
539
|
+
# tag_model.delete_all
|
540
|
+
# assert_equal 0, tag_model.count
|
541
|
+
#
|
542
|
+
# tagged_object.tag_names << 'rio brazil'
|
543
|
+
# tagged_object.save
|
544
|
+
#
|
545
|
+
# assert_equal 2, tag_model.count
|
546
|
+
# assert_equal 2, tagged_object.send(collection).size
|
547
|
+
#
|
548
|
+
# tagged_object.tag_names = 'beach surf'
|
549
|
+
# assert_equal 4, tag_model.count
|
550
|
+
# assert_equal 2, tagged_object.send(collection).size
|
551
|
+
#
|
552
|
+
# tagged_object.tag_names.concat 'soccer+pele', :separator => '+'
|
553
|
+
# assert_equal 6, tag_model.count
|
554
|
+
# assert_equal 4, tagged_object.send(collection).size
|
555
|
+
#
|
556
|
+
# tag_model.delete_all
|
557
|
+
# assert_equal 0, tag_model.count
|
558
|
+
# tagged_object.send(collection).reload
|
559
|
+
#
|
560
|
+
# tagged_object.tag_names = 'dhh'
|
561
|
+
# assert_equal 1, tag_model.count
|
562
|
+
# assert_equal 1, tagged_object.send(collection).size
|
563
|
+
#
|
564
|
+
# tagged_object.tag 'dhh rails my', :clear => true
|
565
|
+
#
|
566
|
+
# assert_equal 3, tag_model.count
|
567
|
+
# assert_equal 3, tagged_object.send(collection).size
|
568
|
+
#
|
569
|
+
# tagged_object.tag 'dhh dhh ruby tags', :clear => true
|
570
|
+
# assert_equal 5, tag_model.count
|
571
|
+
# assert_equal 3, tagged_object.send(collection).size
|
572
|
+
#
|
573
|
+
# tagged_object.tag 'tagging, hello, ruby', :separator => ','
|
574
|
+
# assert_equal 7, tag_model.count
|
575
|
+
# assert_equal 5, tagged_object.send(collection).size
|
576
|
+
#
|
577
|
+
# all_tags = %w( dhh rails my ruby tags tagging hello )
|
578
|
+
# first_tags = %w( dhh ruby tags tagging hello )
|
579
|
+
#
|
580
|
+
# tagged_object.send(collection).reload
|
581
|
+
# assert_equal first_tags, tagged_object.tag_names
|
582
|
+
# all_tags.each do |tag_name|
|
583
|
+
# tag_record = tag_model.find(:first,:conditions=>["#{@@tag_table_column_name.to_s} = ?",tag_name])
|
584
|
+
# assert_not_nil tag_record
|
585
|
+
#
|
586
|
+
# if first_tags.include?(tag_name)
|
587
|
+
# assert tagged_object.send(collection).include?(tag_record)
|
588
|
+
# assert tagged_object.tagged_with?(tag_name)
|
589
|
+
# end
|
590
|
+
# end
|
591
|
+
# end
|
592
|
+
#
|
593
|
+
# def create_test_topics
|
594
|
+
# t1 = Topic.create(:title => 't1')
|
595
|
+
# t2 = Topic.create(:title => 't2')
|
596
|
+
# t3 = Topic.create(:title => 't3')
|
597
|
+
# t4 = Topic.create(:title => 't4')
|
598
|
+
# t5 = Topic.create(:title => 't5')
|
599
|
+
# t6 = Topic.create(:title => 't6')
|
600
|
+
#
|
601
|
+
# t1.tag('rome, luxury, clean, mustsee, greatview', :separator => ','); t1.save
|
602
|
+
# t2.tag('rome, luxury, clean, italian, spicy, goodwine', :separator => ','); t2.save
|
603
|
+
# t3.tag('rome, walking, clean, mustsee', :separator => ','); t3.save
|
604
|
+
# t4.tag('rome, italy, clean, mustsee, greatview', :separator => ','); t4.save
|
605
|
+
# t5.tag('rome, luxury, clean, italian, spicy, wine', :separator => ','); t5.save
|
606
|
+
# t6.tag('rome, walking, clean, greatview', :separator => ','); t6.save
|
607
|
+
#
|
608
|
+
# [ t1, t2, t3, t4, t5, t6 ]
|
609
|
+
# end
|
610
|
+
#end
|
data/test/config.yml
ADDED
data/test/debug.log
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Logfile created on Sun Aug 13 14:26:05 CDT 2006 by logger.rb/1.5.2.7
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: acts_as_taggable
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 2.0.
|
7
|
-
date: 2006-08-
|
6
|
+
version: 2.0.2
|
7
|
+
date: 2006-08-13 00:00:00 -05:00
|
8
8
|
summary: An acts-as Mixin for easy applying and searching tags/folksnomies on Active Record objects
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -29,7 +29,10 @@ authors:
|
|
29
29
|
- Demetrius Nunes,Dirk Elmendorf
|
30
30
|
files:
|
31
31
|
- lib/taggable.rb
|
32
|
+
- test/debug.log
|
32
33
|
- test/acts_as_taggable_test.rb
|
34
|
+
- test/config.yml
|
35
|
+
- test/config.yml.sample
|
33
36
|
- README
|
34
37
|
- CHANGELOG
|
35
38
|
test_files: []
|