11// Licensed to the .NET Foundation under one or more agreements.
22// The .NET Foundation licenses this file to you under the MIT license.
33
4+ using System . Collections . Generic ;
5+ using System . Diagnostics . CodeAnalysis ;
46using Xunit ;
57
68namespace System . SpanTests
@@ -14,17 +16,21 @@ public static void ZeroLengthSequenceEqual()
1416
1517 ReadOnlySpan < int > first = new ReadOnlySpan < int > ( a , 1 , 0 ) ;
1618 ReadOnlySpan < int > second = new ReadOnlySpan < int > ( a , 2 , 0 ) ;
17- bool b = first . SequenceEqual ( second ) ;
18- Assert . True ( b ) ;
19+
20+ Assert . True ( first . SequenceEqual ( second ) ) ;
21+ Assert . True ( first . SequenceEqual ( second , null ) ) ;
22+ Assert . True ( first . SequenceEqual ( second , EqualityComparer < int > . Default ) ) ;
1923 }
2024
2125 [ Fact ]
2226 public static void SameSpanSequenceEqual ( )
2327 {
2428 int [ ] a = { 4 , 5 , 6 } ;
2529 ReadOnlySpan < int > span = new ReadOnlySpan < int > ( a ) ;
26- bool b = span . SequenceEqual ( span ) ;
27- Assert . True ( b ) ;
30+
31+ Assert . True ( span . SequenceEqual ( span ) ) ;
32+ Assert . True ( span . SequenceEqual ( span , null ) ) ;
33+ Assert . True ( span . SequenceEqual ( span , EqualityComparer < int > . Default ) ) ;
2834 }
2935
3036 [ Fact ]
@@ -33,12 +39,17 @@ public static void LengthMismatchSequenceEqual()
3339 int [ ] a = { 4 , 5 , 6 } ;
3440 ReadOnlySpan < int > first = new ReadOnlySpan < int > ( a , 0 , 3 ) ;
3541 ReadOnlySpan < int > second = new ReadOnlySpan < int > ( a , 0 , 2 ) ;
36- bool b = first . SequenceEqual ( second ) ;
37- Assert . False ( b ) ;
42+
43+ Assert . False ( first . SequenceEqual ( second ) ) ;
44+ Assert . False ( first . SequenceEqual ( second , null ) ) ;
45+ Assert . False ( first . SequenceEqual ( second , EqualityComparer < int > . Default ) ) ;
3846 }
3947
40- [ Fact ]
41- public static void OnSequenceEqualOfEqualSpansMakeSureEveryElementIsCompared ( )
48+ [ Theory ]
49+ [ InlineData ( 0 ) ]
50+ [ InlineData ( 1 ) ]
51+ [ InlineData ( 2 ) ]
52+ public static void OnSequenceEqualOfEqualSpansMakeSureEveryElementIsCompared ( int mode )
4253 {
4354 for ( int length = 0 ; length < 100 ; length ++ )
4455 {
@@ -53,8 +64,13 @@ public static void OnSequenceEqualOfEqualSpansMakeSureEveryElementIsCompared()
5364
5465 ReadOnlySpan < TInt > firstSpan = new ReadOnlySpan < TInt > ( first ) ;
5566 ReadOnlySpan < TInt > secondSpan = new ReadOnlySpan < TInt > ( second ) ;
56- bool b = firstSpan . SequenceEqual ( secondSpan ) ;
57- Assert . True ( b ) ;
67+
68+ Assert . True ( mode switch
69+ {
70+ 0 => firstSpan . SequenceEqual ( secondSpan ) ,
71+ 1 => firstSpan . SequenceEqual ( secondSpan , null ) ,
72+ _ => firstSpan . SequenceEqual ( secondSpan , EqualityComparer < TInt > . Default )
73+ } ) ;
5874
5975 // Make sure each element of the array was compared once. (Strictly speaking, it would not be illegal for
6076 // SequenceEqual to compare an element more than once but that would be a non-optimal implementation and
@@ -68,8 +84,11 @@ public static void OnSequenceEqualOfEqualSpansMakeSureEveryElementIsCompared()
6884 }
6985 }
7086
71- [ Fact ]
72- public static void SequenceEqualNoMatch ( )
87+ [ Theory ]
88+ [ InlineData ( 0 ) ]
89+ [ InlineData ( 1 ) ]
90+ [ InlineData ( 2 ) ]
91+ public static void SequenceEqualNoMatch ( int mode )
7392 {
7493 for ( int length = 1 ; length < 32 ; length ++ )
7594 {
@@ -88,8 +107,13 @@ public static void SequenceEqualNoMatch()
88107
89108 ReadOnlySpan < TInt > firstSpan = new ReadOnlySpan < TInt > ( first ) ;
90109 ReadOnlySpan < TInt > secondSpan = new ReadOnlySpan < TInt > ( second ) ;
91- bool b = firstSpan . SequenceEqual ( secondSpan ) ;
92- Assert . False ( b ) ;
110+
111+ Assert . False ( mode switch
112+ {
113+ 0 => firstSpan . SequenceEqual ( secondSpan ) ,
114+ 1 => firstSpan . SequenceEqual ( secondSpan , null ) ,
115+ _ => firstSpan . SequenceEqual ( secondSpan , EqualityComparer < TInt > . Default )
116+ } ) ;
93117
94118 Assert . Equal ( 1 , log . CountCompares ( first [ mismatchIndex ] . Value , second [ mismatchIndex ] . Value ) ) ;
95119 }
@@ -125,8 +149,10 @@ public static void MakeSureNoSequenceEqualChecksGoOutOfRange()
125149
126150 ReadOnlySpan < TInt > firstSpan = new ReadOnlySpan < TInt > ( first , GuardLength , length ) ;
127151 ReadOnlySpan < TInt > secondSpan = new ReadOnlySpan < TInt > ( second , GuardLength , length ) ;
128- bool b = firstSpan . SequenceEqual ( secondSpan ) ;
129- Assert . True ( b ) ;
152+
153+ Assert . True ( firstSpan . SequenceEqual ( secondSpan ) ) ;
154+ Assert . True ( firstSpan . SequenceEqual ( secondSpan , null ) ) ;
155+ Assert . True ( firstSpan . SequenceEqual ( secondSpan , EqualityComparer < TInt > . Default ) ) ;
130156 }
131157 }
132158
@@ -135,8 +161,53 @@ public static void MakeSureNoSequenceEqualChecksGoOutOfRange()
135161 public static void SequenceEqualsNullData_String ( string [ ] firstInput , string [ ] secondInput , bool expected )
136162 {
137163 ReadOnlySpan < string > theStrings = firstInput ;
164+
138165 Assert . Equal ( expected , theStrings . SequenceEqual ( secondInput ) ) ;
139- Assert . Equal ( expected , theStrings . SequenceEqual ( ( ReadOnlySpan < string > ) secondInput ) ) ;
166+ Assert . Equal ( expected , theStrings . SequenceEqual ( secondInput , null ) ) ;
167+ Assert . Equal ( expected , theStrings . SequenceEqual ( secondInput , EqualityComparer < string > . Default ) ) ;
168+ }
169+
170+ [ Fact ]
171+ public static void SequenceEqual_AlwaysTrueComparer ( )
172+ {
173+ Assert . False ( ( ( ReadOnlySpan < int > ) new int [ 1 ] ) . SequenceEqual ( new int [ 2 ] , new AlwaysComparer < int > ( true ) ) ) ;
174+ Assert . True ( ( ( ReadOnlySpan < int > ) new int [ 2 ] ) . SequenceEqual ( new int [ 2 ] , new AlwaysComparer < int > ( true ) ) ) ;
175+ Assert . True ( ( ( ReadOnlySpan < int > ) new int [ 2 ] { 1 , 3 } ) . SequenceEqual ( new int [ 2 ] { 2 , 4 } , new AlwaysComparer < int > ( true ) ) ) ;
176+ }
177+
178+ [ Fact ]
179+ public static void SequenceEqual_AlwaysFalseComparer ( )
180+ {
181+ Assert . False ( ( ( ReadOnlySpan < int > ) new int [ 1 ] ) . SequenceEqual ( new int [ 2 ] , new AlwaysComparer < int > ( false ) ) ) ;
182+ Assert . False ( ( ( ReadOnlySpan < int > ) new int [ 1 ] ) . SequenceEqual ( new int [ 2 ] , new AlwaysComparer < int > ( false ) ) ) ;
183+ Assert . False ( ( ( ReadOnlySpan < int > ) new int [ 2 ] { 1 , 3 } ) . SequenceEqual ( new int [ 2 ] { 2 , 4 } , new AlwaysComparer < int > ( false ) ) ) ;
184+ }
185+
186+ [ Fact ]
187+ public static void SequenceEqual_IgnoreCaseComparer ( )
188+ {
189+ string [ ] lower = new [ ] { "hello" , "world" } ;
190+ string [ ] upper = new [ ] { "HELLO" , "WORLD" } ;
191+ string [ ] different = new [ ] { "hello" , "wurld" } ;
192+
193+ Assert . True ( ( ( ReadOnlySpan < string > ) lower ) . SequenceEqual ( lower ) ) ;
194+ Assert . False ( ( ( ReadOnlySpan < string > ) lower ) . SequenceEqual ( upper ) ) ;
195+ Assert . True ( ( ( ReadOnlySpan < string > ) upper ) . SequenceEqual ( upper ) ) ;
196+
197+ Assert . True ( ( ( ReadOnlySpan < string > ) lower ) . SequenceEqual ( lower , StringComparer . OrdinalIgnoreCase ) ) ;
198+ Assert . True ( ( ( ReadOnlySpan < string > ) lower ) . SequenceEqual ( upper , StringComparer . OrdinalIgnoreCase ) ) ;
199+ Assert . True ( ( ( ReadOnlySpan < string > ) upper ) . SequenceEqual ( upper , StringComparer . OrdinalIgnoreCase ) ) ;
200+
201+ Assert . False ( ( ( ReadOnlySpan < string > ) lower ) . SequenceEqual ( different ) ) ;
202+ Assert . False ( ( ( ReadOnlySpan < string > ) lower ) . SequenceEqual ( different , StringComparer . OrdinalIgnoreCase ) ) ;
203+ }
204+
205+ private sealed class AlwaysComparer < T > : IEqualityComparer < T >
206+ {
207+ private readonly bool _result ;
208+ public AlwaysComparer ( bool result ) => _result = result ;
209+ public bool Equals ( T ? x , T ? y ) => _result ;
210+ public int GetHashCode ( [ DisallowNull ] T obj ) => 0 ;
140211 }
141212 }
142213}
0 commit comments