<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>test/models/country.rb</filename>
    </added>
    <added>
      <filename>test/models/person.rb</filename>
    </added>
    <added>
      <filename>test/models/post.rb</filename>
    </added>
    <added>
      <filename>test/models/user.rb</filename>
    </added>
    <added>
      <filename>test/slugged_model_test.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,3 +1,13 @@
+== 2.0.2 2009-02-09
+
+* 2 major enhancements:
+  * Made FriendlyId depend only on ActiveRecord. It should now be possible to
+    use FriendlyId with Camping or any other codebase that uses AR.
+  * Overhauled creaky testing setup and switched to Shoulda.
+
+* 1 minor enhancment:
+  * Made reserved words work for non-slugged models.
+
 == 2.0.1 2009-01-19
 
 * 1 minor enhancements:</diff>
      <filename>History.txt</filename>
    </modified>
    <modified>
      <diff>@@ -14,32 +14,19 @@ 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/models/country.rb
+test/models/person.rb
+test/models/post.rb
+test/models/user.rb
 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/slugged_model_test.rb
 test/test_helper.rb</diff>
      <filename>Manifest.txt</filename>
    </modified>
    <modified>
      <diff>@@ -5,18 +5,15 @@ $hoe = Hoe.new(&quot;friendly_id&quot;, FriendlyId::Version::STRING) do |p|
   p.rubyforge_name = &quot;friendly-id&quot;
   p.author = ['Norman Clarke', 'Adrian Mugnolo', 'Emilio Tagua']
   p.email = ['norman@randomba.org', 'adrian@randomba.org', 'miloops@gmail.com']
-  p.summary = &quot;A comprehensive slugging and pretty-URL plugin for Ruby on Rails.&quot;
-  p.description = 'A comprehensive slugging and pretty-URL plugin for Ruby on Rails.'
-  p.url = 'http://randomba.org'
-  p.need_tar = true
-  p.need_zip = true
+  p.summary = &quot;A comprehensive slugging and pretty-URL plugin for ActiveRecord.&quot;
+  p.description = 'A comprehensive slugging and pretty-URL plugin for ActiveRecord.'
+  p.url = 'http://friendly-id.rubyforge.org/'
   p.test_globs = ['test/**/*_test.rb']
   p.extra_deps &lt;&lt; ['unicode', '&gt;= 0.1']
-  p.extra_dev_deps = [
-    ['newgem', &quot;&gt;= #{::Newgem::VERSION}&quot;]
-  ]
-  p.rdoc_pattern = /^(lib|bin|ext)|txt|rdoc$/
-  changes = p.paragraphs_of('History.txt', 0..1).join(&quot;\n\n&quot;)
+  p.extra_deps &lt;&lt; ['activerecord', '&gt;= 2.0.0']
+  p.extra_dev_deps &lt;&lt; ['newgem', &quot;&gt;= #{::Newgem::VERSION}&quot;]
+  p.extra_dev_deps &lt;&lt; ['Shoulda', &quot;&gt;= 1.2.0&quot;]
+  p.extra_dev_deps &lt;&lt; ['sqlite3-ruby']
   p.remote_rdoc_dir = &quot;&quot;
 end
 </diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -6,19 +6,20 @@ Gem::Specification.new do |s|
 
   s.required_rubygems_version = Gem::Requirement.new(&quot;&gt;= 0&quot;) if s.respond_to? :required_rubygems_version=
   s.authors = [&quot;Norman Clarke&quot;, &quot;Adrian Mugnolo&quot;, &quot;Emilio Tagua&quot;]
-  s.date = %q{2009-02-07}
-  s.description = %q{A comprehensive slugging and pretty-URL plugin for Ruby on Rails.}
+  s.cert_chain = [&quot;/Users/norman/.gem/gem-public_cert.pem&quot;]
+  s.date = %q{2009-02-09}
+  s.description = %q{A comprehensive slugging and pretty-URL plugin for ActiveRecord.}
   s.email = [&quot;norman@randomba.org&quot;, &quot;adrian@randomba.org&quot;, &quot;miloops@gmail.com&quot;]
   s.extra_rdoc_files = [&quot;History.txt&quot;, &quot;Manifest.txt&quot;, &quot;README.rdoc&quot;]
-  s.files = [&quot;History.txt&quot;, &quot;MIT-LICENSE&quot;, &quot;Manifest.txt&quot;, &quot;README.rdoc&quot;, &quot;Rakefile&quot;, &quot;config/website.yml&quot;, &quot;friendly_id.gemspec&quot;, &quot;generators/friendly_id/friendly_id_generator.rb&quot;, &quot;generators/friendly_id/templates/create_slugs.rb&quot;, &quot;generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb&quot;, &quot;generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb&quot;, &quot;init.rb&quot;, &quot;lib/friendly_id.rb&quot;, &quot;lib/friendly_id/helpers.rb&quot;, &quot;lib/friendly_id/non_sluggable_class_methods.rb&quot;, &quot;lib/friendly_id/non_sluggable_instance_methods.rb&quot;, &quot;lib/friendly_id/shoulda_macros.rb&quot;, &quot;lib/friendly_id/slug.rb&quot;, &quot;lib/friendly_id/sluggable_class_methods.rb&quot;, &quot;lib/friendly_id/sluggable_instance_methods.rb&quot;, &quot;lib/friendly_id/version.rb&quot;, &quot;lib/tasks/friendly_id.rake&quot;, &quot;lib/tasks/friendly_id.rb&quot;, &quot;test/database.yml&quot;, &quot;test/fixtures/countries.yml&quot;, &quot;test/fixtures/country.rb&quot;, &quot;test/fixtures/people.yml&quot;, &quot;test/fixtures/person.rb&quot;, &quot;test/fixtures/post.rb&quot;, &quot;test/fixtures/posts.yml&quot;, &quot;test/fixtures/slugs.yml&quot;, &quot;test/fixtures/user.rb&quot;, &quot;test/fixtures/users.yml&quot;, &quot;test/non_slugged_test.rb&quot;, &quot;test/rails/2.x/app/controllers/application.rb&quot;, &quot;test/rails/2.x/config/boot.rb&quot;, &quot;test/rails/2.x/config/database.yml&quot;, &quot;test/rails/2.x/config/environment.rb&quot;, &quot;test/rails/2.x/config/environments/test.rb&quot;, &quot;test/rails/2.x/config/routes.rb&quot;, &quot;test/schema.rb&quot;, &quot;test/scoped_model_test.rb&quot;, &quot;test/slug_test.rb&quot;, &quot;test/sluggable_test.rb&quot;, &quot;test/test_helper.rb&quot;]
+  s.files = [&quot;History.txt&quot;, &quot;MIT-LICENSE&quot;, &quot;Manifest.txt&quot;, &quot;README.rdoc&quot;, &quot;Rakefile&quot;, &quot;config/website.yml&quot;, &quot;friendly_id.gemspec&quot;, &quot;generators/friendly_id/friendly_id_generator.rb&quot;, &quot;generators/friendly_id/templates/create_slugs.rb&quot;, &quot;generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb&quot;, &quot;generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb&quot;, &quot;init.rb&quot;, &quot;lib/friendly_id.rb&quot;, &quot;lib/friendly_id/helpers.rb&quot;, &quot;lib/friendly_id/non_sluggable_class_methods.rb&quot;, &quot;lib/friendly_id/non_sluggable_instance_methods.rb&quot;, &quot;lib/friendly_id/slug.rb&quot;, &quot;lib/friendly_id/sluggable_class_methods.rb&quot;, &quot;lib/friendly_id/sluggable_instance_methods.rb&quot;, &quot;lib/friendly_id/version.rb&quot;, &quot;lib/tasks/friendly_id.rake&quot;, &quot;lib/tasks/friendly_id.rb&quot;, &quot;test/models/country.rb&quot;, &quot;test/models/person.rb&quot;, &quot;test/models/post.rb&quot;, &quot;test/models/user.rb&quot;, &quot;test/non_slugged_test.rb&quot;, &quot;test/schema.rb&quot;, &quot;test/scoped_model_test.rb&quot;, &quot;test/slug_test.rb&quot;, &quot;test/slugged_model_test.rb&quot;, &quot;test/test_helper.rb&quot;]
   s.has_rdoc = true
-  s.homepage = %q{http://randomba.org}
+  s.homepage = %q{http://friendly-id.rubyforge.org/}
   s.rdoc_options = [&quot;--main&quot;, &quot;README.rdoc&quot;]
   s.require_paths = [&quot;lib&quot;]
   s.rubyforge_project = %q{friendly-id}
   s.rubygems_version = %q{1.3.1}
-  s.summary = %q{A comprehensive slugging and pretty-URL plugin for Ruby on Rails.}
-  s.test_files = [&quot;test/non_slugged_test.rb&quot;, &quot;test/scoped_model_test.rb&quot;, &quot;test/slug_test.rb&quot;, &quot;test/sluggable_test.rb&quot;]
+  s.summary = %q{A comprehensive slugging and pretty-URL plugin for ActiveRecord.}
+  s.test_files = [&quot;test/non_slugged_test.rb&quot;, &quot;test/scoped_model_test.rb&quot;, &quot;test/slug_test.rb&quot;, &quot;test/slugged_model_test.rb&quot;]
 
   if s.respond_to? :specification_version then
     current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
@@ -26,16 +27,25 @@ Gem::Specification.new do |s|
 
     if Gem::Version.new(Gem::RubyGemsVersion) &gt;= Gem::Version.new('1.2.0') then
       s.add_runtime_dependency(%q&lt;unicode&gt;, [&quot;&gt;= 0.1&quot;])
+      s.add_runtime_dependency(%q&lt;active_record&gt;, [&quot;&gt;= 2.0.0&quot;])
       s.add_development_dependency(%q&lt;newgem&gt;, [&quot;&gt;= 1.2.3&quot;])
+      s.add_development_dependency(%q&lt;Shoulda&gt;, [&quot;&gt;= 1.2.0&quot;])
+      s.add_development_dependency(%q&lt;sqlite3-ruby&gt;, [&quot;&gt;= 0&quot;])
       s.add_development_dependency(%q&lt;hoe&gt;, [&quot;&gt;= 1.8.0&quot;])
     else
       s.add_dependency(%q&lt;unicode&gt;, [&quot;&gt;= 0.1&quot;])
+      s.add_dependency(%q&lt;active_record&gt;, [&quot;&gt;= 2.0.0&quot;])
       s.add_dependency(%q&lt;newgem&gt;, [&quot;&gt;= 1.2.3&quot;])
+      s.add_dependency(%q&lt;Shoulda&gt;, [&quot;&gt;= 1.2.0&quot;])
+      s.add_dependency(%q&lt;sqlite3-ruby&gt;, [&quot;&gt;= 0&quot;])
       s.add_dependency(%q&lt;hoe&gt;, [&quot;&gt;= 1.8.0&quot;])
     end
   else
     s.add_dependency(%q&lt;unicode&gt;, [&quot;&gt;= 0.1&quot;])
+    s.add_dependency(%q&lt;active_record&gt;, [&quot;&gt;= 2.0.0&quot;])
     s.add_dependency(%q&lt;newgem&gt;, [&quot;&gt;= 1.2.3&quot;])
+    s.add_dependency(%q&lt;Shoulda&gt;, [&quot;&gt;= 1.2.0&quot;])
+    s.add_dependency(%q&lt;sqlite3-ruby&gt;, [&quot;&gt;= 0&quot;])
     s.add_dependency(%q&lt;hoe&gt;, [&quot;&gt;= 1.8.0&quot;])
   end
 end</diff>
      <filename>friendly_id.gemspec</filename>
    </modified>
    <modified>
      <diff>@@ -1,20 +1,35 @@
 require 'friendly_id/helpers'
 require 'friendly_id/slug'
-require 'friendly_id/shoulda_macros'
-
 
 # FriendlyId is a comprehensize Rails plugin/gem for slugging and permalinks.
 module FriendlyId
 
+  # Default options for has_friendly_id.
+  DEFAULT_FRIENDLY_ID_OPTIONS = {
+    :max_length =&gt; 255,
+    :method =&gt; nil,
+    :reserved =&gt; [&quot;new&quot;, &quot;index&quot;],
+    :reserved_message =&gt; 'can not be &quot;%s&quot;',
+    :scope =&gt; nil,
+    :strip_diacritics =&gt; false,
+    :strip_non_ascii =&gt; false,
+    :use_slug =&gt; false }.freeze
+  
+  # Valid keys for has_friendly_id options.
+  VALID_FRIENDLY_ID_KEYS = [
+    :max_length,
+    :reserved,
+    :reserved_message,
+    :scope,
+    :strip_diacritics,
+    :strip_non_ascii,
+    :use_slug ].freeze
+    
   # This error is raised when it's not possible to generate a unique slug.
   class SlugGenerationError &lt; StandardError ; end
 
   module ClassMethods
 
-    # Default options for friendly_id.
-    DEFAULT_FRIENDLY_ID_OPTIONS = {:method =&gt; nil, :use_slug =&gt; false, :max_length =&gt; 255, :reserved =&gt; [], :strip_diacritics =&gt; false, :strip_non_ascii =&gt; false, :scope =&gt; nil}.freeze
-    VALID_FRIENDLY_ID_KEYS = [:use_slug, :max_length, :reserved, :strip_diacritics, :strip_non_ascii, :scope].freeze
-
     # Set up an ActiveRecord model to use a friendly_id.
     #
     # The column argument can be one of your model's columns, or a method
@@ -25,12 +40,13 @@ module FriendlyId
     # * &lt;tt&gt;:max_length&lt;/tt&gt; - Defaults to 255. The maximum allowed length for a slug.
     # * &lt;tt&gt;:strip_diacritics&lt;/tt&gt; - Defaults to false. If true, it will remove accents, umlauts, etc. from western characters.
     # * &lt;tt&gt;:strip_non_ascii&lt;/tt&gt; - Defaults to false. If true, it will all non-ascii ([^a-z0-9]) characters.
-    # * &lt;tt&gt;:reseved&lt;/tt&gt; - 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 [].
+    # * &lt;tt&gt;:reseved&lt;/tt&gt; - 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 [&quot;new&quot;, &quot;index&quot;].
+    # * &lt;tt&gt;:reseved_message&lt;/tt&gt; - The validation message that will be shown when a reserved word is used as a frindly_id. Defaults to '&quot;%s&quot; is reserved'.
     def has_friendly_id(column, options = {})
       options.assert_valid_keys VALID_FRIENDLY_ID_KEYS
       options = DEFAULT_FRIENDLY_ID_OPTIONS.merge(options).merge(:column =&gt; column)
       write_inheritable_attribute :friendly_id_options, options
-      class_inheritable_reader :friendly_id_options
+      class_inheritable_accessor :friendly_id_options
 
       if options[:use_slug]
         has_many :slugs, :order =&gt; 'id DESC', :as =&gt; :sluggable, :dependent =&gt; :destroy
@@ -44,9 +60,10 @@ module FriendlyId
         require 'friendly_id/non_sluggable_instance_methods'
         extend NonSluggableClassMethods
         include NonSluggableInstanceMethods
+        validate_on_create :validate_friendly_id
       end
     end
-
+    
   end
 
   class &lt;&lt; self
@@ -55,15 +72,6 @@ module FriendlyId
     def enable
       return if ActiveRecord::Base.methods.include? 'has_friendly_id'
       ActiveRecord::Base.class_eval { extend FriendlyId::ClassMethods }
-      begin
-        if Rails.version &gt;= &quot;2.3&quot;
-          ActiveSupport::TestCase.class_eval { include FriendlyId::ShouldaMacros }
-        else
-          Test::Unit::TestCase.class_eval { include FriendlyId::ShouldaMacros }
-        end
-      rescue NoMethodError
-        Test::Unit::TestCase.class_eval { include FriendlyId::ShouldaMacros }
-      end
     end
 
   end</diff>
      <filename>lib/friendly_id.rb</filename>
    </modified>
    <modified>
      <diff>@@ -21,17 +21,17 @@ module FriendlyId::NonSluggableClassMethods
   end
 
   def find_some_with_friendly(ids_and_names, options) #:nodoc:#
-    
+
     results = with_scope :find =&gt; options do
-      find :all, :conditions =&gt; [&quot;#{ quoted_table_name }.#{ primary_key } IN (?) OR #{friendly_id_options[:column].to_s} IN (?)&quot;,
+      find :all, :conditions =&gt; [&quot;#{quoted_table_name}.#{primary_key} IN (?) OR #{friendly_id_options[:column].to_s} IN (?)&quot;,
         ids_and_names, ids_and_names]
     end
-    
+
     expected = expected_size(ids_and_names, options)
     if results.size != expected
       raise ActiveRecord::RecordNotFound, &quot;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 })&quot;
     end
-    
+
     results.each {|r| r.send(:found_using_friendly_id=, true) if ids_and_names.include?(r.friendly_id)}
 
     results</diff>
      <filename>lib/friendly_id/non_sluggable_class_methods.rb</filename>
    </modified>
    <modified>
      <diff>@@ -25,6 +25,14 @@ module FriendlyId::NonSluggableInstanceMethods
   end
 
   private
+  
+  def validate_friendly_id
+    if self.class.friendly_id_options[:reserved].include? friendly_id
+      self.errors.add(self.class.friendly_id_options[:column],
+        self.class.friendly_id_options[:reserved_message] % friendly_id)
+      return false
+    end
+  end
 
   def found_using_friendly_id=(value) #:nodoc#
     @found_using_friendly_id = value</diff>
      <filename>lib/friendly_id/non_sluggable_instance_methods.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,4 @@
+require 'unicode'
 # A Slug is a unique, human-friendly identifier for an ActiveRecord.
 class Slug &lt; ActiveRecord::Base
 
@@ -23,12 +24,12 @@ class Slug &lt; ActiveRecord::Base
     # terror in Europe unlike anything ever seen before or after. I'm not
     # taking any chances.
     def normalize(slug_text)
-      return &quot;&quot; if slug_text.blank?
-      slug_text.
+      return &quot;&quot; if slug_text.nil? || slug_text == &quot;&quot;
+      Unicode::normalize_KC(slug_text).
         send(chars_func).
         # For some reason Spanish &#161; and &#191; are not detected as non-word
         # characters. Bug in Ruby?
-        normalize.gsub(/[\W|&#161;|&#191;]/u, ' ').
+        gsub(/[\W|&#161;|&#191;]/u, ' ').
         strip.
         gsub(/\s+/u, '-').
         gsub(/-\z/u, '').
@@ -42,12 +43,10 @@ class Slug &lt; ActiveRecord::Base
       return name, sequence
     end
 
-    # Remove diacritics (accents, umlauts, etc.) from the string.
+    # Remove diacritics (accents, umlauts, etc.) from the string. Borrowed
+    # from &quot;The Ruby Way.&quot;
     def strip_diacritics(string)
-      require 'unicode'
-      Unicode::normalize_KD(string).unpack('U*').select { |cp|
-        cp &lt; 0x300 || cp &gt; 0x036F
-      }.pack('U*')
+      Unicode::normalize_KD(string).unpack('U*').select { |u| u &lt; 0x300 || u &gt; 0x036F }.pack('U*')
     end
     
     # Remove non-ascii characters from the string.
@@ -58,9 +57,7 @@ class Slug &lt; ActiveRecord::Base
     private
 
     def chars_func
-      Rails.version &gt;= &quot;2.2&quot; ? :mb_chars : :chars
-    rescue NoMethodError
-      :chars
+      &quot;&quot;.respond_to?(:mb_chars) ? :mb_chars : :chars
     end
 
   end
@@ -78,7 +75,7 @@ class Slug &lt; ActiveRecord::Base
 
   # Raise a FriendlyId::SlugGenerationError if the slug name is blank.
   def check_for_blank_name #:nodoc:#
-    if name.blank?
+    if name == &quot;&quot; || name.nil?
       raise FriendlyId::SlugGenerationError.new(&quot;The slug text is blank.&quot;)
     end
   end</diff>
      <filename>lib/friendly_id/slug.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
 module FriendlyId::SluggableClassMethods
-  
+
   include FriendlyId::Helpers
 
   def self.extended(base) #:nodoc:#
@@ -38,6 +38,17 @@ module FriendlyId::SluggableClassMethods
     end
 
     result
+  rescue ActiveRecord::RecordNotFound =&gt; e
+
+    if friendly_id_options[:scope]
+      if !scope
+        e.message &lt;&lt; &quot;; expected scope but got none&quot;
+      else
+        e.message &lt;&lt; &quot; and scope=#{scope}&quot;
+      end
+    end
+
+    raise e
 
   end
 </diff>
      <filename>lib/friendly_id/sluggable_class_methods.rb</filename>
    </modified>
    <modified>
      <diff>@@ -6,7 +6,7 @@ module FriendlyId::SluggableInstanceMethods
   attr_accessor :finder_slug_name
 
   def finder_slug
-    @finder_slug ||= init_finder_slug
+    @finder_slug ||= init_finder_slug or nil
   end
 
   # Was the record found using one of its friendly ids?</diff>
      <filename>lib/friendly_id/sluggable_instance_methods.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,84 +2,89 @@ require File.dirname(__FILE__) + '/test_helper'
 
 class NonSluggedTest &lt; Test::Unit::TestCase
 
-  fixtures :users
+  context &quot;A non-slugged model with default FriendlyId options&quot; do
 
-  def setup
-  end
+    setup do
+      User.delete_all
+      @user = User.create!(:login =&gt; &quot;joe&quot;, :email =&gt; &quot;joe@example.org&quot;)
+    end
 
-  def test_should_find_user_using_friendly_id
-    assert User.find(users(:joe).friendly_id)
-  end
+    should &quot;have friendly_id options&quot; do
+      assert_not_nil User.friendly_id_options
+    end
 
-  def test_should_find_users_using_friendly_id
-    assert User.find([users(:joe).friendly_id])
-  end
+    should &quot;not have a slug&quot; do
+      assert !@user.respond_to?(:slug)
+    end
 
-  def test_to_param_should_return_a_string
-    assert_equal String, users(:joe).to_param.class
-  end
+    should &quot;be findable by its friendly_id&quot; do
+      assert User.find(@user.friendly_id)
+    end
 
-  def test_should_not_find_users_using_non_existent_friendly_ids
-    assert_raises ActiveRecord::RecordNotFound do
-      User.find(['bad', 'bad2'])
+    should &quot;be findable by its regular id&quot; do
+      assert User.find(@user.id)
     end
-  end
-  
-  def test_finding_by_array_with_friendly_and_non_friendly_id_for_same_record_raises_error
-    assert_raises ActiveRecord::RecordNotFound do
-      User.find([users(:joe).id, &quot;joe&quot;]).size
+
+    should &quot;respect finder conditions&quot; do
+      assert_raises ActiveRecord::RecordNotFound do
+        User.find(@user.friendly_id, :conditions =&gt; &quot;1 = 2&quot;)
+      end
     end
-  end
 
-  def test_finding_with_mixed_array_should_indicate_whether_found_by_numeric_or_friendly
-    @users = User.find([users(:jane).id, &quot;joe&quot;], :order =&gt; &quot;login ASC&quot;)
-    assert @users[0].found_using_numeric_id?
-    assert @users[1].found_using_friendly_id?
-  end
+    should &quot;indicate if it was found by its friendly id&quot; do
+      @user = User.find(@user.friendly_id)
+      assert @user.found_using_friendly_id?
+    end
 
-  def test_finder_options_are_not_ignored
-    assert_raises ActiveRecord::RecordNotFound do
-       User.find(users(:joe).friendly_id, :conditions =&gt; &quot;1 = 2&quot;)
+    should &quot;indicate if it was found by its numeric id&quot; do
+      @user = User.find(@user.id)
+      assert @user.found_using_numeric_id?
     end
-    assert_raises ActiveRecord::RecordNotFound do
-       User.find([users(:joe).friendly_id], :conditions =&gt; &quot;1 = 2&quot;)
+
+    should &quot;indicate if it has a better id&quot; do
+      @user = User.find(@user.id)
+      assert @user.has_better_id?
     end
-  end
 
-  def test_user_should_have_friendly_id_options
-    assert_not_nil User.friendly_id_options
-  end
+    should &quot;not validate if the friendly_id text is reserved&quot; do
+      @user = User.new(:login =&gt; &quot;new&quot;, :email =&gt; &quot;test@example.org&quot;)
+      assert !@user.valid?
+    end
 
-  def test_user_should_not_be_found_using_friendly_id_unless_it_really_was
-    assert !User.find(users(:joe).id).found_using_friendly_id?
-  end
+    should &quot;have always string for a friendly_id&quot; do
+      assert_equal String, @user.to_param.class
+    end
 
-  def test_users_should_not_be_found_using_friendly_id_unless_they_really_were
-    @users = User.find([users(:jane).id])
-    assert @users[0].found_using_numeric_id?
-  end
+    context &quot;when using an array as the find argument&quot; do
 
-  def test_user_should_be_considered_found_by_numeric_id_as_default
-    @user = User.new
-    assert @user.found_using_numeric_id?
-  end
+      setup do
+        @user2 = User.create(:login =&gt; &quot;jane&quot;, :email =&gt; &quot;jane@example.org&quot;)
+      end
 
-  def test_user_should_indicate_if_it_was_found_using_numeric_id
-    @user = User.find(users(:joe).id)
-    assert @user.found_using_numeric_id?
-    assert !@user.found_using_friendly_id?
-  end
+      should &quot;return results&quot; do
+        assert_equal 2, User.find([@user.friendly_id, @user2.friendly_id]).size
+      end
 
-  def test_user_should_indicate_if_it_was_found_using_friendly_id
-    @user = User.find(users(:joe).friendly_id)
-    assert !@user.found_using_numeric_id?
-    assert @user.found_using_friendly_id?
-  end
+      should &quot;not allow mixed friendly and non-friendly ids for the same record&quot; do
+        assert_raises ActiveRecord::RecordNotFound do
+          User.find([@user.id, @user.friendly_id]).size
+        end
+      end
+
+      should &quot;raise an error when all records are not found&quot; do
+        assert_raises ActiveRecord::RecordNotFound do
+          User.find(['bad', 'bad2'])
+        end
+      end
+
+      should &quot;indicate if the results were found using a friendly_id&quot; do
+        @users = User.find([@user.id, @user2.friendly_id], :order =&gt; &quot;login ASC&quot;)
+        assert @users[0].found_using_friendly_id?
+        assert @users[1].found_using_numeric_id?
+      end
+
+    end
 
-  def test_should_indicate_there_is_a_better_id_if_found_by_numeric_id
-    @user = User.find(users(:joe).id)
-    assert @user.found_using_numeric_id?
-    assert @user.has_better_id?
   end
 
 end
\ No newline at end of file</diff>
      <filename>test/non_slugged_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,35 +1,35 @@
-ActiveRecord::Schema.define(:version =&gt; 3) do
+ActiveRecord::Schema.define(:version =&gt; 1) do
 
   create_table &quot;posts&quot;, :force =&gt; true do |t|
-    t.string   &quot;name&quot;
-    t.text     &quot;content&quot;
-    t.datetime &quot;created_at&quot;
-    t.datetime &quot;updated_at&quot;
+    t.column &quot;title&quot;, &quot;string&quot;
+    t.column &quot;content&quot;, &quot;text&quot;
+    t.column &quot;created_at&quot;, &quot;datetime&quot;
+    t.column &quot;updated_at&quot;, &quot;datetime&quot;
   end
 
   create_table &quot;users&quot;, :force =&gt; true do |t|
-    t.string   &quot;login&quot;
-    t.string   &quot;email&quot;
-    t.datetime &quot;created_at&quot;
-    t.datetime &quot;updated_at&quot;
+    t.column &quot;login&quot;, &quot;string&quot;
+    t.column &quot;email&quot;, &quot;string&quot;
+    t.column &quot;created_at&quot;, &quot;datetime&quot;
+    t.column &quot;updated_at&quot;, &quot;datetime&quot;
   end
   
   create_table &quot;people&quot;, :force =&gt; true do |t|
-    t.string &quot;name&quot;
-    t.integer &quot;country_id&quot;
+    t.column &quot;name&quot;, &quot;string&quot;
+    t.column &quot;country_id&quot;, &quot;integer&quot;
   end
   
   create_table &quot;countries&quot;, :force =&gt; true do |t|
-    t.string &quot;name&quot;
+    t.column &quot;name&quot;, &quot;string&quot;
   end
 
   create_table &quot;slugs&quot;, :force =&gt; true do |t|
-    t.string &quot;name&quot;
-    t.integer &quot;sluggable_id&quot;
-    t.integer &quot;sequence&quot;, :null       =&gt; false, :default =&gt; 1
-    t.string &quot;sluggable_type&quot;, :limit =&gt; 40
-    t.string &quot;scope&quot;, :limit          =&gt; 40
-    t.datetime &quot;created_at&quot;
+    t.column &quot;name&quot;, &quot;string&quot;
+    t.column &quot;sluggable_id&quot;, &quot;integer&quot;
+    t.column &quot;sequence&quot;, &quot;integer&quot;, :null       =&gt; false, :default =&gt; 1
+    t.column &quot;sluggable_type&quot;, &quot;string&quot;, :limit =&gt; 40
+    t.column &quot;scope&quot;, &quot;string&quot;, :limit          =&gt; 40
+    t.column &quot;created_at&quot;, &quot;datetime&quot;
   end
 
   add_index &quot;slugs&quot;, [&quot;sluggable_id&quot;], :name           =&gt; &quot;index_slugs_on_sluggable_id&quot;</diff>
      <filename>test/schema.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,20 +2,50 @@ require File.dirname(__FILE__) + '/test_helper'
 
 class ScopedModelTest &lt; Test::Unit::TestCase
 
-  fixtures :people, :countries, :slugs
-  
-  def test_should_find_scoped_records_without_scope
-    assert_equal 2, Person.find(:all, &quot;john-smith&quot;).size
-  end
+  context &quot;A slugged model that uses a scope&quot; do
+
+    setup do
+      Person.delete_all
+      Country.delete_all
+      Slug.delete_all
+      @usa = Country.create!(:name =&gt; &quot;USA&quot;)
+      @canada = Country.create!(:name =&gt; &quot;Canada&quot;)
+      @person = Person.create!(:name =&gt; &quot;John Smith&quot;, :country =&gt; @usa)
+      @person2 = Person.create!(:name =&gt; &quot;John Smith&quot;, :country =&gt; @canada)
+    end
+
+    should &quot;find all scoped records without scope&quot; do
+      assert_equal 2, Person.find(:all, @person.friendly_id).size
+    end
+
+    should &quot;find a single scoped records with a scope&quot; do
+      assert Person.find(@person.friendly_id, :scope =&gt; @person.country.to_param)
+    end
+
+    should &quot;raise an error when finding a single scoped record with no scope&quot; do
+      assert_raises ActiveRecord::RecordNotFound do
+        Person.find(@person.friendly_id)
+      end
+    end
+
+    should &quot;append scope error info when missing scope causes a find to fail&quot; do
+      begin
+        Person.find(@person.friendly_id)
+        fail &quot;The find should not have succeeded&quot;
+      rescue ActiveRecord::RecordNotFound =&gt; e
+        assert_match /expected scope/, e.message
+      end
+    end
+
+    should &quot;append scope error info when the scope value causes a find to fail&quot; do
+      begin
+        Person.find(@person.friendly_id, :scope =&gt; &quot;badscope&quot;)
+        fail &quot;The find should not have succeeded&quot;
+      rescue ActiveRecord::RecordNotFound =&gt; e
+        assert_match /scope=badscope/, e.message
+      end
+    end
 
-  def test_should_find_scoped_records_with_scope
-    assert_equal people(:john_smith), Person.find(&quot;john-smith&quot;, :scope =&gt; &quot;argentina&quot;)
-    assert_equal people(:john_smith2), Person.find(&quot;john-smith&quot;, :scope =&gt; &quot;usa&quot;)
-  end
-  
-  def test_should_create_scoped_records_with_scope
-    person = Person.create!(:name =&gt; &quot;Joe Schmoe&quot;, :country =&gt; countries(:usa))
-    assert_equal &quot;usa&quot;, person.slug.scope
   end
 
 end
\ No newline at end of file</diff>
      <filename>test/scoped_model_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,87 +1,106 @@
+# encoding: utf-8
+
 require File.dirname(__FILE__) + '/test_helper'
 
 class SlugTest &lt; Test::Unit::TestCase
 
-  fixtures :posts, :slugs
-
-  def test_should_indicate_if_it_is_the_most_recent
-    assert slugs(:two_new).is_most_recent?
-    assert !slugs(:two_old).is_most_recent?
-  end
-
-  def test_parse_should_return_slug_name_and_sequence
-    assert_equal [&quot;test&quot;, &quot;2&quot;], Slug::parse(&quot;test--2&quot;)
-  end
-
-  def test_parse_should_return_a_default_sequnce_of_1
-    assert_equal [&quot;test&quot;, &quot;1&quot;], Slug::parse(&quot;test&quot;)
-  end
-
-  def test_strip_diacritics_should_strip_diacritics
-    assert_equal &quot;acai&quot;, Slug::strip_diacritics(&quot;a&#231;a&#237;&quot;)
-  end
-
-  def test_to_friendly_id_should_include_sequence_if_its_greater_than_1
-    slug = Slug.new(:name =&gt; &quot;test&quot;, :sequence =&gt; 2)
-    assert_equal &quot;test--2&quot;, slug.to_friendly_id
-  end
-
-  def test_to_friendly_id_should_include_sequence_if_its_than_1
-    slug = Slug.new(:name =&gt; &quot;test&quot;, :sequence =&gt; 1)
-    assert_equal &quot;test&quot;, slug.to_friendly_id
-  end
-
-  def test_normalize_should_lowercase_strings
-    assert_match /abc/, Slug::normalize(&quot;ABC&quot;)
-  end
-
-  def test_normalize_should_replace_whitespace_with_dashes
-    assert_match /a-b/, Slug::normalize(&quot;a b&quot;)
-  end
-
-  def test_normalize_should_replace_2spaces_with_1dash
-    assert_match /a-b/, Slug::normalize(&quot;a  b&quot;)
-  end
-
-  def test_normalize_should_remove_punctuation
-    assert_match /abc/, Slug::normalize('abc!@#$%^&amp;*&#8226;&#182;&#167;&#8734;&#162;&#163;&#163;&#161;&#191;()&gt;&lt;?&quot;&quot;:;][]\.,/')
-  end
-
-  def test_normalize_should_strip_trailing_space
-    assert_match /ab/, Slug::normalize(&quot;ab &quot;)
-  end
-
-  def test_normalize_should_strip_leading_space
-    assert_match /ab/, Slug::normalize(&quot; ab&quot;)
-  end
-
-  def test_normalize_should_strip_trailing_slashes
-    assert_match /ab/, Slug::normalize(&quot;ab-&quot;)
-  end
+  context &quot;a slug&quot; do
+    
+    setup do
+      Slug.delete_all
+      Post.delete_all
+    end
 
-  def test_normalize_should_strip_leading_slashes
-    assert_match /ab/, Slug::normalize(&quot;-ab&quot;)
-  end
+    should &quot;indicate if it is the most recent slug&quot; do
+      @post = Post.create!(:title =&gt; &quot;test title&quot;, :content =&gt; &quot;test content&quot;)
+      @post.title = &quot;a new title&quot;
+      @post.save!
+      assert @post.slugs.last.is_most_recent?
+      assert !@post.slugs.first.is_most_recent?
+    end
 
-  def test_normalize_should_not_modify_valid_name_strings
-    assert_match /a-b-c-d/, Slug::normalize(&quot;a-b-c-d&quot;)
   end
+  
+  context &quot;the Slug class&quot; do
+    
+    should &quot;parse the slug name and sequence&quot; do
+      assert_equal [&quot;test&quot;, &quot;2&quot;], Slug::parse(&quot;test--2&quot;)
+    end
+    
+    should &quot;parse with a default sequence of 1&quot; do
+      assert_equal [&quot;test&quot;, &quot;1&quot;], Slug::parse(&quot;test&quot;)
+    end
 
-  # These strings are taken from various international Google homepages. I
-  # would be most grateful if a fluent speaker of any language that uses a
-  # writing system other than the Roman alphabet could help me make some
-  # better tests to ensure this is working correctly.
-  def test_normalize_works_with_non_roman_chars
-    assert_equal &quot;&#26908;-&#32034;&quot;, Slug::normalize(&quot;&#26908; &#32034;&quot;)
+    should &quot;should strip diacritics&quot; do
+      assert_equal &quot;acai&quot;, Slug::strip_diacritics(&quot;a&#231;a&#237;&quot;)
+    end
+  
+    should &quot;strip diacritics correctly &quot; do
+      input  = &quot;&#192;&#193;&#194;&#195;&#196;&#197;&#198;&#199;&#200;&#202;&#203;&#204;&#205;&#206;&#207;&#208;&#209;&#210;&#211;&#212;&#213;&#214;&#216;&#217;&#218;&#219;&#220;&#221;&#222;&#223;&#224;&#225;&#226;&#227;&#228;&#229;&#230;&#231;&#232;&#233;&#234;&#235;&#236;&#237;&#238;&#239;&#240;&#241;&#242;&#243;&#244;&#245;&#246;&#248;&#249;&#250;&#251;&#252;&#253;&#254;&#255;&quot;
+      output = Slug::strip_diacritics(input).split(//)
+      expected = &quot;AAAAAAAECEEEIIIIDNOOOOOOUUUUYThssaaaaaaaeceeeeiiiidnoooooouuuuythy&quot;.split(//)
+      output.split.each_index do |i|
+        assert_equal output[i], expected[i]
+      end
+    end
+  
   end
-
-  def test_strip_diactics_correctly_strips_diacritics
-    input  = &quot;&#192;&#193;&#194;&#195;&#196;&#197;&#198;&#199;&#200;&#202;&#203;&#204;&#205;&#206;&#207;&#208;&#209;&#210;&#211;&#212;&#213;&#214;&#216;&#217;&#218;&#219;&#220;&#221;&#222;&#223;&#224;&#225;&#226;&#227;&#228;&#229;&#230;&#231;&#232;&#233;&#234;&#235;&#236;&#237;&#238;&#239;&#240;&#241;&#242;&#243;&#244;&#245;&#246;&#248;&#249;&#250;&#251;&#252;&#253;&#254;&#255;&quot;
-    output = Slug::strip_diacritics(input).split(//)
-    expected = &quot;AAAAAAAECEEEIIIIDNOOOOOOUUUUYThssaaaaaaaeceeeeiiiidnoooooouuuuythy&quot;.split(//)
-    output.split.each_index do |i|
-      assert_equal output[i], expected[i]
+  
+  context &quot;the Slug class's to_friendly_id method&quot; do
+    
+    should &quot;include the sequence if the sequence is greater than 1&quot; do
+      slug = Slug.new(:name =&gt; &quot;test&quot;, :sequence =&gt; 2)
+      assert_equal &quot;test--2&quot;, slug.to_friendly_id
     end
+  
+    should &quot;not include the sequence if the sequence is 1&quot; do
+      slug = Slug.new(:name =&gt; &quot;test&quot;, :sequence =&gt; 1)
+      assert_equal &quot;test&quot;, slug.to_friendly_id
+    end
+    
   end
   
+  context &quot;the Slug class's normalize method&quot; do  
+    
+    should &quot;should lowercase  strings&quot; do
+      assert_match /abc/, Slug::normalize(&quot;ABC&quot;)
+    end
+  
+    should &quot;should replace whitespace with dashes&quot; do
+      assert_match /a-b/, Slug::normalize(&quot;a b&quot;)
+    end
+  
+    should &quot;should replace 2spaces with 1dash&quot; do
+      assert_match /a-b/, Slug::normalize(&quot;a  b&quot;)
+    end
+  
+    should &quot;should remove punctuation&quot; do
+      assert_match /abc/, Slug::normalize('abc!@#$%^&amp;*&#8226;&#182;&#167;&#8734;&#162;&#163;&#163;&#161;&#191;()&gt;&lt;?&quot;&quot;:;][]\.,/')
+    end
+  
+    should &quot;should strip trailing space&quot; do
+      assert_match /ab/, Slug::normalize(&quot;ab &quot;)
+    end
+  
+    should &quot;should strip leading space&quot; do
+      assert_match /ab/, Slug::normalize(&quot; ab&quot;)
+    end
+  
+    should &quot;should strip trailing slashes&quot; do
+      assert_match /ab/, Slug::normalize(&quot;ab-&quot;)
+    end
+  
+    should &quot;should strip leading slashes&quot; do
+      assert_match /ab/, Slug::normalize(&quot;-ab&quot;)
+    end
+  
+    should &quot;should not modify valid name strings&quot; do
+      assert_match /a-b-c-d/, Slug::normalize(&quot;a-b-c-d&quot;)
+    end
+  
+    should &quot;work with non roman chars&quot; do
+      assert_equal &quot;&#26908;-&#32034;&quot;, Slug::normalize(&quot;&#26908; &#32034;&quot;)
+    end
+  
+  end
 end
\ No newline at end of file</diff>
      <filename>test/slug_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,35 +1,33 @@
 $:.unshift(File.dirname(__FILE__) + '/../lib')
-$VERBOSE = false
-
-ENV['RAILS_ENV'] = 'test'
-require File.dirname(__FILE__) + '/rails/2.x/config/environment.rb'
-ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + &quot;/debug.log&quot;)
-
+$:.unshift(File.dirname(__FILE__))
+$VERBOSE=false
+require 'rubygems'
 require 'test/unit'
-require 'active_record/fixtures'
-require 'action_controller/test_process'
-require 'sqlite3'
-require 'friendly_id/slug'
-
-config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
-ActiveRecord::Base.establish_connection
-
-silence_stream(STDOUT) do
-  load(File.dirname(__FILE__) + &quot;/schema.rb&quot;)
+require 'shoulda'
+# You can use &quot;rake test AR_VERSION=2.0.5&quot; to test against 2.0.5, for example.
+# The default is to use the latest installed ActiveRecord.
+if ENV[&quot;AR_VERSION&quot;]
+  gem 'activerecord', &quot;#{ENV[&quot;AR_VERSION&quot;]}&quot;
 end
+require 'active_record'
 
-Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + &quot;/fixtures&quot;
-$LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path)
+require 'friendly_id'
+require 'models/post'
+require 'models/person'
+require 'models/user'
+require 'models/country'
 
-class Test::Unit::TestCase #:nodoc:
-  include ActionController::TestProcess
-  def create_fixtures(*table_names)
-    if block_given?
-      Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names) { yield }
-    else
-      Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names)
-    end
-  end
-  self.use_transactional_fixtures = true
-  self.use_instantiated_fixtures  = false
+# Borrowed from ActiveSupport
+def silence_stream(stream)
+  old_stream = stream.dup
+  stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null')
+  stream.sync = true
+  yield
+ensure
+  stream.reopen(old_stream)
 end
+
+ActiveRecord::Base.establish_connection :adapter =&gt; &quot;sqlite3&quot;, :database =&gt; &quot;:memory:&quot;
+silence_stream(STDOUT) do
+  load(File.dirname(__FILE__) + &quot;/schema.rb&quot;)
+end
\ No newline at end of file</diff>
      <filename>test/test_helper.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>lib/friendly_id/shoulda_macros.rb</filename>
    </removed>
    <removed>
      <filename>test/database.yml</filename>
    </removed>
    <removed>
      <filename>test/fixtures/countries.yml</filename>
    </removed>
    <removed>
      <filename>test/fixtures/country.rb</filename>
    </removed>
    <removed>
      <filename>test/fixtures/people.yml</filename>
    </removed>
    <removed>
      <filename>test/fixtures/person.rb</filename>
    </removed>
    <removed>
      <filename>test/fixtures/post.rb</filename>
    </removed>
    <removed>
      <filename>test/fixtures/posts.yml</filename>
    </removed>
    <removed>
      <filename>test/fixtures/slugs.yml</filename>
    </removed>
    <removed>
      <filename>test/fixtures/user.rb</filename>
    </removed>
    <removed>
      <filename>test/fixtures/users.yml</filename>
    </removed>
    <removed>
      <filename>test/rails/2.x/app/controllers/application.rb</filename>
    </removed>
    <removed>
      <filename>test/rails/2.x/config/boot.rb</filename>
    </removed>
    <removed>
      <filename>test/rails/2.x/config/database.yml</filename>
    </removed>
    <removed>
      <filename>test/rails/2.x/config/environment.rb</filename>
    </removed>
    <removed>
      <filename>test/rails/2.x/config/environments/test.rb</filename>
    </removed>
    <removed>
      <filename>test/rails/2.x/config/routes.rb</filename>
    </removed>
    <removed>
      <filename>test/sluggable_test.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>88f6fad0c0535ad6584537ffbd5e9720f4eb2ac8</id>
    </parent>
  </parents>
  <author>
    <name>Norman Clarke</name>
    <email>norman@randomba.org</email>
  </author>
  <url>http://github.com/norman/friendly_id/commit/10e757ad3fcedb0c798b2532b823678e8ef2314e</url>
  <id>10e757ad3fcedb0c798b2532b823678e8ef2314e</id>
  <committed-date>2009-02-09T11:56:42-08:00</committed-date>
  <authored-date>2009-02-09T07:13:53-08:00</authored-date>
  <message>Made reserved words work for non-slugged models. Remove dependencies on Rails
in favor of ActiveRecord. Overhauled creaky testing setup and switched it over
to Shoulda.</message>
  <tree>21682b4c94095abb9b2a4e0ad7635fb28afe3536</tree>
  <committer>
    <name>Norman Clarke</name>
    <email>norman@randomba.org</email>
  </committer>
</commit>
