acts-as-taggable-on 3.1.1 → 3.2.1

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +9 -7
  4. data/Appraisals +13 -8
  5. data/CHANGELOG.md +8 -0
  6. data/Gemfile +1 -2
  7. data/README.md +23 -13
  8. data/Rakefile +5 -17
  9. data/UPGRADING.md +6 -0
  10. data/acts-as-taggable-on.gemspec +13 -13
  11. data/db/migrate/1_acts_as_taggable_on_migration.rb +3 -3
  12. data/db/migrate/2_add_missing_unique_indices.rb +3 -5
  13. data/db/migrate/3_add_taggings_counter_cache_to_tags.rb +1 -1
  14. data/gemfiles/activerecord_3.2.gemfile +15 -0
  15. data/gemfiles/activerecord_4.0.gemfile +15 -0
  16. data/gemfiles/activerecord_4.1.gemfile +15 -0
  17. data/gemfiles/activerecord_edge.gemfile +16 -0
  18. data/lib/acts-as-taggable-on.rb +23 -21
  19. data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +1 -4
  20. data/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb +29 -20
  21. data/lib/acts_as_taggable_on/acts_as_taggable_on/compatibility.rb +11 -10
  22. data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +98 -80
  23. data/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb +5 -12
  24. data/lib/acts_as_taggable_on/acts_as_taggable_on/related.rb +7 -7
  25. data/lib/acts_as_taggable_on/engine.rb +0 -1
  26. data/lib/acts_as_taggable_on/tag.rb +24 -19
  27. data/lib/acts_as_taggable_on/tag_list.rb +95 -21
  28. data/lib/acts_as_taggable_on/taggable.rb +28 -30
  29. data/lib/acts_as_taggable_on/tagger.rb +30 -18
  30. data/lib/acts_as_taggable_on/tagging.rb +7 -8
  31. data/lib/acts_as_taggable_on/tags_helper.rb +1 -1
  32. data/lib/acts_as_taggable_on/utils.rb +25 -3
  33. data/lib/acts_as_taggable_on/version.rb +1 -1
  34. data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +133 -138
  35. data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +55 -58
  36. data/spec/acts_as_taggable_on/caching_spec.rb +34 -35
  37. data/spec/acts_as_taggable_on/related_spec.rb +59 -113
  38. data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +118 -95
  39. data/spec/acts_as_taggable_on/tag_list_spec.rb +89 -57
  40. data/spec/acts_as_taggable_on/tag_spec.rb +125 -114
  41. data/spec/acts_as_taggable_on/taggable_spec.rb +538 -352
  42. data/spec/acts_as_taggable_on/tagger_spec.rb +81 -78
  43. data/spec/acts_as_taggable_on/tagging_spec.rb +13 -14
  44. data/spec/acts_as_taggable_on/tags_helper_spec.rb +25 -25
  45. data/spec/acts_as_taggable_on/utils_spec.rb +9 -9
  46. data/spec/internal/app/models/altered_inheriting_taggable_model.rb +3 -0
  47. data/spec/internal/app/models/cached_model.rb +3 -0
  48. data/spec/internal/app/models/cached_model_with_array.rb +5 -0
  49. data/spec/internal/app/models/company.rb +15 -0
  50. data/spec/internal/app/models/inheriting_taggable_model.rb +2 -0
  51. data/spec/internal/app/models/market.rb +2 -0
  52. data/spec/{models.rb → internal/app/models/models.rb} +34 -2
  53. data/spec/internal/app/models/non_standard_id_taggable_model.rb +8 -0
  54. data/spec/internal/app/models/ordered_taggable_model.rb +4 -0
  55. data/spec/internal/app/models/other_cached_model.rb +3 -0
  56. data/spec/internal/app/models/other_taggable_model.rb +4 -0
  57. data/spec/internal/app/models/student.rb +2 -0
  58. data/spec/internal/app/models/taggable_model.rb +13 -0
  59. data/spec/internal/app/models/untaggable_model.rb +3 -0
  60. data/spec/internal/app/models/user.rb +3 -0
  61. data/spec/{database.yml.sample → internal/config/database.yml.sample} +2 -2
  62. data/spec/internal/db/schema.rb +97 -0
  63. data/spec/schema.rb +11 -0
  64. data/spec/spec_helper.rb +9 -62
  65. data/spec/support/array.rb +9 -0
  66. data/spec/support/database.rb +42 -0
  67. data/spec/support/database_cleaner.rb +17 -0
  68. metadata +101 -37
  69. data/gemfiles/rails_3.2.gemfile +0 -7
  70. data/gemfiles/rails_4.0.gemfile +0 -7
  71. data/gemfiles/rails_4.1.gemfile +0 -7
  72. data/gemfiles/rails_edge.gemfile +0 -7
@@ -1,149 +1,145 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Single Table Inheritance" do
3
+ describe 'Single Table Inheritance' do
4
+ let(:taggable) { TaggableModel.new(name: 'taggable model') }
4
5
 
5
- before(:each) do
6
- clean_database!
7
- end
8
-
9
- let(:taggable) { TaggableModel.new(:name => "taggable model") }
10
-
11
- let(:inheriting_model) { InheritingTaggableModel.new(:name => "Inheriting Taggable Model") }
12
- let(:altered_inheriting) { AlteredInheritingTaggableModel.new(:name => "Altered Inheriting Model") }
6
+ let(:inheriting_model) { InheritingTaggableModel.new(name: 'Inheriting Taggable Model') }
7
+ let(:altered_inheriting) { AlteredInheritingTaggableModel.new(name: 'Altered Inheriting Model') }
13
8
 
14
9
  1.upto(4) do |n|
15
- let(:"inheriting_#{n}") { InheritingTaggableModel.new(:name => "Inheriting Model #{n}") }
10
+ let(:"inheriting_#{n}") { InheritingTaggableModel.new(name: "Inheriting Model #{n}") }
16
11
  end
17
12
 
18
- let(:student) { Student.create! }
13
+ let(:student) { Student.create! }
19
14
 
20
- describe "tag contexts" do
21
- it "should pass on to STI-inherited models" do
22
- inheriting_model.should respond_to(:tag_list, :skill_list, :language_list)
23
- altered_inheriting.should respond_to(:tag_list, :skill_list, :language_list)
15
+ describe 'tag contexts' do
16
+ it 'should pass on to STI-inherited models' do
17
+ expect(inheriting_model).to respond_to(:tag_list, :skill_list, :language_list)
18
+ expect(altered_inheriting).to respond_to(:tag_list, :skill_list, :language_list)
24
19
  end
25
20
 
26
- it "should pass on to altered STI models" do
27
- altered_inheriting.should respond_to(:part_list)
21
+ it 'should pass on to altered STI models' do
22
+ expect(altered_inheriting).to respond_to(:part_list)
28
23
  end
29
24
  end
30
25
 
31
- context "matching contexts" do
26
+ context 'matching contexts' do
32
27
 
33
28
  before do
34
- inheriting_1.offering_list = "one, two"
35
- inheriting_1.need_list = "one, two"
29
+ inheriting_1.offering_list = 'one, two'
30
+ inheriting_1.need_list = 'one, two'
36
31
  inheriting_1.save!
37
32
 
38
- inheriting_2.need_list = "one, two"
33
+ inheriting_2.need_list = 'one, two'
39
34
  inheriting_2.save!
40
35
 
41
- inheriting_3.offering_list = "one, two"
36
+ inheriting_3.offering_list = 'one, two'
42
37
  inheriting_3.save!
43
38
 
44
- inheriting_4.tag_list = "one, two, three, four"
39
+ inheriting_4.tag_list = 'one, two, three, four'
45
40
  inheriting_4.save!
46
41
 
47
- taggable.need_list = "one, two"
42
+ taggable.need_list = 'one, two'
48
43
  taggable.save!
49
44
  end
50
45
 
51
- it "should find objects with tags of matching contexts" do
52
- inheriting_1.find_matching_contexts(:offerings, :needs).should include(inheriting_2)
53
- inheriting_1.find_matching_contexts(:offerings, :needs).should_not include(inheriting_3)
54
- inheriting_1.find_matching_contexts(:offerings, :needs).should_not include(inheriting_4)
55
- inheriting_1.find_matching_contexts(:offerings, :needs).should_not include(taggable)
46
+ it 'should find objects with tags of matching contexts' do
47
+ expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to include(inheriting_2)
48
+ expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to_not include(inheriting_3)
49
+ expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to_not include(inheriting_4)
50
+ expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to_not include(taggable)
56
51
 
57
- inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should include(inheriting_2)
58
- inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(inheriting_3)
59
- inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(inheriting_4)
60
- inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should include(taggable)
52
+ expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to include(inheriting_2)
53
+ expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to_not include(inheriting_3)
54
+ expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to_not include(inheriting_4)
55
+ expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to include(taggable)
61
56
  end
62
57
 
63
- it "should not include the object itself in the list of related objects with tags of matching contexts" do
64
- inheriting_1.find_matching_contexts(:offerings, :needs).should_not include(inheriting_1)
65
- inheriting_1.find_matching_contexts_for(InheritingTaggableModel, :offerings, :needs).should_not include(inheriting_1)
66
- inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs).should_not include(inheriting_1)
58
+ it 'should not include the object itself in the list of related objects with tags of matching contexts' do
59
+ expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to_not include(inheriting_1)
60
+ expect(inheriting_1.find_matching_contexts_for(InheritingTaggableModel, :offerings, :needs)).to_not include(inheriting_1)
61
+ expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to_not include(inheriting_1)
67
62
  end
68
63
  end
69
64
 
70
- context "find related tags" do
65
+ context 'find related tags' do
71
66
  before do
72
- inheriting_1.tag_list = "one, two"
67
+ inheriting_1.tag_list = 'one, two'
73
68
  inheriting_1.save
74
69
 
75
- inheriting_2.tag_list = "three, four"
70
+ inheriting_2.tag_list = 'three, four'
76
71
  inheriting_2.save
77
72
 
78
- inheriting_3.tag_list = "one, four"
73
+ inheriting_3.tag_list = 'one, four'
79
74
  inheriting_3.save
80
75
 
81
- taggable.tag_list = "one, two, three, four"
76
+ taggable.tag_list = 'one, two, three, four'
82
77
  taggable.save
83
78
  end
84
79
 
85
- it "should find related objects based on tag names on context" do
86
- inheriting_1.find_related_tags.should include(inheriting_3)
87
- inheriting_1.find_related_tags.should_not include(inheriting_2)
88
- inheriting_1.find_related_tags.should_not include(taggable)
80
+ it 'should find related objects based on tag names on context' do
81
+ expect(inheriting_1.find_related_tags).to include(inheriting_3)
82
+ expect(inheriting_1.find_related_tags).to_not include(inheriting_2)
83
+ expect(inheriting_1.find_related_tags).to_not include(taggable)
89
84
 
90
- inheriting_1.find_related_tags_for(TaggableModel).should include(inheriting_3)
91
- inheriting_1.find_related_tags_for(TaggableModel).should_not include(inheriting_2)
92
- inheriting_1.find_related_tags_for(TaggableModel).should include(taggable)
85
+ expect(inheriting_1.find_related_tags_for(TaggableModel)).to include(inheriting_3)
86
+ expect(inheriting_1.find_related_tags_for(TaggableModel)).to_not include(inheriting_2)
87
+ expect(inheriting_1.find_related_tags_for(TaggableModel)).to include(taggable)
93
88
  end
94
89
 
95
- it "should not include the object itself in the list of related objects" do
96
- inheriting_1.find_related_tags.should_not include(inheriting_1)
97
- inheriting_1.find_related_tags_for(InheritingTaggableModel).should_not include(inheriting_1)
98
- inheriting_1.find_related_tags_for(TaggableModel).should_not include(inheriting_1)
90
+ it 'should not include the object itself in the list of related objects' do
91
+ expect(inheriting_1.find_related_tags).to_not include(inheriting_1)
92
+ expect(inheriting_1.find_related_tags_for(InheritingTaggableModel)).to_not include(inheriting_1)
93
+ expect(inheriting_1.find_related_tags_for(TaggableModel)).to_not include(inheriting_1)
99
94
  end
100
95
  end
101
96
 
102
- describe "tag list" do
97
+ describe 'tag list' do
103
98
  before do
104
- @inherited_same = InheritingTaggableModel.new(:name => "inherited same")
105
- @inherited_different = AlteredInheritingTaggableModel.new(:name => "inherited different")
99
+ @inherited_same = InheritingTaggableModel.new(name: 'inherited same')
100
+ @inherited_different = AlteredInheritingTaggableModel.new(name: 'inherited different')
106
101
  end
107
102
 
108
- it "should be able to save tags for inherited models" do
109
- inheriting_model.tag_list = "bob, kelso"
103
+ #TODO, shared example
104
+ it 'should be able to save tags for inherited models' do
105
+ inheriting_model.tag_list = 'bob, kelso'
110
106
  inheriting_model.save
111
- InheritingTaggableModel.tagged_with("bob").first.should == inheriting_model
107
+ expect(InheritingTaggableModel.tagged_with('bob').first).to eq(inheriting_model)
112
108
  end
113
109
 
114
- it "should find STI tagged models on the superclass" do
115
- inheriting_model.tag_list = "bob, kelso"
110
+ it 'should find STI tagged models on the superclass' do
111
+ inheriting_model.tag_list = 'bob, kelso'
116
112
  inheriting_model.save
117
- TaggableModel.tagged_with("bob").first.should == inheriting_model
113
+ expect(TaggableModel.tagged_with('bob').first).to eq(inheriting_model)
118
114
  end
119
115
 
120
- it "should be able to add on contexts only to some subclasses" do
121
- altered_inheriting.part_list = "fork, spoon"
116
+ it 'should be able to add on contexts only to some subclasses' do
117
+ altered_inheriting.part_list = 'fork, spoon'
122
118
  altered_inheriting.save
123
- InheritingTaggableModel.tagged_with("fork", :on => :parts).should be_empty
124
- AlteredInheritingTaggableModel.tagged_with("fork", :on => :parts).first.should == altered_inheriting
119
+ expect(InheritingTaggableModel.tagged_with('fork', on: :parts)).to be_empty
120
+ expect(AlteredInheritingTaggableModel.tagged_with('fork', on: :parts).first).to eq(altered_inheriting)
125
121
  end
126
122
 
127
- it "should have different tag_counts_on for inherited models" do
128
- inheriting_model.tag_list = "bob, kelso"
123
+ it 'should have different tag_counts_on for inherited models' do
124
+ inheriting_model.tag_list = 'bob, kelso'
129
125
  inheriting_model.save!
130
- altered_inheriting.tag_list = "fork, spoon"
126
+ altered_inheriting.tag_list = 'fork, spoon'
131
127
  altered_inheriting.save!
132
128
 
133
- InheritingTaggableModel.tag_counts_on(:tags, :order => 'tags.id').map(&:name).should == %w(bob kelso)
134
- AlteredInheritingTaggableModel.tag_counts_on(:tags, :order => 'tags.id').map(&:name).should == %w(fork spoon)
135
- TaggableModel.tag_counts_on(:tags, :order => 'tags.id').map(&:name).should == %w(bob kelso fork spoon)
129
+ expect(InheritingTaggableModel.tag_counts_on(:tags, order: 'tags.id').map(&:name)).to eq(%w(bob kelso))
130
+ expect(AlteredInheritingTaggableModel.tag_counts_on(:tags, order: 'tags.id').map(&:name)).to eq(%w(fork spoon))
131
+ expect(TaggableModel.tag_counts_on(:tags, order: 'tags.id').map(&:name)).to eq(%w(bob kelso fork spoon))
136
132
  end
137
133
 
138
- it "should have different tags_on for inherited models" do
139
- inheriting_model.tag_list = "bob, kelso"
134
+ it 'should have different tags_on for inherited models' do
135
+ inheriting_model.tag_list = 'bob, kelso'
140
136
  inheriting_model.save!
141
- altered_inheriting.tag_list = "fork, spoon"
137
+ altered_inheriting.tag_list = 'fork, spoon'
142
138
  altered_inheriting.save!
143
139
 
144
- InheritingTaggableModel.tags_on(:tags, :order => 'tags.id').map(&:name).should == %w(bob kelso)
145
- AlteredInheritingTaggableModel.tags_on(:tags, :order => 'tags.id').map(&:name).should == %w(fork spoon)
146
- TaggableModel.tags_on(:tags, :order => 'tags.id').map(&:name).should == %w(bob kelso fork spoon)
140
+ expect(InheritingTaggableModel.tags_on(:tags, order: 'tags.id').map(&:name)).to eq(%w(bob kelso))
141
+ expect(AlteredInheritingTaggableModel.tags_on(:tags, order: 'tags.id').map(&:name)).to eq(%w(fork spoon))
142
+ expect(TaggableModel.tags_on(:tags, order: 'tags.id').map(&:name)).to eq(%w(bob kelso fork spoon))
147
143
  end
148
144
 
149
145
  it 'should store same tag without validation conflict' do
@@ -153,35 +149,62 @@ describe "Single Table Inheritance" do
153
149
  inheriting_model.tag_list = 'one'
154
150
  inheriting_model.save!
155
151
 
156
- inheriting_model.update_attributes! :name => 'foo'
152
+ inheriting_model.update_attributes! name: 'foo'
157
153
  end
158
154
  end
159
155
 
160
- describe "ownership" do
161
- it "should have taggings" do
162
- student.tag(taggable, :with=>'ruby,scheme', :on=>:tags)
163
- student.owned_taggings.should have(2).tags
156
+ describe 'ownership' do
157
+ it 'should have taggings' do
158
+ student.tag(taggable, with: 'ruby,scheme', on: :tags)
159
+ expect(student.owned_taggings.count).to eq(2)
164
160
  end
165
161
 
166
- it "should have tags" do
167
- student.tag(taggable, :with=>'ruby,scheme', :on=>:tags)
168
- student.owned_tags.should have(2).tags
162
+ it 'should have tags' do
163
+ student.tag(taggable, with: 'ruby,scheme', on: :tags)
164
+ expect(student.owned_tags.count).to eq(2)
169
165
  end
170
166
 
171
- it "should return tags for the inheriting tagger" do
172
- student.tag(taggable, :with => 'ruby, scheme', :on => :tags)
173
- taggable.tags_from(student).should match_array(%w(ruby scheme))
167
+ it 'should return tags for the inheriting tagger' do
168
+ student.tag(taggable, with: 'ruby, scheme', on: :tags)
169
+ expect(taggable.tags_from(student)).to eq(%w(ruby scheme))
174
170
  end
175
171
 
176
- it "returns owner tags on the tagger" do
177
- student.tag(taggable, :with => 'ruby, scheme', :on => :tags)
178
- taggable.owner_tags_on(student, :tags).should have(2).tags
172
+ it 'returns owner tags on the tagger' do
173
+ student.tag(taggable, with: 'ruby, scheme', on: :tags)
174
+ expect(taggable.owner_tags_on(student, :tags).count).to eq(2)
179
175
  end
180
176
 
181
- it "should scope objects returned by tagged_with by owners" do
182
- student.tag(taggable, :with => 'ruby, scheme', :on => :tags)
183
- TaggableModel.tagged_with(%w(ruby scheme), :owned_by => student).should have(1).tag
177
+ it 'should scope objects returned by tagged_with by owners' do
178
+ student.tag(taggable, with: 'ruby, scheme', on: :tags)
179
+ expect(TaggableModel.tagged_with(%w(ruby scheme), owned_by: student).count).to eq(1)
184
180
  end
185
181
  end
186
182
 
183
+ describe 'a subclass of Tag' do
184
+ let(:company) { Company.new(:name => 'Dewey, Cheatham & Howe') }
185
+ let(:user) { User.create! }
186
+
187
+ subject { Market.create! :name => 'finance' }
188
+
189
+ its(:type) { should eql 'Market' }
190
+
191
+ it 'sets STI type through string list' do
192
+ company.market_list = 'law, accounting'
193
+ company.save!
194
+ expect(Market.count).to eq(2)
195
+ end
196
+
197
+ it 'does not interfere with a normal Tag context on the same model' do
198
+ company.location_list = 'cambridge'
199
+ company.save!
200
+ expect(ActsAsTaggableOn::Tag.where(name: 'cambridge', type: nil)).to_not be_empty
201
+ end
202
+
203
+ it 'is returned with proper type through ownership' do
204
+ user.tag(company, :with => 'ripoffs, rackets', :on => :markets)
205
+ tags = company.owner_tags_on(user, :markets)
206
+ expect(tags.all? { |tag| tag.is_a? Market }).to be_truthy
207
+ end
208
+ end
187
209
  end
210
+
@@ -2,124 +2,156 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  describe ActsAsTaggableOn::TagList do
5
- let(:tag_list) { ActsAsTaggableOn::TagList.new("awesome","radical") }
5
+ let(:tag_list) { ActsAsTaggableOn::TagList.new('awesome', 'radical') }
6
+ let(:another_tag_list) { ActsAsTaggableOn::TagList.new('awesome','crazy', 'alien') }
6
7
 
7
8
  it { should be_kind_of Array }
8
9
 
9
- it "#from should return empty array if empty array is passed" do
10
- ActsAsTaggableOn::TagList.from([]).should be_empty
10
+ it '#from should return empty array if empty array is passed' do
11
+ expect(ActsAsTaggableOn::TagList.from([])).to be_empty
11
12
  end
12
13
 
13
- describe "#add" do
14
- it "should be able to be add a new tag word" do
15
- tag_list.add("cool")
16
- tag_list.include?("cool").should be_true
14
+ describe '#add' do
15
+ it 'should be able to be add a new tag word' do
16
+ tag_list.add('cool')
17
+ expect(tag_list.include?('cool')).to be_truthy
17
18
  end
18
19
 
19
- it "should be able to add delimited lists of words" do
20
- tag_list.add("cool, wicked", :parse => true)
21
- tag_list.should include("cool", "wicked")
20
+ it 'should be able to add delimited lists of words' do
21
+ tag_list.add('cool, wicked', parse: true)
22
+ expect(tag_list).to include('cool', 'wicked')
22
23
  end
23
24
 
24
- it "should be able to add delimited list of words with quoted delimiters" do
25
- tag_list.add("'cool, wicked', \"really cool, really wicked\"", :parse => true)
26
- tag_list.should include("cool, wicked", "really cool, really wicked")
25
+ it 'should be able to add delimited list of words with quoted delimiters' do
26
+ tag_list.add("'cool, wicked', \"really cool, really wicked\"", parse: true)
27
+ expect(tag_list).to include('cool, wicked', 'really cool, really wicked')
27
28
  end
28
29
 
29
- it "should be able to handle other uses of quotation marks correctly" do
30
- tag_list.add("john's cool car, mary's wicked toy", :parse => true)
31
- tag_list.should include("john's cool car", "mary's wicked toy")
30
+ it 'should be able to handle other uses of quotation marks correctly' do
31
+ tag_list.add("john's cool car, mary's wicked toy", parse: true)
32
+ expect(tag_list).to include("john's cool car", "mary's wicked toy")
32
33
  end
33
34
 
34
- it "should be able to add an array of words" do
35
- tag_list.add(["cool", "wicked"], :parse => true)
36
- tag_list.should include("cool", "wicked")
35
+ it 'should be able to add an array of words' do
36
+ tag_list.add(%w(cool wicked), parse: true)
37
+ expect(tag_list).to include('cool', 'wicked')
37
38
  end
38
39
 
39
- it "should quote escape tags with commas in them" do
40
- tag_list.add("cool","rad,bodacious")
41
- tag_list.to_s.should == "awesome, radical, cool, \"rad,bodacious\""
40
+ it 'should quote escape tags with commas in them' do
41
+ tag_list.add('cool', 'rad,bodacious')
42
+ expect(tag_list.to_s).to eq("awesome, radical, cool, \"rad,bodacious\"")
42
43
  end
43
44
 
44
45
  end
45
46
 
46
- describe "#remove" do
47
- it "should be able to remove words" do
48
- tag_list.remove("awesome")
49
- tag_list.should_not include("awesome")
47
+ describe '#remove' do
48
+ it 'should be able to remove words' do
49
+ tag_list.remove('awesome')
50
+ expect(tag_list).to_not include('awesome')
50
51
  end
51
52
 
52
- it "should be able to remove delimited lists of words" do
53
- tag_list.remove("awesome, radical", :parse => true)
54
- tag_list.should be_empty
53
+ it 'should be able to remove delimited lists of words' do
54
+ tag_list.remove('awesome, radical', parse: true)
55
+ expect(tag_list).to be_empty
55
56
  end
56
57
 
57
- it "should be able to remove an array of words" do
58
- tag_list.remove(["awesome", "radical"], :parse => true)
59
- tag_list.should be_empty
58
+ it 'should be able to remove an array of words' do
59
+ tag_list.remove(%w(awesome radical), parse: true)
60
+ expect(tag_list).to be_empty
60
61
  end
61
62
  end
62
63
 
63
- describe "#to_s" do
64
- it "should give a delimited list of words when converted to string" do
65
- tag_list.to_s.should == "awesome, radical"
64
+ describe '#+' do
65
+ it 'should not have duplicate tags' do
66
+ new_tag_list = tag_list + another_tag_list
67
+ expect(tag_list).to eq(%w[awesome radical])
68
+ expect(another_tag_list).to eq(%w[awesome crazy alien])
69
+ expect(new_tag_list).to eq(%w[awesome radical crazy alien])
66
70
  end
67
71
 
68
- it "should be able to call to_s on a frozen tag list" do
72
+ it 'should have class : ActsAsTaggableOn::TagList' do
73
+ new_tag_list = tag_list + another_tag_list
74
+ expect(new_tag_list.class).to eq(ActsAsTaggableOn::TagList)
75
+ end
76
+ end
77
+
78
+ describe '#concat' do
79
+ it 'should not have duplicate tags' do
80
+ expect(tag_list.concat(another_tag_list)).to eq(%w[awesome radical crazy alien])
81
+ end
82
+
83
+ it 'should have class : ActsAsTaggableOn::TagList' do
84
+ new_tag_list = tag_list.concat(another_tag_list)
85
+ expect(new_tag_list.class).to eq(ActsAsTaggableOn::TagList)
86
+ end
87
+ end
88
+
89
+ describe '#to_s' do
90
+ it 'should give a delimited list of words when converted to string' do
91
+ expect(tag_list.to_s).to eq('awesome, radical')
92
+ end
93
+
94
+ it 'should be able to call to_s on a frozen tag list' do
69
95
  tag_list.freeze
70
- lambda { tag_list.add("cool","rad,bodacious") }.should raise_error
71
- lambda { tag_list.to_s }.should_not raise_error
96
+ expect(-> { tag_list.add('cool', 'rad,bodacious') }).to raise_error
97
+ expect(-> { tag_list.to_s }).to_not raise_error
72
98
  end
73
99
  end
74
100
 
75
- describe "cleaning" do
76
- it "should parameterize if force_parameterize is set to true" do
101
+ describe 'cleaning' do
102
+ it 'should parameterize if force_parameterize is set to true' do
77
103
  ActsAsTaggableOn.force_parameterize = true
78
- tag_list = ActsAsTaggableOn::TagList.new("awesome()","radical)(cc")
104
+ tag_list = ActsAsTaggableOn::TagList.new('awesome()', 'radical)(cc')
79
105
 
80
- tag_list.to_s.should == "awesome, radical-cc"
106
+ expect(tag_list.to_s).to eq('awesome, radical-cc')
81
107
  ActsAsTaggableOn.force_parameterize = false
82
108
  end
83
109
 
84
- it "should lowercase if force_lowercase is set to true" do
110
+ it 'should lowercase if force_lowercase is set to true' do
85
111
  ActsAsTaggableOn.force_lowercase = true
86
112
 
87
- tag_list = ActsAsTaggableOn::TagList.new("aweSomE","RaDicaL","Entrée")
88
- tag_list.to_s.should == "awesome, radical, entrée"
113
+ tag_list = ActsAsTaggableOn::TagList.new('aweSomE', 'RaDicaL', 'Entrée')
114
+ expect(tag_list.to_s).to eq('awesome, radical, entrée')
89
115
 
90
116
  ActsAsTaggableOn.force_lowercase = false
91
117
  end
92
118
 
93
119
  end
94
120
 
95
- describe "Multiple Delimiter" do
96
- before do
121
+ describe 'Multiple Delimiter' do
122
+ before do
97
123
  @old_delimiter = ActsAsTaggableOn.delimiter
98
124
  end
99
125
 
100
- after do
126
+ after do
101
127
  ActsAsTaggableOn.delimiter = @old_delimiter
102
128
  end
103
129
 
104
- it "should separate tags by delimiters" do
130
+ it 'should separate tags by delimiters' do
105
131
  ActsAsTaggableOn.delimiter = [',', ' ', '\|']
106
- tag_list = ActsAsTaggableOn::TagList.from "cool, data|I have"
107
- tag_list.to_s.should == 'cool, data, I, have'
132
+ tag_list = ActsAsTaggableOn::TagList.from 'cool, data|I have'
133
+ expect(tag_list.to_s).to eq('cool, data, I, have')
108
134
  end
109
135
 
110
- it "should escape quote" do
136
+ it 'should escape quote' do
111
137
  ActsAsTaggableOn.delimiter = [',', ' ', '\|']
112
138
  tag_list = ActsAsTaggableOn::TagList.from "'I have'|cool, data"
113
- tag_list.to_s.should == '"I have", cool, data'
139
+ expect(tag_list.to_s).to eq('"I have", cool, data')
114
140
 
115
141
  tag_list = ActsAsTaggableOn::TagList.from '"I, have"|cool, data'
116
- tag_list.to_s.should == '"I, have", cool, data'
142
+ expect(tag_list.to_s).to eq('"I, have", cool, data')
117
143
  end
118
144
 
119
- it "should work for utf8 delimiter and long delimiter" do
145
+ it 'should work for utf8 delimiter and long delimiter' do
120
146
  ActsAsTaggableOn.delimiter = [',', '的', '可能是']
121
- tag_list = ActsAsTaggableOn::TagList.from "我的东西可能是不见了,还好有备份"
122
- tag_list.to_s.should == "我, 东西, 不见了, 还好有备份"
147
+ tag_list = ActsAsTaggableOn::TagList.from '我的东西可能是不见了,还好有备份'
148
+ expect(tag_list.to_s).to eq('我, 东西, 不见了, 还好有备份')
149
+ end
150
+
151
+ it 'should work for multiple quoted tags' do
152
+ ActsAsTaggableOn.delimiter = [',']
153
+ tag_list = ActsAsTaggableOn::TagList.from '"Ruby Monsters","eat Katzenzungen"'
154
+ expect(tag_list.to_s).to eq('Ruby Monsters, eat Katzenzungen')
123
155
  end
124
156
  end
125
157