@@ -297,10 +297,39 @@ public BasicDataRecord((int x, string y, int? z, string? w) data)
297
297
( int X , string Y , int ? Z , string ? W ) c2
298
298
) > GenTwoBasic = Gen . Select ( GenBasic , GenBasic , ( c1 , c2 ) => ( c1 , c2 ) ) ;
299
299
300
+ /// <summary>
301
+ /// Count collisions when comparing hashcodes of non-equal structures.
302
+ /// </summary>
303
+ struct CollisionCounter
304
+ {
305
+ private uint Comparisons ;
306
+ private uint Collisions ;
307
+
308
+ public void Add ( bool collides )
309
+ {
310
+ Comparisons += 1 ;
311
+ if ( collides )
312
+ {
313
+ Collisions += 1 ;
314
+ }
315
+ }
316
+
317
+ public double CollisionFraction
318
+ {
319
+ get => ( double ) Collisions / ( double ) Comparisons ;
320
+ }
321
+
322
+ public void AssertCollisionsLessThan ( double fraction )
323
+ {
324
+ Assert . True ( CollisionFraction < fraction , $ "Expected { fraction } portion of collisions, but got { CollisionFraction } = { Collisions } / { Comparisons } ") ;
325
+ }
326
+ }
300
327
301
328
[ Fact ]
302
329
public static void GeneratedProductEqualsWorks ( )
303
330
{
331
+ CollisionCounter collisionCounter = new ( ) ;
332
+
304
333
GenTwoBasic . Sample (
305
334
example =>
306
335
{
@@ -357,10 +386,13 @@ public static void GeneratedProductEqualsWorks()
357
386
// hash code should not depend on the type of object.
358
387
Assert . Equal ( class1 . GetHashCode ( ) , record1 . GetHashCode ( ) ) ;
359
388
Assert . Equal ( record1 . GetHashCode ( ) , struct1 . GetHashCode ( ) ) ;
389
+
390
+ collisionCounter . Add ( class1 . GetHashCode ( ) == class2 . GetHashCode ( ) ) ;
360
391
}
361
392
} ,
362
393
iter : 10_000
363
394
) ;
395
+ collisionCounter . AssertCollisionsLessThan ( 0.05 ) ;
364
396
}
365
397
366
398
[ Type ]
@@ -402,6 +434,8 @@ BasicDataRecord W
402
434
[ Fact ]
403
435
public static void GeneratedSumEqualsWorks ( )
404
436
{
437
+ CollisionCounter collisionCounter = new ( ) ;
438
+
405
439
GenTwoBasicEnum . Sample (
406
440
example =>
407
441
{
@@ -433,10 +467,12 @@ public static void GeneratedSumEqualsWorks()
433
467
Assert . False ( example . e1 == example . e2 ) ;
434
468
Assert . True ( example . e1 != example . e2 ) ;
435
469
Assert . NotEqual ( example . e1 . ToString ( ) , example . e2 . ToString ( ) ) ;
470
+ collisionCounter . Add ( example . e1 . GetHashCode ( ) == example . e2 . GetHashCode ( ) ) ;
436
471
}
437
472
} ,
438
473
iter : 10_000
439
474
) ;
475
+ collisionCounter . AssertCollisionsLessThan ( 0.05 ) ;
440
476
}
441
477
442
478
@@ -465,6 +501,7 @@ public ContainsList(List<BasicEnum?>? theList)
465
501
[ Fact ]
466
502
public static void GeneratedListEqualsWorks ( )
467
503
{
504
+ CollisionCounter collisionCounter = new ( ) ;
468
505
GenTwoContainsList . Sample (
469
506
example =>
470
507
{
@@ -486,10 +523,12 @@ public static void GeneratedListEqualsWorks()
486
523
Assert . False ( example . e1 == example . e2 ) ;
487
524
Assert . True ( example . e1 != example . e2 ) ;
488
525
Assert . NotEqual ( example . e1 . ToString ( ) , example . e2 . ToString ( ) ) ;
526
+ collisionCounter . Add ( example . e1 . GetHashCode ( ) == example . e2 . GetHashCode ( ) ) ;
489
527
}
490
528
} ,
491
529
iter : 10_000
492
530
) ;
531
+ collisionCounter . AssertCollisionsLessThan ( 0.05 ) ;
493
532
}
494
533
495
534
[ Type ]
@@ -550,6 +589,7 @@ public static void GeneratedNestedListEqualsWorks()
550
589
)
551
590
)
552
591
) ;
592
+ CollisionCounter collisionCounter = new ( ) ;
553
593
GenTwoContainsNestedList . Sample (
554
594
example =>
555
595
{
@@ -569,10 +609,12 @@ public static void GeneratedNestedListEqualsWorks()
569
609
Assert . False ( example . e1 == example . e2 ) ;
570
610
Assert . True ( example . e1 != example . e2 ) ;
571
611
Assert . NotEqual ( example . e1 . ToString ( ) , example . e2 . ToString ( ) ) ;
612
+ collisionCounter . Add ( example . e1 . GetHashCode ( ) == example . e2 . GetHashCode ( ) ) ;
572
613
}
573
614
} ,
574
615
iter : 10_000
575
616
) ;
617
+ collisionCounter . AssertCollisionsLessThan ( 0.05 ) ;
576
618
}
577
619
578
620
0 commit comments