From 33ea99d216ebc1373da20d0e8c79d1f2ecc3f28d Mon Sep 17 00:00:00 2001 From: Sean Collins Date: Mon, 5 Aug 2024 13:34:58 -0600 Subject: [PATCH 1/5] Handle diacritics for humanize --- lib/dry/inflector.rb | 2 +- spec/unit/dry/inflector/humanize_spec.rb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/dry/inflector.rb b/lib/dry/inflector.rb index 73398f4..66accd8 100644 --- a/lib/dry/inflector.rb +++ b/lib/dry/inflector.rb @@ -155,7 +155,7 @@ def humanize(input) result = inflections.humans.apply_to(input) result.delete_suffix!("_id") result.tr!("_", " ") - match = /(\W)/.match(result) + match = /([^[:alnum:]])/.match(result) separator = match ? match[0] : DEFAULT_SEPARATOR result.split(separator).map.with_index { |word, index| inflections.acronyms.apply_to(word, capitalize: index.zero?) diff --git a/spec/unit/dry/inflector/humanize_spec.rb b/spec/unit/dry/inflector/humanize_spec.rb index d31354d..88b8e14 100644 --- a/spec/unit/dry/inflector/humanize_spec.rb +++ b/spec/unit/dry/inflector/humanize_spec.rb @@ -29,5 +29,9 @@ expect(subject.humanize(i("openssl/hmac"))).to eql("OpenSSL/HMAC") expect(subject.humanize(i("openssl/digest"))).to eql("OpenSSL/digest") end + + it "handles diacritics" do + expect(subject.humanize(i("éclair"))).to eql("Éclair") + end end end From 9688c5f4299f7c62353c063e9903723b4bb25443 Mon Sep 17 00:00:00 2001 From: Sean Collins Date: Mon, 5 Aug 2024 13:47:23 -0600 Subject: [PATCH 2/5] Support diacritics for (first word of) camelize --- lib/dry/inflector.rb | 2 +- spec/unit/dry/inflector/camelize_upper_spec.rb | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/dry/inflector.rb b/lib/dry/inflector.rb index 66accd8..886e2da 100644 --- a/lib/dry/inflector.rb +++ b/lib/dry/inflector.rb @@ -328,7 +328,7 @@ def to_s # @api private def internal_camelize(input, upper) input = input.to_s.dup - input.sub!(/^[a-z\d]*/) { |match| inflections.acronyms.apply_to(match, capitalize: upper) } + input.sub!(/^[[:lower:][:digit:]]*/) { |match| inflections.acronyms.apply_to(match, capitalize: upper) } input.gsub!(%r{(?:[_-]|(/))([a-z\d]*)}i) do m1 = Regexp.last_match(1) m2 = Regexp.last_match(2) diff --git a/spec/unit/dry/inflector/camelize_upper_spec.rb b/spec/unit/dry/inflector/camelize_upper_spec.rb index ab6535d..08ae642 100644 --- a/spec/unit/dry/inflector/camelize_upper_spec.rb +++ b/spec/unit/dry/inflector/camelize_upper_spec.rb @@ -30,7 +30,7 @@ context "custom acronyms" do subject do Dry::Inflector.new do |inflect| - inflect.acronym("IP", "HTML", "XML", "BSD") + inflect.acronym("IP", "HTML", "XML", "BSD", "ÉUA", "4K") end end @@ -41,6 +41,12 @@ expect(subject.camelize_upper(i("html_tidy_generator"))).to eql("HTMLTidyGenerator") expect(subject.camelize_upper(i("force_xml_controller"))).to eql("ForceXMLController") expect(subject.camelize_upper(i("free_bsd"))).to eql("FreeBSD") + expect(subject.camelize_upper(i("4k-television"))).to eql("4KTelevision") + end + + it "handles diacritics" do + expect(subject.camelize_upper(i("éclair_fest"))).to eql("ÉclairFest") + expect(subject.camelize_upper(i("éua-trip"))).to eql("ÉUATrip") end end end From c357c577d9425c72891770e3996a55ba77bb19ee Mon Sep 17 00:00:00 2001 From: Sean Collins Date: Mon, 5 Aug 2024 13:52:12 -0600 Subject: [PATCH 3/5] Support diacritics for later words when using camelize --- lib/dry/inflector.rb | 2 +- spec/unit/dry/inflector/camelize_lower_spec.rb | 10 +++++++++- spec/unit/dry/inflector/camelize_upper_spec.rb | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/dry/inflector.rb b/lib/dry/inflector.rb index 886e2da..d6d32dc 100644 --- a/lib/dry/inflector.rb +++ b/lib/dry/inflector.rb @@ -329,7 +329,7 @@ def to_s def internal_camelize(input, upper) input = input.to_s.dup input.sub!(/^[[:lower:][:digit:]]*/) { |match| inflections.acronyms.apply_to(match, capitalize: upper) } - input.gsub!(%r{(?:[_-]|(/))([a-z\d]*)}i) do + input.gsub!(%r{(?:[_-]|(/))([[:lower:][:digit:]]*)}i) do m1 = Regexp.last_match(1) m2 = Regexp.last_match(2) "#{m1}#{inflections.acronyms.apply_to(m2)}" diff --git a/spec/unit/dry/inflector/camelize_lower_spec.rb b/spec/unit/dry/inflector/camelize_lower_spec.rb index 0a62108..8a5b99a 100644 --- a/spec/unit/dry/inflector/camelize_lower_spec.rb +++ b/spec/unit/dry/inflector/camelize_lower_spec.rb @@ -26,7 +26,7 @@ context "custom acronyms" do subject do Dry::Inflector.new do |inflect| - inflect.acronym("IP", "HTML", "XML", "BSD") + inflect.acronym("IP", "HTML", "XML", "BSD", "ÉUA", "4K") end end @@ -38,6 +38,14 @@ expect(subject.camelize_lower(i("force_xml_controller"))).to eql("forceXMLController") expect(subject.camelize_lower(i("free_bsd"))).to eql("freeBSD") end + + + it "handles diacritics" do + expect(subject.camelize_lower(i("éclair_fest"))).to eql("éclairFest") + expect(subject.camelize_lower(i("éua-trip"))).to eql("ÉUATrip") + expect(subject.camelize_lower(i("festival_des_éclairs"))).to eql("festivalDesÉclairs") + expect(subject.camelize_lower(i("festival_des_4k"))).to eql("festivalDes4K") + end end end end diff --git a/spec/unit/dry/inflector/camelize_upper_spec.rb b/spec/unit/dry/inflector/camelize_upper_spec.rb index 08ae642..319748c 100644 --- a/spec/unit/dry/inflector/camelize_upper_spec.rb +++ b/spec/unit/dry/inflector/camelize_upper_spec.rb @@ -47,6 +47,8 @@ it "handles diacritics" do expect(subject.camelize_upper(i("éclair_fest"))).to eql("ÉclairFest") expect(subject.camelize_upper(i("éua-trip"))).to eql("ÉUATrip") + expect(subject.camelize_upper(i("festival_des_éclairs"))).to eql("FestivalDesÉclairs") + expect(subject.camelize_upper(i("festival_des_4k"))).to eql("FestivalDes4K") end end end From 3efbaa71708d0e7db7aab949cf9ea75bf6c9edc9 Mon Sep 17 00:00:00 2001 From: Sean Collins Date: Mon, 9 Sep 2024 16:50:48 -0700 Subject: [PATCH 4/5] Support diacrities for underscore --- lib/dry/inflector.rb | 4 +-- spec/unit/dry/inflector/underscore_spec.rb | 40 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/dry/inflector.rb b/lib/dry/inflector.rb index d6d32dc..d1a3de1 100644 --- a/lib/dry/inflector.rb +++ b/lib/dry/inflector.rb @@ -283,8 +283,8 @@ def underscore(input) m2 = Regexp.last_match(2) "#{m1 ? "_" : ""}#{m2.downcase}" end - input.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2') - input.gsub!(/([a-z\d])([A-Z])/, '\1_\2') + input.gsub!(/([[:upper:][:digit:]]+)([[:upper:]][[:lower:]])/, '\1_\2') + input.gsub!(/([[:lower:][:digit:]])([[:upper:]])/, '\1_\2') input.tr!("-", "_") input.downcase! input diff --git a/spec/unit/dry/inflector/underscore_spec.rb b/spec/unit/dry/inflector/underscore_spec.rb index 61a3b38..b78b08d 100644 --- a/spec/unit/dry/inflector/underscore_spec.rb +++ b/spec/unit/dry/inflector/underscore_spec.rb @@ -34,6 +34,10 @@ expect(subject.underscore(i("CLIRunner"))).to eq("cli_runner") end + it "underscores aCli as a_cli" do + expect(subject.underscore(i("aCLI"))).to eq("a_cli") + end + it "accepts symbols" do expect(subject.underscore(:DataMapper)).to eq("data_mapper") end @@ -44,5 +48,41 @@ expect(subject.underscore(i("OpenSSL::HMAC"))).to eql("openssl/hmac") expect(subject.underscore(i("OpenSSL::Digest"))).to eql("openssl/digest") end + + it "handles diacritics" do + expect(subject.underscore(i("éclairFest"))).to eql("éclair_fest") + expect(subject.underscore(i("éuaTrip"))).to eql("éua_trip") + expect(subject.underscore(i("festival-des-éclairs"))).to eql("festival_des_éclairs") + expect(subject.underscore(i("ÉBellisimo"))).to eql("é_bellisimo") + expect(subject.underscore(i("éBellisimo"))).to eql("é_bellisimo") + end + + it "handles number followed by uppercase letter" do + expect(subject.underscore(i("9Lives"))).to eql("9_lives") + end + + pending "handles number followed by lowercase letter" do + pending "this should be `7_ate_9`" + expect(subject.underscore(i("7Ate9"))).to eql("7_ate_9") + end + + it "handles number followed by lowercase letter" do + pending "this should be 9_lives" + expect(subject.underscore(i("9lives"))).to eql("9_lives") + end + + it "handle leading diacritic" do + expect(subject.underscore(i("éBellisimo"))).to eql("é_bellisimo") + end + + it "handles leading number " do + pending "this should be 1_is_one" + expect(subject.underscore(i("1isOne"))).to eql("1_is_one") + end + + it "handles leading number with diacritic" do + pending "this should be 1_é_bellisimo" + expect(subject.underscore(i("1éBellisimo"))).to eql("1_é_bellisimo") + end end end From f78dc3cc6e584ba2084d7f22033281b2ce6f5d7c Mon Sep 17 00:00:00 2001 From: Sean Collins Date: Mon, 9 Sep 2024 16:56:04 -0700 Subject: [PATCH 5/5] Rubocop --- lib/dry/inflector.rb | 4 +++- spec/unit/dry/inflector/camelize_lower_spec.rb | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/dry/inflector.rb b/lib/dry/inflector.rb index d1a3de1..3608fab 100644 --- a/lib/dry/inflector.rb +++ b/lib/dry/inflector.rb @@ -328,7 +328,9 @@ def to_s # @api private def internal_camelize(input, upper) input = input.to_s.dup - input.sub!(/^[[:lower:][:digit:]]*/) { |match| inflections.acronyms.apply_to(match, capitalize: upper) } + input.sub!(/^[[:lower:][:digit:]]*/) do |match| + inflections.acronyms.apply_to(match, capitalize: upper) + end input.gsub!(%r{(?:[_-]|(/))([[:lower:][:digit:]]*)}i) do m1 = Regexp.last_match(1) m2 = Regexp.last_match(2) diff --git a/spec/unit/dry/inflector/camelize_lower_spec.rb b/spec/unit/dry/inflector/camelize_lower_spec.rb index 8a5b99a..43f782d 100644 --- a/spec/unit/dry/inflector/camelize_lower_spec.rb +++ b/spec/unit/dry/inflector/camelize_lower_spec.rb @@ -39,7 +39,6 @@ expect(subject.camelize_lower(i("free_bsd"))).to eql("freeBSD") end - it "handles diacritics" do expect(subject.camelize_lower(i("éclair_fest"))).to eql("éclairFest") expect(subject.camelize_lower(i("éua-trip"))).to eql("ÉUATrip")