aq1018-dm-is-slug 0.9.9
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/History.txt +1 -0
- data/LICENSE +20 -0
- data/Manifest.txt +12 -0
- data/README.txt +56 -0
- data/Rakefile +54 -0
- data/TODO +4 -0
- data/lib/dm-is-slug.rb +36 -0
- data/lib/dm-is-slug/is/slug.rb +164 -0
- data/lib/dm-is-slug/is/version.rb +7 -0
- data/spec/integration/slug_spec.rb +182 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +28 -0
- metadata +85 -0
data/History.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Aaron Qian
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
= dm-is-slug
|
2
|
+
|
3
|
+
DataMapper plugin for creating and slugs(permalinks).
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
NOTE: You no longer need to download dm-more source code in order to install
|
8
|
+
this.
|
9
|
+
|
10
|
+
All you need to do is:
|
11
|
+
|
12
|
+
$ sudo rake install
|
13
|
+
|
14
|
+
Remember to require it in your app's init.rb
|
15
|
+
|
16
|
+
dependency 'dm-is-slug'
|
17
|
+
|
18
|
+
== Getting started
|
19
|
+
|
20
|
+
Lets say we have a post-class, and we want to generate permalinks or slugs for all posts.
|
21
|
+
|
22
|
+
class Post
|
23
|
+
include DataMapper::Resource
|
24
|
+
|
25
|
+
property :id, Serial
|
26
|
+
property :title, String
|
27
|
+
property :content, String
|
28
|
+
|
29
|
+
# here we define that it should have a slug that uses title as the permalink
|
30
|
+
# it will generate an extra slug property of String type, with the same size as title
|
31
|
+
is :slug, :source => :title
|
32
|
+
end
|
33
|
+
|
34
|
+
Let's Say we need to define a permalink based on a method instead of a property.
|
35
|
+
|
36
|
+
class User
|
37
|
+
include DataMapper::Resource
|
38
|
+
|
39
|
+
property :id, Serial
|
40
|
+
property :email, String
|
41
|
+
property :password, String
|
42
|
+
|
43
|
+
# we only want to strip out the domain name
|
44
|
+
# and use only the email account name as the permalink
|
45
|
+
def slug_for_email
|
46
|
+
email.split("@").first
|
47
|
+
end
|
48
|
+
|
49
|
+
# here we define that it should have a slug that uses title as the permalink
|
50
|
+
# it will generate an extra slug property of String type, with the same size as title
|
51
|
+
is :slug, :source => :slug_for_email, :size => 255
|
52
|
+
end
|
53
|
+
|
54
|
+
You can now find objects by slug like this:
|
55
|
+
|
56
|
+
post = Post.first(:slug => "your_slug")
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require 'spec/rake/spectask'
|
6
|
+
require 'pathname'
|
7
|
+
|
8
|
+
ROOT = Pathname(__FILE__).dirname.expand_path
|
9
|
+
require ROOT + 'lib/dm-is-slug/is/version'
|
10
|
+
|
11
|
+
AUTHOR = "Aaron Qian, Nik Radford"
|
12
|
+
EMAIL = "aaron [a] ekohe [d] com; nik [a] terminaldischarge [d] net"
|
13
|
+
GEM_NAME = "dm-is-slug"
|
14
|
+
GEM_VERSION = DataMapper::Is::Slug::VERSION
|
15
|
+
GEM_DEPENDENCIES = [["dm-core", "~>0.9"]]
|
16
|
+
GEM_CLEAN = ["log", "pkg"]
|
17
|
+
GEM_EXTRAS = { :has_rdoc => false }
|
18
|
+
|
19
|
+
PROJECT_NAME = "dm-is-slug"
|
20
|
+
PROJECT_URL = "http://github.com/aq1018/dm-is-slug"
|
21
|
+
PROJECT_DESCRIPTION = PROJECT_SUMMARY = "DataMapper plugin that generates unique slugs"
|
22
|
+
|
23
|
+
require 'tasks/hoe'
|
24
|
+
|
25
|
+
task :default => [ :spec ]
|
26
|
+
|
27
|
+
WIN32 = (RUBY_PLATFORM =~ /win32|mingw|cygwin/) rescue nil
|
28
|
+
SUDO = WIN32 ? '' : ('sudo' unless ENV['SUDOLESS'])
|
29
|
+
|
30
|
+
desc "Install #{GEM_NAME} #{GEM_VERSION}"
|
31
|
+
task :install => [ :package ] do
|
32
|
+
sh "#{SUDO} gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources", :verbose => false
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Uninstall #{GEM_NAME} #{GEM_VERSION} (default ruby)"
|
36
|
+
task :uninstall => [ :clobber ] do
|
37
|
+
sh "#{SUDO} gem uninstall #{GEM_NAME} -v#{GEM_VERSION} -I -x", :verbose => false
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'Run specifications'
|
41
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
42
|
+
t.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
|
43
|
+
t.spec_files = Pathname.glob(Pathname.new(__FILE__).dirname + 'spec/**/*_spec.rb')
|
44
|
+
|
45
|
+
begin
|
46
|
+
t.rcov = ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true
|
47
|
+
t.rcov_opts << '--exclude' << 'spec'
|
48
|
+
t.rcov_opts << '--text-summary'
|
49
|
+
t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
|
50
|
+
rescue Exception
|
51
|
+
puts 'rcov is not installed. Please install before continuing'
|
52
|
+
exit
|
53
|
+
end
|
54
|
+
end
|
data/lib/dm-is-slug.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# Needed to import datamapper and other gems
|
2
|
+
require 'rubygems'
|
3
|
+
require 'pathname'
|
4
|
+
require 'iconv'
|
5
|
+
|
6
|
+
# Add all external dependencies for the plugin here
|
7
|
+
gem 'dm-core', '~>0.9.9'
|
8
|
+
require 'dm-core'
|
9
|
+
|
10
|
+
require Pathname(__FILE__).dirname.expand_path / 'dm-is-slug' / 'is' / 'version.rb'
|
11
|
+
|
12
|
+
# Require plugin-files
|
13
|
+
require Pathname(__FILE__).dirname.expand_path / 'dm-is-slug' / 'is' / 'slug.rb'
|
14
|
+
|
15
|
+
# Include the plugin in Resource
|
16
|
+
module DataMapper
|
17
|
+
module Resource
|
18
|
+
module ClassMethods
|
19
|
+
include DataMapper::Is::Slug
|
20
|
+
end # module ClassMethods
|
21
|
+
end # module Resource
|
22
|
+
end # module DataMapper
|
23
|
+
|
24
|
+
# Include DataMapper::Model#get and DataMapper::Collection#get override
|
25
|
+
# So we do user.posts.get("my-shinny-new-post")
|
26
|
+
|
27
|
+
module DataMapper
|
28
|
+
module Model
|
29
|
+
include DataMapper::Is::Slug::AliasMethods
|
30
|
+
end
|
31
|
+
|
32
|
+
class Collection
|
33
|
+
include DataMapper::Is::Slug::AliasMethods
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,164 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Is
|
3
|
+
module Slug
|
4
|
+
DEFAULT_SLUG_SIZE = 50
|
5
|
+
|
6
|
+
# @param [String] str A string to escape for use as a slug
|
7
|
+
# @return [String] an URL-safe string
|
8
|
+
def self.escape(str)
|
9
|
+
s = Iconv.conv('ascii//translit//IGNORE', 'utf-8', str)
|
10
|
+
s.gsub!(/\W+/, ' ')
|
11
|
+
s.strip!
|
12
|
+
s.downcase!
|
13
|
+
s.gsub!(/\ +/, '-')
|
14
|
+
s
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Methods that should be included in DataMapper::Model.
|
19
|
+
# Normally this should just be your generator, so that the namespace
|
20
|
+
# does not get cluttered. ClassMethods and InstanceMethods gets added
|
21
|
+
# in the specific resources when you fire is :slug
|
22
|
+
##
|
23
|
+
|
24
|
+
# Defines a +slug+ property on your model with the same size as your
|
25
|
+
# source property. This property is Unicode escaped, and treated so as
|
26
|
+
# to be fit for use in URLs.
|
27
|
+
#
|
28
|
+
# ==== Example
|
29
|
+
# Suppose your source attribute was the following string: "Hot deals on
|
30
|
+
# Boxing Day". This string would be escaped to "hot-deals-on-boxing-day".
|
31
|
+
#
|
32
|
+
# Non-ASCII characters are attempted to be converted to their nearest
|
33
|
+
# approximate.
|
34
|
+
#
|
35
|
+
# ==== Parameters
|
36
|
+
# +permanent_slug+::
|
37
|
+
# Permanent slugs are not changed even if the source property has
|
38
|
+
# +source+::
|
39
|
+
# The property on the model to use as the source of the generated slug
|
40
|
+
# +size+::
|
41
|
+
# The length of the +slug+ property
|
42
|
+
#
|
43
|
+
# @param [Hash] provide options in a Hash. See *Parameters* for details
|
44
|
+
def is_slug(options)
|
45
|
+
extend DataMapper::Is::Slug::ClassMethods
|
46
|
+
include DataMapper::Is::Slug::InstanceMethods
|
47
|
+
|
48
|
+
# merge in default options
|
49
|
+
options = { :permanent_slug => true }.merge(options)
|
50
|
+
|
51
|
+
# must at least specify a source property to generate the slug
|
52
|
+
# raise 'You must specify a :source to generate slug' unless options.include?(:source)
|
53
|
+
raise 'You must specify a :source to generate slug' unless options[:source]
|
54
|
+
|
55
|
+
# make sure the source property exsists
|
56
|
+
source_property = properties.detect do |p|
|
57
|
+
p.name == options[:source].to_sym && p.type == String
|
58
|
+
end
|
59
|
+
|
60
|
+
# Find the string length so that slug can adapt size dynamically
|
61
|
+
# depending on the source property, or use the default slug size.
|
62
|
+
options[:size] ||= source_property &&
|
63
|
+
source_property.size ||
|
64
|
+
DataMapper::Is::Slug::DEFAULT_SLUG_SIZE
|
65
|
+
|
66
|
+
# save as class variable for later...
|
67
|
+
@slug_options = options
|
68
|
+
|
69
|
+
unless slug_property
|
70
|
+
property :slug, String, :size => options[:size], :unique => true
|
71
|
+
end
|
72
|
+
|
73
|
+
before :save, :generate_slug
|
74
|
+
end
|
75
|
+
|
76
|
+
module ClassMethods
|
77
|
+
attr_reader :slug_options
|
78
|
+
|
79
|
+
def permanent_slug?
|
80
|
+
slug_options[:permanent_slug]
|
81
|
+
end
|
82
|
+
|
83
|
+
def slug_source
|
84
|
+
slug_options[:source].to_sym
|
85
|
+
end
|
86
|
+
|
87
|
+
def slug_source_property
|
88
|
+
detect_slug_property_by_name(slug_source)
|
89
|
+
end
|
90
|
+
|
91
|
+
def slug_property
|
92
|
+
detect_slug_property_by_name(:slug)
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def detect_slug_property_by_name(name)
|
98
|
+
properties.detect do |p|
|
99
|
+
p.name == name && p.type == String
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end # ClassMethods
|
103
|
+
|
104
|
+
module InstanceMethods
|
105
|
+
def to_param
|
106
|
+
[slug]
|
107
|
+
end
|
108
|
+
|
109
|
+
def permanent_slug?
|
110
|
+
self.class.permanent_slug?
|
111
|
+
end
|
112
|
+
|
113
|
+
def slug_source
|
114
|
+
self.class.slug_source
|
115
|
+
end
|
116
|
+
|
117
|
+
def slug_source_property
|
118
|
+
self.class.slug_source_property
|
119
|
+
end
|
120
|
+
|
121
|
+
def slug_property
|
122
|
+
self.class.slug_property
|
123
|
+
end
|
124
|
+
|
125
|
+
def generate_slug
|
126
|
+
source = self.send(slug_source)
|
127
|
+
|
128
|
+
raise ':source is invalid!' unless slug_source_property || self.respond_to?(slug_source)
|
129
|
+
|
130
|
+
return if permanent_slug? && self.slug || source.nil?
|
131
|
+
|
132
|
+
# we turn the source into a slug here
|
133
|
+
self.slug = DataMapper::Is::Slug.escape(source)
|
134
|
+
|
135
|
+
self.slug = "#{self.slug}-2" if self.class.first(:slug => self.slug)
|
136
|
+
|
137
|
+
while self.class.first(:slug => self.slug) != nil
|
138
|
+
i = self.slug[-1..-1].to_i + 1
|
139
|
+
self.slug = self.slug[0..-2] + i.to_s
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end # InstanceMethods
|
143
|
+
|
144
|
+
module AliasMethods
|
145
|
+
# override the old get method so that it looks for slugs first
|
146
|
+
# and call the old get if slug is not found
|
147
|
+
def get_with_slug(*key)
|
148
|
+
if respond_to?(:slug_options) && slug_options && key[0].to_s.to_i.to_s != key[0].to_s
|
149
|
+
first(:slug => key[0])
|
150
|
+
else
|
151
|
+
get_without_slug(*key)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
##
|
156
|
+
# fired when your plugin gets included into Resource
|
157
|
+
def self.included(base)
|
158
|
+
base.send :alias_method, :get_without_slug, :get
|
159
|
+
base.send :alias_method, :get, :get_with_slug
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end # Slug
|
163
|
+
end # Is
|
164
|
+
end # DataMapper
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
|
3
|
+
|
4
|
+
if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
|
5
|
+
describe 'DataMapper::Is::Slug' do
|
6
|
+
|
7
|
+
class User
|
8
|
+
include DataMapper::Resource
|
9
|
+
|
10
|
+
property :id, Serial
|
11
|
+
property :email, String
|
12
|
+
has n, :posts
|
13
|
+
has n, :todos
|
14
|
+
|
15
|
+
def slug_for_email
|
16
|
+
email.split("@").first
|
17
|
+
end
|
18
|
+
|
19
|
+
is :slug, :source => :slug_for_email, :size => 80, :permanent_slug => false
|
20
|
+
end
|
21
|
+
|
22
|
+
class Post
|
23
|
+
include DataMapper::Resource
|
24
|
+
|
25
|
+
property :id, Serial
|
26
|
+
property :title, String, :size => 2000
|
27
|
+
property :content, Text
|
28
|
+
|
29
|
+
belongs_to :user
|
30
|
+
|
31
|
+
is :slug, :source => :title
|
32
|
+
end
|
33
|
+
|
34
|
+
class Todo
|
35
|
+
include DataMapper::Resource
|
36
|
+
property :id, Serial
|
37
|
+
property :title, String
|
38
|
+
|
39
|
+
belongs_to :user
|
40
|
+
end
|
41
|
+
|
42
|
+
before :all do
|
43
|
+
User.auto_migrate!(:default)
|
44
|
+
Post.auto_migrate!(:default)
|
45
|
+
Todo.auto_migrate!(:default)
|
46
|
+
|
47
|
+
@u1 = User.create(:email => "john@ekohe.com")
|
48
|
+
@p1 = Post.create(:user => @u1, :title => "My first shinny blog post")
|
49
|
+
@p2 = Post.create(:user => @u1, :title => "My second shinny blog post")
|
50
|
+
@p3 = Post.create(:user => @u1, :title => "My third shinny blog post")
|
51
|
+
|
52
|
+
@u2 = User.create(:email => "john@someotherplace.com")
|
53
|
+
@p4 = Post.create(:user => @u2, :title => "My first Shinny blog post")
|
54
|
+
@p5 = Post.create(:user => @u2, :title => "i heart merb and dm")
|
55
|
+
@p6 = Post.create(:user => @u2, :title => "another productive day!!")
|
56
|
+
@p7 = Post.create(:user => @u2, :title => "another productive day!!")
|
57
|
+
@p8 = Post.create(:user => @u2, :title => "another productive day!!")
|
58
|
+
@p9 = Post.create(:user => @u2, :title => "another productive day!!")
|
59
|
+
@p10 = Post.create(:user => @u2, :title => "another productive day!!")
|
60
|
+
@p11 = Post.create(:user => @u2, :title => "another productive day!!")
|
61
|
+
@p12 = Post.create(:user => @u2, :title => "another productive day!!")
|
62
|
+
@p13 = Post.create(:user => @u2, :title => "another productive day!!")
|
63
|
+
@p14 = Post.create(:user => @u2, :title => "another productive day!!")
|
64
|
+
@p15 = Post.create(:user => @u2, :title => "another productive day!!")
|
65
|
+
@p16 = Post.create(:user => @u2, :title => "another productive day!!")
|
66
|
+
@p17 = Post.create(:user => @u2, :title => "A fancy café")
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should generate slugs" do
|
70
|
+
User.all.each do |u|
|
71
|
+
u.slug.should_not be_nil
|
72
|
+
end
|
73
|
+
|
74
|
+
Post.all.each do |p|
|
75
|
+
p.slug.should_not be_nil
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should generate unique slugs" do
|
80
|
+
@u1.slug.should_not == @u2.slug
|
81
|
+
@p1.slug.should_not == @p4.slug
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should generate correct slug for user" do
|
85
|
+
@u1.slug.should == "john"
|
86
|
+
@u2.slug.should == "john-2"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should generate correct slug for post" do
|
90
|
+
@p1.slug.should == "my-first-shinny-blog-post"
|
91
|
+
@p2.slug.should == "my-second-shinny-blog-post"
|
92
|
+
@p3.slug.should == "my-third-shinny-blog-post"
|
93
|
+
@p4.slug.should == "my-first-shinny-blog-post-2"
|
94
|
+
@p5.slug.should == "i-heart-merb-and-dm"
|
95
|
+
@p6.slug.should == "another-productive-day"
|
96
|
+
@p7.slug.should == "another-productive-day-2"
|
97
|
+
@p8.slug.should == "another-productive-day-3"
|
98
|
+
@p9.slug.should == "another-productive-day-4"
|
99
|
+
@p10.slug.should == "another-productive-day-5"
|
100
|
+
@p11.slug.should == "another-productive-day-6"
|
101
|
+
@p12.slug.should == "another-productive-day-7"
|
102
|
+
@p13.slug.should == "another-productive-day-8"
|
103
|
+
@p14.slug.should == "another-productive-day-9"
|
104
|
+
@p15.slug.should == "another-productive-day-10"
|
105
|
+
@p16.slug.should == "another-productive-day-11"
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should update slug if :permanent_slug => :false is specified" do
|
109
|
+
user = User.create(:email => "a_person@ekohe.com")
|
110
|
+
user.slug.should == "a_person"
|
111
|
+
|
112
|
+
user.should_not be_permanent_slug
|
113
|
+
|
114
|
+
user.email = "changed@ekohe.com"
|
115
|
+
user.should be_dirty
|
116
|
+
user.save.should be_true
|
117
|
+
user.slug.should == "changed"
|
118
|
+
user.destroy
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should not update slug if :permanent_slug => :true or not specified" do
|
122
|
+
post = Post.create(:user => @u1, :title => "hello world!")
|
123
|
+
post.slug.should == "hello-world"
|
124
|
+
post.should be_permanent_slug
|
125
|
+
post.title = "hello universe!"
|
126
|
+
post.should be_dirty
|
127
|
+
post.save.should be_true
|
128
|
+
post.slug.should == "hello-world"
|
129
|
+
post.destroy
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should have the right size for properties" do
|
133
|
+
user_slug_property = User.properties.detect{|p| p.name == :slug && p.type == String}
|
134
|
+
user_slug_property.should_not be_nil
|
135
|
+
user_slug_property.size.should == 80
|
136
|
+
|
137
|
+
Post.properties.detect{|p| p.name == :title && p.type == String}.size.should == 2000
|
138
|
+
post_slug_property = Post.properties.detect{|p| p.name == :slug && p.type == String}
|
139
|
+
post_slug_property.should_not be_nil
|
140
|
+
post_slug_property.size.should == 2000
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should find model using get method with slug" do
|
144
|
+
u = User.get("john")
|
145
|
+
u.should_not be_nil
|
146
|
+
u.should == @u1
|
147
|
+
|
148
|
+
Post.get("my-first-shinny-blog-post").should == @p1
|
149
|
+
@u1.posts.get("my-first-shinny-blog-post").should == @p1
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should output slug with to_param method" do
|
153
|
+
@u1.to_param.should == ["john"]
|
154
|
+
@p1.to_param.should == ["my-first-shinny-blog-post"]
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should find model using get method using id" do
|
158
|
+
u = User.get(@u1.id)
|
159
|
+
u.should_not be_nil
|
160
|
+
u.should == @u1
|
161
|
+
|
162
|
+
Post.get("my-first-shinny-blog-post").should == @p1
|
163
|
+
@u1.posts.get("my-first-shinny-blog-post").should == @p1
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should find model using get method using id with non-slug models" do
|
167
|
+
todo = Todo.create(:user => @u1, :title => "blabla")
|
168
|
+
todo.should_not be_nil
|
169
|
+
|
170
|
+
Todo.get(todo.id).should == todo
|
171
|
+
@u1.todos.get(todo.id).should == todo
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'should strip unicode characters from the slug' do
|
175
|
+
@p17.slug.should == 'a-fancy-caf-e'
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'should have slug_property on instance' do
|
179
|
+
@p1.slug_property.should == @p1.class.properties.detect{|p| p.name == :slug}
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'rspec', '~>1.1.3'
|
3
|
+
require 'spec'
|
4
|
+
require 'pathname'
|
5
|
+
require Pathname(__FILE__).dirname.expand_path.parent + 'lib/dm-is-slug'
|
6
|
+
|
7
|
+
def load_driver(name, default_uri)
|
8
|
+
return false if ENV['ADAPTER'] != name.to_s
|
9
|
+
|
10
|
+
lib = "do_#{name}"
|
11
|
+
|
12
|
+
begin
|
13
|
+
gem lib, '~>0.9.7'
|
14
|
+
require lib
|
15
|
+
DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
|
16
|
+
DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
|
17
|
+
true
|
18
|
+
rescue Gem::LoadError => e
|
19
|
+
warn "Could not load #{lib}: #{e}"
|
20
|
+
false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
ENV['ADAPTER'] ||= 'sqlite3'
|
25
|
+
|
26
|
+
HAS_SQLITE3 = load_driver(:sqlite3, 'sqlite3::memory:')
|
27
|
+
HAS_MYSQL = load_driver(:mysql, 'mysql://localhost/dm_core_test')
|
28
|
+
HAS_POSTGRES = load_driver(:postgres, 'postgres://postgres@localhost/dm_core_test')
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aq1018-dm-is-slug
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.9
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aaron Qian, Nik Radford
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-12 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: dm-core
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0.9"
|
23
|
+
version:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: hoe
|
26
|
+
version_requirement:
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ">="
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 1.8.2
|
32
|
+
version:
|
33
|
+
description: DataMapper plugin that generates unique permalinks / slugs
|
34
|
+
email:
|
35
|
+
- aaron [a] ekohe [d] com; nik [a] terminaldischarge [d] net
|
36
|
+
executables: []
|
37
|
+
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files:
|
41
|
+
- History.txt
|
42
|
+
- Manifest.txt
|
43
|
+
- README.txt
|
44
|
+
files:
|
45
|
+
- History.txt
|
46
|
+
- LICENSE
|
47
|
+
- Manifest.txt
|
48
|
+
- README.txt
|
49
|
+
- Rakefile
|
50
|
+
- TODO
|
51
|
+
- lib/dm-is-slug.rb
|
52
|
+
- lib/dm-is-slug/is/slug.rb
|
53
|
+
- lib/dm-is-slug/is/version.rb
|
54
|
+
- spec/integration/slug_spec.rb
|
55
|
+
- spec/spec.opts
|
56
|
+
- spec/spec_helper.rb
|
57
|
+
has_rdoc: false
|
58
|
+
homepage: http://github.com/aq1018/dm-is-slug
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options:
|
61
|
+
- --main
|
62
|
+
- README.txt
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "0"
|
76
|
+
version:
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project: dm-is-slug
|
80
|
+
rubygems_version: 1.2.0
|
81
|
+
signing_key:
|
82
|
+
specification_version: 2
|
83
|
+
summary: DataMapper plugin that generates unique permalinks / slugs
|
84
|
+
test_files: []
|
85
|
+
|