Skip to content

Commit edb8167

Browse files
authored
testing: improve test coverage NodeStackTest (#6432)
* testing: improve test coverage NodeStackTest * style: fix style issues * testing: fix type * testing: fix import * testing: fix import
1 parent fc07cd8 commit edb8167

File tree

1 file changed

+179
-2
lines changed

1 file changed

+179
-2
lines changed

src/test/java/com/thealgorithms/datastructures/stacks/NodeStackTest.java

Lines changed: 179 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
package com.thealgorithms.datastructures.stacks;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4-
import static org.junit.jupiter.api.Assertions.assertFalse;
54
import static org.junit.jupiter.api.Assertions.assertThrows;
65
import static org.junit.jupiter.api.Assertions.assertTrue;
76

7+
import org.junit.jupiter.api.BeforeEach;
8+
import org.junit.jupiter.api.DisplayName;
89
import org.junit.jupiter.api.Test;
910

1011
class NodeStackTest {
1112

13+
private NodeStack<Integer> intStack;
14+
private NodeStack<String> stringStack;
15+
16+
@BeforeEach
17+
void setUp() {
18+
intStack = new NodeStack<>();
19+
stringStack = new NodeStack<>();
20+
}
21+
1222
@Test
23+
@DisplayName("Test push operation")
1324
void testPush() {
1425
NodeStack<Integer> stack = new NodeStack<>();
1526
stack.push(10);
@@ -18,6 +29,7 @@ void testPush() {
1829
}
1930

2031
@Test
32+
@DisplayName("Test pop operation")
2133
void testPop() {
2234
NodeStack<String> stack = new NodeStack<>();
2335
stack.push("First");
@@ -27,12 +39,14 @@ void testPop() {
2739
}
2840

2941
@Test
42+
@DisplayName("Test pop on empty stack throws exception")
3043
void testPopOnEmptyStack() {
3144
NodeStack<Double> stack = new NodeStack<>();
3245
assertThrows(IllegalStateException.class, stack::pop, "Popping an empty stack should throw IllegalStateException.");
3346
}
3447

3548
@Test
49+
@DisplayName("Test peek operation")
3650
void testPeek() {
3751
NodeStack<Integer> stack = new NodeStack<>();
3852
stack.push(5);
@@ -43,22 +57,25 @@ void testPeek() {
4357
}
4458

4559
@Test
60+
@DisplayName("Test peek on empty stack throws exception")
4661
void testPeekOnEmptyStack() {
4762
NodeStack<String> stack = new NodeStack<>();
4863
assertThrows(IllegalStateException.class, stack::peek, "Peeking an empty stack should throw IllegalStateException.");
4964
}
5065

5166
@Test
67+
@DisplayName("Test isEmpty method")
5268
void testIsEmpty() {
5369
NodeStack<Character> stack = new NodeStack<>();
5470
assertTrue(stack.isEmpty(), "Newly initialized stack should be empty.");
5571
stack.push('A');
56-
assertFalse(stack.isEmpty(), "Stack should not be empty after a push operation.");
72+
org.junit.jupiter.api.Assertions.assertFalse(stack.isEmpty(), "Stack should not be empty after a push operation.");
5773
stack.pop();
5874
assertTrue(stack.isEmpty(), "Stack should be empty after popping the only element.");
5975
}
6076

6177
@Test
78+
@DisplayName("Test size method")
6279
void testSize() {
6380
NodeStack<Integer> stack = new NodeStack<>();
6481
assertEquals(0, stack.size(), "Size of empty stack should be 0.");
@@ -70,4 +87,164 @@ void testSize() {
7087
stack.pop();
7188
assertEquals(0, stack.size(), "Size should be 0 after popping all elements.");
7289
}
90+
91+
@Test
92+
@DisplayName("Test push and pop with null values")
93+
void testPushPopWithNull() {
94+
stringStack.push(null);
95+
stringStack.push("not null");
96+
stringStack.push(null);
97+
98+
assertEquals(3, stringStack.size(), "Stack should contain 3 elements including nulls");
99+
org.junit.jupiter.api.Assertions.assertNull(stringStack.pop(), "Should pop null value");
100+
assertEquals("not null", stringStack.pop(), "Should pop 'not null' value");
101+
org.junit.jupiter.api.Assertions.assertNull(stringStack.pop(), "Should pop null value");
102+
assertTrue(stringStack.isEmpty(), "Stack should be empty after popping all elements");
103+
}
104+
105+
@Test
106+
@DisplayName("Test LIFO (Last In First Out) behavior")
107+
void testLifoBehavior() {
108+
int[] values = {1, 2, 3, 4, 5};
109+
110+
// Push values in order
111+
for (int value : values) {
112+
intStack.push(value);
113+
}
114+
115+
// Pop values should be in reverse order
116+
for (int i = values.length - 1; i >= 0; i--) {
117+
assertEquals(values[i], intStack.pop(), "Elements should be popped in LIFO order");
118+
}
119+
}
120+
121+
@Test
122+
@DisplayName("Test peek doesn't modify stack")
123+
void testPeekDoesNotModifyStack() {
124+
intStack.push(1);
125+
intStack.push(2);
126+
intStack.push(3);
127+
128+
int originalSize = intStack.size();
129+
int peekedValue = intStack.peek();
130+
131+
assertEquals(3, peekedValue, "Peek should return top element");
132+
assertEquals(originalSize, intStack.size(), "Peek should not change stack size");
133+
assertEquals(3, intStack.peek(), "Multiple peeks should return same value");
134+
org.junit.jupiter.api.Assertions.assertFalse(intStack.isEmpty(), "Peek should not make stack empty");
135+
}
136+
137+
@Test
138+
@DisplayName("Test mixed push and pop operations")
139+
void testMixedOperations() {
140+
// Test interleaved push/pop operations
141+
intStack.push(1);
142+
assertEquals(1, intStack.pop());
143+
assertTrue(intStack.isEmpty());
144+
145+
intStack.push(2);
146+
intStack.push(3);
147+
assertEquals(3, intStack.pop());
148+
intStack.push(4);
149+
assertEquals(4, intStack.peek());
150+
assertEquals(2, intStack.size());
151+
152+
assertEquals(4, intStack.pop());
153+
assertEquals(2, intStack.pop());
154+
assertTrue(intStack.isEmpty());
155+
}
156+
157+
@Test
158+
@DisplayName("Test stack with duplicate values")
159+
void testStackWithDuplicates() {
160+
intStack.push(1);
161+
intStack.push(1);
162+
intStack.push(1);
163+
164+
assertEquals(3, intStack.size(), "Stack should handle duplicate values");
165+
assertEquals(1, intStack.peek(), "Peek should return duplicate value");
166+
167+
assertEquals(1, intStack.pop(), "Should pop first duplicate");
168+
assertEquals(1, intStack.pop(), "Should pop second duplicate");
169+
assertEquals(1, intStack.pop(), "Should pop third duplicate");
170+
assertTrue(intStack.isEmpty(), "Stack should be empty after popping all duplicates");
171+
}
172+
173+
@Test
174+
@DisplayName("Test stack with different data types")
175+
void testDifferentDataTypes() {
176+
NodeStack<Character> charStack = new NodeStack<>();
177+
NodeStack<Boolean> booleanStack = new NodeStack<>();
178+
179+
// Test with Character
180+
charStack.push('A');
181+
charStack.push('Z');
182+
assertEquals('Z', charStack.peek(), "Should handle Character values");
183+
184+
// Test with Boolean
185+
booleanStack.push(Boolean.TRUE);
186+
booleanStack.push(Boolean.FALSE);
187+
assertEquals(Boolean.FALSE, booleanStack.peek(), "Should handle Boolean values");
188+
}
189+
190+
@Test
191+
@DisplayName("Test stack state consistency after exceptions")
192+
void testStateConsistencyAfterExceptions() {
193+
// Stack should remain consistent after exception-throwing operations
194+
intStack.push(1);
195+
intStack.push(2);
196+
197+
// Try to peek and pop normally first
198+
assertEquals(2, intStack.peek());
199+
assertEquals(2, intStack.pop());
200+
assertEquals(1, intStack.size());
201+
202+
// Pop remaining element
203+
assertEquals(1, intStack.pop());
204+
assertTrue(intStack.isEmpty());
205+
206+
// Now stack is empty, operations should throw exceptions
207+
assertThrows(IllegalStateException.class, intStack::peek);
208+
assertThrows(IllegalStateException.class, intStack::pop);
209+
210+
// Stack should still be in valid empty state
211+
assertTrue(intStack.isEmpty());
212+
assertEquals(0, intStack.size());
213+
214+
// Should be able to push after exceptions
215+
intStack.push(3);
216+
org.junit.jupiter.api.Assertions.assertFalse(intStack.isEmpty());
217+
assertEquals(1, intStack.size());
218+
assertEquals(3, intStack.peek());
219+
}
220+
221+
@Test
222+
@DisplayName("Test single element stack operations")
223+
void testSingleElementStack() {
224+
intStack.push(2);
225+
226+
org.junit.jupiter.api.Assertions.assertFalse(intStack.isEmpty(), "Stack with one element should not be empty");
227+
assertEquals(1, intStack.size(), "Size should be 1");
228+
assertEquals(2, intStack.peek(), "Peek should return the single element");
229+
assertEquals(1, intStack.size(), "Peek should not change size");
230+
231+
assertEquals(2, intStack.pop(), "Pop should return the single element");
232+
assertTrue(intStack.isEmpty(), "Stack should be empty after popping single element");
233+
assertEquals(0, intStack.size(), "Size should be 0 after popping single element");
234+
}
235+
236+
@Test
237+
@DisplayName("Test toString method if implemented")
238+
void testToString() {
239+
// This test assumes NodeStack has a toString method
240+
// If not implemented, this test can be removed or NodeStack can be enhanced
241+
intStack.push(1);
242+
intStack.push(2);
243+
intStack.push(3);
244+
245+
String stackString = intStack.toString();
246+
// Basic check that toString doesn't throw exception and returns something
247+
assertTrue(stackString != null, "toString should not return null");
248+
assertTrue(stackString.length() > 0, "toString should return non-empty string");
249+
}
73250
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy