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.
Files changed (68) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +28 -0
  3. data/Rakefile +31 -0
  4. data/lib/generators/taxonomy/migration/migration_generator.rb +39 -0
  5. data/lib/generators/taxonomy/migration/templates/active_record/migration.rb +36 -0
  6. data/lib/tasks/taxonomy_tasks.rake +4 -0
  7. data/lib/taxonomy.rb +25 -0
  8. data/lib/taxonomy/group_helper.rb +12 -0
  9. data/lib/taxonomy/has_tagger.rb +52 -0
  10. data/lib/taxonomy/has_taxonomy.rb +502 -0
  11. data/lib/taxonomy/tag.rb +485 -0
  12. data/lib/taxonomy/tag_list.rb +97 -0
  13. data/lib/taxonomy/tagging.rb +12 -0
  14. data/lib/taxonomy/tags_helper.rb +13 -0
  15. data/lib/taxonomy/version.rb +3 -0
  16. data/spec/dummy/Rakefile +7 -0
  17. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  18. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  19. data/spec/dummy/app/models/altered_inheriting_taggable_model.rb +3 -0
  20. data/spec/dummy/app/models/inheriting_taggable_model.rb +2 -0
  21. data/spec/dummy/app/models/other_taggable_model.rb +4 -0
  22. data/spec/dummy/app/models/post.rb +2 -0
  23. data/spec/dummy/app/models/taggable_model.rb +6 -0
  24. data/spec/dummy/app/models/taggable_user.rb +3 -0
  25. data/spec/dummy/app/models/treed_model.rb +3 -0
  26. data/spec/dummy/app/models/untaggable_model.rb +2 -0
  27. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  28. data/spec/dummy/config.ru +4 -0
  29. data/spec/dummy/config/application.rb +45 -0
  30. data/spec/dummy/config/boot.rb +10 -0
  31. data/spec/dummy/config/database.yml +19 -0
  32. data/spec/dummy/config/environment.rb +5 -0
  33. data/spec/dummy/config/environments/development.rb +30 -0
  34. data/spec/dummy/config/environments/production.rb +60 -0
  35. data/spec/dummy/config/environments/test.rb +39 -0
  36. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  37. data/spec/dummy/config/initializers/inflections.rb +10 -0
  38. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  39. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  40. data/spec/dummy/config/initializers/session_store.rb +8 -0
  41. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  42. data/spec/dummy/config/locales/en.yml +5 -0
  43. data/spec/dummy/config/routes.rb +58 -0
  44. data/spec/dummy/db/migrate/20111221004133_create_posts.rb +8 -0
  45. data/spec/dummy/db/migrate/20111221023928_taxonomy_migration.rb +35 -0
  46. data/spec/dummy/db/migrate/20111221024100_create_bulk.rb +18 -0
  47. data/spec/dummy/db/schema.rb +65 -0
  48. data/spec/dummy/db/test.sqlite3 +0 -0
  49. data/spec/dummy/log/test.log +100915 -0
  50. data/spec/dummy/public/404.html +26 -0
  51. data/spec/dummy/public/422.html +26 -0
  52. data/spec/dummy/public/500.html +26 -0
  53. data/spec/dummy/public/favicon.ico +0 -0
  54. data/spec/dummy/script/rails +6 -0
  55. data/spec/factories/posts.rb +6 -0
  56. data/spec/generators/taxonomy/migration/migration_generator_spec.rb +22 -0
  57. data/spec/models/post_spec.rb +5 -0
  58. data/spec/spec_helper.rb +30 -0
  59. data/spec/taxonomy/group_helper_spec.rb +21 -0
  60. data/spec/taxonomy/has_tagger_spec.rb +113 -0
  61. data/spec/taxonomy/has_taxonomy_spec.rb +226 -0
  62. data/spec/taxonomy/tag_list_spec.rb +70 -0
  63. data/spec/taxonomy/tag_spec.rb +462 -0
  64. data/spec/taxonomy/taggable_spec.rb +262 -0
  65. data/spec/taxonomy/tagger_spec.rb +40 -0
  66. data/spec/taxonomy/tagging_spec.rb +25 -0
  67. data/spec/taxonomy/tags_helper_spec.rb +29 -0
  68. 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,6 @@
1
+ # Read about factories at http://github.com/thoughtbot/factory_girl
2
+
3
+ FactoryGirl.define do
4
+ factory :post do
5
+ end
6
+ end
@@ -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
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Post do
4
+ pending "add some examples to (or delete) #{__FILE__}"
5
+ end
@@ -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