@@ -201,14 +201,6 @@ public void SkipLastTryCopyTo()
201
201
Array . Clear ( dest ) ;
202
202
source . SkipLast ( 2 ) . TryCopyTo ( dest , 2 ) . ShouldBeTrue ( ) ;
203
203
dest . ShouldBe ( [ 3 , 0 , 0 , 0 , 0 ] ) ;
204
-
205
- Array . Clear ( dest ) ;
206
- source . SkipLast ( 2 ) . TryCopyTo ( dest , 3 ) . ShouldBeTrue ( ) ;
207
- dest . ShouldBe ( [ 0 , 0 , 0 , 0 , 0 ] ) ;
208
-
209
- Array . Clear ( dest ) ;
210
- source . SkipLast ( 3 ) . TryCopyTo ( dest , 2 ) . ShouldBeTrue ( ) ;
211
- dest . ShouldBe ( [ 0 , 0 , 0 , 0 , 0 ] ) ;
212
204
}
213
205
214
206
[ Fact ]
@@ -224,6 +216,172 @@ public void SkipLastTryCopyTo2()
224
216
source2 . Take ( 7 ) . SkipLast ( 2 ) . SkipLast ( 3 ) . ToArray ( ) . ShouldBe ( expected2 ) ;
225
217
}
226
218
219
+ [ Fact ]
220
+ public void SkipLast_TryCopyTo_EmptyCollection ( )
221
+ {
222
+ var emptySource = Array . Empty < int > ( ) . AsValueEnumerable ( ) ;
223
+ var dest = new int [ 5 ] ;
224
+
225
+ // Empty source with skip
226
+ emptySource . SkipLast ( 3 ) . TryCopyTo ( dest , 0 ) . ShouldBeFalse ( ) ;
227
+ dest . ShouldBe ( new int [ 5 ] ) ; // Destination should remain unchanged
228
+ }
229
+
230
+ [ Fact ]
231
+ public void SkipLast_TryCopyTo_SkipCountExceedsSourceSize ( )
232
+ {
233
+ var source = new [ ] { 1 , 2 , 3 } . AsValueEnumerable ( ) ;
234
+ var dest = new int [ 5 ] ;
235
+
236
+ // Skip more than available
237
+ source . SkipLast ( 5 ) . TryCopyTo ( dest , 0 ) . ShouldBeFalse ( ) ;
238
+ dest . ShouldBe ( new int [ 5 ] ) ; // Destination should remain unchanged
239
+ }
240
+
241
+ [ Fact ]
242
+ public void SkipLast_TryCopyTo_InvalidOffset ( )
243
+ {
244
+ var source = new [ ] { 1 , 2 , 3 , 4 , 5 } . AsValueEnumerable ( ) ;
245
+ var dest = new int [ 3 ] ;
246
+
247
+ // Negative offset (in equivalent offset form)
248
+ source . SkipLast ( 2 ) . TryCopyTo ( dest , ^ 4 ) . ShouldBeFalse ( ) ;
249
+
250
+ // Offset beyond remaining count
251
+ source . SkipLast ( 2 ) . TryCopyTo ( dest , 3 ) . ShouldBeFalse ( ) ;
252
+ }
253
+
254
+ [ Fact ]
255
+ public void SkipLast_TryCopyTo_DestinationTooSmall ( )
256
+ {
257
+ var source = new [ ] { 1 , 2 , 3 , 4 , 5 , 6 , 7 } . AsValueEnumerable ( ) ;
258
+ var smallDest = new int [ 2 ] ;
259
+
260
+ // Partial copy with small destination
261
+ source . SkipLast ( 2 ) . TryCopyTo ( smallDest , 0 ) . ShouldBeTrue ( ) ;
262
+ smallDest . ShouldBe ( new [ ] { 1 , 2 } ) ; // Should copy only what fits
263
+
264
+ // With offset
265
+ Array . Clear ( smallDest ) ;
266
+ source . SkipLast ( 2 ) . TryCopyTo ( smallDest , 2 ) . ShouldBeTrue ( ) ;
267
+ smallDest . ShouldBe ( new [ ] { 3 , 4 } ) ;
268
+ }
269
+
270
+ [ Fact ]
271
+ public void SkipLast_TryCopyTo_FromEnd ( )
272
+ {
273
+ var source = new [ ] { 1 , 2 , 3 , 4 , 5 } . AsValueEnumerable ( ) ;
274
+ var dest = new int [ 3 ] ;
275
+
276
+ // Using Index.FromEnd
277
+ source . SkipLast ( 2 ) . TryCopyTo ( dest , ^ 3 ) . ShouldBeTrue ( ) ;
278
+ dest . ShouldBe ( new [ ] { 1 , 2 , 3 } ) ;
279
+
280
+ Array . Clear ( dest ) ;
281
+ source . SkipLast ( 2 ) . TryCopyTo ( dest , ^ 2 ) . ShouldBeTrue ( ) ;
282
+ dest . ShouldBe ( new [ ] { 2 , 3 , 0 } ) ;
283
+
284
+ Array . Clear ( dest ) ;
285
+ source . SkipLast ( 2 ) . TryCopyTo ( dest , ^ 1 ) . ShouldBeTrue ( ) ;
286
+ dest . ShouldBe ( new [ ] { 3 , 0 , 0 } ) ;
287
+ }
288
+
289
+ [ Fact ]
290
+ public void SkipLast_TryCopyTo_WithZeroElementsAvailable ( )
291
+ {
292
+ var source = new [ ] { 1 , 2 , 3 } . AsValueEnumerable ( ) ;
293
+ var dest = new int [ 3 ] ;
294
+
295
+ // When element count is exactly zero after calculations
296
+ source . SkipLast ( 3 ) . TryCopyTo ( dest , 0 ) . ShouldBeFalse ( ) ;
297
+ dest . ShouldBe ( new int [ 3 ] ) ; // Destination should remain unchanged
298
+ }
299
+
300
+ [ Fact ]
301
+ public void SkipLast_TryCopyTo_WithDestinationSlicing ( )
302
+ {
303
+ var source = new [ ] { 1 , 2 , 3 , 4 , 5 , 6 } . AsValueEnumerable ( ) ;
304
+ var dest = new int [ 5 ] ;
305
+
306
+ // Ensure destination slicing works correctly
307
+ source . SkipLast ( 2 ) . TryCopyTo ( dest , 1 ) . ShouldBeTrue ( ) ;
308
+ dest . ShouldBe ( new [ ] { 2 , 3 , 4 , 0 , 0 } ) ;
309
+
310
+ // Test with partial destination
311
+ Array . Clear ( dest ) ;
312
+ var slice = dest . AsSpan ( 1 , 3 ) ;
313
+ source . SkipLast ( 3 ) . TryCopyTo ( slice , 0 ) . ShouldBeTrue ( ) ;
314
+ dest . ShouldBe ( new [ ] { 0 , 1 , 2 , 3 , 0 } ) ;
315
+ }
316
+
317
+ [ Fact ]
318
+ public void SkipLast_TryCopyTo_ExactElementCount ( )
319
+ {
320
+ var source = new [ ] { 1 , 2 , 3 , 4 , 5 } . AsValueEnumerable ( ) ;
321
+ var dest = new int [ 3 ] ;
322
+
323
+ // Destination length exactly matches remaining elements
324
+ source . SkipLast ( 2 ) . TryCopyTo ( dest , 0 ) . ShouldBeTrue ( ) ;
325
+ dest . ShouldBe ( new [ ] { 1 , 2 , 3 } ) ;
326
+ }
327
+
328
+ [ Fact ]
329
+ public void SkipLast_TryCopyTo_ZeroElementsToCopy ( )
330
+ {
331
+ var source = new [ ] { 1 , 2 , 3 , 4 , 5 } . AsValueEnumerable ( ) ;
332
+ var dest = new int [ 0 ] ;
333
+
334
+ source . SkipLast ( 2 ) . TryCopyTo ( dest , 2 ) . ShouldBeFalse ( ) ;
335
+ }
336
+
337
+ [ Fact ]
338
+ public void SkipLast_TryCopyTo_ChainedOperations ( )
339
+ {
340
+ var source = Enumerable . Range ( 1 , 10 ) . ToArray ( ) . AsValueEnumerable ( ) ;
341
+ var dest = new int [ 5 ] ;
342
+
343
+ // Chain multiple operations
344
+ source . Skip ( 2 ) . SkipLast ( 3 ) . TryCopyTo ( dest , 0 ) . ShouldBeTrue ( ) ;
345
+ dest . ShouldBe ( new [ ] { 3 , 4 , 5 , 6 , 7 } ) ;
346
+
347
+ // With different offset
348
+ Array . Clear ( dest ) ;
349
+ source . Skip ( 2 ) . SkipLast ( 3 ) . TryCopyTo ( dest , 2 ) . ShouldBeTrue ( ) ;
350
+ dest . ShouldBe ( new [ ] { 5 , 6 , 7 , 0 , 0 } ) ;
351
+ }
352
+
353
+ [ Fact ]
354
+ public void SkipLast_TryCopyTo_NonEnumerableSourceCount ( )
355
+ {
356
+ // Create a custom enumerable that doesn't implement TryGetNonEnumeratedCount
357
+ var nonCountableSource = new [ ] { 1 , 2 , 3 , 4 , 5 }
358
+ . Select ( x => x ) // Forces enumeration
359
+ . AsValueEnumerable ( ) ;
360
+
361
+ var dest = new int [ 3 ] ;
362
+
363
+ // Should return false since the source can't provide count without enumeration
364
+ nonCountableSource . SkipLast ( 2 ) . TryCopyTo ( dest , 0 ) . ShouldBeFalse ( ) ;
365
+ dest . ShouldBe ( new int [ 3 ] ) ; // Destination should remain unchanged
366
+ }
367
+
368
+ [ Fact ]
369
+ public void SkipLast_TryCopyTo_BoundaryConditions ( )
370
+ {
371
+ var source = new [ ] { 1 , 2 , 3 , 4 , 5 } . AsValueEnumerable ( ) ;
372
+ var dest = new int [ 3 ] ;
373
+
374
+ // Skip everything but one element
375
+ source . SkipLast ( 4 ) . TryCopyTo ( dest , 0 ) . ShouldBeTrue ( ) ;
376
+ dest . ShouldBe ( new [ ] { 1 , 0 , 0 } ) ;
377
+
378
+ // Skip exactly the right number to leave one element with max offset
379
+ Array . Clear ( dest ) ;
380
+ source . SkipLast ( 4 ) . TryCopyTo ( dest , 0 ) . ShouldBeTrue ( ) ;
381
+ dest . ShouldBe ( new [ ] { 1 , 0 , 0 } ) ;
382
+ }
383
+
384
+
227
385
// Helper class to test disposal behavior
228
386
private class DisposableTestEnumerator < T > ( IEnumerable < T > source , Action onDispose ) : IEnumerable < T >
229
387
{
0 commit comments