summaryrefslogtreecommitdiff
path: root/vendor/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/plugins')
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/CHANGELOG167
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/README153
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/generators/acts_as_taggable_migration/acts_as_taggable_migration_generator.rb11
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/generators/acts_as_taggable_migration/templates/migration.rb26
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/init.rb1
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/lib/acts_as_taggable.rb214
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/lib/tag.rb26
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/lib/tag_counts_extension.rb3
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/lib/tag_list.rb91
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/lib/tagging.rb12
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/lib/tags_helper.rb13
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/abstract_unit.rb97
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/acts_as_taggable_test.rb347
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/magazine.rb3
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/magazines.yml7
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/photo.rb8
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/photos.yml24
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/post.rb7
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/posts.yml34
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/special_post.rb2
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/subscription.rb4
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/subscriptions.yml3
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/taggings.yml149
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/tags.yml19
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/user.rb7
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/users.yml7
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/tag_list_test.rb106
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/tag_test.rb34
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/tagging_test.rb13
-rw-r--r--vendor/plugins/acts_as_taggable_on_steroids/test/tags_helper_test.rb28
-rw-r--r--vendor/plugins/acts_as_taggable_redux/MIT-LICENSE (renamed from vendor/plugins/acts_as_taggable_on_steroids/MIT-LICENSE)4
-rw-r--r--vendor/plugins/acts_as_taggable_redux/README143
-rw-r--r--vendor/plugins/acts_as_taggable_redux/Rakefile (renamed from vendor/plugins/acts_as_taggable_on_steroids/Rakefile)6
-rw-r--r--vendor/plugins/acts_as_taggable_redux/acts_as_taggable_redux.gemspec44
-rw-r--r--vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_stylesheet/acts_as_taggable_stylesheet_generator.rb7
-rw-r--r--vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_stylesheet/templates/acts_as_taggable_stylesheet.css7
-rw-r--r--vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_tables/acts_as_taggable_tables_generator.rb7
-rw-r--r--vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_tables/templates/migration.rb29
-rw-r--r--vendor/plugins/acts_as_taggable_redux/init.rb1
-rw-r--r--vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable.rb136
-rw-r--r--vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable_helper.rb38
-rw-r--r--vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable_redux.rb9
-rw-r--r--vendor/plugins/acts_as_taggable_redux/lib/acts_as_tagger.rb25
-rw-r--r--vendor/plugins/acts_as_taggable_redux/lib/tag.rb73
-rw-r--r--vendor/plugins/acts_as_taggable_redux/lib/tagging.rb5
-rw-r--r--vendor/plugins/acts_as_taggable_redux/tasks/acts_as_taggable_tasks.rake20
-rw-r--r--vendor/plugins/acts_as_taggable_redux/test/acts_as_taggable_test.rb34
-rw-r--r--vendor/plugins/acts_as_taggable_redux/test/debug.log104
-rw-r--r--vendor/plugins/acts_as_taggable_redux/test/fixtures/taggings.yml47
-rw-r--r--vendor/plugins/acts_as_taggable_redux/test/fixtures/tags.yml24
-rw-r--r--vendor/plugins/acts_as_taggable_redux/test/fixtures/thing.rb3
-rw-r--r--vendor/plugins/acts_as_taggable_redux/test/fixtures/things.yml15
-rw-r--r--vendor/plugins/acts_as_taggable_redux/test/fixtures/user.rb3
-rw-r--r--vendor/plugins/acts_as_taggable_redux/test/fixtures/users.yml3
-rw-r--r--vendor/plugins/acts_as_taggable_redux/test/tag_test.rb68
-rw-r--r--vendor/plugins/acts_as_taggable_redux/test/tagging_test.rb13
-rw-r--r--vendor/plugins/acts_as_taggable_redux/test/test_helper.rb50
57 files changed, 913 insertions, 1621 deletions
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/CHANGELOG b/vendor/plugins/acts_as_taggable_on_steroids/CHANGELOG
deleted file mode 100644
index f314bd9..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/CHANGELOG
+++ /dev/null
@@ -1,167 +0,0 @@
1[13 March 08]
2
3* Added helper methods for will_paginate compatibility (Clinton R. Nixon)
4* Fixed :conditions in tag_counts to accept array to sanitize (Clinton R. Nixon)
5
6[07 March 08]
7
8* Added support for regexp delimiter (Matt Aimonetti)
9
10[30 Jan 08]
11
12* Fix Tag.destroy_unused on Rails 2.0.
13
14[23 October 2007]
15
16* Make find_options_for_tag_counts and find_options_for_tagged_with dup their options.
17
18* Apply conditions properly in find_options_for_tag_counts.
19
20* Fix tag_cloud when no tags are present.
21
22[22 October 2007]
23
24* Fix find_tagged_with using :match_all and :include.
25
26* Use inner joins instead of left outer joins.
27
28[15 October 2007]
29
30* Make find_tagged_with correctly apply :conditions
31
32* Add Tag.destroy_unused option.
33
34[11 October 2007]
35
36* Make tag_counts work correctly with STI.
37
38[3 October 2007]
39
40* Improve documentation.
41
42* Fix TagsHelper and test.
43
44[2 October 2007]
45
46* Remove TagList.parse, use TagList.from instead.
47
48* Add :parse option to TagList#new, TagList#add, and TagList#remove.
49
50 tag_list = TagList.new("One, Two", :parse => true) # ["One", "Two"]
51
52 tag_list # ["One", "Two"]
53 tag_list.add("Three, Four", :parse => true) # ["One", "Two", "Three", "Four"]
54
55* Remove TagList#names.
56
57[29 September 2007]
58
59* Add TagsHelper to assist with generating tag clouds and provide a simple example.
60
61[27 September 2007]
62
63* Add #tag_counts method to get tag counts for a specific object's tags.
64
65* BACKWARDS INCOMPATIBILITY: Rename #find_options_for_tagged_with to #find_options_for_find_tagged_with
66
67[17 September 2007]
68
69* Fix clearing of cached tag list when all tags removed.
70
71[12 September 2007]
72
73* Make the TagList class inherit from Array.
74
75* Deprecate obsolete TagList#names.
76
77[6 September 2007]
78
79* Add TagList#include? and TagList#empty?
80
81[26 August 2006]
82
83* Remove deprecated Tag.delimiter. Use TagList.delimiter instead.
84
85[25 August 2007]
86
87* Make tag_counts work with has_many :through
88
89[23 August 2007]
90
91* Make search comparisons case-insensitive across different databases. [Moisés Machado]
92
93* Improve compatiblity with STI. [Moisés Machado]
94
95[25 July 2007]
96
97* Respect custom table names for the Tag and Tagging classes.
98
99* Fix the :exclude option for find_tagged_with
100
101[17 July 2007]
102
103* Make the migration work on edge rails
104
105[8 July 2007]
106
107* find_options_for_tagged_with should not alter its arguments
108
109[1 July 2007]
110
111* Fix incorrect tagging when the case of the tag list is changed.
112
113* Fix deprecated Tag.delimiter accessor.
114
115[23 June 2007]
116
117* Add validation to Tag model.
118
119* find_options_for_tagged_with should always return a hash.
120
121* find_tagged_with passing in no tags should return an empty array.
122
123* Improve compatibility with PostgreSQL.
124
125[21 June 2007]
126
127* Remove extra .rb from generated migration file name.
128
129[15 June 2007]
130
131* Introduce TagList class.
132
133* Various cleanups and improvements.
134
135* Use TagList.delimiter now, not Tag.delimiter. Tag.delimiter will be removed at some stage.
136
137[11 June 2007]
138
139* Restructure the creation of the options for find_tagged_with [Thijs Cadier]
140
141* Add an example migration with a generator.
142
143* Add caching.
144
145* Fix compatibility with Ruby < 1.8.6
146
147[23 April 2007]
148
149* Make tag_list to respect Tag.delimiter
150
151[31 March 2007]
152
153* Add Tag.delimiter accessor to change how tags are parsed.
154
155* Fix :include => :tags when used with find_tagged_with
156
157[7 March 2007]
158
159* Fix tag_counts for SQLServer [Brad Young]
160
161[21 Feb 2007]
162
163* Use scoping instead of TagCountsExtension [Michael Schuerig]
164
165[7 Jan 2007]
166
167* Add :match_all to find_tagged_with [Michael Sheakoski]
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/README b/vendor/plugins/acts_as_taggable_on_steroids/README
deleted file mode 100644
index 73b88fe..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/README
+++ /dev/null
@@ -1,153 +0,0 @@
1= acts_as_taggable_on_steroids
2
3NOT THE OFFICIAL REPO, I just imported this project to get few bug fixed when I was using it for a project in early 2008.
4
5USE AT YOUR OWN RISK
6
7
8If you find this plugin useful, please consider a donation to show your support!
9
10 http://www.paypal.com/cgi-bin/webscr?cmd=_send-money
11
12 Email address: jonathan.viney@gmail.com
13
14== Instructions
15
16This plugin is based on acts_as_taggable by DHH but includes extras
17such as tests, smarter tag assignment, and tag cloud calculations.
18
19== Installation
20
21 ruby script/plugin install http://svn.viney.net.nz/things/rails/plugins/acts_as_taggable_on_steroids
22
23== Usage
24
25=== Prepare database
26
27Generate and apply the migration:
28
29 ruby script/generate acts_as_taggable_migration
30 rake db:migrate
31
32=== Basic tagging
33
34Let's suppose users have many posts and we want those posts to have tags.
35The first step is to add +acts_as_taggable+ to the Post class:
36
37 class Post < ActiveRecord::Base
38 acts_as_taggable
39
40 belongs_to :user
41 end
42
43We can now use the tagging methods provided by acts_as_taggable, <tt>#tag_list</tt> and <tt>#tag_list=</tt>. Both these
44methods work like regular attribute accessors.
45
46 p = Post.find(:first)
47 p.tag_list # []
48 p.tag_list = "Funny, Silly"
49 p.save
50 p.tag_list # ["Funny", "Silly"]
51
52You can also add or remove arrays of tags.
53
54 p.tag_list.add("Great", "Awful")
55 p.tag_list.remove("Funny")
56
57=== Finding tagged objects
58
59To retrieve objects tagged with a certain tag, use find_tagged_with.
60
61 Post.find_tagged_with('Funny, Silly')
62
63By default, find_tagged_with will find objects that have any of the given tags. To
64find only objects that are tagged with all the given tags, use match_all.
65
66 Post.find_tagged_with('Funny, Silly', :match_all => true)
67
68See <tt>ActiveRecord::Acts::Taggable::InstanceMethods</tt> for more methods and options.
69
70=== Tag cloud calculations
71
72To construct tag clouds, the frequency of each tag needs to be calculated.
73Because we specified +acts_as_taggable+ on the <tt>Post</tt> class, we can
74get a calculation of all the tag counts by using <tt>Post.tag_counts</tt>. But what if we wanted a tag count for
75an single user's posts? To achieve this we call tag_counts on the association:
76
77 User.find(:first).posts.tag_counts
78
79A helper is included to assist with generating tag clouds. Include it in your helper file:
80
81 module ApplicationHelper
82 include TagsHelper
83 end
84
85Here is an example that generates a tag cloud.
86
87Controller:
88
89 class PostController < ApplicationController
90 def tag_cloud
91 @tags = Post.tag_counts
92 end
93 end
94
95View:
96 <% tag_cloud @tags, %w(css1 css2 css3 css4) do |tag, css_class| %>
97 <%= link_to tag.name, { :action => :tag, :id => tag.name }, :class => css_class %>
98 <% end %>
99
100CSS:
101
102 .css1 { font-size: 1.0em; }
103 .css2 { font-size: 1.2em; }
104 .css3 { font-size: 1.4em; }
105 .css4 { font-size: 1.6em; }
106
107=== Caching
108
109It is useful to cache the list of tags to reduce the number of queries executed. To do this,
110add a column named <tt>cached_tag_list</tt> to the model which is being tagged. The column should be long enough to hold
111the full tag list and must have a default value of null, not an empty string.
112
113 class CachePostTagList < ActiveRecord::Migration
114 def self.up
115 add_column :posts, :cached_tag_list, :string
116 end
117 end
118
119 class Post < ActiveRecord::Base
120 acts_as_taggable
121
122 # The caching column defaults to cached_tag_list, but can be changed:
123 #
124 # set_cached_tag_list_column_name "my_caching_column_name"
125 end
126
127The details of the caching are handled for you. Just continue to use the tag_list accessor as you normally would.
128Note that the cached tag list will not be updated if you directly create Tagging objects or manually append to the
129<tt>tags</tt> or <tt>taggings</tt> associations. To update the cached tag list you should call <tt>save_cached_tag_list</tt> manually.
130
131=== Delimiter
132
133If you want to change the delimiter used to parse and present tags, set TagList.delimiter.
134For example, to use spaces instead of commas, add the following to config/environment.rb:
135
136 TagList.delimiter = " "
137
138You can also use a regexp as delimiter:
139
140 TagList.delimiter = /,|;/
141
142The above code would parse the string and use ',' and ';' as delimiters.
143
144=== Unused tags
145
146Set Tag.destroy_unused to remove tags when they are no longer being
147used to tag any objects. Defaults to false.
148
149 Tag.destroy_unused = true
150
151=== Other
152
153Problems, comments, and suggestions all welcome. jonathan.viney@gmail.com
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/generators/acts_as_taggable_migration/acts_as_taggable_migration_generator.rb b/vendor/plugins/acts_as_taggable_on_steroids/generators/acts_as_taggable_migration/acts_as_taggable_migration_generator.rb
deleted file mode 100644
index be9b39c..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/generators/acts_as_taggable_migration/acts_as_taggable_migration_generator.rb
+++ /dev/null
@@ -1,11 +0,0 @@
1class ActsAsTaggableMigrationGenerator < Rails::Generator::Base
2 def manifest
3 record do |m|
4 m.migration_template 'migration.rb', 'db/migrate'
5 end
6 end
7
8 def file_name
9 "acts_as_taggable_migration"
10 end
11end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/generators/acts_as_taggable_migration/templates/migration.rb b/vendor/plugins/acts_as_taggable_on_steroids/generators/acts_as_taggable_migration/templates/migration.rb
deleted file mode 100644
index ea0c2cc..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/generators/acts_as_taggable_migration/templates/migration.rb
+++ /dev/null
@@ -1,26 +0,0 @@
1class ActsAsTaggableMigration < ActiveRecord::Migration
2 def self.up
3 create_table :tags do |t|
4 t.column :name, :string
5 end
6
7 create_table :taggings do |t|
8 t.column :tag_id, :integer
9 t.column :taggable_id, :integer
10
11 # You should make sure that the column created is
12 # long enough to store the required class names.
13 t.column :taggable_type, :string
14
15 t.column :created_at, :datetime
16 end
17
18 add_index :taggings, :tag_id
19 add_index :taggings, [:taggable_id, :taggable_type]
20 end
21
22 def self.down
23 drop_table :taggings
24 drop_table :tags
25 end
26end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/init.rb b/vendor/plugins/acts_as_taggable_on_steroids/init.rb
deleted file mode 100644
index 64505b9..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/init.rb
+++ /dev/null
@@ -1 +0,0 @@
1require File.dirname(__FILE__) + '/lib/acts_as_taggable'
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/lib/acts_as_taggable.rb b/vendor/plugins/acts_as_taggable_on_steroids/lib/acts_as_taggable.rb
deleted file mode 100644
index d537889..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/lib/acts_as_taggable.rb
+++ /dev/null
@@ -1,214 +0,0 @@
1module ActiveRecord #:nodoc:
2 module Acts #:nodoc:
3 module Taggable #:nodoc:
4 def self.included(base)
5 base.extend(ClassMethods)
6 end
7
8 module ClassMethods
9 def acts_as_taggable
10 has_many :taggings, :as => :taggable, :dependent => :destroy, :include => :tag
11 has_many :tags, :through => :taggings
12
13 before_save :save_cached_tag_list
14 after_save :save_tags
15
16 include ActiveRecord::Acts::Taggable::InstanceMethods
17 extend ActiveRecord::Acts::Taggable::SingletonMethods
18
19 alias_method_chain :reload, :tag_list
20 end
21
22 def cached_tag_list_column_name
23 "cached_tag_list"
24 end
25
26 def set_cached_tag_list_column_name(value = nil, &block)
27 define_attr_method :cached_tag_list_column_name, value, &block
28 end
29 end
30
31 module SingletonMethods
32 # Pass either a tag string, or an array of strings or tags
33 #
34 # Options:
35 # :exclude - Find models that are not tagged with the given tags
36 # :match_all - Find models that match all of the given tags, not just one
37 # :conditions - A piece of SQL conditions to add to the query
38 def find_tagged_with(*args)
39 options = find_options_for_find_tagged_with(*args)
40 options.blank? ? [] : find(:all, options)
41 end
42
43 # will_paginate's method_missing function wants to hit
44 # find_all_tagged_with if you call paginate_tagged_with, which is
45 # obviously suboptimal
46 def find_all_tagged_with(*args)
47 find_tagged_with(*args)
48 end
49
50 def find_options_for_find_tagged_with(tags, options = {})
51 tags = tags.is_a?(Array) ? TagList.new(tags.map(&:to_s)) : TagList.from(tags)
52 options = options.dup
53
54 return {} if tags.empty?
55
56 conditions = []
57 conditions << sanitize_sql(options.delete(:conditions)) if options[:conditions]
58
59 taggings_alias, tags_alias = "#{table_name}_taggings", "#{table_name}_tags"
60
61 if options.delete(:exclude)
62 conditions << <<-END
63 #{table_name}.id NOT IN
64 (SELECT #{Tagging.table_name}.taggable_id FROM #{Tagging.table_name}
65 INNER JOIN #{Tag.table_name} ON #{Tagging.table_name}.tag_id = #{Tag.table_name}.id
66 WHERE #{tags_condition(tags)} AND #{Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})
67 END
68 else
69 if options.delete(:match_all)
70 conditions << <<-END
71 (SELECT COUNT(*) FROM #{Tagging.table_name}
72 INNER JOIN #{Tag.table_name} ON #{Tagging.table_name}.tag_id = #{Tag.table_name}.id
73 WHERE #{Tagging.table_name}.taggable_type = #{quote_value(base_class.name)} AND
74 taggable_id = #{table_name}.id AND
75 #{tags_condition(tags)}) = #{tags.size}
76 END
77 else
78 conditions << tags_condition(tags, tags_alias)
79 end
80 end
81
82 { :select => "DISTINCT #{table_name}.*",
83 :joins => "INNER JOIN #{Tagging.table_name} #{taggings_alias} ON #{taggings_alias}.taggable_id = #{table_name}.#{primary_key} AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)} " +
84 "INNER JOIN #{Tag.table_name} #{tags_alias} ON #{tags_alias}.id = #{taggings_alias}.tag_id",
85 :conditions => conditions.join(" AND ")
86 }.reverse_merge!(options)
87 end
88
89 # Calculate the tag counts for all tags.
90 #
91 # Options:
92 # :start_at - Restrict the tags to those created after a certain time
93 # :end_at - Restrict the tags to those created before a certain time
94 # :conditions - A piece of SQL conditions to add to the query
95 # :limit - The maximum number of tags to return
96 # :order - A piece of SQL to order by. Eg 'tags.count desc' or 'taggings.created_at desc'
97 # :at_least - Exclude tags with a frequency less than the given value
98 # :at_most - Exclude tags with a frequency greater than the given value
99 def tag_counts(options = {})
100 Tag.find(:all, find_options_for_tag_counts(options))
101 end
102
103 # Find how many objects are tagged with a certain tag.
104 def count_by_tag(tag_name)
105 counts = tag_counts(:conditions => "tags.name = #{quote_value(tag_name)}")
106 counts[0].respond_to?(:count) ? counts[0].count : 0
107 end
108
109 def find_options_for_tag_counts(options = {})
110 options.assert_valid_keys :start_at, :end_at, :conditions, :at_least, :at_most, :order, :limit
111 options = options.dup
112
113 scope = scope(:find)
114 start_at = sanitize_sql(["#{Tagging.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at]
115 end_at = sanitize_sql(["#{Tagging.table_name}.created_at <= ?", options.delete(:end_at)]) if options[:end_at]
116
117 conditions = [
118 "#{Tagging.table_name}.taggable_type = #{quote_value(base_class.name)}",
119 sanitize_sql(options.delete(:conditions)),
120 scope && scope[:conditions],
121 start_at,
122 end_at
123 ]
124
125 conditions << type_condition unless descends_from_active_record?
126 conditions.compact!
127 conditions = conditions.join(' AND ')
128
129 joins = ["INNER JOIN #{Tagging.table_name} ON #{Tag.table_name}.id = #{Tagging.table_name}.tag_id"]
130 joins << "INNER JOIN #{table_name} ON #{table_name}.#{primary_key} = #{Tagging.table_name}.taggable_id"
131 joins << scope[:joins] if scope && scope[:joins]
132
133 at_least = sanitize_sql(['COUNT(*) >= ?', options.delete(:at_least)]) if options[:at_least]
134 at_most = sanitize_sql(['COUNT(*) <= ?', options.delete(:at_most)]) if options[:at_most]
135 having = [at_least, at_most].compact.join(' AND ')
136 group_by = "#{Tag.table_name}.id, #{Tag.table_name}.name HAVING COUNT(*) > 0"
137 group_by << " AND #{having}" unless having.blank?
138
139 { :select => "#{Tag.table_name}.id, #{Tag.table_name}.name, COUNT(*) AS count",
140 :joins => joins.join(" "),
141 :conditions => conditions,
142 :group => group_by
143 }.reverse_merge!(options)
144 end
145
146 def caching_tag_list?
147 column_names.include?(cached_tag_list_column_name)
148 end
149
150 private
151 def tags_condition(tags, table_name = Tag.table_name)
152 condition = tags.map { |t| sanitize_sql(["#{table_name}.name LIKE ?", t]) }.join(" OR ")
153 "(" + condition + ")"
154 end
155 end
156
157 module InstanceMethods
158 def tag_list
159 return @tag_list if @tag_list
160
161 if self.class.caching_tag_list? and !(cached_value = send(self.class.cached_tag_list_column_name)).nil?
162 @tag_list = TagList.from(cached_value)
163 else
164 @tag_list = TagList.new(*tags.map(&:name))
165 end
166 end
167
168 def tag_list=(value)
169 @tag_list = TagList.from(value)
170 end
171
172 def save_cached_tag_list
173 if self.class.caching_tag_list?
174 self[self.class.cached_tag_list_column_name] = tag_list.to_s
175 end
176 end
177
178 def save_tags
179 return unless @tag_list
180
181 new_tag_names = @tag_list - tags.map(&:name)
182 old_tags = tags.reject { |tag| @tag_list.include?(tag.name) }
183
184 self.class.transaction do
185 if old_tags.any?
186 taggings.find(:all, :conditions => ["tag_id IN (?)", old_tags.map(&:id)]).each(&:destroy)
187 taggings.reset
188 end
189
190 new_tag_names.each do |new_tag_name|
191 tags << Tag.find_or_create_with_like_by_name(new_tag_name)
192 end
193 end
194
195 true
196 end
197
198 # Calculate the tag counts for the tags used by this model.
199 #
200 # The possible options are the same as the tag_counts class method, excluding :conditions.
201 def tag_counts(options = {})
202 self.class.tag_counts({ :conditions => self.class.send(:tags_condition, tag_list) }.reverse_merge!(options))
203 end
204
205 def reload_with_tag_list(*args) #:nodoc:
206 @tag_list = nil
207 reload_without_tag_list(*args)
208 end
209 end
210 end
211 end
212end
213
214ActiveRecord::Base.send(:include, ActiveRecord::Acts::Taggable)
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/lib/tag.rb b/vendor/plugins/acts_as_taggable_on_steroids/lib/tag.rb
deleted file mode 100644
index 91859d5..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/lib/tag.rb
+++ /dev/null
@@ -1,26 +0,0 @@
1class Tag < ActiveRecord::Base
2 has_many :taggings
3
4 validates_presence_of :name
5 validates_uniqueness_of :name
6
7 cattr_accessor :destroy_unused
8 self.destroy_unused = false
9
10 # LIKE is used for cross-database case-insensitivity
11 def self.find_or_create_with_like_by_name(name)
12 find(:first, :conditions => ["name LIKE ?", name]) || create(:name => name)
13 end
14
15 def ==(object)
16 super || (object.is_a?(Tag) && name == object.name)
17 end
18
19 def to_s
20 name
21 end
22
23 def count
24 read_attribute(:count).to_i
25 end
26end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/lib/tag_counts_extension.rb b/vendor/plugins/acts_as_taggable_on_steroids/lib/tag_counts_extension.rb
deleted file mode 100644
index a1d13b8..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/lib/tag_counts_extension.rb
+++ /dev/null
@@ -1,3 +0,0 @@
1# Deprecated
2module TagCountsExtension #:nodoc:
3end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/lib/tag_list.rb b/vendor/plugins/acts_as_taggable_on_steroids/lib/tag_list.rb
deleted file mode 100644
index 01325b8..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/lib/tag_list.rb
+++ /dev/null
@@ -1,91 +0,0 @@
1class TagList < Array
2 cattr_accessor :delimiter
3 self.delimiter = ','
4
5 def initialize(*args)
6 add(*args)
7 end
8
9 # Add tags to the tag_list. Duplicate or blank tags will be ignored.
10 #
11 # tag_list.add("Fun", "Happy")
12 #
13 # Use the <tt>:parse</tt> option to add an unparsed tag string.
14 #
15 # tag_list.add("Fun, Happy", :parse => true)
16 def add(*names)
17 extract_and_apply_options!(names)
18 concat(names)
19 clean!
20 self
21 end
22
23 # Remove specific tags from the tag_list.
24 #
25 # tag_list.remove("Sad", "Lonely")
26 #
27 # Like #add, the <tt>:parse</tt> option can be used to remove multiple tags in a string.
28 #
29 # tag_list.remove("Sad, Lonely", :parse => true)
30 def remove(*names)
31 extract_and_apply_options!(names)
32 delete_if { |name| names.include?(name) }
33 self
34 end
35
36 # Transform the tag_list into a tag string suitable for edting in a form.
37 # The tags are joined with <tt>TagList.delimiter</tt> and quoted if necessary.
38 #
39 # tag_list = TagList.new("Round", "Square,Cube")
40 # tag_list.to_s # 'Round, "Square,Cube"'
41 def to_s
42 clean!
43
44 list = map do |name|
45 if delimiter.is_a?(Regexp)
46 name.match(delimiter) ? "\"#{name}\"" : name
47 else
48 name.include?(delimiter) ? "\"#{name}\"" : name
49 end
50 end
51
52 list.join( delimiter.is_a?(Regexp) ? "#{delimiter.source.match(/[^\\\[\]\*\?\{\}\.\|]/)[0]} " : (delimiter.ends_with?(" ") ? delimiter : "#{delimiter} ") )
53 end
54
55 private
56 # Remove whitespace, duplicates, and blanks.
57 def clean!
58 reject!(&:blank?)
59 map!(&:strip)
60 uniq!
61 end
62
63 def extract_and_apply_options!(args)
64 options = args.last.is_a?(Hash) ? args.pop : {}
65 options.assert_valid_keys :parse
66
67 if options[:parse]
68 args.map! { |a| self.class.from(a) }
69 end
70
71 args.flatten!
72 end
73
74 class << self
75 # Returns a new TagList using the given tag string.
76 #
77 # tag_list = TagList.from("One , Two, Three")
78 # tag_list # ["One", "Two", "Three"]
79 def from(string)
80 returning new do |tag_list|
81 string = string.to_s.gsub('.', '').dup
82
83 # Parse the quoted tags
84 string.gsub!(/"(.*?)"\s*#{delimiter}?\s*/) { tag_list << $1; "" }
85 string.gsub!(/'(.*?)'\s*#{delimiter}?\s*/) { tag_list << $1; "" }
86
87 tag_list.add(string.split(delimiter))
88 end
89 end
90 end
91end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/lib/tagging.rb b/vendor/plugins/acts_as_taggable_on_steroids/lib/tagging.rb
deleted file mode 100644
index 87bc44d..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/lib/tagging.rb
+++ /dev/null
@@ -1,12 +0,0 @@
1class Tagging < ActiveRecord::Base #:nodoc:
2 belongs_to :tag
3 belongs_to :taggable, :polymorphic => true
4
5 def after_destroy
6 if Tag.destroy_unused
7 if tag.taggings.count.zero?
8 tag.destroy
9 end
10 end
11 end
12end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/lib/tags_helper.rb b/vendor/plugins/acts_as_taggable_on_steroids/lib/tags_helper.rb
deleted file mode 100644
index d5644b7..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/lib/tags_helper.rb
+++ /dev/null
@@ -1,13 +0,0 @@
1module TagsHelper
2 # See the README for an example using tag_cloud.
3 def tag_cloud(tags, classes)
4 return if tags.empty?
5
6 max_count = tags.sort_by(&:count).last.count.to_f
7
8 tags.each do |tag|
9 index = ((tag.count / max_count) * (classes.size - 1)).round
10 yield tag, classes[index]
11 end
12 end
13end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/abstract_unit.rb b/vendor/plugins/acts_as_taggable_on_steroids/test/abstract_unit.rb
deleted file mode 100644
index 42e277a..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/abstract_unit.rb
+++ /dev/null
@@ -1,97 +0,0 @@
1require 'test/unit'
2
3begin
4 require File.dirname(__FILE__) + '/../../../../config/environment'
5rescue LoadError
6 require 'rubygems'
7 gem 'activerecord'
8 gem 'actionpack'
9 require 'active_record'
10 require 'action_controller'
11end
12
13# Search for fixtures first
14fixture_path = File.dirname(__FILE__) + '/fixtures/'
15Dependencies.load_paths.insert(0, fixture_path)
16
17require 'active_record/fixtures'
18
19require File.dirname(__FILE__) + '/../lib/acts_as_taggable'
20require_dependency File.dirname(__FILE__) + '/../lib/tag_list'
21require_dependency File.dirname(__FILE__) + '/../lib/tags_helper'
22
23ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/debug.log')
24ActiveRecord::Base.configurations = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
25ActiveRecord::Base.establish_connection(ENV['DB'] || 'mysql')
26
27load(File.dirname(__FILE__) + '/schema.rb')
28
29Test::Unit::TestCase.fixture_path = fixture_path
30
31class Test::Unit::TestCase #:nodoc:
32 self.use_transactional_fixtures = true
33 self.use_instantiated_fixtures = false
34
35 def assert_equivalent(expected, actual, message = nil)
36 if expected.first.is_a?(ActiveRecord::Base)
37 assert_equal expected.sort_by(&:id), actual.sort_by(&:id), message
38 else
39 assert_equal expected.sort, actual.sort, message
40 end
41 end
42
43 def assert_tag_counts(tags, expected_values)
44 # Map the tag fixture names to real tag names
45 expected_values = expected_values.inject({}) do |hash, (tag, count)|
46 hash[tags(tag).name] = count
47 hash
48 end
49
50 tags.each do |tag|
51 value = expected_values.delete(tag.name)
52
53 assert_not_nil value, "Expected count for #{tag.name} was not provided"
54 assert_equal value, tag.count, "Expected value of #{value} for #{tag.name}, but was #{tag.count}"
55 end
56
57 unless expected_values.empty?
58 assert false, "The following tag counts were not present: #{expected_values.inspect}"
59 end
60 end
61
62 def assert_queries(num = 1)
63 $query_count = 0
64 yield
65 ensure
66 assert_equal num, $query_count, "#{$query_count} instead of #{num} queries were executed."
67 end
68
69 def assert_no_queries(&block)
70 assert_queries(0, &block)
71 end
72
73 # From Rails trunk
74 def assert_difference(expressions, difference = 1, message = nil, &block)
75 expression_evaluations = [expressions].flatten.collect{|expression| lambda { eval(expression, block.binding) } }
76
77 original_values = expression_evaluations.inject([]) { |memo, expression| memo << expression.call }
78 yield
79 expression_evaluations.each_with_index do |expression, i|
80 assert_equal original_values[i] + difference, expression.call, message
81 end
82 end
83
84 def assert_no_difference(expressions, message = nil, &block)
85 assert_difference expressions, 0, message, &block
86 end
87end
88
89ActiveRecord::Base.connection.class.class_eval do
90 def execute_with_counting(sql, name = nil, &block)
91 $query_count ||= 0
92 $query_count += 1
93 execute_without_counting(sql, name, &block)
94 end
95
96 alias_method_chain :execute, :counting
97end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/acts_as_taggable_test.rb b/vendor/plugins/acts_as_taggable_on_steroids/test/acts_as_taggable_test.rb
deleted file mode 100644
index 90ea3c4..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/acts_as_taggable_test.rb
+++ /dev/null
@@ -1,347 +0,0 @@
1require File.dirname(__FILE__) + '/abstract_unit'
2
3class ActsAsTaggableOnSteroidsTest < Test::Unit::TestCase
4 fixtures :tags, :taggings, :posts, :users, :photos, :subscriptions, :magazines
5
6 def test_find_tagged_with
7 assert_equivalent [posts(:jonathan_sky), posts(:sam_flowers)], Post.find_tagged_with('"Very good"')
8 assert_equal Post.find_tagged_with('"Very good"'), Post.find_tagged_with(['Very good'])
9 assert_equal Post.find_tagged_with('"Very good"'), Post.find_tagged_with([tags(:good)])
10
11 assert_equivalent [photos(:jonathan_dog), photos(:sam_flower), photos(:sam_sky)], Photo.find_tagged_with('Nature')
12 assert_equal Photo.find_tagged_with('Nature'), Photo.find_tagged_with(['Nature'])
13 assert_equal Photo.find_tagged_with('Nature'), Photo.find_tagged_with([tags(:nature)])
14
15 assert_equivalent [photos(:jonathan_bad_cat), photos(:jonathan_dog), photos(:jonathan_questioning_dog)], Photo.find_tagged_with('"Crazy animal" Bad')
16 assert_equal Photo.find_tagged_with('"Crazy animal" Bad'), Photo.find_tagged_with(['Crazy animal', 'Bad'])
17 assert_equal Photo.find_tagged_with('"Crazy animal" Bad'), Photo.find_tagged_with([tags(:animal), tags(:bad)])
18 end
19
20 def test_find_tagged_with_nothing
21 assert_equal [], Post.find_tagged_with("")
22 assert_equal [], Post.find_tagged_with([])
23 end
24
25 def test_find_tagged_with_nonexistant_tags
26 assert_equal [], Post.find_tagged_with('ABCDEFG')
27 assert_equal [], Photo.find_tagged_with(['HIJKLM'])
28 assert_equal [], Photo.find_tagged_with([Tag.new(:name => 'unsaved tag')])
29 end
30
31 def test_find_tagged_with_match_all
32 assert_equivalent [photos(:jonathan_dog)], Photo.find_tagged_with('Crazy animal, "Nature"', :match_all => true)
33 end
34
35 def test_find_tagged_with_match_all_and_include
36 assert_equivalent [posts(:jonathan_sky), posts(:sam_flowers)], Post.find_tagged_with(['Very good', 'Nature'], :match_all => true, :include => :tags)
37 end
38
39 def test_find_tagged_with_conditions
40 assert_equal [], Post.find_tagged_with('"Very good", Nature', :conditions => '1=0')
41 end
42
43 def test_find_tagged_with_duplicates_options_hash
44 options = { :conditions => '1=1' }.freeze
45 assert_nothing_raised { Post.find_tagged_with("Nature", options) }
46 end
47
48 def test_find_tagged_with_exclusions
49 assert_equivalent [photos(:jonathan_questioning_dog), photos(:jonathan_bad_cat)], Photo.find_tagged_with("Nature", :exclude => true)
50 assert_equivalent [posts(:jonathan_grass), posts(:jonathan_rain), posts(:jonathan_cloudy), posts(:jonathan_still_cloudy)], Post.find_tagged_with("'Very good', Bad", :exclude => true)
51 end
52
53 def test_find_options_for_find_tagged_with_no_tags_returns_empty_hash
54 assert_equal Hash.new, Post.find_options_for_find_tagged_with("")
55 assert_equal Hash.new, Post.find_options_for_find_tagged_with([nil])
56 end
57
58 def test_find_options_for_find_tagged_with_leaves_arguments_unchanged
59 original_tags = photos(:jonathan_questioning_dog).tags.dup
60 Photo.find_options_for_find_tagged_with(photos(:jonathan_questioning_dog).tags)
61 assert_equal original_tags, photos(:jonathan_questioning_dog).tags
62 end
63
64 def test_find_options_for_find_tagged_with_respects_custom_table_name
65 Tagging.table_name = "categorisations"
66 Tag.table_name = "categories"
67
68 options = Photo.find_options_for_find_tagged_with("Hello")
69
70 assert_no_match(/ taggings /, options[:joins])
71 assert_no_match(/ tags /, options[:joins])
72
73 assert_match(/ categorisations /, options[:joins])
74 assert_match(/ categories /, options[:joins])
75 ensure
76 Tagging.table_name = "taggings"
77 Tag.table_name = "tags"
78 end
79
80 def test_include_tags_on_find_tagged_with
81 assert_nothing_raised do
82 Photo.find_tagged_with('Nature', :include => :tags)
83 Photo.find_tagged_with("Nature", :include => { :taggings => :tag })
84 end
85 end
86
87 def test_basic_tag_counts_on_class
88 assert_tag_counts Post.tag_counts, :good => 2, :nature => 7, :question => 1, :bad => 1
89 assert_tag_counts Photo.tag_counts, :good => 1, :nature => 3, :question => 1, :bad => 1, :animal => 3
90 end
91
92 def test_tag_counts_on_class_with_date_conditions
93 assert_tag_counts Post.tag_counts(:start_at => Date.new(2006, 8, 4)), :good => 1, :nature => 5, :question => 1, :bad => 1
94 assert_tag_counts Post.tag_counts(:end_at => Date.new(2006, 8, 6)), :good => 1, :nature => 4, :question => 1
95 assert_tag_counts Post.tag_counts(:start_at => Date.new(2006, 8, 5), :end_at => Date.new(2006, 8, 10)), :good => 1, :nature => 4, :bad => 1
96
97 assert_tag_counts Photo.tag_counts(:start_at => Date.new(2006, 8, 12), :end_at => Date.new(2006, 8, 19)), :good => 1, :nature => 2, :bad => 1, :question => 1, :animal => 3
98 end
99
100 def test_tag_counts_on_class_with_frequencies
101 assert_tag_counts Photo.tag_counts(:at_least => 2), :nature => 3, :animal => 3
102 assert_tag_counts Photo.tag_counts(:at_most => 2), :good => 1, :question => 1, :bad => 1
103 end
104
105 def test_tag_counts_on_class_with_frequencies_and_conditions
106 assert_tag_counts Photo.tag_counts(:at_least => 2, :conditions => '1=1'), :nature => 3, :animal => 3
107 end
108
109 def test_tag_counts_duplicates_options_hash
110 options = { :at_least => 2, :conditions => '1=1' }.freeze
111 assert_nothing_raised { Photo.tag_counts(options) }
112 end
113
114 def test_tag_counts_with_limit
115 assert_equal 2, Photo.tag_counts(:limit => 2).size
116 assert_equal 1, Post.tag_counts(:at_least => 4, :limit => 2).size
117 end
118
119 def test_tag_counts_with_limit_and_order
120 assert_equal [tags(:nature), tags(:good)], Post.tag_counts(:order => 'count desc', :limit => 2)
121 end
122
123 def test_tag_counts_on_association
124 assert_tag_counts users(:jonathan).posts.tag_counts, :good => 1, :nature => 5, :question => 1
125 assert_tag_counts users(:sam).posts.tag_counts, :good => 1, :nature => 2, :bad => 1
126
127 assert_tag_counts users(:jonathan).photos.tag_counts, :animal => 3, :nature => 1, :question => 1, :bad => 1
128 assert_tag_counts users(:sam).photos.tag_counts, :nature => 2, :good => 1
129 end
130
131 def test_tag_counts_on_association_with_options
132 assert_equal [], users(:jonathan).posts.tag_counts(:conditions => '1=0')
133 assert_tag_counts users(:jonathan).posts.tag_counts(:at_most => 2), :good => 1, :question => 1
134 end
135
136 def test_tag_counts_on_has_many_through
137 assert_tag_counts users(:jonathan).magazines.tag_counts, :good => 1
138 end
139
140 def test_tag_counts_respects_custom_table_names
141 Tagging.table_name = "categorisations"
142 Tag.table_name = "categories"
143
144 options = Photo.find_options_for_tag_counts(:start_at => 2.weeks.ago, :end_at => Date.today)
145 sql = options.values.join(' ')
146
147 assert_no_match /taggings/, sql
148 assert_no_match /tags/, sql
149
150 assert_match /categorisations/, sql
151 assert_match /categories/, sql
152 ensure
153 Tagging.table_name = "taggings"
154 Tag.table_name = "tags"
155 end
156
157 def test_tag_list_reader
158 assert_equivalent ["Very good", "Nature"], posts(:jonathan_sky).tag_list
159 assert_equivalent ["Bad", "Crazy animal"], photos(:jonathan_bad_cat).tag_list
160 end
161
162 def test_reassign_tag_list
163 assert_equivalent ["Nature", "Question"], posts(:jonathan_rain).tag_list
164 posts(:jonathan_rain).taggings.reload
165
166 # Only an update of the posts table should be executed
167 assert_queries 1 do
168 posts(:jonathan_rain).update_attributes!(:tag_list => posts(:jonathan_rain).tag_list.to_s)
169 end
170
171 assert_equivalent ["Nature", "Question"], posts(:jonathan_rain).tag_list
172 end
173
174 def test_new_tags
175 assert_equivalent ["Very good", "Nature"], posts(:jonathan_sky).tag_list
176 posts(:jonathan_sky).update_attributes!(:tag_list => "#{posts(:jonathan_sky).tag_list}, One, Two")
177 assert_equivalent ["Very good", "Nature", "One", "Two"], posts(:jonathan_sky).tag_list
178 end
179
180 def test_remove_tag
181 assert_equivalent ["Very good", "Nature"], posts(:jonathan_sky).tag_list
182 posts(:jonathan_sky).update_attributes!(:tag_list => "Nature")
183 assert_equivalent ["Nature"], posts(:jonathan_sky).tag_list
184 end
185
186 def test_change_case_of_tags
187 original_tag_names = photos(:jonathan_questioning_dog).tag_list
188 photos(:jonathan_questioning_dog).update_attributes!(:tag_list => photos(:jonathan_questioning_dog).tag_list.to_s.upcase)
189
190 # The new tag list is not uppercase becuase the AR finders are not case-sensitive
191 # and find the old tags when re-tagging with the uppercase tags.
192 assert_equivalent original_tag_names, photos(:jonathan_questioning_dog).reload.tag_list
193 end
194
195 def test_remove_and_add_tag
196 assert_equivalent ["Very good", "Nature"], posts(:jonathan_sky).tag_list
197 posts(:jonathan_sky).update_attributes!(:tag_list => "Nature, Beautiful")
198 assert_equivalent ["Nature", "Beautiful"], posts(:jonathan_sky).tag_list
199 end
200
201 def test_tags_not_saved_if_validation_fails
202 assert_equivalent ["Very good", "Nature"], posts(:jonathan_sky).tag_list
203 assert !posts(:jonathan_sky).update_attributes(:tag_list => "One, Two", :text => "")
204 assert_equivalent ["Very good", "Nature"], Post.find(posts(:jonathan_sky).id).tag_list
205 end
206
207 def test_tag_list_accessors_on_new_record
208 p = Post.new(:text => 'Test')
209
210 assert p.tag_list.blank?
211 p.tag_list = "One, Two"
212 assert_equal "One, Two", p.tag_list.to_s
213 end
214
215 def test_clear_tag_list_with_nil
216 p = photos(:jonathan_questioning_dog)
217
218 assert !p.tag_list.blank?
219 assert p.update_attributes(:tag_list => nil)
220 assert p.tag_list.blank?
221
222 assert p.reload.tag_list.blank?
223 end
224
225 def test_clear_tag_list_with_string
226 p = photos(:jonathan_questioning_dog)
227
228 assert !p.tag_list.blank?
229 assert p.update_attributes(:tag_list => ' ')
230 assert p.tag_list.blank?
231
232 assert p.reload.tag_list.blank?
233 end
234
235 def test_tag_list_reset_on_reload
236 p = photos(:jonathan_questioning_dog)
237 assert !p.tag_list.blank?
238 p.tag_list = nil
239 assert p.tag_list.blank?
240 assert !p.reload.tag_list.blank?
241 end
242
243 def test_instance_tag_counts
244 assert_tag_counts posts(:jonathan_sky).tag_counts, :good => 2, :nature => 7
245 end
246
247 def test_tag_list_populated_when_cache_nil
248 assert_nil posts(:jonathan_sky).cached_tag_list
249 posts(:jonathan_sky).save!
250 assert_equal posts(:jonathan_sky).tag_list.to_s, posts(:jonathan_sky).cached_tag_list
251 end
252
253 def test_cached_tag_list_used
254 posts(:jonathan_sky).save!
255 posts(:jonathan_sky).reload
256
257 assert_no_queries do
258 assert_equivalent ["Very good", "Nature"], posts(:jonathan_sky).tag_list
259 end
260 end
261
262 def test_cached_tag_list_not_used
263 # Load fixture and column information
264 posts(:jonathan_sky).taggings(:reload)
265
266 assert_queries 1 do
267 # Tags association will be loaded
268 posts(:jonathan_sky).tag_list
269 end
270 end
271
272 def test_cached_tag_list_updated
273 assert_nil posts(:jonathan_sky).cached_tag_list
274 posts(:jonathan_sky).save!
275 assert_equivalent ["Very good", "Nature"], TagList.from(posts(:jonathan_sky).cached_tag_list)
276 posts(:jonathan_sky).update_attributes!(:tag_list => "None")
277
278 assert_equal 'None', posts(:jonathan_sky).cached_tag_list
279 assert_equal 'None', posts(:jonathan_sky).reload.cached_tag_list
280 end
281
282 def test_clearing_cached_tag_list
283 # Generate the cached tag list
284 posts(:jonathan_sky).save!
285
286 posts(:jonathan_sky).update_attributes!(:tag_list => "")
287 assert_equal "", posts(:jonathan_sky).cached_tag_list
288 end
289
290 def test_find_tagged_with_using_sti
291 special_post = SpecialPost.create!(:text => "Test", :tag_list => "Random")
292
293 assert_equal [special_post], SpecialPost.find_tagged_with("Random")
294 assert Post.find_tagged_with("Random").include?(special_post)
295 end
296
297 def test_tag_counts_using_sti
298 SpecialPost.create!(:text => "Test", :tag_list => "Nature")
299
300 assert_tag_counts SpecialPost.tag_counts, :nature => 1
301 end
302
303 def test_case_insensitivity
304 assert_difference "Tag.count", 1 do
305 Post.create!(:text => "Test", :tag_list => "one")
306 Post.create!(:text => "Test", :tag_list => "One")
307 end
308
309 assert_equal Post.find_tagged_with("Nature"), Post.find_tagged_with("nature")
310 end
311
312 def test_tag_not_destroyed_when_unused
313 posts(:jonathan_sky).tag_list.add("Random")
314 posts(:jonathan_sky).save!
315
316 assert_no_difference 'Tag.count' do
317 posts(:jonathan_sky).tag_list.remove("Random")
318 posts(:jonathan_sky).save!
319 end
320 end
321
322 def test_tag_destroyed_when_unused
323 Tag.destroy_unused = true
324
325 posts(:jonathan_sky).tag_list.add("Random")
326 posts(:jonathan_sky).save!
327
328 assert_difference 'Tag.count', -1 do
329 posts(:jonathan_sky).tag_list.remove("Random")
330 posts(:jonathan_sky).save!
331 end
332 ensure
333 Tag.destroy_unused = false
334 end
335end
336
337class ActsAsTaggableOnSteroidsFormTest < Test::Unit::TestCase
338 fixtures :tags, :taggings, :posts, :users, :photos
339
340 include ActionView::Helpers::FormHelper
341
342 def test_tag_list_contents
343 fields_for :post, posts(:jonathan_sky) do |f|
344 assert_match /Very good, Nature/, f.text_field(:tag_list)
345 end
346 end
347end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/magazine.rb b/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/magazine.rb
deleted file mode 100644
index 554afe4..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/magazine.rb
+++ /dev/null
@@ -1,3 +0,0 @@
1class Magazine < ActiveRecord::Base
2 acts_as_taggable
3end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/magazines.yml b/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/magazines.yml
deleted file mode 100644
index 044ce6d..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/magazines.yml
+++ /dev/null
@@ -1,7 +0,0 @@
1ruby:
2 id: 1
3 name: Ruby
4
5rails:
6 id: 2
7 name: Rails \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/photo.rb b/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/photo.rb
deleted file mode 100644
index 224957f..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/photo.rb
+++ /dev/null
@@ -1,8 +0,0 @@
1class Photo < ActiveRecord::Base
2 acts_as_taggable
3
4 belongs_to :user
5end
6
7class SpecialPhoto < Photo
8end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/photos.yml b/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/photos.yml
deleted file mode 100644
index 25a4118..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/photos.yml
+++ /dev/null
@@ -1,24 +0,0 @@
1jonathan_dog:
2 id: 1
3 user_id: 1
4 title: A small dog
5
6jonathan_questioning_dog:
7 id: 2
8 user_id: 1
9 title: What does this dog want?
10
11jonathan_bad_cat:
12 id: 3
13 user_id: 1
14 title: Bad cat
15
16sam_flower:
17 id: 4
18 user_id: 2
19 title: Flower
20
21sam_sky:
22 id: 5
23 user_id: 2
24 title: Sky
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/post.rb b/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/post.rb
deleted file mode 100644
index bee100a..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/post.rb
+++ /dev/null
@@ -1,7 +0,0 @@
1class Post < ActiveRecord::Base
2 acts_as_taggable
3
4 belongs_to :user
5
6 validates_presence_of :text
7end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/posts.yml b/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/posts.yml
deleted file mode 100644
index 79f50f5..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/posts.yml
+++ /dev/null
@@ -1,34 +0,0 @@
1jonathan_sky:
2 id: 1
3 user_id: 1
4 text: The sky is particularly blue today
5
6jonathan_grass:
7 id: 2
8 user_id: 1
9 text: The grass seems very green
10
11jonathan_rain:
12 id: 3
13 user_id: 1
14 text: Why does the rain fall?
15
16jonathan_cloudy:
17 id: 4
18 user_id: 1
19 text: Is it cloudy?
20
21jonathan_still_cloudy:
22 id: 5
23 user_id: 1
24 text: Is it still cloudy?
25
26sam_ground:
27 id: 6
28 user_id: 2
29 text: The ground is looking too brown
30
31sam_flowers:
32 id: 7
33 user_id: 2
34 text: Why are the flowers dead? \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/special_post.rb b/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/special_post.rb
deleted file mode 100644
index 366a0d5..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/special_post.rb
+++ /dev/null
@@ -1,2 +0,0 @@
1class SpecialPost < Post
2end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/subscription.rb b/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/subscription.rb
deleted file mode 100644
index e975cb7..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/subscription.rb
+++ /dev/null
@@ -1,4 +0,0 @@
1class Subscription < ActiveRecord::Base
2 belongs_to :user
3 belongs_to :magazine
4end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/subscriptions.yml b/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/subscriptions.yml
deleted file mode 100644
index 1b5e68a..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/subscriptions.yml
+++ /dev/null
@@ -1,3 +0,0 @@
1jonathan_rails:
2 user_id: 1
3 magazine_id: 1 \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/taggings.yml b/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/taggings.yml
deleted file mode 100644
index 01e599b..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/taggings.yml
+++ /dev/null
@@ -1,149 +0,0 @@
1# Posts
2jonathan_sky_good:
3 id: 1
4 tag_id: 1
5 taggable_id: 1
6 taggable_type: Post
7 created_at: 2006-08-01
8
9jonathan_sky_nature:
10 id: 2
11 tag_id: 3
12 taggable_id: 1
13 taggable_type: Post
14 created_at: 2006-08-02
15
16jonathan_grass_nature:
17 id: 3
18 tag_id: 3
19 taggable_id: 2
20 taggable_type: Post
21 created_at: 2006-08-03
22
23jonathan_rain_question:
24 id: 4
25 tag_id: 4
26 taggable_id: 3
27 taggable_type: Post
28 created_at: 2006-08-04
29
30jonathan_rain_nature:
31 id: 5
32 tag_id: 3
33 taggable_id: 3
34 taggable_type: Post
35 created_at: 2006-08-05
36
37jonathan_cloudy_nature:
38 id: 6
39 tag_id: 3
40 taggable_id: 4
41 taggable_type: Post
42 created_at: 2006-08-06
43
44jonathan_still_cloudy_nature:
45 id: 7
46 tag_id: 3
47 taggable_id: 5
48 taggable_type: Post
49 created_at: 2006-08-07
50
51sam_ground_nature:
52 id: 8
53 tag_id: 3
54 taggable_id: 6
55 taggable_type: Post
56 created_at: 2006-08-08
57
58sam_ground_bad:
59 id: 9
60 tag_id: 2
61 taggable_id: 6
62 taggable_type: Post
63 created_at: 2006-08-09
64
65sam_flowers_good:
66 id: 10
67 tag_id: 1
68 taggable_id: 7
69 taggable_type: Post
70 created_at: 2006-08-10
71
72sam_flowers_nature:
73 id: 11
74 tag_id: 3
75 taggable_id: 7
76 taggable_type: Post
77 created_at: 2006-08-11
78
79# Photos
80jonathan_dog_animal:
81 id: 12
82 tag_id: 5
83 taggable_id: 1
84 taggable_type: Photo
85 created_at: 2006-08-12
86
87jonathan_dog_nature:
88 id: 13
89 tag_id: 3
90 taggable_id: 1
91 taggable_type: Photo
92 created_at: 2006-08-13
93
94jonathan_questioning_dog_animal:
95 id: 14
96 tag_id: 5
97 taggable_id: 2
98 taggable_type: Photo
99 created_at: 2006-08-14
100
101jonathan_questioning_dog_question:
102 id: 15
103 tag_id: 4
104 taggable_id: 2
105 taggable_type: Photo
106 created_at: 2006-08-15
107
108jonathan_bad_cat_bad:
109 id: 16
110 tag_id: 2
111 taggable_id: 3
112 taggable_type: Photo
113 created_at: 2006-08-16
114
115jonathan_bad_cat_animal:
116 id: 17
117 tag_id: 5
118 taggable_id: 3
119 taggable_type: Photo
120 created_at: 2006-08-17
121
122sam_flower_nature:
123 id: 18
124 tag_id: 3
125 taggable_id: 4
126 taggable_type: Photo
127 created_at: 2006-08-18
128
129sam_flower_good:
130 id: 19
131 tag_id: 1
132 taggable_id: 4
133 taggable_type: Photo
134 created_at: 2006-08-19
135
136sam_sky_nature:
137 id: 20
138 tag_id: 3
139 taggable_id: 5
140 taggable_type: Photo
141 created_at: 2006-08-20
142
143# Magazines
144ruby_good:
145 id: 50
146 tag_id: 1
147 taggable_id: 1
148 taggable_type: Magazine
149 created_at: 2007-08-25
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/tags.yml b/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/tags.yml
deleted file mode 100644
index b8f8367..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/tags.yml
+++ /dev/null
@@ -1,19 +0,0 @@
1good:
2 id: 1
3 name: Very good
4
5bad:
6 id: 2
7 name: Bad
8
9nature:
10 id: 3
11 name: Nature
12
13question:
14 id: 4
15 name: Question
16
17animal:
18 id: 5
19 name: Crazy animal \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/user.rb b/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/user.rb
deleted file mode 100644
index 8c0f787..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/user.rb
+++ /dev/null
@@ -1,7 +0,0 @@
1class User < ActiveRecord::Base
2 has_many :posts
3 has_many :photos
4
5 has_many :subscriptions
6 has_many :magazines, :through => :subscriptions
7end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/users.yml b/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/users.yml
deleted file mode 100644
index da94fea..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/fixtures/users.yml
+++ /dev/null
@@ -1,7 +0,0 @@
1jonathan:
2 id: 1
3 name: Jonathan
4
5sam:
6 id: 2
7 name: Sam
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/tag_list_test.rb b/vendor/plugins/acts_as_taggable_on_steroids/test/tag_list_test.rb
deleted file mode 100644
index d0d135c..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/tag_list_test.rb
+++ /dev/null
@@ -1,106 +0,0 @@
1require File.dirname(__FILE__) + '/abstract_unit'
2
3class TagListTest < Test::Unit::TestCase
4 def test_from_leaves_string_unchanged
5 tags = '"One ", Two'
6 original = tags.dup
7 TagList.from(tags)
8 assert_equal tags, original
9 end
10
11 def test_from_single_name
12 assert_equal %w(Fun), TagList.from("Fun")
13 assert_equal %w(Fun), TagList.from('"Fun"')
14 end
15
16 def test_from_blank
17 assert_equal [], TagList.from(nil)
18 assert_equal [], TagList.from("")
19 end
20
21 def test_from_single_quoted_tag
22 assert_equal ['with, comma'], TagList.from('"with, comma"')
23 end
24
25 def test_spaces_do_not_delineate
26 assert_equal ['A B', 'C'], TagList.from('A B, C')
27 end
28
29 def test_from_multiple_tags
30 assert_equivalent %w(Alpha Beta Delta Gamma), TagList.from("Alpha, Beta, Delta, Gamma")
31 end
32
33 def test_from_multiple_tags_with_quotes
34 assert_equivalent %w(Alpha Beta Delta Gamma), TagList.from('Alpha, "Beta", Gamma , "Delta"')
35 end
36
37 def test_from_with_single_quotes
38 assert_equivalent ['A B', 'C'], TagList.from("'A B', C")
39 end
40
41 def test_from_multiple_tags_with_quote_and_commas
42 assert_equivalent ['Alpha, Beta', 'Delta', 'Gamma, something'], TagList.from('"Alpha, Beta", Delta, "Gamma, something"')
43 end
44
45 def test_from_removes_white_space
46 assert_equivalent %w(Alpha Beta), TagList.from('" Alpha ", "Beta "')
47 assert_equivalent %w(Alpha Beta), TagList.from(' Alpha, Beta ')
48 end
49
50 def test_from_removes_dots
51 assert_equivalent %w(Alpha Beta), TagList.from('Alpha., Beta')
52 assert_equivalent %w(Alpha Beta), TagList.from('Alpha, Be.ta')
53 end
54
55 def test_alternative_delimiter
56 TagList.delimiter = " "
57
58 assert_equal %w(One Two), TagList.from("One Two")
59 assert_equal ['One two', 'three', 'four'], TagList.from('"One two" three four')
60 ensure
61 TagList.delimiter = ","
62 end
63
64 def test_duplicate_tags_removed
65 assert_equal %w(One), TagList.from("One, One")
66 end
67
68 def test_to_s_with_commas
69 assert_equal "Question, Crazy Animal", TagList.new("Question", "Crazy Animal").to_s
70 end
71
72 def test_to_s_with_alternative_delimiter
73 TagList.delimiter = " "
74
75 assert_equal '"Crazy Animal" Question', TagList.new("Crazy Animal", "Question").to_s
76 ensure
77 TagList.delimiter = ","
78 end
79
80 def test_add
81 tag_list = TagList.new("One")
82 assert_equal %w(One), tag_list
83
84 assert_equal %w(One Two), tag_list.add("Two")
85 assert_equal %w(One Two Three), tag_list.add(["Three"])
86 end
87
88 def test_remove
89 tag_list = TagList.new("One", "Two")
90 assert_equal %w(Two), tag_list.remove("One")
91 assert_equal %w(), tag_list.remove(["Two"])
92 end
93
94 def test_new_with_parsing
95 assert_equal %w(One Two), TagList.new("One, Two", :parse => true)
96 end
97
98 def test_add_with_parsing
99 assert_equal %w(One Two), TagList.new.add("One, Two", :parse => true)
100 end
101
102 def test_remove_with_parsing
103 tag_list = TagList.from("Three, Four, Five")
104 assert_equal %w(Four), tag_list.remove("Three, Five", :parse => true)
105 end
106end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/tag_test.rb b/vendor/plugins/acts_as_taggable_on_steroids/test/tag_test.rb
deleted file mode 100644
index 4ca577d..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/tag_test.rb
+++ /dev/null
@@ -1,34 +0,0 @@
1require File.dirname(__FILE__) + '/abstract_unit'
2
3class TagTest < Test::Unit::TestCase
4 fixtures :tags, :taggings, :users, :photos, :posts
5
6 def test_name_required
7 t = Tag.create
8 assert_match /blank/, t.errors[:name].to_s
9 end
10
11 def test_name_unique
12 t = Tag.create!(:name => "My tag")
13 duplicate = t.clone
14
15 assert !duplicate.save
16 assert_match /taken/, duplicate.errors[:name].to_s
17 end
18
19 def test_taggings
20 assert_equivalent [taggings(:jonathan_sky_good), taggings(:sam_flowers_good), taggings(:sam_flower_good), taggings(:ruby_good)], tags(:good).taggings
21 assert_equivalent [taggings(:sam_ground_bad), taggings(:jonathan_bad_cat_bad)], tags(:bad).taggings
22 end
23
24 def test_to_s
25 assert_equal tags(:good).name, tags(:good).to_s
26 end
27
28 def test_equality
29 assert_equal tags(:good), tags(:good)
30 assert_equal Tag.find(1), Tag.find(1)
31 assert_equal Tag.new(:name => 'A'), Tag.new(:name => 'A')
32 assert_not_equal Tag.new(:name => 'A'), Tag.new(:name => 'B')
33 end
34end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/tagging_test.rb b/vendor/plugins/acts_as_taggable_on_steroids/test/tagging_test.rb
deleted file mode 100644
index 172b8e2..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/tagging_test.rb
+++ /dev/null
@@ -1,13 +0,0 @@
1require File.dirname(__FILE__) + '/abstract_unit'
2
3class TaggingTest < Test::Unit::TestCase
4 fixtures :tags, :taggings, :posts
5
6 def test_tag
7 assert_equal tags(:good), taggings(:jonathan_sky_good).tag
8 end
9
10 def test_taggable
11 assert_equal posts(:jonathan_sky), taggings(:jonathan_sky_good).taggable
12 end
13end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/test/tags_helper_test.rb b/vendor/plugins/acts_as_taggable_on_steroids/test/tags_helper_test.rb
deleted file mode 100644
index 9c3ce53..0000000
--- a/vendor/plugins/acts_as_taggable_on_steroids/test/tags_helper_test.rb
+++ /dev/null
@@ -1,28 +0,0 @@
1require File.dirname(__FILE__) + '/abstract_unit'
2
3class TagsHelperTest < Test::Unit::TestCase
4 fixtures :tags, :taggings, :posts
5
6 include TagsHelper
7
8 def test_tag_cloud
9 cloud_elements = []
10
11 tag_cloud Post.tag_counts, %w(css1 css2 css3 css4) do |tag, css_class|
12 cloud_elements << [tag, css_class]
13 end
14
15 assert_equal [
16 [tags(:good), "css2"],
17 [tags(:bad), "css1"],
18 [tags(:nature), "css4"],
19 [tags(:question), "css1"]
20 ], cloud_elements
21 end
22
23 def test_tag_cloud_when_no_tags
24 tag_cloud SpecialPost.tag_counts, %w(css1) do
25 assert false, "tag_cloud should not yield"
26 end
27 end
28end
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/MIT-LICENSE b/vendor/plugins/acts_as_taggable_redux/MIT-LICENSE
index 602bda2..c28cad7 100644
--- a/vendor/plugins/acts_as_taggable_on_steroids/MIT-LICENSE
+++ b/vendor/plugins/acts_as_taggable_redux/MIT-LICENSE
@@ -1,4 +1,4 @@
1Copyright (c) 2006 Jonathan Viney 1Copyright (c) 2007 monki(Wesley Beary)
2 2
3Permission is hereby granted, free of charge, to any person obtaining 3Permission is hereby granted, free of charge, to any person obtaining
4a copy of this software and associated documentation files (the 4a copy of this software and associated documentation files (the
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 17NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 18LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 19OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/README b/vendor/plugins/acts_as_taggable_redux/README
new file mode 100644
index 0000000..d2ea032
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/README
@@ -0,0 +1,143 @@
1ActsAsTaggableRedux
2===================
3
4Allows for user owned tags to be added to multiple classes, and makes tags easier to work with.
5
6
7Prerequisites
8=============
9
10Install Edge Rails before you get started so you get RESTful routing.
11
12ActsAsTaggableRedux depends on database tables to store tagging information. Create the migration for these tables with this command:
13
14 rake acts_as_taggable:db:create
15
16Then run the migration to create the tables with this command:
17
18 rake db:migrate
19
20Also you will need to add this to your user model:
21 acts_as_tagger
22
23OPTIONAL: The helper functions assume the pressence of a tags controller, that is what the tag clouds and tags will link to.
24
25OPTIONAL: To pretty up tag clouds and lists you can generate an example stylesheet with this command:
26
27 rake acts_as_taggable:stylesheet:create
28
29and then include this in your layouts that have tag clouds:
30
31 <%= stylesheet_link_tag 'acts_as_taggable_stylesheet' %>
32
33
34Example
35=======
36
37The following is an example of how you might integrate tags with an Item model.
38
39config/routes.rb
40 may.resource :items, :tags
41
42
43app/views/items/new.erb
44 <h1>New Item</h1>
45
46 <% form_for(:item, @item) do |f| -%>
47
48 <%= error_message_for :item %>
49
50 <b>Tags:</b> <%= f.text_field :tag_list -%>
51
52 <%= submit_tag "Save" -%>
53
54 <% end -%>
55
56if you want users to own taggings change the tags line to this
57 <b>Tags:</b> <%= f.text_field :tag_list, :value => @item.tag_list(user) -%>
58and add this line beneath it
59 <%= f.hidden_field :user_id, :value => user.id -%>
60
61app/views/items/show.erb
62 Item tagged with:
63 <% item.tags.each do |tag| -%>
64 <%= link_to_tag(tag) %>
65 <% end -%>
66
67app/views/items/edit.erb
68 <h1>New Item</h1>
69
70 <% form_for(:item, @item, :html => { :method => :post }) do |f| -%>
71
72 <%= error_messages_for :item %>
73
74 <b>Tags:</b> <%= f.text_field :tag_list -%>
75
76 <%= submit_tag "Save" -%>
77
78 <% end -%>
79
80
81app/controllers/items_controller.rb
82 class ItemController < ApplicationController
83 def new
84 @item = Item.new
85 end
86
87 def create
88 @item = Item.new(params[:item])
89
90 respond_to do |format|
91 if @item.save
92 flash[:notice] = 'Item was successfully created.'
93 format.html { redirect_to item_url(@item) }
94 format.xml { head :created, :location => item_url(@item) }
95 else
96 format.html { render :action => "new" }
97 format.xml { render :xml => @item.errors.to_xml }
98 end
99 end
100 end
101
102 def show
103 @item = Item.find(params[:id], :include => :tags)
104 end
105
106 def edit
107 @item = Item.find(params[:id])
108 end
109
110 def update
111 @item = Item.find(params[:id])
112
113 respond_to do |format|
114 if @item.update_attributes(params[:item])
115 flash[:notice] = 'Item was successfully updated.'
116 format.html { redirect_to item_url(@item) }
117 format.xml { head :updated, :location => item_url(@item) }
118 end
119 format.html { render :action => "edit"}
120 format.xml { render :xml => @item.errors.to_xml}
121 end
122 end
123 end
124
125
126
127Tag clouds
128==========
129
130Tag clouds are created by a helper function, and depend on the counter cache to get fast accurate counts. To ensure this keeps working properly, don't add new tags to a taggable in any way other than using the tag.tag(taggable) style. This will ensure that the caches don't lose track. Also, see the prerequisites for installing the stylesheet so that the tag cloud actually looks like a tag cloud. Otherwise, just pop into a view that you want the tag cloud to appear and type this:
131
132 <%= tag_cloud %>
133
134
135
136Contributing
137============
138
139Welcoming all pull requests on github.com at http://github.com/monki/acts_as_taggable_redux/tree/master or git://github.com/monki/acts_as_taggable_redux.git
140
141
142
143Copyright (c) 2008 monki(Wesley Beary), released under the MIT license \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_on_steroids/Rakefile b/vendor/plugins/acts_as_taggable_redux/Rakefile
index d2c0003..3c968e2 100644
--- a/vendor/plugins/acts_as_taggable_on_steroids/Rakefile
+++ b/vendor/plugins/acts_as_taggable_redux/Rakefile
@@ -5,17 +5,17 @@ require 'rake/rdoctask'
5desc 'Default: run unit tests.' 5desc 'Default: run unit tests.'
6task :default => :test 6task :default => :test
7 7
8desc 'Test the acts_as_taggable_on_steroids plugin.' 8desc 'Test the acts_as_taggable_redux plugin.'
9Rake::TestTask.new(:test) do |t| 9Rake::TestTask.new(:test) do |t|
10 t.libs << 'lib' 10 t.libs << 'lib'
11 t.pattern = 'test/**/*_test.rb' 11 t.pattern = 'test/**/*_test.rb'
12 t.verbose = true 12 t.verbose = true
13end 13end
14 14
15desc 'Generate documentation for the acts_as_taggable_on_steroids plugin.' 15desc 'Generate documentation for the acts_as_taggable_redux plugin.'
16Rake::RDocTask.new(:rdoc) do |rdoc| 16Rake::RDocTask.new(:rdoc) do |rdoc|
17 rdoc.rdoc_dir = 'rdoc' 17 rdoc.rdoc_dir = 'rdoc'
18 rdoc.title = 'Acts As Taggable On Steroids' 18 rdoc.title = 'ActsAsTaggableRedux'
19 rdoc.options << '--line-numbers' << '--inline-source' 19 rdoc.options << '--line-numbers' << '--inline-source'
20 rdoc.rdoc_files.include('README') 20 rdoc.rdoc_files.include('README')
21 rdoc.rdoc_files.include('lib/**/*.rb') 21 rdoc.rdoc_files.include('lib/**/*.rb')
diff --git a/vendor/plugins/acts_as_taggable_redux/acts_as_taggable_redux.gemspec b/vendor/plugins/acts_as_taggable_redux/acts_as_taggable_redux.gemspec
new file mode 100644
index 0000000..9ea8dc1
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/acts_as_taggable_redux.gemspec
@@ -0,0 +1,44 @@
1Gem::Specification.new do |s|
2 s.name = 'acts_as_taggable_redux'
3 s.version = '0.0.1'
4 s.date = '2008-12-06'
5
6 s.summary = 'Allows for user owned tags to be added to multiple classes, and makes tags easier to work with.'
7 s.description = 'Allows for user owned tags to be added to multiple classes, and makes tags easier to work with.'
8
9 s.authors = ['Wesley Beary']
10 s.email = 'monki@geemus.com'
11 s.homepage = 'http://github.com/monki/acts_as_taggable_redux'
12
13 s.has_rdoc = false
14 s.files = [
15 'generators/acts_as_taggable_tables/templates/migration.rb',
16 'generators/acts_as_taggable_tables/acts_as_taggable_tables_generator.rb',
17 'generators/acts_as_taggable_stylesheet/templates/acts_as_taggable_stylesheet.css',
18 'generators/acts_as_taggable_stylesheet/acts_as_taggable_stylesheet_generator.rb',
19 'init.rb',
20 'lib/acts_as_taggable.rb',
21 'lib/acts_as_tagger.rb',
22 'lib/acts_as_taggable_helper.rb',
23 'lib/acts_as_taggable_redux.rb',
24 'lib/tag.rb',
25 'lib/tagging.rb',
26 'MIT-LICENSE',
27 'Rakefile',
28 'README',
29 'tasks/acts_as_taggable_tasks.rake',
30 'test/tagging_test.rb',
31 'test/debug.log',
32 'test/test_helper.rb',
33 'test/fixtures/users.yml',
34 'test/fixtures/tags.yml',
35 'test/fixtures/things.yml',
36 'test/fixtures/thing.rb',
37 'test/fixtures/taggings.yml',
38 'test/fixtures/user.rb',
39 'test/acts_as_taggable_test.rb',
40 'test/tag_test.rb',
41 'test/database.yml',
42 'test/schema.rb'
43 ]
44end
diff --git a/vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_stylesheet/acts_as_taggable_stylesheet_generator.rb b/vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_stylesheet/acts_as_taggable_stylesheet_generator.rb
new file mode 100644
index 0000000..5eb60b8
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_stylesheet/acts_as_taggable_stylesheet_generator.rb
@@ -0,0 +1,7 @@
1class ActsAsTaggableStylesheetGenerator < Rails::Generator::Base
2 def manifest
3 record do |m|
4 m.file "acts_as_taggable_stylesheet.css", "public/stylesheets/acts_as_taggable_stylesheet.css"
5 end
6 end
7end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_stylesheet/templates/acts_as_taggable_stylesheet.css b/vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_stylesheet/templates/acts_as_taggable_stylesheet.css
new file mode 100644
index 0000000..b1c86de
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_stylesheet/templates/acts_as_taggable_stylesheet.css
@@ -0,0 +1,7 @@
1.hTagcloud .popularity { margin:0; padding:0; }
2.hTagcloud .popularity li { display:inline; text-decoration:none; }
3.hTagcloud .popularity .popular { font-size:1.0em; }
4.hTagcloud .popularity .v-popular { font-size:1.2em; }
5.hTagcloud .popularity .vv-popular { font-size:1.4em; }
6.hTagcloud .popularity .vvv-popular { font-size:1.6em; }
7.hTagcloud .popularity .vvvv-popular { font-size:1.8em; } \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_tables/acts_as_taggable_tables_generator.rb b/vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_tables/acts_as_taggable_tables_generator.rb
new file mode 100644
index 0000000..f6d3e51
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_tables/acts_as_taggable_tables_generator.rb
@@ -0,0 +1,7 @@
1class ActsAsTaggableTablesGenerator < Rails::Generator::NamedBase
2 def manifest
3 record do |m|
4 m.migration_template 'migration.rb', 'db/migrate'
5 end
6 end
7end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_tables/templates/migration.rb b/vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_tables/templates/migration.rb
new file mode 100644
index 0000000..335ef6c
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/generators/acts_as_taggable_tables/templates/migration.rb
@@ -0,0 +1,29 @@
1class AddActsAsTaggableTables < ActiveRecord::Migration
2 def self.up
3 create_table :tags do |t|
4 t.column :name, :string
5 t.column :taggings_count, :integer, :default => 0, :null => false
6 end
7 add_index :tags, :name
8 add_index :tags, :taggings_count
9
10 create_table :taggings do |t|
11 t.column :tag_id, :integer
12 t.column :taggable_id, :integer
13 t.column :taggable_type, :string
14 t.column :user_id, :integer
15 end
16
17 # Find objects for a tag
18 add_index :taggings, [:tag_id, :taggable_type]
19 add_index :taggings, [:user_id, :tag_id, :taggable_type]
20 # Find tags for an object
21 add_index :taggings, [:taggable_id, :taggable_type]
22 add_index :taggings, [:user_id, :taggable_id, :taggable_type]
23 end
24
25 def self.down
26 drop_table :tags
27 drop_table :taggings
28 end
29end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/init.rb b/vendor/plugins/acts_as_taggable_redux/init.rb
new file mode 100644
index 0000000..bcc3499
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/init.rb
@@ -0,0 +1 @@
require 'acts_as_taggable_redux'
diff --git a/vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable.rb b/vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable.rb
new file mode 100644
index 0000000..6b5e8b9
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable.rb
@@ -0,0 +1,136 @@
1module ActiveRecord
2 module Acts #:nodoc:
3 module Taggable #:nodoc:
4 def self.included(base)
5 base.extend(ClassMethods)
6 end
7
8 module ClassMethods
9 def acts_as_taggable(options = {})
10 has_many :taggings, :as => :taggable, :dependent => :destroy, :include => :tag
11 has_many :tags, :through => :taggings, :order => 'LOWER(name) asc', :select => "DISTINCT tags.*"
12
13 after_save :update_tags
14
15 extend ActiveRecord::Acts::Taggable::SingletonMethods
16 include ActiveRecord::Acts::Taggable::InstanceMethods
17 end
18 end
19
20 module SingletonMethods
21 # Pass a tag string, returns taggables that match the tag string.
22 #
23 # Options:
24 # :match - Match taggables matching :all or :any of the tags, defaults to :any
25 # :user - Limits results to those owned by a particular user
26 def find_tagged_with(tags, options = {})
27 tagged_with_scope(tags, options) do
28 find(:all, :select => "DISTINCT #{table_name}.*")
29 end
30 end
31
32 def tagged_with_scope(tags, options={})
33 options.assert_valid_keys([:match, :order, :user])
34
35 tags = Tag.parse(tags)
36 return [] if tags.empty?
37
38 group = "#{table_name}_taggings.taggable_id HAVING COUNT(#{table_name}_taggings.taggable_id) >= #{tags.size}" if options[:match] == :all
39 conditions = sanitize_sql(["#{table_name}_tags.name IN (?)", tags])
40 conditions += sanitize_sql([" AND #{table_name}_taggings.user_id = ?", options[:user]]) if options[:user]
41
42 find_parameters = {
43 :joins => "LEFT OUTER JOIN #{Tagging.table_name} #{table_name}_taggings ON #{table_name}_taggings.taggable_id = #{table_name}.#{primary_key} AND #{table_name}_taggings.taggable_type = '#{name}' " +
44 "LEFT OUTER JOIN #{Tag.table_name} #{table_name}_tags ON #{table_name}_tags.id = #{table_name}_taggings.tag_id",
45 :conditions => conditions,
46 :group => group,
47 :order => options[:order]
48 }
49
50 with_scope(:find => find_parameters) { yield }
51 end
52
53 # Pass a tag string, returns taggables that match the tag string for a particular user.
54 #
55 # Options:
56 # :match - Match taggables matching :all or :any of the tags, defaults to :any
57 def find_tagged_with_by_user(tags, user, options = {})
58 options.assert_valid_keys([:match, :order])
59 find_tagged_with(tags, {:match => options[:match], :order => options[:order], :user => user})
60 end
61
62 # Returns an array of related tags.
63 # Related tags are all the other tags that are found on the models tagged with the provided tags.
64 #
65 # Pass either a tag, string, or an array of strings or tags.
66 #
67 # Options:
68 # :order - SQL Order how to order the tags. Defaults to "count DESC, tags.name".
69 # :match - Match taggables matching :all or :any of the tags, defaults to :any
70 def find_related_tags(tags, options = {})
71 #duplicated work, the tags are parsed twice. I need to elimidate this by making find_tagged_with
72 #accept an array of tags and not just a string
73 parsed_tags = Tag.parse(tags)
74 related_models = find_tagged_with(tags, :match => options.delete(:match))
75
76 return [] if related_models.blank?
77
78 related_ids = related_models.to_s(:db)
79
80 Tag.find(:all, options.merge({
81 :select => "#{Tag.table_name}.*, COUNT(#{Tag.table_name}.id) AS count",
82 :joins => "JOIN #{Tagging.table_name} ON #{Tagging.table_name}.taggable_type = '#{base_class.name}'
83AND #{Tagging.table_name}.taggable_id IN (#{related_ids})
84AND #{Tagging.table_name}.tag_id = #{Tag.table_name}.id",
85 :order => options[:order] || "count DESC, #{Tag.table_name}.name",
86 :group => "#{Tag.table_name}.id, #{Tag.table_name}.name HAVING #{Tag.table_name}.name NOT IN (#{parsed_tags.map { |n| quote_value(n) }.join(",")})"
87 }))
88 end
89 end
90
91 module InstanceMethods
92 def tag_list=(new_tag_list)
93 unless tag_list == new_tag_list
94 @new_tag_list = new_tag_list
95 end
96 end
97
98 def user_id=(new_user_id)
99 @new_user_id = new_user_id
100 super(new_user_id)
101 end
102
103 def tag_list(user = nil)
104 unless user
105 result = tags.collect { |tag| tag.name.include?(" ") ? %("#{tag.name}") : tag.name }.join(" ")
106 else
107 #TODO: make it work if I pass in an int instead of a user object
108 tags.find(:all, :conditions => ["#{Tagging.table_name}.user_id = ?", user.id]).collect { |tag| tag.name.include?(" ") ? %("#{tag.name}") : tag.name }.uniq.join(" ")
109 end
110 end
111
112 def update_tags
113 if @new_tag_list
114 Tag.transaction do
115 unless @new_user_id
116 taggings.destroy_all
117 else
118 taggings.find(:all, :conditions => "user_id = #{@new_user_id}").each do |tagging|
119 tagging.destroy
120 end
121 end
122
123 Tag.parse(@new_tag_list).each do |name|
124 Tag.find_or_create_by_name(name).tag(self, @new_user_id)
125 end
126
127 tags.reset
128 taggings.reset
129 @new_tag_list = nil
130 end
131 end
132 end
133 end
134 end
135 end
136end
diff --git a/vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable_helper.rb b/vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable_helper.rb
new file mode 100644
index 0000000..87bc29a
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable_helper.rb
@@ -0,0 +1,38 @@
1module ActsAsTaggableHelper
2 # Create a link to the tag using restful routes and the rel-tag microformat
3 def link_to_tag(tag)
4 link_to(tag.name, tag_url(tag), :rel => 'tag')
5 end
6
7 # Generate a tag cloud of the top 100 tags by usage, uses the proposed hTagcloud microformat.
8 #
9 # Inspired by http://www.juixe.com/techknow/index.php/2006/07/15/acts-as-taggable-tag-cloud/
10 def tag_cloud(options = {})
11 options.assert_valid_keys(:limit, :conditions, :sort)
12 options.reverse_merge! :limit => 100, :sort => :name
13 sort = options.delete(:sort)
14
15 tags = Tag.find(:all, options.merge(:order => 'taggings_count DESC')).sort_by(&sort)
16
17 # TODO: add option to specify which classes you want and overide this if you want?
18 classes = %w(popular v-popular vv-popular vvv-popular vvvv-popular)
19
20 max, min = 0, 0
21 tags.each do |tag|
22 max = tag.taggings_count if tag.taggings_count > max
23 min = tag.taggings_count if tag.taggings_count < min
24 end
25
26 divisor = ((max - min) / classes.size) + 1
27
28 html = %(<div class="hTagcloud">\n)
29 html << %( <ul class="popularity">\n)
30 tags.each do |tag|
31 html << %( <li>)
32 html << link_to(tag.name, tag_url(tag), :class => classes[(tag.taggings_count - min) / divisor])
33 html << %(</li> \n)
34 end
35 html << %( </ul>\n)
36 html << %(</div>\n)
37 end
38end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable_redux.rb b/vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable_redux.rb
new file mode 100644
index 0000000..c5090ae
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/lib/acts_as_taggable_redux.rb
@@ -0,0 +1,9 @@
1require 'acts_as_taggable'
2require 'acts_as_tagger'
3
4ActiveRecord::Base.send(:include, ActiveRecord::Acts::Taggable)
5ActiveRecord::Base.send(:include, ActiveRecord::Acts::Tagger)
6ActionView::Base.send(:include, ActsAsTaggableHelper)
7
8require 'tagging'
9require 'tag'
diff --git a/vendor/plugins/acts_as_taggable_redux/lib/acts_as_tagger.rb b/vendor/plugins/acts_as_taggable_redux/lib/acts_as_tagger.rb
new file mode 100644
index 0000000..16fc654
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/lib/acts_as_tagger.rb
@@ -0,0 +1,25 @@
1module ActiveRecord
2 module Acts #:nodoc:
3 module Tagger #:nodoc:
4 def self.included(base)
5 base.extend(ClassMethods)
6 end
7
8 module ClassMethods
9 def acts_as_tagger(options = {})
10 has_many :taggings
11 has_many :tags, :through => :taggings, :select => "DISTINCT #{Tag.table_name}.*", :order => "LOWER(name) asc"
12
13 extend ActiveRecord::Acts::Tagger::SingletonMethods
14 include ActiveRecord::Acts::Tagger::InstanceMethods
15 end
16 end
17
18 module SingletonMethods
19 end
20
21 module InstanceMethods
22 end
23 end
24 end
25end
diff --git a/vendor/plugins/acts_as_taggable_redux/lib/tag.rb b/vendor/plugins/acts_as_taggable_redux/lib/tag.rb
new file mode 100644
index 0000000..30362fc
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/lib/tag.rb
@@ -0,0 +1,73 @@
1class Tag < ActiveRecord::Base
2 has_many :taggings
3
4 # Parse a text string into an array of tokens for use as tags
5 def self.parse(list)
6 tag_names = []
7
8 return tag_names if list.blank?
9
10 # first, pull out the quoted tags
11 list.gsub!(/\"(.*?)\"\s*/) { tag_names << $1; "" }
12
13 # then, replace all commas with a space
14 list.gsub!(/,/, " ")
15
16 # then, get whatever is left
17 tag_names.concat(list.split(/\s/))
18
19 # delete any blank tag names
20 tag_names = tag_names.delete_if { |t| t.empty? }
21
22 # downcase all tags
23 tag_names = tag_names.map! { |t| t.downcase }
24
25 # remove duplicates
26 tag_names = tag_names.uniq
27
28 return tag_names
29 end
30
31 # Grab a distinct list of tags only for a particular type of taggable.
32 # For example, if you had a taggable Foo, you could get all tags used on Foo via:
33 #
34 # Tag.with_type_scope('Foo') { Tag.find(:all) }
35 #
36 # If no parameter is given, the scope does not take effect.
37 #
38 # pass in a user id to have it scope by user_id as well
39
40 def self.with_type_scope(taggable_type, user = nil)
41 if taggable_type
42 conditions = sanitize_sql(["taggable_type = ?", taggable_type])
43 conditions += sanitize_sql([" AND #{Tagging.table_name}.user_id = ?", user.id]) if user
44 with_scope(:find => {:select => "distinct #{Tag.table_name}.*", :joins => "left outer join #{Tagging.table_name} on #{Tagging.table_name}.tag_id = #{Tag.table_name}.id", :conditions => conditions, :group => "name"}) { yield }
45 else
46 yield
47 end
48 end
49
50 # Tag a taggable with this tag, optionally add user to add owner to tagging
51 def tag(taggable, user_id = nil)
52 taggings.create :taggable => taggable, :user_id => user_id
53 taggings.reset
54 @tagged = nil
55 end
56
57 # A list of all the objects tagged with this tag
58 def tagged
59 @tagged ||= taggings.collect(&:taggable)
60 end
61
62 # Compare tags by name
63 def ==(comparison_object)
64 super || name == comparison_object.to_s
65 end
66
67 # Return the tag's name
68 def to_s
69 name
70 end
71
72 validates_presence_of :name
73end
diff --git a/vendor/plugins/acts_as_taggable_redux/lib/tagging.rb b/vendor/plugins/acts_as_taggable_redux/lib/tagging.rb
new file mode 100644
index 0000000..cbdf8f5
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/lib/tagging.rb
@@ -0,0 +1,5 @@
1class Tagging < ActiveRecord::Base
2 belongs_to :tag, :counter_cache => true
3 belongs_to :taggable, :polymorphic => true
4 belongs_to :user
5end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/tasks/acts_as_taggable_tasks.rake b/vendor/plugins/acts_as_taggable_redux/tasks/acts_as_taggable_tasks.rake
new file mode 100644
index 0000000..db400c5
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/tasks/acts_as_taggable_tasks.rake
@@ -0,0 +1,20 @@
1namespace :acts_as_taggable do
2 namespace :db do
3 desc "Creates tag tables for use with acts_as_taggable"
4 task :create => :environment do
5 require 'rails_generator'
6 require 'rails_generator/scripts/generate'
7 raise "Task unavailable to this database (no migration support)" unless ActiveRecord::Base.connection.supports_migrations?
8 Rails::Generator::Scripts::Generate.new.run([ "acts_as_taggable_tables", "add_acts_as_taggable_tables" ])
9 end
10 end
11
12 namespace :stylesheet do
13 desc "Create tag stylesheet for use with acts_as_taggable"
14 task :create => :environment do
15 require 'rails_generator'
16 require 'rails_generator/scripts/generate'
17 Rails::Generator::Scripts::Generate.new.run([ "acts_as_taggable_stylesheet" ])
18 end
19 end
20end
diff --git a/vendor/plugins/acts_as_taggable_redux/test/acts_as_taggable_test.rb b/vendor/plugins/acts_as_taggable_redux/test/acts_as_taggable_test.rb
new file mode 100644
index 0000000..6e63813
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/test/acts_as_taggable_test.rb
@@ -0,0 +1,34 @@
1require File.dirname(__FILE__) + "/test_helper"
2
3class ActsAsTaggableTest < Test::Unit::TestCase
4 def test_find_tagged_with_any
5 assert_equal [things(:bear), things(:frog)].sort_by(&:id), Thing.find_tagged_with("animal")
6 assert_equal [things(:bear), things(:frog), things(:cactus)].sort_by(&:id), Thing.find_tagged_with("animal green")
7 assert_equal [], Thing.find_tagged_with("fake")
8
9 assert_equal [things(:bear), things(:frog)].sort_by(&:id), Thing.find_tagged_with("animal", :match => :any)
10 assert_equal [things(:bear), things(:frog), things(:cactus)].sort_by(&:id), Thing.find_tagged_with("animal green", :match => :any)
11 assert_equal [], Thing.find_tagged_with("fake", :match => :any)
12 end
13
14 def test_find_tagged_with_all
15 assert_equal [things(:bear), things(:frog)].sort_by(&:id), Thing.find_tagged_with("animal", :match => :all)
16 assert_equal [things(:frog)].sort_by(&:id), Thing.find_tagged_with("animal green", :match => :all)
17 assert_equal [], Thing.find_tagged_with("fake", :match => :all)
18 assert_equal [], Thing.find_tagged_with("animal plant", :match => :all)
19 end
20
21 def test_tag_list
22 assert_equal things(:bear).tag_list, "animal \"not green\""
23 assert_equal things(:frog).tag_list, "animal green"
24 assert_not_equal things(:frog).tag_list, "animal \"not green\""
25 end
26
27 def test_update_tags
28 assert_equal things(:bear).tag_list, "animal \"not green\""
29 things(:bear).tag_list = 'animal "not green" favorite'
30 assert_equal things(:bear).tag_list, "animal \"not green\""
31 things(:bear).update_tags
32 assert_equal things(:bear).tag_list, "animal favorite \"not green\""
33 end
34end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/test/debug.log b/vendor/plugins/acts_as_taggable_redux/test/debug.log
new file mode 100644
index 0000000..b736308
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/test/debug.log
@@ -0,0 +1,104 @@
1# Logfile created on Thu May 15 14:17:58 -0500 2008 by logger.rb/1.5.2.9
2 SQL (0.000346) select sqlite_version(*)
3 SQL (0.000000) SQLite3::SQLException: no such table: tags: DROP TABLE tags
4 SQL (0.000336) CREATE TABLE tags ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) DEFAULT NULL, "taggings_count" integer DEFAULT 0 NOT NULL) 
5 SQL (0.000171) CREATE INDEX "index_tags_on_name" ON tags ("name")
6 SQL (0.000153) CREATE INDEX "index_tags_on_taggings_count" ON tags ("taggings_count")
7 SQL (0.000000) SQLite3::SQLException: no such table: taggings: DROP TABLE taggings
8 SQL (0.000188) CREATE TABLE taggings ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "tag_id" integer DEFAULT NULL, "taggable_id" integer DEFAULT NULL, "taggable_type" varchar(255) DEFAULT NULL, "user_id" integer DEFAULT NULL) 
9 SQL (0.000153) CREATE INDEX "index_taggings_on_tag_id_and_taggable_type" ON taggings ("tag_id", "taggable_type")
10 SQL (0.000166) CREATE INDEX "index_taggings_on_user_id_and_tag_id_and_taggable_type" ON taggings ("user_id", "tag_id", "taggable_type")
11 SQL (0.000156) CREATE INDEX "index_taggings_on_taggable_id_and_taggable_type" ON taggings ("taggable_id", "taggable_type")
12 SQL (0.000161) CREATE INDEX "index_taggings_on_user_id_and_taggable_id_and_taggable_type" ON taggings ("user_id", "taggable_id", "taggable_type")
13 SQL (0.000000) SQLite3::SQLException: no such table: things: DROP TABLE things
14 SQL (0.000176) CREATE TABLE things ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) DEFAULT NULL) 
15 SQL (0.000000) SQLite3::SQLException: no such table: users: DROP TABLE users
16 SQL (0.000177) CREATE TABLE users ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "username" varchar(255) DEFAULT NULL) 
17 SQL (0.000184) CREATE TABLE schema_info (version integer)
18 SQL (0.000069) INSERT INTO schema_info (version) VALUES(0)
19 SQL (0.000082) UPDATE schema_info SET version = 0
20 Thing Load (0.000163) SELECT * FROM things WHERE (things."id" = 1) 
21 Thing Load (0.000162) SELECT * FROM things WHERE (things."id" = 2) 
22 Thing Load (0.001725) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal')) GROUP BY things_taggings.taggable_id HAVING COUNT(things_taggings.taggable_id) = 1
23 Thing Load (0.001072) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal','green')) GROUP BY things_taggings.taggable_id HAVING COUNT(things_taggings.taggable_id) = 2
24 Thing Load (0.000946) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('fake')) GROUP BY things_taggings.taggable_id HAVING COUNT(things_taggings.taggable_id) = 1
25 Thing Load (0.000893) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal','plant')) GROUP BY things_taggings.taggable_id HAVING COUNT(things_taggings.taggable_id) = 2
26 Thing Load (0.000182) SELECT * FROM things WHERE (things."id" = 1) 
27 Thing Load (0.000160) SELECT * FROM things WHERE (things."id" = 2) 
28 Thing Load (0.000919) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal')) 
29 Thing Load (0.000181) SELECT * FROM things WHERE (things."id" = 3) 
30 Thing Load (0.000909) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal','green')) 
31 Thing Load (0.001076) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('fake')) 
32 Thing Load (0.000792) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal')) 
33 Thing Load (0.000842) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('animal','green')) 
34 Thing Load (0.000694) SELECT DISTINCT things.* FROM things LEFT OUTER JOIN taggings things_taggings ON things_taggings.taggable_id = things.id AND things_taggings.taggable_type = 'Thing' LEFT OUTER JOIN tags things_tags ON things_tags.id = things_taggings.tag_id WHERE (things_tags.name IN ('fake')) 
35 Thing Load (0.000173) SELECT * FROM things WHERE (things."id" = 1) 
36 Tag Load (0.010343) SELECT tags.* FROM tags INNER JOIN taggings ON tags.id = taggings.tag_id WHERE ((taggings.taggable_type = 'Thing') AND (taggings.taggable_id = 1)) ORDER BY name asc
37 Thing Load (0.000226) SELECT * FROM things WHERE (things."id" = 2) 
38 Tag Load (0.000703) SELECT tags.* FROM tags INNER JOIN taggings ON tags.id = taggings.tag_id WHERE ((taggings.taggable_type = 'Thing') AND (taggings.taggable_id = 2)) ORDER BY name asc
39 Thing Load (0.000232) SELECT * FROM things WHERE (things."id" = 1) 
40 Tag Load (0.000751) SELECT tags.* FROM tags INNER JOIN taggings ON tags.id = taggings.tag_id WHERE ((taggings.taggable_type = 'Thing') AND (taggings.taggable_id = 1)) ORDER BY name asc
41 Tagging Load Including Associations (0.000550) SELECT taggings."id" AS t0_r0, taggings."tag_id" AS t0_r1, taggings."taggable_id" AS t0_r2, taggings."taggable_type" AS t0_r3, taggings."user_id" AS t0_r4, tags."id" AS t1_r0, tags."name" AS t1_r1, tags."taggings_count" AS t1_r2 FROM taggings LEFT OUTER JOIN tags ON tags.id = taggings.tag_id WHERE (taggings.taggable_id = 1 AND taggings.taggable_type = 'Thing') 
42 Tag Update (0.000111) UPDATE tags SET "taggings_count" = "taggings_count" - 1 WHERE ("id" = 1) 
43 Tag Update (0.000093) UPDATE tags SET "taggings_count" = "taggings_count" - 1 WHERE ("id" = 1) 
44 Tagging Destroy (0.000096)  DELETE FROM taggings
45 WHERE "id" = 1
46
47 Tag Update (0.000095) UPDATE tags SET "taggings_count" = "taggings_count" - 1 WHERE ("id" = 4) 
48 Tag Update (0.000092) UPDATE tags SET "taggings_count" = "taggings_count" - 1 WHERE ("id" = 4) 
49 Tagging Destroy (0.000088)  DELETE FROM taggings
50 WHERE "id" = 2
51
52 Tag Load (0.000196) SELECT * FROM tags WHERE (tags."name" = 'not green') LIMIT 1
53 Tagging Create (0.000163) INSERT INTO taggings ("tag_id", "taggable_type", "taggable_id", "user_id") VALUES(4, 'Thing', 1, NULL)
54 Tag Load (0.000240) SELECT * FROM tags WHERE (tags."id" = 4) 
55 Tag Update (0.000105) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 4) 
56 Tag Update (0.000097) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 4) 
57 Tag Load (0.000217) SELECT * FROM tags WHERE (tags."name" = 'animal') LIMIT 1
58 Tagging Create (0.000175) INSERT INTO taggings ("tag_id", "taggable_type", "taggable_id", "user_id") VALUES(1, 'Thing', 1, NULL)
59 Tag Load (0.000225) SELECT * FROM tags WHERE (tags."id" = 1) 
60 Tag Update (0.000102) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 1) 
61 Tag Update (0.000093) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 1) 
62 Tag Load (0.000186) SELECT * FROM tags WHERE (tags."name" = 'favorite') LIMIT 1
63 Tagging Create (0.000114) INSERT INTO taggings ("tag_id", "taggable_type", "taggable_id", "user_id") VALUES(5, 'Thing', 1, NULL)
64 Tag Load (0.000177) SELECT * FROM tags WHERE (tags."id" = 5) 
65 Tag Update (0.000097) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 5) 
66 Tag Update (0.000091) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 5) 
67 Tag Load (0.000787) SELECT tags.* FROM tags INNER JOIN taggings ON tags.id = taggings.tag_id WHERE ((taggings.taggable_type = 'Thing') AND (taggings.taggable_id = 1)) ORDER BY name asc
68 Tag Load (0.000196) SELECT * FROM tags WHERE (tags."id" = 1) 
69 Tag Load (0.000176) SELECT * FROM tags WHERE (tags."id" = 1) 
70 Tag Load (0.000174) SELECT * FROM tags WHERE (tags."id" = 1) 
71 Tag Load (0.000208) SELECT * FROM tags WHERE (tags."id" = 5) 
72 Tagging Load (0.000101) SELECT * FROM taggings WHERE (taggings.tag_id = 5) 
73 Thing Load (0.000155) SELECT * FROM things WHERE (things."id" = 1) 
74 Tagging Create (0.000130) INSERT INTO taggings ("tag_id", "taggable_type", "taggable_id", "user_id") VALUES(5, 'Thing', 1, NULL)
75 Tag Load (0.000187) SELECT * FROM tags WHERE (tags."id" = 5) 
76 Tag Update (0.000100) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 5) 
77 Tag Update (0.000093) UPDATE tags SET "taggings_count" = "taggings_count" + 1 WHERE ("id" = 5) 
78 Tagging Load (0.000212) SELECT * FROM taggings WHERE (taggings.tag_id = 5) 
79 Thing Load (0.000158) SELECT * FROM things WHERE (things."id" = 1) 
80 Thing Load (0.000169) SELECT * FROM things WHERE (things."id" = 1) 
81 Thing Load (0.000189) SELECT * FROM things WHERE (things."id" = 2) 
82 Tag Load (0.000175) SELECT * FROM tags WHERE (tags."id" = 1) 
83 Tagging Load (0.000343) SELECT * FROM taggings WHERE (taggings.tag_id = 1) 
84 Thing Load (0.000282) SELECT * FROM things WHERE (things."id" = 1) 
85 Thing Load (0.000176) SELECT * FROM things WHERE (things."id" = 2) 
86 Tag Load (0.000228) SELECT * FROM tags WHERE (tags."id" = 2) 
87 Tagging Load (0.000357) SELECT * FROM taggings WHERE (taggings.tag_id = 2) 
88 Thing Load (0.000180) SELECT * FROM things WHERE (things."id" = 3) 
89 Thing Load (0.000172) SELECT * FROM things WHERE (things."id" = 4) 
90 Tagging Load (0.000268) SELECT * FROM taggings WHERE (taggings."id" = 1) 
91 Tagging Load (0.000233) SELECT * FROM taggings WHERE (taggings."id" = 3) 
92 Tag Load (0.000204) SELECT * FROM tags WHERE (tags."id" = 1) 
93 Tagging Load (0.000623) SELECT * FROM taggings WHERE (taggings.tag_id = 1) 
94 Tagging Load (0.000215) SELECT * FROM taggings WHERE (taggings."id" = 5) 
95 Tagging Load (0.000207) SELECT * FROM taggings WHERE (taggings."id" = 7) 
96 Tag Load (0.000195) SELECT * FROM tags WHERE (tags."id" = 1) 
97 Tag Load (0.000344) SELECT * FROM tags WHERE (tags."id" = 1) 
98 Tagging Load (0.000212) SELECT * FROM taggings WHERE (taggings."id" = 1) 
99 Tag Load (0.000175) SELECT * FROM tags WHERE (tags."id" = 1) 
100 Tag Load (0.000180) SELECT * FROM tags WHERE (tags."id" = 2) 
101 Thing Load (0.000163) SELECT * FROM things WHERE (things."id" = 1) 
102 Tagging Load (0.000216) SELECT * FROM taggings WHERE (taggings."id" = 1) 
103 Thing Load (0.000168) SELECT * FROM things WHERE (things."id" = 1) 
104 Thing Load (0.000159) SELECT * FROM things WHERE (things."id" = 2) 
diff --git a/vendor/plugins/acts_as_taggable_redux/test/fixtures/taggings.yml b/vendor/plugins/acts_as_taggable_redux/test/fixtures/taggings.yml
new file mode 100644
index 0000000..5cd86a5
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/test/fixtures/taggings.yml
@@ -0,0 +1,47 @@
1bear_animal:
2 id: 1
3 taggable_id: 1
4 taggable_type: Thing
5 tag_id: 1
6
7bear_not_green:
8 id: 2
9 taggable_id: 1
10 taggable_type: Thing
11 tag_id: 4
12
13frog_animal:
14 id: 3
15 taggable_id: 2
16 taggable_type: Thing
17 tag_id: 1
18
19frog_green:
20 id: 4
21 taggable_id: 2
22 taggable_type: Thing
23 tag_id: 3
24
25cactus_plant:
26 id: 5
27 taggable_id: 3
28 taggable_type: Thing
29 tag_id: 2
30
31cactus_green:
32 id: 6
33 taggable_id: 3
34 taggable_type: Thing
35 tag_id: 3
36
37orange_plant:
38 id: 7
39 taggable_id: 4
40 taggable_type: Thing
41 tag_id: 2
42
43orange_not_green:
44 id: 8
45 taggable_id: 4
46 taggable_type: Thing
47 tag_id: 4 \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/test/fixtures/tags.yml b/vendor/plugins/acts_as_taggable_redux/test/fixtures/tags.yml
new file mode 100644
index 0000000..141aea2
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/test/fixtures/tags.yml
@@ -0,0 +1,24 @@
1animal:
2 id: 1
3 name: animal
4 taggings_count: 2
5
6plant:
7 id: 2
8 name: plant
9 taggings_count: 2
10
11green:
12 id: 3
13 name: green
14 taggings_count: 2
15
16not_green:
17 id: 4
18 name: not green
19 taggings_count: 2
20
21favorite:
22 id: 5
23 name: favorite
24 taggings_count: 0 \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/test/fixtures/thing.rb b/vendor/plugins/acts_as_taggable_redux/test/fixtures/thing.rb
new file mode 100644
index 0000000..79de132
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/test/fixtures/thing.rb
@@ -0,0 +1,3 @@
1class Thing < ActiveRecord::Base
2 acts_as_taggable
3end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/test/fixtures/things.yml b/vendor/plugins/acts_as_taggable_redux/test/fixtures/things.yml
new file mode 100644
index 0000000..7ff1581
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/test/fixtures/things.yml
@@ -0,0 +1,15 @@
1bear:
2 id: 1
3 name: bear
4
5frog:
6 id: 2
7 name: frog
8
9cactus:
10 id: 3
11 name: cactus
12
13orange:
14 id: 4
15 name: orange \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/test/fixtures/user.rb b/vendor/plugins/acts_as_taggable_redux/test/fixtures/user.rb
new file mode 100644
index 0000000..ca0fd57
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/test/fixtures/user.rb
@@ -0,0 +1,3 @@
1class User < ActiveRecord::Base
2 acts_as_tagger
3end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/test/fixtures/users.yml b/vendor/plugins/acts_as_taggable_redux/test/fixtures/users.yml
new file mode 100644
index 0000000..8f6b037
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/test/fixtures/users.yml
@@ -0,0 +1,3 @@
1monki:
2 id: 1
3 username: monki \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/test/tag_test.rb b/vendor/plugins/acts_as_taggable_redux/test/tag_test.rb
new file mode 100644
index 0000000..1ed8357
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/test/tag_test.rb
@@ -0,0 +1,68 @@
1require File.dirname(__FILE__) + "/test_helper"
2
3class TagTest < Test::Unit::TestCase
4 def test_taggings
5 assert_equal [taggings(:bear_animal), taggings(:frog_animal)], tags(:animal).taggings
6 assert_not_equal [taggings(:cactus_plant), taggings(:orange_plant)], tags(:animal).taggings
7 end
8
9 def test_parse_does_not_change_param
10 list = 'a b c'
11 original = list.dup
12 Tag.parse(list)
13 assert_equal list, original
14 end
15
16 def test_parse_blank
17 assert_equal [], Tag.parse(nil)
18 assert_equal [], Tag.parse('')
19 end
20
21 def test_parse_single_tag
22 assert_equal ['a'], Tag.parse('a')
23 assert_equal ['a'], Tag.parse('"a"')
24 end
25
26 def test_parse_quoted_tags
27 assert_equal ['a b', 'c'], Tag.parse('"a b" c')
28 end
29
30 def test_parse_comma_dilineation
31 assert_equal ['a', 'b', 'c'], Tag.parse('a,b,c')
32 assert_equal ['a', 'b', 'c'], Tag.parse('a,b,c')
33 end
34
35 def test_parse_quotes_and_commas
36 assert_equal ['a,b', 'c'], Tag.parse('"a,b",c')
37 end
38
39 def test_parse_removes_whitespace
40 assert_equal ['a', 'b', 'c'], Tag.parse('a b, c')
41 end
42
43 def test_parse_removes_duplicates
44 assert_equal ['a', 'b', 'c'], Tag.parse('a b a c a b')
45 end
46
47 def test_tag
48 assert !tags(:favorite).tagged.include?(things(:bear))
49 tags(:favorite).tag(things(:bear))
50 assert tags(:favorite).tagged.include?(things(:bear))
51 end
52
53 def test_tagged
54 assert_equal [things(:bear), things(:frog)], tags(:animal).tagged
55 assert_not_equal [things(:bear), things(:frog)], tags(:plant).tagged
56 end
57
58 def test_equality
59 assert_equal tags(:animal), tags(:animal)
60 assert_equal Tag.find(1), Tag.find(1)
61 assert_equal Tag.new(:name => 'mineral'), Tag.new(:name => 'mineral')
62 assert_not_equal Tag.new(:name => 'mineral'), tags(:animal)
63 end
64
65 def test_to_s
66 assert_equal tags(:animal).name, tags(:animal).to_s
67 end
68end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/test/tagging_test.rb b/vendor/plugins/acts_as_taggable_redux/test/tagging_test.rb
new file mode 100644
index 0000000..a3b8887
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/test/tagging_test.rb
@@ -0,0 +1,13 @@
1require File.dirname(__FILE__) + "/test_helper"
2
3class TaggingTest < Test::Unit::TestCase
4 def test_taggable
5 assert_equal things(:bear), taggings(:bear_animal).taggable
6 assert_not_equal things(:frog), taggings(:bear_animal).taggable
7 end
8
9 def test_tag
10 assert_equal tags(:animal), taggings(:bear_animal).tag
11 assert_not_equal tags(:plant), taggings(:bear_animal).tag
12 end
13end \ No newline at end of file
diff --git a/vendor/plugins/acts_as_taggable_redux/test/test_helper.rb b/vendor/plugins/acts_as_taggable_redux/test/test_helper.rb
new file mode 100644
index 0000000..edef8aa
--- /dev/null
+++ b/vendor/plugins/acts_as_taggable_redux/test/test_helper.rb
@@ -0,0 +1,50 @@
1ENV["RAILS_ENV"] = "test"
2require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
3require 'test_help'
4require 'test/unit'
5
6require File.dirname(__FILE__) + '/../lib/acts_as_taggable'
7require File.dirname(__FILE__) + '/../lib/tag'
8require File.dirname(__FILE__) + '/../lib/tagging'
9
10ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/debug.log')
11ActiveRecord::Base.configurations = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
12ActiveRecord::Base.establish_connection(ENV['DB'] || 'mysql')
13
14load(File.dirname(__FILE__) + '/schema.rb')
15
16Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + '/fixtures/'
17$LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path)
18
19class Test::Unit::TestCase
20 # Transactional fixtures accelerate your tests by wrapping each test method
21 # in a transaction that's rolled back on completion. This ensures that the
22 # test database remains unchanged so your fixtures don't have to be reloaded
23 # between every test method. Fewer database queries means faster tests.
24 #
25 # Read Mike Clark's excellent walkthrough at
26 # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
27 #
28 # Every Active Record database supports transactions except MyISAM tables
29 # in MySQL. Turn off transactional fixtures in this case; however, if you
30 # don't care one way or the other, switching from MyISAM to InnoDB tables
31 # is recommended.
32 self.use_transactional_fixtures = true
33
34 # Instantiated fixtures are slow, but give you @david where otherwise you
35 # would need people(:david). If you don't want to migrate your existing
36 # test cases which use the @david style and don't mind the speed hit (each
37 # instantiated fixtures translates to a database query per test method),
38 # then set this back to true.
39 self.use_instantiated_fixtures = false
40
41 # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
42 # If you need to control the loading order (due to foreign key constraints etc), you'll
43 # need to change this line to explicitly name the order you desire.
44 #
45 # Note: You'll currently still have to declare fixtures explicitly in integration tests
46 # -- they do not yet inherent this setting
47 fixtures :all
48
49 # Add more helper methods to be used by all tests here...
50end \ No newline at end of file