1
+ package stack .implementation ;
2
+
3
+ import org .junit .jupiter .api .AfterEach ;
4
+ import org .junit .jupiter .api .BeforeEach ;
5
+ import org .junit .jupiter .api .DisplayName ;
6
+ import org .junit .jupiter .api .Test ;
7
+
8
+ import java .io .ByteArrayOutputStream ;
9
+ import java .io .PrintStream ;
10
+ import java .util .EmptyStackException ;
11
+
12
+ import static org .junit .jupiter .api .Assertions .*;
13
+
14
+
15
+ class ArrayTest {
16
+
17
+ private final ByteArrayOutputStream outContent = new ByteArrayOutputStream ();
18
+ private final PrintStream originalOut = System .out ;
19
+
20
+ private Array stack ;
21
+
22
+ @ BeforeEach
23
+ void setUp () {
24
+ // Create a new stack with a capacity of 5 before each test
25
+ stack = new Array (5 );
26
+ // Redirect System.out to our stream capture
27
+ System .setOut (new PrintStream (outContent ));
28
+ }
29
+
30
+ @ AfterEach
31
+ void tearDown () {
32
+ // Restore the original System.out stream
33
+ System .setOut (originalOut );
34
+ }
35
+
36
+ @ Test
37
+ @ DisplayName ("A new stack should be empty" )
38
+ void newStackIsEmpty () {
39
+ assertTrue (stack .isEmpty (), "A newly created stack should be empty." );
40
+ assertEquals (0 , stack .size (), "A newly created stack should have a size of 0." );
41
+ assertFalse (stack .isFull (), "A newly created stack should not be full." );
42
+ }
43
+
44
+ @ Test
45
+ @ DisplayName ("Pushing an element should increase size and allow peeking" )
46
+ void pushAndPeek () {
47
+ stack .push (10 );
48
+ assertFalse (stack .isEmpty ());
49
+ assertEquals (1 , stack .size ());
50
+ assertEquals (10 , stack .peek (), "Peek should return the last element pushed." );
51
+
52
+ stack .push (20 );
53
+ assertEquals (2 , stack .size ());
54
+ assertEquals (20 , stack .peek (), "Peek should be updated after a new push." );
55
+ }
56
+
57
+ @ Test
58
+ @ DisplayName ("Popping an element should return it and decrease size (LIFO)" )
59
+ void popFollowsLifo () {
60
+ stack .push (10 );
61
+ stack .push (20 );
62
+ stack .push (30 );
63
+
64
+ assertEquals (3 , stack .size ());
65
+
66
+ assertEquals (30 , stack .pop (), "Pop should return the last element added (30)." );
67
+ assertEquals (2 , stack .size (), "Size should decrease after pop." );
68
+
69
+ assertEquals (20 , stack .pop (), "Pop should return the next element (20)." );
70
+ assertEquals (1 , stack .size ());
71
+
72
+ assertEquals (10 , stack .pop (), "Pop should return the final element (10)." );
73
+ assertEquals (0 , stack .size ());
74
+ assertTrue (stack .isEmpty (), "Stack should be empty after all elements are popped." );
75
+ }
76
+
77
+ @ Test
78
+ @ DisplayName ("Peeking into an empty stack should throw EmptyStackException" )
79
+ void peekOnEmptyStackThrowsException () {
80
+ assertTrue (stack .isEmpty ());
81
+ assertThrows (EmptyStackException .class , () -> stack .peek (), "Peeking into an empty stack must throw EmptyStackException." );
82
+ }
83
+
84
+ @ Test
85
+ @ DisplayName ("Popping from an empty stack should throw EmptyStackException" )
86
+ void popOnEmptyStackThrowsException () {
87
+ assertTrue (stack .isEmpty ());
88
+ assertThrows (EmptyStackException .class , () -> stack .pop (), "Popping from an empty stack must throw EmptyStackException." );
89
+ }
90
+
91
+ @ Test
92
+ @ DisplayName ("Pushing to a full stack should throw StackOverflowError" )
93
+ void pushOnFullStackThrowsException () {
94
+ // Fill the stack to its capacity
95
+ stack .push (1 );
96
+ stack .push (2 );
97
+ stack .push (3 );
98
+ stack .push (4 );
99
+ stack .push (5 );
100
+
101
+ assertTrue (stack .isFull (), "Stack should be full after pushing 5 elements." );
102
+ assertEquals (5 , stack .size ());
103
+
104
+ // Assert that the next push throws the expected error
105
+ assertThrows (StackOverflowError .class , () -> stack .push (6 ), "Pushing to a full stack must throw StackOverflowError." );
106
+ }
107
+
108
+ @ Test
109
+ @ DisplayName ("isFull should be true only at maximum capacity" )
110
+ void isFull () {
111
+ Array smallStack = new Array (2 );
112
+ assertFalse (smallStack .isFull ());
113
+
114
+ smallStack .push (1 );
115
+ assertFalse (smallStack .isFull ());
116
+
117
+ smallStack .push (2 );
118
+ assertTrue (smallStack .isFull ());
119
+ }
120
+
121
+ @ Test
122
+ @ DisplayName ("Constructor with negative capacity should throw NegativeArraySizeException" )
123
+ void constructorWithNegativeCapacityThrowsException () {
124
+ assertThrows (NegativeArraySizeException .class , () -> new Array (-1 ), "Constructor should not allow a negative size." );
125
+ }
126
+
127
+ @ Test
128
+ @ DisplayName ("display() on an empty stack should print correctly" )
129
+ void displayOnEmptyStack () {
130
+ stack .display ();
131
+ String expectedOutput = "Stack (top to bottom): [ ]" + System .lineSeparator ();
132
+ assertEquals (expectedOutput , outContent .toString ());
133
+ }
134
+
135
+ @ Test
136
+ @ DisplayName ("display() on a populated stack should print elements top-to-bottom" )
137
+ void displayOnPopulatedStack () {
138
+ stack .push (10 );
139
+ stack .push (20 );
140
+ stack .push (30 );
141
+
142
+ stack .display ();
143
+
144
+ // Note the LIFO order in the output (30 is on top)
145
+ String expectedOutput = "Stack (top to bottom): [ 30 20 10 ]" + System .lineSeparator ();
146
+ assertEquals (expectedOutput , outContent .toString ());
147
+ }
148
+ }
0 commit comments