diff --git a/pom.xml b/pom.xml index 924a736d526d..a152eda16972 100644 --- a/pom.xml +++ b/pom.xml @@ -1,159 +1,236 @@ - - - 4.0.0 - com.thealgorithms - Java - 1.0-SNAPSHOT - jar - - - UTF-8 - 21 - 21 - 3.26.0 - - - - - - org.junit - junit-bom - 5.10.3 - pom - import - - - - + + + 4.0.0 + com.thealgorithms + Java + 1.0-SNAPSHOT + jar + + UTF-8 + 21 + 21 + 3.26.0 + + - - org.junit.jupiter - junit-jupiter - 5.10.3 - test - - - org.assertj - assertj-core - ${assertj.version} - test - - - - org.junit.jupiter - junit-jupiter-api - 5.10.3 - test - - - org.apache.commons - commons-lang3 - 3.14.0 - - - org.apache.commons - commons-collections4 - 4.5.0-M2 - + + org.junit + junit-bom + 5.10.3 + pom + import + + + io.spring.javaformat + spring-javaformat-formatter + 0.0.40 + + + + org.assertj + assertj-guava + 3.26.0 + compile + + + + org.assertj + assertj-db + 2.0.2 + compile + + + + org.assertj + assertj-joda-time + 2.2.0 + compile + + - - - - - maven-surefire-plugin - 3.3.0 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.13.0 - - 21 - 21 - - -Xlint:all - -Xlint:-auxiliaryclass - -Xlint:-rawtypes - -Xlint:-unchecked - -Xlint:-lossy-conversions - -Werror - - - - - org.jacoco - jacoco-maven-plugin - 0.8.12 - - - - prepare-agent - - - - generate-code-coverage-report - test - - report - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - 3.4.0 - - checkstyle.xml - true - true - warning - - - - com.puppycrawl.tools - checkstyle - 10.17.0 - - - + + + + org.junit.jupiter + junit-jupiter + 5.10.3 + test + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.junit.jupiter + junit-jupiter-api + 5.10.3 + test + + + org.apache.commons + commons-lang3 + 3.14.0 + + + org.apache.commons + commons-collections4 + 4.5.0-M2 + + + io.spring.javaformat + spring-javaformat-formatter + 0.0.40 + + + + org.assertj + assertj-guava + 3.26.0 + compile + + + + org.assertj + assertj-db + 2.0.2 + compile + + + + org.assertj + assertj-joda-time + 2.2.0 + compile + + + + + + + maven-surefire-plugin + 3.3.0 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + 21 + 21 + + -Xlint:all + -Xlint:-auxiliaryclass + -Xlint:-rawtypes + -Xlint:-unchecked + -Xlint:-lossy-conversions + -Werror + + + + + org.jacoco + jacoco-maven-plugin + 0.8.12 + + + + prepare-agent + + + + generate-code-coverage-report + test + + report + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.4.0 + + checkstyle.xml + true + true + warning + + + + com.puppycrawl.tools + checkstyle + 10.17.0 + + + + + com.github.spotbugs + spotbugs-maven-plugin + 4.8.6.1 + + spotbugs-exclude.xml + true + - com.github.spotbugs - spotbugs-maven-plugin - 4.8.6.1 - - spotbugs-exclude.xml - true - - - com.mebigfatguy.fb-contrib - fb-contrib - 7.6.4 - - - com.h3xstream.findsecbugs - findsecbugs-plugin - 1.13.0 - - - + com.mebigfatguy.fb-contrib + fb-contrib + 7.6.4 - org.apache.maven.plugins - maven-pmd-plugin - 3.23.0 - - true - true - false - pmd-exclude.properties - + com.h3xstream.findsecbugs + findsecbugs-plugin + 1.13.0 - - - + + + + + org.apache.maven.plugins + maven-pmd-plugin + 3.23.0 + + true + true + false + pmd-exclude.properties + + + + 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/thealgorithms/greedyalgorithms/ActivitySelectionActivitySelectionTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionActivitySelectionTest.java new file mode 100644 index 000000000000..a1bf4cb76380 --- /dev/null +++ b/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionActivitySelectionTest.java @@ -0,0 +1,206 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test java-algos using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 +ROOST_METHOD_HASH=activitySelection_77631a6e2d +ROOST_METHOD_SIG_HASH=activitySelection_bf79d28a9f +================================VULNERABILITIES================================ +Vulnerability: cwe-190: integer overflow or wraparound +Issue: The code uses int for array indices and lengths, which could lead to integer overflow if very large input arrays are provided. This could result in unexpected behavior or crashes. +Solution: Use long instead of int for array indices and lengths, or implement input validation to ensure array sizes are within safe limits. +Vulnerability: cwe-789: uncontrolled memory allocation +Issue: The method creates a 2D array (activities) based on input array sizes without any bounds checking. This could lead to OutOfMemoryError if very large input arrays are provided. +Solution: Implement input validation to limit the maximum size of input arrays, or use a more memory-efficient data structure for large inputs. +Vulnerability: cwe-476: null pointer dereference +Issue: The method assumes that startTimes and endTimes arrays are non-null and have the same length. If either is null or they have different lengths, it could lead to NullPointerException or ArrayIndexOutOfBoundsException. +Solution: Add null checks and length validation at the beginning of the method to ensure inputs are valid before processing. +Vulnerability: cwe-440: expected behavior violation +Issue: The method doesn't handle the case where input arrays are empty, which could lead to unexpected behavior or IndexOutOfBoundsException when trying to access activities[0]. +Solution: Add a check for empty input arrays at the beginning of the method and return an appropriate result (e.g., an empty ArrayList) in such cases. +================================================================================ +Based on the provided method and imports, here are several test scenarios for the `activitySelection` method: +``` +Scenario 1: Basic Activity Selection +Details: + TestName: basicActivitySelection + Description: Test the basic functionality of activity selection with a simple set of non-overlapping activities. +Execution: + Arrange: Create arrays for start times and end times with non-overlapping activities. + Act: Call activitySelection with the arranged start and end times. + Assert: Verify that the returned ArrayList contains the expected activity indices in the correct order. +Validation: + This test ensures that the method correctly selects all activities when they don't overlap. It validates the core logic of the activity selection algorithm for a straightforward case. +Scenario 2: Overlapping Activities +Details: + TestName: overlappingActivities + Description: Test the method's ability to select the maximum number of non-overlapping activities from a set of overlapping activities. +Execution: + Arrange: Create arrays for start times and end times with some overlapping activities. + Act: Call activitySelection with the arranged start and end times. + Assert: Verify that the returned ArrayList contains the indices of the maximum set of non-overlapping activities. +Validation: + This test checks if the method correctly handles overlapping activities and selects the optimal set of non-overlapping activities. It validates the core functionality of the greedy algorithm used in activity selection. +Scenario 3: Empty Input Arrays +Details: + TestName: emptyInputArrays + Description: Test the method's behavior when given empty input arrays. +Execution: + Arrange: Create empty arrays for start times and end times. + Act: Call activitySelection with the empty arrays. + Assert: Verify that the method returns an empty ArrayList. +Validation: + This test ensures that the method handles edge cases gracefully, specifically when no activities are provided. It's important to validate that the method doesn't throw exceptions and returns an expected empty result. +Scenario 4: Single Activity +Details: + TestName: singleActivity + Description: Test the method's behavior when given a single activity. +Execution: + Arrange: Create start times and end times arrays with a single element each. + Act: Call activitySelection with these single-element arrays. + Assert: Verify that the returned ArrayList contains only one element with the index 0. +Validation: + This test checks if the method correctly handles the edge case of a single activity. It ensures that the method works correctly for the simplest possible input. +Scenario 5: Activities with Same End Time +Details: + TestName: activitiesWithSameEndTime + Description: Test the method's behavior when multiple activities have the same end time. +Execution: + Arrange: Create start times and end times arrays where multiple activities end at the same time. + Act: Call activitySelection with these arrays. + Assert: Verify that the returned ArrayList contains the correct selection of activities, prioritizing the ones that start earlier. +Validation: + This test ensures that the method correctly handles activities with the same end time, which tests the stability of the sorting algorithm and the selection process. +Scenario 6: Activities with Same Start Time +Details: + TestName: activitiesWithSameStartTime + Description: Test the method's behavior when multiple activities have the same start time. +Execution: + Arrange: Create start times and end times arrays where multiple activities start at the same time. + Act: Call activitySelection with these arrays. + Assert: Verify that the returned ArrayList contains the correct selection of activities, prioritizing the ones that end earlier. +Validation: + This test checks if the method correctly handles activities with the same start time, ensuring that the selection process is based on end times as expected. +Scenario 7: Large Number of Activities +Details: + TestName: largeNumberOfActivities + Description: Test the method's performance and correctness with a large number of activities. +Execution: + Arrange: Create large arrays for start times and end times with many activities. + Act: Call activitySelection with these large arrays. + Assert: Verify that the returned ArrayList contains a correct selection of non-overlapping activities. +Validation: + This test ensures that the method scales well and maintains correctness for a large input size. It helps validate the efficiency of the algorithm implementation. +``` +These test scenarios cover various aspects of the `activitySelection` method, including basic functionality, edge cases, and potential challenging scenarios. They aim to thoroughly validate the method's behavior and correctness. +*/ +// ********RoostGPT******** +package com.thealgorithms.greedyalgorithms; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.stream.Stream; +import static org.assertj.core.api.Assertions.assertThat; +import java.util.Comparator; +import org.junit.jupiter.api.*; + +@Tag("com.thealgorithms.sorts") +@Tag("com.thealgorithms.sorts.sort") +@Tag("com.thealgorithms.maths") +@Tag("com.thealgorithms.maths.add") +@Tag("com.thealgorithms.maths.add") +@Tag("com.thealgorithms.greedyalgorithms") +@Tag("com.thealgorithms.greedyalgorithms.activitySelection") +class ActivitySelectionActivitySelectionTest { + + @Test + void basicActivitySelection() { + int[] startTimes = { 1, 3, 0, 5, 8, 5 }; + int[] endTimes = { 2, 4, 6, 7, 9, 9 }; + ArrayList expected = new ArrayList<>(Arrays.asList(0, 1, 3, 4)); + ArrayList result = ActivitySelection.activitySelection(startTimes, endTimes); + assertThat(result).isEqualTo(expected); + } + + @Test + void overlappingActivities() { + int[] startTimes = { 1, 3, 0, 5, 3, 5 }; + int[] endTimes = { 4, 5, 6, 7, 8, 9 }; + ArrayList expected = new ArrayList<>(Arrays.asList(0, 3)); + ArrayList result = ActivitySelection.activitySelection(startTimes, endTimes); + assertThat(result).isEqualTo(expected); + } + + @Test + void emptyInputArrays() { + int[] startTimes = {}; + int[] endTimes = {}; + ArrayList expected = new ArrayList<>(); + ArrayList result = ActivitySelection.activitySelection(startTimes, endTimes); + assertThat(result).isEqualTo(expected); + } + + @Test + void singleActivity() { + int[] startTimes = { 1 }; + int[] endTimes = { 2 }; + ArrayList expected = new ArrayList<>(Arrays.asList(0)); + ArrayList result = ActivitySelection.activitySelection(startTimes, endTimes); + assertThat(result).isEqualTo(expected); + } + + @Test + void activitiesWithSameEndTime() { + int[] startTimes = { 1, 3, 2, 5 }; + int[] endTimes = { 4, 4, 4, 6 }; + ArrayList expected = new ArrayList<>(Arrays.asList(0, 3)); + ArrayList result = ActivitySelection.activitySelection(startTimes, endTimes); + assertThat(result).isEqualTo(expected); + } + + @Test + void activitiesWithSameStartTime() { + int[] startTimes = { 1, 1, 1, 4 }; + int[] endTimes = { 2, 3, 4, 5 }; + ArrayList expected = new ArrayList<>(Arrays.asList(0, 3)); + ArrayList result = ActivitySelection.activitySelection(startTimes, endTimes); + assertThat(result).isEqualTo(expected); + } + + @Test + void largeNumberOfActivities() { + int[] startTimes = new int[1000]; + int[] endTimes = new int[1000]; + for (int i = 0; i < 1000; i++) { + startTimes[i] = i * 2; + endTimes[i] = i * 2 + 1; + } + ArrayList result = ActivitySelection.activitySelection(startTimes, endTimes); + assertThat(result).hasSize(1000); + for (int i = 0; i < 1000; i++) { + assertThat(result).contains(i); + } + } + + @ParameterizedTest + @MethodSource("provideActivitySelectionTestCases") + void parameterizedActivitySelectionTest(int[] startTimes, int[] endTimes, ArrayList expected) { + ArrayList result = ActivitySelection.activitySelection(startTimes, endTimes); + assertThat(result).isEqualTo(expected); + } + + private static Stream provideActivitySelectionTestCases() { + return Stream.of( + Arguments.of(new int[] { 1, 3, 0, 5, 8, 5 }, new int[] { 2, 4, 6, 7, 9, 9 }, + new ArrayList<>(Arrays.asList(0, 1, 3, 4))), + Arguments.of(new int[] { 1, 3, 0, 5, 3, 5 }, new int[] { 4, 5, 6, 7, 8, 9 }, + new ArrayList<>(Arrays.asList(0, 3))), + Arguments.of(new int[] {}, new int[] {}, new ArrayList<>()), + Arguments.of(new int[] { 1 }, new int[] { 2 }, new ArrayList<>(Arrays.asList(0))), + Arguments.of(new int[] { 1, 3, 2, 5 }, new int[] { 4, 4, 4, 6 }, new ArrayList<>(Arrays.asList(0, 3))), + Arguments.of(new int[] { 1, 1, 1, 4 }, new int[] { 2, 3, 4, 5 }, new ArrayList<>(Arrays.asList(0, 3)))); + } + +} \ No newline at end of file diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeCoinChangeProblemTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeCoinChangeProblemTest.java new file mode 100644 index 000000000000..f039bf9ac958 --- /dev/null +++ b/src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeCoinChangeProblemTest.java @@ -0,0 +1,125 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test java-algos using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 +ROOST_METHOD_HASH=coinChangeProblem_db77356e05 +ROOST_METHOD_SIG_HASH=coinChangeProblem_9cb8b5505c +================================VULNERABILITIES================================ +Vulnerability: integer overflow +Issue: The 'amount' parameter in coinChangeProblem() method could potentially overflow if a large value is passed, leading to unexpected behavior or incorrect results. +Solution: Use BigInteger instead of int for large currency amounts, or implement input validation to ensure the amount is within a safe range. +Vulnerability: denial of service +Issue: If a malicious user provides a very large 'amount', it could lead to excessive loop iterations, potentially causing a denial of service. +Solution: Implement input validation to limit the maximum allowed amount, or use a more efficient algorithm with better time complexity. +Vulnerability: information exposure +Issue: The method returns detailed information about the coin denominations used, which might not be necessary and could potentially expose internal system details. +Solution: Consider returning only the total number of coins or a simplified representation of the result, based on the actual requirements of the application. +Vulnerability: insecure random number generation +Issue: While not directly present in this code, if this method is used in a cryptographic context, the lack of secure random number generation could be a concern. +Solution: If this method is part of a larger system dealing with sensitive financial operations, ensure that any related randomness (e.g., for transaction IDs) uses SecureRandom instead of Random. +================================================================================ +Based on the provided method and imports, here are several test scenarios for the coinChangeProblem method: +Scenario 1: Basic Coin Change for a Small Amount +Details: + TestName: coinChangeForSmallAmount + Description: Test the coin change problem for a small amount that can be perfectly divided using available denominations. +Execution: + Arrange: Set up the test with a small amount (e.g., 78). + Act: Call coinChangeProblem(78). + Assert: Check if the returned ArrayList contains the expected coins [50, 20, 5, 2, 1]. +Validation: + Verify that the method correctly selects the optimal combination of coins for a small amount. This test ensures the greedy algorithm works for simple cases. +Scenario 2: Coin Change for a Large Amount +Details: + TestName: coinChangeForLargeAmount + Description: Test the coin change problem for a large amount to ensure the method can handle bigger values efficiently. +Execution: + Arrange: Set up the test with a large amount (e.g., 5432). + Act: Call coinChangeProblem(5432). + Assert: Check if the returned ArrayList contains the expected coins [2000, 2000, 1000, 500, 20, 10, 2]. +Validation: + Confirm that the method can handle larger amounts and still produce the optimal coin combination. This test checks the scalability of the algorithm. +Scenario 3: Coin Change for Zero Amount +Details: + TestName: coinChangeForZeroAmount + Description: Test the coin change problem when the input amount is zero. +Execution: + Arrange: Set up the test with amount 0. + Act: Call coinChangeProblem(0). + Assert: Check if the returned ArrayList is empty. +Validation: + Ensure that the method correctly handles the edge case of zero amount by returning an empty list. This test verifies the method's behavior for the minimum possible input. +Scenario 4: Coin Change for Maximum Denomination +Details: + TestName: coinChangeForMaxDenomination + Description: Test the coin change problem when the input amount exactly matches the maximum coin denomination. +Execution: + Arrange: Set up the test with amount 2000 (matching the highest denomination). + Act: Call coinChangeProblem(2000). + Assert: Check if the returned ArrayList contains a single coin [2000]. +Validation: + Verify that the method correctly handles the case where the amount matches the highest denomination, returning only one coin. This test checks the algorithm's efficiency for optimal cases. +Scenario 5: Coin Change for Amount Less Than Smallest Denomination +Details: + TestName: coinChangeForAmountLessThanSmallestCoin + Description: Test the coin change problem when the input amount is less than the smallest available coin denomination. +Execution: + Arrange: Set up the test with amount 0.5 (less than the smallest coin of 1). + Act: Call coinChangeProblem(0). + Assert: Check if the returned ArrayList is empty. +Validation: + Ensure that the method correctly handles amounts smaller than the smallest coin by returning an empty list. This test verifies the method's behavior for invalid inputs. +Scenario 6: Coin Change for Large Amount with Repeated Denominations +Details: + TestName: coinChangeForLargeAmountWithRepeatedDenominations + Description: Test the coin change problem for a large amount that requires multiple instances of the same coin denomination. +Execution: + Arrange: Set up the test with a large amount (e.g., 10000). + Act: Call coinChangeProblem(10000). + Assert: Check if the returned ArrayList contains the expected coins [2000, 2000, 2000, 2000, 2000]. +Validation: + Verify that the method correctly handles cases where multiple instances of the highest denomination are required. This test ensures the algorithm can repeat coin selections when necessary. +These test scenarios cover various aspects of the coinChangeProblem method, including normal cases, edge cases, and potential error conditions. They aim to validate the correct functioning of the method across different input ranges and scenarios. +*/ +// ********RoostGPT******** +package com.thealgorithms.greedyalgorithms; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import static org.assertj.core.api.Assertions.assertThat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.stream.Stream; +import java.util.Comparator; +import org.junit.jupiter.api.*; + +@Tag("com.thealgorithms.sorts") +@Tag("com.thealgorithms.sorts.sort") +@Tag("com.thealgorithms.maths") +@Tag("com.thealgorithms.maths.add") +@Tag("com.thealgorithms.greedyalgorithms") +@Tag("com.thealgorithms.greedyalgorithms.coinChangeProblem") +class CoinChangeCoinChangeProblemTest { + + @ParameterizedTest + @MethodSource("coinChangeTestCases") + void testCoinChangeProblem(int amount, ArrayList expected) { + ArrayList result = CoinChange.coinChangeProblem(amount); + assertThat(result).isEqualTo(expected); + } + + private static Stream coinChangeTestCases() { + return Stream.of(Arguments.of(78, new ArrayList<>(Arrays.asList(50, 20, 5, 2, 1))), + Arguments.of(5432, new ArrayList<>(Arrays.asList(2000, 2000, 1000, 500, 20, 10, 2))), + Arguments.of(0, new ArrayList<>()), Arguments.of(2000, new ArrayList<>(Arrays.asList(2000))), + Arguments.of(10000, new ArrayList<>(Arrays.asList(2000, 2000, 2000, 2000, 2000)))); + } + + @Test + void testCoinChangeForAmountLessThanSmallestCoin() { + ArrayList result = CoinChange.coinChangeProblem(0); + assertThat(result).isEmpty(); + } + +} \ No newline at end of file diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackFractionalKnapsackTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackFractionalKnapsackTest.java new file mode 100644 index 000000000000..6fcb88405976 --- /dev/null +++ b/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackFractionalKnapsackTest.java @@ -0,0 +1,196 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test java-algos using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 +ROOST_METHOD_HASH=fractionalKnapsack_b327dd7d5e +ROOST_METHOD_SIG_HASH=fractionalKnapsack_1caf503527 +================================VULNERABILITIES================================ +Vulnerability: integer overflow +Issue: The calculation of finalValue += (int) (ratio[i][1] * current) may lead to integer overflow if the result exceeds Integer.MAX_VALUE. +Solution: Use long for finalValue and cast the result to int only when returning. Also, consider using BigInteger for very large values. +Vulnerability: floating-point precision loss +Issue: Using double for ratio calculations can lead to precision loss, potentially affecting the accuracy of the knapsack algorithm. +Solution: Consider using BigDecimal for precise decimal calculations, especially when dealing with currency or other sensitive numerical data. +Vulnerability: array index out of bounds +Issue: If the weight or value arrays are empty, accessing ratio[i][0] or ratio[i][1] could cause an ArrayIndexOutOfBoundsException. +Solution: Add input validation to check if weight and value arrays are non-empty before processing. +Vulnerability: null pointer dereference +Issue: The method doesn't check if the input arrays (weight and value) are null, which could lead to a NullPointerException. +Solution: Add null checks for input parameters at the beginning of the method and throw an IllegalArgumentException if they are null. +Vulnerability: input validation +Issue: The method doesn't validate if the capacity is non-negative or if the weight and value arrays have the same length. +Solution: Add input validation to ensure capacity is non-negative and that weight and value arrays have the same length. Throw IllegalArgumentException for invalid inputs. +================================================================================ +Based on the provided method and instructions, here are several test scenarios for the fractionalKnapsack method: +Scenario 1: Basic Functionality Test +Details: + TestName: basicFunctionalityTest + Description: Verify that the method correctly calculates the maximum value for a simple knapsack problem with integer weights and values. +Execution: + Arrange: Create arrays for weights, values, and set a capacity. + Act: Call fractionalKnapsack with the prepared data. + Assert: Compare the returned value with the expected maximum value. +Validation: + This test ensures that the basic algorithm works correctly for a straightforward case. It validates that the method can properly sort items by value-to-weight ratio and select the most valuable items within the given capacity. +Scenario 2: Fractional Item Test +Details: + TestName: fractionalItemTest + Description: Test the method's ability to handle fractional items when the knapsack can't fit a whole item. +Execution: + Arrange: Set up weight and value arrays where the last item to be added would exceed the capacity. + Act: Invoke fractionalKnapsack with the prepared data. + Assert: Verify that the returned value includes a fraction of the last item. +Validation: + This test checks if the method correctly calculates and adds the value of a fractional item when the knapsack is almost full. It's crucial for verifying the "fractional" aspect of the algorithm. +Scenario 3: Empty Knapsack Test +Details: + TestName: emptyKnapsackTest + Description: Verify the method's behavior when the knapsack capacity is zero. +Execution: + Arrange: Prepare non-empty weight and value arrays, but set the capacity to 0. + Act: Call fractionalKnapsack with zero capacity. + Assert: Confirm that the returned value is 0. +Validation: + This test ensures that the method handles the edge case of zero capacity correctly, returning no value as expected. +Scenario 4: Single Item Test +Details: + TestName: singleItemTest + Description: Test the method with only one item in the knapsack. +Execution: + Arrange: Create weight and value arrays with a single element. + Act: Invoke fractionalKnapsack with the single-item data. + Assert: Check if the returned value matches the expected value for the single item. +Validation: + This test verifies that the method works correctly with the minimal input of just one item, ensuring no errors occur in edge cases with minimal data. +Scenario 5: Capacity Exceeds Total Weight Test +Details: + TestName: capacityExceedsTotalWeightTest + Description: Test the scenario where the knapsack capacity is larger than the total weight of all items. +Execution: + Arrange: Set up weight and value arrays where the sum of weights is less than the capacity. + Act: Call fractionalKnapsack with the prepared data. + Assert: Verify that the returned value is the sum of all item values. +Validation: + This test ensures that when the capacity is more than sufficient, the method correctly includes all items and returns their total value. +Scenario 6: Large Number of Items Test +Details: + TestName: largeNumberOfItemsTest + Description: Verify the method's performance and correctness with a large number of items. +Execution: + Arrange: Create large arrays for weights and values (e.g., 10000 items). + Act: Invoke fractionalKnapsack with the large dataset. + Assert: Compare the returned value with a pre-calculated expected value. +Validation: + This test checks the method's ability to handle large inputs efficiently and correctly, which is important for real-world scenarios with many items. +Scenario 7: All Items with Same Ratio Test +Details: + TestName: allItemsSameRatioTest + Description: Test the method's behavior when all items have the same value-to-weight ratio. +Execution: + Arrange: Prepare weight and value arrays where all items have the same value-to-weight ratio. + Act: Call fractionalKnapsack with the prepared data. + Assert: Verify that the returned value matches the expected maximum value. +Validation: + This test ensures that the method works correctly when the sorting step doesn't differentiate between items, checking if it properly fills the knapsack in this edge case. +*/ +// ********RoostGPT******** +package com.thealgorithms.greedyalgorithms; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import static org.junit.jupiter.api.Assertions.*; +import java.util.stream.Stream; +import java.util.Arrays; +import java.util.Comparator; +import org.junit.jupiter.api.*; + +@Tag("com.thealgorithms.sorts") +@Tag("com.thealgorithms.sorts.sort") +@Tag("com.thealgorithms.greedyalgorithms") +@Tag("com.thealgorithms.greedyalgorithms.fractionalKnapsack") +class FractionalKnapsackFractionalKnapsackTest { + + @Test + void basicFunctionalityTest() { + int[] weights = { 10, 20, 30 }; + int[] values = { 60, 100, 120 }; + int capacity = 50; + int expectedValue = 240; + assertEquals(expectedValue, FractionalKnapsack.fractionalKnapsack(weights, values, capacity)); + } + + @Test + void fractionalItemTest() { + int[] weights = { 10, 20, 30 }; + int[] values = { 60, 100, 120 }; + int capacity = 55; + int expectedValue = 250; + assertEquals(expectedValue, FractionalKnapsack.fractionalKnapsack(weights, values, capacity)); + } + + @Test + void emptyKnapsackTest() { + int[] weights = { 10, 20, 30 }; + int[] values = { 60, 100, 120 }; + int capacity = 0; + int expectedValue = 0; + assertEquals(expectedValue, FractionalKnapsack.fractionalKnapsack(weights, values, capacity)); + } + + @Test + void singleItemTest() { + int[] weights = { 50 }; + int[] values = { 100 }; + int capacity = 50; + int expectedValue = 100; + assertEquals(expectedValue, FractionalKnapsack.fractionalKnapsack(weights, values, capacity)); + } + + @Test + void capacityExceedsTotalWeightTest() { + int[] weights = { 10, 20, 30 }; + int[] values = { 60, 100, 120 }; + int capacity = 100; + int expectedValue = 280; + assertEquals(expectedValue, FractionalKnapsack.fractionalKnapsack(weights, values, capacity)); + } + + @Test + void largeNumberOfItemsTest() { + int[] weights = new int[10000]; + int[] values = new int[10000]; + for (int i = 0; i < 10000; i++) { + weights[i] = i + 1; + values[i] = (i + 1) * 10; + } + int capacity = 5000; + int expectedValue = 495050; + assertEquals(expectedValue, FractionalKnapsack.fractionalKnapsack(weights, values, capacity)); + } + + @Test + void allItemsSameRatioTest() { + int[] weights = { 10, 20, 30, 40, 50 }; + int[] values = { 20, 40, 60, 80, 100 }; + int capacity = 100; + int expectedValue = 200; + assertEquals(expectedValue, FractionalKnapsack.fractionalKnapsack(weights, values, capacity)); + } + + @ParameterizedTest + @MethodSource("provideTestCases") + void parameterizedTest(int[] weights, int[] values, int capacity, int expectedValue) { + assertEquals(expectedValue, FractionalKnapsack.fractionalKnapsack(weights, values, capacity)); + } + + private static Stream provideTestCases() { + return Stream.of(Arguments.of(new int[] { 10, 20, 30 }, new int[] { 60, 100, 120 }, 50, 240), + Arguments.of(new int[] { 10, 20, 30 }, new int[] { 60, 100, 120 }, 55, 250), + Arguments.of(new int[] { 10, 20, 30 }, new int[] { 60, 100, 120 }, 0, 0), + Arguments.of(new int[] { 50 }, new int[] { 100 }, 50, 100), + Arguments.of(new int[] { 10, 20, 30 }, new int[] { 60, 100, 120 }, 100, 280), + Arguments.of(new int[] { 10, 20, 30, 40, 50 }, new int[] { 20, 40, 60, 80, 100 }, 100, 200)); + } + +} \ No newline at end of file diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingFindJobSequenceTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingFindJobSequenceTest.java new file mode 100644 index 000000000000..9aa2985116bd --- /dev/null +++ b/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingFindJobSequenceTest.java @@ -0,0 +1,184 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test java-algos using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 +ROOST_METHOD_HASH=findJobSequence_a922574874 +ROOST_METHOD_SIG_HASH=findJobSequence_1dce91ae26 +================================VULNERABILITIES================================ +Vulnerability: cwe-190: integer overflow +Issue: The method uses 'int' for array indexing and loop counters, which could lead to integer overflow if the input size is very large. This could result in unexpected behavior or array index out of bounds errors. +Solution: Use 'long' instead of 'int' for size-related variables, or implement input validation to ensure the size is within a safe range. +Vulnerability: cwe-476: null pointer dereference +Issue: The method doesn't check if the input 'jobs' ArrayList is null before accessing it. This could lead to a NullPointerException if the input is null. +Solution: Add a null check at the beginning of the method and handle the null case appropriately, e.g., throw an IllegalArgumentException or return an error message. +Vulnerability: cwe-129: improper validation of array index +Issue: The method doesn't validate that the job deadlines are within the range of the 'slots' array. If a job has a deadline larger than 'size', it could lead to an ArrayIndexOutOfBoundsException. +Solution: Add input validation to ensure all job deadlines are less than or equal to 'size', or use a data structure that can handle arbitrary deadlines. +Vulnerability: cwe-597: use of wrong operator in string comparison +Issue: The method uses '==' to compare Boolean objects in the 'slots' array. While this works for Boolean.TRUE and Boolean.FALSE, it's generally not a good practice for object comparison. +Solution: Use the equals() method for Boolean comparisons, or consider using primitive boolean values instead of Boolean objects for better performance. +Vulnerability: cwe-691: insufficient control flow management +Issue: The method doesn't handle the case where no suitable slot is found for a job. This could lead to unexpected behavior or incorrect results. +Solution: Add logic to handle cases where a job cannot be scheduled, such as maintaining a list of unscheduled jobs or adjusting the algorithm to always find a valid schedule if possible. +================================================================================ +Based on the provided method and imports, I'll generate several test scenarios for the `findJobSequence` method. Here are the test scenarios: +Scenario 1: Test with a valid list of jobs +Details: + TestName: validJobSequence + Description: Test the method with a valid list of jobs to ensure it returns the correct job sequence. +Execution: + Arrange: Create an ArrayList of Job objects with various deadlines and profits. + Act: Call findJobSequence with the created job list and the size of the list. + Assert: Compare the returned string with the expected job sequence. +Validation: + This test verifies that the method correctly identifies and orders jobs based on their deadlines and profits. It ensures that the core functionality of the job sequencing algorithm is working as expected. +Scenario 2: Test with an empty job list +Details: + TestName: emptyJobList + Description: Test the method's behavior when provided with an empty list of jobs. +Execution: + Arrange: Create an empty ArrayList of Job objects. + Act: Call findJobSequence with the empty job list and size 0. + Assert: Verify that the returned string is "Job Sequence: " (empty sequence). +Validation: + This test checks how the method handles edge cases, specifically an empty input. It ensures that the method doesn't throw exceptions and returns an appropriate result for empty inputs. +Scenario 3: Test with jobs having identical deadlines +Details: + TestName: jobsWithIdenticalDeadlines + Description: Test the method's behavior when multiple jobs have the same deadline. +Execution: + Arrange: Create an ArrayList of Job objects where multiple jobs have the same deadline. + Act: Call findJobSequence with the created job list and the size of the list. + Assert: Verify that the returned job sequence prioritizes jobs correctly based on profit. +Validation: + This test ensures that the method can handle cases where multiple jobs compete for the same time slot, verifying that it selects the most profitable jobs when deadlines conflict. +Scenario 4: Test with jobs having deadlines exceeding the size parameter +Details: + TestName: jobsWithExceedingDeadlines + Description: Test the method's behavior when job deadlines exceed the provided size parameter. +Execution: + Arrange: Create an ArrayList of Job objects where some job deadlines are greater than the size parameter. + Act: Call findJobSequence with the created job list and a size smaller than some job deadlines. + Assert: Verify that the returned job sequence only includes jobs within the valid time slots. +Validation: + This test checks if the method correctly handles jobs with deadlines that exceed the available time slots, ensuring it doesn't cause array index out of bounds errors and selects jobs within the valid range. +Scenario 5: Test with a single job +Details: + TestName: singleJobSequence + Description: Test the method's behavior when provided with a list containing only one job. +Execution: + Arrange: Create an ArrayList with a single Job object. + Act: Call findJobSequence with the single-job list and size 1. + Assert: Verify that the returned string contains only the ID of the single job. +Validation: + This test verifies that the method works correctly for the minimal case of a single job, ensuring it doesn't rely on having multiple jobs to function properly. +Scenario 6: Test with jobs having all unique deadlines +Details: + TestName: uniqueDeadlineJobs + Description: Test the method with jobs that all have different deadlines. +Execution: + Arrange: Create an ArrayList of Job objects where each job has a unique deadline. + Act: Call findJobSequence with the created job list and the size of the list. + Assert: Verify that the returned job sequence includes all jobs in the correct order. +Validation: + This test ensures that when there are no deadline conflicts, the method correctly schedules all jobs in their respective time slots, maximizing the number of jobs completed. +These test scenarios cover various aspects of the `findJobSequence` method, including normal operation, edge cases, and potential error conditions. They aim to validate the method's correctness, robustness, and adherence to the job sequencing algorithm's requirements. +*/ +// ********RoostGPT******** +package com.thealgorithms.greedyalgorithms; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import static org.assertj.core.api.Assertions.assertThat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.stream.Stream; +import org.junit.jupiter.api.*; + +@Tag("com.thealgorithms.maths") +@Tag("com.thealgorithms.maths.get") +@Tag("com.thealgorithms.maths.get") +@Tag("com.thealgorithms.datastructures.lists") +@Tag("com.thealgorithms.datastructures.lists.append") +@Tag("com.thealgorithms.datastructures.lists.size") +@Tag("com.thealgorithms.datastructures.lists.append") +@Tag("com.thealgorithms.datastructures.lists.append") +@Tag("com.thealgorithms.datastructures.lists.length") +@Tag("com.thealgorithms.datastructures.lists.length") +@Tag("com.thealgorithms.greedyalgorithms") +@Tag("com.thealgorithms.greedyalgorithms.findJobSequence") +@Tag("com.thealgorithms.greedyalgorithms.toString") +class JobSequencingFindJobSequenceTest { + + @Test + void validJobSequence() { + ArrayList jobs = new ArrayList<>(Arrays.asList(new Job('a', 2, 100), new Job('b', 1, 19), + new Job('c', 2, 27), new Job('d', 1, 25), new Job('e', 3, 15))); + String result = JobSequencing.findJobSequence(jobs, 3); + assertThat(result).isEqualTo("Job Sequence: c -> a -> e"); + } + + @Test + void emptyJobList() { + ArrayList jobs = new ArrayList<>(); + String result = JobSequencing.findJobSequence(jobs, 0); + assertThat(result).isEqualTo("Job Sequence: "); + } + + @Test + void jobsWithIdenticalDeadlines() { + ArrayList jobs = new ArrayList<>(Arrays.asList(new Job('a', 2, 100), new Job('b', 2, 19), + new Job('c', 2, 27), new Job('d', 2, 25), new Job('e', 2, 15))); + String result = JobSequencing.findJobSequence(jobs, 2); + assertThat(result).isEqualTo("Job Sequence: a -> c"); + } + + @Test + void jobsWithExceedingDeadlines() { + ArrayList jobs = new ArrayList<>(Arrays.asList(new Job('a', 4, 100), new Job('b', 1, 19), + new Job('c', 3, 27), new Job('d', 2, 25), new Job('e', 5, 15))); + String result = JobSequencing.findJobSequence(jobs, 3); + assertThat(result).isEqualTo("Job Sequence: b -> d -> c"); + } + + @Test + void singleJobSequence() { + ArrayList jobs = new ArrayList<>(Arrays.asList(new Job('a', 1, 100))); + String result = JobSequencing.findJobSequence(jobs, 1); + assertThat(result).isEqualTo("Job Sequence: a"); + } + + @Test + void uniqueDeadlineJobs() { + ArrayList jobs = new ArrayList<>(Arrays.asList(new Job('a', 1, 100), new Job('b', 2, 19), + new Job('c', 3, 27), new Job('d', 4, 25), new Job('e', 5, 15))); + String result = JobSequencing.findJobSequence(jobs, 5); + assertThat(result).isEqualTo("Job Sequence: a -> b -> c -> d -> e"); + } + + @ParameterizedTest + @MethodSource("provideTestCases") + void parameterizedJobSequenceTest(ArrayList jobs, int size, String expected) { + String result = JobSequencing.findJobSequence(jobs, size); + assertThat(result).isEqualTo(expected); + } + + private static Stream provideTestCases() { + return Stream.of( + Arguments + .of(new ArrayList<>(Arrays.asList(new Job('a', 2, 100), new Job('b', 1, 19), new Job('c', 2, 27), + new Job('d', 1, 25), new Job('e', 3, 15))), 3, "Job Sequence: c -> a -> e"), + Arguments.of(new ArrayList<>(), 0, "Job Sequence: "), + Arguments.of(new ArrayList<>(Arrays.asList(new Job('a', 2, 100), new Job('b', 2, 19), + new Job('c', 2, 27), new Job('d', 2, 25), new Job('e', 2, 15))), 2, "Job Sequence: a -> c"), + Arguments.of(new ArrayList<>(Arrays.asList(new Job('a', 4, 100), new Job('b', 1, 19), + new Job('c', 3, 27), new Job('d', 2, 25), new Job('e', 5, 15))), 3, + "Job Sequence: b -> d -> c"), + Arguments.of(new ArrayList<>(Arrays.asList(new Job('a', 1, 100))), 1, "Job Sequence: a"), + Arguments.of(new ArrayList<>(Arrays.asList(new Job('a', 1, 100), new Job('b', 2, 19), + new Job('c', 3, 27), new Job('d', 4, 25), new Job('e', 5, 15))), 5, + "Job Sequence: a -> b -> c -> d -> e")); + } + +} \ No newline at end of file diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessOfTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessOfTest.java new file mode 100644 index 000000000000..a7d12c5f4c08 --- /dev/null +++ b/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessOfTest.java @@ -0,0 +1,157 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test java-algos using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 +ROOST_METHOD_HASH=of_eb8138c6bc +ROOST_METHOD_SIG_HASH=of_7a04d5363c +================================VULNERABILITIES================================ +Vulnerability: input validation +Issue: The method accepts user input for jobName, processingTime, and deadline without validation, potentially allowing malicious data to be processed. +Solution: Implement input validation for all parameters. For example, check that jobName is not null or empty, and that processingTime and deadline are positive integers within a reasonable range. +Vulnerability: immutability +Issue: The Job class might be mutable, allowing its state to be changed after creation, which could lead to unexpected behavior in multithreaded environments. +Solution: Make the Job class immutable by declaring all fields as final and providing only getter methods. This ensures thread-safety and prevents unauthorized modifications. +Vulnerability: null pointer exception +Issue: The method doesn't check for null jobName, which could lead to NullPointerException if called with null argument. +Solution: Add a null check for jobName and throw an IllegalArgumentException if it's null. For example: if (jobName == null) throw new IllegalArgumentException("jobName cannot be null"); +Vulnerability: integer overflow +Issue: Large values for processingTime or deadline could cause integer overflow, leading to unexpected behavior or security vulnerabilities. +Solution: Implement bounds checking for processingTime and deadline. Consider using long instead of int if larger values are needed, and validate that the values are within an acceptable range. +================================================================================ +Based on the provided method and class information, here are several JUnit test scenarios for the `of` method: +``` +Scenario 1: Create a Job with Valid Parameters +Details: + TestName: createJobWithValidParameters + Description: Test the creation of a Job object with valid input parameters. +Execution: + Arrange: Prepare valid input parameters for jobName, processingTime, and deadline. + Act: Call the of method with these parameters. + Assert: Verify that the returned Job object is not null and has the correct values for all fields. +Validation: + This test ensures that the of method correctly creates and initializes a Job object when given valid inputs. It verifies that the factory method works as expected under normal conditions. +Scenario 2: Create a Job with Minimum Valid Values +Details: + TestName: createJobWithMinimumValidValues + Description: Test the creation of a Job object with the minimum acceptable values for processingTime and deadline. +Execution: + Arrange: Set up input parameters with a valid jobName, processingTime of 1, and deadline of 1. + Act: Invoke the of method with these parameters. + Assert: Check that the returned Job object has the correct values, including startTime of 0 and lateness of 0. +Validation: + This test verifies that the of method can handle the minimum valid values for processingTime and deadline, ensuring that edge cases are properly managed. +Scenario 3: Attempt to Create a Job with Null JobName +Details: + TestName: createJobWithNullJobName + Description: Test the behavior of the of method when passed a null value for jobName. +Execution: + Arrange: Prepare null for jobName, and valid values for processingTime and deadline. + Act: Call the of method with these parameters. + Assert: Expect an IllegalArgumentException or similar exception to be thrown. +Validation: + This test ensures that the method properly handles invalid input by rejecting null job names, maintaining data integrity. +Scenario 4: Attempt to Create a Job with Negative ProcessingTime +Details: + TestName: createJobWithNegativeProcessingTime + Description: Test the of method's response to a negative value for processingTime. +Execution: + Arrange: Set up a valid jobName, a negative value for processingTime, and a valid deadline. + Act: Invoke the of method with these parameters. + Assert: Expect an IllegalArgumentException or similar exception to be thrown. +Validation: + This test verifies that the method enforces the logical constraint that processing time cannot be negative, ensuring data validity. +Scenario 5: Attempt to Create a Job with Negative Deadline +Details: + TestName: createJobWithNegativeDeadline + Description: Test the of method's handling of a negative value for the deadline parameter. +Execution: + Arrange: Prepare a valid jobName, a valid processingTime, and a negative value for deadline. + Act: Call the of method with these parameters. + Assert: Expect an IllegalArgumentException or similar exception to be thrown. +Validation: + This test ensures that the method rejects illogical input where the deadline is set to a negative value, maintaining the integrity of the Job object's time-related properties. +Scenario 6: Create a Job with Large Values +Details: + TestName: createJobWithLargeValues + Description: Test the creation of a Job object with very large values for processingTime and deadline. +Execution: + Arrange: Set up input parameters with a valid jobName, and very large integers for processingTime and deadline (e.g., Integer.MAX_VALUE). + Act: Invoke the of method with these parameters. + Assert: Verify that the returned Job object correctly holds these large values without overflow or precision loss. +Validation: + This test checks the method's ability to handle extreme but valid input values, ensuring that the Job object can represent jobs with very long processing times or far-future deadlines. +``` +These test scenarios cover various aspects of the `of` method, including normal operation, edge cases, and error handling. They aim to ensure the method behaves correctly under different conditions and maintains the integrity of the Job object it creates. +*/ +// ********RoostGPT******** +package com.thealgorithms.greedyalgorithms; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import static org.junit.jupiter.api.Assertions.*; +import java.util.Arrays; +import org.junit.jupiter.api.*; + +@Tag("com.thealgorithms.greedyalgorithms") +@Tag("com.thealgorithms.greedyalgorithms.of") +class MinimizingLatenessOfTest { + + @Test + void createJobWithValidParameters() { + Job job = Job.of("TestJob", 10, 20); + assertNotNull(job); + assertEquals("TestJob", job.jobName); + assertEquals(10, job.processingTime); + assertEquals(20, job.deadline); + assertEquals(0, job.startTime); + assertEquals(0, job.lateness); + } + + @Test + void createJobWithMinimumValidValues() { + Job job = Job.of("MinJob", 1, 1); + assertNotNull(job); + assertEquals("MinJob", job.jobName); + assertEquals(1, job.processingTime); + assertEquals(1, job.deadline); + assertEquals(0, job.startTime); + assertEquals(0, job.lateness); + } + + @Test + void createJobWithNullJobName() { + assertThrows(IllegalArgumentException.class, () -> Job.of(null, 10, 20)); + } + + @Test + void createJobWithNegativeProcessingTime() { + assertThrows(IllegalArgumentException.class, () -> Job.of("NegativeJob", -5, 20)); + } + + @Test + void createJobWithNegativeDeadline() { + assertThrows(IllegalArgumentException.class, () -> Job.of("NegativeDeadline", 10, -5)); + } + + @Test + void createJobWithLargeValues() { + Job job = Job.of("LargeJob", Integer.MAX_VALUE, Integer.MAX_VALUE); + assertNotNull(job); + assertEquals("LargeJob", job.jobName); + assertEquals(Integer.MAX_VALUE, job.processingTime); + assertEquals(Integer.MAX_VALUE, job.deadline); + } + + @ParameterizedTest + @CsvSource({ "Job1, 5, 10", "Job2, 100, 200", "Job3, 50, 50" }) + void createJobWithVariousValues(String jobName, int processingTime, int deadline) { + Job job = Job.of(jobName, processingTime, deadline); + assertNotNull(job); + assertEquals(jobName, job.jobName); + assertEquals(processingTime, job.processingTime); + assertEquals(deadline, job.deadline); + assertEquals(0, job.startTime); + assertEquals(0, job.lateness); + } + +} \ No newline at end of file diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessToStringTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessToStringTest.java new file mode 100644 index 000000000000..00f12ba6475a --- /dev/null +++ b/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessToStringTest.java @@ -0,0 +1,141 @@ +// ********RoostGPT******** +/* +Test generated by RoostGPT for test java-algos using AI Type Claude AI and AI Model claude-3-5-sonnet-20240620 +ROOST_METHOD_HASH=toString_7033209074 +ROOST_METHOD_SIG_HASH=toString_bbffdadaa2 +================================VULNERABILITIES================================ +Vulnerability: cwe-134: uncontrolled format string +Issue: The toString() method uses String.format() with user-controlled input (jobName, startTime, processingTime, lateness) which could lead to format string vulnerabilities if these fields contain malicious format specifiers. +Solution: Use StringBuilder or String concatenation instead of String.format(). Alternatively, escape any '%' characters in the jobName field before passing it to String.format(). +Vulnerability: information exposure +Issue: The toString() method exposes internal state information (startTime, processingTime, lateness) which might be sensitive in certain contexts and could be exploited by attackers to gain insights into the system's internals. +Solution: Consider implementing a separate method for debug logging and limit the information exposed in toString() to non-sensitive data. Use appropriate access modifiers to restrict access to sensitive fields. +Vulnerability: integer overflow +Issue: The calculation of endTime (processingTime + startTime) could potentially lead to integer overflow if these values are large, resulting in unexpected behavior or incorrect calculations. +Solution: Use Math.addExact() for the addition to throw an ArithmeticException on overflow, or consider using long instead of int for these time values to reduce the risk of overflow. +================================================================================ +Based on the provided information, here are several test scenarios for the toString() method: +Scenario 1: Test toString() with All Fields Set +Details: + TestName: allFieldsSet + Description: Verify that the toString() method correctly formats the output when all fields are set to non-null/non-zero values. +Execution: + Arrange: Set jobName, startTime, processingTime, and lateness to valid values. + Act: Call the toString() method. + Assert: Compare the returned string with the expected formatted string. +Validation: + This test ensures that the toString() method correctly incorporates all field values in the expected format. It's crucial for debugging and logging purposes. +Scenario 2: Test toString() with Minimum Values +Details: + TestName: minimumValues + Description: Check the toString() output when all numeric fields are set to their minimum possible values (0). +Execution: + Arrange: Set jobName to a non-empty string, startTime, processingTime, and lateness to 0. + Act: Invoke the toString() method. + Assert: Verify that the returned string matches the expected format with zero values. +Validation: + This test validates that the method handles minimum values correctly, which is important for edge case scenarios. +Scenario 3: Test toString() with Null Job Name +Details: + TestName: nullJobName + Description: Verify the behavior of toString() when jobName is null. +Execution: + Arrange: Set jobName to null, and other fields to valid values. + Act: Call the toString() method. + Assert: Check if the method handles the null jobName appropriately (e.g., displays "null" or an empty string for jobName). +Validation: + This test ensures proper null handling for the jobName field, which is critical for robustness and error prevention. +Scenario 4: Test toString() with Large Values +Details: + TestName: largeValues + Description: Test the toString() method with very large values for numeric fields to ensure proper formatting. +Execution: + Arrange: Set startTime, processingTime, and lateness to very large integers (e.g., Integer.MAX_VALUE). + Act: Execute the toString() method. + Assert: Confirm that the returned string correctly includes these large values without truncation or formatting issues. +Validation: + This test checks the method's ability to handle extreme values, which is important for system robustness and accuracy in reporting. +Scenario 5: Test toString() with Negative Lateness +Details: + TestName: negativeLatenessHandling + Description: Verify that the toString() method correctly handles and displays negative lateness values. +Execution: + Arrange: Set lateness to a negative value, other fields to normal values. + Act: Call the toString() method. + Assert: Check if the negative lateness is correctly represented in the output string. +Validation: + This test ensures that the method can handle and display negative lateness, which might occur in certain scheduling scenarios. +Scenario 6: Test toString() for Consistency +Details: + TestName: consistencyCheck + Description: Ensure that multiple calls to toString() with the same field values produce identical results. +Execution: + Arrange: Set all fields to specific values. + Act: Call toString() multiple times. + Assert: Verify that all calls return the exact same string. +Validation: + This test confirms the consistency and deterministic nature of the toString() method, which is important for reliable logging and debugging. +These scenarios cover various aspects of the toString() method, including normal cases, edge cases, and potential error conditions, providing a comprehensive test suite for this method. +*/ +// ********RoostGPT******** +package com.thealgorithms.greedyalgorithms; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import static org.assertj.core.api.Assertions.assertThat; +import java.util.Arrays; +import org.junit.jupiter.api.*; + +@Tag("com.thealgorithms.greedyalgorithms") +@Tag("com.thealgorithms.greedyalgorithms.toString") +class MinimizingLatenessToStringTest { + + @ParameterizedTest + @CsvSource({ "Job1, 10, 20, 5, 'Job1, startTime: 10, endTime: 30, lateness: 5'", + "Job2, 0, 15, 0, 'Job2, startTime: 0, endTime: 15, lateness: 0'", + "Job3, 100, 50, -10, 'Job3, startTime: 100, endTime: 150, lateness: -10'", + "Job4, 2147483647, 1, 0, 'Job4, startTime: 2147483647, endTime: 2147483648, lateness: 0'" }) + void testToStringWithVariousInputs(String jobName, int startTime, int processingTime, int lateness, + String expected) { + Job job = new Job(jobName, processingTime, 0); + job.startTime = startTime; + job.lateness = lateness; + assertThat(job.toString()).isEqualTo(expected); + } + + @Test + void testToStringWithNullJobName() { + Job job = new Job(null, 10, 0); + job.startTime = 5; + job.lateness = 2; + assertThat(job.toString()).isEqualTo("null, startTime: 5, endTime: 15, lateness: 2"); + } + + @Test + void testToStringConsistency() { + Job job = new Job("ConsistentJob", 30, 0); + job.startTime = 20; + job.lateness = 10; + String result = job.toString(); + assertThat(job.toString()).isEqualTo(result); + assertThat(job.toString()).isEqualTo(result); + } + + @Test + void testToStringWithZeroValues() { + Job job = new Job("ZeroJob", 0, 0); + job.startTime = 0; + job.lateness = 0; + assertThat(job.toString()).isEqualTo("ZeroJob, startTime: 0, endTime: 0, lateness: 0"); + } + + @Test + void testToStringWithLargeValues() { + Job job = new Job("LargeJob", Integer.MAX_VALUE, 0); + job.startTime = Integer.MAX_VALUE; + job.lateness = Integer.MAX_VALUE; + assertThat(job.toString()).isEqualTo("LargeJob, startTime: 2147483647, endTime: -2, lateness: 2147483647"); + } + +} \ No newline at end of file