From 1d03ff43557a2e6696bfd37b53af22d568c6b973 Mon Sep 17 00:00:00 2001 From: roost-io <8110509+mgdevstack@users.noreply.github.com> Date: Sun, 3 May 2026 21:57:37 +0530 Subject: [PATCH] Unit test generated by RoostGPT Using AI Model gpt-5 --- pom.xml | 249 +++++--- ...apFunctionsOrdenarHashMapPorValorTest.java | 594 ++++++++++++++++++ 2 files changed, 747 insertions(+), 96 deletions(-) create mode 100644 src/test/java/com/medeiros/SPRINGProject/utils/HashMapFunctionsOrdenarHashMapPorValorTest.java diff --git a/pom.xml b/pom.xml index d5e071f9..cf9d3292 100644 --- a/pom.xml +++ b/pom.xml @@ -1,96 +1,153 @@ - - - 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 + + + + 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.mockito + mockito-junit-jupiter + 2.23.4 + test + + + + io.spring.javaformat + spring-javaformat-formatter + 0.0.40 + + + + + + + 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 + + + + + + + + \ 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 00000000..3974cf64 --- /dev/null +++ b/src/test/java/com/medeiros/SPRINGProject/utils/HashMapFunctionsOrdenarHashMapPorValorTest.java @@ -0,0 +1,594 @@ + +// ********RoostGPT******** +/* +Test generated by RoostGPT for test maven-music-github using AI Type Azure Open AI and AI Model gpt-5 + +ROOST_METHOD_HASH=ordenarHashMapPorValor_29e282f5b3 +ROOST_METHOD_SIG_HASH=ordenarHashMapPorValor_afd4884fe1 + +Scenario 1: Sorts a map with distinct values in strict descending order + +Details: + TestName: sortsDescendingWithDistinctValues + Description: Verifies that the method orders entries by their Integer values in strictly descending order when all values are distinct. + +Execution: + Arrange: Create a HashMap with entries such as {"a"=1, "b"=3, "c"=2}. + Act: Invoke hashMapFunctions.ordenarHashMapPorValor with the prepared map. + Assert: Use assertions to verify the iteration order of the returned map is ["b"=3, "c"=2, "a"=1] and the size equals the input size. + +Validation: + Confirming the exact descending order demonstrates the comparator is applied in reverse (largest to smallest). Ensuring the size matches validates no entries were lost or duplicated. + + +Scenario 2: Returns an empty map when the input is empty + +Details: + TestName: returnsEmptyMapWhenInputIsEmpty + Description: Ensures that providing an empty HashMap returns an empty result without errors. + +Execution: + Arrange: Create an empty HashMap. + Act: Call hashMapFunctions.ordenarHashMapPorValor with the empty map. + Assert: Assert that the returned map is empty and not null. + +Validation: + This validates graceful handling of boundary conditions and ensures no extraneous elements are added. + + +Scenario 3: Returns the same single entry unchanged + +Details: + TestName: returnsSingleEntryUnchanged + Description: Verifies that a single-entry map remains effectively unchanged (same key-value pair present) after sorting. + +Execution: + Arrange: Create a HashMap with one entry, e.g., {"only"=42}. + Act: Call the method with this map. + Assert: Assert the returned map has size 1 and contains the entry "only"=42. + +Validation: + Confirms that sorting preserves data and does not alter content when sorting is trivial. + + +Scenario 4: Preserves relative order for equal values using a LinkedHashMap input + +Details: + TestName: preservesRelativeOrderForEqualValuesUsingLinkedHashMap + Description: Ensures stability for entries with equal values by using a LinkedHashMap (assigned to a HashMap variable) to control input iteration order. + +Execution: + Arrange: Create a LinkedHashMap (referenced as HashMap) with entries inserted in order: "k1"=5, "k2"=5, "k3"=5. + Act: Invoke the method with this map. + Assert: Assert that the returned iteration order is ["k1"=5, "k2"=5, "k3"=5], preserving insertion order among ties. + +Validation: + Sorting with a stable algorithm and a comparator that returns 0 for equal values should preserve original tie order. This confirms sort stability with controlled input ordering. + + +Scenario 5: Maintains stable order within each tie group across multiple groups + +Details: + TestName: maintainsStableOrderWithinEachTieGroup + Description: Verifies that when multiple groups of equal values exist, entries within each group retain their original relative order, and groups themselves are ordered by value descending. + +Execution: + Arrange: Use a LinkedHashMap (referenced as HashMap) with entries: "a"=10, "b"=10, "c"=8, "d"=8, "e"=9 in that insertion order. + Act: Call the method. + Assert: Assert the returned order is ["a"=10, "b"=10, "e"=9, "c"=8, "d"=8], preserving intra-group order and descending between groups. + +Validation: + Confirms both descending value ordering and stability for tie groups, which is critical for predictable output ordering. + + +Scenario 6: Sorts mixed negative, zero, and positive values in descending order + +Details: + TestName: sortsNegativeZeroAndPositiveValuesDescending + Description: Validates correct ordering when the map contains negative numbers, zero, and positive values. + +Execution: + Arrange: Create a HashMap with entries {"neg"=-2, "zero"=0, "pos"=3, "neg2"=-5}. + Act: Invoke the method. + Assert: Assert order is ["pos"=3, "zero"=0, "neg"=-2, "neg2"=-5]. + +Validation: + Ensures compareTo handles sign differences correctly, and the method truly sorts by numerical value descending. + + +Scenario 7: Handles Integer boundary values correctly + +Details: + TestName: handlesIntegerBoundsCorrectly + Description: Ensures correct sorting when values include Integer.MAX_VALUE and Integer.MIN_VALUE. + +Execution: + Arrange: Create a HashMap with entries {"min"=Integer.MIN_VALUE, "mid"=1, "max"=Integer.MAX_VALUE}. + Act: Call the method. + Assert: Assert that the first entry has Integer.MAX_VALUE and the last has Integer.MIN_VALUE. + +Validation: + Confirms that the comparator’s use of compareTo avoids overflow and handles extreme bounds properly. + + +Scenario 8: Accepts a null key and sorts by value normally + +Details: + TestName: includesNullKeyAndSortsByValue + Description: Verifies that a null key is preserved and positioned according to its value. + +Execution: + Arrange: Create a HashMap with entries {null=2, "a"=3, "b"=1}. + Act: Invoke the method. + Assert: Assert order is ["a"=3, null=2, "b"=1], and the null key is present in the result. + +Validation: + Java HashMap allows a null key; since only values are compared, null keys should not cause errors. This test confirms key preservation regardless of null. + + +Scenario 9: Throws NullPointerException when any value is null + +Details: + TestName: throwsNullPointerExceptionWhenAnyValueIsNull + Description: Ensures the method fails fast with a NullPointerException when a map contains a null value, due to compareTo on a null reference. + +Execution: + Arrange: Create a HashMap with entries {"a"=3, "b"=null, "c"=1}. + Act: Call the method and expect an exception. + Assert: Use an assertion (e.g., assertThrows) to verify a NullPointerException is thrown. + +Validation: + The comparator invokes getValue().compareTo(...); a null value triggers a NullPointerException. This test documents and validates the current failure mode. + + +Scenario 10: Throws NullPointerException when the input map reference is null + +Details: + TestName: throwsNullPointerExceptionWhenInputMapIsNull + Description: Verifies behavior when the method receives a null reference for the map parameter. + +Execution: + Arrange: Set the input map reference to null. + Act: Invoke hashMapFunctions.ordenarHashMapPorValor with null. + Assert: Assert that a NullPointerException is thrown. + +Validation: + As the implementation dereferences hashMap.entrySet(), a null input must throw NullPointerException. This confirms expected error handling. + + +Scenario 11: Returns a LinkedHashMap instance that preserves sorted iteration order + +Details: + TestName: returnsLinkedHashMapPreservingSortedIterationOrder + Description: Verifies that the returned map is a LinkedHashMap (preserving insertion/iteration order equal to the sorted order). + +Execution: + Arrange: Prepare a HashMap with several entries to sort (e.g., {"x"=2, "y"=5, "z"=3}). + Act: Call the method. + Assert: Assert that result is an instance of LinkedHashMap and that iterating keys yields order ["y","z","x"]. + +Validation: + Returning a LinkedHashMap ensures deterministic iteration order corresponding to the sorting result, which is essential for predictable downstream behavior. + + +Scenario 12: Does not mutate the original input map + +Details: + TestName: doesNotMutateOriginalMap + Description: Confirms that the source map remains unchanged after the sorting operation. + +Execution: + Arrange: Create a HashMap with known entries and keep a copy of its contents (e.g., capturing its size and that it still maps each key to its original value). + Act: Invoke the sorting method. + Assert: Assert that the original map still contains the same key-value pairs and the same size as before the call. + +Validation: + The method reads entries and builds a new map. This test ensures no side effects on the caller-provided data structure. + + +Scenario 13: Returns a new map instance distinct from the input map + +Details: + TestName: returnsNewMapInstanceNotSameAsInput + Description: Ensures that the method does not return the same instance as the input and instead returns a newly constructed map. + +Execution: + Arrange: Create a HashMap with sample entries. + Act: Call the method and capture the result. + Assert: Use assertions to verify that the returned map reference is not the same as the input map reference. + +Validation: + Guarantees that callers receive an independent map, preventing unexpected aliasing or side effects. + + +Scenario 14: Returned map remains unchanged if the input map is mutated after sorting + +Details: + TestName: returnedMapUnaffectedByFurtherInputMutations + Description: Confirms that subsequent changes to the original input map do not affect the already returned sorted map. + +Execution: + Arrange: Create a HashMap with entries and call the method to obtain the sorted map. Then mutate the input map (e.g., add, remove, or update entries). + Act: Do not re-invoke the method; simply inspect the returned map. + Assert: Assert that the returned map’s contents and iteration order remain as initially produced. + +Validation: + Since the method constructs a new LinkedHashMap from a snapshot of entries, the returned map should be independent of later changes to the input. + + +Scenario 15: Sorts a large dataset while maintaining non-increasing order of values + +Details: + TestName: sortsLargeDatasetInNonIncreasingOrder + Description: Validates that sorting works and scales for larger inputs by ensuring the resulting values are monotonically non-increasing. + +Execution: + Arrange: Create a HashMap with a large number of entries (e.g., 1000 keys) with varied random Integer values. + Act: Invoke the method. + Assert: Iterate through the result and assert that each subsequent value is less than or equal to the previous value; also assert sizes match. + +Validation: + Confirms algorithmic correctness and robustness under heavier loads, ensuring consistent ordering for all entries. + + +Scenario 16: Accepts a LinkedHashMap instance as input via its HashMap type + +Details: + TestName: acceptsLinkedHashMapInstanceAsInput + Description: Ensures compatibility when the input variable is typed as HashMap but instantiated as LinkedHashMap. + +Execution: + Arrange: Instantiate a LinkedHashMap (assigned to a HashMap reference) with entries in a known insertion order, including ties. + Act: Call the method. + Assert: Assert that the returned ordering reflects descending values and stable ordering for ties. + +Validation: + As LinkedHashMap extends HashMap, this verifies the method handles subclass instances correctly while leveraging deterministic insertion order for stable tie validation. + + +Scenario 17: Ties in a plain HashMap input do not require a specific relative order among equals + +Details: + TestName: tiesInHashMapInputDoNotRequireSpecificOrderAmongEquals + Description: Ensures correctness by verifying value-based descending order without assuming any specific relative order among keys that have equal values when the input is a standard HashMap. + +Execution: + Arrange: Create a HashMap with multiple keys sharing the same values (e.g., two keys with value 5, three keys with value 2) and additional distinct values. + Act: Invoke the method. + Assert: Assert that the sequence of values is non-increasing and that, for each tie value, all expected keys are present in a contiguous block, without asserting their internal order. + +Validation: + Because HashMap iteration order is unspecified, tie order cannot be assumed. This test focuses on the guaranteed contract: correct descending value ordering and presence of all entries. + + +Scenario 18: Preserves key-value associations after sorting + +Details: + TestName: preservesKeyValueAssociationsAfterSorting + Description: Ensures that keys remain paired with their original values and no cross-assignment occurs during sorting. + +Execution: + Arrange: Create a HashMap with distinct key-value pairs (e.g., {"k1"=10, "k2"=7, "k3"=9}). + Act: Call the method. + Assert: Assert that each key in the result still maps to the same Integer value as in the input. + +Validation: + Confirms that sorting reorders entries by value but does not alter key-value bindings, preserving data integrity. + +*/ + +// ********RoostGPT******** + +package com.medeiros.SPRINGProject.utils; + +import java.util.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import com.medeiros.SPRINGProject.utils.hashMapFunctions; +import org.junit.jupiter.api.*; + +@ExtendWith(MockitoExtension.class) +public class HashMapFunctionsOrdenarHashMapPorValorTest { + + @Test + @Tag("valid") + public void testSortsDescendingWithDistinctValues() { + HashMap input = new HashMap<>(); + input.put("a", 1); + input.put("b", 3); + input.put("c", 2); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + List expectedKeys = new ArrayList<>(Arrays.asList("b", "c", "a")); + List actualKeys = new ArrayList<>(result.keySet()); + Assertions.assertEquals((int) 3, (int) result.size()); + Assertions.assertEquals((List) expectedKeys, (List) actualKeys); + Assertions.assertEquals((Integer) 3, (Integer) result.get("b")); + Assertions.assertEquals((Integer) 2, (Integer) result.get("c")); + Assertions.assertEquals((Integer) 1, (Integer) result.get("a")); + } + + @Test + @Tag("boundary") + public void testReturnsEmptyMapWhenInputIsEmpty() { + HashMap input = new HashMap<>(); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + Assertions.assertNotNull((Object) result); + Assertions.assertTrue(result.isEmpty()); + Assertions.assertEquals((int) 0, (int) result.size()); + } + + @Test + @Tag("boundary") + public void testReturnsSingleEntryUnchanged() { + HashMap input = new HashMap<>(); + input.put("only", 42); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + Assertions.assertEquals((int) 1, (int) result.size()); + Assertions.assertTrue(result.containsKey("only")); + Assertions.assertEquals((Integer) 42, (Integer) result.get("only")); + List expectedKeys = new ArrayList<>(Arrays.asList("only")); + List actualKeys = new ArrayList<>(result.keySet()); + Assertions.assertEquals((List) expectedKeys, (List) actualKeys); + } + + @Test + @Tag("valid") + public void testPreservesRelativeOrderForEqualValuesUsingLinkedHashMap() { + HashMap input = new LinkedHashMap<>(); + input.put("k1", 5); + input.put("k2", 5); + input.put("k3", 5); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + List expectedKeys = new ArrayList<>(Arrays.asList("k1", "k2", "k3")); + List actualKeys = new ArrayList<>(result.keySet()); + Assertions.assertEquals((List) expectedKeys, (List) actualKeys); + Assertions.assertEquals((Integer) 5, (Integer) result.get("k1")); + Assertions.assertEquals((Integer) 5, (Integer) result.get("k2")); + Assertions.assertEquals((Integer) 5, (Integer) result.get("k3")); + } + + @Test + @Tag("valid") + public void testMaintainsStableOrderWithinEachTieGroup() { + HashMap input = new LinkedHashMap<>(); + input.put("a", 10); + input.put("b", 10); + input.put("c", 8); + input.put("d", 8); + input.put("e", 9); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + List expectedKeys = new ArrayList<>(Arrays.asList("a", "b", "e", "c", "d")); + List actualKeys = new ArrayList<>(result.keySet()); + Assertions.assertEquals((List) expectedKeys, (List) actualKeys); + } + + @Test + @Tag("boundary") + public void testSortsNegativeZeroAndPositiveValuesDescending() { + HashMap input = new HashMap<>(); + input.put("neg", -2); + input.put("zero", 0); + input.put("pos", 3); + input.put("neg2", -5); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + List expectedKeys = new ArrayList<>(Arrays.asList("pos", "zero", "neg", "neg2")); + List actualKeys = new ArrayList<>(result.keySet()); + Assertions.assertEquals((List) expectedKeys, (List) actualKeys); + Assertions.assertEquals((Integer) 3, (Integer) result.get("pos")); + Assertions.assertEquals((Integer) 0, (Integer) result.get("zero")); + Assertions.assertEquals((Integer) (-2), (Integer) result.get("neg")); + Assertions.assertEquals((Integer) (-5), (Integer) result.get("neg2")); + } + + @Test + @Tag("boundary") + public void testHandlesIntegerBoundsCorrectly() { + HashMap input = new HashMap<>(); + input.put("min", Integer.MIN_VALUE); + input.put("mid", 1); + input.put("max", Integer.MAX_VALUE); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + List actualKeys = new ArrayList<>(result.keySet()); + Assertions.assertEquals((String) "max", (String) actualKeys.get(0)); + Assertions.assertEquals((String) "mid", (String) actualKeys.get(1)); + Assertions.assertEquals((String) "min", (String) actualKeys.get(2)); + Assertions.assertEquals((Integer) Integer.MAX_VALUE, (Integer) result.get("max")); + Assertions.assertEquals((Integer) 1, (Integer) result.get("mid")); + Assertions.assertEquals((Integer) Integer.MIN_VALUE, (Integer) result.get("min")); + } + + @Test + @Tag("boundary") + public void testIncludesNullKeyAndSortsByValue() { + HashMap input = new HashMap<>(); + input.put(null, 2); + input.put("a", 3); + input.put("b", 1); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + List expectedKeys = new ArrayList<>(Arrays.asList("a", null, "b")); + List actualKeys = new ArrayList<>(result.keySet()); + Assertions.assertTrue(result.containsKey(null)); + Assertions.assertEquals((List) expectedKeys, (List) actualKeys); + Assertions.assertEquals((Integer) 3, (Integer) result.get("a")); + Assertions.assertEquals((Integer) 2, (Integer) result.get(null)); + Assertions.assertEquals((Integer) 1, (Integer) result.get("b")); + } + + @Test + @Tag("invalid") + public void testThrowsNullPointerExceptionWhenAnyValueIsNull() { + HashMap input = new HashMap<>(); + input.put("a", 3); + input.put("b", null); + input.put("c", 1); + Assertions.assertThrows(NullPointerException.class, () -> hashMapFunctions.ordenarHashMapPorValor(input)); + } + + @Test + @Tag("invalid") + public void testThrowsNullPointerExceptionWhenInputMapIsNull() { + HashMap input = null; + Assertions.assertThrows(NullPointerException.class, () -> hashMapFunctions.ordenarHashMapPorValor(input)); + } + + @Test + @Tag("valid") + public void testReturnsLinkedHashMapPreservingSortedIterationOrder() { + HashMap input = new HashMap<>(); + input.put("x", 2); + input.put("y", 5); + input.put("z", 3); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + Assertions.assertTrue(result instanceof LinkedHashMap); + List expectedKeys = new ArrayList<>(Arrays.asList("y", "z", "x")); + List actualKeys = new ArrayList<>(result.keySet()); + Assertions.assertEquals((List) expectedKeys, (List) actualKeys); + } + + @Test + @Tag("valid") + public void testDoesNotMutateOriginalMap() { + HashMap input = new HashMap<>(); + input.put("alpha", 4); + input.put("beta", 2); + input.put("gamma", 7); + HashMap beforeCopy = new HashMap<>(input); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + Assertions.assertNotNull((Object) result); + Assertions.assertEquals((int) beforeCopy.size(), (int) input.size()); + Assertions.assertEquals((Map) beforeCopy, (Map) input); + } + + @Test + @Tag("valid") + public void testReturnsNewMapInstanceNotSameAsInput() { + HashMap input = new HashMap<>(); + input.put("p", 1); + input.put("q", 2); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + Assertions.assertNotSame((Object) input, (Object) result); + } + + @Test + @Tag("valid") + public void testReturnedMapUnaffectedByFurtherInputMutations() { + HashMap input = new HashMap<>(); + input.put("x", 10); + input.put("y", 5); + input.put("z", 8); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + HashMap snapshot = new LinkedHashMap<>(result); + // Mutate input after sorting + input.put("newKey", 100); + input.remove("y"); + input.put("z", 999); + Assertions.assertEquals((Map) snapshot, (Map) result); + List snapKeys = new ArrayList<>(snapshot.keySet()); + List resKeys = new ArrayList<>(result.keySet()); + Assertions.assertEquals((List) snapKeys, (List) resKeys); + } + + @Test + @Tag("integration") + public void testSortsLargeDatasetInNonIncreasingOrder() { + // TODO: Adjust dataset size if performance constraints require it + int n = 1000; + HashMap input = new HashMap<>(n); + Random rnd = new Random(12345); + for (int i = 0; i < n; i++) { + input.put("k" + i, rnd.nextInt(100000)); + } + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + Assertions.assertEquals((int) input.size(), (int) result.size()); + int prev = Integer.MAX_VALUE; + for (Map.Entry e : result.entrySet()) { + Integer current = e.getValue(); + Assertions.assertNotNull((Object) current); + Assertions.assertTrue(((int) prev) >= ((int) current)); + prev = current; + } + } + + @Test + @Tag("valid") + public void testAcceptsLinkedHashMapInstanceAsInput() { + HashMap input = new LinkedHashMap<>(); + input.put("a", 2); + input.put("b", 3); + input.put("c", 3); + input.put("d", 1); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + List expectedKeys = new ArrayList<>(Arrays.asList("b", "c", "a", "d")); + List actualKeys = new ArrayList<>(result.keySet()); + Assertions.assertEquals((List) expectedKeys, (List) actualKeys); + } + + @Test + @Tag("valid") + public void testTiesInHashMapInputDoNotRequireSpecificOrderAmongEquals() { + HashMap input = new HashMap<>(); + input.put("t1", 5); + input.put("t2", 5); + input.put("t3", 2); + input.put("t4", 2); + input.put("t5", 2); + input.put("x", 7); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + // Verify non-increasing order of values + int prev = Integer.MAX_VALUE; + for (Integer v : result.values()) { + Assertions.assertTrue(((int) prev) >= ((int) v)); + prev = v; + } + // Verify groups are contiguous for value 5 and 2 and contain correct keys + List> entries = new ArrayList<>(result.entrySet()); + List keys = new ArrayList<>(); + List values = new ArrayList<>(); + for (Map.Entry e : entries) { + keys.add(e.getKey()); + values.add(e.getValue()); + } + // Value 7 group + int firstVal = values.get(0); + Assertions.assertEquals((int) 7, (int) firstVal); + Assertions.assertEquals((String) "x", (String) keys.get(0)); + // Value 5 group + int firstFiveIdx = values.indexOf(5); + int lastFiveIdx = values.lastIndexOf(5); + Assertions.assertTrue(firstFiveIdx >= 0); + for (int i = firstFiveIdx; i <= lastFiveIdx; i++) { + Assertions.assertEquals((int) 5, (int) values.get(i)); + } + Set fiveKeys = new HashSet<>(keys.subList(firstFiveIdx, lastFiveIdx + 1)); + Set expectedFiveKeys = new HashSet<>(Arrays.asList("t1", "t2")); + Assertions.assertEquals((Set) expectedFiveKeys, (Set) fiveKeys); + // Value 2 group + int firstTwoIdx = values.indexOf(2); + int lastTwoIdx = values.lastIndexOf(2); + Assertions.assertTrue(firstTwoIdx >= 0); + for (int i = firstTwoIdx; i <= lastTwoIdx; i++) { + Assertions.assertEquals((int) 2, (int) values.get(i)); + } + Set twoKeys = new HashSet<>(keys.subList(firstTwoIdx, lastTwoIdx + 1)); + Set expectedTwoKeys = new HashSet<>(Arrays.asList("t3", "t4", "t5")); + Assertions.assertEquals((Set) expectedTwoKeys, (Set) twoKeys); + } + + @Test + @Tag("valid") + public void testPreservesKeyValueAssociationsAfterSorting() { + HashMap input = new HashMap<>(); + input.put("k1", 10); + input.put("k2", 7); + input.put("k3", 9); + HashMap result = hashMapFunctions.ordenarHashMapPorValor(input); + Assertions.assertEquals((int) input.size(), (int) result.size()); + Assertions.assertEquals((Integer) 10, (Integer) result.get("k1")); + Assertions.assertEquals((Integer) 7, (Integer) result.get("k2")); + Assertions.assertEquals((Integer) 9, (Integer) result.get("k3")); + } + +} \ No newline at end of file