stringex 1.5.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +16 -0
  3. data/Gemfile.lock +74 -0
  4. data/README.rdoc +22 -1
  5. data/Rakefile +46 -223
  6. data/VERSION +1 -0
  7. data/init.rb +1 -0
  8. data/lib/stringex.rb +11 -3
  9. data/lib/stringex/acts_as_url.rb +49 -97
  10. data/lib/stringex/acts_as_url/adapter.rb +26 -0
  11. data/lib/stringex/acts_as_url/adapter/active_record.rb +23 -0
  12. data/lib/stringex/acts_as_url/adapter/base.rb +188 -0
  13. data/lib/stringex/acts_as_url/adapter/data_mapper.rb +67 -0
  14. data/lib/stringex/acts_as_url/adapter/mongoid.rb +36 -0
  15. data/lib/stringex/configuration.rb +4 -0
  16. data/lib/stringex/configuration/acts_as_url.rb +44 -0
  17. data/lib/stringex/configuration/base.rb +58 -0
  18. data/lib/stringex/configuration/configurator.rb +25 -0
  19. data/lib/stringex/configuration/string_extensions.rb +19 -0
  20. data/lib/stringex/localization.rb +98 -0
  21. data/lib/stringex/localization/backend/i18n.rb +53 -0
  22. data/lib/stringex/localization/backend/internal.rb +51 -0
  23. data/lib/stringex/localization/conversion_expressions.rb +148 -0
  24. data/lib/stringex/localization/converter.rb +121 -0
  25. data/lib/stringex/localization/default_conversions.rb +88 -0
  26. data/lib/stringex/rails/railtie.rb +10 -0
  27. data/lib/stringex/string_extensions.rb +153 -208
  28. data/lib/stringex/unidecoder.rb +6 -101
  29. data/lib/stringex/unidecoder_data/x00.yml +1 -1
  30. data/lib/stringex/unidecoder_data/x02.yml +5 -5
  31. data/lib/stringex/unidecoder_data/x05.yml +1 -1
  32. data/lib/stringex/unidecoder_data/x06.yml +1 -1
  33. data/lib/stringex/unidecoder_data/x07.yml +3 -3
  34. data/lib/stringex/unidecoder_data/x09.yml +1 -1
  35. data/lib/stringex/unidecoder_data/x0e.yml +2 -2
  36. data/lib/stringex/unidecoder_data/x1f.yml +2 -2
  37. data/lib/stringex/unidecoder_data/x20.yml +1 -1
  38. data/lib/stringex/unidecoder_data/xfb.yml +1 -1
  39. data/lib/stringex/unidecoder_data/xff.yml +1 -1
  40. data/lib/stringex/version.rb +8 -0
  41. data/locales/da.yml +73 -0
  42. data/locales/en.yml +66 -0
  43. data/stringex.gemspec +77 -18
  44. data/test/acts_as_url/adapter/active_record.rb +72 -0
  45. data/test/acts_as_url/adapter/data_mapper.rb +82 -0
  46. data/test/acts_as_url/adapter/mongoid.rb +73 -0
  47. data/test/acts_as_url_configuration_test.rb +51 -0
  48. data/test/acts_as_url_integration_test.rb +271 -0
  49. data/test/localization/da_test.rb +117 -0
  50. data/test/localization/default_test.rb +113 -0
  51. data/test/localization/en_test.rb +117 -0
  52. data/test/localization_test.rb +123 -0
  53. data/test/redcloth_to_html_test.rb +37 -0
  54. data/test/string_extensions_test.rb +59 -91
  55. data/test/test_helper.rb +2 -0
  56. data/test/unicode_point_suite/basic_greek_test.rb +113 -0
  57. data/test/unicode_point_suite/basic_latin_test.rb +142 -0
  58. data/test/unicode_point_suite/codepoint_test_helper.rb +32 -0
  59. data/test/unidecoder/bad_localization.yml +1 -0
  60. data/test/unidecoder/localization.yml +4 -0
  61. data/test/unidecoder_test.rb +3 -5
  62. metadata +145 -37
  63. data/test/acts_as_url_test.rb +0 -272
data/stringex.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "stringex"
8
- s.version = "1.5.1"
8
+ s.version = "2.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Russell Norris"]
12
- s.date = "2012-11-30"
12
+ s.date = "2013-06-03"
13
13
  s.description = "Some [hopefully] useful extensions to Ruby's String class. Stringex is made up of three libraries: ActsAsUrl [permalink solution with better character translation], Unidecoder [Unicode to ASCII transliteration], and StringExtensions [miscellaneous helper methods for the String class]."
14
14
  s.email = "rsl@luckysneaks.com"
15
15
  s.extra_rdoc_files = [
@@ -17,12 +17,32 @@ Gem::Specification.new do |s|
17
17
  "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
+ "Gemfile",
21
+ "Gemfile.lock",
20
22
  "MIT-LICENSE",
21
23
  "README.rdoc",
22
24
  "Rakefile",
25
+ "VERSION",
23
26
  "init.rb",
24
27
  "lib/stringex.rb",
25
28
  "lib/stringex/acts_as_url.rb",
29
+ "lib/stringex/acts_as_url/adapter.rb",
30
+ "lib/stringex/acts_as_url/adapter/active_record.rb",
31
+ "lib/stringex/acts_as_url/adapter/base.rb",
32
+ "lib/stringex/acts_as_url/adapter/data_mapper.rb",
33
+ "lib/stringex/acts_as_url/adapter/mongoid.rb",
34
+ "lib/stringex/configuration.rb",
35
+ "lib/stringex/configuration/acts_as_url.rb",
36
+ "lib/stringex/configuration/base.rb",
37
+ "lib/stringex/configuration/configurator.rb",
38
+ "lib/stringex/configuration/string_extensions.rb",
39
+ "lib/stringex/localization.rb",
40
+ "lib/stringex/localization/backend/i18n.rb",
41
+ "lib/stringex/localization/backend/internal.rb",
42
+ "lib/stringex/localization/conversion_expressions.rb",
43
+ "lib/stringex/localization/converter.rb",
44
+ "lib/stringex/localization/default_conversions.rb",
45
+ "lib/stringex/rails/railtie.rb",
26
46
  "lib/stringex/string_extensions.rb",
27
47
  "lib/stringex/unidecoder.rb",
28
48
  "lib/stringex/unidecoder_data/x00.yml",
@@ -205,37 +225,76 @@ Gem::Specification.new do |s|
205
225
  "lib/stringex/unidecoder_data/xfd.yml",
206
226
  "lib/stringex/unidecoder_data/xfe.yml",
207
227
  "lib/stringex/unidecoder_data/xff.yml",
208
- "stringex.gemspec"
228
+ "lib/stringex/version.rb",
229
+ "locales/da.yml",
230
+ "locales/en.yml",
231
+ "stringex.gemspec",
232
+ "test/acts_as_url/adapter/active_record.rb",
233
+ "test/acts_as_url/adapter/data_mapper.rb",
234
+ "test/acts_as_url/adapter/mongoid.rb",
235
+ "test/acts_as_url_configuration_test.rb",
236
+ "test/acts_as_url_integration_test.rb",
237
+ "test/localization/da_test.rb",
238
+ "test/localization/default_test.rb",
239
+ "test/localization/en_test.rb",
240
+ "test/localization_test.rb",
241
+ "test/redcloth_to_html_test.rb",
242
+ "test/string_extensions_test.rb",
243
+ "test/test_helper.rb",
244
+ "test/unicode_point_suite/basic_greek_test.rb",
245
+ "test/unicode_point_suite/basic_latin_test.rb",
246
+ "test/unicode_point_suite/codepoint_test_helper.rb",
247
+ "test/unidecoder/bad_localization.yml",
248
+ "test/unidecoder/localization.yml",
249
+ "test/unidecoder_test.rb"
209
250
  ]
210
251
  s.homepage = "http://github.com/rsl/stringex"
252
+ s.licenses = ["MIT"]
211
253
  s.rdoc_options = ["--main", "README.rdoc", "--charset", "utf-8", "--line-numbers"]
212
254
  s.require_paths = ["lib"]
213
- s.rubygems_version = "1.8.24"
255
+ s.rubygems_version = "2.0.3"
214
256
  s.summary = "Some [hopefully] useful extensions to Ruby's String class"
215
- s.test_files = ["test/acts_as_url_test.rb", "test/string_extensions_test.rb", "test/unidecoder_test.rb"]
216
257
 
217
258
  if s.respond_to? :specification_version then
218
- s.specification_version = 3
259
+ s.specification_version = 4
219
260
 
220
261
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
221
- s.add_development_dependency(%q<activerecord>, [">= 0"])
262
+ s.add_development_dependency(%q<activerecord>, ["= 3.2.13"])
263
+ s.add_development_dependency(%q<dm-core>, ["= 1.2.0"])
264
+ s.add_development_dependency(%q<dm-migrations>, ["= 1.2.0"])
265
+ s.add_development_dependency(%q<dm-sqlite-adapter>, ["= 1.2.0"])
266
+ s.add_development_dependency(%q<dm-validations>, ["= 1.2.0"])
222
267
  s.add_development_dependency(%q<jeweler>, ["= 1.8.4"])
223
- s.add_development_dependency(%q<RedCloth>, [">= 0"])
224
- s.add_development_dependency(%q<sqlite3>, [">= 0"])
225
- s.add_development_dependency(%q<travis-lint>, ["= 1.4.0"])
268
+ s.add_development_dependency(%q<mongoid>, ["= 3.1.4"])
269
+ s.add_development_dependency(%q<RedCloth>, ["= 4.2.9"])
270
+ s.add_development_dependency(%q<sqlite3>, ["= 1.3.7"])
271
+ s.add_development_dependency(%q<travis-lint>, ["= 1.7.0"])
272
+ s.add_development_dependency(%q<i18n>, ["= 0.6.1"])
226
273
  else
227
- s.add_dependency(%q<activerecord>, [">= 0"])
274
+ s.add_dependency(%q<activerecord>, ["= 3.2.13"])
275
+ s.add_dependency(%q<dm-core>, ["= 1.2.0"])
276
+ s.add_dependency(%q<dm-migrations>, ["= 1.2.0"])
277
+ s.add_dependency(%q<dm-sqlite-adapter>, ["= 1.2.0"])
278
+ s.add_dependency(%q<dm-validations>, ["= 1.2.0"])
228
279
  s.add_dependency(%q<jeweler>, ["= 1.8.4"])
229
- s.add_dependency(%q<RedCloth>, [">= 0"])
230
- s.add_dependency(%q<sqlite3>, [">= 0"])
231
- s.add_dependency(%q<travis-lint>, ["= 1.4.0"])
280
+ s.add_dependency(%q<mongoid>, ["= 3.1.4"])
281
+ s.add_dependency(%q<RedCloth>, ["= 4.2.9"])
282
+ s.add_dependency(%q<sqlite3>, ["= 1.3.7"])
283
+ s.add_dependency(%q<travis-lint>, ["= 1.7.0"])
284
+ s.add_dependency(%q<i18n>, ["= 0.6.1"])
232
285
  end
233
286
  else
234
- s.add_dependency(%q<activerecord>, [">= 0"])
287
+ s.add_dependency(%q<activerecord>, ["= 3.2.13"])
288
+ s.add_dependency(%q<dm-core>, ["= 1.2.0"])
289
+ s.add_dependency(%q<dm-migrations>, ["= 1.2.0"])
290
+ s.add_dependency(%q<dm-sqlite-adapter>, ["= 1.2.0"])
291
+ s.add_dependency(%q<dm-validations>, ["= 1.2.0"])
235
292
  s.add_dependency(%q<jeweler>, ["= 1.8.4"])
236
- s.add_dependency(%q<RedCloth>, [">= 0"])
237
- s.add_dependency(%q<sqlite3>, [">= 0"])
238
- s.add_dependency(%q<travis-lint>, ["= 1.4.0"])
293
+ s.add_dependency(%q<mongoid>, ["= 3.1.4"])
294
+ s.add_dependency(%q<RedCloth>, ["= 4.2.9"])
295
+ s.add_dependency(%q<sqlite3>, ["= 1.3.7"])
296
+ s.add_dependency(%q<travis-lint>, ["= 1.7.0"])
297
+ s.add_dependency(%q<i18n>, ["= 0.6.1"])
239
298
  end
240
299
  end
241
300
 
@@ -0,0 +1,72 @@
1
+ require 'rubygems'
2
+ gem 'activerecord'
3
+ require 'active_record'
4
+ require "stringex"
5
+ # Reload adapters to make sure ActsAsUrl sees the ORM
6
+ Stringex::ActsAsUrl::Adapter.load_available
7
+
8
+ puts "-------------------------------------------------"
9
+ puts "Running ActsAsUrl tests with ActiveRecord adapter"
10
+ puts "-------------------------------------------------"
11
+
12
+ ActiveRecord::Base.establish_connection :adapter => "sqlite3", :database => ":memory:"
13
+
14
+ ActiveRecord::Migration.verbose = false
15
+ ActiveRecord::Schema.define do
16
+ create_table :documents, :force => true do |t|
17
+ t.string :title, :other, :url
18
+ end
19
+
20
+ create_table :sti_base_documents, :force => true do |t|
21
+ t.string :title, :other, :url, :type
22
+ end
23
+ end
24
+ ActiveRecord::Migration.verbose = true
25
+
26
+ class Document < ActiveRecord::Base
27
+ acts_as_url :title
28
+ end
29
+
30
+ class STIBaseDocument < ActiveRecord::Base
31
+ # This gets redefined in the only test that uses it but I want to be uniform
32
+ # in setting configuration details in the tests themselves
33
+ acts_as_url :title
34
+ end
35
+
36
+ class STIChildDocument < STIBaseDocument
37
+ end
38
+
39
+ class AnotherSTIChildDocument < STIBaseDocument
40
+ end
41
+
42
+ module AdapterSpecificTestBehaviors
43
+ def setup
44
+ # No setup tasks at present
45
+ end
46
+
47
+ def teardown
48
+ [Document, STIBaseDocument].each do |klass|
49
+ klass.delete_all
50
+ # Reset behavior to default
51
+ klass.class_eval do
52
+ acts_as_url :title
53
+ end
54
+ end
55
+ end
56
+
57
+ def add_validation_on_document_title
58
+ Document.class_eval do
59
+ validates_presence_of :title
60
+ end
61
+ end
62
+
63
+ def remove_validation_on_document_title
64
+ Document.class_eval do
65
+ _validators.delete :title
66
+ end
67
+ end
68
+
69
+ def adapter_specific_update(instance, hash)
70
+ instance.send :update_attributes!, hash
71
+ end
72
+ end
@@ -0,0 +1,82 @@
1
+ require 'rubygems'
2
+ gem 'dm-core'
3
+ gem 'dm-migrations'
4
+ gem 'dm-validations'
5
+ require 'dm-core'
6
+ require 'dm-migrations'
7
+ require 'dm-validations'
8
+ require 'stringex'
9
+ # Reload adapters to make sure ActsAsUrl sees the ORM
10
+ Stringex::ActsAsUrl::Adapter.load_available
11
+
12
+ puts "-------------------------------------------------"
13
+ puts "Running ActsAsUrl tests with DataMapper adapter"
14
+ puts "-------------------------------------------------"
15
+
16
+ DataMapper.setup :default, 'sqlite::memory:'
17
+
18
+ # What the tests do in constant redefining the same classes doesn't quite work with DataMapper.
19
+ # This proc allows us to reset the class definitions on each test. This might be more expensive
20
+ # but it definitely allows the class definitions to be correct. If someone more familiar with
21
+ # DataMapper than I am wants to refactor this, I'd be more than happy to take a look.
22
+ DefineTestClasses = proc do
23
+ class Document
24
+ include DataMapper::Resource
25
+ property :id, Serial
26
+ property :title, String
27
+ property :other, String
28
+ property :url, String, :lazy => false
29
+
30
+ acts_as_url :title
31
+ end
32
+
33
+ class STIBaseDocument
34
+ include DataMapper::Resource
35
+ property :id, Serial
36
+ property :title, String
37
+ property :other, String
38
+ property :url, String, :lazy => false
39
+ property :type, String
40
+
41
+ # This gets redefined in the only test that uses it but I want to be uniform
42
+ # in setting configuration details in the tests themselves
43
+ acts_as_url :title
44
+ end
45
+
46
+ class STIChildDocument < STIBaseDocument
47
+ end
48
+
49
+ class AnotherSTIChildDocument < STIBaseDocument
50
+ end
51
+
52
+ DataMapper.finalize
53
+ Document.auto_migrate!
54
+ STIBaseDocument.auto_migrate!
55
+ end
56
+
57
+ module AdapterSpecificTestBehaviors
58
+ def setup
59
+ DefineTestClasses.call
60
+ end
61
+
62
+ def teardown
63
+ [Document, STIBaseDocument, STIChildDocument, AnotherSTIChildDocument].each do |klass|
64
+ klass.destroy
65
+ Object.send :remove_const, klass.name.intern
66
+ end
67
+ end
68
+
69
+ def add_validation_on_document_title
70
+ Document.class_eval do
71
+ validates_presence_of :title
72
+ end
73
+ end
74
+
75
+ def remove_validation_on_document_title
76
+ # Do nothing. The class is going to be reloaded on the next test.
77
+ end
78
+
79
+ def adapter_specific_update(instance, hash)
80
+ response = instance.send :update, hash
81
+ end
82
+ end
@@ -0,0 +1,73 @@
1
+ require 'rubygems'
2
+ gem 'mongoid'
3
+ require 'mongoid'
4
+ require 'stringex'
5
+ # Reload adapters to make sure ActsAsUrl sees the ORM
6
+ Stringex::ActsAsUrl::Adapter.load_available
7
+
8
+ puts "-------------------------------------------------"
9
+ puts "Running ActsAsUrl tests with Mongoid adapter"
10
+ puts "-------------------------------------------------"
11
+
12
+ Mongoid.configure do |config|
13
+ config.connect_to('acts_as_url')
14
+ end
15
+
16
+ class Document
17
+ include Mongoid::Document
18
+ field :title, :type => String
19
+ field :other, :type => String
20
+ field :url, :type => String
21
+
22
+ acts_as_url :title
23
+ end
24
+
25
+ class STIBaseDocument
26
+ include Mongoid::Document
27
+ field :title, :type => String
28
+ field :other, :type => String
29
+ field :url, :type => String
30
+ field :type, :type => String
31
+
32
+ # This gets redefined in the only test that uses it but I want to be uniform
33
+ # in setting configuration details in the tests themselves
34
+ acts_as_url :title
35
+ end
36
+
37
+ class STIChildDocument < STIBaseDocument
38
+ end
39
+
40
+ class AnotherSTIChildDocument < STIBaseDocument
41
+ end
42
+
43
+ module AdapterSpecificTestBehaviors
44
+ def setup
45
+ # No setup tasks at present
46
+ end
47
+
48
+ def teardown
49
+ [Document, STIBaseDocument].each do |klass|
50
+ klass.delete_all
51
+ # Reset behavior to default
52
+ klass.class_eval do
53
+ acts_as_url :title
54
+ end
55
+ end
56
+ end
57
+
58
+ def add_validation_on_document_title
59
+ Document.class_eval do
60
+ validates_presence_of :title
61
+ end
62
+ end
63
+
64
+ def remove_validation_on_document_title
65
+ Document.class_eval do
66
+ _validators.delete :title
67
+ end
68
+ end
69
+
70
+ def adapter_specific_update(instance, hash)
71
+ instance.send :update_attributes!, hash
72
+ end
73
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'test_helper'
4
+ require 'stringex'
5
+
6
+ class ActsAsUrlConfigurationTest < Test::Unit::TestCase
7
+ def teardown
8
+ Stringex::ActsAsUrl.unconfigure!
9
+ end
10
+
11
+ def test_can_set_base_settings
12
+ default_configuration = Stringex::Configuration::ActsAsUrl.new(:url_attribute => "original")
13
+ assert_equal "original", default_configuration.settings.url_attribute
14
+
15
+ Stringex::ActsAsUrl.configure do |c|
16
+ c.url_attribute = "special"
17
+ end
18
+ new_configuration = Stringex::Configuration::ActsAsUrl.new
19
+ assert_equal "special", new_configuration.settings.url_attribute
20
+ end
21
+
22
+ def test_local_options_overrides_system_wide_configuration
23
+ Stringex::ActsAsUrl.configure do |c|
24
+ c.url_attribute = "special"
25
+ end
26
+ system_configuration = Stringex::Configuration::ActsAsUrl.new
27
+ assert_equal "special", system_configuration.settings.url_attribute
28
+
29
+ local_configuration = Stringex::Configuration::ActsAsUrl.new(:url_attribute => "local")
30
+ assert_equal "local", local_configuration.settings.url_attribute
31
+ end
32
+
33
+ def test_inherits_settings_from_string_extensions
34
+ string_extensions_settings = Stringex::Configuration::StringExtensions.new
35
+ acts_as_url_settings = Stringex::Configuration::ActsAsUrl.new
36
+
37
+ acts_as_url_settings.string_extensions_settings.keys.each do |key|
38
+ assert_equal acts_as_url_settings.settings.send(key), string_extensions_settings.settings.send(key)
39
+ end
40
+ end
41
+
42
+ def test_accepts_base_settings_for_string_extensions
43
+ string_extensions_settings = Stringex::Configuration::StringExtensions.new.default_settings
44
+
45
+ Stringex::ActsAsUrl.configure do |c|
46
+ string_extensions_settings.keys.each do |key|
47
+ assert_respond_to c, "#{key}="
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,271 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'test_helper'
4
+
5
+ adapter = ENV['ADAPTER'] || 'active_record'
6
+ require File.join(File.expand_path(File.dirname(__FILE__)), "acts_as_url/adapter/#{adapter}.rb")
7
+
8
+ class ActsAsUrlIntegrationTest < Test::Unit::TestCase
9
+ include AdapterSpecificTestBehaviors
10
+
11
+ def test_should_create_url
12
+ @doc = Document.create(:title => "Let's Make a Test Title, <em>Okay</em>?")
13
+ assert_equal "lets-make-a-test-title-okay", @doc.url
14
+ end
15
+
16
+ def test_should_create_unique_url
17
+ @doc = Document.create(:title => "Unique")
18
+ @other_doc = Document.create(:title => "Unique")
19
+ assert_equal "unique", @doc.url
20
+ assert_equal "unique-1", @other_doc.url
21
+ end
22
+
23
+ def test_should_create_unique_url_when_partial_url_already_exists
24
+ @doc = Document.create(:title => "House Farms")
25
+ @other_doc = Document.create(:title => "House Farm")
26
+
27
+ assert_equal "house-farms", @doc.url
28
+ assert_equal "house-farm", @other_doc.url
29
+ end
30
+
31
+ def test_should_not_sync_url_by_default
32
+ @doc = Document.create(:title => "Stable as Stone")
33
+ @original_url = @doc.url
34
+ adapter_specific_update @doc, :title => "New Unstable Madness"
35
+ assert_equal @original_url, @doc.url
36
+ end
37
+
38
+ def test_should_allow_syncing_url
39
+ Document.class_eval do
40
+ acts_as_url :title, :sync_url => true
41
+ end
42
+
43
+ @doc = Document.create(:title => "Original")
44
+ @original_url = @doc.url
45
+ adapter_specific_update @doc, :title => "New and Improved"
46
+ assert_not_equal @original_url, @doc.url
47
+ end
48
+
49
+ def test_should_not_increment_count_on_repeated_saves
50
+ Document.class_eval do
51
+ acts_as_url :title, :sync_url => true
52
+ end
53
+
54
+ @doc = Document.create(:title => "Continuous or Constant")
55
+ assert_equal "continuous-or-constant", @doc.url
56
+ 5.times do |n|
57
+ @doc.save!
58
+ assert_equal "continuous-or-constant", @doc.url
59
+ end
60
+ end
61
+
62
+ def test_should_allow_allowing_duplicate_url
63
+ Document.class_eval do
64
+ acts_as_url :title, :allow_duplicates => true
65
+ end
66
+
67
+ @doc = Document.create(:title => "I am not a clone")
68
+ @other_doc = Document.create(:title => "I am not a clone")
69
+ assert_equal @doc.url, @other_doc.url
70
+ end
71
+
72
+ def test_should_allow_scoping_url_uniqueness
73
+ Document.class_eval do
74
+ acts_as_url :title, :scope => :other
75
+ end
76
+
77
+ @doc = Document.create(:title => "Mocumentary", :other => "I don't care if I'm unique for some reason")
78
+ @other_doc = Document.create(:title => "Mocumentary", :other => "Me either")
79
+ assert_equal @doc.url, @other_doc.url
80
+ end
81
+
82
+ def test_should_still_create_unique_urls_if_scoped_attribute_is_the_same
83
+ Document.class_eval do
84
+ acts_as_url :title, :scope => :other
85
+ end
86
+
87
+ @doc = Document.create(:title => "Mocumentary", :other => "Suddenly, I care if I'm unique")
88
+ @other_doc = Document.create(:title => "Mocumentary", :other => "Suddenly, I care if I'm unique")
89
+ assert_not_equal @doc.url, @other_doc.url
90
+ end
91
+
92
+ def test_should_allow_setting_url_attribute
93
+ Document.class_eval do
94
+ # Manually undefining the url method on Document which, in a real class not reused for tests,
95
+ # would never have been defined to begin with.
96
+ remove_method :url
97
+ acts_as_url :title, :url_attribute => :other
98
+ end
99
+
100
+ @doc = Document.create(:title => "Anything at This Point")
101
+ assert_equal "anything-at-this-point", @doc.other
102
+ assert_nil @doc.url
103
+ ensure
104
+ Document.class_eval do
105
+ # Manually undefining the other method on Document for the same reasons as before
106
+ remove_method :other
107
+ end
108
+ end
109
+
110
+ def test_should_allow_updating_url_only_when_blank
111
+ Document.class_eval do
112
+ acts_as_url :title, :only_when_blank => true
113
+ end
114
+
115
+ @string = 'the-url-of-concrete'
116
+ @doc = Document.create(:title => "Stable as Stone", :url => @string)
117
+ assert_equal @string, @doc.url
118
+ @other_doc = Document.create(:title => "Stable as Stone")
119
+ assert_equal 'stable-as-stone', @other_doc.url
120
+ end
121
+
122
+ def test_should_mass_initialize_urls
123
+ @doc = Document.create(:title => "Initial")
124
+ @other_doc = Document.create(:title => "Subsequent")
125
+ adapter_specific_update @doc, :url => nil
126
+ adapter_specific_update @other_doc, :url => nil
127
+ # Just making sure this got unset before the real test
128
+ assert_nil @doc.url
129
+ assert_nil @other_doc.url
130
+
131
+ Document.initialize_urls
132
+
133
+ @doc.reload
134
+ @other_doc.reload
135
+ assert_equal "initial", @doc.url
136
+ assert_equal "subsequent", @other_doc.url
137
+ end
138
+
139
+ def test_should_mass_initialize_urls_with_custom_url_attribute
140
+ Document.class_eval do
141
+ # Manually undefining the url method on Document which, in a real class not reused for tests,
142
+ # would never have been defined to begin with.
143
+ remove_method :url
144
+ acts_as_url :title, :url_attribute => :other
145
+ end
146
+
147
+ @doc = Document.create(:title => "Initial")
148
+ @other_doc = Document.create(:title => "Subsequent")
149
+ adapter_specific_update @doc, :other => nil
150
+ adapter_specific_update @other_doc, :other => nil
151
+ # Just making sure this got unset before the real test
152
+ assert_nil @doc.other
153
+ assert_nil @other_doc.other
154
+
155
+ Document.initialize_urls
156
+
157
+ @doc.reload
158
+ @other_doc.reload
159
+ assert_equal "initial", @doc.other
160
+ assert_equal "subsequent", @other_doc.other
161
+ ensure
162
+ Document.class_eval do
163
+ # Manually undefining the other method on Document for the same reasons as before
164
+ remove_method :other
165
+ end
166
+ end
167
+
168
+ def test_should_allow_using_custom_method_for_generating_url
169
+ Document.class_eval do
170
+ acts_as_url :non_attribute_method
171
+
172
+ def non_attribute_method
173
+ "#{title} got massaged"
174
+ end
175
+ end
176
+
177
+ @doc = Document.create(:title => "Title String")
178
+ assert_equal "title-string-got-massaged", @doc.url
179
+ ensure
180
+ Document.class_eval do
181
+ # Manually undefining method that isn't defined on Document by default
182
+ remove_method :non_attribute_method
183
+ end
184
+ end
185
+
186
+ def test_should_allow_customizing_duplicate_count_separator
187
+ Document.class_eval do
188
+ acts_as_url :title, :duplicate_count_separator => "---"
189
+ end
190
+
191
+ @doc = Document.create(:title => "Unique")
192
+ @other_doc = Document.create(:title => "Unique")
193
+ assert_equal "unique", @doc.url
194
+ assert_equal "unique---1", @other_doc.url
195
+ end
196
+
197
+ def test_should_only_update_url_if_url_attribute_is_valid
198
+ Document.class_eval do
199
+ acts_as_url :title, :sync_url => true
200
+ end
201
+ add_validation_on_document_title
202
+
203
+ @doc = Document.create(:title => "Valid Record", :other => "Present")
204
+ assert_equal "valid-record", @doc.url
205
+ @doc.title = nil
206
+ assert_equal false, @doc.valid?
207
+ assert_equal "valid-record", @doc.url
208
+ ensure
209
+ remove_validation_on_document_title
210
+ end
211
+
212
+ def test_should_allow_customizing_url_limit
213
+ Document.class_eval do
214
+ acts_as_url :title, :limit => 13
215
+ end
216
+
217
+ @doc = Document.create(:title => "I am much too long")
218
+ assert_equal "i-am-much-too", @doc.url
219
+ end
220
+
221
+ def test_handling_duplicate_urls_with_limits
222
+ Document.class_eval do
223
+ acts_as_url :title, :limit => 13
224
+ end
225
+
226
+ @doc = Document.create(:title => "I am much too long and also duplicated")
227
+ assert_equal "i-am-much-too", @doc.url
228
+ @other_doc = Document.create(:title => "I am much too long and also duplicated")
229
+ assert_equal "i-am-much-too-1", @other_doc.url
230
+ end
231
+
232
+ def test_should_allow_excluding_specific_values_from_being_run_through_to_url
233
+ Document.class_eval do
234
+ acts_as_url :title, :exclude => ["_So_Fucking_Special"]
235
+ end
236
+
237
+ @doc = Document.create(:title => "_So_Fucking_Special")
238
+ assert_equal "_So_Fucking_Special", @doc.url
239
+ @doc_2 = Document.create(:title => "But I'm a creep")
240
+ assert_equal "but-im-a-creep", @doc_2.url
241
+ end
242
+
243
+ def test_should_allow_not_forcing_downcasing
244
+ Document.class_eval do
245
+ acts_as_url :title, :force_downcase => false
246
+ end
247
+
248
+ @doc = Document.create(:title => "I have CAPS!")
249
+ assert_equal "I-have-CAPS", @doc.url
250
+ end
251
+
252
+ def test_should_allow_alternate_whitespace_replacements
253
+ Document.class_eval do
254
+ acts_as_url :title, :replace_whitespace_with => "~"
255
+ end
256
+
257
+ @doc = Document.create(:title => "now with tildes")
258
+ assert_equal "now~with~tildes", @doc.url
259
+ end
260
+
261
+ def test_should_allow_enforcing_uniqueness_on_sti_base_class
262
+ STIBaseDocument.class_eval do
263
+ acts_as_url :title, :enforce_uniqueness_on_sti_base_class => true
264
+ end
265
+
266
+ @doc = STIChildDocument.create(:title => "Unique")
267
+ assert_equal "unique", @doc.url
268
+ @doc_2 = AnotherSTIChildDocument.create(:title => "Unique")
269
+ assert_equal "unique-1", @doc_2.url
270
+ end
271
+ end