make_taggable 0.6.3
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.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +47 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.standard.yml +18 -0
- data/.standard_todo.yml +5 -0
- data/.travis.yml +36 -0
- data/Appraisals +11 -0
- data/CHANGELOG.md +0 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +57 -0
- data/Gemfile +16 -0
- data/LICENSE.md +20 -0
- data/LICENSE.txt +21 -0
- data/README.md +478 -0
- data/Rakefile +7 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/db/migrate/1_create_make_taggable_tags.rb +10 -0
- data/db/migrate/2_create_make_taggable_taggings.rb +12 -0
- data/db/migrate/3_add_index_to_tags.rb +5 -0
- data/db/migrate/4_add_index_to_taggings.rb +12 -0
- data/gemfiles/rails_5.gemfile +9 -0
- data/gemfiles/rails_6.gemfile +9 -0
- data/gemfiles/rails_master.gemfile +9 -0
- data/lib/make_taggable.rb +134 -0
- data/lib/make_taggable/default_parser.rb +75 -0
- data/lib/make_taggable/engine.rb +4 -0
- data/lib/make_taggable/generic_parser.rb +19 -0
- data/lib/make_taggable/tag.rb +131 -0
- data/lib/make_taggable/tag_list.rb +102 -0
- data/lib/make_taggable/taggable.rb +100 -0
- data/lib/make_taggable/taggable/cache.rb +90 -0
- data/lib/make_taggable/taggable/collection.rb +183 -0
- data/lib/make_taggable/taggable/core.rb +323 -0
- data/lib/make_taggable/taggable/ownership.rb +137 -0
- data/lib/make_taggable/taggable/related.rb +71 -0
- data/lib/make_taggable/taggable/tag_list_type.rb +4 -0
- data/lib/make_taggable/taggable/tagged_with_query.rb +16 -0
- data/lib/make_taggable/taggable/tagged_with_query/all_tags_query.rb +111 -0
- data/lib/make_taggable/taggable/tagged_with_query/any_tags_query.rb +68 -0
- data/lib/make_taggable/taggable/tagged_with_query/exclude_tags_query.rb +81 -0
- data/lib/make_taggable/taggable/tagged_with_query/query_base.rb +61 -0
- data/lib/make_taggable/tagger.rb +89 -0
- data/lib/make_taggable/tagging.rb +32 -0
- data/lib/make_taggable/tags_helper.rb +15 -0
- data/lib/make_taggable/utils.rb +34 -0
- data/lib/make_taggable/version.rb +4 -0
- data/lib/tasks/tags_collate_utf8.rake +17 -0
- data/make_taggable.gemspec +26 -0
- data/spec/dummy/README.md +24 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +2 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/jobs/application_job.rb +7 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/altered_inheriting_taggable_model.rb +5 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/models/cached_model.rb +3 -0
- data/spec/dummy/app/models/cached_model_with_array.rb +11 -0
- data/spec/dummy/app/models/columns_override_model.rb +5 -0
- data/spec/dummy/app/models/company.rb +15 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/inheriting_taggable_model.rb +4 -0
- data/spec/dummy/app/models/market.rb +2 -0
- data/spec/dummy/app/models/non_standard_id_taggable_model.rb +8 -0
- data/spec/dummy/app/models/ordered_taggable_model.rb +4 -0
- data/spec/dummy/app/models/other_cached_model.rb +3 -0
- data/spec/dummy/app/models/other_taggable_model.rb +4 -0
- data/spec/dummy/app/models/student.rb +4 -0
- data/spec/dummy/app/models/taggable_model.rb +14 -0
- data/spec/dummy/app/models/untaggable_model.rb +3 -0
- data/spec/dummy/app/models/user.rb +3 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +33 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +19 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/credentials.yml.enc +1 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +52 -0
- data/spec/dummy/config/environments/production.rb +105 -0
- data/spec/dummy/config/environments/test.rb +49 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cors.rb +16 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/master.key +1 -0
- data/spec/dummy/config/puma.rb +38 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/db/migrate/20201119220853_create_taggable_models.rb +8 -0
- data/spec/dummy/db/migrate/20201119221037_create_columns_override_models.rb +9 -0
- data/spec/dummy/db/migrate/20201119221121_create_non_standard_id_taggable_models.rb +8 -0
- data/spec/dummy/db/migrate/20201119221228_create_untaggable_models.rb +8 -0
- data/spec/dummy/db/migrate/20201119221247_create_cached_models.rb +9 -0
- data/spec/dummy/db/migrate/20201119221314_create_other_cached_models.rb +11 -0
- data/spec/dummy/db/migrate/20201119221343_create_companies.rb +7 -0
- data/spec/dummy/db/migrate/20201119221416_create_users.rb +7 -0
- data/spec/dummy/db/migrate/20201119221434_create_other_taggable_models.rb +8 -0
- data/spec/dummy/db/migrate/20201119221507_create_ordered_taggable_models.rb +8 -0
- data/spec/dummy/db/migrate/20201119221530_create_cache_methods_injected_models.rb +7 -0
- data/spec/dummy/db/migrate/20201119221629_create_other_cached_with_array_models.rb +11 -0
- data/spec/dummy/db/migrate/20201119221746_create_taggable_model_with_jsons.rb +9 -0
- data/spec/dummy/db/migrate/20201119222429_create_make_taggable_tags.make_taggable_engine.rb +11 -0
- data/spec/dummy/db/migrate/20201119222430_create_make_taggable_taggings.make_taggable_engine.rb +13 -0
- data/spec/dummy/db/migrate/20201119222431_add_index_to_tags.make_taggable_engine.rb +6 -0
- data/spec/dummy/db/migrate/20201119222432_add_index_to_taggings.make_taggable_engine.rb +13 -0
- data/spec/dummy/db/schema.rb +117 -0
- data/spec/dummy/db/seeds.rb +7 -0
- data/spec/dummy/lib/tasks/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/robots.txt +1 -0
- data/spec/dummy/storage/.keep +0 -0
- data/spec/dummy/test/channels/application_cable/connection_test.rb +11 -0
- data/spec/dummy/test/controllers/.keep +0 -0
- data/spec/dummy/test/fixtures/.keep +0 -0
- data/spec/dummy/test/fixtures/files/.keep +0 -0
- data/spec/dummy/test/integration/.keep +0 -0
- data/spec/dummy/test/mailers/.keep +0 -0
- data/spec/dummy/test/models/.keep +0 -0
- data/spec/dummy/test/test_helper.rb +13 -0
- data/spec/dummy/vendor/.keep +0 -0
- data/spec/make_taggable/acts_as_tagger_spec.rb +112 -0
- data/spec/make_taggable/caching_spec.rb +123 -0
- data/spec/make_taggable/default_parser_spec.rb +45 -0
- data/spec/make_taggable/dirty_spec.rb +140 -0
- data/spec/make_taggable/generic_parser_spec.rb +13 -0
- data/spec/make_taggable/make_taggable_spec.rb +260 -0
- data/spec/make_taggable/related_spec.rb +93 -0
- data/spec/make_taggable/single_table_inheritance_spec.rb +220 -0
- data/spec/make_taggable/tag_list_spec.rb +169 -0
- data/spec/make_taggable/tag_spec.rb +297 -0
- data/spec/make_taggable/taggable_spec.rb +804 -0
- data/spec/make_taggable/tagger_spec.rb +149 -0
- data/spec/make_taggable/tagging_spec.rb +115 -0
- data/spec/make_taggable/tags_helper_spec.rb +43 -0
- data/spec/make_taggable/utils_spec.rb +22 -0
- data/spec/make_taggable_spec.rb +5 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/support/array.rb +9 -0
- data/spec/support/helpers.rb +31 -0
- metadata +391 -0
@@ -0,0 +1,93 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Acts As Taggable On" do
|
4
|
+
describe "Related Objects" do
|
5
|
+
# TODO, shared example
|
6
|
+
it "should find related objects based on tag names on context" do
|
7
|
+
taggable1 = TaggableModel.create!(name: "Taggable 1", tag_list: "one, two")
|
8
|
+
taggable2 = TaggableModel.create!(name: "Taggable 2", tag_list: "three, four")
|
9
|
+
taggable3 = TaggableModel.create!(name: "Taggable 3", tag_list: "one, four")
|
10
|
+
|
11
|
+
expect(taggable1.find_related_tags).to include(taggable3)
|
12
|
+
expect(taggable1.find_related_tags).to_not include(taggable2)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "finds related tags for ordered taggable on" do
|
16
|
+
taggable1 = OrderedTaggableModel.create!(name: "Taggable 1", colour_list: "one, two")
|
17
|
+
taggable2 = OrderedTaggableModel.create!(name: "Taggable 2", colour_list: "three, four")
|
18
|
+
taggable3 = OrderedTaggableModel.create!(name: "Taggable 3", colour_list: "one, four")
|
19
|
+
|
20
|
+
expect(taggable1.find_related_colours).to include(taggable3)
|
21
|
+
expect(taggable1.find_related_colours).to_not include(taggable2)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should find related objects based on tag names on context - non standard id" do
|
25
|
+
taggable1 = NonStandardIdTaggableModel.create!(name: "Taggable 1", tag_list: "one, two")
|
26
|
+
taggable2 = NonStandardIdTaggableModel.create!(name: "Taggable 2", tag_list: "three, four")
|
27
|
+
taggable3 = NonStandardIdTaggableModel.create!(name: "Taggable 3", tag_list: "one, four")
|
28
|
+
|
29
|
+
expect(taggable1.find_related_tags).to include(taggable3)
|
30
|
+
expect(taggable1.find_related_tags).to_not include(taggable2)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should find other related objects based on tag names on context" do
|
34
|
+
taggable1 = TaggableModel.create!(name: "Taggable 1", tag_list: "one, two")
|
35
|
+
taggable2 = OtherTaggableModel.create!(name: "Taggable 2", tag_list: "three, four")
|
36
|
+
taggable3 = OtherTaggableModel.create!(name: "Taggable 3", tag_list: "one, four")
|
37
|
+
|
38
|
+
expect(taggable1.find_related_tags_for(OtherTaggableModel)).to include(taggable3)
|
39
|
+
expect(taggable1.find_related_tags_for(OtherTaggableModel)).to_not include(taggable2)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should find other related objects based on tags only from particular context" do
|
43
|
+
taggable1 = TaggableModel.create!(name: "Taggable 1", tag_list: "one, two")
|
44
|
+
taggable2 = TaggableModel.create!(name: "Taggable 2", tag_list: "three, four", skill_list: "one, two")
|
45
|
+
taggable3 = TaggableModel.create!(name: "Taggable 3", tag_list: "one, four")
|
46
|
+
|
47
|
+
expect(taggable1.find_related_tags).to include(taggable3)
|
48
|
+
expect(taggable1.find_related_tags).to_not include(taggable2)
|
49
|
+
end
|
50
|
+
|
51
|
+
shared_examples "a collection" do
|
52
|
+
it do
|
53
|
+
taggable1 = described_class.create!(name: "Taggable 1", tag_list: "one")
|
54
|
+
taggable2 = described_class.create!(name: "Taggable 2", tag_list: "one, two")
|
55
|
+
|
56
|
+
expect(taggable1.find_related_tags).to include(taggable2)
|
57
|
+
expect(taggable1.find_related_tags).to_not include(taggable1)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# it 'should not include the object itself in the list of related objects' do
|
62
|
+
describe TaggableModel do
|
63
|
+
it_behaves_like "a collection"
|
64
|
+
end
|
65
|
+
|
66
|
+
# it 'should not include the object itself in the list of related objects - non standard id' do
|
67
|
+
describe NonStandardIdTaggableModel do
|
68
|
+
it_behaves_like "a collection"
|
69
|
+
end
|
70
|
+
|
71
|
+
context "Ignored Tags" do
|
72
|
+
let(:taggable1) { TaggableModel.create!(name: "Taggable 1", tag_list: "one, two, four") }
|
73
|
+
let(:taggable2) { TaggableModel.create!(name: "Taggable 2", tag_list: "two, three") }
|
74
|
+
let(:taggable3) { TaggableModel.create!(name: "Taggable 3", tag_list: "one, three") }
|
75
|
+
|
76
|
+
it "should not include ignored tags in related search" do
|
77
|
+
expect(taggable1.find_related_tags(ignore: "two")).to_not include(taggable2)
|
78
|
+
expect(taggable1.find_related_tags(ignore: "two")).to include(taggable3)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should accept array of ignored tags" do
|
82
|
+
taggable4 = TaggableModel.create!(name: "Taggable 4", tag_list: "four")
|
83
|
+
|
84
|
+
expect(taggable1.find_related_tags(ignore: ["two", "four"])).to_not include(taggable2)
|
85
|
+
expect(taggable1.find_related_tags(ignore: ["two", "four"])).to_not include(taggable4)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should accept symbols as ignored tags" do
|
89
|
+
expect(taggable1.find_related_tags(ignore: :two)).to_not include(taggable2)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "Single Table Inheritance" do
|
4
|
+
let(:taggable) { TaggableModel.new(name: "taggable model") }
|
5
|
+
|
6
|
+
let(:inheriting_model) { InheritingTaggableModel.new(name: "Inheriting Taggable Model") }
|
7
|
+
let(:altered_inheriting) { AlteredInheritingTaggableModel.new(name: "Altered Inheriting Model") }
|
8
|
+
|
9
|
+
1.upto(4) do |n|
|
10
|
+
let(:"inheriting_#{n}") { InheritingTaggableModel.new(name: "Inheriting Model #{n}") }
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:student) { Student.create! }
|
14
|
+
|
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)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should pass on to altered STI models" do
|
22
|
+
expect(altered_inheriting).to respond_to(:part_list)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "matching contexts" do
|
27
|
+
before do
|
28
|
+
inheriting_1.offering_list = "one, two"
|
29
|
+
inheriting_1.need_list = "one, two"
|
30
|
+
inheriting_1.save!
|
31
|
+
|
32
|
+
inheriting_2.need_list = "one, two"
|
33
|
+
inheriting_2.save!
|
34
|
+
|
35
|
+
inheriting_3.offering_list = "one, two"
|
36
|
+
inheriting_3.save!
|
37
|
+
|
38
|
+
inheriting_4.tag_list = "one, two, three, four"
|
39
|
+
inheriting_4.save!
|
40
|
+
|
41
|
+
taggable.need_list = "one, two"
|
42
|
+
taggable.save!
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should find objects with tags of matching contexts" do
|
46
|
+
expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to include(inheriting_2)
|
47
|
+
expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to_not include(inheriting_3)
|
48
|
+
expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to_not include(inheriting_4)
|
49
|
+
expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to_not include(taggable)
|
50
|
+
|
51
|
+
expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to include(inheriting_2)
|
52
|
+
expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to_not include(inheriting_3)
|
53
|
+
expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to_not include(inheriting_4)
|
54
|
+
expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to include(taggable)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should not include the object itself in the list of related objects with tags of matching contexts" do
|
58
|
+
expect(inheriting_1.find_matching_contexts(:offerings, :needs)).to_not include(inheriting_1)
|
59
|
+
expect(inheriting_1.find_matching_contexts_for(InheritingTaggableModel, :offerings, :needs)).to_not include(inheriting_1)
|
60
|
+
expect(inheriting_1.find_matching_contexts_for(TaggableModel, :offerings, :needs)).to_not include(inheriting_1)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "find related tags" do
|
65
|
+
before do
|
66
|
+
inheriting_1.tag_list = "one, two"
|
67
|
+
inheriting_1.save
|
68
|
+
|
69
|
+
inheriting_2.tag_list = "three, four"
|
70
|
+
inheriting_2.save
|
71
|
+
|
72
|
+
inheriting_3.tag_list = "one, four"
|
73
|
+
inheriting_3.save
|
74
|
+
|
75
|
+
taggable.tag_list = "one, two, three, four"
|
76
|
+
taggable.save
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should find related objects based on tag names on context" do
|
80
|
+
expect(inheriting_1.find_related_tags).to include(inheriting_3)
|
81
|
+
expect(inheriting_1.find_related_tags).to_not include(inheriting_2)
|
82
|
+
expect(inheriting_1.find_related_tags).to_not include(taggable)
|
83
|
+
|
84
|
+
expect(inheriting_1.find_related_tags_for(TaggableModel)).to include(inheriting_3)
|
85
|
+
expect(inheriting_1.find_related_tags_for(TaggableModel)).to_not include(inheriting_2)
|
86
|
+
expect(inheriting_1.find_related_tags_for(TaggableModel)).to include(taggable)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should not include the object itself in the list of related objects" do
|
90
|
+
expect(inheriting_1.find_related_tags).to_not include(inheriting_1)
|
91
|
+
expect(inheriting_1.find_related_tags_for(InheritingTaggableModel)).to_not include(inheriting_1)
|
92
|
+
expect(inheriting_1.find_related_tags_for(TaggableModel)).to_not include(inheriting_1)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "tag list" do
|
97
|
+
before do
|
98
|
+
@inherited_same = InheritingTaggableModel.new(name: "inherited same")
|
99
|
+
@inherited_different = AlteredInheritingTaggableModel.new(name: "inherited different")
|
100
|
+
end
|
101
|
+
|
102
|
+
# TODO, shared example
|
103
|
+
it "should be able to save tags for inherited models" do
|
104
|
+
inheriting_model.tag_list = "bob, kelso"
|
105
|
+
inheriting_model.save
|
106
|
+
expect(InheritingTaggableModel.tagged_with("bob").first).to eq(inheriting_model)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should find STI tagged models on the superclass" do
|
110
|
+
inheriting_model.tag_list = "bob, kelso"
|
111
|
+
inheriting_model.save
|
112
|
+
expect(TaggableModel.tagged_with("bob").first).to eq(inheriting_model)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should be able to add on contexts only to some subclasses" do
|
116
|
+
altered_inheriting.part_list = "fork, spoon"
|
117
|
+
altered_inheriting.save
|
118
|
+
expect(InheritingTaggableModel.tagged_with("fork", on: :parts)).to be_empty
|
119
|
+
expect(AlteredInheritingTaggableModel.tagged_with("fork", on: :parts).first).to eq(altered_inheriting)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should have different tag_counts_on for inherited models" do
|
123
|
+
inheriting_model.tag_list = "bob, kelso"
|
124
|
+
inheriting_model.save!
|
125
|
+
altered_inheriting.tag_list = "fork, spoon"
|
126
|
+
altered_inheriting.save!
|
127
|
+
|
128
|
+
expect(InheritingTaggableModel.tag_counts_on(:tags, order: "#{MakeTaggable.tags_table}.id").map(&:name)).to eq(%w[bob kelso])
|
129
|
+
expect(AlteredInheritingTaggableModel.tag_counts_on(:tags, order: "#{MakeTaggable.tags_table}.id").map(&:name)).to eq(%w[fork spoon])
|
130
|
+
expect(TaggableModel.tag_counts_on(:tags, order: "#{MakeTaggable.tags_table}.id").map(&:name)).to eq(%w[bob kelso fork spoon])
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should have different tags_on for inherited models" do
|
134
|
+
inheriting_model.tag_list = "bob, kelso"
|
135
|
+
inheriting_model.save!
|
136
|
+
altered_inheriting.tag_list = "fork, spoon"
|
137
|
+
altered_inheriting.save!
|
138
|
+
|
139
|
+
expect(InheritingTaggableModel.tags_on(:tags, order: "#{MakeTaggable.tags_table}.id").map(&:name)).to eq(%w[bob kelso])
|
140
|
+
expect(AlteredInheritingTaggableModel.tags_on(:tags, order: "#{MakeTaggable.tags_table}.id").map(&:name)).to eq(%w[fork spoon])
|
141
|
+
expect(TaggableModel.tags_on(:tags, order: "#{MakeTaggable.tags_table}.id").map(&:name)).to eq(%w[bob kelso fork spoon])
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should store same tag without validation conflict" do
|
145
|
+
taggable.tag_list = "one"
|
146
|
+
taggable.save!
|
147
|
+
|
148
|
+
inheriting_model.tag_list = "one"
|
149
|
+
inheriting_model.save!
|
150
|
+
|
151
|
+
inheriting_model.update! name: "foo"
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should only join with taggable table to check type for inherited models" do
|
155
|
+
expect(TaggableModel.tag_counts_on(:tags).to_sql).to_not match(/INNER JOIN taggable_models ON/)
|
156
|
+
expect(InheritingTaggableModel.tag_counts_on(:tags).to_sql).to match(/INNER JOIN taggable_models ON/)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe "ownership" do
|
161
|
+
it "should have taggings" do
|
162
|
+
student.tag(taggable, with: "ruby,scheme", on: :tags)
|
163
|
+
expect(student.owned_taggings.count).to eq(2)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should have tags" do
|
167
|
+
student.tag(taggable, with: "ruby,scheme", on: :tags)
|
168
|
+
expect(student.owned_tags.count).to eq(2)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should return tags for the inheriting tagger" do
|
172
|
+
student.tag(taggable, with: "ruby, scheme", on: :tags)
|
173
|
+
expect(taggable.tags_from(student)).to eq(%w[ruby scheme])
|
174
|
+
end
|
175
|
+
|
176
|
+
it "returns all owner tags on the taggable" do
|
177
|
+
student.tag(taggable, with: "ruby, scheme", on: :tags)
|
178
|
+
student.tag(taggable, with: "skill_one", on: :skills)
|
179
|
+
student.tag(taggable, with: "english, spanish", on: :language)
|
180
|
+
expect(taggable.owner_tags(student).count).to eq(5)
|
181
|
+
expect(taggable.owner_tags(student).sort == %w[english ruby scheme skill_one spanish])
|
182
|
+
end
|
183
|
+
|
184
|
+
it "returns owner tags on the tagger" do
|
185
|
+
student.tag(taggable, with: "ruby, scheme", on: :tags)
|
186
|
+
expect(taggable.owner_tags_on(student, :tags).count).to eq(2)
|
187
|
+
end
|
188
|
+
|
189
|
+
it "returns owner tags on the taggable for an array of contexts" do
|
190
|
+
student.tag(taggable, with: "ruby, scheme", on: :tags)
|
191
|
+
student.tag(taggable, with: "skill_one, skill_two", on: :skills)
|
192
|
+
expect(taggable.owner_tags_on(student, [:tags, :skills]).count).to eq(4)
|
193
|
+
expect(taggable.owner_tags_on(student, [:tags, :skills]).sort == %w[ruby scheme skill_one skill_two])
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should scope objects returned by tagged_with by owners" do
|
197
|
+
student.tag(taggable, with: "ruby, scheme", on: :tags)
|
198
|
+
expect(TaggableModel.tagged_with(%w[ruby scheme], owned_by: student).count).to eq(1)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe "a subclass of Tag" do
|
203
|
+
let(:company) { Company.new(name: "Dewey, Cheatham & Howe") }
|
204
|
+
let(:user) { User.create! }
|
205
|
+
|
206
|
+
subject { Market.create! name: "finance" }
|
207
|
+
|
208
|
+
it "sets STI type through string list" do
|
209
|
+
company.market_list = "law, accounting"
|
210
|
+
company.save!
|
211
|
+
expect(Market.count).to eq(2)
|
212
|
+
end
|
213
|
+
|
214
|
+
it "does not interfere with a normal Tag context on the same model" do
|
215
|
+
company.location_list = "cambridge"
|
216
|
+
company.save!
|
217
|
+
expect(MakeTaggable::Tag.where(name: "cambridge")).to_not be_empty
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe MakeTaggable::TagList do
|
4
|
+
let(:tag_list) { MakeTaggable::TagList.new("awesome", "radical") }
|
5
|
+
let(:another_tag_list) { MakeTaggable::TagList.new("awesome", "crazy", "alien") }
|
6
|
+
|
7
|
+
it { should be_kind_of Array }
|
8
|
+
|
9
|
+
describe "#add" do
|
10
|
+
it "should be able to be add a new tag word" do
|
11
|
+
tag_list.add("cool")
|
12
|
+
expect(tag_list.include?("cool")).to be_truthy
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be able to add delimited lists of words" do
|
16
|
+
tag_list.add("cool, wicked", parse: true)
|
17
|
+
expect(tag_list).to include("cool", "wicked")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should be able to add delimited list of words with quoted delimiters" do
|
21
|
+
tag_list.add("'cool, wicked', \"really cool, really wicked\"", parse: true)
|
22
|
+
expect(tag_list).to include("cool, wicked", "really cool, really wicked")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should be able to handle other uses of quotation marks correctly" do
|
26
|
+
tag_list.add("john's cool car, mary's wicked toy", parse: true)
|
27
|
+
expect(tag_list).to include("john's cool car", "mary's wicked toy")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should be able to add an array of words" do
|
31
|
+
tag_list.add(%w[cool wicked], parse: true)
|
32
|
+
expect(tag_list).to include("cool", "wicked")
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should quote escape tags with commas in them" do
|
36
|
+
tag_list.add("cool", "rad,bodacious")
|
37
|
+
expect(tag_list.to_s).to eq("awesome, radical, cool, \"rad,bodacious\"")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#remove" do
|
42
|
+
it "should be able to remove words" do
|
43
|
+
tag_list.remove("awesome")
|
44
|
+
expect(tag_list).to_not include("awesome")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should be able to remove delimited lists of words" do
|
48
|
+
tag_list.remove("awesome, radical", parse: true)
|
49
|
+
expect(tag_list).to be_empty
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should be able to remove an array of words" do
|
53
|
+
tag_list.remove(%w[awesome radical], parse: true)
|
54
|
+
expect(tag_list).to be_empty
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#+" do
|
59
|
+
it "should not have duplicate tags" do
|
60
|
+
new_tag_list = tag_list + another_tag_list
|
61
|
+
expect(tag_list).to eq(%w[awesome radical])
|
62
|
+
expect(another_tag_list).to eq(%w[awesome crazy alien])
|
63
|
+
expect(new_tag_list).to eq(%w[awesome radical crazy alien])
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should have class : MakeTaggable::TagList" do
|
67
|
+
new_tag_list = tag_list + another_tag_list
|
68
|
+
expect(new_tag_list.class).to eq(MakeTaggable::TagList)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "#concat" do
|
73
|
+
it "should not have duplicate tags" do
|
74
|
+
expect(tag_list.concat(another_tag_list)).to eq(%w[awesome radical crazy alien])
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should have class : MakeTaggable::TagList" do
|
78
|
+
new_tag_list = tag_list.concat(another_tag_list)
|
79
|
+
expect(new_tag_list.class).to eq(MakeTaggable::TagList)
|
80
|
+
end
|
81
|
+
|
82
|
+
context "without duplicates" do
|
83
|
+
let(:arr) { ["crazy", "alien"] }
|
84
|
+
let(:another_tag_list) { MakeTaggable::TagList.new(*arr) }
|
85
|
+
it "adds other list" do
|
86
|
+
expect(tag_list.concat(another_tag_list)).to eq(%w[awesome radical crazy alien])
|
87
|
+
end
|
88
|
+
|
89
|
+
it "adds other array" do
|
90
|
+
expect(tag_list.concat(arr)).to eq(%w[awesome radical crazy alien])
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "#to_s" do
|
96
|
+
it "should give a delimited list of words when converted to string" do
|
97
|
+
expect(tag_list.to_s).to eq("awesome, radical")
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should be able to call to_s on a frozen tag list" do
|
101
|
+
tag_list.freeze
|
102
|
+
expect(-> { tag_list.add("cool", "rad,bodacious") }).to raise_error(RuntimeError)
|
103
|
+
expect(-> { tag_list.to_s }).to_not raise_error
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "cleaning" do
|
108
|
+
it "should parameterize if force_parameterize is set to true" do
|
109
|
+
MakeTaggable.force_parameterize = true
|
110
|
+
tag_list = MakeTaggable::TagList.new("awesome()", "radical)(cc")
|
111
|
+
|
112
|
+
expect(tag_list.to_s).to eq("awesome, radical-cc")
|
113
|
+
MakeTaggable.force_parameterize = false
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should lowercase if force_lowercase is set to true" do
|
117
|
+
MakeTaggable.force_lowercase = true
|
118
|
+
|
119
|
+
tag_list = MakeTaggable::TagList.new("aweSomE", "RaDicaL", "Entrée")
|
120
|
+
expect(tag_list.to_s).to eq("awesome, radical, entrée")
|
121
|
+
|
122
|
+
MakeTaggable.force_lowercase = false
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should ignore case when removing duplicates if strict_case_match is false" do
|
126
|
+
tag_list = MakeTaggable::TagList.new("Junglist", "JUNGLIST", "Junglist", "Massive", "MASSIVE", "MASSIVE")
|
127
|
+
|
128
|
+
expect(tag_list.to_s).to eq("Junglist, Massive")
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should not ignore case when removing duplicates if strict_case_match is true" do
|
132
|
+
MakeTaggable.strict_case_match = true
|
133
|
+
tag_list = MakeTaggable::TagList.new("Junglist", "JUNGLIST", "Junglist", "Massive", "MASSIVE", "MASSIVE")
|
134
|
+
|
135
|
+
expect(tag_list.to_s).to eq("Junglist, JUNGLIST, Massive, MASSIVE")
|
136
|
+
MakeTaggable.strict_case_match = false
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "custom parser" do
|
141
|
+
let(:parser) { double(parse: %w[cool wicked]) }
|
142
|
+
let(:parser_class) { stub_const("MyParser", Class) }
|
143
|
+
|
144
|
+
it "should use a the default parser if none is set as parameter" do
|
145
|
+
allow(MakeTaggable.default_parser).to receive(:new).and_return(parser)
|
146
|
+
MakeTaggable::TagList.new("cool, wicked", parse: true)
|
147
|
+
|
148
|
+
expect(parser).to have_received(:parse)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should use the custom parser passed as parameter" do
|
152
|
+
allow(parser_class).to receive(:new).and_return(parser)
|
153
|
+
|
154
|
+
MakeTaggable::TagList.new("cool, wicked", parser: parser_class)
|
155
|
+
|
156
|
+
expect(parser).to have_received(:parse)
|
157
|
+
end
|
158
|
+
|
159
|
+
it "should use the parser setted as attribute" do
|
160
|
+
allow(parser_class).to receive(:new).with("new, tag").and_return(parser)
|
161
|
+
|
162
|
+
tag_list = MakeTaggable::TagList.new("example")
|
163
|
+
tag_list.parser = parser_class
|
164
|
+
tag_list.add("new, tag", parse: true)
|
165
|
+
|
166
|
+
expect(parser).to have_received(:parse)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|