mil_friendly_id 4.0.9.8

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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +12 -0
  4. data/.travis.yml +20 -0
  5. data/.yardopts +4 -0
  6. data/Changelog.md +86 -0
  7. data/Gemfile +15 -0
  8. data/Guide.rdoc +553 -0
  9. data/MIT-LICENSE +19 -0
  10. data/README.md +150 -0
  11. data/Rakefile +108 -0
  12. data/WhatsNew.md +95 -0
  13. data/bench.rb +63 -0
  14. data/friendly_id.gemspec +43 -0
  15. data/gemfiles/Gemfile.rails-3.0.rb +21 -0
  16. data/gemfiles/Gemfile.rails-3.1.rb +22 -0
  17. data/gemfiles/Gemfile.rails-3.2.rb +22 -0
  18. data/geothird_friendly_id.gemspec +45 -0
  19. data/lib/friendly_id.rb +114 -0
  20. data/lib/friendly_id/base.rb +291 -0
  21. data/lib/friendly_id/configuration.rb +80 -0
  22. data/lib/friendly_id/finder_methods.rb +35 -0
  23. data/lib/friendly_id/globalize.rb +115 -0
  24. data/lib/friendly_id/history.rb +134 -0
  25. data/lib/friendly_id/migration.rb +19 -0
  26. data/lib/friendly_id/object_utils.rb +50 -0
  27. data/lib/friendly_id/reserved.rb +68 -0
  28. data/lib/friendly_id/scoped.rb +149 -0
  29. data/lib/friendly_id/simple_i18n.rb +95 -0
  30. data/lib/friendly_id/slug.rb +14 -0
  31. data/lib/friendly_id/slug_generator.rb +80 -0
  32. data/lib/friendly_id/slugged.rb +329 -0
  33. data/lib/generators/friendly_id_generator.rb +17 -0
  34. data/mil_friendly_id.gemspec +45 -0
  35. data/test/base_test.rb +72 -0
  36. data/test/compatibility/ancestry/Gemfile +8 -0
  37. data/test/compatibility/ancestry/ancestry_test.rb +34 -0
  38. data/test/compatibility/threading/Gemfile +8 -0
  39. data/test/compatibility/threading/threading.rb +45 -0
  40. data/test/configuration_test.rb +48 -0
  41. data/test/core_test.rb +48 -0
  42. data/test/databases.yml +19 -0
  43. data/test/generator_test.rb +20 -0
  44. data/test/globalize_test.rb +57 -0
  45. data/test/helper.rb +87 -0
  46. data/test/history_test.rb +149 -0
  47. data/test/object_utils_test.rb +28 -0
  48. data/test/reserved_test.rb +40 -0
  49. data/test/schema.rb +79 -0
  50. data/test/scoped_test.rb +83 -0
  51. data/test/shared.rb +156 -0
  52. data/test/simple_i18n_test.rb +133 -0
  53. data/test/slugged_test.rb +280 -0
  54. data/test/sti_test.rb +77 -0
  55. metadata +262 -0
@@ -0,0 +1,17 @@
1
+ require 'rails/generators'
2
+ require "rails/generators/active_record"
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
+ extend ActiveRecord::Generators::Migration
9
+
10
+ source_root File.expand_path('../../friendly_id', __FILE__)
11
+
12
+ # Copies the migration template to db/migrate.
13
+ def copy_files(*args)
14
+ migration_template 'migration.rb', 'db/migrate/create_friendly_id_slugs.rb'
15
+ end
16
+
17
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ require "friendly_id"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "mil_friendly_id"
8
+ s.version = FriendlyId::VERSION
9
+ s.authors = ["Norman Clarke", "Philip Arndt"]
10
+ s.email = ["norman@njclarke.com", "parndt@gmail.com"]
11
+ s.homepage = "http://github.com/norman/friendly_id"
12
+ s.summary = "A comprehensive slugging and pretty-URL plugin."
13
+ s.rubyforge_project = "friendly_id"
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test}/*`.split("\n")
16
+ s.require_paths = ["lib"]
17
+
18
+ s.add_dependency 'acts_as_paranoid', '0.4.1'
19
+
20
+ s.add_development_dependency "railties", "~> 3.2.0"
21
+ s.add_development_dependency "activerecord", "~> 3.2.0"
22
+ s.add_development_dependency "minitest", "3.2.0"
23
+ s.add_development_dependency "mocha"
24
+ s.add_development_dependency "maruku"
25
+ s.add_development_dependency "yard"
26
+ s.add_development_dependency "i18n"
27
+ s.add_development_dependency "ffaker"
28
+ s.add_development_dependency "simplecov"
29
+ s.add_development_dependency "globalize3"
30
+
31
+ s.description = <<-EOM
32
+ FriendlyId is the "Swiss Army bulldozer" of slugging and permalink plugins for
33
+ Ruby on Rails. It allows you to create pretty URLs and work with human-friendly
34
+ strings as if they were numeric ids for Active Record models.
35
+ EOM
36
+
37
+ s.post_install_message = <<-EOM
38
+ NOTE: FriendlyId 4.x breaks compatibility with 3.x. If you're upgrading
39
+ from 3.x, please see this document:
40
+
41
+ http://rubydoc.info/github/norman/friendly_id/master/file/WhatsNew.md
42
+
43
+ EOM
44
+
45
+ end
@@ -0,0 +1,72 @@
1
+ require "helper"
2
+
3
+ class CoreTest < MiniTest::Unit::TestCase
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
+
32
+ test "friendly_id should accept a block" do
33
+ klass = Class.new(ActiveRecord::Base) do
34
+ self.abstract_class = true
35
+ extend FriendlyId
36
+ friendly_id :foo do |config|
37
+ config.use :slugged
38
+ config.base = :foo
39
+ config.slug_column = :bar
40
+ end
41
+ end
42
+ assert klass < FriendlyId::Slugged
43
+ assert_equal :foo, klass.friendly_id_config.base
44
+ assert_equal :bar, klass.friendly_id_config.slug_column
45
+ end
46
+
47
+ test "the block passed to friendly_id should be evaluated before arguments" do
48
+ klass = Class.new(ActiveRecord::Base) do
49
+ self.abstract_class = true
50
+ extend FriendlyId
51
+ friendly_id :foo do |config|
52
+ config.base = :bar
53
+ end
54
+ end
55
+ assert_equal :foo, klass.friendly_id_config.base
56
+ end
57
+
58
+ test "should allow defaults to be set via a block" do
59
+ begin
60
+ FriendlyId.defaults do |config|
61
+ config.base = :foo
62
+ end
63
+ klass = Class.new(ActiveRecord::Base) do
64
+ self.abstract_class = true
65
+ extend FriendlyId
66
+ end
67
+ assert_equal :foo, klass.friendly_id_config.base
68
+ ensure
69
+ FriendlyId.instance_variable_set :@defaults, nil
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+
3
+ gem "sqlite3", "~> 1.3.4"
4
+ gem "activerecord", "3.0.10"
5
+ gem "minitest", "~> 2.4.0"
6
+ gem "mocha", "~> 0.9.12"
7
+ gem "ancestry"
8
+ gem "rake"
@@ -0,0 +1,34 @@
1
+ require File.expand_path("../../../helper", __FILE__)
2
+
3
+ require "ancestry"
4
+
5
+ ActiveRecord::Migration.create_table("things") do |t|
6
+ t.string :name
7
+ t.string :slug
8
+ t.string :ancestry
9
+ end
10
+ ActiveRecord::Migration.add_index :things, :ancestry
11
+
12
+ class Thing < ActiveRecord::Base
13
+ extend FriendlyId
14
+ friendly_id do |config|
15
+ config.use :slugged
16
+ config.use :scoped
17
+ config.base = :name
18
+ config.scope = :ancestry
19
+ end
20
+ has_ancestry
21
+ end
22
+
23
+ class AncestryTest < MiniTest::Unit::TestCase
24
+ include FriendlyId::Test
25
+
26
+ test "should sequence slugs when scoped by ancestry" do
27
+ 3.times.inject([]) do |memo, _|
28
+ memo << Thing.create!(:name => "a", :parent => memo.last)
29
+ end.each do |thing|
30
+ assert_equal "a", thing.friendly_id
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,8 @@
1
+ source :rubygems
2
+
3
+ gem "pg"
4
+ gem "mysql2"
5
+ gem "mocha"
6
+ gem "activerecord", "3.1.1"
7
+ gem "sqlite3"
8
+ gem "fatalistic"
@@ -0,0 +1,45 @@
1
+ ENV["DB"] = "postgres"
2
+
3
+ require "thread"
4
+ require File.expand_path("../../../helper", __FILE__)
5
+ require "active_record/locking/fatalistic"
6
+
7
+ ActiveRecord::Migration.tap do |m|
8
+ m.drop_table "things"
9
+ m.create_table("things") do |t|
10
+ t.string :name
11
+ t.string :slug
12
+ end
13
+ m.add_index :things, :slug, :unique => true
14
+ end
15
+
16
+ class Thing < ActiveRecord::Base
17
+ extend FriendlyId
18
+ friendly_id :name, :use => :slugged
19
+ end
20
+
21
+ $things = 10.times.map do
22
+ Thing.new :name => "a b c"
23
+ end
24
+
25
+ $mutex = Mutex.new
26
+
27
+ def save_thing
28
+ thing = $mutex.synchronize do
29
+ $things.pop
30
+ end
31
+ if thing.nil? then return end
32
+ Thing.lock do
33
+ thing.save!
34
+ print "#{thing.friendly_id}\n"
35
+ end
36
+ true
37
+ end
38
+
39
+ 2.times.map do
40
+ Thread.new do
41
+ while true do
42
+ break unless save_thing
43
+ end
44
+ end
45
+ end.map(&:value)
@@ -0,0 +1,48 @@
1
+ require "helper"
2
+
3
+ class ConfigurationTest < MiniTest::Unit::TestCase
4
+
5
+ include FriendlyId::Test
6
+
7
+ def setup
8
+ @model_class = Class.new(ActiveRecord::Base) do
9
+ self.abstract_class = true
10
+ end
11
+ end
12
+
13
+ test "should set model class on initialization" do
14
+ config = FriendlyId::Configuration.new @model_class
15
+ assert_equal @model_class, config.model_class
16
+ end
17
+
18
+ test "should set options on initialization if present" do
19
+ config = FriendlyId::Configuration.new @model_class, :base => "hello"
20
+ assert_equal "hello", config.base
21
+ end
22
+
23
+ test "should raise error if passed unrecognized option" do
24
+ assert_raises NoMethodError do
25
+ FriendlyId::Configuration.new @model_class, :foo => "bar"
26
+ end
27
+ end
28
+
29
+ test "#use should accept a name that resolves to a module" do
30
+ refute @model_class < FriendlyId::Slugged
31
+ @model_class.class_eval do
32
+ extend FriendlyId
33
+ friendly_id :hello, :use => :slugged
34
+ end
35
+ assert @model_class < FriendlyId::Slugged
36
+ end
37
+
38
+ test "#use should accept a module" do
39
+ my_module = Module.new
40
+ refute @model_class < my_module
41
+ @model_class.class_eval do
42
+ extend FriendlyId
43
+ friendly_id :hello, :use => my_module
44
+ end
45
+ assert @model_class < my_module
46
+ end
47
+
48
+ end
@@ -0,0 +1,48 @@
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 < MiniTest::Unit::TestCase
15
+
16
+ include FriendlyId::Test
17
+ include FriendlyId::Test::Shared::Core
18
+
19
+ def model_class
20
+ Author
21
+ end
22
+
23
+ test "models don't use friendly_id by default" do
24
+ assert !Class.new(ActiveRecord::Base) {
25
+ self.abstract_class = true
26
+ }.respond_to?(:friendly_id)
27
+ end
28
+
29
+ test "model classes should have a friendly id config" do
30
+ assert model_class.friendly_id(:name).friendly_id_config
31
+ end
32
+
33
+ test "instances should have a friendly id" do
34
+ with_instance_of(model_class) {|record| assert record.friendly_id}
35
+ end
36
+
37
+ test "instances can be marshaled when a relationship is used" do
38
+ transaction do
39
+ author = Author.create :name => 'Philip'
40
+ author.books.create :name => 'my book'
41
+ begin
42
+ assert Marshal.load(Marshal.dump(author))
43
+ rescue TypeError => e
44
+ flunk(e.to_s)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,19 @@
1
+ mysql:
2
+ adapter: mysql2
3
+ database: friendly_id_test
4
+ username: root
5
+ hostname: localhost
6
+ encoding: utf8
7
+
8
+ postgres:
9
+ adapter: postgresql
10
+ host: localhost
11
+ port: 5432
12
+ username: postgres
13
+ database: friendly_id_test
14
+ encoding: utf8
15
+
16
+ sqlite3:
17
+ adapter: sqlite3
18
+ database: ":memory:"
19
+ encoding: utf8
@@ -0,0 +1,20 @@
1
+ require "helper"
2
+ require "rails/generators"
3
+ require "generators/friendly_id_generator"
4
+
5
+ class FriendlyIdGeneratorTest < Rails::Generators::TestCase
6
+
7
+ tests FriendlyIdGenerator
8
+ destination File.expand_path("../../tmp", __FILE__)
9
+
10
+ setup :prepare_destination
11
+
12
+ test "should generate a migration" do
13
+ begin
14
+ run_generator
15
+ assert_migration "db/migrate/create_friendly_id_slugs"
16
+ ensure
17
+ FileUtils.rm_rf self.destination_root
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ require "helper"
4
+
5
+ class TranslatedArticle < ActiveRecord::Base
6
+ translates :slug, :title
7
+ extend FriendlyId
8
+ friendly_id :title, :use => :globalize
9
+ end
10
+
11
+ class GlobalizeTest < MiniTest::Unit::TestCase
12
+ include FriendlyId::Test
13
+
14
+ def setup
15
+ I18n.locale = :en
16
+ end
17
+
18
+ test "should find slug in current locale if locale is set, otherwise in default locale" do
19
+ transaction do
20
+ I18n.default_locale = :en
21
+ article_en = I18n.with_locale(:en) { TranslatedArticle.create(:title => 'a title') }
22
+ article_de = I18n.with_locale(:de) { TranslatedArticle.create(:title => 'titel') }
23
+
24
+ I18n.with_locale(:de) {
25
+ assert_equal TranslatedArticle.find("titel"), article_de
26
+ assert_equal TranslatedArticle.find("a-title"), article_en
27
+ }
28
+ end
29
+ end
30
+
31
+ test "should set friendly id for locale" do
32
+ transaction do
33
+ article = TranslatedArticle.create!(:title => "War and Peace")
34
+ article.set_friendly_id("Guerra y paz", :es)
35
+ article.save!
36
+ article = TranslatedArticle.find('war-and-peace')
37
+ I18n.with_locale(:es) { assert_equal "guerra-y-paz", article.friendly_id }
38
+ I18n.with_locale(:en) { assert_equal "war-and-peace", article.friendly_id }
39
+ end
40
+ end
41
+
42
+ # https://github.com/svenfuchs/globalize3/blob/master/test/globalize3/dynamic_finders_test.rb#L101
43
+ # see: https://github.com/svenfuchs/globalize3/issues/100
44
+ test "record returned by friendly_id should have all translations" do
45
+ transaction do
46
+ I18n.with_locale(:en) do
47
+ article = TranslatedArticle.create(:title => 'a title')
48
+ Globalize.with_locale(:ja) { article.update_attributes(:title => 'タイトル') }
49
+ article_by_friendly_id = TranslatedArticle.find("a-title")
50
+ article.translations.each do |translation|
51
+ assert_includes article_by_friendly_id.translations, translation
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ end
@@ -0,0 +1,87 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require "minitest/unit"
4
+ require "mocha"
5
+ require "active_record"
6
+ require 'active_support/core_ext/time/conversions'
7
+
8
+
9
+ if ENV["COVERAGE"]
10
+ require 'simplecov'
11
+ SimpleCov.start do
12
+ add_filter "test/"
13
+ add_filter "friendly_id/migration"
14
+ end
15
+ end
16
+
17
+ require "friendly_id"
18
+
19
+ # If you want to see the ActiveRecord log, invoke the tests using `rake test LOG=true`
20
+ if ENV["LOG"]
21
+ require "logger"
22
+ ActiveRecord::Base.logger = Logger.new($stdout)
23
+ end
24
+
25
+ module FriendlyId
26
+ module Test
27
+
28
+ def self.included(base)
29
+ MiniTest::Unit.autorun
30
+ end
31
+
32
+ def transaction
33
+ ActiveRecord::Base.transaction { yield ; raise ActiveRecord::Rollback }
34
+ end
35
+
36
+ def with_instance_of(*args)
37
+ model_class = args.shift
38
+ args[0] ||= {:name => "a b c"}
39
+ transaction { yield model_class.create!(*args) }
40
+ end
41
+
42
+ module Database
43
+ extend self
44
+
45
+ def connect
46
+ version = ActiveRecord::VERSION::STRING
47
+ driver = FriendlyId::Test::Database.driver
48
+ engine = RUBY_ENGINE rescue "ruby"
49
+
50
+ ActiveRecord::Base.establish_connection config[driver]
51
+ message = "Using #{engine} #{RUBY_VERSION} AR #{version} with #{driver}"
52
+
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(File.expand_path("../databases.yml", __FILE__)))
65
+ end
66
+
67
+ def driver
68
+ (ENV["DB"] or "sqlite3").downcase
69
+ end
70
+
71
+ def in_memory?
72
+ config[driver]["database"] == ":memory:"
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ class Module
79
+ def test(name, &block)
80
+ define_method("test_#{name.gsub(/[^a-z0-9']/i, "_")}".to_sym, &block)
81
+ end
82
+ end
83
+
84
+ require "schema"
85
+ require "shared"
86
+ FriendlyId::Test::Database.connect
87
+ at_exit {ActiveRecord::Base.connection.disconnect!}