acts-as-taggable-on 3.2.1 → 3.3.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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +21 -1
  3. data/Appraisals +0 -4
  4. data/CHANGELOG.md +27 -15
  5. data/README.md +18 -11
  6. data/acts-as-taggable-on.gemspec +0 -2
  7. data/db/migrate/4_add_missing_taggable_index.rb +9 -0
  8. data/gemfiles/activerecord_3.2.gemfile +0 -1
  9. data/gemfiles/activerecord_4.0.gemfile +0 -1
  10. data/gemfiles/activerecord_4.1.gemfile +0 -1
  11. data/gemfiles/activerecord_edge.gemfile +0 -1
  12. data/lib/acts-as-taggable-on.rb +28 -20
  13. data/lib/acts_as_taggable_on/tag.rb +1 -1
  14. data/lib/acts_as_taggable_on/tag_list.rb +15 -78
  15. data/lib/acts_as_taggable_on/tag_list_parser.rb +78 -0
  16. data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/cache.rb +1 -0
  17. data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/collection.rb +2 -0
  18. data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/core.rb +68 -44
  19. data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/ownership.rb +1 -1
  20. data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/related.rb +6 -6
  21. data/lib/acts_as_taggable_on/taggable.rb +7 -8
  22. data/lib/acts_as_taggable_on/tagging.rb +7 -1
  23. data/lib/acts_as_taggable_on/tags_helper.rb +2 -2
  24. data/lib/acts_as_taggable_on/utils.rb +26 -50
  25. data/lib/acts_as_taggable_on/version.rb +1 -1
  26. data/spec/acts_as_taggable_on/acts_as_taggable_on_spec.rb +1 -1
  27. data/spec/acts_as_taggable_on/acts_as_tagger_spec.rb +1 -0
  28. data/spec/acts_as_taggable_on/caching_spec.rb +1 -0
  29. data/spec/acts_as_taggable_on/related_spec.rb +1 -0
  30. data/spec/acts_as_taggable_on/single_table_inheritance_spec.rb +1 -0
  31. data/spec/acts_as_taggable_on/tag_list_parser_spec.rb +46 -0
  32. data/spec/acts_as_taggable_on/tag_list_spec.rb +3 -40
  33. data/spec/acts_as_taggable_on/tag_spec.rb +34 -38
  34. data/spec/acts_as_taggable_on/taggable/dirty_spec.rb +127 -0
  35. data/spec/acts_as_taggable_on/taggable_spec.rb +84 -164
  36. data/spec/acts_as_taggable_on/tagger_spec.rb +1 -1
  37. data/spec/acts_as_taggable_on/tagging_spec.rb +37 -1
  38. data/spec/acts_as_taggable_on/tags_helper_spec.rb +1 -0
  39. data/spec/acts_as_taggable_on/utils_spec.rb +6 -11
  40. data/spec/internal/app/models/cached_model_with_array.rb +1 -1
  41. data/spec/internal/app/models/models.rb +2 -2
  42. data/spec/internal/db/schema.rb +2 -2
  43. data/spec/spec_helper.rb +0 -1
  44. data/spec/support/0-helpers.rb +32 -0
  45. data/spec/support/database_cleaner.rb +4 -0
  46. metadata +17 -47
  47. data/spec/bm.rb +0 -52
  48. data/spec/schema.rb +0 -82
  49. /data/lib/acts_as_taggable_on/{acts_as_taggable_on/compatibility.rb → compatibility.rb} +0 -0
  50. /data/lib/acts_as_taggable_on/{acts_as_taggable_on → taggable}/dirty.rb +0 -0
@@ -1,10 +1,13 @@
1
- # encoding: utf-8
1
+ # -*- encoding : utf-8 -*-
2
2
  require 'spec_helper'
3
3
  require 'db/migrate/2_add_missing_unique_indices.rb'
4
4
 
5
5
  shared_examples_for 'without unique index' do
6
- before { AddMissingUniqueIndices.down }
7
- after { ActsAsTaggableOn::Tag.delete_all; AddMissingUniqueIndices.up }
6
+ prepend_before(:all) { AddMissingUniqueIndices.down }
7
+ append_after(:all) do
8
+ ActsAsTaggableOn::Tag.delete_all
9
+ AddMissingUniqueIndices.up
10
+ end
8
11
  end
9
12
 
10
13
  describe ActsAsTaggableOn::Tag do
@@ -14,23 +17,20 @@ describe ActsAsTaggableOn::Tag do
14
17
  end
15
18
 
16
19
 
17
-
18
20
  describe 'named like any' do
19
- context 'case insensitive collation and unique index on tag name' do
20
- if ActsAsTaggableOn::Utils.using_case_insensitive_collation?
21
- before(:each) do
22
- ActsAsTaggableOn::Tag.create(name: 'Awesome')
23
- ActsAsTaggableOn::Tag.create(name: 'epic')
24
- end
25
-
26
- it 'should find both tags' do
27
- expect(ActsAsTaggableOn::Tag.named_like_any(%w(awesome epic)).count).to eq(2)
28
- end
21
+ context 'case insensitive collation and unique index on tag name', if: using_case_insensitive_collation? do
22
+ before(:each) do
23
+ ActsAsTaggableOn::Tag.create(name: 'Awesome')
24
+ ActsAsTaggableOn::Tag.create(name: 'epic')
25
+ end
26
+
27
+ it 'should find both tags' do
28
+ expect(ActsAsTaggableOn::Tag.named_like_any(%w(awesome epic)).count).to eq(2)
29
29
  end
30
30
  end
31
31
 
32
32
  context 'case insensitive collation without indexes or case sensitive collation with indexes' do
33
- if ActsAsTaggableOn::Utils.using_case_insensitive_collation?
33
+ if using_case_insensitive_collation?
34
34
  include_context 'without unique index'
35
35
  end
36
36
 
@@ -67,28 +67,24 @@ describe ActsAsTaggableOn::Tag do
67
67
  end
68
68
  end
69
69
 
70
- unless ActsAsTaggableOn::Utils.using_sqlite?
71
- describe 'find or create by unicode name' do
72
- before(:each) do
73
- @tag.name = 'привет'
74
- @tag.save
75
- end
70
+ describe 'find or create by unicode name', unless: using_sqlite? do
71
+ before(:each) do
72
+ @tag.name = 'привет'
73
+ @tag.save
74
+ end
76
75
 
77
- it 'should find by name' do
78
- expect(ActsAsTaggableOn::Tag.find_or_create_with_like_by_name('привет')).to eq(@tag)
79
- end
76
+ it 'should find by name' do
77
+ expect(ActsAsTaggableOn::Tag.find_or_create_with_like_by_name('привет')).to eq(@tag)
78
+ end
80
79
 
81
- it 'should find by name case insensitive' do
82
- expect(ActsAsTaggableOn::Tag.find_or_create_with_like_by_name('ПРИВЕТ')).to eq(@tag)
83
- end
80
+ it 'should find by name case insensitive' do
81
+ expect(ActsAsTaggableOn::Tag.find_or_create_with_like_by_name('ПРИВЕТ')).to eq(@tag)
82
+ end
84
83
 
85
- if ActsAsTaggableOn::Utils.using_case_insensitive_collation?
86
- it 'should find by name accent insensitive' do
87
- @tag.name = 'inupiat'
88
- @tag.save
89
- expect(ActsAsTaggableOn::Tag.find_or_create_with_like_by_name('Iñupiat')).to eq(@tag)
90
- end
91
- end
84
+ it 'should find by name accent insensitive', if: using_case_insensitive_collation? do
85
+ @tag.name = 'inupiat'
86
+ @tag.save
87
+ expect(ActsAsTaggableOn::Tag.find_or_create_with_like_by_name('Iñupiat')).to eq(@tag)
92
88
  end
93
89
  end
94
90
 
@@ -107,7 +103,7 @@ describe ActsAsTaggableOn::Tag do
107
103
  end
108
104
 
109
105
  context 'case sensitive' do
110
- if ActsAsTaggableOn::Utils.using_case_insensitive_collation?
106
+ if using_case_insensitive_collation?
111
107
  include_context 'without unique index'
112
108
  end
113
109
 
@@ -126,7 +122,7 @@ describe ActsAsTaggableOn::Tag do
126
122
  end
127
123
 
128
124
  context 'case sensitive' do
129
- if ActsAsTaggableOn::Utils.using_case_insensitive_collation?
125
+ if using_case_insensitive_collation?
130
126
  include_context 'without unique index'
131
127
  end
132
128
 
@@ -226,7 +222,7 @@ describe ActsAsTaggableOn::Tag do
226
222
  end
227
223
 
228
224
  context 'case sensitive' do
229
- if ActsAsTaggableOn::Utils.using_case_insensitive_collation?
225
+ if using_case_insensitive_collation?
230
226
  include_context 'without unique index'
231
227
  end
232
228
 
@@ -240,7 +236,7 @@ describe ActsAsTaggableOn::Tag do
240
236
  end
241
237
 
242
238
  context 'case sensitive' do
243
- if ActsAsTaggableOn::Utils.using_case_insensitive_collation?
239
+ if using_case_insensitive_collation?
244
240
  include_context 'without unique index'
245
241
  end
246
242
 
@@ -0,0 +1,127 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe ActsAsTaggableOn::Taggable::Dirty do
5
+ context 'with un-contexted tags' do
6
+ before(:each) do
7
+ @taggable = TaggableModel.create(tag_list: 'awesome, epic')
8
+ end
9
+
10
+ context 'when tag_list changed' do
11
+ before(:each) do
12
+ expect(@taggable.changes).to be_empty
13
+ @taggable.tag_list = 'one'
14
+ end
15
+
16
+ it 'should show changes of dirty object' do
17
+ expect(@taggable.changes).to eq({'tag_list' => ['awesome, epic', ['one']]})
18
+ end
19
+
20
+ it 'flags tag_list as changed' do
21
+ expect(@taggable.tag_list_changed?).to be_truthy
22
+ end
23
+
24
+ it 'preserves original value' do
25
+ expect(@taggable.tag_list_was).to eq('awesome, epic')
26
+ end
27
+
28
+ it 'shows what the change was' do
29
+ expect(@taggable.tag_list_change).to eq(['awesome, epic', ['one']])
30
+ end
31
+
32
+ context 'without order' do
33
+ it 'should not mark attribute if order change ' do
34
+ taggable = TaggableModel.create(name: 'Dirty Harry', tag_list: %w(d c b a))
35
+ taggable.tag_list = %w(a b c d)
36
+ expect(taggable.tag_list_changed?).to be_falsey
37
+ end
38
+ end
39
+
40
+ context 'with order' do
41
+ it 'should mark attribute if order change' do
42
+ taggable = OrderedTaggableModel.create(name: 'Clean Harry', tag_list: 'd,c,b,a')
43
+ taggable.save
44
+ taggable.tag_list = %w(a b c d)
45
+ expect(taggable.tag_list_changed?).to be_truthy
46
+ end
47
+ end
48
+ end
49
+
50
+ context 'when tag_list is the same' do
51
+ before(:each) do
52
+ @taggable.tag_list = 'awesome, epic'
53
+ end
54
+
55
+ it 'is not flagged as changed' do
56
+ expect(@taggable.tag_list_changed?).to be_falsy
57
+ end
58
+
59
+ it 'does not show any changes to the taggable item' do
60
+ expect(@taggable.changes).to be_empty
61
+ end
62
+
63
+ context "and using a delimiter different from a ','" do
64
+ before do
65
+ @old_delimiter = ActsAsTaggableOn.delimiter
66
+ ActsAsTaggableOn.delimiter = ';'
67
+ end
68
+
69
+ after do
70
+ ActsAsTaggableOn.delimiter = @old_delimiter
71
+ end
72
+
73
+ it 'does not show any changes to the taggable item when using array assignments' do
74
+ @taggable.tag_list = %w(awesome epic)
75
+ expect(@taggable.changes).to be_empty
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ context 'with context tags' do
82
+ before(:each) do
83
+ @taggable = TaggableModel.create('language_list' => 'awesome, epic')
84
+ end
85
+
86
+ context 'when language_list changed' do
87
+ before(:each) do
88
+ expect(@taggable.changes).to be_empty
89
+ @taggable.language_list = 'one'
90
+ end
91
+
92
+ it 'should show changes of dirty object' do
93
+ expect(@taggable.changes).to eq({'language_list' => ['awesome, epic', ['one']]})
94
+ end
95
+
96
+ it 'flags language_list as changed' do
97
+ expect(@taggable.language_list_changed?).to be_truthy
98
+ end
99
+
100
+ it 'preserves original value' do
101
+ expect(@taggable.language_list_was).to eq('awesome, epic')
102
+ end
103
+
104
+ it 'shows what the change was' do
105
+ expect(@taggable.language_list_change).to eq(['awesome, epic', ['one']])
106
+ end
107
+
108
+ it 'shows what the changes were' do
109
+ expect(@taggable.language_list_changes).to eq(['awesome, epic', ['one']])
110
+ end
111
+ end
112
+
113
+ context 'when language_list is the same' do
114
+ before(:each) do
115
+ @taggable.language_list = 'awesome, epic'
116
+ end
117
+
118
+ it 'is not flagged as changed' do
119
+ expect(@taggable.language_list_changed?).to be_falsy
120
+ end
121
+
122
+ it 'does not show any changes to the taggable item' do
123
+ expect(@taggable.changes).to be_empty
124
+ end
125
+ end
126
+ end
127
+ end
@@ -208,6 +208,14 @@ describe 'Taggable' do
208
208
  expect(TaggableModel.tagged_with('ruby').group(:created_at).count.count).to eq(1)
209
209
  end
210
210
 
211
+ it 'can be used as scope' do
212
+ @taggable.skill_list = 'ruby'
213
+ @taggable.save
214
+ untaggable_model = @taggable.untaggable_models.create!(name:'foobar')
215
+ scope_tag = TaggableModel.tagged_with('ruby', any: 'distinct', order: 'taggable_models.name asc')
216
+ expect(UntaggableModel.joins(:taggable_model).merge(scope_tag).except(:select)).to eq([untaggable_model])
217
+ end
218
+
211
219
  it "shouldn't generate a query with DISTINCT by default" do
212
220
  @taggable.skill_list = 'ruby, rails, css'
213
221
  @taggable.save
@@ -215,6 +223,20 @@ describe 'Taggable' do
215
223
  expect(TaggableModel.tagged_with('ruby').to_sql).to_not match /DISTINCT/
216
224
  end
217
225
 
226
+ it "should be able to find a tag using dates" do
227
+ @taggable.skill_list = "ruby"
228
+ @taggable.save
229
+
230
+ expect(TaggableModel.tagged_with("ruby", :start_at => Date.today, :end_at => Date.tomorrow).count).to eq(1)
231
+ end
232
+
233
+ it "shouldn't be able to find a tag outside date range" do
234
+ @taggable.skill_list = "ruby"
235
+ @taggable.save
236
+
237
+ expect(TaggableModel.tagged_with("ruby", :start_at => Date.today - 2.days, :end_at => Date.today - 1.day).count).to eq(0)
238
+ end
239
+
218
240
  it 'should be able to find by tag with context' do
219
241
  @taggable.skill_list = 'ruby, rails, css'
220
242
  @taggable.tag_list = 'bob, charlie'
@@ -255,16 +277,14 @@ describe 'Taggable' do
255
277
  expect(TaggableModel.select('distinct(taggable_models.id), taggable_models.*').joins(:untaggable_models).tagged_with(['rails', 'ruby'], :any => false).to_a.sort).to eq([bob, frank].sort)
256
278
  end
257
279
 
258
- unless ActsAsTaggableOn::Utils.using_sqlite?
259
- it 'should not care about case for unicode names' do
260
- ActsAsTaggableOn.strict_case_match = false
261
- TaggableModel.create(name: 'Anya', tag_list: 'ПРИВЕТ')
262
- TaggableModel.create(name: 'Igor', tag_list: 'привет')
263
- TaggableModel.create(name: 'Katia', tag_list: 'ПРИВЕТ')
280
+ it 'should not care about case for unicode names', unless: using_sqlite? do
281
+ ActsAsTaggableOn.strict_case_match = false
282
+ TaggableModel.create(name: 'Anya', tag_list: 'ПРИВЕТ')
283
+ TaggableModel.create(name: 'Igor', tag_list: 'привет')
284
+ TaggableModel.create(name: 'Katia', tag_list: 'ПРИВЕТ')
264
285
 
265
- expect(ActsAsTaggableOn::Tag.all.size).to eq(1)
266
- expect(TaggableModel.tagged_with('привет').to_a).to eq(TaggableModel.tagged_with('ПРИВЕТ').to_a)
267
- end
286
+ expect(ActsAsTaggableOn::Tag.all.size).to eq(1)
287
+ expect(TaggableModel.tagged_with('привет').to_a).to eq(TaggableModel.tagged_with('ПРИВЕТ').to_a)
268
288
  end
269
289
 
270
290
  context 'should be able to create and find tags in languages without capitalization :' do
@@ -494,6 +514,19 @@ describe 'Taggable' do
494
514
  end
495
515
  end
496
516
 
517
+ it 'should options key not be deleted' do
518
+ options = {:exclude => true}
519
+ TaggableModel.tagged_with("foo", options)
520
+ expect(options).to eq({:exclude => true})
521
+ end
522
+
523
+ it 'should not delete tags if not updated' do
524
+ model = TaggableModel.create(name: 'foo', tag_list: 'ruby, rails, programming')
525
+ model.update_attributes(name: 'bar')
526
+ model.reload
527
+ expect(model.tag_list.sort).to eq(%w(ruby rails programming).sort)
528
+ end
529
+
497
530
  context 'Duplicates' do
498
531
  context 'should not create duplicate taggings' do
499
532
  let(:bob) { TaggableModel.create(name: 'Bob') }
@@ -580,28 +613,26 @@ describe 'Taggable' do
580
613
 
581
614
  end
582
615
 
583
- if ActsAsTaggableOn::Utils.supports_concurrency?
584
- xit 'should not duplicate tags added on different threads' do
585
- #TODO, try with more threads and fix deadlock
586
- thread_count = 4
587
- barrier = Barrier.new thread_count
588
-
589
- expect {
590
- thread_count.times.map do |idx|
591
- Thread.start do
592
- connor = TaggableModel.first_or_create(name: 'Connor')
593
- connor.tag_list = 'There, can, be, only, one'
594
- barrier.wait
595
- begin
596
- connor.save
597
- rescue ActsAsTaggableOn::DuplicateTagError
598
- # second save should succeed
599
- connor.save
600
- end
616
+ xit 'should not duplicate tags added on different threads', if: supports_concurrency?, skip: 'FIXME, Deadlocks in travis' do
617
+ #TODO, try with more threads and fix deadlock
618
+ thread_count = 4
619
+ barrier = Barrier.new thread_count
620
+
621
+ expect {
622
+ thread_count.times.map do |idx|
623
+ Thread.start do
624
+ connor = TaggableModel.first_or_create(name: 'Connor')
625
+ connor.tag_list = 'There, can, be, only, one'
626
+ barrier.wait
627
+ begin
628
+ connor.save
629
+ rescue ActsAsTaggableOn::DuplicateTagError
630
+ # second save should succeed
631
+ connor.save
601
632
  end
602
- end.map(&:join)
603
- }.to change(ActsAsTaggableOn::Tag, :count).by(5)
604
- end
633
+ end
634
+ end.map(&:join)
635
+ }.to change(ActsAsTaggableOn::Tag, :count).by(5)
605
636
  end
606
637
  end
607
638
 
@@ -621,8 +652,8 @@ describe 'Taggable' do
621
652
  it 'should return all column names joined for Tag GROUP clause' do
622
653
  # NOTE: type column supports an STI Tag subclass in the test suite, though
623
654
  # isn't included by default in the migration generator
624
- expect(@taggable.grouped_column_names_for(ActsAsTaggableOn::Tag)).
625
- to eq('tags.id, tags.name, tags.taggings_count, tags.type')
655
+ expect(@taggable.grouped_column_names_for(ActsAsTaggableOn::Tag))
656
+ .to eq('tags.id, tags.name, tags.taggings_count, tags.type')
626
657
  end
627
658
 
628
659
  it 'should return all column names joined for TaggableModel GROUP clause' do
@@ -693,114 +724,6 @@ describe 'Taggable' do
693
724
  end
694
725
  end
695
726
 
696
- describe 'Dirty Objects' do
697
- context 'with un-contexted tags' do
698
- before(:each) do
699
- @taggable = TaggableModel.create(tag_list: 'awesome, epic')
700
- end
701
-
702
- context 'when tag_list changed' do
703
- before(:each) do
704
- expect(@taggable.changes).to be_empty
705
- @taggable.tag_list = 'one'
706
- end
707
-
708
- it 'should show changes of dirty object' do
709
- expect(@taggable.changes).to eq({'tag_list' => ['awesome, epic', ['one']]})
710
- end
711
-
712
- it 'flags tag_list as changed' do
713
- expect(@taggable.tag_list_changed?).to be_truthy
714
- end
715
-
716
- it 'preserves original value' do
717
- expect(@taggable.tag_list_was).to eq('awesome, epic')
718
- end
719
-
720
- it 'shows what the change was' do
721
- expect(@taggable.tag_list_change).to eq(['awesome, epic', ['one']])
722
- end
723
- end
724
-
725
- context 'when tag_list is the same' do
726
- before(:each) do
727
- @taggable.tag_list = 'awesome, epic'
728
- end
729
-
730
- it 'is not flagged as changed' do
731
- expect(@taggable.tag_list_changed?).to be_falsy
732
- end
733
-
734
- it 'does not show any changes to the taggable item' do
735
- expect(@taggable.changes).to be_empty
736
- end
737
-
738
- context "and using a delimiter different from a ','" do
739
- before do
740
- @old_delimiter = ActsAsTaggableOn.delimiter
741
- ActsAsTaggableOn.delimiter = ';'
742
- end
743
-
744
- after do
745
- ActsAsTaggableOn.delimiter = @old_delimiter
746
- end
747
-
748
- it 'does not show any changes to the taggable item when using array assignments' do
749
- @taggable.tag_list = %w(awesome epic)
750
- expect(@taggable.changes).to be_empty
751
- end
752
- end
753
- end
754
- end
755
-
756
- context 'with context tags' do
757
- before(:each) do
758
- @taggable = TaggableModel.create('language_list' => 'awesome, epic')
759
- end
760
-
761
- context 'when language_list changed' do
762
- before(:each) do
763
- expect(@taggable.changes).to be_empty
764
- @taggable.language_list = 'one'
765
- end
766
-
767
- it 'should show changes of dirty object' do
768
- expect(@taggable.changes).to eq({'language_list' => ['awesome, epic', ['one']]})
769
- end
770
-
771
- it 'flags language_list as changed' do
772
- expect(@taggable.language_list_changed?).to be_truthy
773
- end
774
-
775
- it 'preserves original value' do
776
- expect(@taggable.language_list_was).to eq('awesome, epic')
777
- end
778
-
779
- it 'shows what the change was' do
780
- expect(@taggable.language_list_change).to eq(['awesome, epic', ['one']])
781
- end
782
-
783
- it 'shows what the changes were' do
784
- expect(@taggable.language_list_changes).to eq(['awesome, epic', ['one']])
785
- end
786
- end
787
-
788
- context 'when language_list is the same' do
789
- before(:each) do
790
- @taggable.language_list = 'awesome, epic'
791
- end
792
-
793
- it 'is not flagged as changed' do
794
- expect(@taggable.language_list_changed?).to be_falsy
795
- end
796
-
797
- it 'does not show any changes to the taggable item' do
798
- expect(@taggable.changes).to be_empty
799
- end
800
- end
801
- end
802
- end
803
-
804
727
  describe 'Autogenerated methods' do
805
728
  it 'should be overridable' do
806
729
  expect(TaggableModel.create(tag_list: 'woo').tag_list_submethod_called).to be_truthy
@@ -847,33 +770,30 @@ describe 'Taggable' do
847
770
  end
848
771
  end
849
772
 
773
+ describe 'Taggable model with json columns', if: postgresql_support_json? do
774
+ before(:each) do
775
+ @taggable = TaggableModelWithJson.new(:name => 'Bob Jones')
776
+ @taggables = [@taggable, TaggableModelWithJson.new(:name => 'John Doe')]
777
+ end
850
778
 
851
- if ActsAsTaggableOn::Utils.using_postgresql?
852
- describe 'Taggable model with json columns' do
853
- before(:each) do
854
- @taggable = TaggableModelWithJson.new(:name => 'Bob Jones')
855
- @taggables = [@taggable, TaggableModelWithJson.new(:name => 'John Doe')]
856
- end
857
-
858
- it 'should be able to find by tag with context' do
859
- @taggable.skill_list = 'ruby, rails, css'
860
- @taggable.tag_list = 'bob, charlie'
861
- @taggable.save
779
+ it 'should be able to find by tag with context' do
780
+ @taggable.skill_list = 'ruby, rails, css'
781
+ @taggable.tag_list = 'bob, charlie'
782
+ @taggable.save
862
783
 
863
- expect(TaggableModelWithJson.tagged_with('ruby').first).to eq(@taggable)
864
- expect(TaggableModelWithJson.tagged_with('ruby, css').first).to eq(@taggable)
865
- expect(TaggableModelWithJson.tagged_with('bob', :on => :skills).first).to_not eq(@taggable)
866
- expect(TaggableModelWithJson.tagged_with('bob', :on => :tags).first).to eq(@taggable)
867
- end
784
+ expect(TaggableModelWithJson.tagged_with('ruby').first).to eq(@taggable)
785
+ expect(TaggableModelWithJson.tagged_with('ruby, css').first).to eq(@taggable)
786
+ expect(TaggableModelWithJson.tagged_with('bob', :on => :skills).first).to_not eq(@taggable)
787
+ expect(TaggableModelWithJson.tagged_with('bob', :on => :tags).first).to eq(@taggable)
788
+ end
868
789
 
869
- it 'should be able to find tagged with any tag' do
870
- bob = TaggableModelWithJson.create(:name => 'Bob', :tag_list => 'fitter, happier, more productive', :skill_list => 'ruby, rails, css')
871
- frank = TaggableModelWithJson.create(:name => 'Frank', :tag_list => 'weaker, depressed, inefficient', :skill_list => 'ruby, rails, css')
872
- steve = TaggableModelWithJson.create(:name => 'Steve', :tag_list => 'fitter, happier, more productive', :skill_list => 'c++, java, ruby')
790
+ it 'should be able to find tagged with any tag' do
791
+ bob = TaggableModelWithJson.create(:name => 'Bob', :tag_list => 'fitter, happier, more productive', :skill_list => 'ruby, rails, css')
792
+ frank = TaggableModelWithJson.create(:name => 'Frank', :tag_list => 'weaker, depressed, inefficient', :skill_list => 'ruby, rails, css')
793
+ steve = TaggableModelWithJson.create(:name => 'Steve', :tag_list => 'fitter, happier, more productive', :skill_list => 'c++, java, ruby')
873
794
 
874
- expect(TaggableModelWithJson.tagged_with(%w(ruby java), :order => 'taggable_model_with_jsons.name', :any => true).to_a).to eq([bob, frank, steve])
875
- expect(TaggableModelWithJson.tagged_with(%w(c++ fitter), :order => 'taggable_model_with_jsons.name', :any => true).to_a).to eq([bob, steve])
876
- expect(TaggableModelWithJson.tagged_with(%w(depressed css), :order => 'taggable_model_with_jsons.name', :any => true).to_a).to eq([bob, frank])
877
- end
795
+ expect(TaggableModelWithJson.tagged_with(%w(ruby java), :order => 'taggable_model_with_jsons.name', :any => true).to_a).to eq([bob, frank, steve])
796
+ expect(TaggableModelWithJson.tagged_with(%w(c++ fitter), :order => 'taggable_model_with_jsons.name', :any => true).to_a).to eq([bob, steve])
797
+ expect(TaggableModelWithJson.tagged_with(%w(depressed css), :order => 'taggable_model_with_jsons.name', :any => true).to_a).to eq([bob, frank])
878
798
  end
879
799
  end
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  require 'spec_helper'
2
3
 
3
4
  describe 'Tagger' do
@@ -43,7 +44,6 @@ describe 'Tagger' do
43
44
  tags = TaggableModel.tagged_with(%w(ruby java), owned_by: @user, any: true)
44
45
  expect(tags).to include(@taggable, @taggable2)
45
46
  expect(tags.size).to eq(2)
46
-
47
47
  end
48
48
 
49
49
  it 'only returns objects tagged by owned_by when exclude is true' do
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  require 'spec_helper'
2
3
 
3
4
  describe ActsAsTaggableOn::Tagging do
@@ -23,5 +24,40 @@ describe ActsAsTaggableOn::Tagging do
23
24
  2.times { ActsAsTaggableOn::Tagging.create(taggable: @taggable, tag: @tag, context: 'tags') }
24
25
  }).to change(ActsAsTaggableOn::Tagging, :count).by(1)
25
26
  end
26
-
27
+
28
+ it 'should not delete tags of other records' do
29
+ 6.times { TaggableModel.create(name: 'Bob Jones', tag_list: 'very, serious, bug') }
30
+ expect(ActsAsTaggableOn::Tag.count).to eq(3)
31
+ taggable = TaggableModel.first
32
+ taggable.tag_list = 'bug'
33
+ taggable.save
34
+
35
+ expect(taggable.tag_list).to eq(['bug'])
36
+
37
+ another_taggable = TaggableModel.where('id != ?', taggable.id).sample
38
+ expect(another_taggable.tag_list.sort).to eq(%w(very serious bug).sort)
39
+ end
40
+
41
+ it 'should destroy unused tags after tagging destroyed' do
42
+ previous_setting = ActsAsTaggableOn.remove_unused_tags
43
+ ActsAsTaggableOn.remove_unused_tags = true
44
+ ActsAsTaggableOn::Tag.destroy_all
45
+ @taggable = TaggableModel.create(name: 'Bob Jones')
46
+ @taggable.update_attribute :tag_list, 'aaa,bbb,ccc'
47
+ @taggable.update_attribute :tag_list, ''
48
+ expect(ActsAsTaggableOn::Tag.count).to eql(0)
49
+ ActsAsTaggableOn.remove_unused_tags = previous_setting
50
+ end
51
+
52
+ pending 'context scopes' do
53
+ describe '.by_context'
54
+
55
+ describe '.by_contexts'
56
+
57
+ describe '.owned_by'
58
+
59
+ describe '.not_owned'
60
+
61
+ end
62
+
27
63
  end
@@ -1,3 +1,4 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  require 'spec_helper'
2
3
 
3
4
  describe ActsAsTaggableOn::TagsHelper do
@@ -1,21 +1,16 @@
1
+ # -*- encoding : utf-8 -*-
1
2
  require 'spec_helper'
2
3
 
3
4
  describe ActsAsTaggableOn::Utils do
4
- describe 'like_operator' do
5
- before(:each) do
6
- TaggableModel.acts_as_taggable_on(:tags, :languages, :skills, :needs, :offerings)
7
- @taggable = TaggableModel.new(name: 'Bob Jones')
8
- end
9
-
10
-
5
+ describe '#like_operator' do
11
6
  it 'should return \'ILIKE\' when the adapter is PostgreSQL' do
12
- allow(TaggableModel.connection).to receive(:adapter_name) { 'PostgreSQL' }
13
- expect(TaggableModel.send(:like_operator)).to eq('ILIKE')
7
+ allow(ActsAsTaggableOn::Utils.connection).to receive(:adapter_name) { 'PostgreSQL' }
8
+ expect(ActsAsTaggableOn::Utils.like_operator).to eq('ILIKE')
14
9
  end
15
10
 
16
11
  it 'should return \'LIKE\' when the adapter is not PostgreSQL' do
17
- allow(TaggableModel.connection).to receive(:adapter_name) { 'MySQL' }
18
- expect(TaggableModel.send(:like_operator)).to eq('LIKE')
12
+ allow(ActsAsTaggableOn::Utils.connection).to receive(:adapter_name) { 'MySQL' }
13
+ expect(ActsAsTaggableOn::Utils.like_operator).to eq('LIKE')
19
14
  end
20
15
  end
21
16
  end
@@ -1,4 +1,4 @@
1
- if ActsAsTaggableOn::Utils.using_postgresql?
1
+ if using_postgresql?
2
2
  class CachedModelWithArray < ActiveRecord::Base
3
3
  acts_as_taggable
4
4
  end