dm-is-slug 0.10.2

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.
@@ -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