Skip to content

Commit 66fa1c7

Browse files
committed
Added some more UString methods. Updated to 0.8.3.
1 parent d31d2d0 commit 66fa1c7

5 files changed

Lines changed: 170 additions & 5 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
namespace UnicodeHelper
2+
{
3+
[TestClass]
4+
public class UStringExtensionsTests
5+
{
6+
#region GetDotNetString tests
7+
private static IEnumerable<object[]> GetDotNetStringIndexExceptionTestData =>
8+
[
9+
["", -1, typeof(ArgumentOutOfRangeException)],
10+
["", 1, typeof(ArgumentOutOfRangeException)],
11+
["This", 5, typeof(ArgumentOutOfRangeException)],
12+
["This is 😮", 10, typeof(ArgumentOutOfRangeException)],
13+
["😁🤔😮", 4, typeof(ArgumentOutOfRangeException)]
14+
];
15+
16+
[TestMethod]
17+
[DynamicData(nameof(GetDotNetStringIndexExceptionTestData))]
18+
public void GetDotNetStringIndex_InvalidParameters(string testString, int index,
19+
Type expectedExceptionType)
20+
{
21+
UString us = new(testString);
22+
Assert.That.ThrowsException(expectedExceptionType, () => us.GetDotNetStringIndex(index));
23+
}
24+
25+
public static IEnumerable<object?[]> GetDotNetStringIndexTestData =>
26+
[
27+
["", 0, 0],
28+
["This is a string!", 0, 0],
29+
["This is a string!", 12, 12],
30+
["This is a string!", 17, 17],
31+
["العربية", 3, 3],
32+
["العربية", 7, 7],
33+
["😁🤔😮", 0, 0],
34+
["😁🤔😮", 1, 2],
35+
["😁🤔😮", 2, 4],
36+
["😁🤔😮", 3, 6],
37+
["This is 😮", 0, 0],
38+
["This is 😮", 8, 8],
39+
["This is 😮", 9, 10],
40+
];
41+
42+
[TestMethod]
43+
[DynamicData(nameof(GetDotNetStringIndexTestData))]
44+
public void GetDotNetStringIndex(string testString, int index, int expectedIndex)
45+
{
46+
UString us = new UString(testString);
47+
Assert.AreEqual(expectedIndex, us.GetDotNetStringIndex(index));
48+
}
49+
#endregion
50+
}
51+
}

UnicodeHelper.Tests/UStringTests.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,66 @@ public void LastIndexOf_UCodepoint(string testString, UCodepoint codePoint,
354354
}
355355
#endregion
356356

357+
#region StartsWith_UCodepoint tests
358+
private static IEnumerable<object[]> UCodepointStartsWithTestData =>
359+
[
360+
["", (UCodepoint)'A', true, false],
361+
["", (UCodepoint)'A', false, false],
362+
["This test!", (UCodepoint)'h', false, false],
363+
["This test!", (UCodepoint)'T', false, true],
364+
["This test!", (UCodepoint)'T', true, true],
365+
["This test!", (UCodepoint)'t', false, false],
366+
["This test!", (UCodepoint)'t', true, true],
367+
["العربية", (UCodepoint)'ا', false, true],
368+
["\U00010570\U00010597", UCodepoint.ReadFromStr("\U00010570", 0), false, true], // VITHKUQI letters
369+
["\U00010570\U00010597", UCodepoint.ReadFromStr("\U00010570", 0), true, true], // VITHKUQI letters
370+
["\U00010570\U00010597", UCodepoint.ReadFromStr("\U00010597", 0), false, false], // VITHKUQI letters
371+
["\U00010570\U00010597", UCodepoint.ReadFromStr("\U00010597", 0), true, true], // VITHKUQI letters
372+
];
373+
374+
[TestMethod]
375+
[DynamicData(nameof(UCodepointStartsWithTestData))]
376+
public void StartsWith_UCodepoint(string testString, UCodepoint codePoint, bool ignoreCase, bool expectedResult)
377+
{
378+
UString us = new(testString);
379+
Assert.AreEqual(expectedResult, us.StartsWith(codePoint, ignoreCase));
380+
381+
// Test making sure that a substring results in the correct result
382+
us = CreateTestSubstring(testString);
383+
Assert.AreEqual(expectedResult, us.StartsWith(codePoint, ignoreCase));
384+
}
385+
#endregion
386+
387+
#region EndsWith_UCodepoint tests
388+
private static IEnumerable<object[]> UCodepointEndsWithTestData =>
389+
[
390+
["", (UCodepoint)'A', true, false],
391+
["", (UCodepoint)'A', false, false],
392+
["This test", (UCodepoint)'s', false, false],
393+
["This test", (UCodepoint)'t', false, true],
394+
["This test", (UCodepoint)'t', true, true],
395+
["This test", (UCodepoint)'T', false, false],
396+
["This test", (UCodepoint)'T', true, true],
397+
["العربية", (UCodepoint)'ة', false, true],
398+
["\U00010570\U00010597", UCodepoint.ReadFromStr("\U00010597", 0), false, true], // VITHKUQI letters
399+
["\U00010570\U00010597", UCodepoint.ReadFromStr("\U00010597", 0), true, true], // VITHKUQI letters
400+
["\U00010570\U00010597", UCodepoint.ReadFromStr("\U00010570", 0), false, false], // VITHKUQI letters
401+
["\U00010570\U00010597", UCodepoint.ReadFromStr("\U00010570", 0), true, true], // VITHKUQI letters
402+
];
403+
404+
[TestMethod]
405+
[DynamicData(nameof(UCodepointEndsWithTestData))]
406+
public void EndsWith_UCodepoint(string testString, UCodepoint codePoint, bool ignoreCase, bool expectedResult)
407+
{
408+
UString us = new(testString);
409+
Assert.AreEqual(expectedResult, us.EndsWith(codePoint, ignoreCase));
410+
411+
// Test making sure that a substring results in the correct result
412+
us = CreateTestSubstring(testString);
413+
Assert.AreEqual(expectedResult, us.EndsWith(codePoint, ignoreCase));
414+
}
415+
#endregion
416+
357417
#region IsNullOrEmpty tests
358418
private static IEnumerable<object?[]> IsNullOrEmptyTestData =>
359419
[

UnicodeHelper/UString.cs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -531,10 +531,20 @@ public int LastIndexOf(UString value, int startIndex, int count)
531531
throw new NotImplementedException();
532532
}
533533

534+
/// <summary>
535+
/// Determines whether the beginning of this Unicode string matches the specified value.
536+
/// </summary>
534537
public bool StartsWith(UCodepoint value, bool ignoreCase = false)
535538
{
536-
// TODO: Write tests for this method
537-
throw new NotImplementedException();
539+
if (Length == 0)
540+
return false;
541+
542+
UCodepoint start = _codepoints[_startIndex];
543+
if (start == value)
544+
return true;
545+
546+
return ignoreCase &&
547+
(UCodepoint.ToLower(start) == value || UCodepoint.ToUpper(start) == value);
538548
}
539549

540550
public bool StartsWith(UString value, bool ignoreCase = false)
@@ -543,10 +553,20 @@ public bool StartsWith(UString value, bool ignoreCase = false)
543553
throw new NotImplementedException();
544554
}
545555

556+
/// <summary>
557+
/// Determines whether the end of this Unicode string matches the specified value.
558+
/// </summary>
546559
public bool EndsWith(UCodepoint value, bool ignoreCase = false)
547560
{
548-
// TODO: Write tests for this method
549-
throw new NotImplementedException();
561+
if (Length == 0)
562+
return false;
563+
564+
UCodepoint end = _codepoints[_startIndex + Length - 1];
565+
if (end == value)
566+
return true;
567+
568+
return ignoreCase &&
569+
(UCodepoint.ToLower(end) == value || UCodepoint.ToUpper(end) == value);
550570
}
551571

552572
public bool EndsWith(UString value, bool ignoreCase = false)

UnicodeHelper/UStringExtensions.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
3+
namespace UnicodeHelper
4+
{
5+
/// <summary>
6+
/// Provides extension methods for the <see cref="UString"/> class, enabling additional functionality
7+
/// such as converting indices and lengths between Unicode strings and .Net strings.
8+
/// </summary>
9+
public static class UStringExtensions
10+
{
11+
/// <summary>
12+
/// Used to convert an index in this UString to an index in the equivalent .Net string
13+
/// </summary>
14+
public static int GetDotNetStringIndex(this UString ustr, int index)
15+
{
16+
if (index < 0)
17+
throw new ArgumentOutOfRangeException(nameof(index), "Index cannot be negative.");
18+
if (index > ustr.Length)
19+
throw new ArgumentOutOfRangeException(nameof(index), "Index cannot be greater than the length.");
20+
21+
if (index == 0)
22+
return 0;
23+
24+
if (index == ustr.Length)
25+
return ustr.CharLength;
26+
27+
int dotNetStringIndex = 0;
28+
for (int i = 0; i < index; i++)
29+
dotNetStringIndex += ustr[i] <= 0xffff ? 1 : 2;
30+
31+
return dotNetStringIndex;
32+
}
33+
}
34+
}

UnicodeHelper/UnicodeHelper.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<RunAnalyzersDuringLiveAnalysis>False</RunAnalyzersDuringLiveAnalysis>
88
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
99
<Title>Unicode Helper</Title>
10-
<Version>0.8.2</Version>
10+
<Version>0.8.3</Version>
1111
<Authors>FoolRunning</Authors>
1212
<Description>.Net library to get information about Unicode codepoints and to better handle the upper planes (1-16) of Unicode.</Description>
1313
<Copyright>© 2025 Tim Steenwyk</Copyright>

0 commit comments

Comments
 (0)