dm-is-slug 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ pkg
2
+ coverage
3
+ tmp
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.
@@ -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")
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ gem 'jeweler', '~> 1.4'
6
+ require 'jeweler'
7
+
8
+ Jeweler::Tasks.new do |gem|
9
+ gem.name = "dm-is-slug"
10
+ gem.summary = "DataMapper plugin that generates unique slugs"
11
+ gem.description = gem.summary
12
+ gem.email = [
13
+ 'aq1018@gmail.com',
14
+ 'james.herdman@gmail.com',
15
+ 'nik [a] terminaldischarge [d] net',
16
+ 'maverick.stoklosa@gmail.com',
17
+ 'frawl021@gmail.com',
18
+ 'cheba@pointlessone.org'
19
+ ]
20
+ gem.homepage = "http://github.com/aq1018/dm-is-slug"
21
+ gem.authors = ['Aaron Qian', 'James Herdman', 'Nik Radford', 'Paul', 'Mike Frawley', 'Alex Makuta']
22
+ gem.add_dependency "dm-core", "~>0.10.2"
23
+ gem.add_dependency "unidecode", "~>1.0.0"
24
+ gem.add_development_dependency 'rspec', '~> 1.3'
25
+ end
26
+
27
+ Jeweler::GemcutterTasks.new
28
+
29
+ FileList['tasks/**/*.rake'].each { |task| import task }
30
+ rescue LoadError
31
+ puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler'
32
+ end
data/TODO ADDED
@@ -0,0 +1,4 @@
1
+ TODO
2
+ ====
3
+
4
+ Docs??
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.10.2
@@ -0,0 +1,69 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{dm-is-slug}
8
+ s.version = "0.10.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Aaron Qian", "James Herdman", "Nik Radford", "Paul", "Mike Frawley", "Alex Makuta"]
12
+ s.date = %q{2010-02-07}
13
+ s.description = %q{DataMapper plugin that generates unique slugs}
14
+ s.email = ["aq1018@gmail.com", "james.herdman@gmail.com", "nik [a] terminaldischarge [d] net", "maverick.stoklosa@gmail.com", "frawl021@gmail.com", "cheba@pointlessone.org"]
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.textile",
18
+ "TODO"
19
+ ]
20
+ s.files = [
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.textile",
24
+ "Rakefile",
25
+ "TODO",
26
+ "VERSION",
27
+ "dm-is-slug.gemspec",
28
+ "lib/dm-is-slug.rb",
29
+ "lib/dm-is-slug/is/slug.rb",
30
+ "spec/integration/slug_spec.rb",
31
+ "spec/rcov.opts",
32
+ "spec/spec.opts",
33
+ "spec/spec_helper.rb",
34
+ "tasks/ci.rake",
35
+ "tasks/metrics.rake",
36
+ "tasks/spec.rake",
37
+ "tasks/yard.rake",
38
+ "tasks/yardstick.rake"
39
+ ]
40
+ s.homepage = %q{http://github.com/aq1018/dm-is-slug}
41
+ s.rdoc_options = ["--charset=UTF-8"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = %q{1.3.5}
44
+ s.summary = %q{DataMapper plugin that generates unique slugs}
45
+ s.test_files = [
46
+ "spec/integration/slug_spec.rb",
47
+ "spec/spec_helper.rb"
48
+ ]
49
+
50
+ if s.respond_to? :specification_version then
51
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
52
+ s.specification_version = 3
53
+
54
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
55
+ s.add_runtime_dependency(%q<dm-core>, ["~> 0.10.2"])
56
+ s.add_runtime_dependency(%q<unidecode>, ["~> 1.0.0"])
57
+ s.add_development_dependency(%q<rspec>, ["~> 1.3"])
58
+ else
59
+ s.add_dependency(%q<dm-core>, ["~> 0.10.2"])
60
+ s.add_dependency(%q<unidecode>, ["~> 1.0.0"])
61
+ s.add_dependency(%q<rspec>, ["~> 1.3"])
62
+ end
63
+ else
64
+ s.add_dependency(%q<dm-core>, ["~> 0.10.2"])
65
+ s.add_dependency(%q<unidecode>, ["~> 1.0.0"])
66
+ s.add_dependency(%q<rspec>, ["~> 1.3"])
67
+ end
68
+ end
69
+
@@ -0,0 +1,7 @@
1
+ require 'pathname'
2
+ require 'dm-core'
3
+
4
+ # Require plugin-files
5
+ require Pathname(__FILE__).dirname.expand_path / 'dm-is-slug' / 'is' / 'slug.rb'
6
+
7
+ DataMapper::Model.append_extensions DataMapper::Is::Slug
@@ -0,0 +1,185 @@
1
+ require 'unidecode'
2
+ require 'dm-core/support/chainable'
3
+
4
+ module DataMapper
5
+ module Is
6
+ module Slug
7
+ class InvalidSlugSourceError < StandardError; end
8
+
9
+ # @param [String] str A string to escape for use as a slug
10
+ # @return [String] an URL-safe string
11
+ def self.escape(str)
12
+ s = str.to_ascii
13
+ s.gsub!(/\W+/, ' ')
14
+ s.strip!
15
+ s.downcase!
16
+ s.gsub!(/\ +/, '-')
17
+ s
18
+ end
19
+
20
+ ##
21
+ # Methods that should be included in DataMapper::Model.
22
+ # Normally this should just be your generator, so that the namespace
23
+ # does not get cluttered. ClassMethods and InstanceMethods gets added
24
+ # in the specific resources when you fire is :slug
25
+ ##
26
+
27
+ # Defines a +slug+ property on your model with the same length as your
28
+ # source property. This property is Unicode escaped, and treated so as
29
+ # to be fit for use in URLs.
30
+ #
31
+ # ==== Example
32
+ # Suppose your source attribute was the following string: "Hot deals on
33
+ # Boxing Day". This string would be escaped to "hot-deals-on-boxing-day".
34
+ #
35
+ # Non-ASCII characters are attempted to be converted to their nearest
36
+ # approximate.
37
+ #
38
+ # ==== Parameters
39
+ # +permanent_slug+::
40
+ # Permanent slugs are not changed even if the source property has
41
+ # +source+::
42
+ # The property on the model to use as the source of the generated slug,
43
+ # or an instance method defined in the model, the method must return
44
+ # a string or nil.
45
+ # +length+::
46
+ # The length of the +slug+ property
47
+ #
48
+ # @param [Hash] provide options in a Hash. See *Parameters* for details
49
+ def is_slug(options)
50
+ if options.key?(:size)
51
+ warn "Slug with :size option is deprecated, use :length instead"
52
+ options[:length] = options.delete(:size)
53
+ end
54
+
55
+ extend DataMapper::Is::Slug::ClassMethods
56
+ include DataMapper::Is::Slug::InstanceMethods
57
+ extend Chainable
58
+
59
+ @slug_options = {}
60
+
61
+ @slug_options[:permanent_slug] = options.delete(:permanent_slug)
62
+ @slug_options[:permanent_slug] = true if @slug_options[:permanent_slug].nil?
63
+
64
+ @slug_options[:source] = options.delete(:source)
65
+ raise InvalidSlugSourceError, 'You must specify a :source to generate slug.' unless slug_source
66
+
67
+
68
+ options[:length] ||= get_slug_length
69
+ property(:slug, String, options.merge(:unique => true)) unless slug_property
70
+
71
+ before :valid?, :generate_slug
72
+ before :save, :generate_slug
73
+ end
74
+
75
+ module ClassMethods
76
+ attr_reader :slug_options
77
+
78
+ def permanent_slug?
79
+ slug_options[:permanent_slug]
80
+ end
81
+
82
+ def slug_source
83
+ slug_options[:source] ? slug_options[:source].to_sym : nil
84
+ end
85
+
86
+ def slug_source_property
87
+ detect_slug_property_by_name(slug_source)
88
+ end
89
+
90
+ def slug_property
91
+ detect_slug_property_by_name(:slug)
92
+ end
93
+
94
+ private
95
+
96
+ def detect_slug_property_by_name(name)
97
+ p = properties[name]
98
+ !p.nil? && p.type == String ? p : nil
99
+ end
100
+
101
+ def get_slug_length
102
+ slug_property.nil? ? (slug_source_property.nil? ? DataMapper::Property::DEFAULT_LENGTH : slug_source_property.length) : slug_property.length
103
+ end
104
+ end # ClassMethods
105
+
106
+ module InstanceMethods
107
+ def to_param
108
+ [slug]
109
+ end
110
+
111
+ def permanent_slug?
112
+ self.class.permanent_slug?
113
+ end
114
+
115
+ def slug_source
116
+ self.class.slug_source
117
+ end
118
+
119
+ def slug_source_property
120
+ self.class.slug_source_property
121
+ end
122
+
123
+ def slug_property
124
+ self.class.slug_property
125
+ end
126
+
127
+ def slug_source_value
128
+ self.send(slug_source)
129
+ end
130
+
131
+ # The slug is not stale if
132
+ # 1. the slug is permanent, and slug column has something valid in it
133
+ # 2. the slug source value is nil or empty
134
+ def stale_slug?
135
+ !((permanent_slug? && slug && !slug.empty?) || (slug_source_value.nil? || slug_source_value.empty?))
136
+ end
137
+
138
+ private
139
+
140
+ def generate_slug
141
+ #puts "\nGenerating slug for #{self.class.name}: #{self.key.inspect}\n"
142
+ return unless self.class.respond_to?(:slug_options) && self.class.slug_options
143
+ raise InvalidSlugSourceError, 'Invalid slug source.' unless slug_source_property || self.respond_to?(slug_source)
144
+ return unless stale_slug?
145
+ attribute_set :slug, unique_slug
146
+ end
147
+
148
+ def unique_slug
149
+ old_slug = self.slug
150
+ max_length = self.class.send(:get_slug_length)
151
+ base_slug = ::DataMapper::Is::Slug.escape(slug_source_value)[0, max_length]
152
+ i = 1
153
+ new_slug = base_slug
154
+
155
+ if old_slug != new_slug
156
+ not_self_conditions = {}
157
+ unless new?
158
+ self.model.key.each do |property|
159
+ not_self_conditions.merge!(property.name.not => self.send(property.name))
160
+ end
161
+ #puts "Not self: #{not_self_conditions.inspect}"
162
+ end
163
+
164
+ lambda do
165
+ #puts "Lambda new slug: #{new_slug}"
166
+ dupe = self.class.first(not_self_conditions.merge(:slug => new_slug))
167
+ if dupe
168
+ #puts "Got dupe: #{dupe.inspect}"
169
+ i = i + 1
170
+ slug_length = max_length - i.to_s.length - 1
171
+ new_slug = "#{base_slug[0, slug_length]}-#{i}"
172
+ #puts "New slug: #{new_slug}"
173
+ redo
174
+ end
175
+ end.call
176
+ #puts "Found new slug: #{new_slug}"
177
+ new_slug
178
+ else
179
+ old_slug
180
+ end
181
+ end
182
+ end # InstanceMethods
183
+ end # Slug
184
+ end # Is
185
+ end # DataMapper
@@ -0,0 +1,269 @@
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, :length => 80, :permanent_slug => false
20
+ end
21
+
22
+ class Post
23
+ include DataMapper::Resource
24
+
25
+ property :id, Serial
26
+ property :title, String, :length => 30
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
+ class SlugKey
43
+ include DataMapper::Resource
44
+ property :title, String
45
+
46
+ is :slug, :source => :title, :key => true
47
+ end
48
+
49
+ before :all do
50
+ User.auto_migrate!(:default)
51
+ Post.auto_migrate!(:default)
52
+ Todo.auto_migrate!(:default)
53
+ SlugKey.auto_migrate!(:default)
54
+
55
+ @u1 = User.create(:email => "john@ekohe.com")
56
+ @p1 = Post.create(:user => @u1, :title => "My first shinny blog post")
57
+ @p2 = Post.create(:user => @u1, :title => "My second shinny blog post")
58
+ @p3 = Post.create(:user => @u1, :title => "My third shinny blog post")
59
+
60
+ @u2 = User.create(:email => "john@someotherplace.com")
61
+ @p4 = Post.create(:user => @u2, :title => "My first Shinny blog post")
62
+ @p5 = Post.create(:user => @u2, :title => "i heart merb and dm")
63
+ @p6 = Post.create(:user => @u2, :title => "A fancy café")
64
+ @p7 = Post.create(:user => @u2, :title => "你好")
65
+
66
+ (1..10).each do |i|
67
+ instance_variable_set "@p1_#{i}".to_sym, Post.create(:user => @u2, :title => "another productive day!!")
68
+ end
69
+ (1..10).each do |i|
70
+ instance_variable_set "@p2_#{i}".to_sym, Post.create(:user => @u2, :title => "DM tricks")
71
+ end
72
+
73
+ @sk = SlugKey.create(:title => 'slug key')
74
+
75
+ @post1 = Post.create :user => @u1, :title => 'a' * Post.slug_property.length
76
+ @post2 = Post.create :user => @u1, :title => 'a' * Post.slug_property.length
77
+ end
78
+
79
+ it "should raise error if :source option is not specified" do
80
+ lambda {
81
+ class BadUsage
82
+ include DataMapper::Resource
83
+
84
+ property :id, Serial
85
+
86
+ is :slug, {}
87
+ end
88
+ }.should raise_error(DataMapper::Is::Slug::InvalidSlugSourceError)
89
+ end
90
+
91
+ it "should display obsolete warning if :size option is used" do
92
+ class Thingy
93
+ end
94
+ Thingy.stub!(:warn)
95
+ Thingy.should_receive(:warn).with("Slug with :size option is deprecated, use :length instead")
96
+
97
+ lambda {
98
+ class Thingy
99
+ include DataMapper::Resource
100
+ property :title, String
101
+
102
+ is :slug, :source => :title, :size => 20
103
+ end
104
+ }.should_not raise_error
105
+
106
+ end
107
+
108
+ it "should generate slugs" do
109
+ User.all.each do |u|
110
+ u.slug.should_not be_nil
111
+ end
112
+
113
+ Post.all.each do |p|
114
+ p.slug.should_not be_nil
115
+ end
116
+ end
117
+
118
+ it "should generate unique slugs" do
119
+ @u1.slug.should_not == @u2.slug
120
+ @p1.slug.should_not == @p4.slug
121
+ end
122
+
123
+ it "should generate correct slug for user" do
124
+ @u1.slug.should == "john"
125
+ @u2.slug.should == "john-2"
126
+ end
127
+
128
+ it "should generate correct slug for post" do
129
+ @p1.slug.should == "my-first-shinny-blog-post"
130
+ @p2.slug.should == "my-second-shinny-blog-post"
131
+ @p3.slug.should == "my-third-shinny-blog-post"
132
+ @p4.slug.should == "my-first-shinny-blog-post-2"
133
+ @p5.slug.should == "i-heart-merb-and-dm"
134
+
135
+ @p1_1.slug.should == "another-productive-day"
136
+ (2..10).each do |i|
137
+ instance_variable_get("@p1_#{i}".to_sym).slug.should == "another-productive-day-#{i}"
138
+ end
139
+
140
+ @p2_1.slug.should == 'dm-tricks'
141
+ (2..10).each do |i|
142
+ instance_variable_get("@p2_#{i}".to_sym).slug.should == "dm-tricks-#{i}"
143
+ end
144
+ end
145
+
146
+ it "should update slug if :permanent_slug => :false is specified" do
147
+ user = User.create(:email => "a_person@ekohe.com")
148
+ user.slug.should == "a_person"
149
+
150
+ user.should_not be_permanent_slug
151
+
152
+ user.email = "changed@ekohe.com"
153
+ user.should be_dirty
154
+
155
+ user.save.should be_true
156
+ user.slug.should == "changed"
157
+ user.destroy
158
+ end
159
+
160
+ it "should not update slug if :permanent_slug => :true or not specified" do
161
+ post = Post.create(:user => @u1, :title => "hello world!")
162
+ post.slug.should == "hello-world"
163
+ post.should be_permanent_slug
164
+ post.title = "hello universe!"
165
+ post.should be_dirty
166
+ post.save.should be_true
167
+ post.slug.should == "hello-world"
168
+ post.destroy
169
+ end
170
+
171
+ it "should have the right size for properties" do
172
+ user_slug_property = User.properties[:slug]
173
+ user_slug_property.should_not be_nil
174
+ user_slug_property.type.should == String
175
+ user_slug_property.length.should == 80
176
+
177
+ post_title_property = Post.properties[:title]
178
+ post_title_property.type.should == String
179
+ post_title_property.length.should == 30
180
+
181
+ post_slug_property = Post.properties[:slug]
182
+ post_slug_property.type.should == String
183
+ post_slug_property.should_not be_nil
184
+ post_slug_property.length.should == 30
185
+ end
186
+
187
+ it "should output slug with to_param method" do
188
+ @u1.to_param.should == ["john"]
189
+ @p1.to_param.should == ["my-first-shinny-blog-post"]
190
+ end
191
+
192
+ it "should find model using get method using id" do
193
+ u = User.get(@u1.id)
194
+ u.should_not be_nil
195
+ u.should == @u1
196
+ end
197
+
198
+ it "should find model using get method using id with non-slug models" do
199
+ todo = Todo.create(:user => @u1, :title => "blabla")
200
+ todo.should_not be_nil
201
+
202
+ Todo.get(todo.id).should == todo
203
+ @u1.todos.get(todo.id).should == todo
204
+ end
205
+
206
+ it 'should unidecode latin characters from the slug' do
207
+ @p6.slug.should == 'a-fancy-cafe'
208
+ end
209
+
210
+ it 'should unidecode chinese characters from the slug' do
211
+ @p7.slug.should == 'ni-hao'
212
+ end
213
+
214
+ it 'should have slug_property on instance' do
215
+ @p1.slug_property.should == @p1.class.properties.detect{|p| p.name == :slug}
216
+ end
217
+
218
+ it 'should properly increment slug suffix' do
219
+ @p2_10.slug.should == 'dm-tricks-10'
220
+ end
221
+
222
+ it 'should work with key on slug and validations' do
223
+ @sk.title.should == 'slug key'
224
+ @sk.slug.should == 'slug-key'
225
+ end
226
+
227
+ it 'should have slug no longer than slug_property.length' do
228
+ @post1.slug.length.should == @post1.slug_property.length
229
+ end
230
+
231
+ it 'should have suffixed slug no longer than slug_property.length' do
232
+ @post2.slug.length.should == @post2.class.slug_property.length
233
+ end
234
+
235
+ it 'should generate right slug for long sources' do
236
+ @post1.slug.should == 'a' * @post1.class.slug_property.length
237
+ @post2.slug.should == ('a' * (@post2.class.slug_property.length - 2) + '-2')
238
+ end
239
+
240
+ describe 'editing' do
241
+ class Post2
242
+ include DataMapper::Resource
243
+ property :id, Serial
244
+ property :title, String, :length => 30
245
+ property :content, Text
246
+
247
+ is :slug, :source => :title, :permanent_slug => false
248
+ end
249
+
250
+ Post2.auto_migrate!
251
+
252
+ before :each do
253
+ Post2.all.destroy!
254
+ @post = Post2.create :title => 'The Post', :content => 'The content.'
255
+ end
256
+
257
+ it 'should not change slug if source is not changed' do
258
+ @post.update :content => 'The other content.'
259
+ Post2.first.slug.should == 'the-post'
260
+ end
261
+
262
+ it 'should change slug if source is changed' do
263
+ @post.update :title => 'The Other Post'
264
+ post = Post2.first
265
+ post.slug.should == 'the-other-post'
266
+ end
267
+ end
268
+ end
269
+ end
@@ -0,0 +1,6 @@
1
+ --exclude "spec"
2
+ --sort coverage
3
+ --callsites
4
+ --xrefs
5
+ --profile
6
+ --text-summary
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --loadby random
3
+ --format profile
4
+ --backtrace
@@ -0,0 +1,38 @@
1
+ require 'rubygems'
2
+
3
+ # use local dm-core if running from a typical dev checkout.
4
+ lib = File.join('..', '..', 'dm-core', 'lib')
5
+ $LOAD_PATH.unshift(lib) if File.directory?(lib)
6
+ require 'dm-core'
7
+
8
+ # use local dm-adjust if running from a typical dev checkout.
9
+ lib = File.join('..', 'dm-adjust', 'lib')
10
+ $LOAD_PATH.unshift(lib) if File.directory?(lib)
11
+ require 'dm-adjust'
12
+
13
+ # Support running specs with 'rake spec' and 'spec'
14
+ $LOAD_PATH.unshift('lib') unless $LOAD_PATH.include?('lib')
15
+
16
+ require 'dm-validations'
17
+ require 'dm-is-slug'
18
+
19
+ def load_driver(name, default_uri)
20
+ return false if ENV['ADAPTER'] != name.to_s
21
+
22
+ begin
23
+ DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
24
+ DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
25
+ true
26
+ rescue LoadError => e
27
+ warn "Could not load do_#{name}: #{e}"
28
+ false
29
+ end
30
+ end
31
+
32
+ ENV['ADAPTER'] ||= 'sqlite3'
33
+
34
+ HAS_SQLITE3 = load_driver(:sqlite3, 'sqlite3::memory:')
35
+ HAS_MYSQL = load_driver(:mysql, 'mysql://localhost/dm_core_test')
36
+ HAS_POSTGRES = load_driver(:postgres, 'postgres://postgres@localhost/dm_core_test')
37
+
38
+
@@ -0,0 +1 @@
1
+ task :ci => [ :verify_measurements, 'metrics:all' ]
@@ -0,0 +1,36 @@
1
+ begin
2
+ require 'metric_fu'
3
+ rescue LoadError
4
+ namespace :metrics do
5
+ task :all do
6
+ abort 'metric_fu is not available. In order to run metrics:all, you must: gem install metric_fu'
7
+ end
8
+ end
9
+ end
10
+
11
+ begin
12
+ require 'reek/adapters/rake_task'
13
+
14
+ Reek::RakeTask.new do |t|
15
+ t.fail_on_error = true
16
+ t.verbose = false
17
+ t.source_files = 'lib/**/*.rb'
18
+ end
19
+ rescue LoadError
20
+ task :reek do
21
+ abort 'Reek is not available. In order to run reek, you must: gem install reek'
22
+ end
23
+ end
24
+
25
+ begin
26
+ require 'roodi'
27
+ require 'roodi_task'
28
+
29
+ RoodiTask.new do |t|
30
+ t.verbose = false
31
+ end
32
+ rescue LoadError
33
+ task :roodi do
34
+ abort 'Roodi is not available. In order to run roodi, you must: gem install roodi'
35
+ end
36
+ end
@@ -0,0 +1,41 @@
1
+ spec_defaults = lambda do |spec|
2
+ spec.pattern = 'spec/**/*_spec.rb'
3
+ spec.libs << 'lib' << 'spec'
4
+ spec.spec_opts << '--options' << 'spec/spec.opts'
5
+ end
6
+
7
+ begin
8
+ require 'spec/rake/spectask'
9
+
10
+ Spec::Rake::SpecTask.new(:spec, &spec_defaults)
11
+ rescue LoadError
12
+ task :spec do
13
+ abort 'rspec is not available. In order to run spec, you must: gem install rspec'
14
+ end
15
+ end
16
+
17
+ begin
18
+ require 'rcov'
19
+ require 'spec/rake/verify_rcov'
20
+
21
+ Spec::Rake::SpecTask.new(:rcov) do |rcov|
22
+ spec_defaults.call(rcov)
23
+ rcov.rcov = true
24
+ rcov.rcov_opts = File.read('spec/rcov.opts').split(/\s+/)
25
+ end
26
+
27
+ RCov::VerifyTask.new(:verify_rcov => :rcov) do |rcov|
28
+ rcov.threshold = 100
29
+ end
30
+ rescue LoadError
31
+ %w[ rcov verify_rcov ].each do |name|
32
+ task name do
33
+ abort "rcov is not available. In order to run #{name}, you must: gem install rcov"
34
+ end
35
+ end
36
+ end
37
+
38
+ task :spec => :check_dependencies
39
+ task :rcov => :check_dependencies
40
+
41
+ task :default => :spec
@@ -0,0 +1,9 @@
1
+ begin
2
+ require 'yard'
3
+
4
+ YARD::Rake::YardocTask.new
5
+ rescue LoadError
6
+ task :yard do
7
+ abort 'YARD is not available. In order to run yard, you must: gem install yard'
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ begin
2
+ require 'pathname'
3
+ require 'yardstick/rake/measurement'
4
+ require 'yardstick/rake/verify'
5
+
6
+ # yardstick_measure task
7
+ Yardstick::Rake::Measurement.new
8
+
9
+ # verify_measurements task
10
+ Yardstick::Rake::Verify.new do |verify|
11
+ verify.threshold = 100
12
+ end
13
+ rescue LoadError
14
+ %w[ yardstick_measure verify_measurements ].each do |name|
15
+ task name.to_s do
16
+ abort "Yardstick is not available. In order to run #{name}, you must: gem install yardstick"
17
+ end
18
+ end
19
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dm-is-slug
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.10.2
5
+ platform: ruby
6
+ authors:
7
+ - Aaron Qian
8
+ - James Herdman
9
+ - Nik Radford
10
+ - Paul
11
+ - Mike Frawley
12
+ - Alex Makuta
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-02-07 00:00:00 +08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: dm-core
22
+ type: :runtime
23
+ version_requirement:
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ version: 0.10.2
29
+ version:
30
+ - !ruby/object:Gem::Dependency
31
+ name: unidecode
32
+ type: :runtime
33
+ version_requirement:
34
+ version_requirements: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ~>
37
+ - !ruby/object:Gem::Version
38
+ version: 1.0.0
39
+ version:
40
+ - !ruby/object:Gem::Dependency
41
+ name: rspec
42
+ type: :development
43
+ version_requirement:
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: "1.3"
49
+ version:
50
+ description: DataMapper plugin that generates unique slugs
51
+ email:
52
+ - aq1018@gmail.com
53
+ - james.herdman@gmail.com
54
+ - nik [a] terminaldischarge [d] net
55
+ - maverick.stoklosa@gmail.com
56
+ - frawl021@gmail.com
57
+ - cheba@pointlessone.org
58
+ executables: []
59
+
60
+ extensions: []
61
+
62
+ extra_rdoc_files:
63
+ - LICENSE
64
+ - README.textile
65
+ - TODO
66
+ files:
67
+ - .gitignore
68
+ - LICENSE
69
+ - README.textile
70
+ - Rakefile
71
+ - TODO
72
+ - VERSION
73
+ - dm-is-slug.gemspec
74
+ - lib/dm-is-slug.rb
75
+ - lib/dm-is-slug/is/slug.rb
76
+ - spec/integration/slug_spec.rb
77
+ - spec/rcov.opts
78
+ - spec/spec.opts
79
+ - spec/spec_helper.rb
80
+ - tasks/ci.rake
81
+ - tasks/metrics.rake
82
+ - tasks/spec.rake
83
+ - tasks/yard.rake
84
+ - tasks/yardstick.rake
85
+ has_rdoc: true
86
+ homepage: http://github.com/aq1018/dm-is-slug
87
+ licenses: []
88
+
89
+ post_install_message:
90
+ rdoc_options:
91
+ - --charset=UTF-8
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: "0"
99
+ version:
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: "0"
105
+ version:
106
+ requirements: []
107
+
108
+ rubyforge_project:
109
+ rubygems_version: 1.3.5
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: DataMapper plugin that generates unique slugs
113
+ test_files:
114
+ - spec/integration/slug_spec.rb
115
+ - spec/spec_helper.rb