gutentag 0.9.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +21 -0
- data/.travis.yml +6 -5
- data/Appraisals +20 -26
- data/Gemfile +13 -8
- data/README.md +5 -1
- data/Rakefile +9 -5
- data/app/models/gutentag/tag.rb +7 -4
- data/app/models/gutentag/tagging.rb +5 -3
- data/bin/literals +9 -0
- data/db/migrate/1_gutentag_tables.rb +5 -3
- data/db/migrate/2_gutentag_cache_counter.rb +2 -0
- data/db/migrate/3_no_null_counters.rb +8 -4
- data/gutentag.gemspec +18 -18
- data/lib/gutentag.rb +13 -13
- data/lib/gutentag/active_record.rb +11 -6
- data/lib/gutentag/active_record/class_methods.rb +4 -16
- data/lib/gutentag/active_record/instance_methods.rb +3 -1
- data/lib/gutentag/change_state.rb +32 -0
- data/lib/gutentag/dirty.rb +4 -1
- data/lib/gutentag/engine.rb +2 -4
- data/lib/gutentag/persistence.rb +13 -16
- data/lib/gutentag/tag_validations.rb +4 -1
- data/lib/gutentag/tagged_with.rb +5 -3
- data/lib/gutentag/tagged_with/id_query.rb +2 -0
- data/lib/gutentag/tagged_with/name_query.rb +2 -0
- data/lib/gutentag/tagged_with/query.rb +2 -0
- data/spec/acceptance/tag_names_spec.rb +40 -38
- data/spec/acceptance/tags_spec.rb +8 -6
- data/spec/gutentag/active_record_spec.rb +69 -112
- data/spec/gutentag_spec.rb +5 -3
- data/spec/internal/app/models/article.rb +2 -0
- data/spec/internal/db/schema.rb +2 -0
- data/spec/models/gutentag/tag_spec.rb +24 -22
- data/spec/models/gutentag/tagging_spec.rb +5 -3
- data/spec/spec_helper.rb +4 -2
- metadata +11 -43
- data/gemfiles/rails_3_2.gemfile +0 -11
- data/gemfiles/rails_4_0.gemfile +0 -11
- data/gemfiles/rails_4_1.gemfile +0 -11
- data/gemfiles/rails_4_2.gemfile +0 -10
- data/gemfiles/rails_5_0.gemfile +0 -8
- data/gemfiles/rails_5_1.gemfile +0 -8
- data/lib/gutentag/has_many_tags.rb +0 -10
data/lib/gutentag/dirty.rb
CHANGED
@@ -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
|
9
|
+
@instance = instance
|
10
|
+
@tag_names = tag_names
|
8
11
|
end
|
9
12
|
|
10
13
|
def call
|
data/lib/gutentag/engine.rb
CHANGED
data/lib/gutentag/persistence.rb
CHANGED
@@ -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
|
8
|
+
attr_writer :tagger
|
4
9
|
|
5
|
-
def initialize(
|
6
|
-
@
|
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 :
|
23
|
+
attr_reader :change_state
|
24
|
+
|
25
|
+
def_delegators :change_state, :taggable, :added, :removed
|
21
26
|
|
22
27
|
def add_new
|
23
|
-
|
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
|
-
|
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,
|
13
|
+
klass.validates :name,
|
14
|
+
:presence => true,
|
12
15
|
:uniqueness => {:case_sensitive => false}
|
13
16
|
end
|
14
17
|
|
data/lib/gutentag/tagged_with.rb
CHANGED
@@ -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
|
37
|
-
require
|
38
|
-
require
|
38
|
+
require "gutentag/tagged_with/query"
|
39
|
+
require "gutentag/tagged_with/id_query"
|
40
|
+
require "gutentag/tagged_with/name_query"
|
@@ -1,38 +1,40 @@
|
|
1
|
-
|
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 =>
|
9
|
+
melbourne = Gutentag::Tag.create :name => "melbourne"
|
8
10
|
|
9
11
|
article.tags << melbourne
|
10
12
|
|
11
|
-
expect(article.tag_names).to eq([
|
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 <<
|
17
|
+
article.tag_names << "melbourne"
|
16
18
|
article.save!
|
17
19
|
|
18
|
-
expect(article.tags.collect(&:name)).to eq([
|
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 <<
|
24
|
+
article.tag_names << "melbourne"
|
23
25
|
article.save!
|
24
26
|
|
25
|
-
article.tag_names = [
|
27
|
+
article.tag_names = ["sydney"]
|
26
28
|
|
27
29
|
expect(article.changed_attributes.stringify_keys).
|
28
|
-
to eq(
|
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 <<
|
34
|
+
article.tag_names << "melbourne"
|
33
35
|
article.save!
|
34
36
|
|
35
|
-
article.tag_names = [
|
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 =>
|
44
|
-
expect(tag.name).to eq(
|
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 <<
|
51
|
-
article.tag_names <<
|
52
|
+
article.tag_names << "melbourne"
|
53
|
+
article.tag_names << "melbourne"
|
52
54
|
article.save!
|
53
55
|
|
54
|
-
expect(article.tags.collect(&:name)).to eq([
|
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 = [
|
60
|
+
article.tag_names = %w[ portland oregon ]
|
59
61
|
article.save!
|
60
62
|
|
61
|
-
expect(article.tags.collect(&:name)).to eq([
|
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 =>
|
68
|
+
existing.tags << Gutentag::Tag.create(:name => "portland")
|
67
69
|
|
68
|
-
article.tag_names = [
|
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 = [
|
76
|
-
article.tag_names += [
|
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([
|
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 = [
|
84
|
-
article.tag_names += [
|
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([
|
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 = [
|
92
|
-
article.tag_names.delete
|
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([
|
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 = [
|
100
|
-
article.tag_names -= [
|
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([
|
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 = [
|
108
|
-
article.tag_names += [
|
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([
|
113
|
+
expect(article.tags.collect(&:name)).to eq(%w[ portland ])
|
112
114
|
|
113
|
-
article.tag_names <<
|
115
|
+
article.tag_names << "Portland"
|
114
116
|
article.save!
|
115
117
|
|
116
|
-
expect(article.tags.collect(&:name)).to eq([
|
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 => [
|
122
|
+
article = Article.new :tag_names => %w[ melbourne pancakes ]
|
121
123
|
article.save!
|
122
124
|
|
123
|
-
expect(article.tag_names).to eq([
|
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
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
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 =>
|
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 =>
|
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
|
40
|
-
gorillas = Gutentag::Tag.create(:name =>
|
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
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
2
4
|
|
3
5
|
describe Gutentag::ActiveRecord do
|
4
|
-
describe
|
6
|
+
describe ".tagged_with" do
|
5
7
|
let!(:melbourne_article) do
|
6
|
-
article = Article.create :title =>
|
7
|
-
article.tag_names <<
|
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 <<
|
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
|
23
|
+
article.tag_names = %w[ oregon melbourne ]
|
22
24
|
article.save!
|
23
25
|
article
|
24
26
|
end
|
25
27
|
|
26
|
-
context
|
27
|
-
subject { Article.tagged_with(:names =>
|
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
|
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
|
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
|
51
|
-
subject { Article.tagged_with(:names => [
|
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
|
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
|
58
|
-
subject { Article.tagged_with(:names => %w
|
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
|
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
|
65
|
-
subject
|
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
|
82
|
+
it { expect(subject.to_sql).not_to include "gutentag_tags" }
|
71
83
|
end
|
72
84
|
|
73
|
-
context
|
74
|
-
subject
|
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
|
93
|
+
it { expect(subject.to_sql).not_to include "gutentag_tags" }
|
80
94
|
end
|
81
95
|
|
82
|
-
context
|
83
|
-
subject
|
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
|
87
|
-
|
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
|
91
|
-
subject
|
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
|
99
|
-
subject
|
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
|
107
|
-
subject
|
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
|
115
|
-
|
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
|
123
|
-
subject { Article.tagged_with(:names => %w
|
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
|