Skip to content

Commit

Permalink
Merge pull request #21897 from swaathi/master
Browse files Browse the repository at this point in the history
Parameterize with options to preserve the case of string
  • Loading branch information
kaspth committed Nov 7, 2015
2 parents cfd5b00 + c9143e1 commit ccdc84c
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 14 deletions.
9 changes: 9 additions & 0 deletions activesupport/CHANGELOG.md
@@ -1,3 +1,12 @@
* Updated `parameterize` to preserve the case of a string, optionally.

Example:

parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
parameterize("Donald E. Knuth", preserve_case: true) # => "Donald-E-Knuth"

*Swaathi Kakarla*

* `HashWithIndifferentAccess.new` respects the default value or proc on objects
that respond to `#to_hash`. `.new_from_hash_copying_default` simply invokes `.new`.
All calls to `.new_from_hash_copying_default` are replaced with `.new`.
Expand Down
22 changes: 20 additions & 2 deletions activesupport/lib/active_support/core_ext/string/inflections.rb
Expand Up @@ -164,8 +164,26 @@ def deconstantize
#
# <%= link_to(@person.name, person_path) %>
# # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
def parameterize(sep = '-'.freeze)
ActiveSupport::Inflector.parameterize(self, sep)
#
# To preserve the case of the characters in a string, use the `preserve_case` argument.
#
# class Person
# def to_param
# "#{id}-#{name.parameterize(preserve_case: true)}"
# end
# end
#
# @person = Person.find(1)
# # => #<Person id: 1, name: "Donald E. Knuth">
#
# <%= link_to(@person.name, person_path) %>
# # => <a href="/person/1-Donald-E-Knuth">Donald E. Knuth</a>
def parameterize(sep = :unused, separator: '-', preserve_case: false)
unless sep == :unused
ActiveSupport::Deprecation.warn("Passing the separator argument as a positional parameter is deprecated and will soon be removed. Use `separator: '#{sep}'` instead.")
separator = sep
end
ActiveSupport::Inflector.parameterize(self, separator: separator, preserve_case: preserve_case)
end

# Creates the name of a table like Rails does for models to table names. This method
Expand Down
31 changes: 23 additions & 8 deletions activesupport/lib/active_support/inflector/transliterate.rb
Expand Up @@ -68,29 +68,44 @@ def transliterate(string, replacement = "?".freeze)
#
# parameterize("Donald E. Knuth") # => "donald-e-knuth"
# parameterize("^trés|Jolie-- ") # => "tres-jolie"
def parameterize(string, sep = '-')
#
# To use a custom separator, override the `separator` argument.
#
# parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
# parameterize("^trés|Jolie-- ", separator: '_') # => "tres_jolie"
#
# To preserve the case of the characters in a string, use the `preserve_case` argument.
#
# parameterize("Donald E. Knuth", preserve_case: true) # => "Donald-E-Knuth"
# parameterize("^trés|Jolie-- ", preserve_case: true) # => "tres-Jolie"
#
def parameterize(string, sep = :unused, separator: '-', preserve_case: false)
unless sep == :unused
ActiveSupport::Deprecation.warn("Passing the separator argument as a positional parameter is deprecated and will soon be removed. Use `separator: '#{sep}'` instead.")
separator = sep
end
# Replace accented chars with their ASCII equivalents.
parameterized_string = transliterate(string)

# Turn unwanted chars into the separator.
parameterized_string.gsub!(/[^a-z0-9\-_]+/i, sep)
parameterized_string.gsub!(/[^a-z0-9\-_]+/i, separator)

unless sep.nil? || sep.empty?
if sep == "-".freeze
unless separator.nil? || separator.empty?
if separator == "-".freeze
re_duplicate_separator = /-{2,}/
re_leading_trailing_separator = /^-|-$/i
else
re_sep = Regexp.escape(sep)
re_sep = Regexp.escape(separator)
re_duplicate_separator = /#{re_sep}{2,}/
re_leading_trailing_separator = /^#{re_sep}|#{re_sep}$/i
end
# No more than one of the separator in a row.
parameterized_string.gsub!(re_duplicate_separator, sep)
parameterized_string.gsub!(re_duplicate_separator, separator)
# Remove leading/trailing separator.
parameterized_string.gsub!(re_leading_trailing_separator, ''.freeze)
end

parameterized_string.downcase!
parameterized_string.downcase! unless preserve_case
parameterized_string
end
end
Expand Down
38 changes: 36 additions & 2 deletions activesupport/test/core_ext/string_ext_test.rb
Expand Up @@ -143,15 +143,49 @@ def test_string_parameterized_normal
end
end

def test_string_parameterized_normal_preserve_case
StringToParameterizedPreserveCase.each do |normal, slugged|
assert_equal(normal.parameterize(preserve_case: true), slugged)
end
end

def test_string_parameterized_no_separator
StringToParameterizeWithNoSeparator.each do |normal, slugged|
assert_equal(normal.parameterize(''), slugged)
assert_equal(normal.parameterize(separator: ''), slugged)
end
end

def test_string_parameterized_no_separator_deprecated
StringToParameterizeWithNoSeparator.each do |normal, slugged|
assert_deprecated(/Passing the separator argument as a positional parameter is deprecated and will soon be removed. Use `separator: ''` instead./i) do
assert_equal(normal.parameterize(''), slugged)
end
end
end

def test_string_parameterized_no_separator_preserve_case
StringToParameterizePreserveCaseWithNoSeparator.each do |normal, slugged|
assert_equal(normal.parameterize(separator: '', preserve_case: true), slugged)
end
end

def test_string_parameterized_underscore
StringToParameterizeWithUnderscore.each do |normal, slugged|
assert_equal(normal.parameterize('_'), slugged)
assert_equal(normal.parameterize(separator: '_'), slugged)
end
end

def test_string_parameterized_underscore_deprecated
StringToParameterizeWithUnderscore.each do |normal, slugged|
assert_deprecated(/Passing the separator argument as a positional parameter is deprecated and will soon be removed. Use `separator: '_'` instead./i) do
assert_equal(normal.parameterize('_'), slugged)
end
end
end

def test_string_parameterized_underscore_preserve_case
StringToParameterizePreserceCaseWithUnderscore.each do |normal, slugged|
assert_equal(normal.parameterize(separator: '_', preserve_case: true), slugged)
end
end

Expand Down
22 changes: 20 additions & 2 deletions activesupport/test/inflector_test.rb
Expand Up @@ -269,14 +269,32 @@ def test_parameterize_and_normalize
def test_parameterize_with_custom_separator
jruby_skip "UTF-8 to UTF8-MAC Converter is unavailable"
StringToParameterizeWithUnderscore.each do |some_string, parameterized_string|
assert_equal(parameterized_string, ActiveSupport::Inflector.parameterize(some_string, '_'))
assert_equal(parameterized_string, ActiveSupport::Inflector.parameterize(some_string, separator: '_'))
end
end

def test_parameterize_with_custom_separator_deprecated
jruby_skip "UTF-8 to UTF8-MAC Converter is unavailable"
StringToParameterizeWithUnderscore.each do |some_string, parameterized_string|
assert_deprecated(/Passing the separator argument as a positional parameter is deprecated and will soon be removed. Use `separator: '_'` instead./i) do
assert_equal(parameterized_string, ActiveSupport::Inflector.parameterize(some_string, '_'))
end
end
end

def test_parameterize_with_multi_character_separator
jruby_skip "UTF-8 to UTF8-MAC Converter is unavailable"
StringToParameterized.each do |some_string, parameterized_string|
assert_equal(parameterized_string.gsub('-', '__sep__'), ActiveSupport::Inflector.parameterize(some_string, '__sep__'))
assert_equal(parameterized_string.gsub('-', '__sep__'), ActiveSupport::Inflector.parameterize(some_string, separator: '__sep__'))
end
end

def test_parameterize_with_multi_character_separator_deprecated
jruby_skip "UTF-8 to UTF8-MAC Converter is unavailable"
StringToParameterized.each do |some_string, parameterized_string|
assert_deprecated(/Passing the separator argument as a positional parameter is deprecated and will soon be removed. Use `separator: '__sep__'` instead./i) do
assert_equal(parameterized_string.gsub('-', '__sep__'), ActiveSupport::Inflector.parameterize(some_string, '__sep__'))
end
end
end

Expand Down
34 changes: 34 additions & 0 deletions activesupport/test/inflector_test_cases.rb
Expand Up @@ -174,6 +174,17 @@ module InflectorTestCases
"Test with malformed utf8 \251" => "test-with-malformed-utf8"
}

StringToParameterizedPreserveCase = {
"Donald E. Knuth" => "Donald-E-Knuth",
"Random text with *(bad)* characters" => "Random-text-with-bad-characters",
"Allow_Under_Scores" => "Allow_Under_Scores",
"Trailing bad characters!@#" => "Trailing-bad-characters",
"!@#Leading bad characters" => "Leading-bad-characters",
"Squeeze separators" => "Squeeze-separators",
"Test with + sign" => "Test-with-sign",
"Test with malformed utf8 \xA9" => "Test-with-malformed-utf8"
}

StringToParameterizeWithNoSeparator = {
"Donald E. Knuth" => "donaldeknuth",
"With-some-dashes" => "with-some-dashes",
Expand All @@ -185,6 +196,17 @@ module InflectorTestCases
"Test with malformed utf8 \251" => "testwithmalformedutf8"
}

StringToParameterizePreserveCaseWithNoSeparator = {
"Donald E. Knuth" => "DonaldEKnuth",
"With-some-dashes" => "With-some-dashes",
"Random text with *(bad)* characters" => "Randomtextwithbadcharacters",
"Trailing bad characters!@#" => "Trailingbadcharacters",
"!@#Leading bad characters" => "Leadingbadcharacters",
"Squeeze separators" => "Squeezeseparators",
"Test with + sign" => "Testwithsign",
"Test with malformed utf8 \xA9" => "Testwithmalformedutf8"
}

StringToParameterizeWithUnderscore = {
"Donald E. Knuth" => "donald_e_knuth",
"Random text with *(bad)* characters" => "random_text_with_bad_characters",
Expand All @@ -197,6 +219,18 @@ module InflectorTestCases
"Test with malformed utf8 \251" => "test_with_malformed_utf8"
}

StringToParameterizePreserceCaseWithUnderscore = {
"Donald E. Knuth" => "Donald_E_Knuth",
"Random text with *(bad)* characters" => "Random_text_with_bad_characters",
"With-some-dashes" => "With-some-dashes",
"Allow_Under_Scores" => "Allow_Under_Scores",
"Trailing bad characters!@#" => "Trailing_bad_characters",
"!@#Leading bad characters" => "Leading_bad_characters",
"Squeeze separators" => "Squeeze_separators",
"Test with + sign" => "Test_with_sign",
"Test with malformed utf8 \xA9" => "Test_with_malformed_utf8"
}

StringToParameterizedAndNormalized = {
"Malmö" => "malmo",
"Garçons" => "garcons",
Expand Down
14 changes: 14 additions & 0 deletions guides/source/active_support_core_extensions.md
Expand Up @@ -1710,6 +1710,20 @@ The method `parameterize` normalizes its receiver in a way that can be used in p
"Kurt Gödel".parameterize # => "kurt-godel"
```

To preserve the case of the string, set the `preserve_case` argument to true. By default, `preserve_case` is set to false.

```ruby
"John Smith".parameterize(preserve_case: true) # => "John-Smith"
"Kurt Gödel".parameterize(preserve_case: true) # => "Kurt-Godel"
```

To use a custom separator, override the `separator` argument.

```ruby
"John Smith".parameterize(separator: "_") # => "john\_smith"
"Kurt Gödel".parameterize(separator: "_") # => "kurt\_godel"
```

In fact, the result string is wrapped in an instance of `ActiveSupport::Multibyte::Chars`.

NOTE: Defined in `active_support/core_ext/string/inflections.rb`.
Expand Down

0 comments on commit ccdc84c

Please sign in to comment.