66import static org .junit .jupiter .api .Assertions .assertTrue ;
77
88import com .thealgorithms .datastructures .bags .Bag ;
9+ import java .util .ArrayList ;
910import java .util .Iterator ;
11+ import java .util .List ;
12+ import java .util .NoSuchElementException ;
1013import org .junit .jupiter .api .Test ;
1114
1215class BagTest {
@@ -156,4 +159,134 @@ void testIteratorWithDuplicates() {
156159 }
157160 assertEquals (3 , count , "Iterator should traverse all 3 items including duplicates" );
158161 }
159- }
162+
163+ @ Test
164+ void testAddNullElement () {
165+ Bag <String > bag = new Bag <>();
166+ bag .add (null );
167+ bag .add ("item1" );
168+ bag .add (null ); // Add null twice
169+
170+ assertEquals (3 , bag .size (), "Bag should contain 3 elements including nulls" );
171+ assertTrue (bag .contains (null ), "Bag should contain null" );
172+ assertTrue (bag .contains ("item1" ), "Bag should contain 'item1'" );
173+
174+ int nullCount = 0 ;
175+ for (String item : bag ) {
176+ if (item == null ) nullCount ++;
177+ }
178+ assertEquals (2 , nullCount , "Bag should contain exactly 2 null values" );
179+ }
180+
181+ @ Test
182+ void testCollectionElements () {
183+ Bag <List <String >> bag = new Bag <>();
184+ List <String > list1 = new ArrayList <>();
185+ list1 .add ("a" );
186+ list1 .add ("b" );
187+
188+ List <String > list2 = new ArrayList <>();
189+ list2 .add ("c" );
190+
191+ List <String > emptyList = new ArrayList <>();
192+
193+ bag .add (list1 );
194+ bag .add (list2 );
195+ bag .add (emptyList );
196+ bag .add (list1 ); // Duplicate
197+
198+ assertEquals (4 , bag .size (), "Bag should contain 4 list elements" );
199+ assertTrue (bag .contains (list1 ), "Bag should contain list1" );
200+ assertTrue (bag .contains (list2 ), "Bag should contain list2" );
201+ assertTrue (bag .contains (emptyList ), "Bag should contain empty list" );
202+ }
203+
204+ @ Test
205+ void testIteratorConsistency () {
206+ Bag <String > bag = new Bag <>();
207+ bag .add ("first" );
208+ bag .add ("second" );
209+ bag .add ("third" );
210+
211+ // Multiple iterations should return same elements
212+ List <String > firstIteration = new ArrayList <>();
213+ for (String item : bag ) {
214+ firstIteration .add (item );
215+ }
216+
217+ List <String > secondIteration = new ArrayList <>();
218+ for (String item : bag ) {
219+ secondIteration .add (item );
220+ }
221+
222+ assertEquals (firstIteration .size (), secondIteration .size (), "Both iterations should have same size" );
223+ assertEquals (3 , firstIteration .size (), "First iteration should have 3 elements" );
224+ assertEquals (3 , secondIteration .size (), "Second iteration should have 3 elements" );
225+ }
226+
227+ @ Test
228+ void testMultipleIterators () {
229+ Bag <String > bag = new Bag <>();
230+ bag .add ("item1" );
231+ bag .add ("item2" );
232+
233+ Iterator <String > iter1 = bag .iterator ();
234+ Iterator <String > iter2 = bag .iterator ();
235+
236+ assertTrue (iter1 .hasNext (), "First iterator should have next element" );
237+ assertTrue (iter2 .hasNext (), "Second iterator should have next element" );
238+
239+ String first1 = iter1 .next ();
240+ String first2 = iter2 .next ();
241+
242+ org .junit .jupiter .api .Assertions .assertNotNull (first1 , "First iterator should return non-null element" );
243+ org .junit .jupiter .api .Assertions .assertNotNull (first2 , "Second iterator should return non-null element" );
244+ }
245+
246+ @ Test
247+ void testIteratorHasNextConsistency () {
248+ Bag <String > bag = new Bag <>();
249+ bag .add ("single" );
250+
251+ Iterator <String > iter = bag .iterator ();
252+ assertTrue (iter .hasNext (), "hasNext should return true" );
253+ assertTrue (iter .hasNext (), "hasNext should still return true after multiple calls" );
254+
255+ String item = iter .next ();
256+ assertEquals ("single" , item , "Next should return the single item" );
257+
258+ assertFalse (iter .hasNext (), "hasNext should return false after consuming element" );
259+ assertFalse (iter .hasNext (), "hasNext should still return false" );
260+ }
261+
262+ @ Test
263+ void testIteratorNextOnEmptyBag () {
264+ Bag <String > bag = new Bag <>();
265+ Iterator <String > iter = bag .iterator ();
266+
267+ assertFalse (iter .hasNext (), "hasNext should return false for empty bag" );
268+ assertThrows (NoSuchElementException .class , iter ::next , "next() should throw NoSuchElementException on empty bag" );
269+ }
270+
271+ @ Test
272+ void testBagOrderIndependence () {
273+ Bag <String > bag1 = new Bag <>();
274+ Bag <String > bag2 = new Bag <>();
275+
276+ // Add same elements in different order
277+ bag1 .add ("first" );
278+ bag1 .add ("second" );
279+ bag1 .add ("third" );
280+
281+ bag2 .add ("third" );
282+ bag2 .add ("first" );
283+ bag2 .add ("second" );
284+
285+ assertEquals (bag1 .size (), bag2 .size (), "Bags should have same size" );
286+
287+ // Both bags should contain all elements
288+ assertTrue (bag1 .contains ("first" ) && bag2 .contains ("first" ));
289+ assertTrue (bag1 .contains ("second" ) && bag2 .contains ("second" ));
290+ assertTrue (bag1 .contains ("third" ) && bag2 .contains ("third" ));
291+ }
292+ }
0 commit comments