Skip to content

Commit a438779

Browse files
Merge branch 'master' into testing/DisjointSetUnionTest
2 parents 56a42aa + 040d385 commit a438779

File tree

5 files changed

+652
-2
lines changed

5 files changed

+652
-2
lines changed

src/test/java/com/thealgorithms/datastructures/bag/BagTest.java

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
import static org.junit.jupiter.api.Assertions.assertTrue;
77

88
import com.thealgorithms.datastructures.bags.Bag;
9+
import java.util.ArrayList;
910
import java.util.Iterator;
11+
import java.util.List;
12+
import java.util.NoSuchElementException;
1013
import org.junit.jupiter.api.Test;
1114

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

src/test/java/com/thealgorithms/datastructures/lists/CursorLinkedListTest.java

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,189 @@ void testMemoryLimitExceeded() {
109109
}
110110
});
111111
}
112+
113+
@Test
114+
void testSingleElementOperations() {
115+
// Test operations with just one element
116+
list.append("Only");
117+
assertEquals("Only", list.get(0));
118+
assertEquals(0, list.indexOf("Only"));
119+
120+
list.remove("Only");
121+
assertNull(list.get(0));
122+
assertEquals(-1, list.indexOf("Only"));
123+
}
124+
125+
@Test
126+
void testDuplicateElements() {
127+
// Test handling of duplicate elements
128+
list.append("Duplicate");
129+
list.append("Other");
130+
list.append("Duplicate");
131+
132+
assertEquals(0, list.indexOf("Duplicate")); // Should return first occurrence
133+
assertEquals("Duplicate", list.get(0));
134+
assertEquals("Duplicate", list.get(2));
135+
136+
list.remove("Duplicate"); // Should remove first occurrence
137+
assertEquals("Other", list.get(0));
138+
assertEquals("Duplicate", list.get(1));
139+
}
140+
141+
@Test
142+
void testRemoveByIndexEdgeCases() {
143+
list.append("First");
144+
list.append("Second");
145+
list.append("Third");
146+
147+
// Test removing invalid indices
148+
list.removeByIndex(-1); // Should not crash
149+
list.removeByIndex(10); // Should not crash
150+
151+
// Verify list unchanged
152+
assertEquals("First", list.get(0));
153+
assertEquals("Second", list.get(1));
154+
assertEquals("Third", list.get(2));
155+
156+
// Test removing first element by index
157+
list.removeByIndex(0);
158+
assertEquals("Second", list.get(0));
159+
assertEquals("Third", list.get(1));
160+
}
161+
162+
@Test
163+
void testRemoveByIndexLastElement() {
164+
list.append("First");
165+
list.append("Second");
166+
list.append("Third");
167+
168+
// Remove last element by index
169+
list.removeByIndex(2);
170+
assertEquals("First", list.get(0));
171+
assertEquals("Second", list.get(1));
172+
assertNull(list.get(2));
173+
}
174+
175+
@Test
176+
void testConsecutiveOperations() {
177+
// Test multiple consecutive operations
178+
list.append("A");
179+
list.append("B");
180+
list.append("C");
181+
list.append("D");
182+
183+
list.remove("B");
184+
list.remove("D");
185+
186+
assertEquals("A", list.get(0));
187+
assertEquals("C", list.get(1));
188+
assertNull(list.get(2));
189+
190+
list.append("E");
191+
assertEquals("E", list.get(2));
192+
}
193+
194+
@Test
195+
void testMemoryReclamation() {
196+
// Test that removed elements free up memory space
197+
for (int i = 0; i < 50; i++) {
198+
list.append("Element" + i);
199+
}
200+
201+
// Remove some elements
202+
for (int i = 0; i < 25; i++) {
203+
list.remove("Element" + i);
204+
}
205+
206+
// Should be able to add more elements (testing memory reclamation)
207+
for (int i = 100; i < 150; i++) {
208+
list.append("New" + i);
209+
}
210+
211+
// Verify some elements exist
212+
assertEquals("Element25", list.get(0));
213+
assertEquals("New100", list.get(25));
214+
}
215+
216+
@Test
217+
void testSpecialCharacters() {
218+
// Test with strings containing special characters
219+
list.append("Hello World!");
220+
list.append("Test@123");
221+
list.append("Special#$%");
222+
list.append(""); // Empty string
223+
224+
assertEquals("Hello World!", list.get(0));
225+
assertEquals("Test@123", list.get(1));
226+
assertEquals("Special#$%", list.get(2));
227+
assertEquals("", list.get(3));
228+
229+
assertEquals(3, list.indexOf(""));
230+
}
231+
232+
@Test
233+
void testLargeIndices() {
234+
list.append("Test");
235+
236+
// Test very large indices
237+
assertNull(list.get(Integer.MAX_VALUE));
238+
assertNull(list.get(1000));
239+
}
240+
241+
@Test
242+
void testSequentialRemovalByIndex() {
243+
list.append("A");
244+
list.append("B");
245+
list.append("C");
246+
list.append("D");
247+
248+
// Remove elements sequentially by index
249+
list.removeByIndex(1); // Remove "B"
250+
assertEquals("A", list.get(0));
251+
assertEquals("C", list.get(1));
252+
assertEquals("D", list.get(2));
253+
254+
list.removeByIndex(1); // Remove "C"
255+
assertEquals("A", list.get(0));
256+
assertEquals("D", list.get(1));
257+
assertNull(list.get(2));
258+
}
259+
260+
@Test
261+
void testAppendAfterRemoval() {
262+
list.append("First");
263+
list.append("Second");
264+
265+
list.remove("First");
266+
list.append("Third");
267+
268+
assertEquals("Second", list.get(0));
269+
assertEquals("Third", list.get(1));
270+
assertEquals(1, list.indexOf("Third"));
271+
}
272+
273+
@Test
274+
void testPerformanceWithManyOperations() {
275+
// Test with many mixed operations
276+
for (int i = 0; i < 50; i++) {
277+
list.append("Item" + i);
278+
}
279+
280+
// Remove every other element
281+
for (int i = 0; i < 50; i += 2) {
282+
list.remove("Item" + i);
283+
}
284+
285+
// Verify remaining elements
286+
assertEquals("Item1", list.get(0));
287+
assertEquals("Item3", list.get(1));
288+
assertEquals("Item5", list.get(2));
289+
290+
// Add more elements
291+
for (int i = 100; i < 110; i++) {
292+
list.append("New" + i);
293+
}
294+
295+
assertEquals("New100", list.get(25));
296+
}
112297
}

src/test/java/com/thealgorithms/datastructures/queues/DequeTest.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,77 @@ void testNullValues() {
121121
assertNull(deque.pollFirst());
122122
org.junit.jupiter.api.Assertions.assertTrue(deque.isEmpty());
123123
}
124+
125+
@Test
126+
void testMultipleAddFirst() {
127+
Deque<Integer> deque = new Deque<>();
128+
deque.addFirst(1);
129+
deque.addFirst(2);
130+
deque.addFirst(3);
131+
132+
assertEquals(3, deque.peekFirst(), "First element should be the last added to front");
133+
assertEquals(1, deque.peekLast(), "Last element should be the first added to front");
134+
assertEquals(3, deque.size(), "Size should reflect all additions");
135+
}
136+
137+
@Test
138+
void testMultipleAddLast() {
139+
Deque<Integer> deque = new Deque<>();
140+
deque.addLast(1);
141+
deque.addLast(2);
142+
deque.addLast(3);
143+
144+
assertEquals(1, deque.peekFirst(), "First element should be the first added to back");
145+
assertEquals(3, deque.peekLast(), "Last element should be the last added to back");
146+
assertEquals(3, deque.size(), "Size should reflect all additions");
147+
}
148+
149+
@Test
150+
void testSingleElementOperations() {
151+
Deque<Integer> deque = new Deque<>();
152+
deque.addFirst(1);
153+
154+
assertEquals(1, deque.peekFirst(), "Single element should be both first and last");
155+
assertEquals(1, deque.peekLast(), "Single element should be both first and last");
156+
assertEquals(1, deque.size());
157+
158+
assertEquals(1, deque.pollFirst(), "Should be able to poll single element from front");
159+
org.junit.jupiter.api.Assertions.assertTrue(deque.isEmpty(), "Deque should be empty after polling single element");
160+
}
161+
162+
@Test
163+
void testSingleElementPollLast() {
164+
Deque<Integer> deque = new Deque<>();
165+
deque.addLast(1);
166+
167+
assertEquals(1, deque.pollLast(), "Should be able to poll single element from back");
168+
org.junit.jupiter.api.Assertions.assertTrue(deque.isEmpty(), "Deque should be empty after polling single element");
169+
}
170+
171+
@Test
172+
void testMixedNullAndValues() {
173+
Deque<String> deque = new Deque<>();
174+
deque.addFirst("first");
175+
deque.addLast(null);
176+
deque.addFirst(null);
177+
deque.addLast("last");
178+
179+
assertEquals(4, deque.size(), "Should handle mixed null and non-null values");
180+
assertNull(deque.pollFirst(), "Should poll null from front");
181+
assertEquals("first", deque.pollFirst(), "Should poll non-null value");
182+
assertNull(deque.pollLast().equals("last") ? null : deque.peekLast(), "Should handle null correctly");
183+
}
184+
185+
@Test
186+
void testSymmetricOperations() {
187+
Deque<Integer> deque = new Deque<>();
188+
189+
// Test that addFirst/pollFirst and addLast/pollLast are symmetric
190+
deque.addFirst(1);
191+
deque.addLast(2);
192+
193+
assertEquals(1, deque.pollFirst(), "addFirst/pollFirst should be symmetric");
194+
assertEquals(2, deque.pollLast(), "addLast/pollLast should be symmetric");
195+
org.junit.jupiter.api.Assertions.assertTrue(deque.isEmpty(), "Deque should be empty after symmetric operations");
196+
}
124197
}

0 commit comments

Comments
 (0)