11package com .thealgorithms .datastructures .trees ;
22
3+ import static org .junit .jupiter .api .Assertions .assertAll ;
4+ import static org .junit .jupiter .api .Assertions .assertDoesNotThrow ;
35import static org .junit .jupiter .api .Assertions .assertEquals ;
46
57import com .thealgorithms .devutils .ConsoleInterceptor ;
@@ -20,11 +22,13 @@ public class AVLSimpleTest {
2022 Setup/TearDown
2123 ======================== */
2224
25+ /** Starts capturing System.in. */
2326 @ BeforeEach
2427 void setup () {
2528 interceptor .captureOutput ();
2629 }
2730
31+ /** Cleans up after each test by closing the interceptor. */
2832 @ AfterEach
2933 void tearDown () {
3034 interceptor .close ();
@@ -34,10 +38,29 @@ void tearDown() {
3438 Helper methods
3539 ======================== */
3640
41+ /**
42+ * Returns a string representation of the expected tree after inserting
43+ * the values 10, 20, and 30 in any order.
44+ * <p>
45+ * The returned string follows the same format as the tree's display method,
46+ * where each node is represented in the form "left=>value<=right" and "END"
47+ * denotes an empty (null) child.
48+ * @return a string representing the expected tree structure
49+ */
3750 String getExpectedTree () {
3851 return "10=>20<=30END=>10<=ENDEND=>30<=END2" ;
3952 }
4053
54+ /**
55+ * Returns the actual string representation of the tree as printed
56+ * by the display method.
57+ *
58+ * <p>This method captures the console output via the interceptor and
59+ * removes all newline characters, returning a single-line string
60+ * suitable for comparison with the expected tree string.
61+ *
62+ * @return the actual tree structure as a single-line string
63+ */
4164 String getActualTree () {
4265 return interceptor .getAndClearConsoleOutput ().replaceAll ("[\\ r\\ n]" , "" );
4366 }
@@ -47,7 +70,7 @@ String getActualTree() {
4770 ======================== */
4871
4972 @ Test
50- @ DisplayName ("A longer generic AVL tree creation that should pass " )
73+ @ DisplayName ("Creates a longer simple AVL tree that matches the expected layout " )
5174 void testTreeCreation () {
5275 tree .insert (25 );
5376 tree .insert (30 );
@@ -77,52 +100,51 @@ void testEmptyTree() {
77100 }
78101
79102 @ ParameterizedTest
80- @ MethodSource ("getTreeNodesInput " )
103+ @ MethodSource ("getTreeNodesValues " )
81104 @ DisplayName ("Test to ensure all rotation paths are covered" )
82- void testAllRotations (int node1 , int node2 , int node3 ) {
83- tree .insert (node1 );
84- tree .insert (node2 );
85- tree .insert (node3 );
105+ void testAllRotations (int node1 , int node2 , int node3 , String errorMessage ) {
106+ assertAll (() -> assertDoesNotThrow (() -> tree .insert (node1 ), "inserting: " + node1 ), () -> assertDoesNotThrow (() -> tree .insert (node2 ), "inserting: " + node2 ), () -> assertDoesNotThrow (() -> tree .insert (node3 ), "inserting: " + node3 ));
86107
87108 tree .display ();
88109
89- assertEquals (getExpectedTree (), getActualTree ());
110+ assertEquals (getExpectedTree (), getActualTree (), errorMessage );
90111 }
91112
92- public static Stream <Arguments > getTreeNodesInput () {
93- return Stream .of (Arguments .of (30 , 20 , 10 ), Arguments .of (30 , 10 , 20 ), Arguments .of (10 , 20 , 30 ), Arguments .of (10 , 30 , 20 ));
113+ public static Stream <Arguments > getTreeNodesValues () {
114+ return Stream .of (Arguments .of (30 , 20 , 10 , "LL rotation failed" ), Arguments .of (30 , 10 , 20 , "LR rotation failed" ), Arguments .of (10 , 20 , 30 , "RR rotation failed" ), Arguments .of (10 , 30 , 20 , "RL rotation failed" ));
94115 }
95116
96117 @ ParameterizedTest
97118 @ MethodSource ("getTreeNodesInputForBFEqualsOneRotations" )
98- @ DisplayName ("Rotation not triggered when balance factor equals threshold" )
99- void testRotatesNotTriggeredWhenBFEqualsOne (int node , String expectedTree ) {
100- tree .insert (30 );
119+ @ DisplayName ("Checks rotation isn't triggered when balance factor equals threshold" )
120+ void testRotationsNotTriggeredWhenBFEqualsOne (int boundaryNode , String expectedTree , String errorMessage ) {
101121 tree .insert (20 );
122+ tree .insert (30 );
102123 tree .insert (10 );
103- tree .insert (node );
124+ tree .insert (boundaryNode );
104125
105126 tree .display ();
106127
107- assertEquals (expectedTree , getActualTree ());
128+ assertEquals (expectedTree , getActualTree (), errorMessage );
108129 }
109130
110131 public static Stream <Arguments > getTreeNodesInputForBFEqualsOneRotations () {
111- return Stream .of (Arguments .of (5 , "10=>20<=305=>10<=ENDEND=>5<=ENDEND=>30<=END3" ), Arguments .of (35 , "10=>20<=30END=>10<=ENDEND=>30<=35END=>35<=END3" ));
132+ return Stream .of (Arguments .of (5 , "10=>20<=305=>10<=ENDEND=>5<=ENDEND=>30<=END3" , "Insertion of 5 should not trigger rotation" ), Arguments .of (15 , "10=>20<=30END=>10<=15END=>15<=ENDEND=>30<=END3" , "Insertion of 15 should not trigger rotation" ),
133+ Arguments .of (25 , "10=>20<=30END=>10<=END25=>30<=ENDEND=>25<=END3" , "Insertion of 25 should not trigger rotation" ), Arguments .of (35 , "10=>20<=30END=>10<=ENDEND=>30<=35END=>35<=END3" , "Insertion of 35 should not trigger rotation" ));
112134 }
113135
114136 @ Test
115- @ DisplayName ("Should return true for a tree that don't account for duplicates " )
116- void testDuplicatesInTreeCreationDoNotStick () {
137+ @ DisplayName ("Ignores duplicate insertions and create a tree with depth one " )
138+ void testDuplicateInsertionsIgnored () {
117139 int duplicate = 20 ;
118- tree .insert (30 );
119140 tree .insert (duplicate );
120- tree .insert (20 );
121141 tree .insert (duplicate );
122- tree .insert (10 );
142+ tree .insert (duplicate );
123143
124144 tree .display ();
125145
126- assertEquals (getExpectedTree (), getActualTree ());
146+ String actualTree = getActualTree ();
147+
148+ assertEquals ('1' , actualTree .charAt (actualTree .length () - 1 ));
127149 }
128150}
0 commit comments