diff --git a/.editorconfig b/.editorconfig index 5f9f928..07bac5a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -74,7 +74,7 @@ csharp_style_expression_bodied_accessors = true:none csharp_style_pattern_matching_over_is_with_cast_check = true : suggestion csharp_style_pattern_matching_over_as_with_null_check = true : suggestion csharp_style_inlined_variable_declaration = true : suggestion -csharp_style_throw_expression = true : suggestion +csharp_style_throw_expression = true:suggestion csharp_style_conditional_delegate_call = true : suggestion # Newline settings @@ -97,7 +97,7 @@ csharp_indent_labels = flush csharp_indent_switch_labels = true csharp_new_line_between_query_expression_clauses = true csharp_prefer_braces = true:silent -csharp_prefer_simple_default_expression = true : suggestion +csharp_prefer_simple_default_expression = true:suggestion csharp_style_deconstructed_variable_declaration = true : suggestion csharp_preserve_single_line_blocks = true csharp_preserve_single_line_statements = true @@ -114,11 +114,13 @@ csharp_space_between_method_declaration_parameter_list_parentheses = false csharp_space_between_parentheses = false csharp_style_pattern_local_over_anonymous_function = true : suggestion csharp_prefer_simple_using_statement = true:suggestion -csharp_style_namespace_declarations = block_scoped:silent +csharp_style_namespace_declarations = file_scoped:silent csharp_style_prefer_method_group_conversion = true:silent csharp_style_prefer_top_level_statements = true:silent csharp_style_expression_bodied_lambdas = true:silent csharp_style_expression_bodied_local_functions = false:silent +csharp_style_prefer_primary_constructors = true:suggestion +csharp_style_prefer_null_check_over_type_check = true:suggestion # XML and Config style settings: @@ -196,3 +198,13 @@ dotnet_style_object_initializer = true:suggestion dotnet_style_collection_initializer = true:suggestion dotnet_style_operator_placement_when_wrapping = beginning_of_line tab_width = 4 +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion +dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion +dotnet_style_namespace_match_folder = true:suggestion diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 01f58dd..9e92bbb 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -1,23 +1,25 @@ name: CI Build -run-name: CIBuild_${{ github.event_name }}_${{ github.ref_name }}_${{ github.run_number }}${{ github.run_attempt }} +run-name: CIBuild_${{ github.event_name }}_${{ github.ref_name }}_${{ github.run_number }}.${{ github.run_attempt }} env: PKG_MAJOR_VERSION: '1.1' PROJECT_NAME: 'DNX.Extensions' - DOTNET_VERSION: 6.0.x + DOTNET_VERSION: 8.0.x NUGET_VERSION: 5.x BUILD_CONFIG: Release BUILD_PLATFORM: Any CPU PACK_PARAMETERS: '' NUGET_OUTPUT_FOLDER: nupkgs + BRANCH_RELEASE_CANDIDATE: rc/** on: push: branches: - main - - 'feature/**' - - 'task/**' - - 'spike/**' + - rc/** + - feature/** + - task/** + - spike/** pull_request: branches: @@ -26,6 +28,8 @@ on: workflow_dispatch: jobs: + ########################################################## + ## Pipeline Configuration and Setup setup: name: Setup Pipeline @@ -39,7 +43,7 @@ jobs: - name: Set Package Suffix id: package_suffix run: | - branch='${{ github.ref }}' + branch="${{ github.ref }}" package_suffix='' if [ "$branch" != "refs/heads/main" ] @@ -57,7 +61,10 @@ jobs: if [ "${{ github.event_name }}" == "pull_request" ] then should_publish=true - elif [ "${{ github.ref }}" == 'refs/heads/main' ] + elif [ "${{ github.ref }}" == "refs/heads/main" ] + then + should_publish=true + elif [[ "${{ github.ref }}" == ${{ env.BRANCH_RELEASE_CANDIDATE }}* ]] then should_publish=true fi @@ -83,7 +90,7 @@ jobs: should_publish: ${{ env.should_publish }} ########################################################## - ## Bulid DotNet projects + ## Build DotNet projects build: name: Build .NET @@ -93,10 +100,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install .NET SDK - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: ${{ env.DOTNET_VERSION }} @@ -104,10 +111,10 @@ jobs: run: dotnet restore - name: Build - run: dotnet build --configuration ${{ env.BUILD_CONFIG }} /p:"Platform=${{ env.BUILD_PLATFORM }}" /p:"Version=${{ needs.setup.outputs.product_version }}" /p:"AssemblyVersion=${{ needs.setup.outputs.assembly_version }}" --no-restore + run: dotnet build --no-restore --configuration ${{ env.BUILD_CONFIG }} /p:"Platform=${{ env.BUILD_PLATFORM }}" /p:"Version=${{ needs.setup.outputs.product_version }}" /p:"AssemblyVersion=${{ needs.setup.outputs.assembly_version }}" - name: Test - run: dotnet test --configuration ${{ env.BUILD_CONFIG }} --no-restore --no-build --verbosity normal --collect:"XPlat Code Coverage" + run: dotnet test --no-restore --no-build --configuration ${{ env.BUILD_CONFIG }} --verbosity normal --collect:"XPlat Code Coverage" - name: Code Coverage Report uses: irongut/CodeCoverageSummary@v1.3.0 @@ -133,14 +140,14 @@ jobs: run: dotnet pack --configuration ${{ env.BUILD_CONFIG }} /p:"Platform=${{ env.BUILD_PLATFORM }}" /p:"PackageVersion=${{ needs.setup.outputs.package_version }}" --no-restore --output "${{ env.NUGET_OUTPUT_FOLDER }}" - name: Upload Build Artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: build_output path: "**/${{ env.PROJECT_NAME }}/bin/${{ env.BUILD_CONFIG }}/**" if-no-files-found: error - name: Upload NuGet Artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: nuget_output path: "${{ env.NUGET_OUTPUT_FOLDER }}/**" @@ -152,13 +159,15 @@ jobs: name: Create GitHub Release if: github.ref == 'refs/heads/main' && success() - needs: [setup, build] + needs: + - setup + - build runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Build Changelog id: build_changelog @@ -172,6 +181,7 @@ jobs: tag: v${{ needs.setup.outputs.assembly_version }} name: Release ${{ needs.setup.outputs.assembly_version }} body: ${{ steps.build_changelog.outputs.changelog }} + artifacts: '**/*.nupkg' - name: Tag git uses: pkgdeps/git-tag-action@v2.0.5 @@ -188,7 +198,10 @@ jobs: name: Publish to NuGet if: needs.setup.outputs.should_publish == 'true' - needs: [setup, build, release] + needs: + - setup + - build + - release runs-on: ubuntu-latest @@ -201,7 +214,7 @@ jobs: - name: Download NuGet Output id: download_nuget - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: nuget_output path: ${{ env.NUGET_OUTPUT_FOLDER }} diff --git a/src/DNX.Extensions/DNX.Extensions.csproj b/src/DNX.Extensions/DNX.Extensions.csproj index 40cb839..31fafd8 100644 --- a/src/DNX.Extensions/DNX.Extensions.csproj +++ b/src/DNX.Extensions/DNX.Extensions.csproj @@ -1,8 +1,10 @@ + Latest netstandard2.0 true + disable diff --git a/src/DNX.Extensions/DNX.Extensions.csproj.DotSettings b/src/DNX.Extensions/DNX.Extensions.csproj.DotSettings new file mode 100644 index 0000000..195c460 --- /dev/null +++ b/src/DNX.Extensions/DNX.Extensions.csproj.DotSettings @@ -0,0 +1,2 @@ + + Latest \ No newline at end of file diff --git a/src/DNX.Extensions/Enumerations/EnumerableExtensions.cs b/src/DNX.Extensions/Enumerations/EnumerableExtensions.cs index dd29c1f..04be678 100644 --- a/src/DNX.Extensions/Enumerations/EnumerableExtensions.cs +++ b/src/DNX.Extensions/Enumerations/EnumerableExtensions.cs @@ -1,34 +1,33 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; -namespace DNX.Extensions.Enumerations +namespace DNX.Extensions.Enumerations; + +public static class EnumerableExtensions { - public static class EnumerableExtensions + /// + /// Determines whether the specified enumerable has any elements and is not null + /// + /// + /// The enumerable. + /// true if the specified enumerable has any elements; otherwise, false. + /// Also available as an extension method + public static bool HasAny(this IEnumerable enumerable) { - /// - /// Determines whether the specified enumerable has any elements and is not null - /// - /// - /// The enumerable. - /// true if the specified enumerable has any elements; otherwise, false. - /// Also available as an extension method - public static bool HasAny(this IEnumerable enumerable) - { - return enumerable != null && enumerable.Any(); - } + return enumerable != null && enumerable.Any(); + } - /// - /// Determines whether the specified enumerable has any elements that match the predicate and is not null - /// - /// - /// The enumerable. - /// The predicate. - /// true if the specified predicate has any elements that match the predicate; otherwise, false. - /// Also available as an extension method - public static bool HasAny(this IEnumerable enumerable, Func predicate) - { - return enumerable != null && enumerable.Any(predicate); - } + /// + /// Determines whether the specified enumerable has any elements that match the predicate and is not null + /// + /// + /// The enumerable. + /// The predicate. + /// true if the specified predicate has any elements that match the predicate; otherwise, false. + /// Also available as an extension method + public static bool HasAny(this IEnumerable enumerable, Func predicate) + { + return enumerable != null && enumerable.Any(predicate); } } diff --git a/src/DNX.Extensions/Strings/SplitDelimiterType.cs b/src/DNX.Extensions/Strings/SplitDelimiterType.cs index 7d4d2ca..0c89b32 100644 --- a/src/DNX.Extensions/Strings/SplitDelimiterType.cs +++ b/src/DNX.Extensions/Strings/SplitDelimiterType.cs @@ -1,18 +1,17 @@ -namespace DNX.Extensions.Strings +namespace DNX.Extensions.Strings; + +/// +/// How the delimiter is to be treated when splitting text +/// +public enum SplitDelimiterType { /// - /// How the delimiter is to be treated when splitting text + /// Any specified value can be a delimiter /// - public enum SplitDelimiterType - { - /// - /// Any specified value can be a delimiter - /// - Any = 0, + Any = 0, - /// - /// All specified values are the delimiter - /// - All - } -} \ No newline at end of file + /// + /// All specified values are the delimiter + /// + All +} diff --git a/src/DNX.Extensions/Strings/StringExtensions.cs b/src/DNX.Extensions/Strings/StringExtensions.cs index 910c35b..95a858c 100644 --- a/src/DNX.Extensions/Strings/StringExtensions.cs +++ b/src/DNX.Extensions/Strings/StringExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -11,616 +11,615 @@ // ReSharper disable InvertIf // ReSharper disable LoopCanBeConvertedToQuery -namespace DNX.Extensions.Strings +namespace DNX.Extensions.Strings; + +/// +/// String Extensions +/// +public static class StringExtensions { + private const string SI_WORDIFY_REGEX_TEXT = "(?<=[a-z])(?[A-Z])|(?<=.)(?[A-Z])(?=[a-z])"; + + private static readonly Regex WordifyRegex = new Regex(SI_WORDIFY_REGEX_TEXT, RegexOptions.Compiled); + /// - /// String Extensions + /// Determines whether the specified text is null or empty /// - public static class StringExtensions + /// The text. + /// true if [is null or empty] [the specified text]; otherwise, false. + public static bool IsNullOrEmpty(this string text) { - private const string SI_WORDIFY_REGEX_TEXT = "(?<=[a-z])(?[A-Z])|(?<=.)(?[A-Z])(?=[a-z])"; - - private static readonly Regex WordifyRegex = new Regex(SI_WORDIFY_REGEX_TEXT, RegexOptions.Compiled); - - /// - /// Determines whether the specified text is null or empty - /// - /// The text. - /// true if [is null or empty] [the specified text]; otherwise, false. - public static bool IsNullOrEmpty(this string text) - { - return string.IsNullOrEmpty(text); - } + return string.IsNullOrEmpty(text); + } - /// - /// Determines whether the specified text is null or white space - /// - /// The text. - /// true if [is null or white space] [the specified text]; otherwise, false. - public static bool IsNullOrWhiteSpace(this string text) - { - return string.IsNullOrWhiteSpace(text); - } + /// + /// Determines whether the specified text is null or white space + /// + /// The text. + /// true if [is null or white space] [the specified text]; otherwise, false. + public static bool IsNullOrWhiteSpace(this string text) + { + return string.IsNullOrWhiteSpace(text); + } - /// - /// Ensure a string starts with a prefix string - /// - /// - /// - /// System.String. - /// Also available as an extension method - public static string EnsureStartsWith(this string text, string prefix) + /// + /// Ensure a string starts with a prefix string + /// + /// + /// + /// System.String. + /// Also available as an extension method + public static string EnsureStartsWith(this string text, string prefix) + { + if (!string.IsNullOrEmpty(prefix)) { - if (!string.IsNullOrEmpty(prefix)) + if (string.IsNullOrEmpty(text) || !text.StartsWith(prefix)) { - if (string.IsNullOrEmpty(text) || !text.StartsWith(prefix)) - { - text = string.Concat(prefix, text); - } + text = string.Concat(prefix, text); } - - return text; } - /// - /// Ensures a string ends with a suffix string. - /// - /// The text. - /// The suffix. - /// System.String. - /// Also available as an extension method - public static string EnsureEndsWith(this string text, string suffix) + return text; + } + + /// + /// Ensures a string ends with a suffix string. + /// + /// The text. + /// The suffix. + /// System.String. + /// Also available as an extension method + public static string EnsureEndsWith(this string text, string suffix) + { + if (!string.IsNullOrEmpty(suffix)) { - if (!string.IsNullOrEmpty(suffix)) + if (string.IsNullOrEmpty(text) || !text.EndsWith(suffix)) { - if (string.IsNullOrEmpty(text) || !text.EndsWith(suffix)) - { - text = string.Concat(text, suffix); - } + text = string.Concat(text, suffix); } - - return text; } - /// - /// Ensures a string starts and ends with a prefix / suffix string. - /// - /// The text. - /// The prefix / suffix. - /// System.String. - /// Also available as an extension method - public static string EnsureStartsAndEndsWith(this string text, string prefixsuffix) - { - return text.EnsureStartsWith(prefixsuffix) - .EnsureEndsWith(prefixsuffix); - } + return text; + } - /// - /// Ensures a string starts a prefix string and ends with a suffix string. - /// - /// The text. - /// The prefix. - /// The suffix. - /// System.String. - /// Also available as an extension method - public static string EnsureStartsAndEndsWith(this string text, string prefix, string suffix) - { - return text.EnsureStartsWith(prefix) - .EnsureEndsWith(suffix); - } + /// + /// Ensures a string starts and ends with a prefix / suffix string. + /// + /// The text. + /// The prefix / suffix. + /// System.String. + /// Also available as an extension method + public static string EnsureStartsAndEndsWith(this string text, string prefixsuffix) + { + return text.EnsureStartsWith(prefixsuffix) + .EnsureEndsWith(prefixsuffix); + } + + /// + /// Ensures a string starts a prefix string and ends with a suffix string. + /// + /// The text. + /// The prefix. + /// The suffix. + /// System.String. + /// Also available as an extension method + public static string EnsureStartsAndEndsWith(this string text, string prefix, string suffix) + { + return text.EnsureStartsWith(prefix) + .EnsureEndsWith(suffix); + } - /// - /// Ensures a string does not start with a prefix string - /// - /// The text. - /// The prefix. - /// System.String. - /// Also available as an extension method - public static string RemoveStartsWith(this string text, string prefix) + /// + /// Ensures a string does not start with a prefix string + /// + /// The text. + /// The prefix. + /// System.String. + /// Also available as an extension method + public static string RemoveStartsWith(this string text, string prefix) + { + if (!string.IsNullOrEmpty(prefix) && !string.IsNullOrEmpty(text)) { - if (!string.IsNullOrEmpty(prefix) && !string.IsNullOrEmpty(text)) + while (text.StartsWith(prefix)) { - while (text.StartsWith(prefix)) - { - text = text.Substring(prefix.Length); - } + text = text.Substring(prefix.Length); } - - return text; } - /// - /// Ensures a string does not end with a suffix string - /// - /// The text. - /// The suffix. - /// System.String. - /// Also available as an extension method - public static string RemoveEndsWith(this string text, string suffix) + return text; + } + + /// + /// Ensures a string does not end with a suffix string + /// + /// The text. + /// The suffix. + /// System.String. + /// Also available as an extension method + public static string RemoveEndsWith(this string text, string suffix) + { + if (!string.IsNullOrEmpty(suffix) && !string.IsNullOrEmpty(text)) { - if (!string.IsNullOrEmpty(suffix) && !string.IsNullOrEmpty(text)) + while (text.EndsWith(suffix)) { - while (text.EndsWith(suffix)) - { - text = text.Substring(0, text.Length - suffix.Length); - } + text = text.Substring(0, text.Length - suffix.Length); } - - return text; } - /// - /// Ensures a string does not start or end with a prefix / suffix string - /// - /// The text. - /// The prefix and suffix. - /// System.String. - /// Also available as an extension method - public static string RemoveStartsAndEndsWith(this string text, string prefixSuffix) - { - return text.RemoveEndsWith(prefixSuffix) - .RemoveStartsWith(prefixSuffix); - } + return text; + } - /// - /// Ensures a string does not start with a prefix string or end with a suffix string - /// - /// The text. - /// The prefix. - /// The suffix. - /// System.String. - /// Also available as an extension method - public static string RemoveStartsAndEndsWith(this string text, string prefix, string suffix) - { - return text.RemoveStartsWith(prefix) - .RemoveEndsWith(suffix); - } + /// + /// Ensures a string does not start or end with a prefix / suffix string + /// + /// The text. + /// The prefix and suffix. + /// System.String. + /// Also available as an extension method + public static string RemoveStartsAndEndsWith(this string text, string prefixSuffix) + { + return text.RemoveEndsWith(prefixSuffix) + .RemoveStartsWith(prefixSuffix); + } - /// - /// Gets the text between the specified start and end text. - /// - /// The text. - /// The start text. - /// The end text. - /// The comparison. - /// System.String. - public static string Between(this string text, string startText, string endText, StringComparison comparison = StringComparison.Ordinal) - { - return text + /// + /// Ensures a string does not start with a prefix string or end with a suffix string + /// + /// The text. + /// The prefix. + /// The suffix. + /// System.String. + /// Also available as an extension method + public static string RemoveStartsAndEndsWith(this string text, string prefix, string suffix) + { + return text.RemoveStartsWith(prefix) + .RemoveEndsWith(suffix); + } + + /// + /// Gets the text between the specified start and end text. + /// + /// The text. + /// The start text. + /// The end text. + /// The comparison. + /// System.String. + public static string Between(this string text, string startText, string endText, StringComparison comparison = StringComparison.Ordinal) + { + return text .After(startText, comparison) .Before(endText, comparison) - ; - } + ; + } - /// - /// Gets the text before the specified end text. - /// - /// The text. - /// The end text. - /// The comparison. - /// System.String. - public static string Before(this string text, string endText, StringComparison comparison = StringComparison.Ordinal) + /// + /// Gets the text before the specified end text. + /// + /// The text. + /// The end text. + /// The comparison. + /// System.String. + public static string Before(this string text, string endText, StringComparison comparison = StringComparison.Ordinal) + { + if (text.IsNullOrEmpty()) { - if (text.IsNullOrEmpty()) - { - return null; - } + return null; + } - var endIndex = endText.IsNullOrEmpty() - ? -1 - : text.IndexOf(endText, comparison); + var endIndex = endText.IsNullOrEmpty() + ? -1 + : text.IndexOf(endText, comparison); - var result = endIndex >= 0 - ? text.Substring(0, endIndex) - : null; + var result = endIndex >= 0 + ? text.Substring(0, endIndex) + : null; - return result; - } + return result; + } - /// - /// Gets the text after the specified start text. - /// - /// The text. - /// The start text. - /// The comparison. - /// System.String. - public static string After(this string text, string startText, StringComparison comparison = StringComparison.Ordinal) + /// + /// Gets the text after the specified start text. + /// + /// The text. + /// The start text. + /// The comparison. + /// System.String. + public static string After(this string text, string startText, StringComparison comparison = StringComparison.Ordinal) + { + if (string.IsNullOrEmpty(text)) { - if (string.IsNullOrEmpty(text)) - { - return null; - } + return null; + } + + var startTextLength = startText?.Length ?? 0; - var startTextLength = startText?.Length ?? 0; + var startIndex = string.IsNullOrEmpty(startText) + ? -1 + : text.IndexOf(startText, comparison); - var startIndex = string.IsNullOrEmpty(startText) - ? -1 - : text.IndexOf(startText, comparison); + var result = startIndex >= 0 + ? text.Substring(startIndex + startTextLength) + : null; - var result = startIndex >= 0 - ? text.Substring(startIndex + startTextLength) - : null; + return result; + } - return result; + /// + /// Determines whether the text contains the specified search text. + /// + /// The text. + /// The search text. + /// The comparison. + /// true if the specified search text contains text; otherwise, false. + /// Also available as an extension method + public static bool ContainsText(this string text, string searchText, StringComparison comparison = StringComparison.CurrentCultureIgnoreCase) + { + if (text == null) + { + return false; } - /// - /// Determines whether the text contains the specified search text. - /// - /// The text. - /// The search text. - /// The comparison. - /// true if the specified search text contains text; otherwise, false. - /// Also available as an extension method - public static bool ContainsText(this string text, string searchText, StringComparison comparison = StringComparison.CurrentCultureIgnoreCase) + if (string.IsNullOrEmpty(searchText)) { - if (text == null) - { - return false; - } + return true; + } - if (string.IsNullOrEmpty(searchText)) - { - return true; - } + return text.IndexOf(searchText, comparison) >= 0; + } - return text.IndexOf(searchText, comparison) >= 0; - } + /// + /// Determines whether text contains only the specified characters. + /// + /// The text. + /// The characters. + /// true if the specified characters contains only; otherwise, false. + /// Also available as an extension method + public static bool ContainsOnly(this string text, string characters) + { + return ContainsOnly(text, (characters ?? string.Empty).ToCharArray()); + } - /// - /// Determines whether text contains only the specified characters. - /// - /// The text. - /// The characters. - /// true if the specified characters contains only; otherwise, false. - /// Also available as an extension method - public static bool ContainsOnly(this string text, string characters) + /// + /// Determines whether text contains only the specified characters. + /// + /// The text. + /// The characters. + /// System.Boolean. + /// Also available as an extension method + public static bool ContainsOnly(this string text, IList characters) + { + if (text == null || !characters.HasAny()) { - return ContainsOnly(text, (characters ?? string.Empty).ToCharArray()); + return false; } - /// - /// Determines whether text contains only the specified characters. - /// - /// The text. - /// The characters. - /// System.Boolean. - /// Also available as an extension method - public static bool ContainsOnly(this string text, IList characters) + foreach (var ch in text) { - if (text == null || !characters.HasAny()) + if (!characters.Contains(ch)) { return false; } - - foreach (var ch in text) - { - if (!characters.Contains(ch)) - { - return false; - } - } - - return true; } - /// - /// Removes any of the specified characters from a string - /// - /// The text. - /// The chars to remove. - /// System.String. - /// Also available as an extension method - public static string RemoveAny(this string text, string charsToRemove) - { - return RemoveAny(text, charsToRemove.ToCharArray()); - } + return true; + } - /// - /// Removes any of the specified characters from a string - /// - /// The text. - /// The chars to remove. - /// System.String. - /// Also available as an extension method - public static string RemoveAny(this string text, char[] charsToRemove) + /// + /// Removes any of the specified characters from a string + /// + /// The text. + /// The chars to remove. + /// System.String. + /// Also available as an extension method + public static string RemoveAny(this string text, string charsToRemove) + { + return RemoveAny(text, charsToRemove.ToCharArray()); + } + + /// + /// Removes any of the specified characters from a string + /// + /// The text. + /// The chars to remove. + /// System.String. + /// Also available as an extension method + public static string RemoveAny(this string text, char[] charsToRemove) + { + if (charsToRemove.HasAny() && !string.IsNullOrEmpty(text)) { - if (charsToRemove.HasAny() && !string.IsNullOrEmpty(text)) + foreach (var c in charsToRemove) { - foreach (var c in charsToRemove) - { - text = text.Replace(c.ToString(), string.Empty); - } + text = text.Replace(c.ToString(), string.Empty); } - - return text; } - /// - /// Removes any characters from a string so that only instances of the specified characters remain - /// - /// The text. - /// The chars to keep. - /// System.String. - /// Also available as an extension method - public static string RemoveAnyExcept(this string text, string charsToKeep) - { - return RemoveAnyExcept(text, (charsToKeep ?? string.Empty).ToCharArray()); - } + return text; + } + + /// + /// Removes any characters from a string so that only instances of the specified characters remain + /// + /// The text. + /// The chars to keep. + /// System.String. + /// Also available as an extension method + public static string RemoveAnyExcept(this string text, string charsToKeep) + { + return RemoveAnyExcept(text, (charsToKeep ?? string.Empty).ToCharArray()); + } - /// - /// Removes any characters from a string so that only instances of the specified characters remain - /// - /// The text. - /// The chars to keep. - /// System.String. - /// Also available as an extension method - public static string RemoveAnyExcept(this string text, IList charsToKeep) + /// + /// Removes any characters from a string so that only instances of the specified characters remain + /// + /// The text. + /// The chars to keep. + /// System.String. + /// Also available as an extension method + public static string RemoveAnyExcept(this string text, IList charsToKeep) + { + if (string.IsNullOrEmpty(text)) { - if (string.IsNullOrEmpty(text)) - { - return text; - } + return text; + } - var sb = new StringBuilder(text.Length); + var sb = new StringBuilder(text.Length); - if (charsToKeep.HasAny()) + if (charsToKeep.HasAny()) + { + foreach (var c in text.ToCharArray()) { - foreach (var c in text.ToCharArray()) + if (charsToKeep.Contains(c)) { - if (charsToKeep.Contains(c)) - { - sb.Append(c); - } + sb.Append(c); } } - - return sb.ToString(); } - /// - /// Reverses the specified text. - /// - /// The text. - /// System.String. - /// Also available as an extension method - public static string Reverse(this string text) - { - if (string.IsNullOrWhiteSpace(text)) - { - return text; - } + return sb.ToString(); + } - var charArray = text.ToCharArray(); - Array.Reverse(charArray); - return new string(charArray); + /// + /// Reverses the specified text. + /// + /// The text. + /// System.String. + /// Also available as an extension method + public static string Reverse(this string text) + { + if (string.IsNullOrWhiteSpace(text)) + { + return text; } - /// - /// Splits the text by the specified delimiters. - /// - /// The text. - /// The delimiters. - /// The options. - /// Type of the delimiter. - /// IEnumerable<System.String>. - /// delimiterType - Value must be one of {string.Join(",", Enum.GetNames(typeof(SplitDelimiterType)))} - /// Also available as an extension method - public static IEnumerable SplitText(this string text, string delimiters, StringSplitOptions options = StringSplitOptions.None, SplitDelimiterType delimiterType = SplitDelimiterType.Any) + var charArray = text.ToCharArray(); + Array.Reverse(charArray); + return new string(charArray); + } + + /// + /// Splits the text by the specified delimiters. + /// + /// The text. + /// The delimiters. + /// The options. + /// Type of the delimiter. + /// IEnumerable<System.String>. + /// delimiterType - Value must be one of {string.Join(",", Enum.GetNames(typeof(SplitDelimiterType)))} + /// Also available as an extension method + public static IEnumerable SplitText(this string text, string delimiters, StringSplitOptions options = StringSplitOptions.None, SplitDelimiterType delimiterType = SplitDelimiterType.Any) + { + switch (delimiterType) { - switch (delimiterType) - { - case SplitDelimiterType.Any: - return text.Split(delimiters.ToCharArray(), options); + case SplitDelimiterType.Any: + return text.Split(delimiters.ToCharArray(), options); - case SplitDelimiterType.All: - // NOTE: A native text.Split(string, ...) is available in NET Core 2.1+ - return text.SplitByText(delimiters, options); + case SplitDelimiterType.All: + // NOTE: A native text.Split(string, ...) is available in NET Core 2.1+ + return text.SplitByText(delimiters, options); - default: - throw new ArgumentOutOfRangeException(nameof(delimiterType), delimiterType, $"Value must be one of {string.Join(",", Enum.GetNames(typeof(SplitDelimiterType)))}"); - } + default: + throw new ArgumentOutOfRangeException(nameof(delimiterType), delimiterType, $"Value must be one of {string.Join(",", Enum.GetNames(typeof(SplitDelimiterType)))}"); } + } - /// - /// Splits the text by the specified text string. - /// - /// The text. - /// The delimiter text. - /// The options. - /// The comparison. - /// IEnumerable<System.String>. - public static IEnumerable SplitByText(this string text, string delimiterText, StringSplitOptions options = StringSplitOptions.None, StringComparison comparison = StringComparison.CurrentCulture) - { - var elements = new List(); - - var tempText = text; - - while (!string.IsNullOrEmpty(delimiterText) && tempText.Contains(delimiterText)) - { - var index = tempText.IndexOf(delimiterText, comparison); + /// + /// Splits the text by the specified text string. + /// + /// The text. + /// The delimiter text. + /// The options. + /// The comparison. + /// IEnumerable<System.String>. + public static IEnumerable SplitByText(this string text, string delimiterText, StringSplitOptions options = StringSplitOptions.None, StringComparison comparison = StringComparison.CurrentCulture) + { + var elements = new List(); - var element = index == 0 ? string.Empty : tempText.Substring(0, index); + var tempText = text; - if (options == StringSplitOptions.None || !string.IsNullOrEmpty(element)) - { - elements.Add(element); - } + while (!string.IsNullOrEmpty(delimiterText) && tempText.Contains(delimiterText)) + { + var index = tempText.IndexOf(delimiterText, comparison); - tempText = tempText.Substring(element.Length + delimiterText.Length); - } + var element = index == 0 ? string.Empty : tempText.Substring(0, index); - if (!string.IsNullOrEmpty(tempText)) + if (options == StringSplitOptions.None || !string.IsNullOrEmpty(element)) { - elements.Add(tempText); + elements.Add(element); } - return elements; + tempText = tempText.Substring(element.Length + delimiterText.Length); } - /// - /// Coalesces the list of strings to find the first not null - /// - /// The strings. - /// System.String. - /// Also available as an extension method - public static string CoalesceNull(params string[] strings) + if (!string.IsNullOrEmpty(tempText)) { - return strings.CoalesceNull(); + elements.Add(tempText); } - /// - /// Coalesces the list of strings to find the first not null - /// - /// The strings. - /// System.String. - /// Also available as an extension method - public static string CoalesceNull(this IList strings) - { - var value = strings.FirstOrDefault(s => s != null); + return elements; + } - return value; - } + /// + /// Coalesces the list of strings to find the first not null + /// + /// The strings. + /// System.String. + /// Also available as an extension method + public static string CoalesceNull(params string[] strings) + { + return strings.CoalesceNull(); + } - /// - /// Coalesces the list of strings to find the first not null or empty. - /// - /// The strings. - /// System.String. - /// Also available as an extension method - public static string CoalesceNullOrEmpty(params string[] strings) - { - return strings.CoalesceNullOrEmpty(); - } + /// + /// Coalesces the list of strings to find the first not null + /// + /// The strings. + /// System.String. + /// Also available as an extension method + public static string CoalesceNull(this IList strings) + { + var value = strings.FirstOrDefault(s => s != null); - /// - /// Coalesces the list of strings to find the first not null or empty. - /// - /// The strings. - /// System.String. - /// Also available as an extension method - public static string CoalesceNullOrEmpty(this IList strings) - { - var value = strings.FirstOrDefault(s => !string.IsNullOrEmpty(s)); + return value; + } - return value; - } + /// + /// Coalesces the list of strings to find the first not null or empty. + /// + /// The strings. + /// System.String. + /// Also available as an extension method + public static string CoalesceNullOrEmpty(params string[] strings) + { + return strings.CoalesceNullOrEmpty(); + } - /// - /// Coalesces the list of strings to find the first not null or whitespace. - /// - /// The strings. - /// System.String. - /// Also available as an extension method - public static string CoalesceNullOrWhitespace(params string[] strings) - { - return strings.CoalesceNullOrWhitespace(); - } + /// + /// Coalesces the list of strings to find the first not null or empty. + /// + /// The strings. + /// System.String. + /// Also available as an extension method + public static string CoalesceNullOrEmpty(this IList strings) + { + var value = strings.FirstOrDefault(s => !string.IsNullOrEmpty(s)); - /// - /// Coalesces the list of strings to find the first not null or whitespace. - /// - /// The strings. - /// System.String. - /// Also available as an extension method - public static string CoalesceNullOrWhitespace(this IList strings) - { - var value = strings.FirstOrDefault(s => !string.IsNullOrWhiteSpace(s)); + return value; + } - return value; - } + /// + /// Coalesces the list of strings to find the first not null or whitespace. + /// + /// The strings. + /// System.String. + /// Also available as an extension method + public static string CoalesceNullOrWhitespace(params string[] strings) + { + return strings.CoalesceNullOrWhitespace(); + } - /// - /// Builds the number validation regex for the specified cultureinfo - /// - /// The culture information. - /// System.String. - internal static string BuildNumberValidationRegexForCulture(CultureInfo cultureInfo) - { - var pattern =string.Format( - @"^[\{2}\{3}]?(0|[1-9][0-9]*|[1-9][0-9]{{0,{4}}}(\{0}[0-9]{{{5},{5}}})*)([\{1}]+[0-9]+)?$", - cultureInfo.NumberFormat.NumberGroupSeparator, - cultureInfo.NumberFormat.NumberDecimalSeparator, - cultureInfo.NumberFormat.NegativeSign, - cultureInfo.NumberFormat.PositiveSign, - cultureInfo.NumberFormat.NumberGroupSizes.First() - 1, - cultureInfo.NumberFormat.NumberGroupSizes.First() - ); - - return pattern; - } + /// + /// Coalesces the list of strings to find the first not null or whitespace. + /// + /// The strings. + /// System.String. + /// Also available as an extension method + public static string CoalesceNullOrWhitespace(this IList strings) + { + var value = strings.FirstOrDefault(s => !string.IsNullOrWhiteSpace(s)); - /// - /// Determines whether the specified text is numeric conforming to the current Culture NumberFormat. - /// - /// The text. - /// true if the specified culture information is numeric; otherwise, false. - public static bool IsValidNumber(this string text) - { - var pattern = BuildNumberValidationRegexForCulture(CultureInfo.DefaultThreadCurrentCulture); + return value; + } - return Regex.IsMatch(text, pattern); - } + /// + /// Builds the number validation regex for the specified cultureinfo + /// + /// The culture information. + /// System.String. + internal static string BuildNumberValidationRegexForCulture(CultureInfo cultureInfo) + { + var pattern =string.Format( + @"^[\{2}\{3}]?(0|[1-9][0-9]*|[1-9][0-9]{{0,{4}}}(\{0}[0-9]{{{5},{5}}})*)([\{1}]+[0-9]+)?$", + cultureInfo.NumberFormat.NumberGroupSeparator, + cultureInfo.NumberFormat.NumberDecimalSeparator, + cultureInfo.NumberFormat.NegativeSign, + cultureInfo.NumberFormat.PositiveSign, + cultureInfo.NumberFormat.NumberGroupSizes.First() - 1, + cultureInfo.NumberFormat.NumberGroupSizes.First() + ); + + return pattern; + } - /// - /// Determines whether the specified text is numeric conforming to the specified Culture NumberFormat. - /// - /// The text. - /// The culture information. - /// true if the specified culture information is numeric; otherwise, false. - public static bool IsValidNumber(this string text, CultureInfo cultureInfo) - { - var pattern = BuildNumberValidationRegexForCulture(cultureInfo); + /// + /// Determines whether the specified text is numeric conforming to the current Culture NumberFormat. + /// + /// The text. + /// true if the specified culture information is numeric; otherwise, false. + public static bool IsValidNumber(this string text) + { + var pattern = BuildNumberValidationRegexForCulture(CultureInfo.DefaultThreadCurrentCulture); - return Regex.IsMatch(text, pattern); - } + return Regex.IsMatch(text, pattern); + } - /// - /// Add spaces to separate the capitalized words in the string, - /// i.e. insert a space before each uppercase letter that is - /// either preceded by a lowercase letter or followed by a - /// lowercase letter (but not for the first char in string). - /// This keeps groups of uppercase letters - e.g. preservedWords - together. - /// - /// A string in PascalCase - /// - public static string Wordify(this string titleCaseString) - { - return titleCaseString.Wordify(null); - } + /// + /// Determines whether the specified text is numeric conforming to the specified Culture NumberFormat. + /// + /// The text. + /// The culture information. + /// true if the specified culture information is numeric; otherwise, false. + public static bool IsValidNumber(this string text, CultureInfo cultureInfo) + { + var pattern = BuildNumberValidationRegexForCulture(cultureInfo); - /// - /// Add spaces to separate the capitalized words in the string, - /// i.e. insert a space before each uppercase letter that is - /// either preceded by a lowercase letter or followed by a - /// lowercase letter (but not for the first char in string). - /// This keeps groups of uppercase letters - e.g. acronyms - together. - /// - /// A string in PascalCase - /// The preservedWords - beyond acronyms - /// System.String. - public static string Wordify(this string titleCaseString, IList preservedWords) - { - if (string.IsNullOrWhiteSpace(titleCaseString)) - return titleCaseString; + return Regex.IsMatch(text, pattern); + } - var text = WordifyRegex - .Replace(titleCaseString, " ${x}") - .Replace(" ", " "); + /// + /// Add spaces to separate the capitalized words in the string, + /// i.e. insert a space before each uppercase letter that is + /// either preceded by a lowercase letter or followed by a + /// lowercase letter (but not for the first char in string). + /// This keeps groups of uppercase letters - e.g. preservedWords - together. + /// + /// A string in PascalCase + /// + public static string Wordify(this string titleCaseString) + { + return titleCaseString.Wordify(null); + } - if (preservedWords.HasAny()) - { - var acronymDict = preservedWords - .Distinct() - .ToDictionary(x => x.Wordify(), x => x) - ; - - text = acronymDict.Aggregate(text, - (current, dict) => current.Replace(dict.Key, dict.Value) - ); - } + /// + /// Add spaces to separate the capitalized words in the string, + /// i.e. insert a space before each uppercase letter that is + /// either preceded by a lowercase letter or followed by a + /// lowercase letter (but not for the first char in string). + /// This keeps groups of uppercase letters - e.g. acronyms - together. + /// + /// A string in PascalCase + /// The preservedWords - beyond acronyms + /// System.String. + public static string Wordify(this string titleCaseString, IList preservedWords) + { + if (string.IsNullOrWhiteSpace(titleCaseString)) + return titleCaseString; - return text; + var text = WordifyRegex + .Replace(titleCaseString, " ${x}") + .Replace(" ", " "); + + if (preservedWords.HasAny()) + { + var acronymDict = preservedWords + .Distinct() + .ToDictionary(x => x.Wordify(), x => x) + ; + + text = acronymDict.Aggregate(text, + (current, dict) => current.Replace(dict.Key, dict.Value) + ); } + + return text; } } diff --git a/tests/DNX.Extensions.Tests/DNX.Extensions.Tests.csproj b/tests/DNX.Extensions.Tests/DNX.Extensions.Tests.csproj index 7d89f43..ef324c8 100644 --- a/tests/DNX.Extensions.Tests/DNX.Extensions.Tests.csproj +++ b/tests/DNX.Extensions.Tests/DNX.Extensions.Tests.csproj @@ -1,27 +1,30 @@ - + + Latest Exe - net6.0 + net8.0 enable - enable + disable - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + all runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/tests/DNX.Extensions.Tests/DNX.Extensions.Tests.csproj.DotSettings b/tests/DNX.Extensions.Tests/DNX.Extensions.Tests.csproj.DotSettings new file mode 100644 index 0000000..195c460 --- /dev/null +++ b/tests/DNX.Extensions.Tests/DNX.Extensions.Tests.csproj.DotSettings @@ -0,0 +1,2 @@ + + Latest \ No newline at end of file diff --git a/tests/DNX.Extensions.Tests/Enumerations/EnumerableExtensionsTests.cs b/tests/DNX.Extensions.Tests/Enumerations/EnumerableExtensionsTests.cs index e193373..876fd1e 100644 --- a/tests/DNX.Extensions.Tests/Enumerations/EnumerableExtensionsTests.cs +++ b/tests/DNX.Extensions.Tests/Enumerations/EnumerableExtensionsTests.cs @@ -1,39 +1,42 @@ -using DNX.Extensions.Enumerations; -using NUnit.Framework; +using DNX.Extensions.Enumerations; +using FluentAssertions; +using Xunit; -namespace DNX.Extensions.Tests.Enumerations +namespace DNX.Extensions.Tests.Enumerations; + +public class EnumerableExtensionsTests { - [TestFixture] - public class EnumerableExtensionsTests + [Theory] + [InlineData("", false)] + [InlineData(null, false)] + [InlineData("a,b,c,d,e,f,g,h,i,j", true)] + public void Test_HasAny(string commaDelimitedArray, bool expectedResult) { - [TestCase("", ExpectedResult = false)] - [TestCase(null, ExpectedResult = false)] - [TestCase("a,b,c,d,e,f,g,h,i,j", ExpectedResult = true)] - public bool Test_HasAny(string commaDelimitedArray) - { - var enumerable = commaDelimitedArray == null - ? null - : commaDelimitedArray.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + var enumerable = commaDelimitedArray? + .Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); - var result = enumerable.HasAny(); + // Act + var result = enumerable.HasAny(); - return result; - } + // Assert + result.Should().Be(expectedResult); + } - [TestCase("", "1", ExpectedResult = false)] - [TestCase(null, "1", ExpectedResult = false)] - [TestCase("a1,b2,c1,d2,e1,f2,g1,h2,i1,j2", "1", ExpectedResult = true)] - [TestCase("a1,b2,c1,d2,e1,f2,g1,h2,i1,j2", "2", ExpectedResult = true)] - [TestCase("a1,b2,c1,d2,e1,f2,g1,h2,i1,j2", "0", ExpectedResult = false)] - public bool Test_HasAny_predicate(string commaDelimitedArray, string suffix) - { - var enumerable = commaDelimitedArray == null - ? null - : commaDelimitedArray.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); + [Theory] + [InlineData("", "1", false)] + [InlineData(null, "1", false)] + [InlineData("a1,b2,c1,d2,e1,f2,g1,h2,i1,j2", "1", true)] + [InlineData("a1,b2,c1,d2,e1,f2,g1,h2,i1,j2", "2", true)] + [InlineData("a1,b2,c1,d2,e1,f2,g1,h2,i1,j2", "0", false)] + public void Test_HasAny_predicate(string commaDelimitedArray, string suffix, bool expectedResult) + { + var enumerable = commaDelimitedArray? + .Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); - var result = enumerable.HasAny(s => s.EndsWith(suffix)); + // Act + var result = enumerable.HasAny(s => s.EndsWith(suffix)); - return result; - } + // Assert + result.Should().Be(expectedResult); } } diff --git a/tests/DNX.Extensions.Tests/Strings/StringExtensionsTests.cs b/tests/DNX.Extensions.Tests/Strings/StringExtensionsTests.cs index acf6e57..9ac280a 100644 --- a/tests/DNX.Extensions.Tests/Strings/StringExtensionsTests.cs +++ b/tests/DNX.Extensions.Tests/Strings/StringExtensionsTests.cs @@ -1,528 +1,592 @@ -using System.Globalization; +using System.Globalization; using DNX.Extensions.Strings; -using NUnit.Framework; -using Shouldly; +using FluentAssertions; +using Xunit; -namespace DNX.Extensions.Tests.Strings -{ - public class StringExtensionsTests - { - [TestCase(null, ExpectedResult = true)] - [TestCase("", ExpectedResult = true)] - [TestCase(" ", ExpectedResult = false)] - [TestCase("a", ExpectedResult = false)] - [TestCase(" A ", ExpectedResult = false)] - [TestCase("ABC", ExpectedResult = false)] - public bool Test_IsNullOrEmpty(string text) - { - return text.IsNullOrEmpty(); - } +#pragma warning disable xUnit1025 // Duplicate inline test cases - [TestCase(null, ExpectedResult = true)] - [TestCase("", ExpectedResult = true)] - [TestCase(" ", ExpectedResult = true)] - [TestCase("a", ExpectedResult = false)] - [TestCase(" A ", ExpectedResult = false)] - [TestCase("ABC", ExpectedResult = false)] - public bool Test_IsNullOrWhiteSpace(string text) - { - return text.IsNullOrWhiteSpace(); - } +namespace DNX.Extensions.Tests.Strings; - [TestCase(null, "hello", ExpectedResult = "hello")] - [TestCase("", "", ExpectedResult = "")] - [TestCase("hello", null, ExpectedResult = "hello")] - [TestCase("hello", "h", ExpectedResult = "hello")] - [TestCase("hello", "he", ExpectedResult = "hello")] - [TestCase("hello", "hel", ExpectedResult = "hello")] - [TestCase("hello", "hell", ExpectedResult = "hello")] - [TestCase("hello", "hello", ExpectedResult = "hello")] - [TestCase("hello", " ", ExpectedResult = " hello")] - [TestCase(" hello", " ", ExpectedResult = " hello")] - [TestCase(" hello", " ", ExpectedResult = " hello")] - public string Test_EnsureStartsWith(string text, string prefix) - { - var result = text.EnsureStartsWith(prefix); - - return result; - } +public class StringExtensionsTests +{ + [Theory] + [InlineData(null, true)] + [InlineData("", true)] + [InlineData(" ", false)] + [InlineData("a", false)] + [InlineData(" A ", false)] + [InlineData("ABC", false)] + public void Test_IsNullOrEmpty(string text, bool expectedResult) + { + // Assert + text.IsNullOrEmpty().Should().Be(expectedResult); + } - [TestCase(null, "hello", ExpectedResult = "hello")] - [TestCase("", "", ExpectedResult = "")] - [TestCase("hello", null, ExpectedResult = "hello")] - [TestCase("hello", "o", ExpectedResult = "hello")] - [TestCase("hello", "lo", ExpectedResult = "hello")] - [TestCase("hello", "llo", ExpectedResult = "hello")] - [TestCase("hello", "ello", ExpectedResult = "hello")] - [TestCase("hello", "hello", ExpectedResult = "hello")] - [TestCase("hello", " ", ExpectedResult = "hello ")] - [TestCase("hello ", " ", ExpectedResult = "hello ")] - [TestCase("hello ", " ", ExpectedResult = "hello ")] - public string Test_EnsureEndsWith(string text, string suffix) - { - var result = text.EnsureEndsWith(suffix); + [Theory] + [InlineData(null, true)] + [InlineData("", true)] + [InlineData(" ", true)] + [InlineData("a", false)] + [InlineData(" A ", false)] + [InlineData("ABC", false)] + public void Test_IsNullOrWhiteSpace(string text, bool expectedResult) + { + text.IsNullOrWhiteSpace().Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData(null, "hello", "hello")] + [InlineData("", "", "")] + [InlineData("hello", null, "hello")] + [InlineData("hello", "h", "hello")] + [InlineData("hello", "he", "hello")] + [InlineData("hello", "hel", "hello")] + [InlineData("hello", "hell", "hello")] + [InlineData("hello", "hello", "hello")] + [InlineData("hello", " ", " hello")] + [InlineData(" hello", " ", " hello")] + [InlineData(" hello", " ", " hello")] + public void Test_EnsureStartsWith(string text, string prefix, string expectedResult) + { + var result = text.EnsureStartsWith(prefix); - [TestCase("hello", "#", ExpectedResult = "#hello#")] - [TestCase("hello", "", ExpectedResult = "hello")] - [TestCase("hello", null, ExpectedResult = "hello")] - [TestCase("hello", "_", ExpectedResult = "_hello_")] - [TestCase("", "_", ExpectedResult = "_")] - public string Test_EnsureStartsAndEndsWith(string text, string prefixsuffix) - { - var result = text.EnsureStartsAndEndsWith(prefixsuffix); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData(null, "hello", "hello")] + [InlineData("", "", "")] + [InlineData("hello", null, "hello")] + [InlineData("hello", "o", "hello")] + [InlineData("hello", "lo", "hello")] + [InlineData("hello", "llo", "hello")] + [InlineData("hello", "ello", "hello")] + [InlineData("hello", "hello", "hello")] + [InlineData("hello", " ", "hello ")] + [InlineData("hello ", " ", "hello ")] + [InlineData("hello ", " ", "hello ")] + public void Test_EnsureEndsWith(string text, string suffix, string expectedResult) + { + var result = text.EnsureEndsWith(suffix); - [TestCase("hello", "[", "]", ExpectedResult = "[hello]")] - [TestCase("hello", "", ":", ExpectedResult = "hello:")] - [TestCase("hello", null, ":", ExpectedResult = "hello:")] - [TestCase("hello", ":", "", ExpectedResult = ":hello")] - [TestCase("hello", ":", null, ExpectedResult = ":hello")] - [TestCase("", "[", "]", ExpectedResult = "[]")] - public string Test_EnsureStartsAndEndsWith_prefix_and_suffix(string text, string prefix, string suffix) - { - var result = text.EnsureStartsAndEndsWith(prefix, suffix); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("hello", "#", "#hello#")] + [InlineData("hello", "", "hello")] + [InlineData("hello", null, "hello")] + [InlineData("hello", "_", "_hello_")] + [InlineData("", "_", "_")] + public void Test_EnsureStartsAndEndsWith(string text, string prefixSuffix, string expectedResult) + { + var result = text.EnsureStartsAndEndsWith(prefixSuffix); - [TestCase(null, "hello", ExpectedResult = null)] - [TestCase("", "hello", ExpectedResult = "")] - [TestCase("hello", "", ExpectedResult = "hello")] - [TestCase("hello", null, ExpectedResult = "hello")] - [TestCase("hello", "h", ExpectedResult = "ello")] - [TestCase("00099", "0", ExpectedResult = "99")] - public string Test_RemoveStartsWith(string text, string prefix) - { - var result = text.RemoveStartsWith(prefix); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("hello", "[", "]", "[hello]")] + [InlineData("hello", "", ":", "hello:")] + [InlineData("hello", null, ":", "hello:")] + [InlineData("hello", ":", "", ":hello")] + [InlineData("hello", ":", null, ":hello")] + [InlineData("", "[", "]", "[]")] + public void Test_EnsureStartsAndEndsWith_prefix_and_suffix(string text, string prefix, string suffix, string expectedResult) + { + var result = text.EnsureStartsAndEndsWith(prefix, suffix); - [TestCase(null, "hello", ExpectedResult = null)] - [TestCase("", "hello", ExpectedResult = "")] - [TestCase("hello", "", ExpectedResult = "hello")] - [TestCase("hello", null, ExpectedResult = "hello")] - [TestCase("hello", "o", ExpectedResult = "hell")] - [TestCase("00099", "9", ExpectedResult = "000")] - [TestCase("123232323", "23", ExpectedResult = "1")] - public string Test_RemoveEndsWith(string text, string suffix) - { - var result = text.RemoveEndsWith(suffix); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData(null, "hello", null)] + [InlineData("", "hello", "")] + [InlineData("hello", "", "hello")] + [InlineData("hello", null, "hello")] + [InlineData("hello", "h", "ello")] + [InlineData("00099", "0", "99")] + public void Test_RemoveStartsWith(string text, string prefix, string expectedResult) + { + var result = text.RemoveStartsWith(prefix); - [TestCase("hello", null, ExpectedResult = "hello")] - [TestCase("hello", "", ExpectedResult = "hello")] - [TestCase("", "h", ExpectedResult = "")] - [TestCase(null, "h", ExpectedResult = null)] - [TestCase("hello", "h", ExpectedResult = "ello")] - [TestCase("hello", "o", ExpectedResult = "hell")] - [TestCase("bob", "b", ExpectedResult = "o")] - public string Test_RemoveStartsAndEndsWith(string text, string prefixsuffix) - { - var result = text.RemoveStartsAndEndsWith(prefixsuffix); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData(null, "hello", null)] + [InlineData("", "hello", "")] + [InlineData("hello", "", "hello")] + [InlineData("hello", null, "hello")] + [InlineData("hello", "o", "hell")] + [InlineData("00099", "9", "000")] + [InlineData("123232323", "23", "1")] + public void Test_RemoveEndsWith(string text, string suffix, string expectedResult) + { + var result = text.RemoveEndsWith(suffix); - [TestCase("hello", null, null, ExpectedResult = "hello")] - [TestCase("hello", "", "", ExpectedResult = "hello")] - [TestCase("", "h", "e", ExpectedResult = "")] - [TestCase(null, "h", "e", ExpectedResult = null)] - [TestCase("hello", "h", "o", ExpectedResult = "ell")] - [TestCase("hello", "o", "h", ExpectedResult = "hello")] - [TestCase("bob", "b", "b", ExpectedResult = "o")] - public string Test_RemoveStartsAndEndsWith_prefix_and_suffix(string text, string prefix, string suffix) - { - var result = text.RemoveStartsAndEndsWith(prefix, suffix); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("hello", null, "hello")] + [InlineData("hello", "", "hello")] + [InlineData("", "h", "")] + [InlineData(null, "h", null)] + [InlineData("hello", "h", "ello")] + [InlineData("hello", "o", "hell")] + [InlineData("bob", "b", "o")] + public void Test_RemoveStartsAndEndsWith(string text, string prefixSuffix, string expectedResult) + { + var result = text.RemoveStartsAndEndsWith(prefixSuffix); - [TestCase("[Section Name]", "[", "]", ExpectedResult = "Section Name")] - [TestCase("[[Red]]This is some text[[/Red]]", "[[Red]]", "[[/Red]]", ExpectedResult = "This is some text")] - [TestCase("[Section Name]", "", "]", ExpectedResult = null)] - [TestCase("[Section Name]", "[", "", ExpectedResult = null)] - [TestCase("[Section Name]", null, "]", ExpectedResult = null)] - [TestCase("[Section Name]", "[", null, ExpectedResult = null)] - [TestCase("[Section Name]", null, null, ExpectedResult = null)] - [TestCase("A123B", "A", "B", ExpectedResult = "123")] - [TestCase("[Section Name]", "(", ")", ExpectedResult = null)] - [TestCase("", "[", "]", ExpectedResult = null)] - [TestCase(null, "[", "]", ExpectedResult = null)] - public string Test_Between(string text, string startText, string endText) - { - var result = text.Between(startText, endText); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("hello", null, null, "hello")] + [InlineData("hello", "", "", "hello")] + [InlineData("", "h", "e", "")] + [InlineData(null, "h", "e", null)] + [InlineData("hello", "h", "o", "ell")] + [InlineData("hello", "o", "h", "hello")] + [InlineData("bob", "b", "b", "o")] + public void Test_RemoveStartsAndEndsWith_prefix_and_suffix(string text, string prefix, string suffix, string expectedResult) + { + var result = text.RemoveStartsAndEndsWith(prefix, suffix); - [TestCase("[Section Name]", "[", "]", StringComparison.CurrentCulture, ExpectedResult = "Section Name")] - [TestCase("[Section Name]", "(", ")", StringComparison.CurrentCulture, ExpectedResult = null)] - [TestCase("A123B", "a", "b", StringComparison.OrdinalIgnoreCase, ExpectedResult = "123")] - [TestCase("A123B", "a", "b", StringComparison.Ordinal, ExpectedResult = null)] - public string Test_Between_ComparisonType(string text, string startText, string endText, StringComparison comparison) - { - var result = text.Between(startText, endText, comparison); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("[Section Name]", "[", "]", "Section Name")] + [InlineData("[[Red]]This is some text[[/Red]]", "[[Red]]", "[[/Red]]", "This is some text")] + [InlineData("[Section Name]", "", "]", null)] + [InlineData("[Section Name]", "[", "", null)] + [InlineData("[Section Name]", null, "]", null)] + [InlineData("[Section Name]", "[", null, null)] + [InlineData("[Section Name]", null, null, null)] + [InlineData("A123B", "A", "B", "123")] + [InlineData("[Section Name]", "(", ")", null)] + [InlineData("", "[", "]", null)] + [InlineData(null, "[", "]", null)] + public void Test_Between(string text, string startText, string endText, string expectedResult) + { + var result = text.Between(startText, endText); - [TestCase("This is some text", "some", ExpectedResult = "This is ")] - [TestCase("This is some text", "bob", ExpectedResult = null)] - [TestCase("This is some [[Red]]text[[/Red]]", "[[", ExpectedResult = "This is some ")] - [TestCase("This is some text", " ", ExpectedResult = "This")] - [TestCase("This is some text", "", ExpectedResult = null)] - [TestCase("This is some text", null, ExpectedResult = null)] - [TestCase(null, "o", ExpectedResult = null)] - public string Test_Before(string text, string endText) - { - var result = text.Before(endText); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("[Section Name]", "[", "]", StringComparison.CurrentCulture, "Section Name")] + [InlineData("[Section Name]", "(", ")", StringComparison.CurrentCulture, null)] + [InlineData("A123B", "a", "b", StringComparison.OrdinalIgnoreCase, "123")] + [InlineData("A123B", "a", "b", StringComparison.Ordinal, null)] + public void Test_Between_ComparisonType(string text, string startText, string endText, StringComparison comparison, string expectedResult) + { + var result = text.Between(startText, endText, comparison); - [TestCase("This is some text", "some", StringComparison.CurrentCulture, ExpectedResult = "This is ")] - [TestCase("This is some text", "bob", StringComparison.CurrentCulture, ExpectedResult = null)] - [TestCase("This is some text", "SOME", StringComparison.Ordinal, ExpectedResult = null)] - [TestCase("This is some text", "SOME", StringComparison.OrdinalIgnoreCase, ExpectedResult = "This is ")] - public string Test_Before_ComparisonType(string text, string endText, StringComparison comparison) - { - var result = text.Before(endText, comparison); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("This is some text", "some", "This is ")] + [InlineData("This is some text", "bob", null)] + [InlineData("This is some [[Red]]text[[/Red]]", "[[", "This is some ")] + [InlineData("This is some text", " ", "This")] + [InlineData("This is some text", "", null)] + [InlineData("This is some text", null, null)] + [InlineData(null, "o", null)] + public void Test_Before(string text, string endText, string expectedResult) + { + var result = text.Before(endText); - [TestCase("This is some text", "some", ExpectedResult = " text")] - [TestCase("This is some text", "bob", ExpectedResult = null)] - [TestCase("This is some [[Red]]text[[/Red]]", "[[", ExpectedResult = "Red]]text[[/Red]]")] - [TestCase("This is some text", " ", ExpectedResult = "is some text")] - [TestCase("This is some text", "", ExpectedResult = null)] - [TestCase("This is some text", null, ExpectedResult = null)] - [TestCase(null, "o", ExpectedResult = null)] - public string Test_After(string text, string startText) - { - var result = text.After(startText); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("This is some text", "some", StringComparison.CurrentCulture, "This is ")] + [InlineData("This is some text", "bob", StringComparison.CurrentCulture, null)] + [InlineData("This is some text", "SOME", StringComparison.Ordinal, null)] + [InlineData("This is some text", "SOME", StringComparison.OrdinalIgnoreCase, "This is ")] + public void Test_Before_ComparisonType(string text, string endText, StringComparison comparison, string expectedResult) + { + var result = text.Before(endText, comparison); - [TestCase("This is some text", "some", StringComparison.CurrentCulture, ExpectedResult = " text")] - [TestCase("This is some text", "bob", StringComparison.CurrentCulture, ExpectedResult = null)] - [TestCase("This is some text", "SOME", StringComparison.Ordinal, ExpectedResult = null)] - [TestCase("This is some text", "SOME", StringComparison.OrdinalIgnoreCase, ExpectedResult = " text")] - public string Test_After_ComparisonType(string text, string startText, StringComparison comparison) - { - var result = text.After(startText, comparison); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("This is some text", "some", " text")] + [InlineData("This is some text", "bob", null)] + [InlineData("This is some [[Red]]text[[/Red]]", "[[", "Red]]text[[/Red]]")] + [InlineData("This is some text", " ", "is some text")] + [InlineData("This is some text", "", null)] + [InlineData("This is some text", null, null)] + [InlineData(null, "o", null)] + public void Test_After(string text, string startText, string expectedResult) + { + var result = text.After(startText); - [TestCase("bob", "b", StringComparison.CurrentCultureIgnoreCase, ExpectedResult = true)] - [TestCase("BOB", "o", StringComparison.CurrentCultureIgnoreCase, ExpectedResult = true)] - [TestCase("bob", "b", StringComparison.CurrentCulture, ExpectedResult = true)] - [TestCase("BOB", "o", StringComparison.CurrentCulture, ExpectedResult = false)] - [TestCase("BOB", "", StringComparison.CurrentCulture, ExpectedResult = true)] - [TestCase("BOB", null, StringComparison.CurrentCulture, ExpectedResult = true)] - [TestCase("", "b", StringComparison.CurrentCulture, ExpectedResult = false)] - [TestCase(null, "o", StringComparison.CurrentCulture, ExpectedResult = false)] - public bool Test_ContainsText(string text, string searchText, StringComparison comparison) - { - var result = text.ContainsText(searchText, comparison); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("This is some text", "some", StringComparison.CurrentCulture, " text")] + [InlineData("This is some text", "bob", StringComparison.CurrentCulture, null)] + [InlineData("This is some text", "SOME", StringComparison.Ordinal, null)] + [InlineData("This is some text", "SOME", StringComparison.OrdinalIgnoreCase, " text")] + public void Test_After_ComparisonType(string text, string startText, StringComparison comparison, string expectedResult) + { + var result = text.After(startText, comparison); - [TestCase("hello", "helo", ExpectedResult = true)] - [TestCase("1234.56", "1234567890.", ExpectedResult = true)] - [TestCase("1,234.56", "1234567890.", ExpectedResult = false)] - [TestCase("1,234.56", "", ExpectedResult = false)] - [TestCase("1,234.56", null, ExpectedResult = false)] - public bool Test_ContainsOnly(string text, string characters) - { - var result = text.ContainsOnly(characters); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("bob", "b", StringComparison.CurrentCultureIgnoreCase, true)] + [InlineData("BOB", "o", StringComparison.CurrentCultureIgnoreCase, true)] + [InlineData("bob", "b", StringComparison.CurrentCulture, true)] + [InlineData("BOB", "o", StringComparison.CurrentCulture, false)] + [InlineData("BOB", "", StringComparison.CurrentCulture, true)] + [InlineData("BOB", null, StringComparison.CurrentCulture, true)] + [InlineData("", "b", StringComparison.CurrentCulture, false)] + [InlineData(null, "o", StringComparison.CurrentCulture, false)] + public void Test_ContainsText(string text, string searchText, StringComparison comparison, bool expectedResult) + { + var result = text.ContainsText(searchText, comparison); - [TestCase("1234.56", new[] { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.' }, ExpectedResult = true)] - [TestCase("1,234.56", new [] { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.' }, ExpectedResult = false)] - [TestCase("1,234.56", new char[] {}, ExpectedResult = false)] - [TestCase("1,234.56", null, ExpectedResult = false)] - [TestCase(null, new[] { 'a', 'e', 'i', 'o', 'u' }, ExpectedResult = false)] - public bool Test_ContainsOnlyCharacterArray(string text, IList characters) - { - var result = text.ContainsOnly(characters); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("hello", "helo", true)] + [InlineData("1234.56", "1234567890.", true)] + [InlineData("1,234.56", "1234567890.", false)] + [InlineData("1,234.56", "", false)] + [InlineData("1,234.56", null, false)] + public void Test_ContainsOnly(string text, string characters, bool expectedResult) + { + var result = text.ContainsOnly(characters); - [TestCase("obviously this piece of text contains at least one of every vowel", "aeiou", ExpectedResult = "bvsly ths pc f txt cntns t lst n f vry vwl")] - [TestCase("123,456,789.00", ",.", ExpectedResult = "12345678900")] - public string Test_RemoveAny(string text, string charsToRemove) - { - var result = text.RemoveAny(charsToRemove); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("1234.56", new[] { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.' }, true)] + [InlineData("1,234.56", new [] { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.' }, false)] + [InlineData("1,234.56", new char[] {}, false)] + [InlineData("1,234.56", null, false)] + [InlineData(null, new[] { 'a', 'e', 'i', 'o', 'u' }, false)] + public void Test_ContainsOnlyCharacterArray(string text, IList characters, bool expectedResult) + { + var result = text.ContainsOnly(characters); - [TestCase("", new [] { 'a', 'e', 'i', 'o', 'u' }, ExpectedResult = "")] - [TestCase(null, new[] { 'a', 'e', 'i', 'o', 'u' }, ExpectedResult = null)] - [TestCase("aeiou", new char[] { }, ExpectedResult = "aeiou")] - [TestCase("aeiou", null, ExpectedResult = "aeiou")] - [TestCase("obviously this piece of text contains at least one of every vowel", new[] { 'a', 'e', 'i', 'o', 'u' }, ExpectedResult = "bvsly ths pc f txt cntns t lst n f vry vwl")] - [TestCase("123,456,789.00", new [] { ',', '.' }, ExpectedResult = "12345678900")] - public string Test_RemoveAny_char_array(string text, char[] charsToRemove) - { - var result = text.RemoveAny(charsToRemove); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("obviously this piece of text contains at least one of every vowel", "aeiou", "bvsly ths pc f txt cntns t lst n f vry vwl")] + [InlineData("123,456,789.00", ",.", "12345678900")] + public void Test_RemoveAny(string text, string charsToRemove, string expectedResult) + { + var result = text.RemoveAny(charsToRemove); - [TestCase("", "1234567890.", ExpectedResult = "")] - [TestCase(null, "1234567890.", ExpectedResult = null)] - [TestCase("hello", "", ExpectedResult = "")] - [TestCase("hello", null, ExpectedResult = "")] - [TestCase("The amount to pay is: 123,456.00", "1234567890.", ExpectedResult = "123456.00")] - public string Test_RemoveAnyExcept(string text, string charsToKeep) - { - var result = text.RemoveAnyExcept(charsToKeep); + // Assert + result.Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("", new [] { 'a', 'e', 'i', 'o', 'u' }, "")] + [InlineData(null, new[] { 'a', 'e', 'i', 'o', 'u' }, null)] + [InlineData("aeiou", new char[] { }, "aeiou")] + [InlineData("aeiou", null, "aeiou")] + [InlineData("obviously this piece of text contains at least one of every vowel", new[] { 'a', 'e', 'i', 'o', 'u' }, "bvsly ths pc f txt cntns t lst n f vry vwl")] + [InlineData("123,456,789.00", new [] { ',', '.' }, "12345678900")] + public void Test_RemoveAny_char_array(string text, char[] charsToRemove, string expectedResult) + { + var result = text.RemoveAny(charsToRemove); - // GB - [TestCase("0", "en-gb", ExpectedResult = true)] - [TestCase("1", "en-gb", ExpectedResult = true)] - [TestCase("-1", "en-gb", ExpectedResult = true)] - [TestCase("+1", "en-gb", ExpectedResult = true)] - [TestCase("123.72", "en-gb", ExpectedResult = true)] - [TestCase("-123.72", "en-gb", ExpectedResult = true)] - [TestCase("+123.72", "en-gb", ExpectedResult = true)] - [TestCase("3,123.451", "en-gb", ExpectedResult = true)] - [TestCase("-3,123.451", "en-gb", ExpectedResult = true)] - [TestCase("+3,123.451", "en-gb", ExpectedResult = true)] - [TestCase("3412123.76543", "en-gb", ExpectedResult = true)] - [TestCase("-3412123.76543", "en-gb", ExpectedResult = true)] - [TestCase("+3412123.76543", "en-gb", ExpectedResult = true)] - [TestCase("7,034.989", "en-gb", ExpectedResult = true)] - [TestCase("-7,034.989", "en-gb", ExpectedResult = true)] - [TestCase("+7,034.989", "en-gb", ExpectedResult = true)] - // DE - [TestCase("3,123.451", "de-DE", ExpectedResult = false)] - [TestCase("3.123,451", "de-DE", ExpectedResult = true)] - public bool Test_IsValidNumber_default_culture(string text, string cultureInfoName) - { - var previousCulture = CultureInfo.DefaultThreadCurrentCulture; + // Assert + result.Should().Be(expectedResult); + } - try - { - CultureInfo.DefaultThreadCurrentCulture = CultureInfo.GetCultureInfo(cultureInfoName); + [Theory] + [InlineData("", "1234567890.", "")] + [InlineData(null, "1234567890.", null)] + [InlineData("hello", "", "")] + [InlineData("hello", null, "")] + [InlineData("The amount to pay is: 123,456.00", "1234567890.", "123456.00")] + public void Test_RemoveAnyExcept(string text, string charsToKeep, string expectedResult) + { + var result = text.RemoveAnyExcept(charsToKeep); - var result = text.IsValidNumber(); + // Assert + result.Should().Be(expectedResult); + } - return result; - } - finally - { - CultureInfo.DefaultThreadCurrentCulture = previousCulture; - } - } + [Theory] + // GB + [InlineData("0", "en-gb", true)] + [InlineData("1", "en-gb", true)] + [InlineData("-1", "en-gb", true)] + [InlineData("+1", "en-gb", true)] + [InlineData("123.72", "en-gb", true)] + [InlineData("-123.72", "en-gb", true)] + [InlineData("+123.72", "en-gb", true)] + [InlineData("3,123.451", "en-gb", true)] + [InlineData("-3,123.451", "en-gb", true)] + [InlineData("+3,123.451", "en-gb", true)] + [InlineData("3412123.76543", "en-gb", true)] + [InlineData("-3412123.76543", "en-gb", true)] + [InlineData("+3412123.76543", "en-gb", true)] + [InlineData("7,034.989", "en-gb", true)] + [InlineData("-7,034.989", "en-gb", true)] + [InlineData("+7,034.989", "en-gb", true)] + // DE + [InlineData("3,123.451", "de-DE", false)] + [InlineData("3.123,451", "de-DE", true)] + public void Test_IsValidNumber_default_culture(string text, string cultureInfoName, bool expectedResult) + { + var previousCulture = CultureInfo.DefaultThreadCurrentCulture; - // GB - [TestCase("0", "en-gb", ExpectedResult = true)] - [TestCase("1", "en-gb", ExpectedResult = true)] - [TestCase("-1", "en-gb", ExpectedResult = true)] - [TestCase("+1", "en-gb", ExpectedResult = true)] - [TestCase("123.72", "en-gb", ExpectedResult = true)] - [TestCase("-123.72", "en-gb", ExpectedResult = true)] - [TestCase("+123.72", "en-gb", ExpectedResult = true)] - [TestCase("3,123.451", "en-gb", ExpectedResult = true)] - [TestCase("-3,123.451", "en-gb", ExpectedResult = true)] - [TestCase("+3,123.451", "en-gb", ExpectedResult = true)] - [TestCase("3412123.76543", "en-gb", ExpectedResult = true)] - [TestCase("-3412123.76543", "en-gb", ExpectedResult = true)] - [TestCase("+3412123.76543", "en-gb", ExpectedResult = true)] - [TestCase("7,034.989", "en-gb", ExpectedResult = true)] - [TestCase("-7,034.989", "en-gb", ExpectedResult = true)] - [TestCase("+7,034.989", "en-gb", ExpectedResult = true)] - // DE - [TestCase("3,123.451", "de-DE", ExpectedResult = false)] - [TestCase("3.123,451", "de-DE", ExpectedResult = true)] - public bool Test_IsValidNumber(string text, string cultureInfoName) + try { - var cultureInfo = CultureInfo.GetCultureInfo(cultureInfoName); + CultureInfo.DefaultThreadCurrentCulture = CultureInfo.GetCultureInfo(cultureInfoName); - var result = text.IsValidNumber(cultureInfo); + // Act + var result = text.IsValidNumber(); - return result; + // Assert + result.Should().Be(expectedResult); } - - [TestCase("hello world", ExpectedResult = "dlrow olleh")] - [TestCase("12345", ExpectedResult = "54321")] - [TestCase("abcba", ExpectedResult = "abcba")] - [TestCase("", ExpectedResult = "")] - [TestCase(null, ExpectedResult = null)] - public string Test_Reverse(string text) + finally { - var result = text.Reverse(); - - return result; + CultureInfo.DefaultThreadCurrentCulture = previousCulture; } + } - [TestCase("a-b-c-d-e", "-", StringSplitOptions.None, ExpectedResult = "a,b,c,d,e")] - [TestCase("a-b[c]d=e", "-[]=", StringSplitOptions.None, ExpectedResult = "a,b,c,d,e")] - [TestCase("a-b--d-e", "-", StringSplitOptions.RemoveEmptyEntries, ExpectedResult = "a,b,d,e")] - [TestCase("a-b[]d=e", "-[]=", StringSplitOptions.RemoveEmptyEntries, ExpectedResult = "a,b,d,e")] - [TestCase("a-b[]d=e", "-[]=", StringSplitOptions.None, ExpectedResult = "a,b,,d,e")] - public string Test_SplitText(string text, string delimiters, StringSplitOptions options) - { - var result = text.SplitText(delimiters, options); + [Theory] + // GB + [InlineData("0", "en-gb", true)] + [InlineData("1", "en-gb", true)] + [InlineData("-1", "en-gb", true)] + [InlineData("+1", "en-gb", true)] + [InlineData("123.72", "en-gb", true)] + [InlineData("-123.72", "en-gb", true)] + [InlineData("+123.72", "en-gb", true)] + [InlineData("3,123.451", "en-gb", true)] + [InlineData("-3,123.451", "en-gb", true)] + [InlineData("+3,123.451", "en-gb", true)] + [InlineData("3412123.76543", "en-gb", true)] + [InlineData("-3412123.76543", "en-gb", true)] + [InlineData("+3412123.76543", "en-gb", true)] + [InlineData("7,034.989", "en-gb", true)] + [InlineData("-7,034.989", "en-gb", true)] + [InlineData("+7,034.989", "en-gb", true)] + // DE + [InlineData("3,123.451", "de-DE", false)] + [InlineData("3.123,451", "de-DE", true)] + public void Test_IsValidNumber(string text, string cultureInfoName, bool expectedResult) + { + var cultureInfo = CultureInfo.GetCultureInfo(cultureInfoName); - return string.Join(",", result); - } + // Act + var result = text.IsValidNumber(cultureInfo); - [TestCase("a-b-c-d-e", "-", StringSplitOptions.None, SplitDelimiterType.Any, ExpectedResult = "a,b,c,d,e")] - [TestCase("a-b[c]d=e", "-[]=", StringSplitOptions.None, SplitDelimiterType.Any, ExpectedResult = "a,b,c,d,e")] - [TestCase("a-b--d-e", "-", StringSplitOptions.RemoveEmptyEntries, SplitDelimiterType.Any, ExpectedResult = "a,b,d,e")] - [TestCase("a-b[]d=e", "-[]=", StringSplitOptions.RemoveEmptyEntries, SplitDelimiterType.Any, ExpectedResult = "a,b,d,e")] - [TestCase("a-b[]d=e", "-[]=", StringSplitOptions.None, SplitDelimiterType.Any, ExpectedResult = "a,b,,d,e")] - [TestCase("a-b-c-d-e", "-", StringSplitOptions.None, SplitDelimiterType.All, ExpectedResult = "a,b,c,d,e")] - [TestCase("a-b--d-e", "--", StringSplitOptions.RemoveEmptyEntries, SplitDelimiterType.All, ExpectedResult = "a-b,d-e")] - [TestCase("a-b----d-e", "--", StringSplitOptions.None, SplitDelimiterType.All, ExpectedResult = "a-b,,d-e")] - [TestCase("a-b[]d=e", "[]", StringSplitOptions.RemoveEmptyEntries, SplitDelimiterType.All, ExpectedResult = "a-b,d=e")] - public string Test_SplitText_DelimiterType(string text, string delimiters, StringSplitOptions options, SplitDelimiterType delimiterType) - { - var result = text.SplitText(delimiters, options, delimiterType); + // Assert + result.Should().Be(expectedResult); + } - return string.Join(",", result); - } + [Theory] + [InlineData("hello world", "dlrow olleh")] + [InlineData("12345", "54321")] + [InlineData("abcba", "abcba")] + [InlineData("", "")] + [InlineData(null, null)] + public void Test_Reverse(string text, string expectedResult) + { + var result = text.Reverse(); - [Test] - public void Test_SplitText_InvalidDelimiterType() - { - // Arrange - var text = "a,b,c"; - var delimiters = ","; + // Assert + result.Should().Be(expectedResult); + } - // Act - var ex = Assert.Throws( - () => text.SplitText(delimiters, StringSplitOptions.None, (SplitDelimiterType) int.MaxValue) - ); + [Theory] + [InlineData("a-b-c-d-e", "-", StringSplitOptions.None, "a,b,c,d,e")] + [InlineData("a-b[c]d=e", "-[]=", StringSplitOptions.None, "a,b,c,d,e")] + [InlineData("a-b--d-e", "-", StringSplitOptions.RemoveEmptyEntries, "a,b,d,e")] + [InlineData("a-b[]d=e", "-[]=", StringSplitOptions.RemoveEmptyEntries, "a,b,d,e")] + [InlineData("a-b[]d=e", "-[]=", StringSplitOptions.None, "a,b,,d,e")] + public void Test_SplitText(string text, string delimiters, StringSplitOptions options, string expectedResult) + { + var result = text.SplitText(delimiters, options); - // Assert - ex.ShouldNotBeNull(); - ex.ParamName.ShouldBe("delimiterType"); - ex.Message.ShouldContain(nameof(SplitDelimiterType.Any)); - ex.Message.ShouldContain(nameof(SplitDelimiterType.All)); - } + // Assert + string.Join(",", result).Should().Be(expectedResult); + } - [TestCase("a-b-c-d-e", "-", StringSplitOptions.None, ExpectedResult = "a,b,c,d,e")] - [TestCase("a-b[c]d-e", "-", StringSplitOptions.None, ExpectedResult = "a,b[c]d,e")] - [TestCase("a-b--d-e", "-", StringSplitOptions.RemoveEmptyEntries, ExpectedResult = "a,b,d,e")] - [TestCase("a-b[]d=e", "[]", StringSplitOptions.RemoveEmptyEntries, ExpectedResult = "a-b,d=e")] - [TestCase("a-b//d=e", "/", StringSplitOptions.None, ExpectedResult = "a-b,,d=e")] - [TestCase("a-b//d=e", "/", StringSplitOptions.RemoveEmptyEntries, ExpectedResult = "a-b,d=e")] - public string Test_SplitByText(string text, string delimiters, StringSplitOptions options) - { - var result = text.SplitByText(delimiters, options); + [Theory] + [InlineData("a-b-c-d-e", "-", StringSplitOptions.None, SplitDelimiterType.Any, "a,b,c,d,e")] + [InlineData("a-b[c]d=e", "-[]=", StringSplitOptions.None, SplitDelimiterType.Any, "a,b,c,d,e")] + [InlineData("a-b--d-e", "-", StringSplitOptions.RemoveEmptyEntries, SplitDelimiterType.Any, "a,b,d,e")] + [InlineData("a-b[]d=e", "-[]=", StringSplitOptions.RemoveEmptyEntries, SplitDelimiterType.Any, "a,b,d,e")] + [InlineData("a-b[]d=e", "-[]=", StringSplitOptions.None, SplitDelimiterType.Any, "a,b,,d,e")] + [InlineData("a-b-c-d-e", "-", StringSplitOptions.None, SplitDelimiterType.All, "a,b,c,d,e")] + [InlineData("a-b--d-e", "--", StringSplitOptions.RemoveEmptyEntries, SplitDelimiterType.All, "a-b,d-e")] + [InlineData("a-b----d-e", "--", StringSplitOptions.None, SplitDelimiterType.All, "a-b,,d-e")] + [InlineData("a-b[]d=e", "[]", StringSplitOptions.RemoveEmptyEntries, SplitDelimiterType.All, "a-b,d=e")] + public void Test_SplitText_DelimiterType(string text, string delimiters, StringSplitOptions options, SplitDelimiterType delimiterType, string expectedResult) + { + var result = text.SplitText(delimiters, options, delimiterType); - return string.Join(",", result); - } + // Assert + string.Join(",", result).Should().Be(expectedResult); + } - [TestCase("Line 1/Line 2//Line 4", StringSplitOptions.None, StringComparison.CurrentCulture, ExpectedResult = "Line 1/Line 2//Line 4")] - [TestCase("Line 1/Line 2//Line 4", StringSplitOptions.RemoveEmptyEntries, StringComparison.CurrentCulture, ExpectedResult = "Line 1/Line 2/Line 4")] - [TestCase("Line 1///Line 2//Line 4/", StringSplitOptions.None, StringComparison.CurrentCulture, ExpectedResult = "Line 1///Line 2//Line 4")] - [TestCase("Line 1/Line 2//Line 4", StringSplitOptions.RemoveEmptyEntries, StringComparison.CurrentCulture, ExpectedResult = "Line 1/Line 2/Line 4")] - public string Test_SplitByText_ComplexDelimiter(string text, StringSplitOptions options, StringComparison comparison) - { - var delimiters = Environment.NewLine; + [Fact] + public void Test_SplitText_InvalidDelimiterType() + { + // Arrange + var text = "a,b,c"; + var delimiters = ","; + + // Act + var ex = Assert.Throws( + () => text.SplitText(delimiters, StringSplitOptions.None, (SplitDelimiterType) int.MaxValue) + ); + + // Assert + ex.Should().NotBeNull(); + ex.ParamName.Should().Be("delimiterType"); + ex.Message.Should().ContainAll(Enum.GetValues().Select(x => x.ToString())); + } - var adjustedText = string.Join(Environment.NewLine, text.Split('/')); + [Theory] + [InlineData("a-b-c-d-e", "-", StringSplitOptions.None, "a,b,c,d,e")] + [InlineData("a-b[c]d-e", "-", StringSplitOptions.None, "a,b[c]d,e")] + [InlineData("a-b--d-e", "-", StringSplitOptions.RemoveEmptyEntries, "a,b,d,e")] + [InlineData("a-b[]d=e", "[]", StringSplitOptions.RemoveEmptyEntries, "a-b,d=e")] + [InlineData("a-b//d=e", "/", StringSplitOptions.None, "a-b,,d=e")] + [InlineData("a-b//d=e", "/", StringSplitOptions.RemoveEmptyEntries, "a-b,d=e")] + public void Test_SplitByText(string text, string delimiters, StringSplitOptions options, string expectedResult) + { + var result = text.SplitByText(delimiters, options); - var lines = adjustedText.SplitByText(delimiters, options, comparison); + // Assert + string.Join(",", result).Should().Be(expectedResult); + } - return string.Join("/", lines); - } + [Theory] + [InlineData("Line 1/Line 2//Line 4", StringSplitOptions.None, StringComparison.CurrentCulture, "Line 1/Line 2//Line 4")] + [InlineData("Line 1/Line 2//Line 4", StringSplitOptions.RemoveEmptyEntries, StringComparison.CurrentCulture, "Line 1/Line 2/Line 4")] + [InlineData("Line 1///Line 2//Line 4/", StringSplitOptions.None, StringComparison.CurrentCulture, "Line 1///Line 2//Line 4")] + [InlineData("Line 1/Line 2//Line 4", StringSplitOptions.RemoveEmptyEntries, StringComparison.CurrentCulture, "Line 1/Line 2/Line 4")] + public void Test_SplitByText_ComplexDelimiter(string text, StringSplitOptions options, StringComparison comparison, string expectedResult) + { + var delimiters = Environment.NewLine; - [TestCase("a", "b", "c", ExpectedResult = "a")] - [TestCase("a", null, null, ExpectedResult = "a")] - [TestCase(null, "b", "c", ExpectedResult = "b")] - [TestCase(null, null, "c", ExpectedResult = "c")] - [TestCase(null, null, null, ExpectedResult = null)] - [TestCase("a", "b", "c", ExpectedResult = "a")] - [TestCase("a", "", "", ExpectedResult = "a")] - [TestCase("", "b", "c", ExpectedResult = "")] - [TestCase("", "", "c", ExpectedResult = "")] - [TestCase("", "", "", ExpectedResult = "")] - - public string Test_CoalesceNull(string a, string b, string c) - { - var result = StringExtensions.CoalesceNull(a, b, c); + var adjustedText = string.Join(Environment.NewLine, text.Split('/')); - return result; - } + // Act + var lines = adjustedText.SplitByText(delimiters, options, comparison); - [TestCase("a", "b", "c", ExpectedResult = "a")] - [TestCase("a", null, null, ExpectedResult = "a")] - [TestCase(null, "b", "c", ExpectedResult = "b")] - [TestCase(null, null, "c", ExpectedResult = "c")] - [TestCase(null, null, null, ExpectedResult = null)] - [TestCase("a", "b", "c", ExpectedResult = "a")] - [TestCase("a", "", "", ExpectedResult = "a")] - [TestCase("", "b", "c", ExpectedResult = "b")] - [TestCase("", "", "c", ExpectedResult = "c")] - [TestCase("", "", "", ExpectedResult = null)] - - public string Test_CoalesceNullOrEmpty(string a, string b, string c) - { - var result = StringExtensions.CoalesceNullOrEmpty(a, b, c); + // Assert + string.Join("/", lines).Should().Be(expectedResult); + } - return result; - } + [Theory] + [InlineData("a", "b", "c", "a")] + [InlineData("a", null, null, "a")] + [InlineData(null, "b", "c", "b")] + [InlineData(null, null, "c", "c")] + [InlineData(null, null, null, null)] + [InlineData("a", "b", "c", "a")] + [InlineData("a", "", "", "a")] + [InlineData("", "b", "c", "")] + [InlineData("", "", "c", "")] + [InlineData("", "", "", "")] + public void Test_CoalesceNull(string a, string b, string c, string expectedResult) + { + var result = StringExtensions.CoalesceNull(a, b, c); - [TestCase("a", "b", "c", ExpectedResult = "a")] - [TestCase(" ", "b", "c", ExpectedResult = "b")] - [TestCase(" ", " ", "c", ExpectedResult = "c")] - [TestCase(" ", " ", null, ExpectedResult = null)] + // Assert + result.Should().Be(expectedResult); + } - public string Test_CoalesceNullOrWhitespace(string a, string b, string c) - { - var result = StringExtensions.CoalesceNullOrWhitespace(a, b, c); + [Theory] + [InlineData("a", "b", "c", "a")] + [InlineData("a", null, null, "a")] + [InlineData(null, "b", "c", "b")] + [InlineData(null, null, "c", "c")] + [InlineData(null, null, null, null)] + [InlineData("a", "b", "c", "a")] + [InlineData("a", "", "", "a")] + [InlineData("", "b", "c", "b")] + [InlineData("", "", "c", "c")] + [InlineData("", "", "", null)] + public void Test_CoalesceNullOrEmpty(string a, string b, string c, string expectedResult) + { + var result = StringExtensions.CoalesceNullOrEmpty(a, b, c); - return result; - } + // Assert + result.Should().Be(expectedResult); + } - [TestCase(null, null, null)] - [TestCase("", null, "")] - [TestCase("TwoWords", null, "Two Words")] - [TestCase("ThreeWordsTogether", null, "Three Words Together")] - [TestCase("pascalCase", null, "pascal Case")] - [TestCase("Already Spaced", null, "Already Spaced")] - [TestCase("AnEntireSentenceSquashedTogetherIntoOneSingleWord", null, "An Entire Sentence Squashed Together Into One Single Word")] - [TestCase("IsITVDramaBetterThanBBCDrama", null, "Is ITV Drama Better Than BBC Drama")] - [TestCase("IsTheHoLAnOutdatedInstitution", null, "Is The Ho L An Outdated Institution")] - [TestCase("IsTheHoLAnOutdatedInstitution", "HoL", "Is The HoL An Outdated Institution")] - [TestCase("VirusesLikeH1N1AndH5N1WereWarningsForThePanDemicToCome", null, "Viruses Like H1N1 And H5N1 Were Warnings For The Pan Demic To Come")] - [TestCase("VirusesLikeH1N1AndH5N1WereWarningsForThePanDemicToCome", "H1N1|H5N1|PanDemic", "Viruses Like H1N1 And H5N1 Were Warnings For The PanDemic To Come")] - public void Wordify_Tests(string text, string preservedWordsText, string expected) - { - // Arrange - var preservedWords = preservedWordsText? - .Split("|") - .ToArray(); + [Theory] + [InlineData("a", "b", "c", "a")] + [InlineData(" ", "b", "c", "b")] + [InlineData(" ", " ", "c", "c")] + [InlineData(" ", " ", null, null)] + public void Test_CoalesceNullOrWhitespace(string a, string b, string c, string expectedResult) + { + var result = StringExtensions.CoalesceNullOrWhitespace(a, b, c); - // Act - var result = text.Wordify(preservedWords); + // Assert + result.Should().Be(expectedResult); + } - // Assert - result.ShouldBe(expected); - } + [Theory] + [InlineData(null, null, null)] + [InlineData("", null, "")] + [InlineData("TwoWords", null, "Two Words")] + [InlineData("ThreeWordsTogether", null, "Three Words Together")] + [InlineData("pascalCase", null, "pascal Case")] + [InlineData("Already Spaced", null, "Already Spaced")] + [InlineData("AnEntireSentenceSquashedTogetherIntoOneSingleWord", null, "An Entire Sentence Squashed Together Into One Single Word")] + [InlineData("IsITVDramaBetterThanBBCDrama", null, "Is ITV Drama Better Than BBC Drama")] + [InlineData("IsTheHoLAnOutdatedInstitution", null, "Is The Ho L An Outdated Institution")] + [InlineData("IsTheHoLAnOutdatedInstitution", "HoL", "Is The HoL An Outdated Institution")] + [InlineData("VirusesLikeH1N1AndH5N1WereWarningsForThePanDemicToCome", null, "Viruses Like H1N1 And H5N1 Were Warnings For The Pan Demic To Come")] + [InlineData("VirusesLikeH1N1AndH5N1WereWarningsForThePanDemicToCome", "H1N1|H5N1|PanDemic", "Viruses Like H1N1 And H5N1 Were Warnings For The PanDemic To Come")] + public void Wordify_Tests(string text, string preservedWordsText, string expectedResult) + { + // Arrange + var preservedWords = preservedWordsText? + .Split("|") + .ToArray(); + + // Act + var result = text.Wordify(preservedWords); + + // Assert + result.Should().Be(expectedResult); } }