Skip to content

Commit

Permalink
Merge branch 'master' of git://github.com/miloops/friendly_id into mi…
Browse files Browse the repository at this point in the history
…loops/master

Conflicts:
	lib/friendly_id.rb
	test/sluggable_test.rb
  • Loading branch information
Norman Clarke committed Dec 11, 2008
2 parents 0c5d284 + fc4ddac commit c5b1e13
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 43 deletions.
18 changes: 10 additions & 8 deletions lib/friendly_id.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,16 @@ def find_one_with_friendly(id_or_name, options)

scope_options = {:select => "#{self.table_name}.*", :conditions => conditions}

scope_options[:joins] = :slugs unless options[:include] && [*options[:include]].flatten.include?(:slugs)
scope_options[:joins] = :slugs unless options[:include] && [*options[:include]].flatten.include?(:slugs)

result = with_scope :find => scope_options do
find_initial(options)
end

if result
result.finder_slug_name = id_or_name
else
result = find_one_without_friendly id_or_name, options
result = find_one_without_friendly id_or_name, options
end
result
end
Expand All @@ -166,7 +166,7 @@ def find_some_with_friendly(ids_and_names, options)
results = []

scope_options = {:select => "#{self.table_name}.*", :conditions => Slug.with_names(names)}
scope_options[:joins] = :slugs unless options[:include] && [*options[:include]].flatten.include?(:slugs)
scope_options[:joins] = :slugs unless options[:include] && [*options[:include]].flatten.include?(:slugs)

results += with_scope(:find => scope_options) { find_every options } unless names.empty?

Expand Down Expand Up @@ -194,13 +194,13 @@ module SluggableInstanceMethods

NUM_CHARS_RESERVED_FOR_FRIENDLY_ID_EXTENSION = 2

attr :finder_slug
attr :finder_slug
attr_accessor :finder_slug_name

def finder_slug
@finder_slug ||= init_finder_slug
end

# Was the record found using one of its friendly ids?
def found_using_friendly_id?
finder_slug
Expand Down Expand Up @@ -236,7 +236,7 @@ def slug(reload = false)

# Returns the friendly id, or if none is available, the numeric id.
def to_param
slug ? slug.name : id.to_s
(slug && !slug.name.blank?) ? slug.name : id.to_s
end

# Generate the text for the friendly id, ensuring no duplication.
Expand All @@ -263,7 +263,9 @@ def set_slug
if slugs.empty? || slugs.first.name != slug_text
previous_slug = slugs.find_by_name friendly_id_base
previous_slug.destroy if previous_slug
slugs.build :name => generate_friendly_id
name = generate_friendly_id
# If all name characters are removed, don't create a useless slug
slugs.build :name => name unless name.blank?
end
end
end
Expand Down
76 changes: 41 additions & 35 deletions test/sluggable_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class SluggableTest < Test::Unit::TestCase
def setup
Post.friendly_id_options[:max_length] = FriendlyId::ClassMethods::DEFAULT_FRIENDLY_ID_OPTIONS[:max_length]
end

def test_finder_options_are_not_ignored
assert_raises ActiveRecord::RecordNotFound do
Post.find(slugs(:one).name, :conditions => "1 = 2")
Expand All @@ -27,115 +27,115 @@ def test_post_should_generate_friendly_id
assert_equal "test-post", @post.generate_friendly_id
assert_equal "Test post", @post.name
end

def test_post_should_have_friendly_id_options
assert_not_nil Post.friendly_id_options
end

def test_slug_should_not_have_friendly_id_options
assert_raises NoMethodError do
Slug.friendly_id_options
end
end

def test_post_should_not_be_found_using_friendly_id_unless_it_really_was
@post = Post.new
assert !@post.found_using_friendly_id?
end

def test_posts_should_be_using_friendly_id_when_given_as_array
@posts = Post.find([posts(:with_one_slug).slug.name, posts(:with_two_slugs).slug.name])
assert @posts.all? { |post| post.found_using_friendly_id? }
end

def test_posts_raises_active_record_not_found_when_not_all_records_found
assert_raises(ActiveRecord::RecordNotFound) do
Post.find([posts(:with_one_slug).slug.name, 'non-existant-slug-record'])
end
end

def test_post_should_be_considered_found_by_numeric_id_as_default
@post = Post.new
assert @post.found_using_numeric_id?
end

def test_post_should_indicate_if_it_was_found_using_numeric_id
@post = Post.find(posts(:with_two_slugs).id)
assert @post.found_using_numeric_id?
end

def test_post_should_indicate_if_it_was_found_using_friendly_id
@post = Post.find(posts(:with_two_slugs).slug.name)
assert @post.found_using_friendly_id?
end

def test_post_should_indicate_if_it_was_found_using_outdated_friendly_id
@post = Post.find(posts(:with_two_slugs).slugs.last.name)
assert @post.found_using_outdated_friendly_id?
end

def test_should_indicate_there_is_a_better_id_if_found_by_numeric_id
@post = Post.find(posts(:with_one_slug).id)
assert @post.has_better_id?
end

def test_should_indicate_there_is_a_better_id_if_found_by_outdated_friendly_id
@post = Post.find(posts(:with_two_slugs).slugs.last.name)
assert @post.has_better_id?
end

def test_should_indicate_correct_best_id
@post = Post.find(posts(:with_two_slugs).slug.name)
assert !@post.has_better_id?
assert slugs(:two_new).name, @post.slug.name
end

def test_should_strip_diactics_from_slug
Post.friendly_id_options[:strip_diacritics] = true
@post = Post.new(:name => "ÀÁÂÃÄÅÆÇÈÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ", :content => "Test content")
assert_equal "aaaaaaaeceeeiiiidnoooooouuuuythssaaaaaaaeceeeeiiiidnoooooouuuuythy", @post.generate_friendly_id
end

def test_should_not_strip_diactics_from_slug
Post.friendly_id_options[:strip_diacritics] = false
@post = Post.new(:name => "ÀÁÂÃÄÅÆÇÈÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ", :content => "Test content")
assert_equal "ÀÁÂÃÄÅÆÇÈÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ", @post.generate_friendly_id
end

def test_post_should_not_make_new_slug_if_name_is_unchanged
posts(:with_one_slug).content = "Edited content"
posts(:with_one_slug).save!
assert_equal 1, posts(:with_one_slug).slugs.size
end

def test_post_should_make_new_slug_if_name_is_changed
posts(:with_one_slug).name = "Edited name"
posts(:with_one_slug).save!
assert_equal 2, posts(:with_one_slug).slugs.size
end

def test_should_not_consider_substrings_as_duplicate_slugs
@substring = slugs(:one).name[0, slugs(:one).name.length - 1]
@post = Post.new(:name => @substring, :content => "stuff")
assert_equal @substring, @post.generate_friendly_id
end

def test_should_append_extension_to_duplicate_slugs
@post = Post.new(:name => slugs(:one).name, :content => "stuff")
assert_equal slugs(:one).name + "-2", @post.generate_friendly_id
end

def test_should_create_post_with_slug
@post = Post.create(:name => "Test post", :content => "Test content")
assert_not_nil @post.slug
end

def test_should_truncate_slugs_longer_than_maxlength
Post.friendly_id_options[:max_length] = 10
@post = Post.new(:name => "x" * 11, :content => "Test content")
assert @post.generate_friendly_id.length <= Post.friendly_id_options[:max_length]
end

def test_should_ensure_truncated_slugs_are_unique
max_length = posts(:with_one_slug).friendly_id.length
Post.friendly_id_options[:max_length] = max_length
Expand All @@ -145,7 +145,7 @@ def test_should_ensure_truncated_slugs_are_unique
assert_not_equal posts(:with_one_slug).friendly_id, q.friendly_id
assert_not_equal p.friendly_id, q.friendly_id
end

def test_should_be_able_to_rename_back_to_old_friendly_id
p = Post.create!(:name => "value")
assert_equal "value", p.friendly_id
Expand All @@ -158,7 +158,7 @@ def test_should_be_able_to_rename_back_to_old_friendly_id
p.reload
assert_equal "value", p.friendly_id
end

def test_should_avoid_extention_collisions
Post.create!(:name => "Post 2/4")
assert Post.create!(:name => "Post")
Expand All @@ -168,44 +168,44 @@ def test_should_avoid_extention_collisions
assert Post.create!(:name => "Post-2-2")
assert Post.create!(:name => "Post 2/4")
end

def test_slug_should_indicate_if_it_is_the_most_recent
assert slugs(:two_new).is_most_recent?
end

def test_should_raise_error_if_friendly_is_base_is_blank
assert_raises(FriendlyId::SlugGenerationError) do
Post.create(:name => nil)
end
end

def test_should_not_use_reserved_slugs
post = Post.create!(:name => 'new')
assert_not_equal 'new', post.friendly_id
end

def test_should_append_extension_to_reseved_slugs
post = Post.create!(:name => 'new')
assert_equal 'new-2', post.friendly_id
end

def test_slug_sequence_is_based_on_highest_extension_rather_than_slug_count
assert_equal "test", Slug.get_best_name("test", Post)
@post = Post.create!(:name => "test", :content => "stuff")
assert_equal "test", @post.slug.name

assert_equal "test-2", Slug.get_best_name("test", Post)
@post2 = Post.create!(:name => "test", :content => "stuff") # slug should be "test-2"
assert_equal "test-2", @post2.slug.name

assert_equal "test-3", Slug.get_best_name("test", Post)
@post3 = Post.create!(:name => "test", :content => "stuff")
assert_equal "test-3", @post3.slug.name

assert_equal "test-4", Slug.get_best_name("test", Post)
@post.destroy # will destroy slug named "test" along with it
# Make sure the next slug is still test-4 and not test-3
assert_equal "test-4", Slug.get_best_name("test", Post)
assert_equal "test-4", Slug.get_best_name("test", Post)
@post4 = Post.create!(:name => "test", :content => "stuff")
assert_equal "test-4", @post4.slug.name
end
Expand All @@ -215,7 +215,7 @@ def test_should_return_record_by_id
Post.create!(:name => "#{post.id.to_s} and some text")
assert_equal post, Post.find(post.id)
end

def test_should_not_repeat_slug_names
Post.create!(:name => "test")
2.upto(10) do |i|
Expand All @@ -228,9 +228,15 @@ def test_should_allow_eager_loading_slugs
assert_nothing_raised do
Post.find(slugs(:one).name, :include => :slugs)
end

assert_nothing_raised do
Post.find([slugs(:one).name, slugs(:two_new).name], :include => :slugs)
end
end

def test_should_not_return_empty_slugs
post = Post.create!(:name => "-.-")
assert_not_equal '', post.to_param
assert_equal post.id.to_s, post.to_param
end
end

0 comments on commit c5b1e13

Please sign in to comment.