taxonomy 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +28 -0
- data/Rakefile +31 -0
- data/lib/generators/taxonomy/migration/migration_generator.rb +39 -0
- data/lib/generators/taxonomy/migration/templates/active_record/migration.rb +36 -0
- data/lib/tasks/taxonomy_tasks.rake +4 -0
- data/lib/taxonomy.rb +25 -0
- data/lib/taxonomy/group_helper.rb +12 -0
- data/lib/taxonomy/has_tagger.rb +52 -0
- data/lib/taxonomy/has_taxonomy.rb +502 -0
- data/lib/taxonomy/tag.rb +485 -0
- data/lib/taxonomy/tag_list.rb +97 -0
- data/lib/taxonomy/tagging.rb +12 -0
- data/lib/taxonomy/tags_helper.rb +13 -0
- data/lib/taxonomy/version.rb +3 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/altered_inheriting_taggable_model.rb +3 -0
- data/spec/dummy/app/models/inheriting_taggable_model.rb +2 -0
- data/spec/dummy/app/models/other_taggable_model.rb +4 -0
- data/spec/dummy/app/models/post.rb +2 -0
- data/spec/dummy/app/models/taggable_model.rb +6 -0
- data/spec/dummy/app/models/taggable_user.rb +3 -0
- data/spec/dummy/app/models/treed_model.rb +3 -0
- data/spec/dummy/app/models/untaggable_model.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +19 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +30 -0
- data/spec/dummy/config/environments/production.rb +60 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/db/migrate/20111221004133_create_posts.rb +8 -0
- data/spec/dummy/db/migrate/20111221023928_taxonomy_migration.rb +35 -0
- data/spec/dummy/db/migrate/20111221024100_create_bulk.rb +18 -0
- data/spec/dummy/db/schema.rb +65 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +100915 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/factories/posts.rb +6 -0
- data/spec/generators/taxonomy/migration/migration_generator_spec.rb +22 -0
- data/spec/models/post_spec.rb +5 -0
- data/spec/spec_helper.rb +30 -0
- data/spec/taxonomy/group_helper_spec.rb +21 -0
- data/spec/taxonomy/has_tagger_spec.rb +113 -0
- data/spec/taxonomy/has_taxonomy_spec.rb +226 -0
- data/spec/taxonomy/tag_list_spec.rb +70 -0
- data/spec/taxonomy/tag_spec.rb +462 -0
- data/spec/taxonomy/taggable_spec.rb +262 -0
- data/spec/taxonomy/tagger_spec.rb +40 -0
- data/spec/taxonomy/tagging_spec.rb +25 -0
- data/spec/taxonomy/tags_helper_spec.rb +29 -0
- metadata +225 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/404.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
23
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/422.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>The change you wanted was rejected.</h1>
|
23
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<style type="text/css">
|
6
|
+
body { background-color: #fff; color: #666; text-align: center; font-family: arial, sans-serif; }
|
7
|
+
div.dialog {
|
8
|
+
width: 25em;
|
9
|
+
padding: 0 4em;
|
10
|
+
margin: 4em auto 0 auto;
|
11
|
+
border: 1px solid #ccc;
|
12
|
+
border-right-color: #999;
|
13
|
+
border-bottom-color: #999;
|
14
|
+
}
|
15
|
+
h1 { font-size: 100%; color: #f00; line-height: 1.5em; }
|
16
|
+
</style>
|
17
|
+
</head>
|
18
|
+
|
19
|
+
<body>
|
20
|
+
<!-- This file lives in public/500.html -->
|
21
|
+
<div class="dialog">
|
22
|
+
<h1>We're sorry, but something went wrong.</h1>
|
23
|
+
<p>We've been notified about this issue and we'll take a look at it shortly.</p>
|
24
|
+
</div>
|
25
|
+
</body>
|
26
|
+
</html>
|
File without changes
|
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
|
+
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
6
|
+
require 'rails/commands'
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Generators are not automatically loaded by Rails
|
4
|
+
require 'generators/taxonomy/migration/migration_generator'
|
5
|
+
|
6
|
+
describe Taxonomy::MigrationGenerator do
|
7
|
+
# Tell the generator where to put its output (what it thinks of as Rails.root)
|
8
|
+
destination File.expand_path("../../../../../tmp", __FILE__)
|
9
|
+
|
10
|
+
before do
|
11
|
+
prepare_destination
|
12
|
+
Rails::Generators.options[:rails][:orm] = :active_record
|
13
|
+
end
|
14
|
+
describe 'no arguments' do
|
15
|
+
before { run_generator }
|
16
|
+
|
17
|
+
describe 'db/migrate/taxonomy_migration.rb' do
|
18
|
+
subject { file('db/migrate/taxonomy_migration.rb') }
|
19
|
+
it { should be_a_migration }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
2
|
+
ENV["RAILS_ENV"] ||= 'test'
|
3
|
+
# require File.expand_path("../../config/environment", __FILE__)
|
4
|
+
|
5
|
+
require 'ruby-debug'
|
6
|
+
require File.expand_path(File.dirname(__FILE__) + "/dummy/config/environment", __FILE__)
|
7
|
+
require 'rspec/rails'
|
8
|
+
require 'factory_girl_rails'
|
9
|
+
require 'ammeter/init'
|
10
|
+
|
11
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
12
|
+
# in spec/support/ and its subdirectories.
|
13
|
+
# Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
14
|
+
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
|
15
|
+
Dir[File.dirname(__FILE__) + "/factories/**/*.rb"].each {|f| require f}
|
16
|
+
|
17
|
+
RSpec.configure do |config|
|
18
|
+
# == Mock Framework
|
19
|
+
#
|
20
|
+
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
21
|
+
#
|
22
|
+
# config.mock_with :mocha
|
23
|
+
# config.mock_with :flexmock
|
24
|
+
# config.mock_with :rr
|
25
|
+
|
26
|
+
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
27
|
+
# examples within a transaction, remove the following line or assign false
|
28
|
+
# instead of true.
|
29
|
+
config.use_transactional_fixtures = true
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe "Group Helper" do
|
4
|
+
before(:each) do
|
5
|
+
# clean_database!
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "grouped_column_names_for method" do
|
9
|
+
before(:each) do
|
10
|
+
@taggable = TaggableModel.new(:name => "Bob Jones")
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return all column names joined for Tag GROUP clause" do
|
14
|
+
@taggable.grouped_column_names_for(Tag).should == "tags.id, tags.parent_id, tags.lft, tags.rgt, tags.name, tags.context, tags.slug"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return all column names joined for TaggableModel GROUP clause" do
|
18
|
+
@taggable.grouped_column_names_for(TaggableModel).should == "taggable_models.id, taggable_models.name, taggable_models.type"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe "acts_as_tagger" do
|
4
|
+
before(:each) do
|
5
|
+
# clean_database!
|
6
|
+
end
|
7
|
+
|
8
|
+
context "Tagger Method Generation" do
|
9
|
+
before(:each) do
|
10
|
+
@tagger = TaggableUser.new()
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should add #is_tagger? query method to the class-side" do
|
14
|
+
TaggableUser.should respond_to(:is_tagger?)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return true from the class-side #is_tagger?" do
|
18
|
+
TaggableUser.is_tagger?.should be_true
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return false from the base #is_tagger?" do
|
22
|
+
ActiveRecord::Base.is_tagger?.should be_false
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should add #is_tagger? query method to the singleton" do
|
26
|
+
@tagger.should respond_to(:is_tagger?)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should add #tag method on the instance-side" do
|
30
|
+
@tagger.should respond_to(:tag)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should generate an association for #owned_taggings and #owned_tags" do
|
34
|
+
@tagger.should respond_to(:owned_taggings, :owned_tags)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#tag" do
|
39
|
+
context 'when called with a non-existent tag context' do
|
40
|
+
before(:each) do
|
41
|
+
@tagger = TaggableUser.new()
|
42
|
+
@taggable = TaggableModel.new(:name=>"Richard Prior")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should by default not throw an exception " do
|
46
|
+
@taggable.tag_list_on(:foo).should be_empty
|
47
|
+
lambda {
|
48
|
+
@tagger.tag(@taggable, :with=>'this, and, that', :on=>:foo)
|
49
|
+
}.should_not raise_error
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should by default create the tag context on-the-fly' do
|
53
|
+
@taggable.tag_list_on(:here_ond_now).should be_empty
|
54
|
+
@tagger.tag(@taggable, :with=>'that', :on => :here_ond_now)
|
55
|
+
@taggable.tag_list_on(:here_ond_now).should_not include('that')
|
56
|
+
@taggable.all_tags_list_on(:here_ond_now).should include('that')
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should show all the tag list when both public and owned tags exist" do
|
60
|
+
@taggable.tag_list = 'ruby, python'
|
61
|
+
@tagger.tag(@taggable, :with => 'java, lisp', :on => :tags)
|
62
|
+
@taggable.all_tags_on(:tags).map(&:name).sort.should == %w(ruby python java lisp).sort
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should not add owned tags to the common list" do
|
66
|
+
@taggable.tag_list = 'ruby, python'
|
67
|
+
@tagger.tag(@taggable, :with => 'java, lisp', :on => :foo)
|
68
|
+
@tagger.tag(@taggable, :with => '', :on => :foo)
|
69
|
+
@taggable.tag_list.should == %w(ruby python)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should throw an exception when the default is over-ridden" do
|
73
|
+
@taggable.tag_list_on(:foo_boo).should be_empty
|
74
|
+
lambda {
|
75
|
+
@tagger.tag(@taggable, :with=>'this, and, that', :on=>:foo_boo, :force=>false)
|
76
|
+
}.should raise_error
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should not create the tag context on-the-fly when the default is over-ridden" do
|
80
|
+
@taggable.tag_list_on(:foo_boo).should be_empty
|
81
|
+
@tagger.tag(@taggable, :with=>'this, and, that', :on=>:foo_boo, :force=>false) rescue
|
82
|
+
@taggable.tag_list_on(:foo_boo).should be_empty
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when called by multiple tagger's" do
|
87
|
+
before(:each) do
|
88
|
+
@user_x = TaggableUser.create(:name => "User X")
|
89
|
+
@user_y = TaggableUser.create(:name => "User Y")
|
90
|
+
@taggable = TaggableModel.create(:name => 'has_taxonomy_on', :tag_list => 'plugin')
|
91
|
+
|
92
|
+
@user_x.tag(@taggable, :with => 'ruby, rails', :on => :tags)
|
93
|
+
@user_y.tag(@taggable, :with => 'ruby, plugin', :on => :tags)
|
94
|
+
|
95
|
+
@user_y.tag(@taggable, :with => '', :on => :tags)
|
96
|
+
@user_y.tag(@taggable, :with => '', :on => :tags)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should delete owned tags" do
|
100
|
+
@user_y.owned_tags.should == []
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should not delete other taggers tags" do
|
104
|
+
@user_x.owned_tags.should have(2).items
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should not delete original tags" do
|
108
|
+
@taggable.all_tags_list_on(:tags).should include('plugin')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe "Acts As Taxonomy" do
|
4
|
+
before(:each) do
|
5
|
+
# clean_database!
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should provide a class method 'taggable?' that is false for untaggable models" do
|
9
|
+
UntaggableModel.should_not be_taggable
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "Treed Taggings Method Generation" do
|
13
|
+
before(:each) do
|
14
|
+
[TreedModel, Tag, Tagging].each(&:delete_all)
|
15
|
+
@taggable = TreedModel.new(:name => "Bob Jones")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should respond 'true' to tag_type_treed?" do
|
19
|
+
TreedModel.should be_categories_treed
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "Taggable Method Generation" do
|
24
|
+
before(:each) do
|
25
|
+
[TaggableModel, Tag, Tagging, TaggableUser].each(&:delete_all)
|
26
|
+
@taggable = TaggableModel.new(:name => "Bob Jones")
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should respond 'true' to taggable?" do
|
30
|
+
@taggable.class.should be_taggable
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should respond 'false' to tag_type_treed?" do
|
34
|
+
TaggableModel.should_not be_skills_treed
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should create a class attribute for tag types" do
|
38
|
+
@taggable.class.should respond_to(:tag_types)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should create an instance attribute for tag types" do
|
42
|
+
@taggable.should respond_to(:tag_types)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should generate an association for each tag type" do
|
46
|
+
@taggable.should respond_to(:tags, :skills, :languages)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should generate a cached column checker for each tag type" do
|
50
|
+
TaggableModel.should respond_to(:caching_tag_list?, :caching_skill_list?, :caching_language_list?)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should add tagged_with and tag_counts to singleton" do
|
54
|
+
TaggableModel.should respond_to(:find_tagged_with, :tag_counts)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should add saving of tag lists and cached tag lists to the instance" do
|
58
|
+
@taggable.should respond_to(:save_cached_tag_list)
|
59
|
+
@taggable.should respond_to(:save_tags)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should generate a tag_list accessor/setter for each tag type" do
|
63
|
+
@taggable.should respond_to(:tag_list, :skill_list, :language_list)
|
64
|
+
@taggable.should respond_to(:tag_list=, :skill_list=, :language_list=)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "Single Table Inheritance" do
|
69
|
+
before do
|
70
|
+
@taggable = TaggableModel.new(:name => "taggable")
|
71
|
+
@inherited_same = InheritingTaggableModel.new(:name => "inherited same")
|
72
|
+
@inherited_different = AlteredInheritingTaggableModel.new(:name => "inherited different")
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should pass on tag contexts to STI-inherited models" do
|
76
|
+
@inherited_same.should respond_to(:tag_list, :skill_list, :language_list)
|
77
|
+
@inherited_different.should respond_to(:tag_list, :skill_list, :language_list)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should have tag contexts added in altered STI models" do
|
81
|
+
@inherited_different.should respond_to(:part_list)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "Reloading" do
|
86
|
+
it "should save a model instantiated by Model.find" do
|
87
|
+
taggable = TaggableModel.create!(:name => "Taggable")
|
88
|
+
found_taggable = TaggableModel.find(taggable.id)
|
89
|
+
found_taggable.save
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "Related Objects" do
|
94
|
+
it "should find related objects based on tag names on context" do
|
95
|
+
taggable1 = TaggableModel.create!(:name => "Taggable 1")
|
96
|
+
taggable2 = TaggableModel.create!(:name => "Taggable 2")
|
97
|
+
taggable3 = TaggableModel.create!(:name => "Taggable 3")
|
98
|
+
|
99
|
+
taggable1.tag_list = "one, two"
|
100
|
+
taggable1.save
|
101
|
+
|
102
|
+
taggable2.tag_list = "three, four"
|
103
|
+
taggable2.save
|
104
|
+
|
105
|
+
taggable3.tag_list = "one, four"
|
106
|
+
taggable3.save
|
107
|
+
|
108
|
+
taggable1.find_related_tags.should include(taggable3)
|
109
|
+
taggable1.find_related_tags.should_not include(taggable2)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should find other related objects based on tag names on context" do
|
113
|
+
taggable1 = TaggableModel.create!(:name => "Taggable 1")
|
114
|
+
taggable2 = OtherTaggableModel.create!(:name => "Taggable 2")
|
115
|
+
taggable3 = OtherTaggableModel.create!(:name => "Taggable 3")
|
116
|
+
|
117
|
+
taggable1.tag_list = "one, two"
|
118
|
+
taggable1.save
|
119
|
+
|
120
|
+
taggable2.tag_list = "three, four"
|
121
|
+
taggable2.save
|
122
|
+
|
123
|
+
taggable3.tag_list = "one, four"
|
124
|
+
taggable3.save
|
125
|
+
|
126
|
+
taggable1.find_related_tags_for(OtherTaggableModel).should include(taggable3)
|
127
|
+
taggable1.find_related_tags_for(OtherTaggableModel).should_not include(taggable2)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should not include the object itself in the list of related objects" do
|
131
|
+
taggable1 = TaggableModel.create!(:name => "Taggable 1")
|
132
|
+
taggable2 = TaggableModel.create!(:name => "Taggable 2")
|
133
|
+
|
134
|
+
taggable1.tag_list = "one"
|
135
|
+
taggable1.save
|
136
|
+
|
137
|
+
taggable2.tag_list = "one, two"
|
138
|
+
taggable2.save
|
139
|
+
|
140
|
+
taggable1.find_related_tags.should include(taggable2)
|
141
|
+
taggable1.find_related_tags.should_not include(taggable1)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "Matching Contexts" do
|
146
|
+
it "should find objects with tags of matching contexts" do
|
147
|
+
taggable1 = TaggableModel.create!(:name => "Taggable 1")
|
148
|
+
taggable2 = TaggableModel.create!(:name => "Taggable 2")
|
149
|
+
taggable3 = TaggableModel.create!(:name => "Taggable 3")
|
150
|
+
|
151
|
+
taggable1.offering_list = "one, two"
|
152
|
+
taggable1.save!
|
153
|
+
|
154
|
+
taggable2.need_list = "one, two"
|
155
|
+
taggable2.save!
|
156
|
+
|
157
|
+
taggable3.offering_list = "one, two"
|
158
|
+
taggable3.save!
|
159
|
+
|
160
|
+
taggable1.find_matching_contexts(:offerings, :needs).should include(taggable2)
|
161
|
+
taggable1.find_matching_contexts(:offerings, :needs).should_not include(taggable3)
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should find other related objects with tags of matching contexts" do
|
165
|
+
taggable1 = TaggableModel.create!(:name => "Taggable 1")
|
166
|
+
taggable2 = OtherTaggableModel.create!(:name => "Taggable 2")
|
167
|
+
taggable3 = OtherTaggableModel.create!(:name => "Taggable 3")
|
168
|
+
|
169
|
+
taggable1.offering_list = "one, two"
|
170
|
+
taggable1.save
|
171
|
+
|
172
|
+
taggable2.need_list = "one, two"
|
173
|
+
taggable2.save
|
174
|
+
|
175
|
+
taggable3.offering_list = "one, two"
|
176
|
+
taggable3.save
|
177
|
+
|
178
|
+
taggable1.find_matching_contexts_for(OtherTaggableModel, :offerings, :needs).should include(taggable2)
|
179
|
+
taggable1.find_matching_contexts_for(OtherTaggableModel, :offerings, :needs).should_not include(taggable3)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should not include the object itself in the list of related objects" do
|
183
|
+
taggable1 = TaggableModel.create!(:name => "Taggable 1")
|
184
|
+
taggable2 = TaggableModel.create!(:name => "Taggable 2")
|
185
|
+
|
186
|
+
taggable1.tag_list = "one"
|
187
|
+
taggable1.save
|
188
|
+
|
189
|
+
taggable2.tag_list = "one, two"
|
190
|
+
taggable2.save
|
191
|
+
|
192
|
+
taggable1.find_related_tags.should include(taggable2)
|
193
|
+
taggable1.find_related_tags.should_not include(taggable1)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe 'Tagging Contexts' do
|
198
|
+
it 'should eliminate duplicate tagging contexts ' do
|
199
|
+
TaggableModel.has_taxonomy_on(:skills, :skills)
|
200
|
+
TaggableModel.tag_types.count("skills").should == 1
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should not contain embedded/nested arrays" do
|
204
|
+
TaggableModel.has_taxonomy_on([:array], [:array])
|
205
|
+
TaggableModel.tag_types.count([:array]).should == 0
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should _flatten_ the content of arrays" do
|
209
|
+
TaggableModel.has_taxonomy_on([:array], [:array])
|
210
|
+
TaggableModel.tag_types.count("array").should == 1
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should not raise an error when passed nil" do
|
214
|
+
lambda {
|
215
|
+
TaggableModel.has_taxonomy_on()
|
216
|
+
}.should_not raise_error
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should not raise an error when passed [nil]" do
|
220
|
+
lambda {
|
221
|
+
TaggableModel.has_taxonomy_on([nil])
|
222
|
+
}.should_not raise_error
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|