friendly_id 2.2.5 → 2.2.6

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.
@@ -1,7 +1,6 @@
1
- # encoding: utf-8
2
-
3
1
  require File.dirname(__FILE__) + '/test_helper'
4
2
 
3
+
5
4
  class ScopedModelTest < Test::Unit::TestCase
6
5
 
7
6
  context "A slugged model that uses a scope" do
@@ -9,33 +8,42 @@ class ScopedModelTest < Test::Unit::TestCase
9
8
  setup do
10
9
  @usa = Country.create!(:name => "USA")
11
10
  @canada = Country.create!(:name => "Canada")
12
- @person = Person.create!(:name => "John Smith", :country => @usa)
13
- @person2 = Person.create!(:name => "John Smith", :country => @canada)
11
+ @resident = Resident.create!(:name => "John Smith", :country => @usa)
12
+ @resident2 = Resident.create!(:name => "John Smith", :country => @canada)
14
13
  end
15
14
 
16
15
  teardown do
17
- Person.delete_all
16
+ Resident.delete_all
18
17
  Country.delete_all
19
18
  Slug.delete_all
20
19
  end
21
20
 
21
+ should "should not show the scope in the friendly_id" do
22
+ assert_equal "john-smith", @resident.friendly_id
23
+ assert_equal "john-smith", @resident2.friendly_id
24
+ end
25
+
22
26
  should "find all scoped records without scope" do
23
- assert_equal 2, Person.find(:all, @person.friendly_id).size
27
+ assert_equal 2, Resident.find(:all, @resident.friendly_id).size
28
+ end
29
+
30
+ should "find a single scoped records with a scope as a string" do
31
+ assert Resident.find(@resident.friendly_id, :scope => @resident.country.to_param)
24
32
  end
25
33
 
26
34
  should "find a single scoped records with a scope" do
27
- assert Person.find(@person.friendly_id, :scope => @person.country.to_param)
35
+ assert Resident.find(@resident.friendly_id, :scope => @resident.country)
28
36
  end
29
37
 
30
38
  should "raise an error when finding a single scoped record with no scope" do
31
39
  assert_raises ActiveRecord::RecordNotFound do
32
- Person.find(@person.friendly_id)
40
+ Resident.find(@resident.friendly_id)
33
41
  end
34
42
  end
35
43
 
36
44
  should "append scope error info when missing scope causes a find to fail" do
37
45
  begin
38
- Person.find(@person.friendly_id)
46
+ Resident.find(@resident.friendly_id)
39
47
  fail "The find should not have succeeded"
40
48
  rescue ActiveRecord::RecordNotFound => e
41
49
  assert_match /expected scope/, e.message
@@ -44,7 +52,7 @@ class ScopedModelTest < Test::Unit::TestCase
44
52
 
45
53
  should "append scope error info when the scope value causes a find to fail" do
46
54
  begin
47
- Person.find(@person.friendly_id, :scope => "badscope")
55
+ Resident.find(@resident.friendly_id, :scope => "badscope")
48
56
  fail "The find should not have succeeded"
49
57
  rescue ActiveRecord::RecordNotFound => e
50
58
  assert_match /scope=badscope/, e.message
@@ -1,5 +1,4 @@
1
1
  # encoding: utf-8
2
-
3
2
  require File.dirname(__FILE__) + '/test_helper'
4
3
 
5
4
  class SlugTest < Test::Unit::TestCase
@@ -12,8 +11,8 @@ class SlugTest < Test::Unit::TestCase
12
11
  end
13
12
 
14
13
  should "indicate if it is the most recent slug" do
15
- post = Post.create!(:title => "test title", :content => "test content")
16
- post.title = "a new title"
14
+ post = Post.create!(:name => "test title")
15
+ post.name = "a new title"
17
16
  post.save!
18
17
  assert post.slugs.last.is_most_recent?
19
18
  assert !post.slugs.first.is_most_recent?
@@ -1,5 +1,4 @@
1
1
  # encoding: utf-8
2
-
3
2
  require File.dirname(__FILE__) + '/test_helper'
4
3
 
5
4
  class SluggedModelTest < Test::Unit::TestCase
@@ -7,17 +6,16 @@ class SluggedModelTest < Test::Unit::TestCase
7
6
  context "A slugged model with default FriendlyId options" do
8
7
 
9
8
  setup do
10
- Post.friendly_id_options = FriendlyId::DEFAULT_OPTIONS.merge(:method => :title, :use_slug => true)
11
- @post = Post.new :title => "Test post", :content => "Test content", :published => true
9
+ Post.friendly_id_options = FriendlyId::DEFAULT_OPTIONS.merge(:method => :name, :use_slug => true)
10
+ @post = Post.new :name => "Test post", :published => true
12
11
  @post.save!
13
12
  end
14
13
 
15
14
  teardown do
16
15
  Post.delete_all
17
16
  Person.delete_all
17
+ Place.delete_all
18
18
  Slug.delete_all
19
- Thing.delete_all
20
- LegacyThing.delete_all
21
19
  end
22
20
 
23
21
  should "have friendly_id options" do
@@ -51,7 +49,7 @@ class SluggedModelTest < Test::Unit::TestCase
51
49
  end
52
50
 
53
51
  should "generate slug text" do
54
- post = Post.new :title => "Test post", :content => "Test content"
52
+ post = Post.new :name => "Test post"
55
53
  assert_not_nil post.slug_text
56
54
  end
57
55
 
@@ -63,36 +61,36 @@ class SluggedModelTest < Test::Unit::TestCase
63
61
 
64
62
  should "raise an error if the friendly_id text is reserved" do
65
63
  assert_raises(FriendlyId::SlugGenerationError) do
66
- Post.create!(:title => "new")
64
+ Post.create!(:name => "new")
67
65
  end
68
66
  end
69
67
 
70
68
  should "raise an error if the friendly_id text is an empty string" do
71
69
  assert_raises(FriendlyId::SlugGenerationError) do
72
- Post.create(:title => "")
70
+ Post.create(:name => "")
73
71
  end
74
72
  end
75
73
 
76
74
  should "raise an error if the friendly_id text is nil" do
77
75
  assert_raises(FriendlyId::SlugGenerationError) do
78
- Post.create(:title => nil)
76
+ Post.create(:name => nil)
79
77
  end
80
78
  end
81
79
 
82
80
  should "raise an error if the normalized friendly id becomes blank" do
83
81
  assert_raises(FriendlyId::SlugGenerationError) do
84
- post = Post.create!(:title => "-.-")
82
+ post = Post.create!(:name => "-.-")
85
83
  end
86
84
  end
87
85
 
88
86
  should "not make a new slug unless the friendly_id method value has changed" do
89
- @post.content = "Changed content"
87
+ @post.published = !@post.published
90
88
  @post.save!
91
89
  assert_equal 1, @post.slugs.size
92
90
  end
93
91
 
94
92
  should "make a new slug if the friendly_id method value has changed" do
95
- @post.title = "Changed title"
93
+ @post.name = "Changed title"
96
94
  @post.save!
97
95
  assert_equal 2, @post.slugs.size
98
96
  end
@@ -102,12 +100,12 @@ class SluggedModelTest < Test::Unit::TestCase
102
100
  end
103
101
 
104
102
  should "increment sequence for duplicate slug names" do
105
- @post2 = Post.create! :title => @post.title, :content => "Test content for post2"
103
+ @post2 = Post.create! :name => @post.name
106
104
  assert_equal 2, @post2.slug.sequence
107
105
  end
108
106
 
109
107
  should "have a friendly_id that terminates with -- and the slug sequence if the sequence is greater than 1" do
110
- @post2 = Post.create! :title => @post.title, :content => "Test content for post2"
108
+ @post2 = Post.create! :name => @post.name
111
109
  assert_match(/--2\z/, @post2.friendly_id)
112
110
  end
113
111
 
@@ -116,36 +114,36 @@ class SluggedModelTest < Test::Unit::TestCase
116
114
  end
117
115
 
118
116
  should "not strip diacritics" do
119
- post = Post.new(:title => "¡Feliz año!")
117
+ post = Post.new(:name => "¡Feliz año!")
120
118
  assert_match(/#{'ñ'}/, post.slug_text)
121
119
  end
122
120
 
123
121
  should "not convert to ASCII" do
124
- post = Post.new(:title => "katakana: ゲコゴサザシジ")
122
+ post = Post.new(:name => "katakana: ゲコゴサザシジ")
125
123
  assert_equal "katakana-ゲコゴサザシジ", post.slug_text
126
124
  end
127
125
 
128
126
  should "allow the same friendly_id across models" do
129
- person = Person.create!(:name => @post.title)
130
- assert_equal person.friendly_id, @post.friendly_id
127
+ district = District.create!(:name => @post.name)
128
+ assert_equal district.friendly_id, @post.friendly_id
131
129
  end
132
130
 
133
131
  should "truncate slug text longer than the max length" do
134
- post = Post.new(:title => "a" * (Post.friendly_id_options[:max_length] + 1))
132
+ post = Post.new(:name => "a" * (Post.friendly_id_options[:max_length] + 1))
135
133
  assert_equal post.slug_text.length, Post.friendly_id_options[:max_length]
136
134
  end
137
135
 
138
136
  should "truncate slug in 'right way' when slug is unicode" do
139
- post = Post.new(:title => "ё" * 100 + 'ю' *(Post.friendly_id_options[:max_length] - 100 + 1))
137
+ post = Post.new(:name => "ё" * 100 + 'ю' *(Post.friendly_id_options[:max_length] - 100 + 1))
140
138
  assert_equal post.slug_text.mb_chars[-1], 'ю'
141
139
  end
142
140
 
143
141
  should "be able to reuse an old friendly_id without incrementing the sequence" do
144
- old_title = @post.title
142
+ old_title = @post.name
145
143
  old_friendly_id = @post.friendly_id
146
- @post.title = "A changed title"
144
+ @post.name = "A changed title"
147
145
  @post.save!
148
- @post.title = old_title
146
+ @post.name = old_title
149
147
  @post.save!
150
148
  assert_equal old_friendly_id, @post.friendly_id
151
149
  end
@@ -158,8 +156,8 @@ class SluggedModelTest < Test::Unit::TestCase
158
156
 
159
157
  # This emulates a fairly common issue where id's generated by fixtures are very high.
160
158
  should "continue to admit very large ids" do
161
- Thing.connection.execute("INSERT INTO things (id, name) VALUES (2147483647, 'big')")
162
- assert Thing.find(2147483647)
159
+ Person.connection.execute("INSERT INTO people (id, name) VALUES (2147483647, 'Joe Schmoe')")
160
+ assert Person.find(2147483647)
163
161
  end
164
162
 
165
163
  context "and configured to strip diacritics" do
@@ -168,19 +166,19 @@ class SluggedModelTest < Test::Unit::TestCase
168
166
  end
169
167
 
170
168
  should "strip diacritics from Roman alphabet based characters" do
171
- post = Post.new(:title => "¡Feliz año!")
169
+ post = Post.new(:name => "¡Feliz año!")
172
170
  assert_no_match(/#{'ñ'}/, post.slug_text)
173
171
  end
174
172
 
175
173
  should "raise an error if the friendly_id text is an empty string" do
176
174
  assert_raises(FriendlyId::SlugGenerationError) do
177
- Post.create(:title => "")
175
+ Post.create(:name => "")
178
176
  end
179
177
  end
180
178
 
181
179
  should "raise an error if the friendly_id text is nil" do
182
180
  assert_raises(FriendlyId::SlugGenerationError) do
183
- Post.create(:title => nil)
181
+ Post.create(:name => nil)
184
182
  end
185
183
  end
186
184
 
@@ -192,14 +190,14 @@ class SluggedModelTest < Test::Unit::TestCase
192
190
  end
193
191
 
194
192
  should "strip non-ascii characters" do
195
- post = Post.new(:title => "katakana: ゲコゴサザシジ")
193
+ post = Post.new(:name => "katakana: ゲコゴサザシジ")
196
194
  assert_equal "katakana", post.slug_text
197
195
  end
198
196
  end
199
197
 
200
198
  context "that uses a custom table name" do
201
199
  should "support normal CRUD operations" do
202
- assert thing = LegacyThing.create!(:name => "a name")
200
+ assert thing = Place.create!(:name => "a name")
203
201
  thing.name = "a new name"
204
202
  assert thing.save!
205
203
  assert thing.destroy
@@ -268,7 +266,7 @@ class SluggedModelTest < Test::Unit::TestCase
268
266
  context "when found using an outdated friendly id" do
269
267
  setup do
270
268
  old_id = @post.friendly_id
271
- @post.title = "Title changed"
269
+ @post.name = "Title changed"
272
270
  @post.save!
273
271
  @post = Post.find(old_id)
274
272
  end
@@ -291,10 +289,18 @@ class SluggedModelTest < Test::Unit::TestCase
291
289
 
292
290
  end
293
291
 
292
+ context "when table does not exist" do
293
+ should "not raise an error when doing friendly_id setup" do
294
+ assert_nothing_raised do
295
+ Question.has_friendly_id :title, :use_slug => true
296
+ end
297
+ end
298
+ end
299
+
294
300
  context "when using an array as the find argument" do
295
301
 
296
302
  setup do
297
- @post2 = Post.create!(:title => "another post", :content => "more content", :published => true)
303
+ @post2 = Post.create!(:name => "another post", :published => true)
298
304
  end
299
305
 
300
306
  should "return results when passed an array of non-friendly ids" do
@@ -314,7 +320,7 @@ class SluggedModelTest < Test::Unit::TestCase
314
320
  end
315
321
 
316
322
  should "return results when passed an array of non-friendly ids, of which one represents a record with multiple slugs" do
317
- @post2.update_attributes(:title => 'another post [updated]')
323
+ @post2.update_attributes(:name => 'another post [updated]')
318
324
  assert_equal 2, Post.find([@post.id, @post2.id]).size
319
325
  end
320
326
 
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  require File.dirname(__FILE__) + '/test_helper'
4
2
 
5
3
  class STIModelTest < Test::Unit::TestCase
@@ -7,8 +5,8 @@ class STIModelTest < Test::Unit::TestCase
7
5
  context "A slugged model using single table inheritance" do
8
6
 
9
7
  setup do
10
- Novel.friendly_id_options = FriendlyId::DEFAULT_OPTIONS.merge(:method => :title, :use_slug => true)
11
- @novel = Novel.new :title => "Test novel"
8
+ Novel.friendly_id_options = FriendlyId::DEFAULT_OPTIONS.merge(:method => :name, :use_slug => true)
9
+ @novel = Novel.new :name => "Test novel"
12
10
  @novel.save!
13
11
  end
14
12
 
@@ -0,0 +1,6 @@
1
+ adapter: postgresql
2
+ host: localhost
3
+ port: 5432
4
+ username: postgres
5
+ database: friendly_id_test
6
+ encoding: utf8
@@ -0,0 +1,2 @@
1
+ adapter: sqlite3
2
+ database: ":memory:"
@@ -0,0 +1,45 @@
1
+ class CreateSupportModels < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :books do |t|
4
+ t.string :name
5
+ t.string :type
6
+ end
7
+ create_table :cities do |t|
8
+ t.string :name
9
+ t.string :my_slug
10
+ t.integer :population
11
+ end
12
+ create_table :countries do |t|
13
+ t.string :name
14
+ end
15
+ create_table :districts do |t|
16
+ t.string :name
17
+ t.string :cached_slug
18
+ end
19
+ create_table :events do |t|
20
+ t.string :name
21
+ t.datetime :event_date
22
+ end
23
+ create_table :legacy_table do |t|
24
+ t.string :name
25
+ end
26
+ create_table :people do |t|
27
+ t.string :name
28
+ end
29
+ create_table :posts do |t|
30
+ t.string :name
31
+ t.boolean :published
32
+ end
33
+ create_table :residents do |t|
34
+ t.string :name
35
+ t.integer :country_id
36
+ end
37
+ create_table :users do |t|
38
+ t.string :name
39
+ end
40
+ end
41
+
42
+ def self.down
43
+ end
44
+ end
45
+
@@ -1,6 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/test_helper'
2
2
  require "friendly_id/tasks"
3
- require "mocha"
4
3
 
5
4
  class TasksTest < Test::Unit::TestCase
6
5
 
@@ -42,7 +41,7 @@ class TasksTest < Test::Unit::TestCase
42
41
  context "The 'delete_slugs_for' task" do
43
42
 
44
43
  setup do
45
- @post = Post.create! :title => "Slugs Considered Harmful"
44
+ @post = Post.create! :name => "Slugs Considered Harmful"
46
45
  @city = City.create! :name => "Buenos Aires"
47
46
  end
48
47
 
@@ -59,9 +58,9 @@ class TasksTest < Test::Unit::TestCase
59
58
  end
60
59
 
61
60
  should "set the cached_slug column to NULL" do
62
- FriendlyId::Tasks.delete_slugs_for("City")
63
- @city.reload
64
- assert_nil @city.my_slug
61
+ District.create! :name => "Garment"
62
+ FriendlyId::Tasks.delete_slugs_for("District")
63
+ assert_nil District.first.cached_slug
65
64
  end
66
65
 
67
66
  end
@@ -69,7 +68,7 @@ class TasksTest < Test::Unit::TestCase
69
68
  context "The 'delete_old_slugs' task" do
70
69
 
71
70
  setup do
72
- @post = Post.create! :title => "Slugs Considered Harmful"
71
+ @post = Post.create! :name => "Slugs Considered Harmful"
73
72
  @city = City.create! :name => "Buenos Aires"
74
73
  City.connection.execute "UPDATE slugs SET created_at = '%s' WHERE id = %d" % [
75
74
  45.days.ago.strftime("%Y-%m-%d"), @city.slug.id]
@@ -1,38 +1,104 @@
1
- # encoding: utf-8
2
-
3
1
  $:.unshift(File.dirname(__FILE__) + '/../lib')
4
2
  $:.unshift(File.dirname(__FILE__))
3
+
5
4
  $KCODE = 'UTF8' if RUBY_VERSION < '1.9'
6
5
  $VERBOSE = false
6
+
7
+ require 'rubygems'
7
8
  require 'test/unit'
8
9
  require 'contest'
9
- # You can use "rake test AR_VERSION=2.0.5" to test against 2.0.5, for example.
10
+ require 'mocha'
11
+
12
+ # You can use "rake test AR_VERSION=2.2.3" to test against 2.2.3 for example.
10
13
  # The default is to use the latest installed ActiveRecord.
11
14
  if ENV["AR_VERSION"]
12
15
  gem 'activerecord', "#{ENV["AR_VERSION"]}"
13
16
  gem 'activesupport', "#{ENV["AR_VERSION"]}"
14
17
  end
18
+
15
19
  require 'active_record'
16
20
  require 'active_support'
21
+ require 'friendly_id'
22
+ require File.dirname(__FILE__) + '/../generators/friendly_id/templates/create_slugs'
23
+ require File.dirname(__FILE__) + '/support/models'
17
24
 
18
- ActiveRecord::Base.establish_connection :adapter => "sqlite3", :database => ":memory:"
19
- silence_stream(STDOUT) do
20
- load(File.dirname(__FILE__) + "/schema.rb")
21
- end
25
+ local_db_settings = File.dirname(__FILE__) + '/support/database.yml'
26
+ default_db_settings = File.dirname(__FILE__) + '/support/database.yml.sqlite3'
27
+ db_settings = File.exists?(local_db_settings) ? local_db_settings : default_db_settings
28
+ ActiveRecord::Base.establish_connection(YAML::load(File.open(db_settings)))
22
29
 
23
30
  class ActiveRecord::Base
24
31
  def log_protected_attribute_removal(*args) end
25
32
  end
26
33
 
27
- require 'friendly_id'
28
- require 'models/post'
29
- require 'models/person'
30
- require 'models/user'
31
- require 'models/country'
32
- require 'models/book'
33
- require 'models/novel'
34
- require 'models/thing'
35
- require 'models/event'
36
- require 'models/city'
37
- require 'models/district'
38
- require 'models/legacy_thing'
34
+ ActiveRecord::Base.connection.tables.each do |table|
35
+ ActiveRecord::Base.connection.drop_table(table)
36
+ end
37
+ ActiveRecord::Migration.verbose = false
38
+ CreateSlugs.up
39
+ CreateSupportModels.up
40
+
41
+ # A model that uses the automagically configured "cached_slug" column
42
+ class District < ActiveRecord::Base
43
+ has_friendly_id :name, :use_slug => true
44
+ end
45
+
46
+ # A model that specifies a custom cached slug column
47
+ class City < ActiveRecord::Base
48
+ attr_accessible :name
49
+ has_friendly_id :name, :use_slug => true, :cache_column => 'my_slug'
50
+ end
51
+
52
+ # A model with a custom slug text normalizer
53
+ class Person < ActiveRecord::Base
54
+ has_friendly_id :name, :use_slug => true do |text|
55
+ text.upcase
56
+ end
57
+ end
58
+
59
+ # A slugged model that uses a scope
60
+ class Resident < ActiveRecord::Base
61
+ belongs_to :country
62
+ has_friendly_id :name, :use_slug => true, :scope => :country
63
+ end
64
+
65
+ # A model used as a scope
66
+ class Country < ActiveRecord::Base
67
+ has_many :people
68
+ has_friendly_id :name, :use_slug => true
69
+ end
70
+
71
+ # A model that doesn't use slugs
72
+ class User < ActiveRecord::Base
73
+ has_friendly_id :name
74
+ end
75
+
76
+ # A model that uses default slug settings and has a named scope
77
+ class Post < ActiveRecord::Base
78
+ has_friendly_id :name, :use_slug => true
79
+ named_scope :published, :conditions => { :published => true }
80
+ end
81
+
82
+ # Model that uses a custom table name
83
+ class Place < ActiveRecord::Base
84
+ self.table_name = "legacy_table"
85
+ has_friendly_id :name, :use_slug => true
86
+ end
87
+
88
+ # A model that uses a datetime field for its friendly_id
89
+ class Event < ActiveRecord::Base
90
+ has_friendly_id :event_date, :use_slug => true
91
+ end
92
+
93
+ # A base model for single table inheritence
94
+ class Book < ActiveRecord::Base ; end
95
+
96
+ # A model that uses STI
97
+ class Novel < ::Book
98
+ has_friendly_id :name, :use_slug => true
99
+ end
100
+
101
+ # A model with no table
102
+ class Question < ActiveRecord::Base
103
+ has_friendly_id :name, :use_slug => true
104
+ end