Skip to content

Commit 304bb93

Browse files
Added more test coverage and corrected issue with large enums.
1 parent c85db01 commit 304bb93

3 files changed

Lines changed: 171 additions & 18 deletions

File tree

Source/EnumValue.cs

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -319,33 +319,40 @@ public EnumValueCaseIgnored(StringSegment value)
319319
/// <summary>
320320
/// Compares an EnumValueCaseIgnored and EnumValue for enum inequality.
321321
/// </summary>
322-
public static bool operator !=(EnumValueCaseIgnored<TEnum> left, EnumValue<TEnum> right) => !left.Value.Equals(right.Value);
322+
public static bool operator !=(EnumValueCaseIgnored<TEnum> left, EnumValue<TEnum> right)
323+
=> !left.Value.Equals(right.Value);
323324

324325
/// <inheritdoc cref="EnumValue{TEnum}.Equals(EnumValue{TEnum})"/>
325-
public bool Equals(EnumValueCaseIgnored<TEnum> other) => Value.Equals(other.Value);
326+
public bool Equals(EnumValueCaseIgnored<TEnum> other)
327+
=> Value.Equals(other.Value);
326328

327329
/// <summary>
328330
/// Compares two EnumValueCaseIgnored for enum equality.
329331
/// </summary>
330-
public static bool operator ==(EnumValueCaseIgnored<TEnum> left, EnumValueCaseIgnored<TEnum> right) => left.Value.Equals(right.Value);
332+
public static bool operator ==(EnumValueCaseIgnored<TEnum> left, EnumValueCaseIgnored<TEnum> right)
333+
=> left.Value.Equals(right.Value);
331334

332335
/// <summary>
333336
/// Compares two EnumValueCaseIgnored for enum inequality.
334337
/// </summary>
335-
public static bool operator !=(EnumValueCaseIgnored<TEnum> left, EnumValueCaseIgnored<TEnum> right) => !left.Value.Equals(right.Value);
338+
public static bool operator !=(EnumValueCaseIgnored<TEnum> left, EnumValueCaseIgnored<TEnum> right)
339+
=> !left.Value.Equals(right.Value);
336340

337341
/// <inheritdoc cref="EnumValue{TEnum}.Equals(TEnum)"/>
338-
public bool Equals(TEnum other) => Value.Equals(other);
342+
public bool Equals(TEnum other)
343+
=> Value.Equals(other);
339344

340345
/// <summary>
341346
/// Compares an EnumValueCaseIgnored and an enum value for enum equality.
342347
/// </summary>
343-
public static bool operator ==(EnumValueCaseIgnored<TEnum> left, TEnum right) => left.Value.Equals(right);
348+
public static bool operator ==(EnumValueCaseIgnored<TEnum> left, TEnum right)
349+
=> left.Value.Equals(right);
344350

345351
/// <summary>
346352
/// Compares an EnumValueCaseIgnored and an enum value for enum inequality.
347353
/// </summary>
348-
public static bool operator !=(EnumValueCaseIgnored<TEnum> left, TEnum right) => !left.Value.Equals(right);
354+
public static bool operator !=(EnumValueCaseIgnored<TEnum> left, TEnum right)
355+
=> !left.Value.Equals(right);
349356

350357
/// <inheritdoc />
351358
public override bool Equals(object? obj)
@@ -354,28 +361,33 @@ public override bool Equals(object? obj)
354361
|| obj is EnumValue<TEnum> v2 && Value.Equals(v2.Value);
355362

356363
/// <inheritdoc />
357-
public override int GetHashCode() => Value.GetHashCode();
364+
public override int GetHashCode()
365+
=> Value.GetHashCode();
358366

359367
/// <summary>
360368
/// Implicitly converts an EnumValue to an EnumValueCaseInsensitive.
361369
/// Before conversion they are already equivalent.
362370
/// </summary>
363-
public static implicit operator EnumValueCaseIgnored<TEnum>(EnumValue<TEnum> value) => new(value.Value);
371+
public static implicit operator EnumValueCaseIgnored<TEnum>(EnumValue<TEnum> value)
372+
=> new(value.Value);
364373

365374
/// <summary>
366375
/// Implicitly returns the actual enum contained by the EnumValueCaseIgnored.
367376
/// </summary>
368-
public static implicit operator TEnum(EnumValueCaseIgnored<TEnum> value) => value.Value;
377+
public static implicit operator TEnum(EnumValueCaseIgnored<TEnum> value)
378+
=> value.Value;
369379

370380
/// <summary>
371381
/// Implicitly converts an string to an EnumValueCaseIgnored of enum type TEnum.
372382
/// </summary>
373-
public static implicit operator EnumValueCaseIgnored<TEnum>(StringSegment value) => new(value);
383+
public static implicit operator EnumValueCaseIgnored<TEnum>(StringSegment value)
384+
=> new(value);
374385

375386
/// <summary>
376387
/// Implicitly converts an string to an EnumValueCaseIgnored of enum type TEnum.
377388
/// </summary>
378-
public static implicit operator EnumValueCaseIgnored<TEnum>(string value) => new(value);
389+
public static implicit operator EnumValueCaseIgnored<TEnum>(string value)
390+
=> new(value);
379391

380392
private string GetDebuggerDisplay()
381393
{
@@ -465,7 +477,9 @@ public static bool TryParse<TEnum>(StringSegment value, bool ignoreCase, out TEn
465477
if (r is null) goto notFound;
466478
Debug.Assert(r.Length != 0);
467479

468-
var sc = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
480+
var sc = ignoreCase
481+
? StringComparison.OrdinalIgnoreCase
482+
: StringComparison.Ordinal;
469483

470484
if (r.Length > 64)
471485
goto binarySearch;
@@ -511,15 +525,16 @@ public static bool TryParse<TEnum>(StringSegment value, bool ignoreCase, out TEn
511525
return true;
512526
}
513527

514-
span = span.Slice(0, 1);
528+
span = span.Slice(1, 1);
515529
goto search;
516530
}
517531

518532
default:
519533
{
520534
int i = span.Length / 2;
521-
var (Name, Value) = r[i];
522-
switch ((StringSegment.Compare(value, Name, sc) >> 31) | 1)
535+
var (Name, Value) = span[i];
536+
var comparison = StringSegment.Compare(value, Name, sc);
537+
switch (Math.Sign(comparison))
523538
{
524539
case 0:
525540
e = Value;

Source/Open.Text.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<RepositoryUrl>https://github.com/Open-NET-Libraries/Open.Text</RepositoryUrl>
2020
<RepositoryType>git</RepositoryType>
2121
<PackageTags>string, span, enum, readonlyspan, text, format, split, trim, equals, trimmed equals, first, last, preceding, following, stringbuilder, extensions, stringcomparable, spancomparable, stringsegment, splitassegment</PackageTags>
22-
<Version>6.4.0</Version>
22+
<Version>6.4.1</Version>
2323
<PackageReleaseNotes></PackageReleaseNotes>
2424
<PackageLicenseExpression>MIT</PackageLicenseExpression>
2525
<PublishRepositoryUrl>true</PublishRepositoryUrl>

Tests/EnumValueTests.cs

Lines changed: 139 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,91 @@ public enum Greek
4343
None
4444
}
4545

46+
public enum LongEnum
47+
{
48+
In_the_glowing_moonlight_the_winds_caress_and_serenade_the_silent_ocean_waves,
49+
Amidst_the_twinkling_stars_dreams_weave_through_the_dancing_cosmic_ribbon,
50+
As_autumn_leaves_whisper_secrets_winds_carry_them_to_mystic_destinations,
51+
Underneath_the_willow_tree_souls_unite_in_soft_melodies_of_unspoken_love
52+
}
53+
54+
public enum LargeEnum
55+
{
56+
Item001,
57+
Item002,
58+
Item003,
59+
Item004,
60+
Item005,
61+
Item006,
62+
Item007,
63+
Item008,
64+
Item009,
65+
Item010,
66+
Item011,
67+
Item012,
68+
Item013,
69+
Item014,
70+
Item015,
71+
Item016,
72+
Item017,
73+
Item018,
74+
Item019,
75+
Item020,
76+
Item021,
77+
Item022,
78+
Item023,
79+
Item024,
80+
Item025,
81+
Item026,
82+
Item027,
83+
Item028,
84+
Item029,
85+
Item030,
86+
Item031,
87+
Item032,
88+
Item033,
89+
Item034,
90+
Item035,
91+
Item036,
92+
Item037,
93+
Item038,
94+
Item039,
95+
Item040,
96+
Item041,
97+
Item042,
98+
Item043,
99+
Item044,
100+
Item045,
101+
Item046,
102+
Item047,
103+
Item048,
104+
Item049,
105+
Item050,
106+
Item051,
107+
Item052,
108+
Item053,
109+
Item054,
110+
Item055,
111+
Item056,
112+
Item057,
113+
Item058,
114+
Item059,
115+
Item060,
116+
Item061,
117+
Item062,
118+
Item063,
119+
Item064,
120+
Item065
121+
}
122+
46123
public static class EnumValueTests
47124
{
48125
[Fact]
49126
public static void IsIntType()
50127
{
51128
var tInt = typeof(int);
52129
var t = EnumValue<Greek>.UnderlyingType;
53-
Assert.Equal(tInt,t);
130+
Assert.Equal(tInt, t);
54131
}
55132

56133
[Theory]
@@ -133,4 +210,65 @@ static void CheckImplicitCaseIgnored(EnumValueCaseIgnored<Greek> value, Greek ex
133210
Assert.False(value != expected);
134211
Assert.False(value != new EnumValue<Greek>(expected));
135212
}
213+
214+
static void TryParseTestsCore<T>() where T : Enum
215+
{
216+
var values = EnumValue<T>.Values;
217+
foreach (var e in values)
218+
{
219+
string toString = e.GetName();
220+
221+
{
222+
var x = new EnumValue<T>(e);
223+
Assert.Equal(e, x);
224+
Assert.Equal(e.GetHashCode(), x.GetHashCode());
225+
Assert.Equal(e.ToString(), x.ToString());
226+
}
227+
228+
{
229+
var x = new EnumValueCaseIgnored<T>(e);
230+
Assert.Equal(e, x);
231+
Assert.Equal(e.GetHashCode(), x.GetHashCode());
232+
Assert.Equal(e.ToString(), x.ToString());
233+
}
234+
235+
Assert.True(EnumValue.TryParse(toString, out T v));
236+
Assert.Equal(e, v);
237+
Assert.True(EnumValue.TryParse(toString, true, out v));
238+
Assert.Equal(e, v);
239+
Assert.True(EnumValue.TryParse(toString, false, out v));
240+
Assert.Equal(e, v);
241+
242+
string toStringLower = toString.ToLower();
243+
Assert.False(EnumValue.TryParse(toStringLower, out T _));
244+
Assert.True(EnumValue.TryParse(toStringLower, true, out v));
245+
Assert.Equal(e, v);
246+
Assert.False(EnumValue.TryParse(toStringLower, false, out v));
247+
248+
Assert.Equal(default, v);
249+
Assert.False(EnumValue.TryParse("XXX", out v));
250+
Assert.Equal(default, v);
251+
Assert.False(EnumValue.TryParse("XXX", true, out v));
252+
Assert.Equal(default, v);
253+
Assert.False(EnumValue.TryParse("XXX", false, out v));
254+
Assert.Equal(default, v);
255+
}
256+
257+
// Final tests that cover values that don't exist.
258+
Assert.False(EnumValue.TryParse("Item000", out T _));
259+
Assert.False(EnumValue.TryParse("Item100", out T _));
260+
Assert.False(EnumValue.TryParse("Item1000", out T _));
261+
}
262+
263+
[Fact]
264+
public static void TryParseTests()
265+
=> TryParseTestsCore<Greek>();
266+
267+
[Fact]
268+
public static void LongEnumTests()
269+
=> TryParseTestsCore<LongEnum>();
270+
271+
[Fact]
272+
public static void LargeEnumTests()
273+
=> TryParseTestsCore<LargeEnum>();
136274
}

0 commit comments

Comments
 (0)