From 0d37928605c02c6ddb3130810e45a2dbaae3143f Mon Sep 17 00:00:00 2001 From: "Bruni, Ottorino" Date: Fri, 24 May 2024 09:03:20 +0200 Subject: [PATCH 1/4] Add Base64 Decode Encode Converter --- .../Base64DecodeCaseConverterTest.cs | 48 +++++++++++++++++++ .../Base64EncodeCaseConverterTest.cs | 48 +++++++++++++++++++ .../Converters/Base64DecodeCaseConverter.cs | 34 +++++++++++++ .../Converters/Base64EncodeCaseConverter.cs | 23 +++++++++ TextCase/Extensions/StringExtensions.cs | 20 ++++++++ TextCase/TextCase.cs | 4 +- TextCase/TextCaseFactory.cs | 2 + 7 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 TextCase.UnitTests/Base64DecodeCaseConverterTest.cs create mode 100644 TextCase.UnitTests/Base64EncodeCaseConverterTest.cs create mode 100644 TextCase/Converters/Base64DecodeCaseConverter.cs create mode 100644 TextCase/Converters/Base64EncodeCaseConverter.cs diff --git a/TextCase.UnitTests/Base64DecodeCaseConverterTest.cs b/TextCase.UnitTests/Base64DecodeCaseConverterTest.cs new file mode 100644 index 0000000..c86d24a --- /dev/null +++ b/TextCase.UnitTests/Base64DecodeCaseConverterTest.cs @@ -0,0 +1,48 @@ +using System; +using System.Buffers.Text; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TextCase.Converters; +using TextCase.Extensions; +using Xunit; + +namespace TextCase.UnitTests +{ + public class Base64DecodeCaseConverterTest + { + [Theory] + [InlineData("SGVsbG8gV29ybGQ=", "Hello World")] + [InlineData("SEVMTE8gV09STEQ=", "HELLO WORLD")] + [InlineData("SUNIIEJJTiBHTMOcQ0tMSUNI", "ICH BIN GLÜCKLICH")] + [InlineData("ICBDaGUgT3JlIFNvbm8/IA==", " Che Ore Sono? ")] + public void ToBase64DecodeCase_WhenValidInput_ShouldReturnDecodedString(string input, string expected) + { + // Setup + var service = new Base64DecodeCaseConverter(); + + // Execute + var actual = service.Convert(input); + + // Assert + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData("SGVsbG8gV29ybGQ=", "Hello World")] + [InlineData("SEVMTE8gV09STEQ=", "HELLO WORLD")] + [InlineData("SUNIIEJJTiBHTMOcQ0tMSUNI", "ICH BIN GLÜCKLICH")] + [InlineData("ICBDaGUgT3JlIFNvbm8/IA==", " Che Ore Sono? ")] + public void ToBase64DecodeCase_WhenBase64DecodeCase_TextShouldBeBase64DecodeCase(string input, string output) + { + // Execute + var convertedText = input.ToBase64DecodeCase(); + + // Assert + var expected = output; + var actual = convertedText; + Assert.Equal(expected, actual); + } + } +} diff --git a/TextCase.UnitTests/Base64EncodeCaseConverterTest.cs b/TextCase.UnitTests/Base64EncodeCaseConverterTest.cs new file mode 100644 index 0000000..2af9e00 --- /dev/null +++ b/TextCase.UnitTests/Base64EncodeCaseConverterTest.cs @@ -0,0 +1,48 @@ +using System; +using System.Buffers.Text; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TextCase.Converters; +using TextCase.Extensions; +using Xunit; + +namespace TextCase.UnitTests +{ + public class Base64EncodeCaseConverterTest + { + [Theory] + [InlineData("Hello World", "SGVsbG8gV29ybGQ=")] + [InlineData("HELLO WORLD", "SEVMTE8gV09STEQ=")] + [InlineData("ICH BIN GLÜCKLICH", "SUNIIEJJTiBHTMOcQ0tMSUNI")] + [InlineData(" Che Ore Sono? ", "ICBDaGUgT3JlIFNvbm8/IA==")] + public void ToBase64EncodeCase_WhenValidInput_ShouldReturnBase64EncodedString(string input, string expected) + { + // Setup + var service = new Base64EncodeCaseConverter(); + + // Execute + var actual = service.Convert(input); + + // Assert + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData("Hello World", "SGVsbG8gV29ybGQ=")] + [InlineData("HELLO WORLD", "SEVMTE8gV09STEQ=")] + [InlineData("ICH BIN GLÜCKLICH", "SUNIIEJJTiBHTMOcQ0tMSUNI")] + [InlineData(" Che Ore Sono? ", "ICBDaGUgT3JlIFNvbm8/IA==")] + public void ToBase64EncodeCase_WhenBase64EncodeCase_TextShouldBeBase64EncodeCase(string input, string output) + { + // Execute + var convertedText = input.ToBase64EncodeCase(); + + // Assert + var expected = output; + var actual = convertedText; + Assert.Equal(expected, actual); + } + } +} diff --git a/TextCase/Converters/Base64DecodeCaseConverter.cs b/TextCase/Converters/Base64DecodeCaseConverter.cs new file mode 100644 index 0000000..c9a3c52 --- /dev/null +++ b/TextCase/Converters/Base64DecodeCaseConverter.cs @@ -0,0 +1,34 @@ +using System; +using System.Text; + +namespace TextCase.Converters +{ + /// + /// Represents a base64 decode converter. + /// + public class Base64DecodeCaseConverter : ICaseConverter + { + /// + /// Converts the specified text to base64 decode. + /// + /// The string to convert to base64 decode. + /// The specified text converted to base64 decode. + public string Convert(string text) + { + if (string.IsNullOrEmpty(text)) + { + return string.Empty; + } + + try + { + return Encoding.UTF8.GetString(System.Convert.FromBase64String(text)); + } + catch (FormatException) + { + return text; + } + } + } + +} diff --git a/TextCase/Converters/Base64EncodeCaseConverter.cs b/TextCase/Converters/Base64EncodeCaseConverter.cs new file mode 100644 index 0000000..1679ed5 --- /dev/null +++ b/TextCase/Converters/Base64EncodeCaseConverter.cs @@ -0,0 +1,23 @@ +using System.Text; + +namespace TextCase.Converters +{ + /// + /// Represents a base64 encode converter. + /// + public class Base64EncodeCaseConverter : ICaseConverter + { + /// + /// Converts the specified text to base64 encode. + /// + /// The string to convert to base64 encode. + /// The specified text converted to base64 encode. + public string Convert(string text) + { + return string.IsNullOrWhiteSpace(text) ? + string.Empty : + System.Convert.ToBase64String(Encoding.UTF8.GetBytes(text)); + } + } + +} diff --git a/TextCase/Extensions/StringExtensions.cs b/TextCase/Extensions/StringExtensions.cs index 20331f7..5250dd5 100644 --- a/TextCase/Extensions/StringExtensions.cs +++ b/TextCase/Extensions/StringExtensions.cs @@ -231,5 +231,25 @@ public static string ToTrainCase(this string value) { return TextCase.Convert(value, Case.TrainCase); } + + /// + /// Converts the specified text to base64 decode case. + /// + /// The string to convert to base64 decode case. + /// The specified text converted to base64 decode case. + public static string ToBase64DecodeCase(this string value) + { + return TextCase.Convert(value, Case.Base64DecodeCase); + } + + /// + /// Converts the specified text to base64 encode case. + /// + /// The string to convert to base64 encode case. + /// The specified text converted to base64 encode case. + public static string ToBase64EncodeCase(this string value) + { + return TextCase.Convert(value, Case.Base64EncodeCase); + } } } diff --git a/TextCase/TextCase.cs b/TextCase/TextCase.cs index b1ca174..5132843 100644 --- a/TextCase/TextCase.cs +++ b/TextCase/TextCase.cs @@ -21,7 +21,9 @@ public enum Case ConstantCase, CobolCase, TrainCase, - InverseCase + InverseCase, + Base64EncodeCase, + Base64DecodeCase } public static class TextCase diff --git a/TextCase/TextCaseFactory.cs b/TextCase/TextCaseFactory.cs index d68bbf2..efafa16 100644 --- a/TextCase/TextCaseFactory.cs +++ b/TextCase/TextCaseFactory.cs @@ -25,6 +25,8 @@ internal static ICaseConverter GetCaseConverter(Case textCase) Case.CobolCase => new CobolCaseConverter(), Case.TrainCase => new TrainCaseConverter(), Case.InverseCase => new InverseCaseConverter(), + Case.Base64DecodeCase => new Base64DecodeCaseConverter(), + Case.Base64EncodeCase => new Base64EncodeCaseConverter(), _ => throw new ArgumentException("No valid TextCase"), }; } From f7a2ea4202f0f1fb3655822f5f7ec2ff0c46291b Mon Sep 17 00:00:00 2001 From: Ottorino Bruni Date: Fri, 24 May 2024 09:08:52 +0200 Subject: [PATCH 2/4] Update README.md --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dc56033..17b7861 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ TextCase is a powerful .NET library designed to simplify text manipulation by providing a variety of case conversion methods. Key Features -- Wide Range of Conversions: Transform text into 17 different cases including UpperCase, LowerCase, TitleCase, CamelCase, PascalCase, and more. +- Wide Range of Conversions: Transform text into 19 different cases including UpperCase, LowerCase, TitleCase, CamelCase, PascalCase, Base64 encoding/decoding, and more. - Text Analysis: Easily count characters, words, letters, and sentences within your text. - Easy Integration: Simple and intuitive API that integrates seamlessly with your .NET applications. @@ -27,6 +27,8 @@ Available Conversions - CapitaliseWordsCase: Capitalizes the first letter of each word. - ReverseCase: Reverses the text. - AlternateCase: Alternates case starting with uppercase. +- Base64EncodeCase: Encodes text to Base64. +- Base64DecodeCase: Decodes Base64 text. It's possible to count in the text: - number of characters @@ -101,6 +103,14 @@ TextCase.Convert("You talking to me?", Case.InverseCase); TextCase.Convert("You talking to me?", Case.TrainCase); "You talking to me?".ToTrainCase(); +// Encode text to Base64 +TextCase.Convert("You talking to me?", Case.Base64EncodeCase); +"You talking to me?".ToBase64EncodeCase(); + +// Decode Base64 text +TextCase.Convert("WW91IHRhbGtpbmcgdG8gbWU/", Case.Base64DecodeCase); +"WW91IHRhbGtpbmcgdG8gbWU?".ToBase64DecodeCase(); + // Text Count TextCase.GetTextCount("You talking to me?"); "You talking to me?".GetTextCount(); @@ -116,6 +126,7 @@ TextCase.GetLettersCount("You talking to me?"); // Sentences Count TextCase.GetSentencesCount("You talking to me?"); "You talking to me?".GetSentencesCount(); + ``` ## Get it on NuGet: From 26fc7736b8e6d9c4ac86081af5637028b6a92828 Mon Sep 17 00:00:00 2001 From: "Bruni, Ottorino" Date: Fri, 24 May 2024 10:06:02 +0200 Subject: [PATCH 3/4] Add ParagraphsCount --- TextCase.UnitTests/StringExtensionsTest.cs | 27 +++++++++++++-- TextCase/Extensions/StringExtensions.cs | 38 +++++++++++++++++----- TextCase/TextCase.cs | 5 +++ 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/TextCase.UnitTests/StringExtensionsTest.cs b/TextCase.UnitTests/StringExtensionsTest.cs index 5b86019..dca0eff 100644 --- a/TextCase.UnitTests/StringExtensionsTest.cs +++ b/TextCase.UnitTests/StringExtensionsTest.cs @@ -55,8 +55,13 @@ public void GetLettersCount_WhenInput_LettersShouldBeCount(string input, int cou [Theory] [InlineData("", 0)] - [InlineData("hello world. icH bIn glückLICH", 2)] - [InlineData(" che ore sono? ", 1)] + [InlineData(null, 0)] + [InlineData("This is a single sentence.", 1)] + [InlineData("This is the first sentence. This is the second one! Is this the third? Yes, it is.", 4)] + [InlineData("First sentence.\nSecond sentence!\nThird sentence?", 3)] + [InlineData("First sentence. Second sentence! Third sentence? ", 3)] + [InlineData("First sentence.Second sentence!Third sentence?", 3)] + [InlineData("This is a sentence with a Mr Smith. And here's another one! Finally, this is the last one?", 3)] public void GetSentencesCount_WhenInput_SentencesShouldBeCount(string input, int count) { // Execute @@ -67,5 +72,23 @@ public void GetSentencesCount_WhenInput_SentencesShouldBeCount(string input, int var actual = result; Assert.Equal(expected, actual); } + + [Theory] + [InlineData("", 0)] + [InlineData(null, 0)] + [InlineData("This is a single paragraph.", 1)] + [InlineData("This is the first paragraph.\n\nThis is the second paragraph.\n\nThis is the third paragraph.", 3)] + [InlineData("First paragraph.\r\n\r\nSecond paragraph.\r\n\r\nThird paragraph.", 3)] + [InlineData("First paragraph. \n\n Second paragraph! \n\n Third paragraph? ", 3)] + [InlineData("First paragraph.\nSecond paragraph! \n\nThird paragraph?", 2)] + [InlineData("First paragraph.\n\n\nSecond paragraph!\n\n\n\nThird paragraph?", 3)] + public void GetParagraphsCount_VariousInputs_ReturnsExpectedResult(string input, int expected) + { + // Act + int result = TextCase.GetParagraphsCount(input); + + // Assert + Assert.Equal(expected, result); + } } } diff --git a/TextCase/Extensions/StringExtensions.cs b/TextCase/Extensions/StringExtensions.cs index 5250dd5..4ab5edb 100644 --- a/TextCase/Extensions/StringExtensions.cs +++ b/TextCase/Extensions/StringExtensions.cs @@ -33,7 +33,12 @@ public static int GetTextCount(this string value) /// The number of words in the current string. public static int GetWordsCount(this string value) { - return string.IsNullOrEmpty(value) ? 0 : value.Split(new[] { ' ', '\t', '\n', '\r', '.', ',', ';', '!', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; + if (string.IsNullOrWhiteSpace(value)) + { + return 0; + } + var words = Regex.Matches(value, @"\b\w+\b"); + return words.Count; } /// @@ -63,15 +68,32 @@ public static int GetSentencesCount(this string value) return 0; } - // Split sentences based on common sentence-ending punctuation marks. - var sentenceSeparators = new char[] { '.', '!', '?' }; - var sentences = value.Split(sentenceSeparators, StringSplitOptions.RemoveEmptyEntries) - .Where(sentence => !string.IsNullOrWhiteSpace(sentence)) - .ToArray(); + var sentenceSeparators = new string[] { ".", "!", "?" }; + var sentenceExtraSeparators = new string[] { ". " }; + var demo = value.Split(sentenceSeparators, StringSplitOptions.RemoveEmptyEntries); + var demo2 = value.Split(sentenceExtraSeparators, StringSplitOptions.RemoveEmptyEntries); + + var result = demo.Count(sentence => !string.IsNullOrWhiteSpace(sentence)); - return sentences.Length; + return value.Split(sentenceSeparators, StringSplitOptions.RemoveEmptyEntries) + .Count(sentence => !string.IsNullOrWhiteSpace(sentence)); } - + + /// + /// Gets the number of paragraphs in the current String value. + /// + /// The string to count. + /// The number of paragraphs in the current string. + public static int GetParagraphsCount(this string value) + { + if (string.IsNullOrWhiteSpace(value)) + { + return 0; + } + return value.Split(new string[] { "\r\n\r\n", "\n\n" }, StringSplitOptions.RemoveEmptyEntries) + .Count(paragraph => !string.IsNullOrWhiteSpace(paragraph)); + } + /// /// Converts the specified string to uppercase using the casing rules of the invariant culture. /// diff --git a/TextCase/TextCase.cs b/TextCase/TextCase.cs index 5132843..09605d6 100644 --- a/TextCase/TextCase.cs +++ b/TextCase/TextCase.cs @@ -52,5 +52,10 @@ public static int GetSentencesCount(string text) { return text.GetSentencesCount(); } + + public static int GetParagraphsCount(string text) + { + return text.GetParagraphsCount(); + } } } From 462321873b5b772d9f4bcc4f1cca0c900fb8165c Mon Sep 17 00:00:00 2001 From: Ottorino Bruni Date: Fri, 24 May 2024 10:12:10 +0200 Subject: [PATCH 4/4] Update README.md --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 17b7861..d766c51 100644 --- a/README.md +++ b/README.md @@ -30,13 +30,14 @@ Available Conversions - Base64EncodeCase: Encodes text to Base64. - Base64DecodeCase: Decodes Base64 text. -It's possible to count in the text: +Text Analysis Examples: - number of characters - number of words - number of letters - number of sentences +- number of paragraphs -## Usage: +## Usage Examples: ```cscharp // YOU TALKING TO ME? @@ -110,7 +111,10 @@ TextCase.Convert("You talking to me?", Case.Base64EncodeCase); // Decode Base64 text TextCase.Convert("WW91IHRhbGtpbmcgdG8gbWU/", Case.Base64DecodeCase); "WW91IHRhbGtpbmcgdG8gbWU?".ToBase64DecodeCase(); +``` +Text Analysis Functions +```cscharp // Text Count TextCase.GetTextCount("You talking to me?"); "You talking to me?".GetTextCount(); @@ -127,6 +131,10 @@ TextCase.GetLettersCount("You talking to me?"); TextCase.GetSentencesCount("You talking to me?"); "You talking to me?".GetSentencesCount(); +// Paragraphs Count +TextCase.GetParagraphsCount("You talking to me?"); +"You talking to me?".GetParagraphsCount(); + ``` ## Get it on NuGet: