nateabbott-friendly_id 2.1.4

Sign up to get free protection for your applications and to get access to all the features.
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