From 75cd953c30124b1a3d5e08da0c224395e3dfd386 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Fri, 20 Dec 2024 09:38:48 +0000 Subject: [PATCH] feat: correct implementation for pascal_case and camel_case --- helix-core/src/case_conversion.rs | 144 +++++++++++++++++++++++------- 1 file changed, 111 insertions(+), 33 deletions(-) diff --git a/helix-core/src/case_conversion.rs b/helix-core/src/case_conversion.rs index 35287d5be..f4f1a166b 100644 --- a/helix-core/src/case_conversion.rs +++ b/helix-core/src/case_conversion.rs @@ -71,23 +71,6 @@ pub fn to_alternate_case_with(text: impl Iterator, buf: &mut Tendri } } -pub fn to_pascal_case_with(text: impl Iterator, buf: &mut Tendril) { - let mut at_word_start = true; - for c in text { - // we don't count _ as a word char here so case conversions work well - if !c.is_alphanumeric() { - at_word_start = true; - continue; - } - if at_word_start { - at_word_start = false; - buf.extend(c.to_uppercase()); - } else { - buf.push(c) - } - } -} - pub fn to_title_case_with(text: impl Iterator, buf: &mut Tendril) { let mut capitalize_next = true; let mut prev_is_lowercase = false; @@ -150,24 +133,119 @@ pub fn to_snake_case_with(text: impl Iterator, buf: &mut Tendril) { to_case_with_separator(text, buf, '_'); } -pub fn to_camel_case_with(mut text: impl Iterator, buf: &mut Tendril) { - for c in &mut text { - if c.is_alphanumeric() { - buf.extend(c.to_lowercase()) - } - } - let mut at_word_start = false; +pub fn to_camel_case_with(text: impl Iterator, buf: &mut Tendril) { + to_camel_or_pascal_case_with(text, buf, false); +} + +pub fn to_pascal_case_with(text: impl Iterator, buf: &mut Tendril) { + to_camel_or_pascal_case_with(text, buf, true); +} + +pub fn to_camel_or_pascal_case_with( + text: impl Iterator, + buf: &mut Tendril, + is_pascal: bool, +) { + let mut capitalize_next = is_pascal; + for c in text { - // we don't count _ as a word char here so case conversions work well - if !c.is_alphanumeric() { - at_word_start = true; - continue; - } - if at_word_start { - at_word_start = false; - buf.extend(c.to_uppercase()); + if c.is_alphanumeric() { + if capitalize_next { + buf.extend(c.to_uppercase()); + capitalize_next = false; + } else { + buf.extend(c.to_lowercase()); + } } else { - buf.push(c) + capitalize_next = true; } } } + +#[cfg(test)] +mod tests { + use super::*; + + fn case_tester<'a, F>(change_fn: F) -> impl Fn(&'a str, &'a str) + 'a + where + F: Fn(std::str::Chars<'a>) -> Tendril + 'a, + { + move |input: &str, expected: &str| { + let transformed = change_fn(input.chars()); + let m = transformed.to_string(); + dbg!(input); + assert_eq!(m.as_str(), expected) + } + } + + #[test] + fn test_camel_case_conversion() { + let camel_test = case_tester(to_camel_case); + camel_test("hello world", "helloWorld"); + camel_test("Hello World", "helloWorld"); + camel_test("hello_world", "helloWorld"); + camel_test("HELLO_WORLD", "helloWorld"); + } + + #[test] + fn test_lower_case_conversion() { + let lower_test = case_tester(to_lower_case); + lower_test("HelloWorld", "helloworld"); + lower_test("HELLO WORLD", "hello world"); + lower_test("hello_world", "hello_world"); + lower_test("Hello-World", "hello-world"); + } + + #[test] + fn test_upper_case_conversion() { + let upper_test = case_tester(to_upper_case); + upper_test("helloWorld", "HELLOWORLD"); + upper_test("hello world", "HELLO WORLD"); + upper_test("hello_world", "HELLO_WORLD"); + upper_test("Hello-World", "HELLO-WORLD"); + } + + #[test] + fn test_pascal_case_conversion() { + let pascal_test = case_tester(to_pascal_case); + pascal_test("hello world", "HelloWorld"); + pascal_test("Hello World", "HelloWorld"); + pascal_test("hello_world", "HelloWorld"); + pascal_test("HELLO_WORLD", "HelloWorld"); + } + + #[test] + fn test_alternate_case_conversion() { + let alternate_test = case_tester(to_alternate_case); + alternate_test("hello world", "HELLO WORLD"); + alternate_test("Hello World", "hELLO wORLD"); + alternate_test("helLo_woRlD", "HELlO_WOrLd"); + } + + #[test] + fn test_title_case_conversion() { + let title_test = case_tester(to_title_case); + title_test("hello world", "Hello World"); + title_test("Hello World", "Hello World"); + title_test("hello_world", "Hello World"); + title_test("HELLO_WORLD", "Hello World"); + } + + #[test] + fn test_kebab_case_conversion() { + let kebab_test = case_tester(to_kebab_case); + kebab_test("helloWorld", "hello-world"); + kebab_test("HelloWorld", "hello-world"); + kebab_test("hello_world", "hello-world"); + kebab_test("HELLO_WORLD", "hello-world"); + } + + #[test] + fn test_snake_case_conversion() { + let snake_test = case_tester(to_snake_case); + snake_test("helloWorld", "hello_world"); + snake_test("HelloWorld", "hello_world"); + snake_test("hello world", "hello_world"); + snake_test("HELLO WORLD", "hello_world"); + } +}