1
+ using SpanExtensions ;
2
+ using static Tests . TestHelper ;
3
+
4
+ namespace Tests
5
+ {
6
+ public static class ReadOnlySpanTests
7
+ {
8
+ const int count = 250 ;
9
+ const int minValue = 0 ;
10
+ const int maxValue = 100 ;
11
+ const int length = 100 ;
12
+ static readonly IEnumerable < StringSplitOptions > stringSplitOptions = GetAllStringSplitOptions ( ) ;
13
+
14
+ public static class LinqTests
15
+ {
16
+ }
17
+
18
+ public static class SplitTests
19
+ {
20
+ public sealed class RandomData
21
+ {
22
+ [ Fact ]
23
+ public void TestSplit ( )
24
+ {
25
+ int [ ] integerArray = GenerateRandomIntegers ( count , minValue , maxValue ) . ToArray ( ) ;
26
+ ReadOnlySpan < int > integerSpan = integerArray ;
27
+
28
+ // source contains delimiter
29
+ int integerDelimiter = integerArray [ random . Next ( integerArray . Length ) ] ;
30
+ Assert . True (
31
+ SequencesEqual (
32
+ Split ( integerArray , integerDelimiter ) ,
33
+ integerSpan . Split ( integerDelimiter ) . ToSystemEnumerable ( )
34
+ ) ,
35
+ GenerateAssertionMessage ( integerArray , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , integerDelimiter ) )
36
+ ) ;
37
+
38
+ // source does not contain delimiter
39
+ integerDelimiter = maxValue + 1 ;
40
+ Assert . True (
41
+ SequencesEqual (
42
+ Split ( integerArray , integerDelimiter ) ,
43
+ integerSpan . Split ( integerDelimiter ) . ToSystemEnumerable ( )
44
+ ) ,
45
+ GenerateAssertionMessage ( integerArray , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , integerDelimiter ) )
46
+ ) ;
47
+
48
+ char [ ] charArray = GenerateRandomString ( length ) . ToCharArray ( ) ;
49
+ ReadOnlySpan < char > charSpan = charArray ;
50
+
51
+ // source contains delimiter
52
+ char charDelimiter = charArray [ random . Next ( charArray . Length ) ] ;
53
+ Assert . True (
54
+ SequencesEqual (
55
+ Split ( charArray , charDelimiter ) ,
56
+ charSpan . Split ( charDelimiter ) . ToSystemEnumerable ( )
57
+ ) ,
58
+ GenerateAssertionMessage ( charArray , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , charDelimiter ) )
59
+ ) ;
60
+
61
+ // source does not contain delimiter
62
+ charDelimiter = '!' ; // the generated array only consists of lowercase letters and numbers
63
+ Assert . True (
64
+ SequencesEqual (
65
+ Split ( charArray , charDelimiter ) ,
66
+ charSpan . Split ( charDelimiter ) . ToSystemEnumerable ( )
67
+ ) ,
68
+ GenerateAssertionMessage ( charArray , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , charDelimiter ) )
69
+ ) ;
70
+ }
71
+
72
+ [ Fact ]
73
+ public void TestSplitWithCount ( )
74
+ {
75
+ int [ ] integerArray = GenerateRandomIntegers ( count , minValue , maxValue ) . ToArray ( ) ;
76
+ ReadOnlySpan < int > integerSpan = integerArray ;
77
+
78
+ // source contains delimiter
79
+ int integerDelimiter = integerArray [ random . Next ( integerArray . Length ) ] ;
80
+ int countDelimiters = integerArray . Count ( x => x == integerDelimiter ) ;
81
+ Assert . True (
82
+ SequencesEqual (
83
+ Split ( integerArray , integerDelimiter , countDelimiters ) ,
84
+ integerSpan . Split ( integerDelimiter , countDelimiters ) . ToSystemEnumerable ( )
85
+ ) ,
86
+ GenerateAssertionMessage ( integerArray , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , integerDelimiter ) , ( "count" , countDelimiters ) )
87
+ ) ;
88
+
89
+ // source does not contain delimiter
90
+ integerDelimiter = maxValue + 1 ;
91
+ Assert . True (
92
+ SequencesEqual (
93
+ Split ( integerArray , integerDelimiter , countDelimiters ) ,
94
+ integerSpan . Split ( integerDelimiter , countDelimiters ) . ToSystemEnumerable ( )
95
+ ) ,
96
+ GenerateAssertionMessage ( integerArray , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , integerDelimiter ) , ( "count" , countDelimiters ) )
97
+ ) ;
98
+
99
+ char [ ] charArray = GenerateRandomString ( length ) . ToCharArray ( ) ;
100
+ ReadOnlySpan < char > charSpan = charArray ;
101
+
102
+ // source contains delimiter
103
+ char charDelimiter = charArray [ random . Next ( charArray . Length ) ] ;
104
+ countDelimiters = charArray . Count ( x => x == charDelimiter ) ;
105
+ Assert . True (
106
+ SequencesEqual (
107
+ Split ( charArray , charDelimiter , countDelimiters ) ,
108
+ charSpan . Split ( charDelimiter , countDelimiters ) . ToSystemEnumerable ( )
109
+ ) ,
110
+ GenerateAssertionMessage ( charArray , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , charDelimiter ) , ( "count" , countDelimiters ) )
111
+ ) ;
112
+
113
+ // source does not contain delimiter
114
+ charDelimiter = '!' ; // the generated array only consists of lowercase letters and numbers
115
+ Assert . True (
116
+ SequencesEqual (
117
+ Split ( charArray , charDelimiter , countDelimiters ) ,
118
+ charSpan . Split ( charDelimiter , countDelimiters ) . ToSystemEnumerable ( )
119
+ ) ,
120
+ GenerateAssertionMessage ( charArray , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , charDelimiter ) , ( "count" , countDelimiters ) )
121
+ ) ;
122
+ }
123
+
124
+ [ Fact ]
125
+ public void TestSplitString ( )
126
+ {
127
+ static void AssertOptions ( StringSplitOptions options )
128
+ {
129
+ string @string = GenerateRandomString ( length ) ;
130
+ ReadOnlySpan < char > charSpan = @string ;
131
+
132
+ // source contains delimiter
133
+ char charDelimiter = @string [ random . Next ( @string . Length ) ] ;
134
+ Assert . True (
135
+ SequencesEqual (
136
+ @string . Split ( charDelimiter , options ) ,
137
+ charSpan . Split ( charDelimiter , options ) . ToSystemEnumerable ( )
138
+ ) ,
139
+ GenerateAssertionMessage ( @string , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , charDelimiter ) , ( "options" , options ) )
140
+ ) ;
141
+
142
+ // source does not contain delimiter
143
+ charDelimiter = '!' ; // the generated array only consists of lowercase letters and numbers
144
+ Assert . True (
145
+ SequencesEqual (
146
+ @string . Split ( charDelimiter , options ) ,
147
+ charSpan . Split ( charDelimiter , options ) . ToSystemEnumerable ( )
148
+ ) ,
149
+ GenerateAssertionMessage ( @string , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , charDelimiter ) , ( "options" , options ) )
150
+ ) ;
151
+ }
152
+
153
+ foreach ( StringSplitOptions _options in stringSplitOptions )
154
+ {
155
+ AssertOptions ( _options ) ;
156
+ }
157
+
158
+ // consecutive delimiters and a delimiter at the end should result in empty arrays/spans
159
+ const string @string = "abbab" ;
160
+ ReadOnlySpan < char > charSpan = @string ;
161
+ const char charDelimiter = 'b' ;
162
+ const StringSplitOptions options = StringSplitOptions . None ;
163
+ Assert . True (
164
+ SequencesEqual (
165
+ @string . Split ( charDelimiter , options ) ,
166
+ charSpan . Split ( charDelimiter , options ) . ToSystemEnumerable ( )
167
+ ) ,
168
+ GenerateAssertionMessage ( @string , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , charDelimiter ) , ( "options" , options ) )
169
+ ) ;
170
+ }
171
+
172
+ [ Fact ]
173
+ public void TestSplitStringWithCount ( )
174
+ {
175
+ static void AssertOptions ( StringSplitOptions options )
176
+ {
177
+ string @string = GenerateRandomString ( length ) ;
178
+ ReadOnlySpan < char > charSpan = @string ;
179
+
180
+ // source contains delimiter
181
+ char charDelimiter = @string [ random . Next ( @string . Length ) ] ;
182
+ int countDelimiters = @string . Count ( x => x == charDelimiter ) ;
183
+ Assert . True (
184
+ SequencesEqual (
185
+ @string . Split ( charDelimiter , countDelimiters , options ) ,
186
+ charSpan . Split ( charDelimiter , options , countDelimiters ) . ToSystemEnumerable ( )
187
+ ) ,
188
+ GenerateAssertionMessage ( @string , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , charDelimiter ) , ( "options" , options ) , ( "count" , countDelimiters ) )
189
+ ) ;
190
+
191
+ // source does not contain delimiter
192
+ charDelimiter = '!' ; // the generated array only consists of lowercase letters and numbers
193
+ Assert . True (
194
+ SequencesEqual (
195
+ @string . Split ( charDelimiter , countDelimiters , options ) ,
196
+ charSpan . Split ( charDelimiter , options , countDelimiters ) . ToSystemEnumerable ( )
197
+ ) ,
198
+ GenerateAssertionMessage ( @string , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , charDelimiter ) , ( "options" , options ) , ( "count" , countDelimiters ) )
199
+ ) ;
200
+ }
201
+
202
+ foreach ( StringSplitOptions options in stringSplitOptions )
203
+ {
204
+ AssertOptions ( options ) ;
205
+ }
206
+ }
207
+ }
208
+
209
+ public static class Facts
210
+ {
211
+ public sealed class SplitString
212
+ {
213
+ [ Fact ]
214
+ public void ConsecutiveDelimitersResultInEmptySpan ( )
215
+ {
216
+ const string @string = "abba" ;
217
+ ReadOnlySpan < char > charSpan = @string ;
218
+ const char charDelimiter = 'b' ;
219
+ const StringSplitOptions options = StringSplitOptions . None ;
220
+ Assert . True (
221
+ SequencesEqual (
222
+ @string . Split ( charDelimiter , options ) ,
223
+ charSpan . Split ( charDelimiter , options ) . ToSystemEnumerable ( )
224
+ ) ,
225
+ GenerateAssertionMessage ( @string , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , charDelimiter ) , ( "options" , options ) )
226
+ ) ;
227
+ }
228
+
229
+ [ Fact ]
230
+ public void DelimiterAtTheEndResultInEmptySpan ( )
231
+ {
232
+ const string @string = "aab" ;
233
+ ReadOnlySpan < char > charSpan = @string ;
234
+ const char charDelimiter = 'b' ;
235
+ const StringSplitOptions options = StringSplitOptions . None ;
236
+ Assert . True (
237
+ SequencesEqual (
238
+ @string . Split ( charDelimiter , options ) ,
239
+ charSpan . Split ( charDelimiter , options ) . ToSystemEnumerable ( )
240
+ ) ,
241
+ GenerateAssertionMessage ( @string , nameof ( ReadOnlySpanExtensions . Split ) , ( "delimiter" , charDelimiter ) , ( "options" , options ) )
242
+ ) ;
243
+ }
244
+ }
245
+ }
246
+ }
247
+
248
+ public static class StringTests
249
+ {
250
+ }
251
+ }
252
+ }
0 commit comments