acts-as-taggable-on 2.4.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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