diff --git a/.editorconfig b/.editorconfig
index b2d7e6f..356a1bb 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,7 +1,7 @@
####################################################################
-# Editor Configuration (Updated 2023-07-26)
+# Editor Configuration (Updated 2025-12-05)
#
-# (c)2023 superdev GmbH
+# (c)2025 superdev GmbH
####################################################################
root = true
@@ -15,7 +15,7 @@ tab_width = 2
indent_style = space
indent_size = 4
tab_width = 4
-end_of_line = crlf
+end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = false
max_line_length = 200
@@ -112,6 +112,7 @@ 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 = false:silent
dotnet_style_namespace_match_folder = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
csharp_style_unused_value_expression_statement_preference = discard_variable:none
@@ -175,4 +176,7 @@ dotnet_diagnostic.IDE0051.severity = warning
dotnet_diagnostic.CS1591.severity = none
# CA1416: Validate platform compatibility
-dotnet_diagnostic.CA1416.severity = suggestion
\ No newline at end of file
+dotnet_diagnostic.CA1416.severity = suggestion
+
+# LocalVariableHidesMember: Local variable hides member
+resharper_local_variable_hides_member_highlighting = none
diff --git a/Diacritics.sln.DotSettings b/Diacritics.sln.DotSettings
new file mode 100644
index 0000000..c60a7bc
--- /dev/null
+++ b/Diacritics.sln.DotSettings
@@ -0,0 +1,7 @@
+
+ True
+ True
+ True
+ True
+ True
+ True
\ No newline at end of file
diff --git a/Diacritics/Diacritics.csproj b/Diacritics/Diacritics.csproj
index 2df07d6..e7584bc 100644
--- a/Diacritics/Diacritics.csproj
+++ b/Diacritics/Diacritics.csproj
@@ -1,9 +1,11 @@
- net462;netstandard1.2;netstandard2.0;netstandard2.1;net7.0;net8.0;net9.0
+ net48;netstandard1.2;netstandard2.0;netstandard2.1;net7.0;net8.0;net9.0
Library
True
+ latest
+ enable
@@ -28,7 +30,6 @@
snupkg
true
true
- True
@@ -40,7 +41,6 @@
true
-
diff --git a/Diacritics/DiacriticsMapper.cs b/Diacritics/DiacriticsMapper.cs
index 992357c..358760b 100644
--- a/Diacritics/DiacriticsMapper.cs
+++ b/Diacritics/DiacriticsMapper.cs
@@ -1,19 +1,20 @@
using System;
using System.Collections;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Diagnostics.CodeAnalysis;
using System.Threading;
using Diacritics.AccentMappings;
using Diacritics.Internals;
+// ReSharper disable ConvertIfStatementToNullCoalescingAssignment
+
namespace Diacritics
{
public class DiacriticsMapper : IDiacriticsMapper
{
#region DiacriticsMapper.Current
- private static Lazy Implementation;
+ private static Lazy Implementation = null!;
static DiacriticsMapper()
{
@@ -43,35 +44,37 @@ public DiacriticsMapper(params IAccentMapping[] mappings)
private static IDictionary ConvertMappings(IAccentMapping[] accentMappings)
{
+ if (accentMappings == null)
+ {
+ throw new ArgumentNullException(nameof(accentMappings));
+ }
+
var all = new Dictionary();
- if (accentMappings != null)
+ foreach (var accentMapping in accentMappings)
{
- foreach (var accentMapping in accentMappings)
+ var mappings = accentMapping.Mapping;
+ foreach (var mapping in mappings)
{
- var mappings = accentMapping.Mapping;
- foreach (var mapping in mappings)
+ if (!all.TryGetValue(mapping.Key, out var mappingReplacement))
{
- if (!all.TryGetValue(mapping.Key, out var mappingReplacement))
+ all[mapping.Key] = mapping.Value;
+ }
+ else
+ {
+ // Merge existing DecomposeTitle and Decompose properties,
+ // unless the current mapping replacement defines them.
+ if (mappingReplacement.DecomposeTitle == null)
{
- all[mapping.Key] = mapping.Value;
+ mappingReplacement.DecomposeTitle = mapping.Value.DecomposeTitle;
}
- else
+
+ if (mappingReplacement.Decompose == null)
{
- // Merge existing DecomposeTitle and Decompose properties,
- // unless the current mapping replacement defines them.
- if (mappingReplacement.DecomposeTitle == null)
- {
- mappingReplacement.DecomposeTitle = mapping.Value.DecomposeTitle;
- }
-
- if (mappingReplacement.Decompose == null)
- {
- mappingReplacement.Decompose = mapping.Value.Decompose;
- }
-
- all[mapping.Key] = mappingReplacement;
+ mappingReplacement.Decompose = mapping.Value.Decompose;
}
+
+ all[mapping.Key] = mappingReplacement;
}
}
}
@@ -90,28 +93,33 @@ IEnumerator IEnumerable.GetEnumerator()
return this.GetEnumerator();
}
- public string RemoveDiacritics(string source)
+ [return: NotNullIfNotNull(nameof(source))]
+ public string? RemoveDiacritics(string? source)
{
return this.RemoveDiacritics(source, options: null);
}
- public string RemoveDiacritics(string source, DiacriticsOptions options)
+ [return: NotNullIfNotNull(nameof(source))]
+ public string? RemoveDiacritics(string? source, DiacriticsOptions? options)
{
return RemoveDiacritics(source, this.diacriticsMappings, options);
}
- public string RemoveDiacritics(string source, IAccentMapping[] mappings)
+ [return: NotNullIfNotNull(nameof(source))]
+ public string? RemoveDiacritics(string? source, IAccentMapping[] mappings)
{
return this.RemoveDiacritics(source, mappings, options: null);
}
- public string RemoveDiacritics(string source, IAccentMapping[] mappings, DiacriticsOptions options)
+ [return: NotNullIfNotNull(nameof(source))]
+ public string? RemoveDiacritics(string? source, IAccentMapping[] mappings, DiacriticsOptions? options)
{
var diacriticsMappings = ConvertMappings(mappings);
return RemoveDiacritics(source, diacriticsMappings, options);
}
- private static string RemoveDiacritics(string source, IDictionary diacriticsMappings, DiacriticsOptions options)
+ [return: NotNullIfNotNull(nameof(source))]
+ private static string? RemoveDiacritics(string? source, IDictionary diacriticsMappings, DiacriticsOptions? options)
{
if (string.IsNullOrWhiteSpace(source))
{
@@ -120,7 +128,8 @@ private static string RemoveDiacritics(string source, IDictionary
- public static string RemoveDiacritics(this string source)
+ [return: NotNullIfNotNull(nameof(source))]
+ public static string? RemoveDiacritics(this string? source)
{
return DiacriticsMapper.Current.RemoveDiacritics(source);
}
///
- public static string RemoveDiacritics(this string source, DiacriticsOptions options)
+ [return: NotNullIfNotNull(nameof(source))]
+ public static string? RemoveDiacritics(this string? source, DiacriticsOptions options)
{
return DiacriticsMapper.Current.RemoveDiacritics(source, options);
}
///
- public static string RemoveDiacritics(this string source, params IAccentMapping[] mappings)
+ [return: NotNullIfNotNull(nameof(source))]
+ public static string? RemoveDiacritics(this string? source, params IAccentMapping[] mappings)
{
return DiacriticsMapper.Current.RemoveDiacritics(source, mappings);
}
///
- public static string RemoveDiacritics(this string source, IAccentMapping[] mappings, DiacriticsOptions options)
+ [return: NotNullIfNotNull(nameof(source))]
+ public static string? RemoveDiacritics(this string? source, IAccentMapping[] mappings, DiacriticsOptions options)
{
return DiacriticsMapper.Current.RemoveDiacritics(source, mappings, options);
}
///
- public static bool HasDiacritics(this string source)
+ public static bool HasDiacritics(this string? source)
{
return DiacriticsMapper.Current.HasDiacritics(source);
}
///
- public static bool HasDiacritics(this string source, DiacriticsOptions options)
+ public static bool HasDiacritics(this string? source, DiacriticsOptions options)
{
return DiacriticsMapper.Current.HasDiacritics(source, options);
}
diff --git a/Diacritics/IDiacriticsMapper.cs b/Diacritics/IDiacriticsMapper.cs
index 8502720..9c5ad89 100644
--- a/Diacritics/IDiacriticsMapper.cs
+++ b/Diacritics/IDiacriticsMapper.cs
@@ -16,21 +16,21 @@ public interface IDiacriticsMapper : IEnumerable.
///
/// The source string.
- string RemoveDiacritics(string source);
+ string? RemoveDiacritics(string? source);
///
/// Removes any diacritical characters from .
///
/// The source string.
/// The options.
- string RemoveDiacritics(string source, DiacriticsOptions options);
+ string? RemoveDiacritics(string? source, DiacriticsOptions? options);
///
/// Removes any diacritical characters from using custom accent mappings.
///
/// The source string.
/// The accent mapping to be used to replace diacritical characters.
- string RemoveDiacritics(string source, IAccentMapping[] mappings);
+ string? RemoveDiacritics(string? source, IAccentMapping[] mappings);
///
/// Removes any diacritical characters from using custom accent mappings.
@@ -38,14 +38,14 @@ public interface IDiacriticsMapper : IEnumerableThe source string.
/// The accent mapping to be used to replace diacritical characters.
/// The options.
- string RemoveDiacritics(string source, IAccentMapping[] mappings, DiacriticsOptions options);
+ string? RemoveDiacritics(string? source, IAccentMapping[] mappings, DiacriticsOptions? options);
///
/// Checks if the given string contains any diacritical characters.
///
/// The source string.
/// true if the source string contains any diacritical characters; otherwise, false.
- bool HasDiacritics(string source);
+ bool HasDiacritics(string? source);
///
/// Checks if the given string contains any diacritical characters.
@@ -53,6 +53,6 @@ public interface IDiacriticsMapper : IEnumerableThe source string.
/// The options.
/// true if the source string contains any diacritical characters; otherwise, false.
- bool HasDiacritics(string source, DiacriticsOptions options);
+ bool HasDiacritics(string? source, DiacriticsOptions? options);
}
}
\ No newline at end of file
diff --git a/Diacritics/Internals/Nullable.cs b/Diacritics/Internals/Nullable.cs
new file mode 100644
index 0000000..8e27d33
--- /dev/null
+++ b/Diacritics/Internals/Nullable.cs
@@ -0,0 +1,64 @@
+#if NET48_OR_GREATER || NETSTANDARD1_2 || NETSTANDARD2_0
+// ReSharper disable once CheckNamespace
+namespace System.Diagnostics.CodeAnalysis
+{
+ /*
+ * Nullable Reference Types (NRT) are a compiler feature introduced with C# 8.
+ * Older target frameworks (.NET Framework 4.8, .NET Standard 2.0 and earlier)
+ * do not provide the nullable-analysis attributes that newer frameworks include.
+ *
+ * These attribute stubs are included only for those older TFMs so the compiler
+ * can emit correct nullability metadata and consumers can benefit from NRT
+ * annotations. They have no runtime behavior and should NOT be included when the
+ * framework already provides them (.NET Core 3.0+, .NET Standard 2.1+, .NET 5+).
+ */
+
+ [ExcludeFromCodeCoverage]
+ [DebuggerNonUserCode]
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ internal sealed class MaybeNullWhenAttribute : Attribute
+ {
+ public bool ReturnValue { get; }
+
+ public MaybeNullWhenAttribute(bool returnValue)
+ {
+ this.ReturnValue = returnValue;
+ }
+ }
+
+ [ExcludeFromCodeCoverage]
+ [DebuggerNonUserCode]
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ internal sealed class NotNullWhenAttribute : Attribute
+ {
+ public bool ReturnValue { get; }
+
+ public NotNullWhenAttribute(bool returnValue)
+ {
+ this.ReturnValue = returnValue;
+ }
+ }
+
+ [ExcludeFromCodeCoverage]
+ [DebuggerNonUserCode]
+ [AttributeUsage(
+ AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue,
+ AllowMultiple = true,
+ Inherited = false
+ )]
+ internal sealed class NotNullIfNotNullAttribute : Attribute
+ {
+ public string ParameterName { get; }
+
+ public NotNullIfNotNullAttribute(string parameterName)
+ {
+ this.ParameterName = parameterName;
+ }
+ }
+
+#if NETSTANDARD1_2
+ [AttributeUsage(AttributeTargets.Class, Inherited = false)]
+ internal sealed class ExcludeFromCodeCoverage : Attribute;
+#endif
+}
+#endif
\ No newline at end of file
diff --git a/Diacritics/Internals/StringBuilderCache.cs b/Diacritics/Internals/StringBuilderCache.cs
index 8b867ee..012a132 100644
--- a/Diacritics/Internals/StringBuilderCache.cs
+++ b/Diacritics/Internals/StringBuilderCache.cs
@@ -17,7 +17,7 @@ internal static class StringBuilderCache
private const int DefaultCapacity = 16;
[ThreadStatic]
- private static StringBuilder CachedInstance;
+ private static StringBuilder? CachedInstance;
///
/// Acquires a cached instance of if one exists otherwise a new instance.
diff --git a/Diacritics/Model/MappingReplacement.cs b/Diacritics/Model/MappingReplacement.cs
index 89035a4..5192f82 100644
--- a/Diacritics/Model/MappingReplacement.cs
+++ b/Diacritics/Model/MappingReplacement.cs
@@ -4,18 +4,18 @@ namespace Diacritics
{
public struct MappingReplacement : IEquatable
{
- public MappingReplacement(string @base, string decompose, string decomposeTitle) : this()
+ public MappingReplacement(string? @base, string? decompose, string? decomposeTitle) : this()
{
this.Base = @base;
this.Decompose = decompose;
this.DecomposeTitle = decomposeTitle;
}
- public string Base { get; set; }
+ public string? Base { get; set; }
- public string Decompose { get; set; }
+ public string? Decompose { get; set; }
- public string DecomposeTitle { get; set; }
+ public string? DecomposeTitle { get; set; }
public static implicit operator MappingReplacement(string value) => new MappingReplacement(value, null, null);
@@ -26,7 +26,7 @@ public bool Equals(MappingReplacement other)
string.Equals(this.DecomposeTitle, other.DecomposeTitle, StringComparison.Ordinal);
}
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
return obj is MappingReplacement other && this.Equals(other);
}
diff --git a/Diacritics/StaticDiacritics.cs b/Diacritics/StaticDiacritics.cs
deleted file mode 100644
index 3f019a2..0000000
--- a/Diacritics/StaticDiacritics.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-using System.Threading;
-
-namespace Diacritics
-{
- [Obsolete("Use DiacriticsMapper instead")]
- public static class StaticDiacritics
- {
- private static Lazy Implementation;
-
- static StaticDiacritics()
- {
- SetDefaultMapper(CreateDefaultDiacriticsMapper);
- }
-
- [Obsolete("Use DiacriticsMapper.Current instead")]
- public static IDiacriticsMapper Current => Implementation.Value;
-
- [Obsolete("Use DiacriticsMapper.SetDefaultMapper instead")]
- public static void SetDefaultMapper(Func factory)
- {
- Implementation = new Lazy(factory, LazyThreadSafetyMode.PublicationOnly);
- }
-
- private static IDiacriticsMapper CreateDefaultDiacriticsMapper()
- {
- return new DefaultDiacriticsMapper();
- }
- }
-}
\ No newline at end of file
diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt
index 090e9d3..7660ff3 100644
--- a/ReleaseNotes.txt
+++ b/ReleaseNotes.txt
@@ -1,3 +1,7 @@
+4.1
+- Support for nullable reference types.
+- Replace StaticDiacritics class with IDiacriticsMapper.Current.
+
4.0
- Use cached StringBuilder instances to improve memory usage and reduce garbage collection pressure.
- Remove unsupported target frameworks, update dependencies, maintenance and cleanup.
diff --git a/Tests/Diacritics.Benchmark/Diacritics.Benchmark.csproj b/Tests/Diacritics.Benchmark/Diacritics.Benchmark.csproj
index 077f3c6..8224d89 100644
--- a/Tests/Diacritics.Benchmark/Diacritics.Benchmark.csproj
+++ b/Tests/Diacritics.Benchmark/Diacritics.Benchmark.csproj
@@ -4,11 +4,12 @@
Exe
net9.0
enable
+ latest
enable
-
+
diff --git a/Tests/Diacritics.Benchmark/RemoveDiacriticsBenchmark.cs b/Tests/Diacritics.Benchmark/RemoveDiacriticsBenchmark.cs
index ed56ecb..3cc90fe 100644
--- a/Tests/Diacritics.Benchmark/RemoveDiacriticsBenchmark.cs
+++ b/Tests/Diacritics.Benchmark/RemoveDiacriticsBenchmark.cs
@@ -14,8 +14,8 @@ public class RemoveDiacriticsBenchmark
private static readonly IResourceLoader ResourceLoader = System.Reflection.ResourceLoader.Current;
private static readonly IDiacriticsMapper DiacriticsMapper = IDiacriticsMapper.Current;
- private string loremIpsum100K;
- private string loremIpsum1M;
+ private string? loremIpsum100K;
+ private string? loremIpsum1M;
[GlobalSetup]
public void Setup()
@@ -25,13 +25,13 @@ public void Setup()
}
[Benchmark]
- public string RemoveDiacritics_100kWords()
+ public string? RemoveDiacritics_100kWords()
{
return DiacriticsMapper.RemoveDiacritics(this.loremIpsum100K);
}
[Benchmark]
- public string RemoveDiacritics_1mWords()
+ public string? RemoveDiacritics_1mWords()
{
return DiacriticsMapper.RemoveDiacritics(this.loremIpsum1M);
}
diff --git a/Tests/Diacritics.Tests/Diacritics.Tests.csproj b/Tests/Diacritics.Tests/Diacritics.Tests.csproj
index 3a5e892..7cc131c 100644
--- a/Tests/Diacritics.Tests/Diacritics.Tests.csproj
+++ b/Tests/Diacritics.Tests/Diacritics.Tests.csproj
@@ -3,6 +3,8 @@
net9.0
false
+ latest
+ enable
@@ -12,8 +14,8 @@
-
-
+
+
diff --git a/Tests/Diacritics.Tests/DiacriticsMapperTests.cs b/Tests/Diacritics.Tests/DiacriticsMapperTests.cs
index 337c989..3b4eeb0 100644
--- a/Tests/Diacritics.Tests/DiacriticsMapperTests.cs
+++ b/Tests/Diacritics.Tests/DiacriticsMapperTests.cs
@@ -1,6 +1,4 @@
-using System;
-using System.Linq;
-using Diacritics.AccentMappings;
+using Diacritics.AccentMappings;
using FluentAssertions;
using Xunit;
@@ -15,14 +13,14 @@ public void ShouldNotRemoveDiacritics_IfNoMappingsAvailable()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper();
- const string InputText = "ètôile";
- const string ExpectedText = "ètôile";
+ const string inputText = "ètôile";
+ const string expectedText = "ètôile";
// Act
- var output = diacriticsMapper.RemoveDiacritics(InputText);
+ var output = diacriticsMapper.RemoveDiacritics(inputText);
// Assert
- output.Should().Be(ExpectedText);
+ output.Should().Be(expectedText);
}
[Fact]
@@ -30,14 +28,14 @@ public void ShouldRemoveDiacritics_WithSingleMapping()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper(new FrenchAccentsMapping());
- const string InputText = "Delémont";
- const string ExpectedText = "Delemont";
+ const string inputText = "Delémont";
+ const string expectedText = "Delemont";
// Act
- var output = diacriticsMapper.RemoveDiacritics(InputText);
+ var output = diacriticsMapper.RemoveDiacritics(inputText);
// Assert
- output.Should().Be(ExpectedText);
+ output.Should().Be(expectedText);
}
[Fact]
@@ -45,14 +43,14 @@ public void ShouldNotRemoveDiacritics_IfTheyAreNotPartOfTheMapping()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper(new FrenchAccentsMapping());
- const string InputText = "ètöile";
- const string ExpectedText = "etöile";
+ const string inputText = "ètöile";
+ const string expectedText = "etöile";
// Act
- var output = diacriticsMapper.RemoveDiacritics(InputText);
+ var output = diacriticsMapper.RemoveDiacritics(inputText);
// Assert
- output.Should().Be(ExpectedText);
+ output.Should().Be(expectedText);
}
[Fact]
@@ -60,14 +58,14 @@ public void ShouldRemoveDiacritics_WithMultipleMappings()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper(new FrenchAccentsMapping(), new GermanAccentsMapping());
- const string InputText = "ètöile";
- const string ExpectedText = "etoile";
+ const string inputText = "ètöile";
+ const string expectedText = "etoile";
// Act
- var output = diacriticsMapper.RemoveDiacritics(InputText);
+ var output = diacriticsMapper.RemoveDiacritics(inputText);
// Assert
- output.Should().Be(ExpectedText);
+ output.Should().Be(expectedText);
}
[Fact]
@@ -75,14 +73,14 @@ public void ShouldRemoveDiacritics_FromUppercaseCharacters()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper(new FrenchAccentsMapping());
- const string InputText = "Ètoilé";
- const string ExpectedText = "Etoile";
+ const string inputText = "Ètoilé";
+ const string expectedText = "Etoile";
// Act
- var output = diacriticsMapper.RemoveDiacritics(InputText);
+ var output = diacriticsMapper.RemoveDiacritics(inputText);
// Assert
- output.Should().Be(ExpectedText);
+ output.Should().Be(expectedText);
}
[Fact]
@@ -90,14 +88,14 @@ public void ShouldRemoveDiacritics_CombinedCedilleDiacritics()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper(new FrenchAccentsMapping());
- const string InputText = "François";
- const string ExpectedText = "Francois";
+ const string inputText = "François";
+ const string expectedText = "Francois";
// Act
- var output = diacriticsMapper.RemoveDiacritics(InputText);
+ var output = diacriticsMapper.RemoveDiacritics(inputText);
// Assert
- output.Should().Be(ExpectedText);
+ output.Should().Be(expectedText);
}
[Fact]
@@ -105,8 +103,8 @@ public void ShouldRemoveEszett()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper(new GermanAccentsMapping());
- const string InputText = "Paßstraße";
- const string ExpectedText = "Passstrasse";
+ const string inputText = "Paßstraße";
+ const string expectedText = "Passstrasse";
var options = new DiacriticsOptions
{
@@ -114,10 +112,10 @@ public void ShouldRemoveEszett()
};
// Act
- var output = diacriticsMapper.RemoveDiacritics(InputText, options);
+ var output = diacriticsMapper.RemoveDiacritics(inputText, options);
// Assert
- output.Should().Be(ExpectedText);
+ output.Should().Be(expectedText);
}
[Fact]
@@ -125,8 +123,8 @@ public void ShouldRemoveUmlaut_Decomposed()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper(new FinnishAccentsMapping(), new GermanAccentsMapping());
- const string InputText = "Gefäß";
- const string ExpectedText = "Gefaess";
+ const string inputText = "Gefäß";
+ const string expectedText = "Gefaess";
var options = new DiacriticsOptions
{
@@ -134,10 +132,10 @@ public void ShouldRemoveUmlaut_Decomposed()
};
// Act
- var output = diacriticsMapper.RemoveDiacritics(InputText, options);
+ var output = diacriticsMapper.RemoveDiacritics(inputText, options);
// Assert
- output.Should().Be(ExpectedText);
+ output.Should().Be(expectedText);
}
[Fact]
@@ -145,8 +143,8 @@ public void ShouldRemoveFirstCharacter_WithSingleMapping_AndDecomposeFalse()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper(new FrenchAccentsMapping());
- const string InputText = "épaule";
- const string ExpectedText = "epaule";
+ const string inputText = "épaule";
+ const string expectedText = "epaule";
var options = new DiacriticsOptions
{
@@ -154,10 +152,10 @@ public void ShouldRemoveFirstCharacter_WithSingleMapping_AndDecomposeFalse()
};
// Act
- var output = diacriticsMapper.RemoveDiacritics(InputText, options);
+ var output = diacriticsMapper.RemoveDiacritics(inputText, options);
// Assert
- output.Should().Be(ExpectedText);
+ output.Should().Be(expectedText);
}
[Fact]
@@ -165,8 +163,8 @@ public void ShouldRemoveFirstCharacter_WithSingleMapping_AndDecomposeTrue()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper(new GermanAccentsMapping());
- const string InputText = "Ärzte";
- const string ExpectedText = "Aerzte";
+ const string inputText = "Ärzte";
+ const string expectedText = "Aerzte";
var options = new DiacriticsOptions
{
@@ -174,10 +172,10 @@ public void ShouldRemoveFirstCharacter_WithSingleMapping_AndDecomposeTrue()
};
// Act
- var output = diacriticsMapper.RemoveDiacritics(InputText, options);
+ var output = diacriticsMapper.RemoveDiacritics(inputText, options);
// Assert
- output.Should().Be(ExpectedText);
+ output.Should().Be(expectedText);
}
[Fact]
@@ -185,8 +183,8 @@ public void ShouldRemoveFirstCharacter_WithMultipleMappings_AndDecomposeFalse()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper(new FrenchAccentsMapping(), new GermanAccentsMapping());
- const string InputText = "épaule";
- const string ExpectedText = "epaule";
+ const string inputText = "épaule";
+ const string expectedText = "epaule";
var options = new DiacriticsOptions
{
@@ -194,10 +192,10 @@ public void ShouldRemoveFirstCharacter_WithMultipleMappings_AndDecomposeFalse()
};
// Act
- var output = diacriticsMapper.RemoveDiacritics(InputText, options);
+ var output = diacriticsMapper.RemoveDiacritics(inputText, options);
// Assert
- output.Should().Be(ExpectedText);
+ output.Should().Be(expectedText);
}
[Fact]
@@ -205,8 +203,8 @@ public void ShouldRemoveFirstCharacter_WithMultipleMappings_AndDecomposeTrue()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper(new FrenchAccentsMapping(), new GermanAccentsMapping());
- const string InputText = "épaule";
- const string ExpectedText = "epaule";
+ const string inputText = "épaule";
+ const string expectedText = "epaule";
var options = new DiacriticsOptions
{
@@ -214,10 +212,10 @@ public void ShouldRemoveFirstCharacter_WithMultipleMappings_AndDecomposeTrue()
};
// Act
- var output = diacriticsMapper.RemoveDiacritics(InputText, options);
+ var output = diacriticsMapper.RemoveDiacritics(inputText, options);
// Assert
- output.Should().Be(ExpectedText);
+ output.Should().Be(expectedText);
}
#endregion
@@ -228,10 +226,10 @@ public void ShouldReturnFalseIfHasNoMappings()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper();
- const string InputText = "ètôile";
+ const string inputText = "ètôile";
// Act
- var output = diacriticsMapper.HasDiacritics(InputText);
+ var output = diacriticsMapper.HasDiacritics(inputText);
// Assert
output.Should().BeFalse();
@@ -242,10 +240,10 @@ public void ShouldReturnFalseIfHasNoDiacritics()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper(new FrenchAccentsMapping());
- const string InputText = "etoile";
+ const string inputText = "etoile";
// Act
- var output = diacriticsMapper.HasDiacritics(InputText);
+ var output = diacriticsMapper.HasDiacritics(inputText);
// Assert
output.Should().BeFalse();
@@ -256,10 +254,10 @@ public void ShouldReturnTrueIfHasDiacritics()
{
// Arrange
IDiacriticsMapper diacriticsMapper = new DiacriticsMapper(new FrenchAccentsMapping());
- const string InputText = "ètôile";
+ const string inputText = "ètôile";
// Act
- var output = diacriticsMapper.HasDiacritics(InputText);
+ var output = diacriticsMapper.HasDiacritics(inputText);
// Assert
output.Should().BeTrue();
diff --git a/Tests/Diacritics.Tests/Extensions/StringExtensionsTests.cs b/Tests/Diacritics.Tests/Extensions/StringExtensionsTests.cs
index c86b0b7..50aa54e 100644
--- a/Tests/Diacritics.Tests/Extensions/StringExtensionsTests.cs
+++ b/Tests/Diacritics.Tests/Extensions/StringExtensionsTests.cs
@@ -31,7 +31,7 @@ public void ShouldCallRemoveDiacriticsOnCustomMapperWhenCallRemoveDiacritics()
[Theory]
[ClassData(typeof(DiacriticsTestData))]
- public void ShouldRemoveDiacritics(string input, (bool, string) expectedOutput)
+ public void ShouldRemoveDiacritics(string? input, (bool, string?) expectedOutput)
{
// Act
var hasDiacritics = input.HasDiacritics();
@@ -42,7 +42,7 @@ public void ShouldRemoveDiacritics(string input, (bool, string) expectedOutput)
hasDiacritics.Should().Be(expectedOutput.Item1);
}
- public class DiacriticsTestData : TheoryData
+ public class DiacriticsTestData : TheoryData
{
public DiacriticsTestData()
{
diff --git a/Tests/Diacritics.Tests/Import/ImportCodeGeneratorTests.cs b/Tests/Diacritics.Tests/Import/ImportCodeGeneratorTests.cs
index 2d368f0..7763695 100644
--- a/Tests/Diacritics.Tests/Import/ImportCodeGeneratorTests.cs
+++ b/Tests/Diacritics.Tests/Import/ImportCodeGeneratorTests.cs
@@ -37,7 +37,7 @@ public async Task GenerateAccentMappings(string languageUrl, string className)
// Generate mapping file
var fileContent = GenerateTemplate(className, mappings);
var filePath = Path.Combine(AccentMappingsFolder, className + ".cs");
- File.WriteAllText(filePath, fileContent);
+ await File.WriteAllTextAsync(filePath, fileContent);
}
internal class ImportUrls : TheoryData
@@ -86,7 +86,7 @@ private static async Task ImportAccentMappingsAsync(string url)
using (var httpClient = new HttpClient())
{
var json = await httpClient.GetStringAsync(url);
- return JsonConvert.DeserializeObject(json);
+ return JsonConvert.DeserializeObject(json)!;
}
}
diff --git a/Tests/Diacritics.Tests/Import/Model/AccentsMapping.cs b/Tests/Diacritics.Tests/Import/Model/AccentsMapping.cs
index 68347f0..0b2ae41 100644
--- a/Tests/Diacritics.Tests/Import/Model/AccentsMapping.cs
+++ b/Tests/Diacritics.Tests/Import/Model/AccentsMapping.cs
@@ -5,8 +5,15 @@ namespace Diacritics.Tests.Import
{
public class AccentsMapping
{
- public Metadata Metadata { get; set; }
+ public AccentsMapping()
+ {
+ this.Data = new List();
+ }
+ [JsonProperty("metadata")]
+ public Metadata? Metadata { get; set; }
+
+ [JsonProperty("data")]
[JsonConverter(typeof(AccentsMappingDataJsonConverter))]
public List Data { get; set; }
}
diff --git a/Tests/Diacritics.Tests/Import/Model/AccentsMappingData.cs b/Tests/Diacritics.Tests/Import/Model/AccentsMappingData.cs
index 6b961a2..f7ba1a6 100644
--- a/Tests/Diacritics.Tests/Import/Model/AccentsMappingData.cs
+++ b/Tests/Diacritics.Tests/Import/Model/AccentsMappingData.cs
@@ -2,17 +2,17 @@
namespace Diacritics.Tests.Import
{
- [DebuggerDisplay("Mapping '{this.Source}' -> '{this.Target}' ({this.Case})")]
+ [DebuggerDisplay("Mapping '{this.Source}' -> '{this.Decompose}' ({this.Case})")]
public class AccentsMappingData
{
- public char Source { get; set; }
+ public char Source { get; init; }
- public string Base { get; set; }
+ public string? Base { get; init; }
- public string Decompose { get; set; }
+ public string? Decompose { get; init; }
- public string DecomposeTitle { get; set; }
+ public string? DecomposeTitle { get; init; }
- public string Case { get; set; }
+ public string? Case { get; init; }
}
}
diff --git a/Tests/Diacritics.Tests/Import/Model/AccentsMappingDataJsonConverter.cs b/Tests/Diacritics.Tests/Import/Model/AccentsMappingDataJsonConverter.cs
index b0058a8..9a530df 100644
--- a/Tests/Diacritics.Tests/Import/Model/AccentsMappingDataJsonConverter.cs
+++ b/Tests/Diacritics.Tests/Import/Model/AccentsMappingDataJsonConverter.cs
@@ -7,10 +7,10 @@ namespace Diacritics.Tests.Import
{
public class AccentsMappingDataJsonConverter : JsonConverter
{
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
var token = JToken.Load(reader);
- var list = Activator.CreateInstance(objectType) as System.Collections.IList;
+ var list = (Activator.CreateInstance(objectType) as System.Collections.IList)!;
//var itemType = objectType.GenericTypeArguments[0];
if (token.Type.ToString() == "Object")
{
@@ -26,7 +26,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
var childName = nameProp[0];
var childValue = ((JProperty)child).Value;
- var @case = childValue["case"].Value();
+ var @case = childValue["case"]?.Value();
//if (@case == "upper")
//{
// continue;
@@ -34,20 +34,20 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
var mapping = childValue["mapping"];
- string @base = null;
- if (mapping["base"] is JToken baseToken)
+ string? @base = null;
+ if (mapping?["base"] is JToken baseToken)
{
@base = baseToken.Value();
}
- string decompose = null;
- string decomposeTitle = null;
- if (mapping["decompose"] is JToken decomposeToken)
+ string? decompose = null;
+ string? decomposeTitle = null;
+ if (mapping?["decompose"] is JToken decomposeToken)
{
decompose = decomposeToken["value"]?.Value();
decomposeTitle = decomposeToken["titleCase"]?.Value();
}
-
+
var accentsMappingData = new AccentsMappingData
{
Source = childName,
@@ -71,6 +71,6 @@ public override bool CanConvert(Type objectType)
}
public override bool CanWrite => false;
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) => throw new NotImplementedException();
+ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) => throw new NotImplementedException();
}
}
diff --git a/Tests/Diacritics.Tests/Import/Model/Metadata.cs b/Tests/Diacritics.Tests/Import/Model/Metadata.cs
index fb8d61e..fdb1fda 100644
--- a/Tests/Diacritics.Tests/Import/Model/Metadata.cs
+++ b/Tests/Diacritics.Tests/Import/Model/Metadata.cs
@@ -5,13 +5,21 @@ namespace Diacritics.Tests.Import
{
public class Metadata
{
- public string Alphabet { get; set; }
+ public Metadata()
+ {
+ this.Continents = new List();
+ }
+
+ [JsonProperty("alphabet")]
+ public string? Alphabet { get; set; }
[JsonProperty("continent")]
public ICollection Continents { get; set; }
- public string Language { get; set; }
+ [JsonProperty("language")]
+ public string? Language { get; set; }
- public string LanguageNative { get; set; }
+ [JsonProperty("languageNative")]
+ public string? LanguageNative { get; set; }
}
}
diff --git a/Tests/Diacritics.Tests/Internals/StringBuilderCacheTests.cs b/Tests/Diacritics.Tests/Internals/StringBuilderCacheTests.cs
index 108f805..3cdf221 100644
--- a/Tests/Diacritics.Tests/Internals/StringBuilderCacheTests.cs
+++ b/Tests/Diacritics.Tests/Internals/StringBuilderCacheTests.cs
@@ -107,7 +107,7 @@ public void Cache_ShouldBeThreadLocal()
stringBuilder1.Append("main");
StringBuilderCache.GetStringAndRelease(stringBuilder1);
- StringBuilder stringBuilder2 = null;
+ StringBuilder? stringBuilder2 = null;
// Act
var thread = new Thread(() =>
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 004ed35..7ca65d2 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -7,7 +7,7 @@
name: $[format('{0}', variables['buildName'])]
pool:
- vmImage: 'windows-2022'
+ vmImage: 'windows-latest'
trigger:
branches:
@@ -25,7 +25,7 @@ variables:
buildPlatform: 'Any CPU'
buildConfiguration: 'Release'
majorVersion: 4
- minorVersion: 0
+ minorVersion: 1
patchVersion: $[counter(format('{0}.{1}', variables.majorVersion, variables.minorVersion), 0)]
${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}:
# Versioning: 1.0.0