gutentag 0.9.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +21 -0
  4. data/.travis.yml +6 -5
  5. data/Appraisals +20 -26
  6. data/Gemfile +13 -8
  7. data/README.md +5 -1
  8. data/Rakefile +9 -5
  9. data/app/models/gutentag/tag.rb +7 -4
  10. data/app/models/gutentag/tagging.rb +5 -3
  11. data/bin/literals +9 -0
  12. data/db/migrate/1_gutentag_tables.rb +5 -3
  13. data/db/migrate/2_gutentag_cache_counter.rb +2 -0
  14. data/db/migrate/3_no_null_counters.rb +8 -4
  15. data/gutentag.gemspec +18 -18
  16. data/lib/gutentag.rb +13 -13
  17. data/lib/gutentag/active_record.rb +11 -6
  18. data/lib/gutentag/active_record/class_methods.rb +4 -16
  19. data/lib/gutentag/active_record/instance_methods.rb +3 -1
  20. data/lib/gutentag/change_state.rb +32 -0
  21. data/lib/gutentag/dirty.rb +4 -1
  22. data/lib/gutentag/engine.rb +2 -4
  23. data/lib/gutentag/persistence.rb +13 -16
  24. data/lib/gutentag/tag_validations.rb +4 -1
  25. data/lib/gutentag/tagged_with.rb +5 -3
  26. data/lib/gutentag/tagged_with/id_query.rb +2 -0
  27. data/lib/gutentag/tagged_with/name_query.rb +2 -0
  28. data/lib/gutentag/tagged_with/query.rb +2 -0
  29. data/spec/acceptance/tag_names_spec.rb +40 -38
  30. data/spec/acceptance/tags_spec.rb +8 -6
  31. data/spec/gutentag/active_record_spec.rb +69 -112
  32. data/spec/gutentag_spec.rb +5 -3
  33. data/spec/internal/app/models/article.rb +2 -0
  34. data/spec/internal/db/schema.rb +2 -0
  35. data/spec/models/gutentag/tag_spec.rb +24 -22
  36. data/spec/models/gutentag/tagging_spec.rb +5 -3
  37. data/spec/spec_helper.rb +4 -2
  38. metadata +11 -43
  39. data/gemfiles/rails_3_2.gemfile +0 -11
  40. data/gemfiles/rails_4_0.gemfile +0 -11
  41. data/gemfiles/rails_4_1.gemfile +0 -11
  42. data/gemfiles/rails_4_2.gemfile +0 -10
  43. data/gemfiles/rails_5_0.gemfile +0 -8
  44. data/gemfiles/rails_5_1.gemfile +0 -8
  45. data/lib/gutentag/has_many_tags.rb +0 -10
@@ -1,10 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Gutentag::Dirty
2
4
  def self.call(instance, tag_names)
3
5
  new(instance, tag_names).call
4
6
  end
5
7
 
6
8
  def initialize(instance, tag_names)
7
- @instance, @tag_names = instance, tag_names
9
+ @instance = instance
10
+ @tag_names = tag_names
8
11
  end
9
12
 
10
13
  def call
@@ -1,7 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Gutentag::Engine < Rails::Engine
2
4
  engine_name :gutentag
3
-
4
- ActiveSupport.on_load :active_record do
5
- extend Gutentag::HasManyTags
6
- end
7
5
  end
@@ -1,11 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
1
5
  class Gutentag::Persistence
6
+ extend Forwardable
2
7
 
3
- attr_writer :tagger, :normaliser
8
+ attr_writer :tagger
4
9
 
5
- def initialize(taggable)
6
- @taggable = taggable
7
- @existing = normalised taggable.tags.collect(&:name)
8
- @changes = normalised taggable.tag_names
10
+ def initialize(change_state)
11
+ @change_state = change_state
9
12
  end
10
13
 
11
14
  def persist
@@ -17,20 +20,18 @@ class Gutentag::Persistence
17
20
 
18
21
  private
19
22
 
20
- attr_reader :taggable, :existing, :changes
23
+ attr_reader :change_state
24
+
25
+ def_delegators :change_state, :taggable, :added, :removed
21
26
 
22
27
  def add_new
23
- (changes - existing).each do |name|
28
+ added.each do |name|
24
29
  taggable.tags << tagger.find_or_create(name)
25
30
  end
26
31
  end
27
32
 
28
- def normalised(names)
29
- names.collect { |name| normaliser.call(name) }.uniq
30
- end
31
-
32
33
  def remove_old
33
- (existing - changes).each do |name|
34
+ removed.each do |name|
34
35
  taggable.tags.delete tagger.find_by_name(name)
35
36
  end
36
37
  end
@@ -38,8 +39,4 @@ class Gutentag::Persistence
38
39
  def tagger
39
40
  @tagger ||= Gutentag::Tag
40
41
  end
41
-
42
- def normaliser
43
- @normaliser ||= Proc.new { |name| Gutentag.normaliser.call(name) }
44
- end
45
42
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Gutentag::TagValidations
2
4
  def self.call(klass)
3
5
  new(klass).call
@@ -8,7 +10,8 @@ class Gutentag::TagValidations
8
10
  end
9
11
 
10
12
  def call
11
- klass.validates :name, :presence => true,
13
+ klass.validates :name,
14
+ :presence => true,
12
15
  :uniqueness => {:case_sensitive => false}
13
16
  end
14
17
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Gutentag::TaggedWith
2
4
  def self.call(model, options)
3
5
  new(model, options).call
@@ -33,6 +35,6 @@ class Gutentag::TaggedWith
33
35
  end
34
36
  end
35
37
 
36
- require 'gutentag/tagged_with/query'
37
- require 'gutentag/tagged_with/id_query'
38
- require 'gutentag/tagged_with/name_query'
38
+ require "gutentag/tagged_with/query"
39
+ require "gutentag/tagged_with/id_query"
40
+ require "gutentag/tagged_with/name_query"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Gutentag::TaggedWith::IDQuery < Gutentag::TaggedWith::Query
2
4
  private
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Gutentag::TaggedWith::NameQuery < Gutentag::TaggedWith::Query
2
4
  def initialize(model, values, match)
3
5
  super
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Gutentag::TaggedWith::Query
2
4
  def initialize(model, values, match)
3
5
  @model = model
@@ -1,38 +1,40 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  describe "Managing tags via names" do
4
6
  let(:article) { Article.create }
5
7
 
6
8
  it "returns tag names" do
7
- melbourne = Gutentag::Tag.create :name => 'melbourne'
9
+ melbourne = Gutentag::Tag.create :name => "melbourne"
8
10
 
9
11
  article.tags << melbourne
10
12
 
11
- expect(article.tag_names).to eq(['melbourne'])
13
+ expect(article.tag_names).to eq(["melbourne"])
12
14
  end
13
15
 
14
16
  it "adds tags via their names" do
15
- article.tag_names << 'melbourne'
17
+ article.tag_names << "melbourne"
16
18
  article.save!
17
19
 
18
- expect(article.tags.collect(&:name)).to eq(['melbourne'])
20
+ expect(article.tags.collect(&:name)).to eq(["melbourne"])
19
21
  end
20
22
 
21
23
  it "makes model dirty when changing through tag_names" do
22
- article.tag_names << 'melbourne'
24
+ article.tag_names << "melbourne"
23
25
  article.save!
24
26
 
25
- article.tag_names = ['sydney']
27
+ article.tag_names = ["sydney"]
26
28
 
27
29
  expect(article.changed_attributes.stringify_keys).
28
- to eq('tag_names' => ['melbourne'])
30
+ to eq("tag_names" => ["melbourne"])
29
31
  end if Gutentag.dirtier
30
32
 
31
33
  it "does not make model dirty when changing through tag_names" do
32
- article.tag_names << 'melbourne'
34
+ article.tag_names << "melbourne"
33
35
  article.save!
34
36
 
35
- article.tag_names = ['melbourne']
37
+ article.tag_names = ["melbourne"]
36
38
 
37
39
  expect(article.changed_attributes).to eq({})
38
40
  end
@@ -40,87 +42,87 @@ describe "Managing tags via names" do
40
42
  it "allows for different tag normalisation" do
41
43
  Gutentag.normaliser = lambda { |name| name.upcase }
42
44
 
43
- tag = Gutentag::Tag.create(:name => 'melbourne')
44
- expect(tag.name).to eq('MELBOURNE')
45
+ tag = Gutentag::Tag.create(:name => "melbourne")
46
+ expect(tag.name).to eq("MELBOURNE")
45
47
 
46
48
  Gutentag.normaliser = nil
47
49
  end
48
50
 
49
51
  it "doesn't complain when adding an existing tag" do
50
- article.tag_names << 'melbourne'
51
- article.tag_names << 'melbourne'
52
+ article.tag_names << "melbourne"
53
+ article.tag_names << "melbourne"
52
54
  article.save!
53
55
 
54
- expect(article.tags.collect(&:name)).to eq(['melbourne'])
56
+ expect(article.tags.collect(&:name)).to eq(["melbourne"])
55
57
  end
56
58
 
57
59
  it "accepts a completely new set of tags" do
58
- article.tag_names = ['portland', 'oregon']
60
+ article.tag_names = %w[ portland oregon ]
59
61
  article.save!
60
62
 
61
- expect(article.tags.collect(&:name)).to eq(['portland', 'oregon'])
63
+ expect(article.tags.collect(&:name)).to eq(%w[ portland oregon ])
62
64
  end
63
65
 
64
66
  it "does not allow duplication of tags" do
65
67
  existing = Article.create
66
- existing.tags << Gutentag::Tag.create(:name => 'portland')
68
+ existing.tags << Gutentag::Tag.create(:name => "portland")
67
69
 
68
- article.tag_names = ['portland']
70
+ article.tag_names = %w[ portland ]
69
71
  article.save!
70
72
 
71
73
  expect(existing.tag_ids).to eq(article.tag_ids)
72
74
  end
73
75
 
74
76
  it "appends tag names" do
75
- article.tag_names = ['portland']
76
- article.tag_names += ['oregon', 'ruby']
77
+ article.tag_names = %w[ portland ]
78
+ article.tag_names += %w[ oregon ruby ]
77
79
  article.save!
78
80
 
79
- expect(article.tags.collect(&:name)).to eq(['portland', 'oregon', 'ruby'])
81
+ expect(article.tags.collect(&:name)).to eq(%w[ portland oregon ruby ])
80
82
  end
81
83
 
82
84
  it "does not repeat appended names that already exist" do
83
- article.tag_names = ['portland', 'oregon']
84
- article.tag_names += ['oregon', 'ruby']
85
+ article.tag_names = %w[ portland oregon ]
86
+ article.tag_names += %w[ oregon ruby ]
85
87
  article.save!
86
88
 
87
- expect(article.tags.collect(&:name)).to eq(['portland', 'oregon', 'ruby'])
89
+ expect(article.tags.collect(&:name)).to eq(%w[ portland oregon ruby ])
88
90
  end
89
91
 
90
92
  it "removes a single tag name" do
91
- article.tag_names = ['portland', 'oregon']
92
- article.tag_names.delete 'oregon'
93
+ article.tag_names = %w[ portland oregon ]
94
+ article.tag_names.delete "oregon"
93
95
  article.save!
94
96
 
95
- expect(article.tags.collect(&:name)).to eq(['portland'])
97
+ expect(article.tags.collect(&:name)).to eq(%w[ portland ])
96
98
  end
97
99
 
98
100
  it "removes tag names" do
99
- article.tag_names = ['portland', 'oregon', 'ruby']
100
- article.tag_names -= ['oregon', 'ruby']
101
+ article.tag_names = %w[ portland oregon ruby ]
102
+ article.tag_names -= %w[ oregon ruby ]
101
103
  article.save!
102
104
 
103
- expect(article.tags.collect(&:name)).to eq(['portland'])
105
+ expect(article.tags.collect(&:name)).to eq(%w[ portland ])
104
106
  end
105
107
 
106
108
  it "matches tag names ignoring case" do
107
- article.tag_names = ['portland']
108
- article.tag_names += ['Portland']
109
+ article.tag_names = %w[ portland ]
110
+ article.tag_names += %w[ Portland ]
109
111
  article.save!
110
112
 
111
- expect(article.tags.collect(&:name)).to eq(['portland'])
113
+ expect(article.tags.collect(&:name)).to eq(%w[ portland ])
112
114
 
113
- article.tag_names << 'Portland'
115
+ article.tag_names << "Portland"
114
116
  article.save!
115
117
 
116
- expect(article.tags.collect(&:name)).to eq(['portland'])
118
+ expect(article.tags.collect(&:name)).to eq(%w[ portland ])
117
119
  end
118
120
 
119
121
  it "allows setting of tag names on unpersisted objects" do
120
- article = Article.new :tag_names => ['melbourne', 'pancakes']
122
+ article = Article.new :tag_names => %w[ melbourne pancakes ]
121
123
  article.save!
122
124
 
123
- expect(article.tag_names).to eq(['melbourne', 'pancakes'])
125
+ expect(article.tag_names).to eq(%w[ melbourne pancakes ])
124
126
  end
125
127
 
126
128
  it "allows overriding of tag_names=" do
@@ -1,8 +1,10 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
- describe 'Adding and removing tags' do
3
+ require "spec_helper"
4
+
5
+ describe "Adding and removing tags" do
4
6
  let(:article) { Article.create }
5
- let(:pancakes) { Gutentag::Tag.create :name => 'pancakes' }
7
+ let(:pancakes) { Gutentag::Tag.create :name => "pancakes" }
6
8
 
7
9
  it "stores new tags" do
8
10
  article.tags << pancakes
@@ -24,7 +26,7 @@ describe 'Adding and removing tags' do
24
26
  article.destroy
25
27
 
26
28
  expect(Gutentag::Tagging.where(
27
- :taggable_type => 'Article', :taggable_id => article.id
29
+ :taggable_type => "Article", :taggable_id => article.id
28
30
  ).count).to be_zero
29
31
  end
30
32
 
@@ -36,8 +38,8 @@ describe 'Adding and removing tags' do
36
38
  expect(Gutentag::Tagging.where(:tag_id => pancakes.id).count).to be_zero
37
39
  end
38
40
 
39
- it 'should have a mean tag cloud' do
40
- gorillas = Gutentag::Tag.create(:name => 'gorillas')
41
+ it "should have a mean tag cloud" do
42
+ gorillas = Gutentag::Tag.create(:name => "gorillas")
41
43
  another_article = Article.create
42
44
 
43
45
  article.tags << pancakes
@@ -1,37 +1,39 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  describe Gutentag::ActiveRecord do
4
- describe '.tagged_with' do
6
+ describe ".tagged_with" do
5
7
  let!(:melbourne_article) do
6
- article = Article.create :title => 'Overview'
7
- article.tag_names << 'melbourne'
8
+ article = Article.create :title => "Overview"
9
+ article.tag_names << "melbourne"
8
10
  article.save!
9
11
  article
10
12
  end
11
13
 
12
14
  let!(:oregon_article) do
13
15
  article = Article.create
14
- article.tag_names << 'oregon'
16
+ article.tag_names << "oregon"
15
17
  article.save!
16
18
  article
17
19
  end
18
20
 
19
21
  let!(:melbourne_oregon_article) do
20
22
  article = Article.create
21
- article.tag_names = %w(oregon melbourne)
23
+ article.tag_names = %w[ oregon melbourne ]
22
24
  article.save!
23
25
  article
24
26
  end
25
27
 
26
- context 'given a single tag name' do
27
- subject { Article.tagged_with(:names => 'melbourne') }
28
+ context "given a single tag name" do
29
+ subject { Article.tagged_with(:names => "melbourne") }
28
30
 
29
31
  it { expect(subject.count).to eq 2 }
30
32
  it { is_expected.to include melbourne_article, melbourne_oregon_article }
31
33
  it { is_expected.not_to include oregon_article }
32
34
  end
33
35
 
34
- context 'given a single tag name[symbol]' do
36
+ context "given a single tag name[symbol]" do
35
37
  subject { Article.tagged_with(:names => :melbourne) }
36
38
 
37
39
  it { expect(subject.count).to eq 2 }
@@ -39,7 +41,7 @@ describe Gutentag::ActiveRecord do
39
41
  it { is_expected.not_to include oregon_article }
40
42
  end
41
43
 
42
- context 'given a denormalized tag name' do
44
+ context "given a denormalized tag name" do
43
45
  subject { Article.tagged_with(:names => "MelbournE") }
44
46
 
45
47
  it { expect(subject.count).to eq 2 }
@@ -47,160 +49,115 @@ describe Gutentag::ActiveRecord do
47
49
  it { is_expected.not_to include oregon_article }
48
50
  end
49
51
 
50
- context 'given multiple tag names' do
51
- subject { Article.tagged_with(:names => ['melbourne', 'oregon']) }
52
+ context "given multiple tag names" do
53
+ subject { Article.tagged_with(:names => %w[ melbourne oregon ]) }
52
54
 
53
55
  it { expect(subject.count).to eq 3 }
54
- it { is_expected.to include melbourne_article, oregon_article, melbourne_oregon_article }
56
+ it do
57
+ is_expected.to include(
58
+ melbourne_article, oregon_article, melbourne_oregon_article
59
+ )
60
+ end
55
61
  end
56
62
 
57
- context 'given an array of tag names' do
58
- subject { Article.tagged_with(:names => %w(melbourne oregon)) }
63
+ context "given an array of tag names" do
64
+ subject { Article.tagged_with(:names => %w[ melbourne oregon ]) }
59
65
 
60
66
  it { expect(subject.count).to eq 3 }
61
- it { is_expected.to include melbourne_article, oregon_article, melbourne_oregon_article }
67
+ it do
68
+ is_expected.to include(
69
+ melbourne_article, oregon_article, melbourne_oregon_article
70
+ )
71
+ end
62
72
  end
63
73
 
64
- context 'given a single tag instance' do
65
- subject { Article.tagged_with(:tags => Gutentag::Tag.find_by_name!('melbourne')) }
74
+ context "given a single tag instance" do
75
+ subject do
76
+ Article.tagged_with(:tags => Gutentag::Tag.find_by_name!("melbourne"))
77
+ end
66
78
 
67
79
  it { expect(subject.count).to eq 2 }
68
80
  it { is_expected.to include melbourne_article, melbourne_oregon_article }
69
81
  it { is_expected.not_to include oregon_article }
70
- it { expect(subject.to_sql).not_to include 'gutentag_tags' }
82
+ it { expect(subject.to_sql).not_to include "gutentag_tags" }
71
83
  end
72
84
 
73
- context 'given a single tag id' do
74
- subject { Article.tagged_with(:ids => Gutentag::Tag.find_by_name!('melbourne').id) }
85
+ context "given a single tag id" do
86
+ subject do
87
+ Article.tagged_with(:ids => Gutentag::Tag.find_by_name!("melbourne").id)
88
+ end
75
89
 
76
90
  it { expect(subject.count).to eq 2 }
77
91
  it { is_expected.to include melbourne_article, melbourne_oregon_article }
78
92
  it { is_expected.not_to include oregon_article }
79
- it { expect(subject.to_sql).not_to include 'gutentag_tags' }
93
+ it { expect(subject.to_sql).not_to include "gutentag_tags" }
80
94
  end
81
95
 
82
- context 'given multiple tag objects' do
83
- subject { Article.tagged_with(:tags => Gutentag::Tag.where(name: %w(melbourne oregon))) }
96
+ context "given multiple tag objects" do
97
+ subject do
98
+ Article.tagged_with(
99
+ :tags => Gutentag::Tag.where(:name => %w[ melbourne oregon ])
100
+ )
101
+ end
84
102
 
85
103
  it { expect(subject.count).to eq 3 }
86
- it { is_expected.to include melbourne_article, oregon_article, melbourne_oregon_article }
87
- it { expect(subject.to_sql).not_to include 'gutentag_tags' }
104
+ it do
105
+ is_expected.to include(
106
+ melbourne_article, oregon_article, melbourne_oregon_article
107
+ )
108
+ end
109
+ it { expect(subject.to_sql).not_to include "gutentag_tags" }
88
110
  end
89
111
 
90
- context 'chaining where clause' do
91
- subject { Article.tagged_with(:names => %w(melbourne oregon)).where(title: 'Overview') }
112
+ context "chaining where clause" do
113
+ subject do
114
+ Article.tagged_with(:names => %w[ melbourne oregon ]).
115
+ where(:title => "Overview")
116
+ end
92
117
 
93
118
  it { expect(subject.count).to eq 1 }
94
119
  it { is_expected.to include melbourne_article }
95
120
  it { is_expected.not_to include oregon_article, melbourne_oregon_article }
96
121
  end
97
122
 
98
- context 'appended onto a relation' do
99
- subject { Article.where(title: 'Overview').tagged_with(:names => %w(melbourne oregon)) }
123
+ context "appended onto a relation" do
124
+ subject do
125
+ Article.where(:title => "Overview").
126
+ tagged_with(:names => %w[ melbourne oregon ])
127
+ end
100
128
 
101
129
  it { expect(subject.count).to eq 1 }
102
130
  it { is_expected.to include melbourne_article }
103
131
  it { is_expected.not_to include oregon_article, melbourne_oregon_article }
104
132
  end
105
133
 
106
- context 'matching against all tags' do
107
- subject { Article.tagged_with(:names => %w(melbourne oregon), :match => :all) }
134
+ context "matching against all tags" do
135
+ subject do
136
+ Article.tagged_with(:names => %w[ melbourne oregon ], :match => :all)
137
+ end
108
138
 
109
139
  it { expect(subject.count).to eq 1 }
110
140
  it { is_expected.to include melbourne_oregon_article }
111
141
  it { is_expected.not_to include oregon_article, melbourne_article }
112
142
  end
113
143
 
114
- context 'matching against all tag ids' do
115
- subject { Article.tagged_with(:ids => Gutentag::Tag.where(:name => %w(melbourne oregon)).pluck(:id), :match => :all) }
144
+ context "matching against all tag ids" do
145
+ let(:tag_ids) do
146
+ Gutentag::Tag.where(:name => %w[ melbourne oregon ]).pluck(:id)
147
+ end
148
+ subject { Article.tagged_with(:ids => tag_ids, :match => :all) }
116
149
 
117
150
  it { expect(subject.count).to eq 1 }
118
151
  it { is_expected.to include melbourne_oregon_article }
119
152
  it { is_expected.not_to include oregon_article, melbourne_article }
120
153
  end
121
154
 
122
- context 'matching against all one tag is the same as any' do
123
- subject { Article.tagged_with(:names => %w(melbourne), :match => :all) }
155
+ context "matching against all one tag is the same as any" do
156
+ subject { Article.tagged_with(:names => %w[ melbourne ], :match => :all) }
124
157
 
125
158
  it { expect(subject.count).to eq 2 }
126
159
  it { is_expected.to include melbourne_article, melbourne_oregon_article }
127
160
  it { is_expected.not_to include oregon_article }
128
161
  end
129
-
130
- context "deprecated" do
131
- before { expect(ActiveSupport::Deprecation).to receive(:warn) }
132
-
133
- context 'given a single tag name' do
134
- subject { Article.tagged_with('melbourne') }
135
-
136
- it { expect(subject.count).to eq 2 }
137
- it { is_expected.to include melbourne_article, melbourne_oregon_article }
138
- it { is_expected.not_to include oregon_article }
139
- end
140
-
141
- context 'given a single tag name[symbol]' do
142
- subject { Article.tagged_with(:melbourne) }
143
-
144
- it { expect(subject.count).to eq 2 }
145
- it { is_expected.to include melbourne_article, melbourne_oregon_article }
146
- it { is_expected.not_to include oregon_article }
147
- end
148
-
149
- context 'given a denormalized tag name' do
150
- subject { Article.tagged_with("MelbournE") }
151
-
152
- it { expect(subject.count).to eq 2 }
153
- it { is_expected.to include melbourne_article, melbourne_oregon_article }
154
- it { is_expected.not_to include oregon_article }
155
- end
156
-
157
- context 'given multiple tag names' do
158
- subject { Article.tagged_with('melbourne', 'oregon') }
159
-
160
- it { expect(subject.count).to eq 3 }
161
- it { is_expected.to include melbourne_article, oregon_article, melbourne_oregon_article }
162
- end
163
-
164
- context 'given an array of tag names' do
165
- subject { Article.tagged_with(%w(melbourne oregon)) }
166
-
167
- it { expect(subject.count).to eq 3 }
168
- it { is_expected.to include melbourne_article, oregon_article, melbourne_oregon_article }
169
- end
170
-
171
- context 'given a single tag instance' do
172
- subject { Article.tagged_with(Gutentag::Tag.find_by_name!('melbourne')) }
173
-
174
- it { expect(subject.count).to eq 2 }
175
- it { is_expected.to include melbourne_article, melbourne_oregon_article }
176
- it { is_expected.not_to include oregon_article }
177
- it { expect(subject.to_sql).not_to include 'gutentag_tags' }
178
- end
179
-
180
- context 'given a single tag id' do
181
- subject { Article.tagged_with(Gutentag::Tag.find_by_name!('melbourne').id) }
182
-
183
- it { expect(subject.count).to eq 2 }
184
- it { is_expected.to include melbourne_article, melbourne_oregon_article }
185
- it { is_expected.not_to include oregon_article }
186
- it { expect(subject.to_sql).not_to include 'gutentag_tags' }
187
- end
188
-
189
- context 'given multiple tag objects' do
190
- subject { Article.tagged_with(Gutentag::Tag.where(name: %w(melbourne oregon))) }
191
-
192
- it { expect(subject.count).to eq 3 }
193
- it { is_expected.to include melbourne_article, oregon_article, melbourne_oregon_article }
194
- it { expect(subject.to_sql).not_to include 'gutentag_tags' }
195
- end
196
-
197
- context 'chaining where clause' do
198
- subject { Article.tagged_with(%w(melbourne oregon)).where(title: 'Overview') }
199
-
200
- it { expect(subject.count).to eq 1 }
201
- it { is_expected.to include melbourne_article }
202
- it { is_expected.not_to include oregon_article, melbourne_oregon_article }
203
- end
204
- end
205
162
  end
206
163
  end