tagged 0.0.0

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/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ *.swp
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |g|
9
+ g.name = 'tagged'
10
+ g.summary = %(Simple ORM agnostic tagging.)
11
+ g.description = %(Simple ORM agnostic tagging.)
12
+ g.email = 'matt@toastyapps.com'
13
+ g.homepage = 'http://github.com/toastyapps/tagged'
14
+ g.authors = %w(toastyapps)
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts 'Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com'
19
+ end
20
+
21
+ Rake::TestTask.new do |t|
22
+ t.libs = %w(test)
23
+ t.pattern = 'test/**/*_test.rb'
24
+ end
25
+
26
+ task :default => :test
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
@@ -0,0 +1,11 @@
1
+ class VestalVersionsMigrationGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ m.migration_template 'migration.rb', 'db/migrate'
5
+ end
6
+ end
7
+
8
+ def file_name
9
+ 'create_tagged'
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ class CreateTagged < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :taggings do |t|
4
+ t.belongs_to :tagged, :polymorphic => true
5
+ t.belongs_to :tag
6
+ t.datetime :created_at
7
+ end
8
+
9
+ create_table :tags do |t|
10
+ t.string :name
11
+ end
12
+
13
+ add_index :tags, :name
14
+ add_index :taggings, :tag_id
15
+ add_index :taggings, [:taggable_id, :taggable_type]
16
+
17
+ end
18
+
19
+ def self.down
20
+ drop_table :taggings
21
+ drop_table :tags
22
+ end
23
+ end
data/lib/tagged.rb ADDED
@@ -0,0 +1,57 @@
1
+ module Tagged
2
+
3
+ module Extension
4
+ def self.included(base)
5
+ base.class_eval do
6
+ def self.tagged
7
+ include Tagged::Base
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ module Base
14
+
15
+ def self.included(model)
16
+ model.class_eval do
17
+ def self.delimiter
18
+ @@delimiter ||= ','
19
+ end
20
+
21
+ def self.delimiter=(value)
22
+ @@delimiter = value
23
+ end
24
+ end
25
+ end
26
+
27
+ def delimiter
28
+ self.class.delimiter
29
+ end
30
+
31
+ def tag_list
32
+ self._tag_list
33
+ end
34
+
35
+ def tag_list=(list)
36
+ self._tag_list = Tagged::TagList.new(list.split(delimiter).map(&:strip))
37
+ end
38
+
39
+ def tag(list)
40
+ list.split(delimiter).map {|tag| self._tag_list << tag.strip }
41
+ end
42
+
43
+ def untag(items)
44
+ items.split(delimiter).map{|tag| self._tag_list.delete(tag.strip)}
45
+ end
46
+
47
+ def _tag_list
48
+ @tag_list ||= Tagged::TagList.new([], delimiter)
49
+ end
50
+ end
51
+ end
52
+
53
+ require 'tagged/tag'
54
+ require 'tagged/tag_list'
55
+ require 'tagged/adapters/abstract_adapter'
56
+
57
+
@@ -0,0 +1,4 @@
1
+ module Tagged
2
+ class AbstractAdapter
3
+ end
4
+ end
@@ -0,0 +1,35 @@
1
+ require 'tagged'
2
+
3
+ module Tagged
4
+
5
+ module ActiveRecordExtension
6
+ def self.included(base)
7
+ base.class_eval do
8
+ @@tagged_adapter = ActiveRecordAdapter.new
9
+ extend ClassMethods
10
+ include Tagged::Base
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ def tagged
16
+ self.class_eval do
17
+ has_many :taggings, :as => :tagged, :dependent => :destroy
18
+ has_many :tags, :through => :taggings
19
+ after_save :save_tags
20
+ end
21
+ end
22
+ end
23
+
24
+ def save_tags
25
+ tag_list.each do |tag_name|
26
+ tags << ::Tag.find_or_initialize_by_name(tag_name)
27
+ end
28
+ end
29
+ end
30
+ class ActiveRecordAdapter < AbstractAdapter
31
+
32
+ end
33
+ end
34
+
35
+ ActiveRecord::Base.send(:include, Tagged::ActiveRecordExtension)
@@ -0,0 +1,32 @@
1
+ require 'tagged'
2
+
3
+ module Tagged
4
+
5
+ module MongoMapperExtension
6
+ def self.included(base)
7
+ base.class_eval do
8
+ @@tagged_adapter = MongoMapperAdapter.new
9
+ include Tagged::Base
10
+ end
11
+ end
12
+ end
13
+ class MongoMapperAdapter < AbstractAdapter
14
+
15
+ end
16
+ end
17
+
18
+ module MongoMapper
19
+ module Document
20
+ module ClassMethods
21
+ def tagged
22
+ include Tagged::MongoMapperExtension
23
+ key :tags, Array
24
+ before_save :save_tags
25
+ end
26
+ end
27
+
28
+ def save_tags
29
+ self.tags = self.tag_list
30
+ end
31
+ end
32
+ end
data/lib/tagged/tag.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Tagged
2
+ class Tag
3
+ attr_accessor :name, :kind
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ module Tagged
2
+ class TagList < Array
3
+ attr_accessor :tags, :delimiter
4
+ def initialize(*list)
5
+ self.delimiter = ','
6
+ if list[0].is_a?(Array)
7
+ self.delimiter = list[1]
8
+ list = list[0]
9
+ end
10
+ list = list.is_a?(Array) ? list : list.split(self.delimiter).collect(&:strip).reject(&:blank)
11
+ super(list)
12
+ end
13
+
14
+ def +(list)
15
+ Tagged::TagList.new(self.to_a + list, self.delimiter)
16
+ end
17
+
18
+ def to_s(delimiter = nil)
19
+ join(delimiter || self.delimiter)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,4 @@
1
+ module Tagged
2
+ class Tagging
3
+ end
4
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'tagged'
@@ -0,0 +1,55 @@
1
+ require 'test_helper'
2
+ require 'active_record'
3
+ require 'tagged/adapters/active_record_adapter'
4
+ require 'schema'
5
+
6
+
7
+ class ActiveRecordTest < Test::Unit::TestCase
8
+ context "A Tagged ActiveRecord class" do
9
+ should "respond to tagged class methods" do
10
+ [:delimiter, :delimiter=].each do |method|
11
+ assert Post.respond_to?(method)
12
+ end
13
+ end
14
+ end
15
+
16
+ context "A Tagged ActiveRecord instance" do
17
+ setup do
18
+ @post = Post.new
19
+ end
20
+
21
+ should "respond to tagged instance methods" do
22
+ [:tag, :tag_list, :untag].each do |method|
23
+ assert @post.respond_to?(method)
24
+ end
25
+ end
26
+
27
+ should "respond to taggings" do
28
+ assert @post.respond_to?(:taggings)
29
+ end
30
+
31
+ should "have no tags to begin with" do
32
+ assert_equal [], @post.tag_list
33
+ end
34
+
35
+ should "be able to add a tag" do
36
+ @post.tag('foo')
37
+ assert_equal ['foo'], @post.tag_list
38
+ end
39
+
40
+ should "be able to remove a tag" do
41
+ @post.tag('foo')
42
+ @post.untag('foo')
43
+ assert_equal [], @post.tag_list
44
+ end
45
+
46
+ should "be able to save tags" do
47
+ @post.tag('foo,bar')
48
+ @post.save
49
+ assert_equal 2, Tag.count
50
+ assert_equal 2, Tagging.count
51
+ end
52
+
53
+ end
54
+ end
55
+
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ class Bar
4
+ include Tagged::Base
5
+ end
6
+
7
+ class TaggingTest < Test::Unit::TestCase
8
+ context "A tagged instance with a custom delimiter" do
9
+ setup do
10
+ Bar.delimiter = '|'
11
+ @bar = Bar.new
12
+ @bar.tag('hoge|fuga|piyo')
13
+ end
14
+
15
+ should "respond with the correct tags" do
16
+ assert_equal ['hoge', 'fuga', 'piyo'], @bar.tag_list
17
+ end
18
+
19
+ should "be able to represent the tags as a string" do
20
+ assert_equal "hoge|fuga|piyo", @bar.tag_list.to_s
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,8 @@
1
+ MongoMapper.connection = Mongo::Connection.new('127.0.0.1')
2
+ MongoMapper.database = "testing_tagged"
3
+
4
+ class Article
5
+ include MongoMapper::Document
6
+ key :title, String
7
+ tagged
8
+ end
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+ require 'mongo_mapper'
3
+ require 'tagged/adapters/mongo_mapper_adapter'
4
+ require 'mongo_mapper_schema'
5
+
6
+
7
+ class MongoMapperTest < Test::Unit::TestCase
8
+ context "A Tagged MongoMapper class" do
9
+ should "respond to tagged class methods" do
10
+ [:delimiter, :delimiter=].each do |method|
11
+ assert Article.respond_to?(method)
12
+ end
13
+ end
14
+ end
15
+
16
+ context "A Tagged MongoMapper instance" do
17
+ setup do
18
+ @article = Article.new
19
+ end
20
+
21
+ should "respond to tagged instance methods" do
22
+ [:tag, :tag_list, :untag].each do |method|
23
+ assert @article.respond_to?(method)
24
+ end
25
+ end
26
+
27
+ should "have no tags to begin with" do
28
+ assert_equal [], @article.tag_list
29
+ end
30
+
31
+ should "be able to add a tag" do
32
+ @article.tag('foo')
33
+ assert_equal ['foo'], @article.tag_list
34
+ end
35
+
36
+ should "be able to remove a tag" do
37
+ @article.tag('foo')
38
+ @article.untag('foo')
39
+ assert_equal [], @article.tag_list
40
+ end
41
+
42
+ should "be able to save tags" do
43
+ @article.tag('foo,bar')
44
+ @article.save
45
+ @find_article = Article.find(@article.id)
46
+ assert_equal ['foo', 'bar'], @find_article.tags
47
+ end
48
+
49
+ end
50
+ end
51
+
data/test/schema.rb ADDED
@@ -0,0 +1,38 @@
1
+ ActiveRecord::Base.configurations = {'sqlite3' => {:adapter => 'sqlite3', :database => ':memory:'}}
2
+ ActiveRecord::Base.establish_connection('sqlite3')
3
+ ActiveRecord::Base.logger = Logger.new(STDERR)
4
+ ActiveRecord::Base.logger.level = Logger::WARN
5
+
6
+ class CreateSchema < ActiveRecord::Migration
7
+ def self.up
8
+ create_table :taggings do |t|
9
+ t.belongs_to :tagged, :polymorphic => true
10
+ t.belongs_to :tag
11
+ t.datetime :created_at
12
+ end
13
+
14
+ create_table :tags do |t|
15
+ t.string :name
16
+ end
17
+ create_table :posts do |t|
18
+ t.string :title, :default => ''
19
+ end
20
+ end
21
+ end
22
+
23
+ CreateSchema.suppress_messages do
24
+ CreateSchema.migrate(:up)
25
+ end
26
+
27
+ class Tagging < ActiveRecord::Base
28
+ belongs_to :tag
29
+ belongs_to :tagged, :polymorphic => true
30
+ end
31
+
32
+ class Post < ActiveRecord::Base
33
+ tagged
34
+ end
35
+
36
+ class Tag < ActiveRecord::Base
37
+ has_many :taggings, :dependent => :destroy
38
+ end
@@ -0,0 +1,37 @@
1
+ require 'test_helper'
2
+
3
+ class TaggingTest < Test::Unit::TestCase
4
+ context "A tag_list" do
5
+ setup do
6
+ @list = Tagged::TagList.new
7
+ end
8
+
9
+ should 'be able to add tags with tags#+=' do
10
+ tags = ['foo', 'bar']
11
+ @list += tags
12
+ assert_equal tags, @list
13
+ end
14
+
15
+ should 'be able to add tags with <<' do
16
+ tags = ['foo', 'bar']
17
+ tags.each do |tag|
18
+ @list << tag
19
+ end
20
+ assert_equal tags, @list
21
+ end
22
+
23
+ should 'be able to represent the tags in a string' do
24
+ tags = ['foo', 'bar']
25
+ @list += tags
26
+ assert_equal "foo,bar", @list.to_s
27
+ end
28
+
29
+ should 'be able to remove tags' do
30
+ tags = ['foo', 'bar']
31
+ @list += tags
32
+ @list.delete('foo')
33
+ assert_equal ['bar'], @list
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,41 @@
1
+ require 'test_helper'
2
+
3
+ class Foo
4
+ include Tagged::Base
5
+ end
6
+
7
+ class TaggingTest < Test::Unit::TestCase
8
+ context "A tagged instance" do
9
+ setup do
10
+ @foo = Foo.new
11
+ @foo.tag("hoge, fuga, piyo")
12
+ end
13
+
14
+ should "respond with the correct tags" do
15
+ assert_equal ['hoge', 'fuga', 'piyo'], @foo.tag_list
16
+ end
17
+
18
+ should "be able to add tags" do
19
+ @foo.tag('osake')
20
+ assert_equal ['hoge', 'fuga', 'piyo', 'osake'], @foo.tag_list
21
+ end
22
+
23
+ should "be able to remove a tag" do
24
+ @foo.untag('fuga')
25
+ assert_equal ['hoge', 'piyo'], @foo.tag_list
26
+ end
27
+
28
+ should "be able to remove multiple tags" do
29
+ @foo.untag('hoge, fuga')
30
+ assert_equal ['piyo'], @foo.tag_list
31
+ end
32
+
33
+ should "be able to represent the tags as a string" do
34
+ assert_equal "hoge,fuga,piyo", @foo.tag_list.to_s
35
+ end
36
+
37
+ should "be able to represent the tags as a custom string" do
38
+ assert_equal "hoge, fuga, piyo", @foo.tag_list.to_s(', ')
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,7 @@
1
+ $: << File.join(File.dirname(__FILE__), '..', 'lib')
2
+ $: << File.dirname(__FILE__)
3
+ require 'rubygems'
4
+ require 'test/unit'
5
+ require 'tagged'
6
+ require 'shoulda'
7
+
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tagged
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - toastyapps
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-21 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Simple ORM agnostic tagging.
17
+ email: matt@toastyapps.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - .gitignore
26
+ - Rakefile
27
+ - VERSION
28
+ - generators/tagged_migration/tagged_migration_generator.rb
29
+ - generators/tagged_migration/templates/migration.rb
30
+ - lib/tagged.rb
31
+ - lib/tagged/adapters/abstract_adapter.rb
32
+ - lib/tagged/adapters/active_record_adapter.rb
33
+ - lib/tagged/adapters/mongo_mapper_adapter.rb
34
+ - lib/tagged/tag.rb
35
+ - lib/tagged/tag_list.rb
36
+ - lib/tagged/tagging.rb
37
+ - rails/init.rb
38
+ - test/active_record_test.rb
39
+ - test/delimiter_test.rb
40
+ - test/mongo_mapper_schema.rb
41
+ - test/mongo_mapper_test.rb
42
+ - test/schema.rb
43
+ - test/tag_list_test.rb
44
+ - test/tagging_test.rb
45
+ - test/test_helper.rb
46
+ has_rdoc: true
47
+ homepage: http://github.com/toastyapps/tagged
48
+ licenses: []
49
+
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --charset=UTF-8
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.3.5
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Simple ORM agnostic tagging.
74
+ test_files:
75
+ - test/active_record_test.rb
76
+ - test/delimiter_test.rb
77
+ - test/mongo_mapper_schema.rb
78
+ - test/mongo_mapper_test.rb
79
+ - test/schema.rb
80
+ - test/tag_list_test.rb
81
+ - test/tagging_test.rb
82
+ - test/test_helper.rb