nateabbott-friendly_id 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. data/History.txt +133 -0
  2. data/MIT-LICENSE +19 -0
  3. data/Manifest.txt +39 -0
  4. data/README.rdoc +343 -0
  5. data/Rakefile +49 -0
  6. data/config/website.yml +2 -0
  7. data/friendly_id.gemspec +45 -0
  8. data/generators/friendly_id/friendly_id_generator.rb +12 -0
  9. data/generators/friendly_id/templates/create_slugs.rb +18 -0
  10. data/generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb +11 -0
  11. data/generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb +19 -0
  12. data/init.rb +3 -0
  13. data/lib/friendly_id/helpers.rb +15 -0
  14. data/lib/friendly_id/non_sluggable_class_methods.rb +42 -0
  15. data/lib/friendly_id/non_sluggable_instance_methods.rb +43 -0
  16. data/lib/friendly_id/slug.rb +102 -0
  17. data/lib/friendly_id/sluggable_class_methods.rb +116 -0
  18. data/lib/friendly_id/sluggable_instance_methods.rb +116 -0
  19. data/lib/friendly_id/version.rb +10 -0
  20. data/lib/friendly_id.rb +101 -0
  21. data/lib/tasks/friendly_id.rake +50 -0
  22. data/lib/tasks/friendly_id.rb +1 -0
  23. data/test/contest.rb +94 -0
  24. data/test/custom_slug_normalizer_test.rb +35 -0
  25. data/test/models/book.rb +2 -0
  26. data/test/models/country.rb +4 -0
  27. data/test/models/event.rb +3 -0
  28. data/test/models/novel.rb +3 -0
  29. data/test/models/person.rb +6 -0
  30. data/test/models/post.rb +6 -0
  31. data/test/models/thing.rb +6 -0
  32. data/test/models/user.rb +3 -0
  33. data/test/non_slugged_test.rb +98 -0
  34. data/test/schema.rb +55 -0
  35. data/test/scoped_model_test.rb +53 -0
  36. data/test/slug_test.rb +106 -0
  37. data/test/slugged_model_test.rb +284 -0
  38. data/test/sti_test.rb +48 -0
  39. data/test/test_helper.rb +30 -0
  40. metadata +155 -0
@@ -0,0 +1,284 @@
1
+ # encoding: utf-8
2
+
3
+ require File.dirname(__FILE__) + '/test_helper'
4
+
5
+ class SluggedModelTest < Test::Unit::TestCase
6
+
7
+ context "A slugged model with default FriendlyId options" do
8
+
9
+ setup do
10
+ Post.friendly_id_options = FriendlyId::DEFAULT_FRIENDLY_ID_OPTIONS.merge(:column => :title, :use_slug => true)
11
+ Post.delete_all
12
+ Person.delete_all
13
+ Slug.delete_all
14
+ @post = Post.new :title => "Test post", :content => "Test content", :published => true
15
+ @post.save!
16
+ end
17
+
18
+ should "have friendly_id options" do
19
+ assert_not_nil Post.friendly_id_options
20
+ end
21
+
22
+ should "have a slug" do
23
+ assert_not_nil @post.slug
24
+ end
25
+
26
+ should "be findable by its friendly_id" do
27
+ assert Post.find(@post.friendly_id)
28
+ end
29
+
30
+ should "be findable by its regular id" do
31
+ assert Post.find(@post.id)
32
+ end
33
+
34
+ should "generate slug text" do
35
+ post = Post.new :title => "Test post", :content => "Test content"
36
+ assert_not_nil @post.slug_text
37
+ end
38
+
39
+ should "respect finder conditions" do
40
+ assert_raises ActiveRecord::RecordNotFound do
41
+ Post.find(@post.friendly_id, :conditions => "1 = 2")
42
+ end
43
+ end
44
+
45
+ should "raise an error if the friendly_id text is reserved" do
46
+ assert_raises(FriendlyId::SlugGenerationError) do
47
+ Post.create!(:title => "new")
48
+ end
49
+ end
50
+
51
+ should "raise an error if the friendly_id text is blank" do
52
+ assert_raises(FriendlyId::SlugGenerationError) do
53
+ Post.create(:title => "")
54
+ end
55
+ end
56
+
57
+ should "raise an error if the normalized friendly id becomes blank" do
58
+ assert_raises(FriendlyId::SlugGenerationError) do
59
+ post = Post.create!(:title => "-.-")
60
+ end
61
+ end
62
+
63
+ should "not make a new slug unless the friendly_id method value has changed" do
64
+ @post.content = "Changed content"
65
+ @post.save!
66
+ assert_equal 1, @post.slugs.size
67
+ end
68
+
69
+ should "make a new slug if the friendly_id method value has changed" do
70
+ @post.title = "Changed title"
71
+ @post.save!
72
+ assert_equal 2, @post.slugs.size
73
+ end
74
+
75
+ should "have a slug sequence of 1 by default" do
76
+ assert_equal 1, @post.slug.sequence
77
+ end
78
+
79
+ should "increment sequence for duplicate slug names" do
80
+ @post2 = Post.create! :title => @post.title, :content => "Test content for post2"
81
+ assert_equal 2, @post2.slug.sequence
82
+ end
83
+
84
+ should "have a friendly_id that terminates with -- and the slug sequence if the sequence is greater than 1" do
85
+ @post2 = Post.create! :title => @post.title, :content => "Test content for post2"
86
+ assert_match(/--2\z/, @post2.friendly_id)
87
+ end
88
+
89
+ should "allow datetime columns to be used as slugs" do
90
+ assert Event.create(:name => "Test", :event_date => DateTime.now)
91
+ end
92
+
93
+ should "not strip diacritics" do
94
+ @post = Post.new(:title => "¡Feliz año!")
95
+ assert_match(/#{'ñ'}/, @post.slug_text)
96
+ end
97
+
98
+ should "not convert to ASCII" do
99
+ @post = Post.new(:title => "katakana: ゲコゴサザシジ")
100
+ assert_equal "katakana-ゲコゴサザシジ", @post.slug_text
101
+ end
102
+
103
+ should "allow the same friendly_id across models" do
104
+ @person = Person.create!(:name => @post.title)
105
+ assert_equal @person.friendly_id, @post.friendly_id
106
+ end
107
+
108
+ should "truncate slug text longer than the max length" do
109
+ @post = Post.new(:title => "a" * (Post.friendly_id_options[:max_length] + 1))
110
+ assert_equal @post.slug_text.length, Post.friendly_id_options[:max_length]
111
+ end
112
+
113
+ should "be able to reuse an old friendly_id without incrementing the sequence" do
114
+ old_title = @post.title
115
+ old_friendly_id = @post.friendly_id
116
+ @post.title = "A changed title"
117
+ @post.save!
118
+ @post.title = old_title
119
+ @post.save!
120
+ assert_equal old_friendly_id, @post.friendly_id
121
+ end
122
+
123
+ should "allow eager loading of slugs" do
124
+ assert_nothing_raised do
125
+ Post.find(@post.friendly_id, :include => :slugs)
126
+ end
127
+ end
128
+
129
+ context "and configured to strip diacritics" do
130
+ setup do
131
+ Post.friendly_id_options = Post.friendly_id_options.merge(:strip_diacritics => true)
132
+ end
133
+
134
+ should "strip diacritics from Roman alphabet based characters" do
135
+ @post = Post.new(:title => "¡Feliz año!")
136
+ assert_no_match(/#{'ñ'}/, @post.slug_text)
137
+ end
138
+ end
139
+
140
+ context "and configured to convert to ASCII" do
141
+ setup do
142
+ Post.friendly_id_options = Post.friendly_id_options.merge(:strip_non_ascii => true)
143
+ end
144
+
145
+ should "strip non-ascii characters" do
146
+ @post = Post.new(:title => "katakana: ゲコゴサザシジ")
147
+ assert_equal "katakana", @post.slug_text
148
+ end
149
+ end
150
+
151
+ context "that doesn't have a slug" do
152
+
153
+ setup do
154
+ @post.slug.destroy
155
+ @post = Post.find(@post.id)
156
+ end
157
+
158
+ should "have a to_param method that returns the id cast to a string" do
159
+ assert_equal @post.id.to_s, @post.to_param
160
+ end
161
+
162
+ end
163
+
164
+ context "when found using its friendly_id" do
165
+ setup do
166
+ @post = Post.find(@post.friendly_id)
167
+ end
168
+
169
+ should "indicate that it was found using the friendly_id" do
170
+ assert @post.found_using_friendly_id?
171
+ end
172
+
173
+ should "not indicate that it has a better id" do
174
+ assert !@post.has_better_id?
175
+ end
176
+
177
+ should "not indicate that it was found using its numeric id" do
178
+ assert !@post.found_using_numeric_id?
179
+ end
180
+
181
+ should "have a finder slug" do
182
+ assert_not_nil @post.finder_slug
183
+ end
184
+
185
+ end
186
+
187
+ context "when found using its regular id" do
188
+ setup do
189
+ @post = Post.find(@post.id)
190
+ end
191
+
192
+ should "indicate that it was not found using the friendly id" do
193
+ assert !@post.found_using_friendly_id?
194
+ end
195
+
196
+ should "indicate that it has a better id" do
197
+ assert @post.has_better_id?
198
+ end
199
+
200
+ should "indicate that it was found using its numeric id" do
201
+ assert @post.found_using_numeric_id?
202
+ end
203
+
204
+ should "not have a finder slug" do
205
+ assert_nil @post.finder_slug
206
+ end
207
+
208
+ end
209
+
210
+ context "when found using an outdated friendly id" do
211
+ setup do
212
+ old_id = @post.friendly_id
213
+ @post.title = "Title changed"
214
+ @post.save!
215
+ @post = Post.find(old_id)
216
+ end
217
+
218
+ should "indicate that it was found using a friendly_id" do
219
+ assert @post.found_using_friendly_id?
220
+ end
221
+
222
+ should "indicate that it has a better id" do
223
+ assert @post.has_better_id?
224
+ end
225
+
226
+ should "not indicate that it was found using its numeric id" do
227
+ assert !@post.found_using_numeric_id?
228
+ end
229
+
230
+ should "should have a finder slug different from its default slug" do
231
+ assert_not_equal @post.slug, @post.finder_slug
232
+ end
233
+
234
+ end
235
+
236
+ context "when using an array as the find argument" do
237
+
238
+ setup do
239
+ @post2 = Post.create!(:title => "another post", :content => "more content", :published => true)
240
+ end
241
+
242
+ should "return results when passed an array of non-friendly ids" do
243
+ assert_equal 2, Post.find([@post.id, @post2.id]).size
244
+ end
245
+
246
+ should "return results when passed an array of friendly ids" do
247
+ assert_equal 2, Post.find([@post.friendly_id, @post2.friendly_id]).size
248
+ end
249
+
250
+ should "return results when searching using a named scope" do
251
+ assert_equal 2, Post.published.find([@post.id, @post2.id]).size
252
+ end
253
+
254
+ should "return results when passed a mixed array of friendly and non-friendly ids" do
255
+ assert_equal 2, Post.find([@post.friendly_id, @post2.id]).size
256
+ end
257
+
258
+ should "return results when passed an array of non-friendly ids, of which one represents a record with multiple slugs" do
259
+ @post2.update_attributes(:title => 'another post [updated]')
260
+ assert_equal 2, Post.find([@post.id, @post2.id]).size
261
+ end
262
+
263
+ should "indicate that the results were found using a friendly_id" do
264
+ @posts = Post.find [@post.friendly_id, @post2.friendly_id]
265
+ @posts.each { |p| assert p.found_using_friendly_id? }
266
+ end
267
+
268
+ should "raise an error when all records are not found" do
269
+ assert_raises(ActiveRecord::RecordNotFound) do
270
+ Post.find([@post.friendly_id, 'non-existant-slug-record'])
271
+ end
272
+ end
273
+
274
+ should "allow eager loading of slugs" do
275
+ assert_nothing_raised do
276
+ Post.find([@post.friendly_id, @post2.friendly_id], :include => :slugs)
277
+ end
278
+ end
279
+
280
+ end
281
+
282
+ end
283
+
284
+ end
data/test/sti_test.rb ADDED
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ require File.dirname(__FILE__) + '/test_helper'
4
+
5
+ class SluggedModelTest < Test::Unit::TestCase
6
+
7
+ context "A slugged model using single table inheritance" do
8
+
9
+ setup do
10
+ Novel.friendly_id_options = FriendlyId::DEFAULT_FRIENDLY_ID_OPTIONS.merge(:column => :title, :use_slug => true)
11
+ Novel.delete_all
12
+ Slug.delete_all
13
+ @novel = Novel.new :title => "Test novel"
14
+ @novel.save!
15
+ end
16
+
17
+ should "have a slug" do
18
+ assert_not_nil @novel.slug
19
+ end
20
+
21
+ context "found by its friendly id" do
22
+
23
+ setup do
24
+ @novel = Novel.find(@novel.friendly_id)
25
+ end
26
+
27
+ should "not indicate that it has a better id" do
28
+ assert !@novel.has_better_id?
29
+ end
30
+
31
+ end
32
+
33
+
34
+ context "found by its numeric id" do
35
+
36
+ setup do
37
+ @novel = Novel.find(@novel.id)
38
+ end
39
+
40
+ should "indicate that it has a better id" do
41
+ assert @novel.has_better_id?
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
4
+ $:.unshift(File.dirname(__FILE__))
5
+ $KCODE = 'UTF8' if RUBY_VERSION < '1.9'
6
+ $VERBOSE = false
7
+ require 'test/unit'
8
+ require 'contest'
9
+ # You can use "rake test AR_VERSION=2.0.5" to test against 2.0.5, for example.
10
+ # The default is to use the latest installed ActiveRecord.
11
+ if ENV["AR_VERSION"]
12
+ gem 'activerecord', "#{ENV["AR_VERSION"]}"
13
+ gem 'activesupport', "#{ENV["AR_VERSION"]}"
14
+ end
15
+ require 'active_record'
16
+ require 'active_support'
17
+ require 'friendly_id'
18
+ require 'models/post'
19
+ require 'models/person'
20
+ require 'models/user'
21
+ require 'models/country'
22
+ require 'models/book'
23
+ require 'models/novel'
24
+ require 'models/thing'
25
+ require 'models/event'
26
+
27
+ ActiveRecord::Base.establish_connection :adapter => "sqlite3", :database => ":memory:"
28
+ silence_stream(STDOUT) do
29
+ load(File.dirname(__FILE__) + "/schema.rb")
30
+ end
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nateabbott-friendly_id
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.1.4
5
+ platform: ruby
6
+ authors:
7
+ - Norman Clarke
8
+ - Adrian Mugnolo
9
+ - Emilio Tagua
10
+ - Nate Abbott
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+
15
+ date: 2009-06-03 00:00:00 -07:00
16
+ default_executable:
17
+ dependencies:
18
+ - !ruby/object:Gem::Dependency
19
+ name: activerecord
20
+ type: :runtime
21
+ version_requirement:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.0
27
+ version:
28
+ - !ruby/object:Gem::Dependency
29
+ name: activesupport
30
+ type: :runtime
31
+ version_requirement:
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 2.0.0
37
+ version:
38
+ - !ruby/object:Gem::Dependency
39
+ name: newgem
40
+ type: :development
41
+ version_requirement:
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.4.1
47
+ version:
48
+ - !ruby/object:Gem::Dependency
49
+ name: sqlite3-ruby
50
+ type: :development
51
+ version_requirement:
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ - !ruby/object:Gem::Dependency
59
+ name: hoe
60
+ type: :development
61
+ version_requirement:
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 1.8.0
67
+ version:
68
+ description: A comprehensive slugging and pretty-URL plugin for ActiveRecord.
69
+ email:
70
+ - norman@rubysouth.com
71
+ - adrian@rubysouth.com
72
+ - miloops@gmail.com
73
+ - nate@everlater.com
74
+ executables: []
75
+
76
+ extensions: []
77
+
78
+ extra_rdoc_files:
79
+ - History.txt
80
+ - Manifest.txt
81
+ - README.rdoc
82
+ files:
83
+ - History.txt
84
+ - MIT-LICENSE
85
+ - Manifest.txt
86
+ - README.rdoc
87
+ - Rakefile
88
+ - config/website.yml
89
+ - friendly_id.gemspec
90
+ - generators/friendly_id/friendly_id_generator.rb
91
+ - generators/friendly_id/templates/create_slugs.rb
92
+ - generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb
93
+ - generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb
94
+ - init.rb
95
+ - lib/friendly_id.rb
96
+ - lib/friendly_id/helpers.rb
97
+ - lib/friendly_id/non_sluggable_class_methods.rb
98
+ - lib/friendly_id/non_sluggable_instance_methods.rb
99
+ - lib/friendly_id/slug.rb
100
+ - lib/friendly_id/sluggable_class_methods.rb
101
+ - lib/friendly_id/sluggable_instance_methods.rb
102
+ - lib/friendly_id/version.rb
103
+ - lib/tasks/friendly_id.rake
104
+ - lib/tasks/friendly_id.rb
105
+ - test/contest.rb
106
+ - test/custom_slug_normalizer_test.rb
107
+ - test/models/book.rb
108
+ - test/models/country.rb
109
+ - test/models/event.rb
110
+ - test/models/novel.rb
111
+ - test/models/person.rb
112
+ - test/models/post.rb
113
+ - test/models/thing.rb
114
+ - test/models/user.rb
115
+ - test/non_slugged_test.rb
116
+ - test/schema.rb
117
+ - test/scoped_model_test.rb
118
+ - test/slug_test.rb
119
+ - test/slugged_model_test.rb
120
+ - test/sti_test.rb
121
+ - test/test_helper.rb
122
+ has_rdoc: false
123
+ homepage: http://friendly-id.rubyforge.org/
124
+ post_install_message:
125
+ rdoc_options:
126
+ - --main
127
+ - README.rdoc
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: "0"
135
+ version:
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: "0"
141
+ version:
142
+ requirements: []
143
+
144
+ rubyforge_project: nate_friendly-id
145
+ rubygems_version: 1.2.0
146
+ signing_key:
147
+ specification_version: 3
148
+ summary: A comprehensive slugging and pretty-URL plugin for ActiveRecord.
149
+ test_files:
150
+ - test/custom_slug_normalizer_test.rb
151
+ - test/non_slugged_test.rb
152
+ - test/scoped_model_test.rb
153
+ - test/slug_test.rb
154
+ - test/slugged_model_test.rb
155
+ - test/sti_test.rb