friendly_id4 4.0.0.beta6 → 4.0.0.pre

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,6 +0,0 @@
1
- # A FriendlyId slug stored in an external table.
2
- #
3
- # @see FriendlyId::History
4
- class FriendlyIdSlug < ActiveRecord::Base
5
- belongs_to :sluggable, :polymorphic => true
6
- end
@@ -1,82 +0,0 @@
1
- module FriendlyId
2
- # This class offers functionality to check slug strings for uniqueness and,
3
- # if necessary, append a sequence to ensure it.
4
- class SlugSequencer
5
- attr_reader :sluggable
6
-
7
- def initialize(sluggable)
8
- @sluggable = sluggable
9
- end
10
-
11
- # Given a slug, get the next available slug in the sequence.
12
- def next
13
- sequence = conflict.slug.split(separator)[1].to_i
14
- next_sequence = sequence == 0 ? 2 : sequence.next
15
- "#{normalized}#{separator}#{next_sequence}"
16
- end
17
-
18
- # Generate a new sequenced slug.
19
- def generate
20
- if new_record? or slug_changed?
21
- conflict? ? self.next : normalized
22
- else
23
- sluggable.friendly_id
24
- end
25
- end
26
-
27
- # Whether or not the model instance's slug has changed.
28
- def slug_changed?
29
- separator = Regexp.escape friendly_id_config.sequence_separator
30
- base != sluggable.current_friendly_id.try(:sub, /#{separator}[\d]*\z/, '')
31
- end
32
-
33
- private
34
-
35
- def base
36
- sluggable.send friendly_id_config.base
37
- end
38
-
39
- def column
40
- sluggable.connection.quote_column_name friendly_id_config.query_field
41
- end
42
-
43
- def conflict?
44
- !! conflict
45
- end
46
-
47
- def conflict
48
- unless defined? @conflict
49
- @conflict = conflicts.first
50
- end
51
- @conflict
52
- end
53
-
54
- def conflicts
55
- pkey = sluggable.class.primary_key
56
- value = sluggable.send pkey
57
- scope = sluggable.class.where("#{column} = ? OR #{column} LIKE ?", normalized, wildcard)
58
- scope = scope.where("#{pkey} <> ?", value) unless sluggable.new_record?
59
- scope = scope.order("LENGTH(#{column}) DESC, #{column} DESC")
60
- end
61
-
62
- def friendly_id_config
63
- sluggable.friendly_id_config
64
- end
65
-
66
- def new_record?
67
- sluggable.new_record?
68
- end
69
-
70
- def normalized
71
- @normalized ||= sluggable.normalize_friendly_id(base)
72
- end
73
-
74
- def separator
75
- friendly_id_config.sequence_separator
76
- end
77
-
78
- def wildcard
79
- "#{normalized}#{separator}%"
80
- end
81
- end
82
- end
@@ -1,24 +0,0 @@
1
- require 'rails/generators'
2
- require 'rails/generators/migration'
3
-
4
- # This generator adds a migration for the {FriendlyId::History
5
- # FriendlyId::History} addon.
6
- class FriendlyIdGenerator < Rails::Generators::Base
7
- include Rails::Generators::Migration
8
-
9
- source_root File.expand_path('../../friendly_id', __FILE__)
10
-
11
- # Copies the migration template to db/migrate.
12
- def copy_files(*args)
13
- migration_template 'migration.rb', 'db/migrate/create_friendly_id_slugs.rb'
14
- end
15
-
16
- # Taken from ActiveRecord's migration generator
17
- def self.next_migration_number(dirname) #:nodoc:
18
- if ActiveRecord::Base.timestamped_migrations
19
- Time.now.utc.strftime("%Y%m%d%H%M%S")
20
- else
21
- "%.3d" % (current_migration_number(dirname) + 1)
22
- end
23
- end
24
- end
@@ -1,54 +0,0 @@
1
- require File.expand_path("../helper.rb", __FILE__)
2
-
3
- class CoreTest < MiniTest::Unit::TestCase
4
- include FriendlyId::Test
5
-
6
- test "friendly_id should accept a base and a hash" do
7
- klass = Class.new(ActiveRecord::Base) do
8
- extend FriendlyId
9
- friendly_id :foo, :use => :slugged, :slug_column => :bar
10
- end
11
- assert klass < FriendlyId::Slugged
12
- assert_equal :foo, klass.friendly_id_config.base
13
- assert_equal :bar, klass.friendly_id_config.slug_column
14
- end
15
-
16
-
17
- test "friendly_id should accept a block" do
18
- klass = Class.new(ActiveRecord::Base) do
19
- extend FriendlyId
20
- friendly_id :foo do |config|
21
- config.use :slugged
22
- config.base = :foo
23
- config.slug_column = :bar
24
- end
25
- end
26
- assert klass < FriendlyId::Slugged
27
- assert_equal :foo, klass.friendly_id_config.base
28
- assert_equal :bar, klass.friendly_id_config.slug_column
29
- end
30
-
31
- test "the block passed to friendly_id should be evaluated before arguments" do
32
- klass = Class.new(ActiveRecord::Base) do
33
- extend FriendlyId
34
- friendly_id :foo do |config|
35
- config.base = :bar
36
- end
37
- end
38
- assert_equal :foo, klass.friendly_id_config.base
39
- end
40
-
41
- test "should allow defaults to be set via a block" do
42
- begin
43
- FriendlyId.defaults do |config|
44
- config.base = :foo
45
- end
46
- klass = Class.new(ActiveRecord::Base) do
47
- extend FriendlyId
48
- end
49
- assert_equal :foo, klass.friendly_id_config.base
50
- ensure
51
- FriendlyId.instance_variable_set :@defaults, nil
52
- end
53
- end
54
- end
@@ -1,5 +0,0 @@
1
- adapter: mysql
2
- database: friendly_id_test
3
- username: root
4
- hostname: localhost
5
- encoding: utf8
@@ -1,5 +0,0 @@
1
- adapter: mysql2
2
- database: friendly_id_test
3
- username: root
4
- hostname: localhost
5
- encoding: utf8
@@ -1,6 +0,0 @@
1
- adapter: postgresql
2
- host: localhost
3
- port: 5432
4
- username: postgres
5
- database: friendly_id_test
6
- encoding: utf8
@@ -1,3 +0,0 @@
1
- adapter: sqlite3
2
- database: ":memory:"
3
- encoding: utf8
@@ -1,27 +0,0 @@
1
- require File.expand_path("../helper", __FILE__)
2
-
3
- class ConfigurationTest < MiniTest::Unit::TestCase
4
-
5
- include FriendlyId::Test
6
-
7
- def setup
8
- @model_class = Class.new(ActiveRecord::Base)
9
- end
10
-
11
- test "should set model class on initialization" do
12
- config = FriendlyId::Configuration.new @model_class
13
- assert_equal @model_class, config.model_class
14
- end
15
-
16
- test "should set options on initialization if present" do
17
- config = FriendlyId::Configuration.new @model_class, :base => "hello"
18
- assert_equal "hello", config.base
19
- end
20
-
21
- test "should raise error if passed unrecognized option" do
22
- assert_raises NoMethodError do
23
- FriendlyId::Configuration.new @model_class, :foo => "bar"
24
- end
25
- end
26
-
27
- end
@@ -1,90 +0,0 @@
1
- $: << File.expand_path("../../lib", __FILE__)
2
- $: << File.expand_path("../", __FILE__)
3
- $:.uniq!
4
-
5
- require "rubygems"
6
- require "bundler/setup"
7
- require "mocha"
8
- require "minitest/unit"
9
- require "active_record"
10
- # require "active_support/core_ext/class"
11
-
12
- if ENV["COVERAGE"]
13
- require 'simplecov'
14
- SimpleCov.start do
15
- add_filter "test/"
16
- add_filter "friendly_id/migration"
17
- end
18
- end
19
-
20
- require "friendly_id"
21
-
22
- # If you want to see the ActiveRecord log, invoke the tests using `rake test LOG=true`
23
- if ENV["LOG"]
24
- require "logger"
25
- ActiveRecord::Base.logger = Logger.new($stdout)
26
- end
27
-
28
- module FriendlyId
29
- module Test
30
-
31
- def self.included(base)
32
- MiniTest::Unit.autorun
33
- end
34
-
35
- def transaction
36
- ActiveRecord::Base.transaction { yield ; raise ActiveRecord::Rollback }
37
- end
38
-
39
- def with_instance_of(*args)
40
- model_class = args.shift
41
- args[0] ||= {:name => "a"}
42
- transaction { yield model_class.create!(*args) }
43
- end
44
-
45
- module Database
46
- extend self
47
-
48
- def connect
49
- ActiveRecord::Base.establish_connection config
50
- version = ActiveRecord::VERSION::STRING
51
- driver = FriendlyId::Test::Database.driver
52
- message = "Using #{RUBY_ENGINE} #{RUBY_VERSION} AR #{version} with #{driver}"
53
- puts "-" * 72
54
- if in_memory?
55
- ActiveRecord::Migration.verbose = false
56
- Schema.up
57
- puts "#{message} (in-memory)"
58
- else
59
- puts message
60
- end
61
- end
62
-
63
- def config
64
- @config ||= YAML::load(File.open(config_file))
65
- end
66
-
67
- def config_file
68
- File.expand_path("../config/#{driver}.yml", __FILE__)
69
- end
70
-
71
- def driver
72
- (ENV["DB"] or "sqlite3").downcase
73
- end
74
-
75
- def in_memory?
76
- config["database"] == ":memory:"
77
- end
78
- end
79
- end
80
- end
81
-
82
- class Module
83
- def test(name, &block)
84
- define_method("test_#{name.gsub(/[^a-z0-9']/i, "_")}".to_sym, &block)
85
- end
86
- end
87
-
88
- require "schema"
89
- require "shared"
90
- FriendlyId::Test::Database.connect
@@ -1,55 +0,0 @@
1
- require File.expand_path("../helper.rb", __FILE__)
2
-
3
- class Manual < ActiveRecord::Base
4
- extend FriendlyId
5
- friendly_id :name, :use => :history
6
- end
7
-
8
- class HistoryTest < MiniTest::Unit::TestCase
9
-
10
- include FriendlyId::Test
11
- include FriendlyId::Test::Shared::Core
12
-
13
- def model_class
14
- Manual
15
- end
16
-
17
- test "should insert record in slugs table on create" do
18
- with_instance_of(model_class) {|record| assert !record.friendly_id_slugs.empty?}
19
- end
20
-
21
- test "should not create new slug record if friendly_id is not changed" do
22
- with_instance_of(model_class) do |record|
23
- record.active = true
24
- record.save!
25
- assert_equal 1, FriendlyIdSlug.count
26
- end
27
- end
28
-
29
- test "should create new slug record when friendly_id changes" do
30
- with_instance_of(model_class) do |record|
31
- record.name = record.name + "b"
32
- record.save!
33
- assert_equal 2, FriendlyIdSlug.count
34
- end
35
- end
36
-
37
- test "should be findable by old slugs" do
38
- with_instance_of(model_class) do |record|
39
- old_friendly_id = record.friendly_id
40
- record.name = record.name + "b"
41
- record.save!
42
- assert found = model_class.find_by_friendly_id(old_friendly_id)
43
- assert !found.readonly?
44
- end
45
- end
46
-
47
- test "should raise error if used with scoped" do
48
- model_class = Class.new(ActiveRecord::Base)
49
- model_class.extend FriendlyId
50
- assert_raises RuntimeError do
51
- model_class.friendly_id :name, :use => [:history, :scoped]
52
- end
53
- end
54
-
55
- end
@@ -1,26 +0,0 @@
1
- require File.expand_path("../helper.rb", __FILE__)
2
-
3
-
4
- class ObjectUtilsTest < MiniTest::Unit::TestCase
5
-
6
- include FriendlyId::Test
7
-
8
- test "strings with letters are friendly_ids" do
9
- assert "a".friendly_id?
10
- end
11
-
12
- test "integers should be unfriendly ids" do
13
- assert 1.unfriendly_id?
14
- end
15
-
16
- test "numeric strings are neither friendly nor unfriendly" do
17
- assert_equal nil, "1".friendly_id?
18
- assert_equal nil, "1".unfriendly_id?
19
- end
20
-
21
- test "ActiveRecord::Base instances should be unfriendly_ids" do
22
- model_class = Class.new(ActiveRecord::Base)
23
- model_class.table_name = "authors"
24
- assert model_class.new.unfriendly_id?
25
- end
26
- end
@@ -1,26 +0,0 @@
1
- require File.expand_path("../helper.rb", __FILE__)
2
-
3
- class ReservedTest < MiniTest::Unit::TestCase
4
-
5
- include FriendlyId::Test
6
-
7
- class Journalist < ActiveRecord::Base
8
- extend FriendlyId
9
- friendly_id :name
10
- end
11
-
12
-
13
- def model_class
14
- Journalist
15
- end
16
-
17
- test "should reserve 'new' and 'edit' by default" do
18
- ["new", "edit"].each do |word|
19
- transaction do
20
- assert_raises(ActiveRecord::RecordInvalid) {model_class.create! :name => word}
21
- end
22
- end
23
- end
24
- end
25
-
26
-
@@ -1,56 +0,0 @@
1
- require "friendly_id/migration"
2
-
3
- module FriendlyId
4
- module Test
5
- class Schema < ActiveRecord::Migration
6
- class << self
7
- def down
8
- CreateFriendlyIdSlugs.down
9
- tables.each do |name|
10
- drop_table name
11
- end
12
- end
13
-
14
- def up
15
- CreateFriendlyIdSlugs.up
16
-
17
- tables.each do |table_name|
18
- create_table table_name do |t|
19
- t.string :name
20
- t.boolean :active
21
- end
22
- end
23
-
24
- slugged_tables.each do |table_name|
25
- add_column table_name, :slug, :string
26
- add_index table_name, :slug, :unique => true
27
- end
28
-
29
- # This will be used to test scopes
30
- add_column :novels, :novelist_id, :integer
31
- remove_index :novels, :slug
32
-
33
- # This will be used to test column name quoting
34
- add_column :journalists, "strange name", :string
35
-
36
- # This will be used to test STI
37
- add_column :journalists, "type", :string
38
- end
39
-
40
- private
41
-
42
- def slugged_tables
43
- ["journalists", "articles", "novelists", "novels", "manuals"]
44
- end
45
-
46
- def simple_tables
47
- ["authors", "books"]
48
- end
49
-
50
- def tables
51
- simple_tables + slugged_tables
52
- end
53
- end
54
- end
55
- end
56
- end