acts-as-taggable-on 2.4.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +13 -4
  3. data/Appraisals +8 -4
  4. data/CHANGELOG.md +47 -0
  5. data/Gemfile +7 -1
  6. data/README.md +21 -11
  7. data/Rakefile +21 -3
  8. data/UPGRADING +7 -0
  9. data/acts-as-taggable-on.gemspec +5 -5
  10. data/{lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb → db/migrate/1_acts_as_taggable_on_migration.rb} +0 -0
  11. data/db/migrate/2_add_missing_unique_indices.rb +21 -0
  12. data/gemfiles/{rails_3.gemfile → rails_3.2.gemfile} +1 -2
  13. data/gemfiles/rails_4.0.gemfile +7 -0
  14. data/gemfiles/rails_4.1.gemfile +7 -0
  15. data/lib/acts-as-taggable-on.rb +9 -13
  16. data/lib/acts_as_taggable_on.rb +6 -0
  17. data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +49 -20
  18. data/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb +42 -32
  19. data/lib/acts_as_taggable_on/acts_as_taggable_on/compatibility.rb +1 -1
  20. data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +24 -13
  21. data/lib/acts_as_taggable_on/engine.rb +6 -0
  22. data/lib/acts_as_taggable_on/tag.rb +27 -7
  23. data/lib/acts_as_taggable_on/taggable.rb +6 -6
  24. data/lib/acts_as_taggable_on/tagger.rb +6 -6
  25. data/lib/acts_as_taggable_on/tags_helper.rb +1 -1
  26. data/lib/acts_as_taggable_on/version.rb +1 -1
  27. data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +4 -71
  28. data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +19 -19
  29. data/spec/acts_as_taggable_on/caching_spec.rb +77 -0
  30. data/spec/acts_as_taggable_on/tags_helper_spec.rb +10 -10
  31. data/spec/schema.rb +25 -21
  32. data/spec/spec_helper.rb +9 -25
  33. metadata +40 -56
  34. data/gemfiles/rails_4.gemfile +0 -8
  35. data/lib/generators/acts_as_taggable_on/migration/migration_generator.rb +0 -39
  36. data/spec/generators/acts_as_taggable_on/migration/migration_generator_spec.rb +0 -22
@@ -31,4 +31,4 @@ module ActsAsTaggableOn::Compatibility
31
31
 
32
32
  [scope_opts, opts]
33
33
  end
34
- end
34
+ end
@@ -104,14 +104,14 @@ module ActsAsTaggableOn::Taggable
104
104
  tags_conditions = tag_list.map { |t| sanitize_sql(["#{ActsAsTaggableOn::Tag.table_name}.name #{like_operator} ?", t]) }.join(" OR ")
105
105
  end
106
106
 
107
- conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)})"
107
+ conditions << "#{table_name}.#{primary_key} NOT IN (SELECT #{ActsAsTaggableOn::Tagging.table_name}.taggable_id FROM #{ActsAsTaggableOn::Tagging.table_name} JOIN #{ActsAsTaggableOn::Tag.table_name} ON #{ActsAsTaggableOn::Tagging.table_name}.tag_id = #{ActsAsTaggableOn::Tag.table_name}.#{ActsAsTaggableOn::Tag.primary_key} AND (#{tags_conditions}) WHERE #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name, nil)})"
108
108
 
109
109
  if owned_by
110
110
  joins << "JOIN #{ActsAsTaggableOn::Tagging.table_name}" +
111
111
  " ON #{ActsAsTaggableOn::Tagging.table_name}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
112
- " AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name)}" +
113
- " AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_id = #{owned_by.id}" +
114
- " AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_type = #{quote_value(owned_by.class.base_class.to_s)}"
112
+ " AND #{ActsAsTaggableOn::Tagging.table_name}.taggable_type = #{quote_value(base_class.name, nil)}" +
113
+ " AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_id = #{quote_value(owned_by.id, nil)}" +
114
+ " AND #{ActsAsTaggableOn::Tagging.table_name}.tagger_type = #{quote_value(owned_by.class.base_class.to_s, nil)}"
115
115
  end
116
116
 
117
117
  elsif options.delete(:any)
@@ -134,11 +134,11 @@ module ActsAsTaggableOn::Taggable
134
134
 
135
135
  tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
136
136
  " ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
137
- " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}"
137
+ " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name, nil)}"
138
138
  tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context
139
139
 
140
140
  # don't need to sanitize sql, map all ids and join with OR logic
141
- conditions << tags.map { |t| "#{taggings_alias}.tag_id = #{t.id}" }.join(" OR ")
141
+ conditions << tags.map { |t| "#{taggings_alias}.tag_id = #{quote_value(t.id, nil)}" }.join(" OR ")
142
142
  select_clause = "DISTINCT #{table_name}.*" unless context and tag_types.one?
143
143
 
144
144
  if owned_by
@@ -160,8 +160,8 @@ module ActsAsTaggableOn::Taggable
160
160
  taggings_alias = adjust_taggings_alias("#{alias_base_name[0..11]}_taggings_#{sha_prefix(tag.name)}")
161
161
  tagging_join = "JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
162
162
  " ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
163
- " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}" +
164
- " AND #{taggings_alias}.tag_id = #{tag.id}"
163
+ " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name, nil)}" +
164
+ " AND #{taggings_alias}.tag_id = #{quote_value(tag.id, nil)}"
165
165
 
166
166
  tagging_join << " AND " + sanitize_sql(["#{taggings_alias}.context = ?", context.to_s]) if context
167
167
 
@@ -183,7 +183,7 @@ module ActsAsTaggableOn::Taggable
183
183
  if options.delete(:match_all)
184
184
  joins << "LEFT OUTER JOIN #{ActsAsTaggableOn::Tagging.table_name} #{taggings_alias}" +
185
185
  " ON #{taggings_alias}.taggable_id = #{quote}#{table_name}#{quote}.#{primary_key}" +
186
- " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name)}"
186
+ " AND #{taggings_alias}.taggable_type = #{quote_value(base_class.name, nil)}"
187
187
 
188
188
 
189
189
  group_columns = ActsAsTaggableOn::Tag.using_postgresql? ? grouped_column_names_for(self) : "#{table_name}.#{primary_key}"
@@ -245,8 +245,13 @@ module ActsAsTaggableOn::Taggable
245
245
 
246
246
  def tag_list_cache_on(context)
247
247
  variable_name = "@#{context.to_s.singularize}_list"
248
- return instance_variable_get(variable_name) if instance_variable_defined?(variable_name) && instance_variable_get(variable_name)
249
- instance_variable_set(variable_name, ActsAsTaggableOn::TagList.new(tags_on(context).map(&:name)))
248
+ if instance_variable_get(variable_name)
249
+ instance_variable_get(variable_name)
250
+ elsif cached_tag_list_on(context) && self.class.caching_tag_list_on?(context)
251
+ instance_variable_set(variable_name, ActsAsTaggableOn::TagList.from(cached_tag_list_on(context)))
252
+ else
253
+ instance_variable_set(variable_name, ActsAsTaggableOn::TagList.new(tags_on(context).map(&:name)))
254
+ end
250
255
  end
251
256
 
252
257
  def tag_list_on(context)
@@ -324,6 +329,12 @@ module ActsAsTaggableOn::Taggable
324
329
  super(*args)
325
330
  end
326
331
 
332
+ ##
333
+ # Find existing tags or create non-existing tags
334
+ def load_tags(tag_list)
335
+ ActsAsTaggableOn::Tag.find_or_create_all_with_like_by_name(tag_list)
336
+ end
337
+
327
338
  def save_tags
328
339
  tagging_contexts.each do |context|
329
340
  next unless tag_list_cache_set_on(context)
@@ -331,7 +342,7 @@ module ActsAsTaggableOn::Taggable
331
342
  tag_list = tag_list_cache_on(context).uniq
332
343
 
333
344
  # Find existing tags or create non-existing tags:
334
- tags = ActsAsTaggableOn::Tag.find_or_create_all_with_like_by_name(tag_list)
345
+ tags = load_tags(tag_list)
335
346
 
336
347
  # Tag objects for currently assigned tags
337
348
  current_tags = tags_on(context)
@@ -350,7 +361,7 @@ module ActsAsTaggableOn::Taggable
350
361
  new_tags |= current_tags[index...current_tags.size] & shared_tags
351
362
 
352
363
  # Order the array of tag objects to match the tag list
353
- new_tags = tags.map do |t|
364
+ new_tags = tags.map do |t|
354
365
  new_tags.find { |n| n.name.downcase == t.name.downcase }
355
366
  end.compact
356
367
  end
@@ -0,0 +1,6 @@
1
+ require 'rails/engine'
2
+ module ActsAsTaggableOn
3
+ class Engine < Rails::Engine
4
+
5
+ end
6
+ end
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  module ActsAsTaggableOn
2
3
  class Tag < ::ActiveRecord::Base
3
4
  include ActsAsTaggableOn::Utils
@@ -31,18 +32,29 @@ module ActsAsTaggableOn
31
32
 
32
33
  def self.named_any(list)
33
34
  if ActsAsTaggableOn.strict_case_match
34
- where(list.map { |tag| sanitize_sql(["name = #{binary}?", tag.to_s.mb_chars]) }.join(" OR "))
35
+ clause = list.map { |tag|
36
+ sanitize_sql(["name = #{binary}?", as_8bit_ascii(tag)])
37
+ }.join(" OR ")
38
+ where(clause)
35
39
  else
36
- where(list.map { |tag| sanitize_sql(["lower(name) = ?", tag.to_s.mb_chars.downcase]) }.join(" OR "))
40
+ clause = list.map { |tag|
41
+ lowercase_ascii_tag = as_8bit_ascii(tag).downcase
42
+ sanitize_sql(["lower(name) = ?", lowercase_ascii_tag])
43
+ }.join(" OR ")
44
+ where(clause)
37
45
  end
38
46
  end
39
47
 
40
48
  def self.named_like(name)
41
- where(["name #{like_operator} ? ESCAPE '!'", "%#{escape_like(name)}%"])
49
+ clause = ["name #{like_operator} ? ESCAPE '!'", "%#{escape_like(name)}%"]
50
+ where(clause)
42
51
  end
43
52
 
44
53
  def self.named_like_any(list)
45
- where(list.map { |tag| sanitize_sql(["name #{like_operator} ? ESCAPE '!'", "%#{escape_like(tag.to_s)}%"]) }.join(" OR "))
54
+ clause = list.map { |tag|
55
+ sanitize_sql(["name #{like_operator} ? ESCAPE '!'", "%#{escape_like(tag.to_s)}%"])
56
+ }.join(" OR ")
57
+ where(clause)
46
58
  end
47
59
 
48
60
  ### CLASS METHODS:
@@ -56,7 +68,7 @@ module ActsAsTaggableOn
56
68
  end
57
69
 
58
70
  def self.find_or_create_all_with_like_by_name(*list)
59
- list = [list].flatten
71
+ list = Array(list).flatten
60
72
 
61
73
  return [] if list.empty?
62
74
 
@@ -64,7 +76,7 @@ module ActsAsTaggableOn
64
76
 
65
77
  list.map do |tag_name|
66
78
  comparable_tag_name = comparable_name(tag_name)
67
- existing_tag = existing_tags.find { |tag| comparable_name(tag.name) == comparable_tag_name }
79
+ existing_tag = existing_tags.detect { |tag| comparable_name(tag.name) == comparable_tag_name }
68
80
 
69
81
  existing_tag || Tag.create(:name => tag_name)
70
82
  end
@@ -88,12 +100,20 @@ module ActsAsTaggableOn
88
100
  private
89
101
 
90
102
  def comparable_name(str)
91
- str.mb_chars.downcase.to_s
103
+ as_8bit_ascii(str).downcase
92
104
  end
93
105
 
94
106
  def binary
95
107
  /mysql/ === ActiveRecord::Base.connection_config[:adapter] ? "BINARY " : nil
96
108
  end
109
+
110
+ def as_8bit_ascii(string)
111
+ if defined?(Encoding)
112
+ string.to_s.force_encoding('BINARY')
113
+ else
114
+ string.to_s.mb_chars
115
+ end
116
+ end
97
117
  end
98
118
  end
99
119
  end
@@ -25,7 +25,7 @@ module ActsAsTaggableOn
25
25
  def acts_as_ordered_taggable
26
26
  acts_as_ordered_taggable_on :tags
27
27
  end
28
-
28
+
29
29
  ##
30
30
  # Make a model taggable on specified contexts.
31
31
  #
@@ -38,8 +38,8 @@ module ActsAsTaggableOn
38
38
  def acts_as_taggable_on(*tag_types)
39
39
  taggable_on(false, tag_types)
40
40
  end
41
-
42
-
41
+
42
+
43
43
  ##
44
44
  # Make a model taggable on specified contexts
45
45
  # and preserves the order in which tags are created
@@ -53,9 +53,9 @@ module ActsAsTaggableOn
53
53
  def acts_as_ordered_taggable_on(*tag_types)
54
54
  taggable_on(true, tag_types)
55
55
  end
56
-
56
+
57
57
  private
58
-
58
+
59
59
  # Make a model taggable on specified contexts
60
60
  # and optionally preserves the order in which tags are created
61
61
  #
@@ -78,7 +78,7 @@ module ActsAsTaggableOn
78
78
  self.tag_types = tag_types
79
79
  class_attribute :preserve_tag_order
80
80
  self.preserve_tag_order = preserve_tag_order
81
-
81
+
82
82
  class_eval do
83
83
  has_many :taggings, :as => :taggable, :dependent => :destroy, :class_name => "ActsAsTaggableOn::Tagging"
84
84
  has_many :base_tags, :through => :taggings, :source => :tag, :class_name => "ActsAsTaggableOn::Tag"
@@ -15,17 +15,17 @@ module ActsAsTaggableOn
15
15
  # end
16
16
  def acts_as_tagger(opts={})
17
17
  class_eval do
18
- has_many_with_compatibility :owned_taggings,
18
+ has_many_with_compatibility :owned_taggings,
19
19
  opts.merge(
20
- :as => :tagger,
20
+ :as => :tagger,
21
21
  :dependent => :destroy,
22
22
  :class_name => "ActsAsTaggableOn::Tagging"
23
23
  )
24
24
 
25
- has_many_with_compatibility :owned_tags,
26
- :through => :owned_taggings,
27
- :source => :tag,
28
- :class_name => "ActsAsTaggableOn::Tag",
25
+ has_many_with_compatibility :owned_tags,
26
+ :through => :owned_taggings,
27
+ :source => :tag,
28
+ :class_name => "ActsAsTaggableOn::Tag",
29
29
  :uniq => true
30
30
  end
31
31
 
@@ -12,4 +12,4 @@ module ActsAsTaggableOn
12
12
  end
13
13
  end
14
14
  end
15
- end
15
+ end
@@ -1,4 +1,4 @@
1
1
  module ActsAsTaggableOn
2
- VERSION = '2.4.1'
2
+ VERSION = '3.0.0'
3
3
  end
4
4
 
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  require 'spec_helper'
2
3
 
3
4
  describe "Acts As Taggable On" do
@@ -8,7 +9,7 @@ describe "Acts As Taggable On" do
8
9
  it "should provide a class method 'taggable?' that is false for untaggable models" do
9
10
  UntaggableModel.should_not be_taggable
10
11
  end
11
-
12
+
12
13
  describe "Taggable Method Generation To Preserve Order" do
13
14
  before(:each) do
14
15
  clean_database!
@@ -46,7 +47,7 @@ describe "Acts As Taggable On" do
46
47
  it "should have all tag types" do
47
48
  @taggable.tag_types.should == [:tags, :languages, :skills, :needs, :offerings]
48
49
  end
49
-
50
+
50
51
  it "should create a class attribute for preserve tag order" do
51
52
  @taggable.class.should respond_to(:preserve_tag_order?)
52
53
  end
@@ -54,7 +55,7 @@ describe "Acts As Taggable On" do
54
55
  it "should create an instance attribute for preserve tag order" do
55
56
  @taggable.should respond_to(:preserve_tag_order?)
56
57
  end
57
-
58
+
58
59
  it "should respond 'false' to preserve_tag_order?" do
59
60
  @taggable.class.preserve_tag_order?.should be_false
60
61
  end
@@ -168,74 +169,6 @@ describe "Acts As Taggable On" do
168
169
  end
169
170
  end
170
171
 
171
- describe 'Caching' do
172
- before(:each) do
173
- @taggable = CachedModel.new(:name => "Bob Jones")
174
- @another_taggable = OtherCachedModel.new(:name => "John Smith")
175
- end
176
-
177
- it "should add saving of tag lists and cached tag lists to the instance" do
178
- @taggable.should respond_to(:save_cached_tag_list)
179
- @another_taggable.should respond_to(:save_cached_tag_list)
180
-
181
- @taggable.should respond_to(:save_tags)
182
- end
183
-
184
- it "should add cached tag lists to the instance if cached column is not present" do
185
- TaggableModel.new(:name => "Art Kram").should_not respond_to(:save_cached_tag_list)
186
- end
187
-
188
- it "should generate a cached column checker for each tag type" do
189
- CachedModel.should respond_to(:caching_tag_list?)
190
- OtherCachedModel.should respond_to(:caching_language_list?)
191
- end
192
-
193
- it 'should not have cached tags' do
194
- @taggable.cached_tag_list.should be_blank
195
- @another_taggable.cached_language_list.should be_blank
196
- end
197
-
198
- it 'should cache tags' do
199
- @taggable.update_attributes(:tag_list => 'awesome, epic')
200
- @taggable.cached_tag_list.should == 'awesome, epic'
201
-
202
- @another_taggable.update_attributes(:language_list => 'ruby, .net')
203
- @another_taggable.cached_language_list.should == 'ruby, .net'
204
- end
205
-
206
- it 'should keep the cache' do
207
- @taggable.update_attributes(:tag_list => 'awesome, epic')
208
- @taggable = CachedModel.find(@taggable)
209
- @taggable.save!
210
- @taggable.cached_tag_list.should == 'awesome, epic'
211
- end
212
-
213
- it 'should update the cache' do
214
- @taggable.update_attributes(:tag_list => 'awesome, epic')
215
- @taggable.update_attributes(:tag_list => 'awesome')
216
- @taggable.cached_tag_list.should == 'awesome'
217
- end
218
-
219
- it 'should remove the cache' do
220
- @taggable.update_attributes(:tag_list => 'awesome, epic')
221
- @taggable.update_attributes(:tag_list => '')
222
- @taggable.cached_tag_list.should be_blank
223
- end
224
-
225
- it 'should have a tag list' do
226
- @taggable.update_attributes(:tag_list => 'awesome, epic')
227
- @taggable = CachedModel.find(@taggable.id)
228
- @taggable.tag_list.sort.should == %w(awesome epic).sort
229
- end
230
-
231
- it 'should keep the tag list' do
232
- @taggable.update_attributes(:tag_list => 'awesome, epic')
233
- @taggable = CachedModel.find(@taggable.id)
234
- @taggable.save!
235
- @taggable.tag_list.sort.should == %w(awesome epic).sort
236
- end
237
- end
238
-
239
172
  context 'when tagging context ends in an "s" when singular (ex. "status", "glass", etc.)' do
240
173
  describe 'caching' do
241
174
  before { @taggable = OtherCachedModel.new(:name => "John Smith") }
@@ -4,7 +4,7 @@ describe "acts_as_tagger" do
4
4
  before(:each) do
5
5
  clean_database!
6
6
  end
7
-
7
+
8
8
  describe "Tagger Method Generation" do
9
9
  before(:each) do
10
10
  @tagger = User.new
@@ -13,55 +13,55 @@ describe "acts_as_tagger" do
13
13
  it "should add #is_tagger? query method to the class-side" do
14
14
  User.should respond_to(:is_tagger?)
15
15
  end
16
-
16
+
17
17
  it "should return true from the class-side #is_tagger?" do
18
18
  User.is_tagger?.should be_true
19
19
  end
20
-
20
+
21
21
  it "should return false from the base #is_tagger?" do
22
22
  ActiveRecord::Base.is_tagger?.should be_false
23
23
  end
24
-
24
+
25
25
  it "should add #is_tagger? query method to the singleton" do
26
26
  @tagger.should respond_to(:is_tagger?)
27
27
  end
28
-
28
+
29
29
  it "should add #tag method on the instance-side" do
30
30
  @tagger.should respond_to(:tag)
31
31
  end
32
-
32
+
33
33
  it "should generate an association for #owned_taggings and #owned_tags" do
34
34
  @tagger.should respond_to(:owned_taggings, :owned_tags)
35
35
  end
36
36
  end
37
-
37
+
38
38
  describe "#tag" do
39
39
  context 'when called with a non-existent tag context' do
40
40
  before(:each) do
41
41
  @tagger = User.new
42
42
  @taggable = TaggableModel.new(:name=>"Richard Prior")
43
43
  end
44
-
44
+
45
45
  it "should by default not throw an exception " do
46
46
  @taggable.tag_list_on(:foo).should be_empty
47
47
  lambda {
48
48
  @tagger.tag(@taggable, :with=>'this, and, that', :on=>:foo)
49
49
  }.should_not raise_error
50
50
  end
51
-
51
+
52
52
  it 'should by default create the tag context on-the-fly' do
53
53
  @taggable.tag_list_on(:here_ond_now).should be_empty
54
54
  @tagger.tag(@taggable, :with=>'that', :on => :here_ond_now)
55
55
  @taggable.tag_list_on(:here_ond_now).should_not include('that')
56
56
  @taggable.all_tags_list_on(:here_ond_now).should include('that')
57
57
  end
58
-
58
+
59
59
  it "should show all the tag list when both public and owned tags exist" do
60
60
  @taggable.tag_list = 'ruby, python'
61
61
  @tagger.tag(@taggable, :with => 'java, lisp', :on => :tags)
62
62
  @taggable.all_tags_on(:tags).map(&:name).sort.should == %w(ruby python java lisp).sort
63
63
  end
64
-
64
+
65
65
  it "should not add owned tags to the common list" do
66
66
  @taggable.tag_list = 'ruby, python'
67
67
  @tagger.tag(@taggable, :with => 'java, lisp', :on => :tags)
@@ -69,12 +69,12 @@ describe "acts_as_tagger" do
69
69
  @tagger.tag(@taggable, :with => '', :on => :tags)
70
70
  @taggable.tag_list.should == %w(ruby python)
71
71
  end
72
-
72
+
73
73
  it "should throw an exception when the default is over-ridden" do
74
74
  @taggable.tag_list_on(:foo_boo).should be_empty
75
75
  lambda {
76
76
  @tagger.tag(@taggable, :with=>'this, and, that', :on=>:foo_boo, :force=>false)
77
- }.should raise_error
77
+ }.should raise_error
78
78
  end
79
79
 
80
80
  it "should not create the tag context on-the-fly when the default is over-ridden" do
@@ -83,28 +83,28 @@ describe "acts_as_tagger" do
83
83
  @taggable.tag_list_on(:foo_boo).should be_empty
84
84
  end
85
85
  end
86
-
86
+
87
87
  describe "when called by multiple tagger's" do
88
88
  before(:each) do
89
89
  @user_x = User.create(:name => "User X")
90
90
  @user_y = User.create(:name => "User Y")
91
91
  @taggable = TaggableModel.create(:name => 'acts_as_taggable_on', :tag_list => 'plugin')
92
-
92
+
93
93
  @user_x.tag(@taggable, :with => 'ruby, rails', :on => :tags)
94
94
  @user_y.tag(@taggable, :with => 'ruby, plugin', :on => :tags)
95
95
 
96
96
  @user_y.tag(@taggable, :with => '', :on => :tags)
97
97
  @user_y.tag(@taggable, :with => '', :on => :tags)
98
98
  end
99
-
100
- it "should delete owned tags" do
99
+
100
+ it "should delete owned tags" do
101
101
  @user_y.owned_tags.should == []
102
102
  end
103
-
103
+
104
104
  it "should not delete other taggers tags" do
105
105
  @user_x.owned_tags.should have(2).items
106
106
  end
107
-
107
+
108
108
  it "should not delete original tags" do
109
109
  @taggable.all_tags_list_on(:tags).should include('plugin')
110
110
  end