mil_friendly_id 4.0.9.8

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 (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