mil_friendly_id 4.0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +12 -0
  4. data/.travis.yml +20 -0
  5. data/.yardopts +4 -0
  6. data/Changelog.md +86 -0
  7. data/Gemfile +15 -0
  8. data/Guide.rdoc +553 -0
  9. data/MIT-LICENSE +19 -0
  10. data/README.md +150 -0
  11. data/Rakefile +108 -0
  12. data/WhatsNew.md +95 -0
  13. data/bench.rb +63 -0
  14. data/friendly_id.gemspec +43 -0
  15. data/gemfiles/Gemfile.rails-3.0.rb +21 -0
  16. data/gemfiles/Gemfile.rails-3.1.rb +22 -0
  17. data/gemfiles/Gemfile.rails-3.2.rb +22 -0
  18. data/geothird_friendly_id.gemspec +45 -0
  19. data/lib/friendly_id.rb +114 -0
  20. data/lib/friendly_id/base.rb +291 -0
  21. data/lib/friendly_id/configuration.rb +80 -0
  22. data/lib/friendly_id/finder_methods.rb +35 -0
  23. data/lib/friendly_id/globalize.rb +115 -0
  24. data/lib/friendly_id/history.rb +134 -0
  25. data/lib/friendly_id/migration.rb +19 -0
  26. data/lib/friendly_id/object_utils.rb +50 -0
  27. data/lib/friendly_id/reserved.rb +68 -0
  28. data/lib/friendly_id/scoped.rb +149 -0
  29. data/lib/friendly_id/simple_i18n.rb +95 -0
  30. data/lib/friendly_id/slug.rb +14 -0
  31. data/lib/friendly_id/slug_generator.rb +80 -0
  32. data/lib/friendly_id/slugged.rb +329 -0
  33. data/lib/generators/friendly_id_generator.rb +17 -0
  34. data/mil_friendly_id.gemspec +45 -0
  35. data/test/base_test.rb +72 -0
  36. data/test/compatibility/ancestry/Gemfile +8 -0
  37. data/test/compatibility/ancestry/ancestry_test.rb +34 -0
  38. data/test/compatibility/threading/Gemfile +8 -0
  39. data/test/compatibility/threading/threading.rb +45 -0
  40. data/test/configuration_test.rb +48 -0
  41. data/test/core_test.rb +48 -0
  42. data/test/databases.yml +19 -0
  43. data/test/generator_test.rb +20 -0
  44. data/test/globalize_test.rb +57 -0
  45. data/test/helper.rb +87 -0
  46. data/test/history_test.rb +149 -0
  47. data/test/object_utils_test.rb +28 -0
  48. data/test/reserved_test.rb +40 -0
  49. data/test/schema.rb +79 -0
  50. data/test/scoped_test.rb +83 -0
  51. data/test/shared.rb +156 -0
  52. data/test/simple_i18n_test.rb +133 -0
  53. data/test/slugged_test.rb +280 -0
  54. data/test/sti_test.rb +77 -0
  55. metadata +262 -0
@@ -0,0 +1,133 @@
1
+ require "helper"
2
+
3
+ class SimpleI18nTest < MiniTest::Unit::TestCase
4
+ include FriendlyId::Test
5
+
6
+ class Journalist < ActiveRecord::Base
7
+ extend FriendlyId
8
+ friendly_id :name, :use => :simple_i18n
9
+ end
10
+
11
+ def setup
12
+ I18n.locale = :en
13
+ end
14
+
15
+ test "friendly_id should return the current locale's slug" do
16
+ journalist = Journalist.new(:name => "John Doe")
17
+ journalist.slug_es = "juan-fulano"
18
+ journalist.valid?
19
+ I18n.with_locale(I18n.default_locale) do
20
+ assert_equal "john-doe", journalist.friendly_id
21
+ end
22
+ I18n.with_locale(:es) do
23
+ assert_equal "juan-fulano", journalist.friendly_id
24
+ end
25
+ end
26
+
27
+ test "should create record with slug in column for the current locale" do
28
+ I18n.with_locale(I18n.default_locale) do
29
+ journalist = Journalist.new(:name => "John Doe")
30
+ journalist.valid?
31
+ assert_equal "john-doe", journalist.slug_en
32
+ assert_nil journalist.slug_es
33
+ end
34
+ I18n.with_locale(:es) do
35
+ journalist = Journalist.new(:name => "John Doe")
36
+ journalist.valid?
37
+ assert_equal "john-doe", journalist.slug_es
38
+ assert_nil journalist.slug_en
39
+ end
40
+ end
41
+
42
+ test "to_param should return the numeric id when there's no slug for the current locale" do
43
+ transaction do
44
+ journalist = Journalist.new(:name => "Juan Fulano")
45
+ I18n.with_locale(:es) do
46
+ journalist.save!
47
+ assert_equal "juan-fulano", journalist.to_param
48
+ end
49
+ assert_equal journalist.id.to_s, journalist.to_param
50
+ end
51
+ end
52
+
53
+ test "should set friendly id for locale" do
54
+ transaction do
55
+ journalist = Journalist.create!(:name => "John Smith")
56
+ journalist.set_friendly_id("Juan Fulano", :es)
57
+ journalist.save!
58
+ assert_equal "juan-fulano", journalist.slug_es
59
+ I18n.with_locale(:es) do
60
+ assert_equal "juan-fulano", journalist.to_param
61
+ end
62
+ end
63
+ end
64
+
65
+ test "set friendly_id should fall back default locale when none is given" do
66
+ transaction do
67
+ journalist = I18n.with_locale(:es) do
68
+ Journalist.create!(:name => "Juan Fulano")
69
+ end
70
+ journalist.set_friendly_id("John Doe")
71
+ journalist.save!
72
+ assert_equal "john-doe", journalist.slug_en
73
+ end
74
+ end
75
+
76
+ test "should sequence localized slugs" do
77
+ transaction do
78
+ journalist = Journalist.create!(:name => "John Smith")
79
+ I18n.with_locale(:es) do
80
+ Journalist.create!(:name => "Juan Fulano")
81
+ end
82
+ journalist.set_friendly_id("Juan Fulano", :es)
83
+ journalist.save!
84
+ assert_equal "john-smith", journalist.to_param
85
+ I18n.with_locale(:es) do
86
+ assert_equal "juan-fulano--2", journalist.to_param
87
+ end
88
+ end
89
+ end
90
+
91
+ class RegressionTest < MiniTest::Unit::TestCase
92
+ include FriendlyId::Test
93
+
94
+ test "should not overwrite slugs on update_attributes" do
95
+ transaction do
96
+ journalist = Journalist.create!(:name => "John Smith")
97
+ journalist.set_friendly_id("Juan Fulano", :es)
98
+ journalist.save!
99
+ assert_equal "john-smith", journalist.to_param
100
+ journalist.update_attributes :name => "Johnny Smith"
101
+ assert_equal "johnny-smith", journalist.to_param
102
+ I18n.with_locale(:es) do
103
+ assert_equal "juan-fulano", journalist.to_param
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ class ConfigurationTest < MiniTest::Unit::TestCase
110
+ test "should add locale to slug column for a non-default locale" do
111
+ I18n.with_locale :es do
112
+ assert_equal "slug_es", Journalist.friendly_id_config.slug_column
113
+ end
114
+ end
115
+
116
+ test "should add locale to non-default slug column and non-default locale" do
117
+ model_class = Class.new(ActiveRecord::Base) do
118
+ self.abstract_class = true
119
+ extend FriendlyId
120
+ friendly_id :name, :use => :simple_i18n, :slug_column => :foo
121
+ end
122
+ I18n.with_locale :es do
123
+ assert_equal "foo_es", model_class.friendly_id_config.slug_column
124
+ end
125
+ end
126
+
127
+ test "should add locale to slug column for default locale" do
128
+ I18n.with_locale(I18n.default_locale) do
129
+ assert_equal "slug_en", Journalist.friendly_id_config.slug_column
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,280 @@
1
+ require "helper"
2
+
3
+ class Journalist < ActiveRecord::Base
4
+ extend FriendlyId
5
+ friendly_id :name, :use => :slugged
6
+ end
7
+
8
+ class Article < ActiveRecord::Base
9
+ extend FriendlyId
10
+ friendly_id :name, :use => :slugged
11
+ end
12
+
13
+ class Novelist < ActiveRecord::Base
14
+ extend FriendlyId
15
+ friendly_id :name, :use => :slugged, :sequence_separator => '_'
16
+
17
+ def normalize_friendly_id(string)
18
+ super.gsub("-", "_")
19
+ end
20
+ end
21
+
22
+ class SluggedTest < MiniTest::Unit::TestCase
23
+
24
+ include FriendlyId::Test
25
+ include FriendlyId::Test::Shared::Core
26
+ include FriendlyId::Test::Shared::Slugged
27
+
28
+ def model_class
29
+ Journalist
30
+ end
31
+
32
+ test "should not allow reserved words in resulting slug" do
33
+ ["new", "New", "NEW"].each do |word|
34
+ transaction do
35
+ assert_raises(ActiveRecord::RecordInvalid) {model_class.create! :name => word}
36
+ end
37
+ end
38
+ end
39
+
40
+ test "should allow validations on the slug" do
41
+ model_class = Class.new(ActiveRecord::Base) do
42
+ self.table_name = "articles"
43
+ extend FriendlyId
44
+ friendly_id :name, :use => :slugged
45
+ validates_length_of :slug, :maximum => 1
46
+ def self.name
47
+ "Article"
48
+ end
49
+ end
50
+ instance = model_class.new :name => "hello"
51
+ refute instance.valid?
52
+ end
53
+
54
+ test "should allow nil slugs" do
55
+ transaction do
56
+ m1 = model_class.create!
57
+ model_class.create!
58
+ assert_nil m1.slug
59
+ end
60
+ end
61
+
62
+ test "should not break validates_uniqueness_of" do
63
+ model_class = Class.new(ActiveRecord::Base) do
64
+ self.table_name = "journalists"
65
+ extend FriendlyId
66
+ friendly_id :name, :use => :slugged
67
+ validates_uniqueness_of :slug_en
68
+ def self.name
69
+ "Journalist"
70
+ end
71
+ end
72
+ transaction do
73
+ instance = model_class.create! :name => "hello", :slug_en => "hello"
74
+ instance2 = model_class.create :name => "hello", :slug_en => "hello"
75
+ assert instance.valid?
76
+ refute instance2.valid?
77
+ end
78
+ end
79
+ end
80
+
81
+ class SlugGeneratorTest < MiniTest::Unit::TestCase
82
+
83
+ include FriendlyId::Test
84
+
85
+ def model_class
86
+ Journalist
87
+ end
88
+
89
+ test "should quote column names" do
90
+ model_class = Class.new(ActiveRecord::Base) do
91
+ self.abstract_class = true
92
+ self.table_name = "journalists"
93
+ extend FriendlyId
94
+ friendly_id :name, :use => :slugged, :slug_column => "strange name"
95
+ end
96
+
97
+ begin
98
+ with_instance_of(model_class) {|record| assert model_class.find(record.friendly_id)}
99
+ rescue ActiveRecord::StatementInvalid
100
+ flunk "column name was not quoted"
101
+ end
102
+ end
103
+
104
+ test "should not resequence lower sequences on update" do
105
+ transaction do
106
+ m1 = model_class.create! :name => "a b c d"
107
+ assert_equal "a-b-c-d", m1.slug
108
+ model_class.create! :name => "a b c d"
109
+ m1 = model_class.find(m1.id)
110
+ m1.save!
111
+ assert_equal "a-b-c-d", m1.slug
112
+ end
113
+ end
114
+
115
+ test "should correctly sequence slugs that end with numbers" do
116
+ transaction do
117
+ record1 = model_class.create! :name => "Peugeuot 206"
118
+ assert_equal "peugeuot-206", record1.slug
119
+ record2 = model_class.create! :name => "Peugeuot 206"
120
+ assert_equal "peugeuot-206--2", record2.slug
121
+ end
122
+ end
123
+
124
+ test "should correctly sequence slugs with underscores" do
125
+ transaction do
126
+ record1 = Novelist.create! :name => 'wordsfail, buildings tumble'
127
+ record2 = Novelist.create! :name => 'word fail'
128
+ assert_equal 'word_fail', record2.slug
129
+ end
130
+ end
131
+
132
+ end
133
+
134
+ class SlugSeparatorTest < MiniTest::Unit::TestCase
135
+
136
+ include FriendlyId::Test
137
+
138
+ class Journalist < ActiveRecord::Base
139
+ extend FriendlyId
140
+ friendly_id :name, :use => :slugged, :sequence_separator => ":"
141
+ end
142
+
143
+ def model_class
144
+ Journalist
145
+ end
146
+
147
+ test "should increment sequence with configured sequence separator" do
148
+ with_instance_of model_class do |record|
149
+ record2 = model_class.create! :name => record.name
150
+ assert record2.friendly_id.match(/:2\z/)
151
+ end
152
+ end
153
+
154
+ test "should detect when a sequenced slug has changed" do
155
+ with_instance_of model_class do |record|
156
+ record2 = model_class.create! :name => record.name
157
+ assert !record2.should_generate_new_friendly_id?
158
+ record2.name = "hello world"
159
+ assert record2.should_generate_new_friendly_id?
160
+ end
161
+ end
162
+
163
+ test "should correctly sequence slugs that uses single dashes as sequence separator" do
164
+ model_class = Class.new(ActiveRecord::Base) do
165
+ self.table_name = "journalists"
166
+ extend FriendlyId
167
+ friendly_id :name, :use => :slugged, :sequence_separator => '-'
168
+ def self.name
169
+ "Journalist"
170
+ end
171
+ end
172
+ transaction do
173
+ record1 = model_class.create! :name => "Peugeuot 206"
174
+ assert_equal "peugeuot-206", record1.slug
175
+ record2 = model_class.create! :name => "Peugeuot 206"
176
+ assert_equal "peugeuot-206-2", record2.slug
177
+ end
178
+ end
179
+
180
+ test "should detect when a sequenced slug has changed when name ends in number and using single dash" do
181
+ model_class = Class.new(ActiveRecord::Base) do
182
+ self.table_name = "journalists"
183
+ extend FriendlyId
184
+ friendly_id :name, :use => :slugged, :sequence_separator => '-'
185
+ end
186
+ transaction do
187
+ record1 = model_class.create! :name => "Peugeuot 206"
188
+ assert !record1.should_generate_new_friendly_id?
189
+ record1.save!
190
+ assert !record1.should_generate_new_friendly_id?
191
+ record1.name = "Peugeot 307"
192
+ assert record1.should_generate_new_friendly_id?
193
+ end
194
+ end
195
+ end
196
+
197
+ class DefaultScopeTest < MiniTest::Unit::TestCase
198
+
199
+ include FriendlyId::Test
200
+
201
+ class Journalist < ActiveRecord::Base
202
+ extend FriendlyId
203
+ friendly_id :name, :use => :slugged
204
+ default_scope :order => 'id ASC', :conditions => { :active => true }
205
+ end
206
+
207
+ test "friendly_id should correctly sequence a default_scoped ordered table" do
208
+ transaction do
209
+ 3.times { assert Journalist.create :name => "a", :active => true }
210
+ end
211
+ end
212
+
213
+ test "friendly_id should correctly sequence a default_scoped scoped table" do
214
+ transaction do
215
+ assert Journalist.create :name => "a", :active => false
216
+ assert Journalist.create :name => "a", :active => true
217
+ end
218
+ end
219
+ end
220
+
221
+ class SluggedRegressionsTest < MiniTest::Unit::TestCase
222
+ include FriendlyId::Test
223
+
224
+ def model_class
225
+ Journalist
226
+ end
227
+
228
+ test "should increment the slug sequence for duplicate friendly ids beyond 10" do
229
+ with_instance_of model_class do |record|
230
+ (2..12).each do |i|
231
+ r = model_class.create! :name => record.name
232
+ assert r.friendly_id.match(/#{i}\z/)
233
+ end
234
+ end
235
+ end
236
+ end
237
+
238
+ class UnderscoreAsSequenceSeparatorRegressionTest < MiniTest::Unit::TestCase
239
+ include FriendlyId::Test
240
+
241
+ class Manual < ActiveRecord::Base
242
+ extend FriendlyId
243
+ friendly_id :name, :use => :slugged, :sequence_separator => "_"
244
+ end
245
+
246
+ test "should not create duplicate slugs" do
247
+ 3.times do
248
+ begin
249
+ assert Manual.create! :name => "foo"
250
+ rescue
251
+ flunk "Tried to insert duplicate slug"
252
+ end
253
+ end
254
+ end
255
+
256
+ end
257
+
258
+ # https://github.com/norman/friendly_id/issues/148
259
+ class FailedValidationAfterUpdateRegressionTest < MiniTest::Unit::TestCase
260
+ include FriendlyId::Test
261
+
262
+ class Journalist < ActiveRecord::Base
263
+ extend FriendlyId
264
+ friendly_id :name, :use => :slugged
265
+ validates_presence_of :slug_de
266
+ end
267
+
268
+ test "to_param should return the unchanged value if the slug changes before validation fails" do
269
+ transaction do
270
+ journalist = Journalist.create! :name => "Joseph Pulitzer", :slug_de => "value"
271
+ assert_equal "joseph-pulitzer", journalist.to_param
272
+ assert journalist.valid?
273
+ assert journalist.persisted?
274
+ journalist.name = "Joe Pulitzer"
275
+ journalist.slug_de = nil
276
+ assert !journalist.valid?
277
+ assert_equal "joseph-pulitzer", journalist.to_param
278
+ end
279
+ end
280
+ end
@@ -0,0 +1,77 @@
1
+ require "helper"
2
+
3
+ class StiTest < MiniTest::Unit::TestCase
4
+
5
+ include FriendlyId::Test
6
+ include FriendlyId::Test::Shared::Core
7
+ include FriendlyId::Test::Shared::Slugged
8
+
9
+ class Journalist < ActiveRecord::Base
10
+ extend FriendlyId
11
+ friendly_id :name, :use => :slugged
12
+ end
13
+
14
+ class Editorialist < Journalist
15
+ end
16
+
17
+ def model_class
18
+ Editorialist
19
+ end
20
+
21
+ test "friendly_id should accept a base and a hash with single table inheritance" do
22
+ abstract_klass = Class.new(ActiveRecord::Base) do
23
+ def self.table_exists?; false end
24
+ extend FriendlyId
25
+ friendly_id :foo, :use => :slugged, :slug_column => :bar
26
+ end
27
+ klass = Class.new(abstract_klass)
28
+ assert klass < FriendlyId::Slugged
29
+ assert_equal :foo, klass.friendly_id_config.base
30
+ assert_equal :bar, klass.friendly_id_config.slug_column
31
+ end
32
+
33
+ test "the configuration's model_class should be the class, not the base_class" do
34
+ assert_equal model_class, model_class.friendly_id_config.model_class
35
+ end
36
+
37
+ test "friendly_id should accept a block with single table inheritance" do
38
+ abstract_klass = Class.new(ActiveRecord::Base) do
39
+ def self.table_exists?; false end
40
+ extend FriendlyId
41
+ friendly_id :foo do |config|
42
+ config.use :slugged
43
+ config.base = :foo
44
+ config.slug_column = :bar
45
+ end
46
+ end
47
+ klass = Class.new(abstract_klass)
48
+ assert klass < FriendlyId::Slugged
49
+ assert_equal :foo, klass.friendly_id_config.base
50
+ assert_equal :bar, klass.friendly_id_config.slug_column
51
+ end
52
+
53
+ test "friendly_id slugs should not clash with eachother" do
54
+ transaction do
55
+ journalist = model_class.base_class.create! :name => 'foo bar'
56
+ editoralist = model_class.create! :name => 'foo bar'
57
+
58
+ assert_equal 'foo-bar', journalist.slug
59
+ assert_equal 'foo-bar--2', editoralist.slug
60
+ end
61
+ end
62
+
63
+ end
64
+
65
+ class StiTestWithHistory < StiTest
66
+ class Journalist < ActiveRecord::Base
67
+ extend FriendlyId
68
+ friendly_id :name, :use => [:slugged, :history]
69
+ end
70
+
71
+ class Editorialist < Journalist
72
+ end
73
+
74
+ def model_class
75
+ Editorialist
76
+ end
77
+ end