@@ -113,6 +113,18 @@ public void Add_IncreasesCount_WhenValueAlreadyExists()
113113 Assert . That ( hashTable . Count , Is . EqualTo ( 2 ) ) ;
114114 }
115115
116+ [ Test ]
117+ public void Add_ThrowsException_OnCollision ( )
118+ {
119+ // Arrange
120+ var hashTable = new HashTable < Collider , int > ( ) ;
121+ hashTable . Add ( new Collider ( 1 ) , 1 ) ;
122+
123+
124+ // Act & Assert
125+ Assert . Throws < ArgumentException > ( ( ) => hashTable . Add ( new Collider ( 1 ) , 2 ) ) ;
126+ }
127+
116128 [ Test ]
117129 public void Remove_ThrowsException_WhenKeyIsNull ( )
118130 {
@@ -154,12 +166,45 @@ public void Remove_DecreasesCount_WhenKeyExists()
154166 public void Remove_DoesNotDecreaseCount_WhenKeyDoesNotExist ( )
155167 {
156168 var hashTable = new HashTable < string , int > ( ) ;
157-
158169 hashTable . Remove ( "a" ) ;
159170
160171 Assert . That ( hashTable . Count , Is . EqualTo ( 0 ) ) ;
161172 }
162173
174+ [ Test ]
175+ public void Remove_TriggersResizeDown ( )
176+ {
177+ var hashTable = new HashTable < int , string > ( 4 ) ;
178+ for ( var i = 1 ; i <= 50 ; i ++ )
179+ {
180+ hashTable . Add ( i , $ "Value{ i } ") ;
181+ }
182+
183+ for ( var i = 1 ; i <= 40 ; i ++ )
184+ {
185+ hashTable . Remove ( i ) ;
186+ }
187+
188+ Assert . That ( hashTable . Capacity , Is . EqualTo ( 40 ) ) ;
189+ }
190+
191+ [ Test ]
192+ public void Remove_TriggersResizeDown_MinimumOfDefaultCapacity ( )
193+ {
194+ var hashTable = new HashTable < int , string > ( 4 ) ;
195+ for ( var i = 1 ; i <= 50 ; i ++ )
196+ {
197+ hashTable . Add ( i , $ "Value{ i } ") ;
198+ }
199+
200+ for ( var i = 1 ; i <= 48 ; i ++ )
201+ {
202+ hashTable . Remove ( i ) ;
203+ }
204+
205+ Assert . That ( hashTable . Capacity , Is . EqualTo ( 16 ) ) ;
206+ }
207+
163208 [ Test ]
164209 public void ContainsValue_ReturnsFalse_WhenValueDoesNotExist ( )
165210 {
@@ -234,6 +279,17 @@ public void Clear_RemovesAllElements()
234279 Assert . That ( hashTable . ContainsKey ( "a" ) , Is . False ) ;
235280 }
236281
282+ [ Test ]
283+ public void Clear_ResetsTable ( )
284+ {
285+ var hashTable = new HashTable < int , string > ( ) ;
286+ hashTable . Add ( 1 , "A" ) ;
287+ hashTable . Clear ( ) ;
288+ hashTable . Add ( 2 , "B" ) ;
289+ Assert . That ( hashTable . Count , Is . EqualTo ( 1 ) ) ;
290+ Assert . That ( hashTable [ 2 ] , Is . EqualTo ( "B" ) ) ;
291+ }
292+
237293 [ Test ]
238294 public void Resize_IncreasesCapacity ( )
239295 {
@@ -313,6 +369,13 @@ public void Constructor_ThrowsException_WhenLoadFactorIsGreaterThanOne()
313369 Assert . Throws < ArgumentOutOfRangeException > ( ( ) => new HashTable < string , int > ( 4 , 2 ) ) ;
314370 }
315371
372+ [ Test ]
373+ public void Constructor_RoundsCapacityToPrime ( )
374+ {
375+ var hashTable = new HashTable < int , string > ( 17 ) ;
376+ Assert . That ( hashTable . Capacity , Is . EqualTo ( 19 ) ) ;
377+ }
378+
316379 [ Test ]
317380 public void GetIndex_ThrowsException_WhenKeyIsNull ( )
318381 {
@@ -388,6 +451,23 @@ public void Test_NegativeHashKey_ReturnsCorrectValue()
388451 Assert . That ( hashTable [ new NegativeHashKey ( 1 ) ] , Is . EqualTo ( 1 ) ) ;
389452 }
390453
454+ [ Test ]
455+ public void Resize_HandlesNegativeHashCodeCorrectly ( )
456+ {
457+ // Arrange
458+ var hashTable = new HashTable < NegativeHashKey , string > ( 2 ) ;
459+
460+ // Act
461+ hashTable . Add ( new NegativeHashKey ( 1 ) , "A" ) ;
462+ hashTable . Add ( new NegativeHashKey ( 2 ) , "B" ) ;
463+ hashTable . Add ( new NegativeHashKey ( 3 ) , "C" ) ;
464+
465+ // Assert
466+ Assert . That ( hashTable [ new NegativeHashKey ( 1 ) ] , Is . EqualTo ( "A" ) ) ;
467+ Assert . That ( hashTable [ new NegativeHashKey ( 2 ) ] , Is . EqualTo ( "B" ) ) ;
468+ Assert . That ( hashTable [ new NegativeHashKey ( 3 ) ] , Is . EqualTo ( "C" ) ) ;
469+ }
470+
391471 [ Test ]
392472 public void Add_ShouldTriggerResize_WhenThresholdExceeded ( )
393473 {
@@ -396,14 +476,14 @@ public void Add_ShouldTriggerResize_WhenThresholdExceeded()
396476 var hashTable = new HashTable < int , string > ( initialCapacity ) ;
397477
398478 // Act
399- for ( int i = 1 ; i <= 4 ; i ++ ) // Start keys from 1 to avoid default(TKey) = 0 issue
479+ for ( var i = 1 ; i <= 32 ; i ++ )
400480 {
401481 hashTable . Add ( i , $ "Value{ i } ") ;
402482 }
403483
404484 // Assert
405- hashTable . Capacity . Should ( ) . BeGreaterThan ( initialCapacity ) ; // Ensure resizing occurred
406- hashTable . Count . Should ( ) . Be ( 4 ) ; // Verify count reflects number of added items
485+ hashTable . Capacity . Should ( ) . BeGreaterThan ( initialCapacity ) ;
486+ hashTable . Count . Should ( ) . Be ( 32 ) ;
407487 }
408488
409489
@@ -473,23 +553,28 @@ public void Capacity_Increases_WhenResizeOccurs()
473553 var initialCapacity = 4 ;
474554 var hashTable = new HashTable < int , string > ( initialCapacity ) ;
475555
476- for ( int i = 1 ; i <= 5 ; i ++ )
556+ for ( var i = 1 ; i <= 5 ; i ++ )
477557 {
478558 hashTable . Add ( i , $ "Value{ i } ") ;
479559 }
480560
481561 hashTable . Capacity . Should ( ) . BeGreaterThan ( initialCapacity ) ;
482562 }
483- }
484-
485- public class NegativeHashKey
486- {
487- private readonly int id ;
488563
489- public NegativeHashKey ( int id )
564+ [ Test ]
565+ public void IndexerSet_Throws_KeyNotFound ( )
490566 {
491- this . id = id ;
567+ // Arrange
568+ var hashTable = new HashTable < int , string > ( ) ;
569+
570+ // Act & Assert
571+ Assert . Throws < KeyNotFoundException > ( ( ) => hashTable [ 1 ] = "A" ) ;
492572 }
573+ }
574+
575+ public class NegativeHashKey ( int id )
576+ {
577+ private readonly int id = id ;
493578
494579 public override int GetHashCode ( )
495580 {
@@ -506,3 +591,14 @@ public override bool Equals(object? obj)
506591 return false ;
507592 }
508593}
594+
595+ /// <summary>
596+ /// Class to simulate hash collisions
597+ /// </summary>
598+ /// <param name="id">Id of this object</param>
599+ public class Collider ( int id )
600+ {
601+ private readonly int id = id ;
602+ public override int GetHashCode ( ) => 42 ; // Force all instances to collide
603+ public override bool Equals ( object ? obj ) => obj is Collider other && other . id == id ;
604+ }
0 commit comments