From c7b5e3c97cb91b6bb0b5421727e2d293d20ba68d Mon Sep 17 00:00:00 2001 From: roost-io Date: Wed, 19 Nov 2025 14:55:28 +0000 Subject: [PATCH] Unit test generated by RoostGPT Using AI Model claude-sonnet-4-20250514 --- pom.xml | 370 ++++++++++++----- ...erAccountControllerUpdateUserByIdTest.java | 301 ++++++++++++++ .../AlgorithmBlenderAlgorithmCalcTest.java | 366 +++++++++++++++++ ...apFunctionsOrdenarHashMapPorValorTest.java | 381 ++++++++++++++++++ 4 files changed, 1322 insertions(+), 96 deletions(-) create mode 100644 src/test/java/com/medeiros/SPRINGProject/Controllers/UserAccountControllerUpdateUserByIdTest.java create mode 100644 src/test/java/com/medeiros/SPRINGProject/algorithm/AlgorithmBlenderAlgorithmCalcTest.java create mode 100644 src/test/java/com/medeiros/SPRINGProject/utils/HashMapFunctionsOrdenarHashMapPorValorTest.java diff --git a/pom.xml b/pom.xml index d5e071f..522c44d 100644 --- a/pom.xml +++ b/pom.xml @@ -1,96 +1,274 @@ - - - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 3.0.6 - - - com.medeiros - SPRINGProject - 0.0.1-SNAPSHOT - SPRINGProject - Demo project for Spring Boot - - 20 - - 6.0.3 - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-starter-web - - - - org.springframework.boot - spring-boot-devtools - runtime - true - - - com.mysql - mysql-connector-j - runtime - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.springframework.boot - spring-boot-starter-thymeleaf - 3.0.6 - - - - org.springframework.boot - spring-boot-starter-security - - - - io.jsonwebtoken - jjwt-api - 0.11.5 - - - - - - - org.springframework.security - spring-security-core - 6.0.3 - - - - - - - io.jsonwebtoken - jjwt-impl - 0.11.5 - runtime - - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.0.6 + + + + com.medeiros + SPRINGProject + 0.0.1-SNAPSHOT + SPRINGProject + Demo project for Spring Boot + + 20 + + 6.0.3 + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-devtools + runtime + true + + + com.mysql + mysql-connector-j + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-thymeleaf + 3.0.6 + + + org.springframework.boot + spring-boot-starter-security + + + org.mockito + mockito-junit-jupiter + 2.23.4 + + + + io.spring.javaformat + spring-javaformat-formatter + 0.0.40 + + + + io.jsonwebtoken + jjwt-api + 0.11.5 + compile + + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + compile + + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + compile + + + + org.junit.jupiter + junit-jupiter-api + 5.9.3 + compile + + + + org.junit.jupiter + junit-jupiter-engine + 5.9.3 + compile + + + + org.mockito + mockito-core + 5.3.1 + compile + + + + net.bytebuddy + byte-buddy + 1.14.4 + compile + + + + net.bytebuddy + byte-buddy-agent + 1.14.4 + compile + + + + org.objenesis + objenesis + 3.3 + compile + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + org.jacoco + jacoco-maven-plugin + 0.8.11 + + + + prepare-agent + + + + report + test + + report + + + coverageReport + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + + + + org.apache.maven.plugins + maven-surefire-report-plugin + 3.2.5 + + testReport + + + + + org.apache.maven.plugins + maven-site-plugin + 2.1 + + testReport + + + + + io.spring.javaformat + spring-javaformat-maven-plugin + 0.0.40 + + + + + + + + + + + org.mockito + mockito-junit-jupiter + 2.23.4 + + + + io.spring.javaformat + spring-javaformat-formatter + 0.0.40 + + + + io.jsonwebtoken + jjwt-api + 0.11.5 + compile + + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + compile + + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + compile + + + + org.junit.jupiter + junit-jupiter-api + 5.9.3 + compile + + + + org.junit.jupiter + junit-jupiter-engine + 5.9.3 + compile + + + + org.mockito + mockito-core + 5.3.1 + compile + + + + net.bytebuddy + byte-buddy + 1.14.4 + compile + + + + net.bytebuddy + byte-buddy-agent + 1.14.4 + compile + + + + org.objenesis + objenesis + 3.3 + compile + + + + + \ No newline at end of file diff --git a/src/test/java/com/medeiros/SPRINGProject/Controllers/UserAccountControllerUpdateUserByIdTest.java b/src/test/java/com/medeiros/SPRINGProject/Controllers/UserAccountControllerUpdateUserByIdTest.java new file mode 100644 index 0000000..e4d7f2f --- /dev/null +++ b/src/test/java/com/medeiros/SPRINGProject/Controllers/UserAccountControllerUpdateUserByIdTest.java @@ -0,0 +1,301 @@ + +// ********RoostGPT******** +/* +Test generated by RoostGPT for test java-music using AI Type Claude AI and AI Model claude-sonnet-4-20250514 + +ROOST_METHOD_HASH=updateUserById_45a90e9627 +ROOST_METHOD_SIG_HASH=updateUserById_9cf5a84c94 + +Scenario 1: Successfully Update User with Valid ID and Parameters + +Details: + TestName: updateUserByIdWithValidParametersReturnsSuccessMessage + Description: This test verifies that when a valid user ID is provided along with valid email, password, and username parameters, the method successfully updates the user and returns a success message in Portuguese. + +Execution: + Arrange: Create a mock User_Credentials object with a valid ID (e.g., 1). Set up the UserAccRepo mock to return this user when findById is called. Prepare valid test data for email, password, and username parameters. + Act: Call updateUserById method with valid string ID "1" and valid email, password, and username parameters. + Assert: Verify that the method returns "Usuário Salvo" and that UserAccRepo.save() was called with the updated user object. + +Validation: + This assertion verifies that the happy path scenario works correctly when all inputs are valid. The test ensures that the user data is properly updated and persisted, which is critical for maintaining data integrity in user management operations. + +Scenario 2: User Not Found with Valid ID Format + +Details: + TestName: updateUserByIdWithNonExistentUserReturnsNotFoundMessage + Description: This test checks the behavior when a valid numeric ID format is provided but no user exists with that ID in the database. + +Execution: + Arrange: Set up UserAccRepo mock to return null when findById is called with any integer value. Prepare valid test parameters for email, password, and username. + Act: Call updateUserById method with a non-existent user ID "999" and valid other parameters. + Assert: Verify that the method returns "User não encontrado" and that UserAccRepo.save() is never called. + +Validation: + This assertion ensures proper error handling when attempting to update a non-existent user. The test validates that the system gracefully handles missing user scenarios without attempting database operations, preventing potential data corruption. + +Scenario 3: Invalid ID Format Causes NumberFormatException + +Details: + TestName: updateUserByIdWithInvalidIdFormatThrowsNumberFormatException + Description: This test verifies that when an invalid ID format (non-numeric string) is provided, the method throws a NumberFormatException due to Integer.parseInt() failure. + +Execution: + Arrange: Prepare invalid ID string "invalid_id" and valid parameters for email, password, and username. No need to mock UserAccRepo since the exception occurs before database access. + Act: Call updateUserById method with invalid ID format and valid other parameters. + Assert: Verify that NumberFormatException is thrown and that no database operations are performed. + +Validation: + This assertion validates input validation behavior and ensures that the system properly handles malformed input data. The test is important for security and stability, preventing unexpected application crashes from invalid user input. + +Scenario 4: Update User with Empty String Parameters + +Details: + TestName: updateUserByIdWithEmptyStringParametersUpdatesUserWithEmptyValues + Description: This test examines the behavior when valid ID is provided but email, password, and username parameters are empty strings. + +Execution: + Arrange: Create a mock User_Credentials object with valid ID. Set up UserAccRepo to return this user. Prepare empty string values for email, password, and username parameters. + Act: Call updateUserById method with valid ID "1" and empty string parameters. + Assert: Verify that the method returns "Usuário Salvo", the user object's fields are set to empty strings, and UserAccRepo.save() is called. + +Validation: + This assertion checks whether the system allows empty values for user credentials. The test reveals potential business logic issues where empty credentials might be considered valid, which could impact application security and data quality. + +Scenario 5: Update User with Null String Parameters + +Details: + TestName: updateUserByIdWithNullParametersUpdatesUserWithNullValues + Description: This test verifies the method's behavior when null values are passed for email, password, and username parameters while providing a valid user ID. + +Execution: + Arrange: Create a mock User_Credentials object with valid ID. Configure UserAccRepo mock to return this user. Set email, password, and username parameters to null. + Act: Call updateUserById method with valid ID "1" and null parameters. + Assert: Verify that the method returns "Usuário Salvo", the user object's fields are set to null values, and UserAccRepo.save() is called. + +Validation: + This assertion tests null value handling in the update process. The test is crucial for understanding data integrity constraints and whether the system properly validates required fields before persistence. + +Scenario 6: Update User with Very Long String Parameters + +Details: + TestName: updateUserByIdWithVeryLongParametersUpdatesSuccessfully + Description: This test checks the method's behavior when extremely long strings are provided for email, password, and username parameters. + +Execution: + Arrange: Create a mock User_Credentials object with valid ID. Set up UserAccRepo mock appropriately. Prepare very long strings (e.g., 1000+ characters) for all parameter values. + Act: Call updateUserById method with valid ID "1" and very long string parameters. + Assert: Verify that the method returns "Usuário Salvo" and that the user object is updated with the long values. + +Validation: + This assertion validates the system's handling of boundary conditions regarding string length. The test helps identify potential database constraints or memory issues that could arise from processing large input values. + +Scenario 7: Update User with Special Characters in Parameters + +Details: + TestName: updateUserByIdWithSpecialCharactersUpdatesSuccessfully + Description: This test verifies that the method correctly handles special characters, Unicode characters, and symbols in the email, password, and username parameters. + +Execution: + Arrange: Create a mock User_Credentials object with valid ID. Configure UserAccRepo mock to return this user. Prepare parameters containing special characters, emojis, and Unicode symbols. + Act: Call updateUserById method with valid ID "1" and parameters containing special characters. + Assert: Verify that the method returns "Usuário Salvo" and that all special characters are properly preserved in the user object. + +Validation: + This assertion ensures proper character encoding and handling of international characters. The test is important for applications supporting multiple languages and special character sets in user credentials. + +Scenario 8: Update User with Zero as ID + +Details: + TestName: updateUserByIdWithZeroIdHandlesEdgeCase + Description: This test examines the method's behavior when ID "0" is provided, which is a valid integer but might be an edge case for database operations. + +Execution: + Arrange: Set up UserAccRepo mock to return null when findById(0) is called (assuming 0 is not a valid user ID). Prepare valid parameters for other fields. + Act: Call updateUserById method with ID "0" and valid other parameters. + Assert: Verify that the method returns "User não encontrado" since no user typically exists with ID 0. + +Validation: + This assertion tests edge case handling for boundary values in ID parameters. The test ensures that the system properly handles potentially invalid but technically parseable ID values. + +Scenario 9: Update User with Negative ID + +Details: + TestName: updateUserByIdWithNegativeIdHandlesEdgeCase + Description: This test verifies the method's behavior when a negative ID is provided, which is a valid integer but likely invalid for database primary keys. + +Execution: + Arrange: Configure UserAccRepo mock to return null when findById is called with any negative integer. Prepare valid parameters for email, password, and username. + Act: Call updateUserById method with negative ID "-1" and valid other parameters. + Assert: Verify that the method returns "User não encontrado" and no save operation is performed. + +Validation: + This assertion validates the system's handling of logically invalid but syntactically correct input values. The test ensures robust error handling for edge cases that might occur in real-world usage scenarios. + +*/ + +// ********RoostGPT******** + +package com.medeiros.SPRINGProject.Controllers; + +import com.medeiros.SPRINGProject.Models.*; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Tag; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import java.time.LocalDateTime; +import java.util.Objects; +import java.util.Optional; + +class UserAccountControllerUpdateUserByIdTest { + + @Mock + private UserAccRepository UserAccRepo; + + @Mock + private UserInfoRepository UserInfoRepo; + + @Mock + private LogRepository Log; + + @InjectMocks + private UserAccountController userAccountController; + + private User_Credentials mockUser; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + mockUser = new User_Credentials(); + mockUser.setId(1); + mockUser.setEmail("test@example.com"); + mockUser.setPassword("password123"); + mockUser.setUsername("testuser"); + } + + @Test + @Tag("valid") + void updateUserByIdWithValidParametersReturnsSuccessMessage() { + when(UserAccRepo.findById(1)).thenReturn(mockUser); + + String result = userAccountController.updateUserById("1", "newemail@example.com", "newpassword", "newusername"); + + assertEquals("Usuário Salvo", result); + assertEquals("newemail@example.com", mockUser.getEmail()); + assertEquals("newpassword", mockUser.getPassword()); + assertEquals("newusername", mockUser.getUsername()); + verify(UserAccRepo).save(mockUser); + } + + @Test + @Tag("invalid") + void updateUserByIdWithNonExistentUserReturnsNotFoundMessage() { + when(UserAccRepo.findById(999)).thenReturn(null); + + String result = userAccountController.updateUserById("999", "test@example.com", "password", "username"); + + assertEquals("User não encontrado", result); + verify(UserAccRepo, never()).save(any()); + } + + @Test + @Tag("invalid") + void updateUserByIdWithInvalidIdFormatThrowsNumberFormatException() { + assertThrows(NumberFormatException.class, () -> { + userAccountController.updateUserById("invalid_id", "test@example.com", "password", "username"); + }); + + verify(UserAccRepo, never()).findById(anyInt()); + verify(UserAccRepo, never()).save(any()); + } + + @Test + @Tag("boundary") + void updateUserByIdWithEmptyStringParametersUpdatesUserWithEmptyValues() { + when(UserAccRepo.findById(1)).thenReturn(mockUser); + + String result = userAccountController.updateUserById("1", "", "", ""); + + assertEquals("Usuário Salvo", result); + assertEquals("", mockUser.getEmail()); + assertEquals("", mockUser.getPassword()); + assertEquals("", mockUser.getUsername()); + verify(UserAccRepo).save(mockUser); + } + + @Test + @Tag("boundary") + void updateUserByIdWithNullParametersUpdatesUserWithNullValues() { + when(UserAccRepo.findById(1)).thenReturn(mockUser); + + String result = userAccountController.updateUserById("1", null, null, null); + + assertEquals("Usuário Salvo", result); + assertNull(mockUser.getEmail()); + assertNull(mockUser.getPassword()); + assertNull(mockUser.getUsername()); + verify(UserAccRepo).save(mockUser); + } + + @Test + @Tag("boundary") + void updateUserByIdWithVeryLongParametersUpdatesSuccessfully() { + when(UserAccRepo.findById(1)).thenReturn(mockUser); + String longString = "a".repeat(1000); + + String result = userAccountController.updateUserById("1", longString, longString, longString); + + assertEquals("Usuário Salvo", result); + assertEquals(longString, mockUser.getEmail()); + assertEquals(longString, mockUser.getPassword()); + assertEquals(longString, mockUser.getUsername()); + verify(UserAccRepo).save(mockUser); + } + + @Test + @Tag("valid") + void updateUserByIdWithSpecialCharactersUpdatesSuccessfully() { + when(UserAccRepo.findById(1)).thenReturn(mockUser); + String specialEmail = "test@éxample.com"; + String specialPassword = "pássw0rd!@#$%"; + String specialUsername = "üser_ñame🚀"; + + String result = userAccountController.updateUserById("1", specialEmail, specialPassword, specialUsername); + + assertEquals("Usuário Salvo", result); + assertEquals(specialEmail, mockUser.getEmail()); + assertEquals(specialPassword, mockUser.getPassword()); + assertEquals(specialUsername, mockUser.getUsername()); + verify(UserAccRepo).save(mockUser); + } + + @Test + @Tag("boundary") + void updateUserByIdWithZeroIdHandlesEdgeCase() { + when(UserAccRepo.findById(0)).thenReturn(null); + + String result = userAccountController.updateUserById("0", "test@example.com", "password", "username"); + + assertEquals("User não encontrado", result); + verify(UserAccRepo, never()).save(any()); + } + + @Test + @Tag("boundary") + void updateUserByIdWithNegativeIdHandlesEdgeCase() { + when(UserAccRepo.findById(-1)).thenReturn(null); + + String result = userAccountController.updateUserById("-1", "test@example.com", "password", "username"); + + assertEquals("User não encontrado", result); + verify(UserAccRepo, never()).save(any()); + } + +} \ No newline at end of file diff --git a/src/test/java/com/medeiros/SPRINGProject/algorithm/AlgorithmBlenderAlgorithmCalcTest.java b/src/test/java/com/medeiros/SPRINGProject/algorithm/AlgorithmBlenderAlgorithmCalcTest.java new file mode 100644 index 0000000..8d6c581 --- /dev/null +++ b/src/test/java/com/medeiros/SPRINGProject/algorithm/AlgorithmBlenderAlgorithmCalcTest.java @@ -0,0 +1,366 @@ + +// ********RoostGPT******** +/* +Test generated by RoostGPT for test java-music using AI Type Claude AI and AI Model claude-sonnet-4-20250514 + +ROOST_METHOD_HASH=algorithmCalc_e489e5c1fc +ROOST_METHOD_SIG_HASH=algorithmCalc_009085eae1 + +Scenario 1: Valid Music List with Multiple Items + +Details: + TestName: algorithmCalcWithValidMusicList + Description: This test verifies that the algorithmCalc method correctly processes a list of MusicModel objects and returns a HashMap with music names as keys and calculated algorithm points as values. The test ensures that the method properly iterates through all music items and calculates points based on likes and comments. +Execution: + Arrange: Create a list of MusicModel objects with different numbers of likes and comments. Mock the algorithmData (AD) methods to return predictable point values for likes and comments. + Act: Call the algorithmCalc method with the prepared list of MusicModel objects. + Assert: Verify that the returned HashMap contains the correct number of entries, proper music names as keys, and expected calculated points as values. +Validation: + This assertion verifies that the core functionality of the algorithm calculation works correctly with valid input data. The test ensures that the method properly combines likes points and comments points for each music item, which is essential for the application's music ranking system. + +Scenario 2: Empty Music List + +Details: + TestName: algorithmCalcWithEmptyList + Description: This test checks the behavior of the algorithmCalc method when provided with an empty Iterable of MusicModel objects. It ensures that the method handles empty collections gracefully without throwing exceptions. +Execution: + Arrange: Create an empty ArrayList or any empty Iterable implementation of MusicModel. + Act: Invoke the algorithmCalc method with the empty collection. + Assert: Verify that the method returns an empty HashMap without throwing any exceptions. +Validation: + This test ensures robustness when dealing with edge cases where no music data is available. It validates that the method doesn't fail when processing empty collections, which is important for maintaining application stability in scenarios where no music items are present. + +Scenario 3: Single Music Item + +Details: + TestName: algorithmCalcWithSingleMusicItem + Description: This test validates the method's behavior when processing a collection containing only one MusicModel object. It ensures that the calculation logic works correctly for the minimal valid input case. +Execution: + Arrange: Create a single MusicModel object with specific numbers of likes and comments. Set up mock responses for the algorithmData methods. + Act: Call the algorithmCalc method with a collection containing the single music item. + Assert: Verify that the returned HashMap contains exactly one entry with the correct music name and calculated points. +Validation: + This test confirms that the method works correctly with the smallest possible valid dataset. It's crucial for ensuring that the basic calculation logic functions properly and that the HashMap population mechanism works for individual items. + +Scenario 4: Music Items with Zero Likes and Comments + +Details: + TestName: algorithmCalcWithZeroLikesAndComments + Description: This test examines how the method handles MusicModel objects that have zero likes and zero comments. It ensures that the algorithm calculation doesn't break when dealing with music items that have no engagement. +Execution: + Arrange: Create MusicModel objects with zero likes and zero comments. Configure the algorithmData mock to return appropriate point values for zero inputs. + Act: Execute the algorithmCalc method with the collection of zero-engagement music items. + Assert: Verify that the method returns a HashMap with correct entries and that the calculated points reflect the zero engagement values. +Validation: + This test ensures that the application can handle music items with no user engagement without errors. It's important for maintaining data integrity when processing newly uploaded or unpopular music items that haven't received any likes or comments yet. + +Scenario 5: Music Items with Maximum Integer Values + +Details: + TestName: algorithmCalcWithMaximumValues + Description: This test evaluates the method's behavior when processing MusicModel objects with very large numbers of likes and comments (near Integer.MAX_VALUE). It checks for potential overflow issues in the calculation logic. +Execution: + Arrange: Create MusicModel objects with likes and comments set to very large integer values. Mock the algorithmData methods to return appropriate responses for these extreme values. + Act: Call the algorithmCalc method with the collection containing high-value music items. + Assert: Verify that the method completes successfully and returns valid results without integer overflow or other numerical issues. +Validation: + This test ensures that the application can handle extreme cases where music items have very high engagement numbers. It's crucial for preventing numerical overflow errors that could occur with viral or extremely popular music content. + +Scenario 6: Duplicate Music Names + +Details: + TestName: algorithmCalcWithDuplicateMusicNames + Description: This test checks how the method handles multiple MusicModel objects that have the same music name. Since HashMap keys must be unique, this test verifies which value is retained when duplicate keys are encountered. +Execution: + Arrange: Create multiple MusicModel objects with identical music names but different likes and comments values. Set up appropriate mock responses for the algorithmData calculations. + Act: Execute the algorithmCalc method with the collection containing duplicate music names. + Assert: Verify that the returned HashMap contains only one entry per unique music name and confirm which calculated value is retained (typically the last one processed). +Validation: + This test validates the method's behavior when dealing with data inconsistencies where multiple music entries share the same name. Understanding this behavior is important for data integrity and helps identify potential issues in the music data model. + +Scenario 7: Null Music Name Handling + +Details: + TestName: algorithmCalcWithNullMusicName + Description: This test examines the method's behavior when encountering MusicModel objects that return null for the music name. It ensures that the method handles null keys appropriately in the HashMap. +Execution: + Arrange: Create MusicModel objects where getMusicName() returns null, along with valid likes and comments values. Configure the algorithmData mock appropriately. + Act: Call the algorithmCalc method with the collection containing null music names. + Assert: Verify that the method handles null keys correctly, either by including them in the HashMap or handling them gracefully without exceptions. +Validation: + This test ensures robustness when dealing with incomplete or corrupted music data where the music name might be missing. It's important for maintaining application stability when processing data from external sources or during data migration scenarios. + +Scenario 8: Mixed Valid and Invalid Data + +Details: + TestName: algorithmCalcWithMixedData + Description: This test validates the method's behavior when processing a collection that contains both valid MusicModel objects and objects with various edge case values (zero engagement, null names, extreme values). +Execution: + Arrange: Create a diverse collection of MusicModel objects including normal cases, zero values, high values, and potential null scenarios. Set up comprehensive mock responses for all scenarios. + Act: Execute the algorithmCalc method with the mixed data collection. + Assert: Verify that the method processes all items correctly and returns a HashMap with appropriate entries for each valid case while handling edge cases gracefully. +Validation: + This comprehensive test ensures that the method can handle real-world data scenarios where collections might contain a mix of normal and edge case data. It validates the overall robustness and reliability of the algorithm calculation functionality. + +*/ + +// ********RoostGPT******** + +package com.medeiros.SPRINGProject.algorithm; + +import com.medeiros.SPRINGProject.Models.MusicModel; +import com.medeiros.SPRINGProject.utils.hashMapFunctions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Tag; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import java.util.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; +import org.junit.jupiter.api.*; +import java.util.HashMap; +import java.util.Map; + +class AlgorithmBlenderAlgorithmCalcTest { + + private algorithmBlender algorithmBlender; + + @Mock + private MusicModel musicModel1; + + @Mock + private MusicModel musicModel2; + + @Mock + private MusicModel musicModel3; + + @Mock + private algorithmData mockAlgorithmData; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + algorithmBlender = new algorithmBlender(); + algorithmBlender.AD = mockAlgorithmData; + } + + @Test + @Tag("valid") + void algorithmCalcWithValidMusicList() { + // Arrange + List musicList = Arrays.asList(musicModel1, musicModel2, musicModel3); + + when(musicModel1.getNumberOfLikes()).thenReturn(10); + when(musicModel1.getNumberOfComents()).thenReturn(5); + when(musicModel1.getMusicName()).thenReturn("Song1"); + + when(musicModel2.getNumberOfLikes()).thenReturn(20); + when(musicModel2.getNumberOfComents()).thenReturn(8); + when(musicModel2.getMusicName()).thenReturn("Song2"); + + when(musicModel3.getNumberOfLikes()).thenReturn(15); + when(musicModel3.getNumberOfComents()).thenReturn(3); + when(musicModel3.getMusicName()).thenReturn("Song3"); + + when(mockAlgorithmData.rithmPointsByLike(10)).thenReturn(100); + when(mockAlgorithmData.rithmPointsByComents(5)).thenReturn(75); + when(mockAlgorithmData.rithmPointsByLike(20)).thenReturn(200); + when(mockAlgorithmData.rithmPointsByComents(8)).thenReturn(120); + when(mockAlgorithmData.rithmPointsByLike(15)).thenReturn(150); + when(mockAlgorithmData.rithmPointsByComents(3)).thenReturn(45); + + // Act + Map result = algorithmBlender.algorithmCalc(musicList); + + // Assert + assertNotNull(result); + assertEquals(3, result.size()); + assertEquals(175, result.get("Song1")); + assertEquals(320, result.get("Song2")); + assertEquals(195, result.get("Song3")); + } + + @Test + @Tag("boundary") + void algorithmCalcWithEmptyList() { + // Arrange + List emptyList = new ArrayList<>(); + + // Act + Map result = algorithmBlender.algorithmCalc(emptyList); + + // Assert + assertNotNull(result); + assertTrue(result.isEmpty()); + assertEquals(0, result.size()); + } + + @Test + @Tag("valid") + void algorithmCalcWithSingleMusicItem() { + // Arrange + List singleItemList = Arrays.asList(musicModel1); + + when(musicModel1.getNumberOfLikes()).thenReturn(25); + when(musicModel1.getNumberOfComents()).thenReturn(10); + when(musicModel1.getMusicName()).thenReturn("SingleSong"); + when(mockAlgorithmData.rithmPointsByLike(25)).thenReturn(250); + when(mockAlgorithmData.rithmPointsByComents(10)).thenReturn(150); + + // Act + Map result = algorithmBlender.algorithmCalc(singleItemList); + + // Assert + assertNotNull(result); + assertEquals(1, result.size()); + assertEquals(400, result.get("SingleSong")); + assertTrue(result.containsKey("SingleSong")); + } + + @Test + @Tag("boundary") + void algorithmCalcWithZeroLikesAndComments() { + // Arrange + List musicList = Arrays.asList(musicModel1, musicModel2); + + when(musicModel1.getNumberOfLikes()).thenReturn(0); + when(musicModel1.getNumberOfComents()).thenReturn(0); + when(musicModel1.getMusicName()).thenReturn("ZeroEngagement1"); + + when(musicModel2.getNumberOfLikes()).thenReturn(0); + when(musicModel2.getNumberOfComents()).thenReturn(0); + when(musicModel2.getMusicName()).thenReturn("ZeroEngagement2"); + + when(mockAlgorithmData.rithmPointsByLike(0)).thenReturn(0); + when(mockAlgorithmData.rithmPointsByComents(0)).thenReturn(0); + + // Act + Map result = algorithmBlender.algorithmCalc(musicList); + + // Assert + assertNotNull(result); + assertEquals(2, result.size()); + assertEquals(0, result.get("ZeroEngagement1")); + assertEquals(0, result.get("ZeroEngagement2")); + } + + @Test + @Tag("boundary") + void algorithmCalcWithMaximumValues() { + // Arrange + List musicList = Arrays.asList(musicModel1); + + when(musicModel1.getNumberOfLikes()).thenReturn(Integer.MAX_VALUE); + when(musicModel1.getNumberOfComents()).thenReturn(Integer.MAX_VALUE); + when(musicModel1.getMusicName()).thenReturn("MaxValueSong"); + when(mockAlgorithmData.rithmPointsByLike(Integer.MAX_VALUE)).thenReturn(1000000); + when(mockAlgorithmData.rithmPointsByComents(Integer.MAX_VALUE)).thenReturn(2000000); + + // Act + Map result = algorithmBlender.algorithmCalc(musicList); + + // Assert + assertNotNull(result); + assertEquals(1, result.size()); + assertEquals(3000000, result.get("MaxValueSong")); + } + + @Test + @Tag("valid") + void algorithmCalcWithDuplicateMusicNames() { + // Arrange + List musicList = Arrays.asList(musicModel1, musicModel2); + + when(musicModel1.getNumberOfLikes()).thenReturn(10); + when(musicModel1.getNumberOfComents()).thenReturn(5); + when(musicModel1.getMusicName()).thenReturn("DuplicateSong"); + + when(musicModel2.getNumberOfLikes()).thenReturn(20); + when(musicModel2.getNumberOfComents()).thenReturn(8); + when(musicModel2.getMusicName()).thenReturn("DuplicateSong"); + + when(mockAlgorithmData.rithmPointsByLike(10)).thenReturn(100); + when(mockAlgorithmData.rithmPointsByComents(5)).thenReturn(75); + when(mockAlgorithmData.rithmPointsByLike(20)).thenReturn(200); + when(mockAlgorithmData.rithmPointsByComents(8)).thenReturn(120); + + // Act + Map result = algorithmBlender.algorithmCalc(musicList); + + // Assert + assertNotNull(result); + assertEquals(1, result.size()); + assertEquals(320, result.get("DuplicateSong")); + } + + @Test + @Tag("invalid") + void algorithmCalcWithNullMusicName() { + // Arrange + List musicList = Arrays.asList(musicModel1, musicModel2); + + when(musicModel1.getNumberOfLikes()).thenReturn(10); + when(musicModel1.getNumberOfComents()).thenReturn(5); + when(musicModel1.getMusicName()).thenReturn(null); + + when(musicModel2.getNumberOfLikes()).thenReturn(15); + when(musicModel2.getNumberOfComents()).thenReturn(7); + when(musicModel2.getMusicName()).thenReturn("ValidSong"); + + when(mockAlgorithmData.rithmPointsByLike(10)).thenReturn(100); + when(mockAlgorithmData.rithmPointsByComents(5)).thenReturn(75); + when(mockAlgorithmData.rithmPointsByLike(15)).thenReturn(150); + when(mockAlgorithmData.rithmPointsByComents(7)).thenReturn(105); + + // Act + Map result = algorithmBlender.algorithmCalc(musicList); + + // Assert + assertNotNull(result); + assertEquals(2, result.size()); + assertEquals(175, result.get(null)); + assertEquals(255, result.get("ValidSong")); + assertTrue(result.containsKey(null)); + } + + @Test + @Tag("integration") + void algorithmCalcWithMixedData() { + // Arrange + List musicList = Arrays.asList(musicModel1, musicModel2, musicModel3); + + when(musicModel1.getNumberOfLikes()).thenReturn(0); + when(musicModel1.getNumberOfComents()).thenReturn(0); + when(musicModel1.getMusicName()).thenReturn("ZeroSong"); + + when(musicModel2.getNumberOfLikes()).thenReturn(100); + when(musicModel2.getNumberOfComents()).thenReturn(50); + when(musicModel2.getMusicName()).thenReturn("PopularSong"); + + when(musicModel3.getNumberOfLikes()).thenReturn(5); + when(musicModel3.getNumberOfComents()).thenReturn(2); + when(musicModel3.getMusicName()).thenReturn(null); + + when(mockAlgorithmData.rithmPointsByLike(0)).thenReturn(0); + when(mockAlgorithmData.rithmPointsByComents(0)).thenReturn(0); + when(mockAlgorithmData.rithmPointsByLike(100)).thenReturn(1000); + when(mockAlgorithmData.rithmPointsByComents(50)).thenReturn(750); + when(mockAlgorithmData.rithmPointsByLike(5)).thenReturn(50); + when(mockAlgorithmData.rithmPointsByComents(2)).thenReturn(30); + + // Act + Map result = algorithmBlender.algorithmCalc(musicList); + + // Assert + assertNotNull(result); + assertEquals(3, result.size()); + assertEquals(0, result.get("ZeroSong")); + assertEquals(1750, result.get("PopularSong")); + assertEquals(80, result.get(null)); + assertTrue(result.containsKey("ZeroSong")); + assertTrue(result.containsKey("PopularSong")); + assertTrue(result.containsKey(null)); + } + +} \ No newline at end of file diff --git a/src/test/java/com/medeiros/SPRINGProject/utils/HashMapFunctionsOrdenarHashMapPorValorTest.java b/src/test/java/com/medeiros/SPRINGProject/utils/HashMapFunctionsOrdenarHashMapPorValorTest.java new file mode 100644 index 0000000..97c33d8 --- /dev/null +++ b/src/test/java/com/medeiros/SPRINGProject/utils/HashMapFunctionsOrdenarHashMapPorValorTest.java @@ -0,0 +1,381 @@ + +// ********RoostGPT******** +/* +Test generated by RoostGPT for test java-music using AI Type Claude AI and AI Model claude-sonnet-4-20250514 + +ROOST_METHOD_HASH=ordenarHashMapPorValor_29e282f5b3 +ROOST_METHOD_SIG_HASH=ordenarHashMapPorValor_afd4884fe1 + +Scenario 1: Sort HashMap with Multiple Entries in Descending Order by Value + +Details: + TestName: sortHashMapWithMultipleEntriesDescendingOrder + Description: This test verifies that the method correctly sorts a HashMap containing multiple key-value pairs in descending order based on their integer values. The test ensures that entries with higher values appear first in the resulting HashMap. +Execution: + Arrange: Create a HashMap with multiple String-Integer pairs having different values (e.g., "apple"->5, "banana"->3, "cherry"->8, "date"->1). + Act: Call ordenarHashMapPorValor method with the prepared HashMap. + Assert: Verify that the returned HashMap maintains the correct descending order of values and contains all original entries. +Validation: + The assertion verifies that the sorting algorithm correctly arranges entries from highest to lowest value. This test is crucial for ensuring the primary functionality works as expected when processing typical data sets with varied integer values. + +Scenario 2: Sort HashMap with Single Entry + +Details: + TestName: sortHashMapWithSingleEntry + Description: This test checks the method's behavior when processing a HashMap containing only one key-value pair. It ensures that single-entry HashMaps are handled correctly without errors. +Execution: + Arrange: Create a HashMap with a single String-Integer pair (e.g., "single"->10). + Act: Invoke ordenarHashMapPorValor method with the single-entry HashMap. + Assert: Confirm that the returned HashMap contains the same single entry with unchanged key and value. +Validation: + This assertion ensures that the method handles edge cases gracefully and doesn't introduce errors when processing minimal data sets. It's important for robustness testing and prevents potential failures in real-world scenarios with limited data. + +Scenario 3: Sort Empty HashMap + +Details: + TestName: sortEmptyHashMap + Description: This test validates the method's behavior when given an empty HashMap as input. It ensures that empty collections are processed without throwing exceptions or producing unexpected results. +Execution: + Arrange: Create an empty HashMap. + Act: Call ordenarHashMapPorValor method with the empty HashMap. + Assert: Verify that the returned HashMap is also empty and not null. +Validation: + The assertion confirms that empty input produces empty output without errors. This test is essential for preventing null pointer exceptions and ensuring the method's stability when processing edge cases in production environments. + +Scenario 4: Sort HashMap with Duplicate Values + +Details: + TestName: sortHashMapWithDuplicateValues + Description: This test examines how the method handles HashMap entries that have identical integer values. It verifies that all entries are preserved and that the sorting maintains stability for equal values. +Execution: + Arrange: Create a HashMap with multiple entries having some duplicate values (e.g., "first"->5, "second"->3, "third"->5, "fourth"->3). + Act: Execute ordenarHashMapPorValor method with the HashMap containing duplicate values. + Assert: Ensure that all entries are present in the result and that entries with equal values maintain their relative positions or follow a consistent ordering pattern. +Validation: + This assertion verifies that the sorting algorithm handles duplicate values correctly without losing data. It's crucial for ensuring data integrity when processing real-world datasets that may contain repeated values. + +Scenario 5: Sort HashMap with Negative Values + +Details: + TestName: sortHashMapWithNegativeValues + Description: This test validates the method's capability to sort HashMap entries containing negative integer values. It ensures that negative numbers are correctly ordered in descending sequence. +Execution: + Arrange: Create a HashMap with a mix of positive and negative integer values (e.g., "positive"->10, "negative"->-5, "zero"->0, "moreNegative"->-15). + Act: Call ordenarHashMapPorValor method with the HashMap containing negative values. + Assert: Verify that the returned HashMap is sorted in descending order, with positive values first, followed by zero, then negative values in descending order. +Validation: + The assertion ensures that the comparison logic correctly handles negative integers and maintains proper mathematical ordering. This test is important for applications that process financial data, temperature readings, or other metrics that can have negative values. + +Scenario 6: Sort HashMap with Zero Values + +Details: + TestName: sortHashMapWithZeroValues + Description: This test checks the method's behavior when processing HashMap entries with zero values mixed with positive and negative values. It ensures that zero is positioned correctly in the sorted sequence. +Execution: + Arrange: Create a HashMap with entries including zero values (e.g., "positive"->5, "zero1"->0, "negative"->-3, "zero2"->0). + Act: Invoke ordenarHashMapPorValor method with the HashMap containing zero values. + Assert: Confirm that zero values are positioned correctly between positive and negative values in the descending order. +Validation: + This assertion verifies that zero values are handled as a distinct case and positioned appropriately in the sorted sequence. It's essential for maintaining mathematical accuracy in sorting operations. + +Scenario 7: Sort HashMap with Maximum Integer Values + +Details: + TestName: sortHashMapWithMaximumIntegerValues + Description: This test evaluates the method's performance and correctness when dealing with HashMap entries containing maximum possible integer values (Integer.MAX_VALUE). +Execution: + Arrange: Create a HashMap with entries including Integer.MAX_VALUE and other large values (e.g., "max"->Integer.MAX_VALUE, "large"->999999, "medium"->1000). + Act: Execute ordenarHashMapPorValor method with the HashMap containing maximum integer values. + Assert: Verify that Integer.MAX_VALUE appears first in the sorted result and that all other values follow in correct descending order. +Validation: + The assertion ensures that the method can handle extreme values without overflow or comparison errors. This test is crucial for applications that might encounter boundary values in their data processing. + +Scenario 8: Sort HashMap with Minimum Integer Values + +Details: + TestName: sortHashMapWithMinimumIntegerValues + Description: This test validates the method's ability to process HashMap entries containing the minimum possible integer value (Integer.MIN_VALUE) along with other values. +Execution: + Arrange: Create a HashMap with entries including Integer.MIN_VALUE and other small values (e.g., "min"->Integer.MIN_VALUE, "small"->-999999, "negative"->-100). + Act: Call ordenarHashMapPorValor method with the HashMap containing minimum integer values. + Assert: Ensure that Integer.MIN_VALUE appears last in the sorted result and that all other values are correctly positioned in descending order. +Validation: + This assertion confirms that extreme negative values are handled correctly without causing arithmetic errors or incorrect comparisons. It's important for ensuring robustness when processing data with boundary values. + +Scenario 9: Verify Return Type is LinkedHashMap + +Details: + TestName: verifyReturnTypeIsLinkedHashMap + Description: This test confirms that the method returns a LinkedHashMap instance, which maintains insertion order and is crucial for preserving the sorted sequence of entries. +Execution: + Arrange: Create a HashMap with several String-Integer pairs. + Act: Invoke ordenarHashMapPorValor method and capture the returned object. + Assert: Verify that the returned object is an instance of LinkedHashMap and maintains the expected order of entries. +Validation: + The assertion ensures that the method returns the correct data structure type that preserves ordering. This is essential because regular HashMap doesn't guarantee order preservation, which would defeat the purpose of sorting. + +Scenario 10: Verify Original HashMap Remains Unchanged + +Details: + TestName: verifyOriginalHashMapRemainsUnchanged + Description: This test ensures that the original HashMap passed as a parameter is not modified during the sorting process. It validates that the method creates a new sorted HashMap without altering the input. +Execution: + Arrange: Create a HashMap with multiple entries and create a copy of its contents for comparison. + Act: Call ordenarHashMapPorValor method with the original HashMap. + Assert: Verify that the original HashMap contains the same entries in the same state as before the method call. +Validation: + This assertion confirms that the method follows immutability principles and doesn't have side effects on input parameters. It's crucial for ensuring that calling code can rely on input data remaining unchanged, which is important for functional programming practices and preventing unexpected behavior. + +*/ + +// ********RoostGPT******** + +package com.medeiros.SPRINGProject.utils; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Tag; +import static org.junit.jupiter.api.Assertions.*; +import java.util.*; +import org.junit.jupiter.api.*; + +public class HashMapFunctionsOrdenarHashMapPorValorTest { + + @Test + @Tag("valid") + public void sortHashMapWithMultipleEntriesDescendingOrder() { + // Arrange + HashMap hashMap = new HashMap<>(); + hashMap.put("apple", 5); + hashMap.put("banana", 3); + hashMap.put("cherry", 8); + hashMap.put("date", 1); + + // Act + HashMap result = hashMapFunctions.ordenarHashMapPorValor(hashMap); + + // Assert + assertNotNull(result); + assertEquals(4, result.size()); + + List values = new ArrayList<>(result.values()); + assertEquals(8, values.get(0)); + assertEquals(5, values.get(1)); + assertEquals(3, values.get(2)); + assertEquals(1, values.get(3)); + + assertTrue(result.containsKey("cherry")); + assertTrue(result.containsKey("apple")); + assertTrue(result.containsKey("banana")); + assertTrue(result.containsKey("date")); + } + + @Test + @Tag("boundary") + public void sortHashMapWithSingleEntry() { + // Arrange + HashMap hashMap = new HashMap<>(); + hashMap.put("single", 10); + + // Act + HashMap result = hashMapFunctions.ordenarHashMapPorValor(hashMap); + + // Assert + assertNotNull(result); + assertEquals(1, result.size()); + assertTrue(result.containsKey("single")); + assertEquals(10, result.get("single")); + } + + @Test + @Tag("boundary") + public void sortEmptyHashMap() { + // Arrange + HashMap hashMap = new HashMap<>(); + + // Act + HashMap result = hashMapFunctions.ordenarHashMapPorValor(hashMap); + + // Assert + assertNotNull(result); + assertTrue(result.isEmpty()); + assertEquals(0, result.size()); + } + + @Test + @Tag("valid") + public void sortHashMapWithDuplicateValues() { + // Arrange + HashMap hashMap = new HashMap<>(); + hashMap.put("first", 5); + hashMap.put("second", 3); + hashMap.put("third", 5); + hashMap.put("fourth", 3); + + // Act + HashMap result = hashMapFunctions.ordenarHashMapPorValor(hashMap); + + // Assert + assertNotNull(result); + assertEquals(4, result.size()); + + List values = new ArrayList<>(result.values()); + assertEquals(5, values.get(0)); + assertEquals(5, values.get(1)); + assertEquals(3, values.get(2)); + assertEquals(3, values.get(3)); + + assertTrue(result.containsKey("first")); + assertTrue(result.containsKey("second")); + assertTrue(result.containsKey("third")); + assertTrue(result.containsKey("fourth")); + } + + @Test + @Tag("valid") + public void sortHashMapWithNegativeValues() { + // Arrange + HashMap hashMap = new HashMap<>(); + hashMap.put("positive", 10); + hashMap.put("negative", -5); + hashMap.put("zero", 0); + hashMap.put("moreNegative", -15); + + // Act + HashMap result = hashMapFunctions.ordenarHashMapPorValor(hashMap); + + // Assert + assertNotNull(result); + assertEquals(4, result.size()); + + List values = new ArrayList<>(result.values()); + assertEquals(10, values.get(0)); + assertEquals(0, values.get(1)); + assertEquals(-5, values.get(2)); + assertEquals(-15, values.get(3)); + } + + @Test + @Tag("valid") + public void sortHashMapWithZeroValues() { + // Arrange + HashMap hashMap = new HashMap<>(); + hashMap.put("positive", 5); + hashMap.put("zero1", 0); + hashMap.put("negative", -3); + hashMap.put("zero2", 0); + + // Act + HashMap result = hashMapFunctions.ordenarHashMapPorValor(hashMap); + + // Assert + assertNotNull(result); + assertEquals(4, result.size()); + + List values = new ArrayList<>(result.values()); + assertEquals(5, values.get(0)); + assertEquals(0, values.get(1)); + assertEquals(0, values.get(2)); + assertEquals(-3, values.get(3)); + } + + @Test + @Tag("boundary") + public void sortHashMapWithMaximumIntegerValues() { + // Arrange + HashMap hashMap = new HashMap<>(); + hashMap.put("max", Integer.MAX_VALUE); + hashMap.put("large", 999999); + hashMap.put("medium", 1000); + + // Act + HashMap result = hashMapFunctions.ordenarHashMapPorValor(hashMap); + + // Assert + assertNotNull(result); + assertEquals(3, result.size()); + + List values = new ArrayList<>(result.values()); + assertEquals(Integer.MAX_VALUE, values.get(0)); + assertEquals(999999, values.get(1)); + assertEquals(1000, values.get(2)); + + assertTrue(result.containsKey("max")); + assertEquals(Integer.MAX_VALUE, result.get("max")); + } + + @Test + @Tag("boundary") + public void sortHashMapWithMinimumIntegerValues() { + // Arrange + HashMap hashMap = new HashMap<>(); + hashMap.put("min", Integer.MIN_VALUE); + hashMap.put("small", -999999); + hashMap.put("negative", -100); + + // Act + HashMap result = hashMapFunctions.ordenarHashMapPorValor(hashMap); + + // Assert + assertNotNull(result); + assertEquals(3, result.size()); + + List values = new ArrayList<>(result.values()); + assertEquals(-100, values.get(0)); + assertEquals(-999999, values.get(1)); + assertEquals(Integer.MIN_VALUE, values.get(2)); + + assertTrue(result.containsKey("min")); + assertEquals(Integer.MIN_VALUE, result.get("min")); + } + + @Test + @Tag("integration") + public void verifyReturnTypeIsLinkedHashMap() { + // Arrange + HashMap hashMap = new HashMap<>(); + hashMap.put("first", 3); + hashMap.put("second", 1); + hashMap.put("third", 2); + + // Act + HashMap result = hashMapFunctions.ordenarHashMapPorValor(hashMap); + + // Assert + assertNotNull(result); + assertTrue(result instanceof LinkedHashMap); + + List values = new ArrayList<>(result.values()); + assertEquals(3, values.get(0)); + assertEquals(2, values.get(1)); + assertEquals(1, values.get(2)); + } + + @Test + @Tag("integration") + public void verifyOriginalHashMapRemainsUnchanged() { + // Arrange + HashMap originalHashMap = new HashMap<>(); + originalHashMap.put("apple", 5); + originalHashMap.put("banana", 3); + originalHashMap.put("cherry", 8); + + HashMap copyForComparison = new HashMap<>(originalHashMap); + + // Act + HashMap result = hashMapFunctions.ordenarHashMapPorValor(originalHashMap); + + // Assert + assertNotNull(result); + assertEquals(copyForComparison.size(), originalHashMap.size()); + assertEquals(copyForComparison.get("apple"), originalHashMap.get("apple")); + assertEquals(copyForComparison.get("banana"), originalHashMap.get("banana")); + assertEquals(copyForComparison.get("cherry"), originalHashMap.get("cherry")); + + assertTrue(originalHashMap.containsKey("apple")); + assertTrue(originalHashMap.containsKey("banana")); + assertTrue(originalHashMap.containsKey("cherry")); + + assertNotSame(originalHashMap, result); + } + +} \ No newline at end of file