norman-friendly_id 2.0.2 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,18 @@
1
+ == 2.0.3 2009-02-11
2
+
3
+ * 1 minor enhancment:
4
+ * Fixed to_param returning an empty string for non-slugged models with a null friendly_id.
5
+
6
+ == 2.0.2 2009-02-09
7
+
8
+ * 2 major enhancements:
9
+ * Made FriendlyId depend only on ActiveRecord. It should now be possible to
10
+ use FriendlyId with Camping or any other codebase that uses AR.
11
+ * Overhauled creaky testing setup and switched to Shoulda.
12
+
13
+ * 1 minor enhancment:
14
+ * Made reserved words work for non-slugged models.
15
+
1
16
  == 2.0.1 2009-01-19
2
17
 
3
18
  * 1 minor enhancements:
data/Manifest.txt CHANGED
@@ -14,32 +14,19 @@ lib/friendly_id.rb
14
14
  lib/friendly_id/helpers.rb
15
15
  lib/friendly_id/non_sluggable_class_methods.rb
16
16
  lib/friendly_id/non_sluggable_instance_methods.rb
17
- lib/friendly_id/shoulda_macros.rb
18
17
  lib/friendly_id/slug.rb
19
18
  lib/friendly_id/sluggable_class_methods.rb
20
19
  lib/friendly_id/sluggable_instance_methods.rb
21
20
  lib/friendly_id/version.rb
22
21
  lib/tasks/friendly_id.rake
23
22
  lib/tasks/friendly_id.rb
24
- test/database.yml
25
- test/fixtures/countries.yml
26
- test/fixtures/country.rb
27
- test/fixtures/people.yml
28
- test/fixtures/person.rb
29
- test/fixtures/post.rb
30
- test/fixtures/posts.yml
31
- test/fixtures/slugs.yml
32
- test/fixtures/user.rb
33
- test/fixtures/users.yml
23
+ test/models/country.rb
24
+ test/models/person.rb
25
+ test/models/post.rb
26
+ test/models/user.rb
34
27
  test/non_slugged_test.rb
35
- test/rails/2.x/app/controllers/application.rb
36
- test/rails/2.x/config/boot.rb
37
- test/rails/2.x/config/database.yml
38
- test/rails/2.x/config/environment.rb
39
- test/rails/2.x/config/environments/test.rb
40
- test/rails/2.x/config/routes.rb
41
28
  test/schema.rb
42
29
  test/scoped_model_test.rb
43
30
  test/slug_test.rb
44
- test/sluggable_test.rb
31
+ test/slugged_model_test.rb
45
32
  test/test_helper.rb
data/Rakefile CHANGED
@@ -5,18 +5,15 @@ $hoe = Hoe.new("friendly_id", FriendlyId::Version::STRING) do |p|
5
5
  p.rubyforge_name = "friendly-id"
6
6
  p.author = ['Norman Clarke', 'Adrian Mugnolo', 'Emilio Tagua']
7
7
  p.email = ['norman@randomba.org', 'adrian@randomba.org', 'miloops@gmail.com']
8
- p.summary = "A comprehensive slugging and pretty-URL plugin for Ruby on Rails."
9
- p.description = 'A comprehensive slugging and pretty-URL plugin for Ruby on Rails.'
10
- p.url = 'http://randomba.org'
11
- p.need_tar = true
12
- p.need_zip = true
8
+ p.summary = "A comprehensive slugging and pretty-URL plugin for ActiveRecord."
9
+ p.description = 'A comprehensive slugging and pretty-URL plugin for ActiveRecord.'
10
+ p.url = 'http://friendly-id.rubyforge.org/'
13
11
  p.test_globs = ['test/**/*_test.rb']
14
12
  p.extra_deps << ['unicode', '>= 0.1']
15
- p.extra_dev_deps = [
16
- ['newgem', ">= #{::Newgem::VERSION}"]
17
- ]
18
- p.rdoc_pattern = /^(lib|bin|ext)|txt|rdoc$/
19
- changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
13
+ p.extra_deps << ['activerecord', '>= 2.0.0']
14
+ p.extra_dev_deps << ['newgem', ">= #{::Newgem::VERSION}"]
15
+ p.extra_dev_deps << ['Shoulda', ">= 1.2.0"]
16
+ p.extra_dev_deps << ['sqlite3-ruby']
20
17
  p.remote_rdoc_dir = ""
21
18
  end
22
19
 
data/friendly_id.gemspec CHANGED
@@ -2,23 +2,23 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{friendly_id}
5
- s.version = "2.0.2"
5
+ s.version = "2.0.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Norman Clarke", "Adrian Mugnolo", "Emilio Tagua"]
9
- s.date = %q{2009-02-07}
10
- s.description = %q{A comprehensive slugging and pretty-URL plugin for Ruby on Rails.}
9
+ s.date = %q{2009-02-11}
10
+ s.description = %q{A comprehensive slugging and pretty-URL plugin for ActiveRecord.}
11
11
  s.email = ["norman@randomba.org", "adrian@randomba.org", "miloops@gmail.com"]
12
12
  s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc"]
13
- s.files = ["History.txt", "MIT-LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "config/website.yml", "friendly_id.gemspec", "generators/friendly_id/friendly_id_generator.rb", "generators/friendly_id/templates/create_slugs.rb", "generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb", "generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb", "init.rb", "lib/friendly_id.rb", "lib/friendly_id/helpers.rb", "lib/friendly_id/non_sluggable_class_methods.rb", "lib/friendly_id/non_sluggable_instance_methods.rb", "lib/friendly_id/shoulda_macros.rb", "lib/friendly_id/slug.rb", "lib/friendly_id/sluggable_class_methods.rb", "lib/friendly_id/sluggable_instance_methods.rb", "lib/friendly_id/version.rb", "lib/tasks/friendly_id.rake", "lib/tasks/friendly_id.rb", "test/database.yml", "test/fixtures/countries.yml", "test/fixtures/country.rb", "test/fixtures/people.yml", "test/fixtures/person.rb", "test/fixtures/post.rb", "test/fixtures/posts.yml", "test/fixtures/slugs.yml", "test/fixtures/user.rb", "test/fixtures/users.yml", "test/non_slugged_test.rb", "test/rails/2.x/app/controllers/application.rb", "test/rails/2.x/config/boot.rb", "test/rails/2.x/config/database.yml", "test/rails/2.x/config/environment.rb", "test/rails/2.x/config/environments/test.rb", "test/rails/2.x/config/routes.rb", "test/schema.rb", "test/scoped_model_test.rb", "test/slug_test.rb", "test/sluggable_test.rb", "test/test_helper.rb"]
13
+ s.files = ["History.txt", "MIT-LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "config/website.yml", "friendly_id.gemspec", "generators/friendly_id/friendly_id_generator.rb", "generators/friendly_id/templates/create_slugs.rb", "generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb", "generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb", "init.rb", "lib/friendly_id.rb", "lib/friendly_id/helpers.rb", "lib/friendly_id/non_sluggable_class_methods.rb", "lib/friendly_id/non_sluggable_instance_methods.rb", "lib/friendly_id/slug.rb", "lib/friendly_id/sluggable_class_methods.rb", "lib/friendly_id/sluggable_instance_methods.rb", "lib/friendly_id/version.rb", "lib/tasks/friendly_id.rake", "lib/tasks/friendly_id.rb", "test/models/country.rb", "test/models/person.rb", "test/models/post.rb", "test/models/user.rb", "test/non_slugged_test.rb", "test/schema.rb", "test/scoped_model_test.rb", "test/slug_test.rb", "test/slugged_model_test.rb", "test/test_helper.rb"]
14
14
  s.has_rdoc = true
15
- s.homepage = %q{http://randomba.org}
15
+ s.homepage = %q{http://friendly-id.rubyforge.org/}
16
16
  s.rdoc_options = ["--main", "README.rdoc"]
17
17
  s.require_paths = ["lib"]
18
18
  s.rubyforge_project = %q{friendly-id}
19
19
  s.rubygems_version = %q{1.3.1}
20
- s.summary = %q{A comprehensive slugging and pretty-URL plugin for Ruby on Rails.}
21
- s.test_files = ["test/non_slugged_test.rb", "test/scoped_model_test.rb", "test/slug_test.rb", "test/sluggable_test.rb"]
20
+ s.summary = %q{A comprehensive slugging and pretty-URL plugin for ActiveRecord.}
21
+ s.test_files = ["test/non_slugged_test.rb", "test/scoped_model_test.rb", "test/slug_test.rb", "test/slugged_model_test.rb"]
22
22
 
23
23
  if s.respond_to? :specification_version then
24
24
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
@@ -26,16 +26,25 @@ Gem::Specification.new do |s|
26
26
 
27
27
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
28
  s.add_runtime_dependency(%q<unicode>, [">= 0.1"])
29
+ s.add_runtime_dependency(%q<activerecord>, [">= 2.0.0"])
29
30
  s.add_development_dependency(%q<newgem>, [">= 1.2.3"])
31
+ s.add_development_dependency(%q<Shoulda>, [">= 1.2.0"])
32
+ s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
30
33
  s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
31
34
  else
32
35
  s.add_dependency(%q<unicode>, [">= 0.1"])
36
+ s.add_dependency(%q<activerecord>, [">= 2.0.0"])
33
37
  s.add_dependency(%q<newgem>, [">= 1.2.3"])
38
+ s.add_dependency(%q<Shoulda>, [">= 1.2.0"])
39
+ s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
34
40
  s.add_dependency(%q<hoe>, [">= 1.8.0"])
35
41
  end
36
42
  else
37
43
  s.add_dependency(%q<unicode>, [">= 0.1"])
44
+ s.add_dependency(%q<activerecord>, [">= 2.0.0"])
38
45
  s.add_dependency(%q<newgem>, [">= 1.2.3"])
46
+ s.add_dependency(%q<Shoulda>, [">= 1.2.0"])
47
+ s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
39
48
  s.add_dependency(%q<hoe>, [">= 1.8.0"])
40
49
  end
41
50
  end
@@ -21,17 +21,17 @@ module FriendlyId::NonSluggableClassMethods
21
21
  end
22
22
 
23
23
  def find_some_with_friendly(ids_and_names, options) #:nodoc:#
24
-
24
+
25
25
  results = with_scope :find => options do
26
- find :all, :conditions => ["#{ quoted_table_name }.#{ primary_key } IN (?) OR #{friendly_id_options[:column].to_s} IN (?)",
26
+ find :all, :conditions => ["#{quoted_table_name}.#{primary_key} IN (?) OR #{friendly_id_options[:column].to_s} IN (?)",
27
27
  ids_and_names, ids_and_names]
28
28
  end
29
-
29
+
30
30
  expected = expected_size(ids_and_names, options)
31
31
  if results.size != expected
32
32
  raise ActiveRecord::RecordNotFound, "Couldn't find all #{ name.pluralize } with IDs (#{ ids_and_names * ', ' }) AND #{ sanitize_sql options[:conditions] } (found #{ results.size } results, but was looking for #{ expected })"
33
33
  end
34
-
34
+
35
35
  results.each {|r| r.send(:found_using_friendly_id=, true) if ids_and_names.include?(r.friendly_id)}
36
36
 
37
37
  results
@@ -21,10 +21,18 @@ module FriendlyId::NonSluggableInstanceMethods
21
21
 
22
22
  # Returns the friendly id, or if none is available, the numeric id.
23
23
  def to_param
24
- friendly_id.to_s || id.to_s
24
+ (friendly_id || id).to_s
25
25
  end
26
26
 
27
27
  private
28
+
29
+ def validate_friendly_id
30
+ if self.class.friendly_id_options[:reserved].include? friendly_id
31
+ self.errors.add(self.class.friendly_id_options[:column],
32
+ self.class.friendly_id_options[:reserved_message] % friendly_id)
33
+ return false
34
+ end
35
+ end
28
36
 
29
37
  def found_using_friendly_id=(value) #:nodoc#
30
38
  @found_using_friendly_id = value
@@ -1,3 +1,4 @@
1
+ require 'unicode'
1
2
  # A Slug is a unique, human-friendly identifier for an ActiveRecord.
2
3
  class Slug < ActiveRecord::Base
3
4
 
@@ -23,12 +24,12 @@ class Slug < ActiveRecord::Base
23
24
  # terror in Europe unlike anything ever seen before or after. I'm not
24
25
  # taking any chances.
25
26
  def normalize(slug_text)
26
- return "" if slug_text.blank?
27
- slug_text.
27
+ return "" if slug_text.nil? || slug_text == ""
28
+ Unicode::normalize_KC(slug_text).
28
29
  send(chars_func).
29
30
  # For some reason Spanish ¡ and ¿ are not detected as non-word
30
31
  # characters. Bug in Ruby?
31
- normalize.gsub(/[\W|¡|¿]/u, ' ').
32
+ gsub(/[\W|¡|¿]/u, ' ').
32
33
  strip.
33
34
  gsub(/\s+/u, '-').
34
35
  gsub(/-\z/u, '').
@@ -42,12 +43,10 @@ class Slug < ActiveRecord::Base
42
43
  return name, sequence
43
44
  end
44
45
 
45
- # Remove diacritics (accents, umlauts, etc.) from the string.
46
+ # Remove diacritics (accents, umlauts, etc.) from the string. Borrowed
47
+ # from "The Ruby Way."
46
48
  def strip_diacritics(string)
47
- require 'unicode'
48
- Unicode::normalize_KD(string).unpack('U*').select { |cp|
49
- cp < 0x300 || cp > 0x036F
50
- }.pack('U*')
49
+ Unicode::normalize_KD(string).unpack('U*').select { |u| u < 0x300 || u > 0x036F }.pack('U*')
51
50
  end
52
51
 
53
52
  # Remove non-ascii characters from the string.
@@ -58,9 +57,7 @@ class Slug < ActiveRecord::Base
58
57
  private
59
58
 
60
59
  def chars_func
61
- Rails.version >= "2.2" ? :mb_chars : :chars
62
- rescue NoMethodError
63
- :chars
60
+ "".respond_to?(:mb_chars) ? :mb_chars : :chars
64
61
  end
65
62
 
66
63
  end
@@ -78,7 +75,7 @@ class Slug < ActiveRecord::Base
78
75
 
79
76
  # Raise a FriendlyId::SlugGenerationError if the slug name is blank.
80
77
  def check_for_blank_name #:nodoc:#
81
- if name.blank?
78
+ if name == "" || name.nil?
82
79
  raise FriendlyId::SlugGenerationError.new("The slug text is blank.")
83
80
  end
84
81
  end
@@ -1,5 +1,5 @@
1
1
  module FriendlyId::SluggableClassMethods
2
-
2
+
3
3
  include FriendlyId::Helpers
4
4
 
5
5
  def self.extended(base) #:nodoc:#
@@ -38,6 +38,17 @@ module FriendlyId::SluggableClassMethods
38
38
  end
39
39
 
40
40
  result
41
+ rescue ActiveRecord::RecordNotFound => e
42
+
43
+ if friendly_id_options[:scope]
44
+ if !scope
45
+ e.message << "; expected scope but got none"
46
+ else
47
+ e.message << " and scope=#{scope}"
48
+ end
49
+ end
50
+
51
+ raise e
41
52
 
42
53
  end
43
54
 
@@ -6,7 +6,7 @@ module FriendlyId::SluggableInstanceMethods
6
6
  attr_accessor :finder_slug_name
7
7
 
8
8
  def finder_slug
9
- @finder_slug ||= init_finder_slug
9
+ @finder_slug ||= init_finder_slug or nil
10
10
  end
11
11
 
12
12
  # Was the record found using one of its friendly ids?
@@ -2,7 +2,7 @@ module FriendlyId #:nodoc:
2
2
  module Version #:nodoc:
3
3
  MAJOR = 2
4
4
  MINOR = 0
5
- TINY = 2
5
+ TINY = 3
6
6
  STRING = [MAJOR, MINOR, TINY].join('.')
7
7
  end
8
8
  end
data/lib/friendly_id.rb CHANGED
@@ -1,20 +1,35 @@
1
1
  require 'friendly_id/helpers'
2
2
  require 'friendly_id/slug'
3
- require 'friendly_id/shoulda_macros'
4
-
5
3
 
6
4
  # FriendlyId is a comprehensize Rails plugin/gem for slugging and permalinks.
7
5
  module FriendlyId
8
6
 
7
+ # Default options for has_friendly_id.
8
+ DEFAULT_FRIENDLY_ID_OPTIONS = {
9
+ :max_length => 255,
10
+ :method => nil,
11
+ :reserved => ["new", "index"],
12
+ :reserved_message => 'can not be "%s"',
13
+ :scope => nil,
14
+ :strip_diacritics => false,
15
+ :strip_non_ascii => false,
16
+ :use_slug => false }.freeze
17
+
18
+ # Valid keys for has_friendly_id options.
19
+ VALID_FRIENDLY_ID_KEYS = [
20
+ :max_length,
21
+ :reserved,
22
+ :reserved_message,
23
+ :scope,
24
+ :strip_diacritics,
25
+ :strip_non_ascii,
26
+ :use_slug ].freeze
27
+
9
28
  # This error is raised when it's not possible to generate a unique slug.
10
29
  class SlugGenerationError < StandardError ; end
11
30
 
12
31
  module ClassMethods
13
32
 
14
- # Default options for friendly_id.
15
- DEFAULT_FRIENDLY_ID_OPTIONS = {:method => nil, :use_slug => false, :max_length => 255, :reserved => [], :strip_diacritics => false, :strip_non_ascii => false, :scope => nil}.freeze
16
- VALID_FRIENDLY_ID_KEYS = [:use_slug, :max_length, :reserved, :strip_diacritics, :strip_non_ascii, :scope].freeze
17
-
18
33
  # Set up an ActiveRecord model to use a friendly_id.
19
34
  #
20
35
  # The column argument can be one of your model's columns, or a method
@@ -25,12 +40,13 @@ module FriendlyId
25
40
  # * <tt>:max_length</tt> - Defaults to 255. The maximum allowed length for a slug.
26
41
  # * <tt>:strip_diacritics</tt> - Defaults to false. If true, it will remove accents, umlauts, etc. from western characters.
27
42
  # * <tt>:strip_non_ascii</tt> - Defaults to false. If true, it will all non-ascii ([^a-z0-9]) characters.
28
- # * <tt>:reseved</tt> - Array of words that are reserved and can't be used as slugs. If such a word is used, it will be treated the same as if that slug was already taken (numeric extension will be appended). Defaults to [].
43
+ # * <tt>:reserved</tt> - Array of words that are reserved and can't be used as friendly_id's. For sluggable models, if such a word is used, it will be treated the same as if that slug was already taken (numeric extension will be appended). Defaults to ["new", "index"].
44
+ # * <tt>:reserved_message</tt> - The validation message that will be shown when a reserved word is used as a frindly_id. Defaults to '"%s" is reserved'.
29
45
  def has_friendly_id(column, options = {})
30
46
  options.assert_valid_keys VALID_FRIENDLY_ID_KEYS
31
47
  options = DEFAULT_FRIENDLY_ID_OPTIONS.merge(options).merge(:column => column)
32
48
  write_inheritable_attribute :friendly_id_options, options
33
- class_inheritable_reader :friendly_id_options
49
+ class_inheritable_accessor :friendly_id_options
34
50
 
35
51
  if options[:use_slug]
36
52
  has_many :slugs, :order => 'id DESC', :as => :sluggable, :dependent => :destroy
@@ -44,9 +60,10 @@ module FriendlyId
44
60
  require 'friendly_id/non_sluggable_instance_methods'
45
61
  extend NonSluggableClassMethods
46
62
  include NonSluggableInstanceMethods
63
+ validate_on_create :validate_friendly_id
47
64
  end
48
65
  end
49
-
66
+
50
67
  end
51
68
 
52
69
  class << self
@@ -55,15 +72,6 @@ module FriendlyId
55
72
  def enable
56
73
  return if ActiveRecord::Base.methods.include? 'has_friendly_id'
57
74
  ActiveRecord::Base.class_eval { extend FriendlyId::ClassMethods }
58
- begin
59
- if Rails.version >= "2.3"
60
- ActiveSupport::TestCase.class_eval { include FriendlyId::ShouldaMacros }
61
- else
62
- Test::Unit::TestCase.class_eval { include FriendlyId::ShouldaMacros }
63
- end
64
- rescue NoMethodError
65
- Test::Unit::TestCase.class_eval { include FriendlyId::ShouldaMacros }
66
- end
67
75
  end
68
76
 
69
77
  end
@@ -0,0 +1,3 @@
1
+ class Post < ActiveRecord::Base
2
+ has_friendly_id :title, :use_slug => true
3
+ end
@@ -2,84 +2,95 @@ require File.dirname(__FILE__) + '/test_helper'
2
2
 
3
3
  class NonSluggedTest < Test::Unit::TestCase
4
4
 
5
- fixtures :users
5
+ context "A non-slugged model with default FriendlyId options" do
6
6
 
7
- def setup
8
- end
7
+ setup do
8
+ User.delete_all
9
+ @user = User.create!(:login => "joe", :email => "joe@example.org")
10
+ end
9
11
 
10
- def test_should_find_user_using_friendly_id
11
- assert User.find(users(:joe).friendly_id)
12
- end
12
+ should "have friendly_id options" do
13
+ assert_not_nil User.friendly_id_options
14
+ end
13
15
 
14
- def test_should_find_users_using_friendly_id
15
- assert User.find([users(:joe).friendly_id])
16
- end
16
+ should "not have a slug" do
17
+ assert !@user.respond_to?(:slug)
18
+ end
17
19
 
18
- def test_to_param_should_return_a_string
19
- assert_equal String, users(:joe).to_param.class
20
- end
20
+ should "be findable by its friendly_id" do
21
+ assert User.find(@user.friendly_id)
22
+ end
21
23
 
22
- def test_should_not_find_users_using_non_existent_friendly_ids
23
- assert_raises ActiveRecord::RecordNotFound do
24
- User.find(['bad', 'bad2'])
24
+ should "be findable by its regular id" do
25
+ assert User.find(@user.id)
25
26
  end
26
- end
27
-
28
- def test_finding_by_array_with_friendly_and_non_friendly_id_for_same_record_raises_error
29
- assert_raises ActiveRecord::RecordNotFound do
30
- User.find([users(:joe).id, "joe"]).size
27
+
28
+ should "respect finder conditions" do
29
+ assert_raises ActiveRecord::RecordNotFound do
30
+ User.find(@user.friendly_id, :conditions => "1 = 2")
31
+ end
31
32
  end
32
- end
33
33
 
34
- def test_finding_with_mixed_array_should_indicate_whether_found_by_numeric_or_friendly
35
- @users = User.find([users(:jane).id, "joe"], :order => "login ASC")
36
- assert @users[0].found_using_numeric_id?
37
- assert @users[1].found_using_friendly_id?
38
- end
34
+ should "indicate if it was found by its friendly id" do
35
+ @user = User.find(@user.friendly_id)
36
+ assert @user.found_using_friendly_id?
37
+ end
39
38
 
40
- def test_finder_options_are_not_ignored
41
- assert_raises ActiveRecord::RecordNotFound do
42
- User.find(users(:joe).friendly_id, :conditions => "1 = 2")
39
+ should "indicate if it was found by its numeric id" do
40
+ @user = User.find(@user.id)
41
+ assert @user.found_using_numeric_id?
43
42
  end
44
- assert_raises ActiveRecord::RecordNotFound do
45
- User.find([users(:joe).friendly_id], :conditions => "1 = 2")
43
+
44
+ should "indicate if it has a better id" do
45
+ @user = User.find(@user.id)
46
+ assert @user.has_better_id?
46
47
  end
47
- end
48
48
 
49
- def test_user_should_have_friendly_id_options
50
- assert_not_nil User.friendly_id_options
51
- end
49
+ should "not validate if the friendly_id text is reserved" do
50
+ @user = User.new(:login => "new", :email => "test@example.org")
51
+ assert !@user.valid?
52
+ end
52
53
 
53
- def test_user_should_not_be_found_using_friendly_id_unless_it_really_was
54
- assert !User.find(users(:joe).id).found_using_friendly_id?
55
- end
54
+ should "have always string for a friendly_id" do
55
+ assert_equal String, @user.to_param.class
56
+ end
56
57
 
57
- def test_users_should_not_be_found_using_friendly_id_unless_they_really_were
58
- @users = User.find([users(:jane).id])
59
- assert @users[0].found_using_numeric_id?
60
- end
58
+ should "return its id if the friendly_id is null" do
59
+ @user.login = nil
60
+ assert_equal @user.id.to_s, @user.to_param
61
+ end
61
62
 
62
- def test_user_should_be_considered_found_by_numeric_id_as_default
63
- @user = User.new
64
- assert @user.found_using_numeric_id?
65
- end
66
63
 
67
- def test_user_should_indicate_if_it_was_found_using_numeric_id
68
- @user = User.find(users(:joe).id)
69
- assert @user.found_using_numeric_id?
70
- assert !@user.found_using_friendly_id?
71
- end
64
+ context "when using an array as the find argument" do
72
65
 
73
- def test_user_should_indicate_if_it_was_found_using_friendly_id
74
- @user = User.find(users(:joe).friendly_id)
75
- assert !@user.found_using_numeric_id?
76
- assert @user.found_using_friendly_id?
77
- end
66
+ setup do
67
+ @user2 = User.create(:login => "jane", :email => "jane@example.org")
68
+ end
69
+
70
+ should "return results" do
71
+ assert_equal 2, User.find([@user.friendly_id, @user2.friendly_id]).size
72
+ end
73
+
74
+ should "not allow mixed friendly and non-friendly ids for the same record" do
75
+ assert_raises ActiveRecord::RecordNotFound do
76
+ User.find([@user.id, @user.friendly_id]).size
77
+ end
78
+ end
79
+
80
+ should "raise an error when all records are not found" do
81
+ assert_raises ActiveRecord::RecordNotFound do
82
+ User.find(['bad', 'bad2'])
83
+ end
84
+ end
85
+
86
+ should "indicate if the results were found using a friendly_id" do
87
+ @users = User.find([@user.id, @user2.friendly_id], :order => "login ASC")
88
+ assert @users[0].found_using_friendly_id?
89
+ assert @users[1].found_using_numeric_id?
90
+ end
91
+
92
+ end
78
93
 
79
- def test_should_indicate_there_is_a_better_id_if_found_by_numeric_id
80
- @user = User.find(users(:joe).id)
81
- assert @user.found_using_numeric_id?
82
- assert @user.has_better_id?
83
94
  end
84
95
 
85
96
  end
data/test/schema.rb CHANGED
@@ -1,35 +1,40 @@
1
- ActiveRecord::Schema.define(:version => 3) do
1
+ ActiveRecord::Schema.define(:version => 1) do
2
+
3
+ create_table "books", :force => true do |t|
4
+ t.column "title", "string"
5
+ t.column "type", "text"
6
+ end
2
7
 
3
8
  create_table "posts", :force => true do |t|
4
- t.string "name"
5
- t.text "content"
6
- t.datetime "created_at"
7
- t.datetime "updated_at"
9
+ t.column "title", "string"
10
+ t.column "content", "text"
11
+ t.column "created_at", "datetime"
12
+ t.column "updated_at", "datetime"
8
13
  end
9
14
 
10
15
  create_table "users", :force => true do |t|
11
- t.string "login"
12
- t.string "email"
13
- t.datetime "created_at"
14
- t.datetime "updated_at"
16
+ t.column "login", "string"
17
+ t.column "email", "string"
18
+ t.column "created_at", "datetime"
19
+ t.column "updated_at", "datetime"
15
20
  end
16
21
 
17
22
  create_table "people", :force => true do |t|
18
- t.string "name"
19
- t.integer "country_id"
23
+ t.column "name", "string"
24
+ t.column "country_id", "integer"
20
25
  end
21
26
 
22
27
  create_table "countries", :force => true do |t|
23
- t.string "name"
28
+ t.column "name", "string"
24
29
  end
25
30
 
26
31
  create_table "slugs", :force => true do |t|
27
- t.string "name"
28
- t.integer "sluggable_id"
29
- t.integer "sequence", :null => false, :default => 1
30
- t.string "sluggable_type", :limit => 40
31
- t.string "scope", :limit => 40
32
- t.datetime "created_at"
32
+ t.column "name", "string"
33
+ t.column "sluggable_id", "integer"
34
+ t.column "sequence", "integer", :null => false, :default => 1
35
+ t.column "sluggable_type", "string", :limit => 40
36
+ t.column "scope", "string", :limit => 40
37
+ t.column "created_at", "datetime"
33
38
  end
34
39
 
35
40
  add_index "slugs", ["sluggable_id"], :name => "index_slugs_on_sluggable_id"