friendly_id 5.6.0 → 5.7.0

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,22 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec path: "../"
4
-
5
- gem "activerecord", "~> 7.0.0"
6
- gem "railties", "~> 7.0.0"
7
-
8
- # Database Configuration
9
- group :development, :test do
10
- platforms :jruby do
11
- gem "activerecord-jdbcmysql-adapter", "~> 61.0"
12
- gem "activerecord-jdbcpostgresql-adapter", "~> 61.0"
13
- gem "kramdown"
14
- end
15
-
16
- platforms :ruby, :rbx do
17
- gem "sqlite3"
18
- gem "mysql2"
19
- gem "pg"
20
- gem "redcarpet"
21
- end
22
- end
@@ -1,22 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec path: "../"
4
-
5
- gem "activerecord", "~> 7.1.0"
6
- gem "railties", "~> 7.1.0"
7
-
8
- # Database Configuration
9
- group :development, :test do
10
- platforms :jruby do
11
- gem "activerecord-jdbcmysql-adapter", "~> 61.0"
12
- gem "activerecord-jdbcpostgresql-adapter", "~> 61.0"
13
- gem "kramdown"
14
- end
15
-
16
- platforms :ruby, :rbx do
17
- gem "sqlite3"
18
- gem "mysql2"
19
- gem "pg"
20
- gem "redcarpet"
21
- end
22
- end
@@ -1,22 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec path: "../"
4
-
5
- gem "activerecord", "~> 7.2.0"
6
- gem "railties", "~> 7.2.0"
7
-
8
- # Database Configuration
9
- group :development, :test do
10
- platforms :jruby do
11
- gem "activerecord-jdbcmysql-adapter", "~> 61.0"
12
- gem "activerecord-jdbcpostgresql-adapter", "~> 61.0"
13
- gem "kramdown"
14
- end
15
-
16
- platforms :ruby, :rbx do
17
- gem "sqlite3"
18
- gem "mysql2"
19
- gem "pg"
20
- gem "redcarpet"
21
- end
22
- end
@@ -1,22 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec path: "../"
4
-
5
- gem "activerecord", "~> 8.0.0"
6
- gem "railties", "~> 8.0.0"
7
-
8
- # Database Configuration
9
- group :development, :test do
10
- platforms :jruby do
11
- gem "activerecord-jdbcmysql-adapter", "~> 61.0"
12
- gem "activerecord-jdbcpostgresql-adapter", "~> 61.0"
13
- gem "kramdown"
14
- end
15
-
16
- platforms :ruby, :rbx do
17
- gem "sqlite3"
18
- gem "mysql2"
19
- gem "pg"
20
- gem "redcarpet"
21
- end
22
- end
data/guide.rb DELETED
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # This script generates the Guide.md file included in the Yard docs.
4
-
5
- def comments_from path
6
- path = File.expand_path("../lib/friendly_id/#{path}", __FILE__)
7
- matches = File.read(path).match(/\n\s*# @guide begin\n(.*)\s*# @guide end/m)
8
-
9
- return if matches.nil?
10
-
11
- match = matches[1].to_s
12
- match.split("\n")
13
- .map { |x| x.sub(/^\s*#\s?/, "") } # Strip off the comment, leading whitespace, and the space after the comment
14
- .reject { |x| x =~ /^@/ } # Ignore yarddoc tags for the guide
15
- .join("\n").strip
16
- end
17
-
18
- File.open(File.expand_path("../Guide.md", __FILE__), "w:utf-8") do |guide|
19
- ["../friendly_id.rb", "base.rb", "finders.rb", "slugged.rb", "history.rb",
20
- "scoped.rb", "simple_i18n.rb", "reserved.rb"].each do |file|
21
- guide.write comments_from file
22
- guide.write "\n"
23
- end
24
- end
data/test/base_test.rb DELETED
@@ -1,69 +0,0 @@
1
- require "helper"
2
-
3
- class CoreTest < TestCaseClass
4
- include FriendlyId::Test
5
-
6
- test "friendly_id can be added using 'extend'" do
7
- klass = Class.new(ActiveRecord::Base) do
8
- extend FriendlyId
9
- end
10
- assert klass.respond_to? :friendly_id
11
- end
12
-
13
- test "friendly_id can be added using 'include'" do
14
- klass = Class.new(ActiveRecord::Base) do
15
- include FriendlyId
16
- end
17
- assert klass.respond_to? :friendly_id
18
- end
19
-
20
- test "friendly_id should accept a base and a hash" do
21
- klass = Class.new(ActiveRecord::Base) do
22
- self.abstract_class = true
23
- extend FriendlyId
24
- friendly_id :foo, use: :slugged, slug_column: :bar
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 "friendly_id should accept a block" do
32
- klass = Class.new(ActiveRecord::Base) do
33
- self.abstract_class = true
34
- extend FriendlyId
35
- friendly_id :foo do |config|
36
- config.use :slugged
37
- config.base = :foo
38
- config.slug_column = :bar
39
- end
40
- end
41
- assert klass < FriendlyId::Slugged
42
- assert_equal :foo, klass.friendly_id_config.base
43
- assert_equal :bar, klass.friendly_id_config.slug_column
44
- end
45
-
46
- test "the block passed to friendly_id should be evaluated before arguments" do
47
- klass = Class.new(ActiveRecord::Base) do
48
- self.abstract_class = true
49
- extend FriendlyId
50
- friendly_id :foo do |config|
51
- config.base = :bar
52
- end
53
- end
54
- assert_equal :foo, klass.friendly_id_config.base
55
- end
56
-
57
- test "should allow defaults to be set via a block" do
58
- FriendlyId.defaults do |config|
59
- config.base = :foo
60
- end
61
- klass = Class.new(ActiveRecord::Base) do
62
- self.abstract_class = true
63
- extend FriendlyId
64
- end
65
- assert_equal :foo, klass.friendly_id_config.base
66
- ensure
67
- FriendlyId.instance_variable_set :@defaults, nil
68
- end
69
- end
@@ -1,90 +0,0 @@
1
- require File.expand_path("../../helper", __FILE__)
2
- require "ffaker"
3
-
4
- # This benchmark tests ActiveRecord and FriendlyId methods for performing a find
5
- #
6
- # ActiveRecord: where.first 8.970000 0.040000 9.010000 ( 9.029544)
7
- # ActiveRecord: where.take 8.100000 0.030000 8.130000 ( 8.157024)
8
- # ActiveRecord: find 2.720000 0.010000 2.730000 ( 2.733527)
9
- # ActiveRecord: find_by(:id) 2.920000 0.000000 2.920000 ( 2.926318)
10
- # ActiveRecord: find_by(:slug) 2.650000 0.020000 2.670000 ( 2.662677)
11
- # FriendlyId: find (in-table slug w/ finders) 9.820000 0.030000 9.850000 ( 9.873358)
12
- # FriendlyId: friendly.find (in-table slug) 12.890000 0.050000 12.940000 ( 12.951156)
13
-
14
- N = 50000
15
-
16
- def transaction
17
- ActiveRecord::Base.transaction do
18
- yield
19
-
20
- raise ActiveRecord::Rollback
21
- end
22
- end
23
-
24
- class Array
25
- def rand
26
- self[Kernel.rand(length)]
27
- end
28
- end
29
-
30
- Book = Class.new ActiveRecord::Base
31
-
32
- class Journalist < ActiveRecord::Base
33
- extend FriendlyId
34
- friendly_id :name, use: :slugged
35
- end
36
-
37
- class Manual < ActiveRecord::Base
38
- extend FriendlyId
39
- friendly_id :name, use: :history
40
- end
41
-
42
- class Restaurant < ActiveRecord::Base
43
- extend FriendlyId
44
- friendly_id :name, use: :finders
45
- end
46
-
47
- BOOKS = []
48
- JOURNALISTS = []
49
- MANUALS = []
50
- RESTAURANTS = []
51
-
52
- 100.times do
53
- name = FFaker::Name.name
54
- BOOKS << (Book.create! name: name).id
55
- JOURNALISTS << (Journalist.create! name: name).friendly_id
56
- MANUALS << (Manual.create! name: name).friendly_id
57
- RESTAURANTS << (Restaurant.create! name: name).friendly_id
58
- end
59
-
60
- ActiveRecord::Base.connection.execute "UPDATE manuals SET slug = NULL"
61
-
62
- Benchmark.bmbm do |x|
63
- x.report "ActiveRecord: where.first" do
64
- N.times { Book.where(id: BOOKS.rand).first }
65
- end
66
-
67
- x.report "ActiveRecord: where.take" do
68
- N.times { Book.where(id: BOOKS.rand).take }
69
- end
70
-
71
- x.report "ActiveRecord: find" do
72
- N.times { Book.find BOOKS.rand }
73
- end
74
-
75
- x.report "ActiveRecord: find_by(:id)" do
76
- N.times { Book.find_by(id: BOOKS.rand) }
77
- end
78
-
79
- x.report "ActiveRecord: find_by(:slug)" do
80
- N.times { Restaurant.find_by(slug: RESTAURANTS.rand) }
81
- end
82
-
83
- x.report "FriendlyId: find (in-table slug w/ finders)" do
84
- N.times { Restaurant.find RESTAURANTS.rand }
85
- end
86
-
87
- x.report "FriendlyId: friendly.find (in-table slug)" do
88
- N.times { Restaurant.friendly.find RESTAURANTS.rand }
89
- end
90
- end
@@ -1,56 +0,0 @@
1
- require File.expand_path("../../helper", __FILE__)
2
-
3
- # This benchmark compares the timings of the friendly_id? and unfriendly_id? on various objects
4
- #
5
- # integer friendly_id? 6.370000 0.000000 6.370000 ( 6.380925)
6
- # integer unfriendly_id? 6.640000 0.010000 6.650000 ( 6.646057)
7
- # AR::Base friendly_id? 2.340000 0.000000 2.340000 ( 2.340743)
8
- # AR::Base unfriendly_id? 2.560000 0.000000 2.560000 ( 2.560039)
9
- # hash friendly_id? 5.090000 0.010000 5.100000 ( 5.097662)
10
- # hash unfriendly_id? 5.430000 0.000000 5.430000 ( 5.437160)
11
- # nil friendly_id? 5.610000 0.010000 5.620000 ( 5.611487)
12
- # nil unfriendly_id? 5.870000 0.000000 5.870000 ( 5.880484)
13
- # numeric string friendly_id? 9.270000 0.030000 9.300000 ( 9.308452)
14
- # numeric string unfriendly_id? 9.190000 0.040000 9.230000 ( 9.252890)
15
- # test_string friendly_id? 8.380000 0.010000 8.390000 ( 8.411762)
16
- # test_string unfriendly_id? 8.450000 0.010000 8.460000 ( 8.463662)
17
-
18
- # From the ObjectUtils docs...
19
- # 123.friendly_id? #=> false
20
- # :id.friendly_id? #=> false
21
- # {:name => 'joe'}.friendly_id? #=> false
22
- # ['name = ?', 'joe'].friendly_id? #=> false
23
- # nil.friendly_id? #=> false
24
- # "123".friendly_id? #=> nil
25
- # "abc123".friendly_id? #=> true
26
-
27
- Book = Class.new ActiveRecord::Base
28
-
29
- test_integer = 123
30
- test_active_record_object = Book.new
31
- test_hash = {name: "joe"}
32
- test_nil = nil
33
- test_numeric_string = "123"
34
- test_string = "abc123"
35
-
36
- N = 5_000_000
37
-
38
- Benchmark.bmbm do |x|
39
- x.report("integer friendly_id?") { N.times { test_integer.friendly_id? } }
40
- x.report("integer unfriendly_id?") { N.times { test_integer.unfriendly_id? } }
41
-
42
- x.report("AR::Base friendly_id?") { N.times { test_active_record_object.friendly_id? } }
43
- x.report("AR::Base unfriendly_id?") { N.times { test_active_record_object.unfriendly_id? } }
44
-
45
- x.report("hash friendly_id?") { N.times { test_hash.friendly_id? } }
46
- x.report("hash unfriendly_id?") { N.times { test_hash.unfriendly_id? } }
47
-
48
- x.report("nil friendly_id?") { N.times { test_nil.friendly_id? } }
49
- x.report("nil unfriendly_id?") { N.times { test_nil.unfriendly_id? } }
50
-
51
- x.report("numeric string friendly_id?") { N.times { test_numeric_string.friendly_id? } }
52
- x.report("numeric string unfriendly_id?") { N.times { test_numeric_string.unfriendly_id? } }
53
-
54
- x.report("test_string friendly_id?") { N.times { test_string.friendly_id? } }
55
- x.report("test_string unfriendly_id?") { N.times { test_string.unfriendly_id? } }
56
- end
@@ -1,142 +0,0 @@
1
- require "helper"
2
-
3
- class CandidatesTest < TestCaseClass
4
- include FriendlyId::Test
5
-
6
- class Airport
7
- def initialize(code)
8
- @code = code
9
- end
10
- attr_reader :code
11
- alias_method :to_s, :code
12
- end
13
-
14
- class City < ActiveRecord::Base
15
- extend FriendlyId
16
- friendly_id :slug_candidates, use: :slugged
17
- alias_attribute :slug_candidates, :name
18
- end
19
-
20
- def model_class
21
- City
22
- end
23
-
24
- def with_instances_of(klass = model_class, &block)
25
- transaction do
26
- city1 = klass.create! name: "New York", code: "JFK"
27
- city2 = klass.create! name: "New York", code: "EWR"
28
- yield city1, city2
29
- end
30
- end
31
- alias_method :with_instances, :with_instances_of
32
-
33
- test "resolves conflict with candidate" do
34
- with_instances do |city1, city2|
35
- assert_equal "new-york", city1.slug
36
- assert_match(/\Anew-york-([a-z0-9]+-){4}[a-z0-9]+\z/, city2.slug)
37
- end
38
- end
39
-
40
- test "accepts candidate as symbol" do
41
- klass = Class.new model_class do
42
- def slug_candidates
43
- :name
44
- end
45
- end
46
- with_instances_of klass do |_, city|
47
- assert_match(/\Anew-york-([a-z0-9]+-){4}[a-z0-9]+\z/, city.slug)
48
- end
49
- end
50
-
51
- test "accepts multiple candidates" do
52
- klass = Class.new model_class do
53
- def slug_candidates
54
- [name, code]
55
- end
56
- end
57
- with_instances_of klass do |_, city|
58
- assert_equal "ewr", city.slug
59
- end
60
- end
61
-
62
- test "ignores blank candidate" do
63
- klass = Class.new model_class do
64
- def slug_candidates
65
- [name, ""]
66
- end
67
- end
68
- with_instances_of klass do |_, city|
69
- assert_match(/\Anew-york-([a-z0-9]+-){4}[a-z0-9]+\z/, city.slug)
70
- end
71
- end
72
-
73
- test "ignores nil candidate" do
74
- klass = Class.new model_class do
75
- def slug_candidates
76
- [name, nil]
77
- end
78
- end
79
- with_instances_of klass do |_, city|
80
- assert_match(/\Anew-york-([a-z0-9]+-){4}[a-z0-9]+\z/, city.slug)
81
- end
82
- end
83
-
84
- test "accepts candidate with nested array" do
85
- klass = Class.new model_class do
86
- def slug_candidates
87
- [name, [name, code]]
88
- end
89
- end
90
- with_instances_of klass do |_, city|
91
- assert_equal "new-york-ewr", city.slug
92
- end
93
- end
94
-
95
- test "accepts candidate with lambda" do
96
- klass = Class.new City do
97
- def slug_candidates
98
- [name, [name, -> { rand 1000 }]]
99
- end
100
- end
101
- with_instances_of klass do |_, city|
102
- assert_match(/\Anew-york-\d{,3}\z/, city.friendly_id)
103
- end
104
- end
105
-
106
- test "accepts candidate with object" do
107
- klass = Class.new City do
108
- def slug_candidates
109
- [name, [name, Airport.new(code)]]
110
- end
111
- end
112
- with_instances_of klass do |_, city|
113
- assert_equal "new-york-ewr", city.friendly_id
114
- end
115
- end
116
-
117
- test "allows to iterate through candidates without passing block" do
118
- klass = Class.new model_class do
119
- def slug_candidates
120
- :name
121
- end
122
- end
123
- with_instances_of klass do |_, city|
124
- candidates = FriendlyId::Candidates.new(city, city.slug_candidates)
125
- assert_equal candidates.each, ["new-york"]
126
- end
127
- end
128
-
129
- test "iterates through candidates with passed block" do
130
- klass = Class.new model_class do
131
- def slug_candidates
132
- :name
133
- end
134
- end
135
- with_instances_of klass do |_, city|
136
- collected_candidates = []
137
- candidates = FriendlyId::Candidates.new(city, city.slug_candidates)
138
- candidates.each { |candidate| collected_candidates << candidate }
139
- assert_equal collected_candidates, ["new-york"]
140
- end
141
- end
142
- end
@@ -1,60 +0,0 @@
1
- require "helper"
2
-
3
- class ConfigurationTest < TestCaseClass
4
- include FriendlyId::Test
5
-
6
- def setup
7
- @model_class = Class.new(ActiveRecord::Base) do
8
- self.abstract_class = true
9
- end
10
- end
11
-
12
- test "should set model class on initialization" do
13
- config = FriendlyId::Configuration.new @model_class
14
- assert_equal @model_class, config.model_class
15
- end
16
-
17
- test "should set options on initialization if present" do
18
- config = FriendlyId::Configuration.new @model_class, base: "hello"
19
- assert_equal "hello", config.base
20
- end
21
-
22
- test "should raise error if passed unrecognized option" do
23
- assert_raises NoMethodError do
24
- FriendlyId::Configuration.new @model_class, foo: "bar"
25
- end
26
- end
27
-
28
- test "#use should accept a name that resolves to a module" do
29
- refute @model_class < FriendlyId::Slugged
30
- @model_class.class_eval do
31
- extend FriendlyId
32
- friendly_id :hello, use: :slugged
33
- end
34
- assert @model_class < FriendlyId::Slugged
35
- end
36
-
37
- test "#use should accept a module" do
38
- my_module = Module.new
39
- refute @model_class < my_module
40
- @model_class.class_eval do
41
- extend FriendlyId
42
- friendly_id :hello, use: my_module
43
- end
44
- assert @model_class < my_module
45
- end
46
-
47
- test "#base should optionally set a value" do
48
- config = FriendlyId::Configuration.new @model_class
49
- assert_nil config.base
50
- config.base = "foo"
51
- assert_equal "foo", config.base
52
- end
53
-
54
- test "#base can set the value to nil" do
55
- config = FriendlyId::Configuration.new @model_class
56
- config.base "foo"
57
- config.base nil
58
- assert_nil config.base
59
- end
60
- end
data/test/core_test.rb DELETED
@@ -1,35 +0,0 @@
1
- require "helper"
2
-
3
- class Book < ActiveRecord::Base
4
- extend FriendlyId
5
- friendly_id :name
6
- end
7
-
8
- class Author < ActiveRecord::Base
9
- extend FriendlyId
10
- friendly_id :name
11
- has_many :books
12
- end
13
-
14
- class CoreTest < TestCaseClass
15
- include FriendlyId::Test
16
- include FriendlyId::Test::Shared::Core
17
-
18
- def model_class
19
- Author
20
- end
21
-
22
- test "models don't use friendly_id by default" do
23
- assert !Class.new(ActiveRecord::Base) {
24
- self.abstract_class = true
25
- }.respond_to?(:friendly_id)
26
- end
27
-
28
- test "model classes should have a friendly id config" do
29
- assert model_class.friendly_id(:name).friendly_id_config
30
- end
31
-
32
- test "instances should have a friendly id" do
33
- with_instance_of(model_class) { |record| assert record.friendly_id }
34
- end
35
- end
data/test/databases.yml DELETED
@@ -1,22 +0,0 @@
1
- mysql:
2
- adapter: mysql2
3
- database: friendly_id_test
4
- username: root
5
- password: <%= ENV['MYSQL_PASSWORD'] %>
6
- host: 127.0.0.1
7
- port: 3306
8
- encoding: utf8
9
-
10
- postgres:
11
- adapter: postgresql
12
- host: <%= ENV.fetch('PGHOST', 'localhost') %>
13
- port: <%= ENV.fetch('PGPORT', '5432') %>
14
- username: <%= ENV.fetch('PGUSER', 'postgres') %>
15
- password: <%= ENV.fetch('PGPASSWORD', 'postgres') %>
16
- database: friendly_id_test
17
- encoding: utf8
18
-
19
- sqlite3:
20
- adapter: sqlite3
21
- database: ":memory:"
22
- encoding: utf8
data/test/finders_test.rb DELETED
@@ -1,76 +0,0 @@
1
- require "helper"
2
-
3
- class JournalistWithFriendlyFinders < ActiveRecord::Base
4
- self.table_name = "journalists"
5
- extend FriendlyId
6
- scope :existing, -> { where("1 = 1") }
7
- friendly_id :name, use: [:slugged, :finders]
8
- end
9
-
10
- class Finders < TestCaseClass
11
- include FriendlyId::Test
12
-
13
- def model_class
14
- JournalistWithFriendlyFinders
15
- end
16
-
17
- test "should find records with finders as class methods" do
18
- with_instance_of(model_class) do |record|
19
- assert model_class.find(record.friendly_id)
20
- end
21
- end
22
-
23
- test "should find records with finders on relations" do
24
- with_instance_of(model_class) do |record|
25
- assert model_class.existing.find(record.friendly_id)
26
- end
27
- end
28
-
29
- test "allows nil with allow_nil: true" do
30
- with_instance_of(model_class) do |record|
31
- assert_nil model_class.find("foo", allow_nil: true)
32
- end
33
- end
34
-
35
- test "allows nil on relations with allow_nil: true" do
36
- with_instance_of(model_class) do |record|
37
- assert_nil model_class.existing.find("foo", allow_nil: true)
38
- end
39
- end
40
-
41
- test "allows nil with a bad primary key ID and allow_nil: true" do
42
- with_instance_of(model_class) do |record|
43
- assert_nil model_class.find(0, allow_nil: true)
44
- end
45
- end
46
-
47
- test "allows nil on relations with a bad primary key ID and allow_nil: true" do
48
- with_instance_of(model_class) do |record|
49
- assert_nil model_class.existing.find(0, allow_nil: true)
50
- end
51
- end
52
-
53
- test "allows nil with a bad potential primary key ID and allow_nil: true" do
54
- with_instance_of(model_class) do |record|
55
- assert_nil model_class.find("0", allow_nil: true)
56
- end
57
- end
58
-
59
- test "allows nil on relations with a bad potential primary key ID and allow_nil: true" do
60
- with_instance_of(model_class) do |record|
61
- assert_nil model_class.existing.find("0", allow_nil: true)
62
- end
63
- end
64
-
65
- test "allows nil with nil ID and allow_nil: true" do
66
- with_instance_of(model_class) do |record|
67
- assert_nil model_class.find(nil, allow_nil: true)
68
- end
69
- end
70
-
71
- test "allows nil on relations with nil ID and allow_nil: true" do
72
- with_instance_of(model_class) do |record|
73
- assert_nil model_class.existing.find(nil, allow_nil: true)
74
- end
75
- end
76
- end