diff --git a/cucumber/features/general.feature b/cucumber/features/general.feature index 4255c89e7..3ac610669 100644 --- a/cucumber/features/general.feature +++ b/cucumber/features/general.feature @@ -1,7 +1,7 @@ @general Feature: API Validation - + @split-pdf-by-sections @positive Scenario Outline: split-pdf-by-sections with different parameters Given I generate a PDF file as "fileInput" @@ -66,7 +66,7 @@ Feature: API Validation | pageNumbers | file_count | | 1,3,5-9 | 8 | | all | 20 | - | 2n+1 | 11 | + | 2n+1 | 10 | | 3n | 7 | @@ -106,9 +106,9 @@ Feature: API Validation And the response ZIP should contain 2 files And the response file should have size greater than 0 And the response status code should be 200 - + Examples: - | format | - | png | + | format | + | png | | gif | - | jpeg | + | jpeg | diff --git a/src/main/java/stirling/software/SPDF/utils/GeneralUtils.java b/src/main/java/stirling/software/SPDF/utils/GeneralUtils.java index ac4cdca8f..799511452 100644 --- a/src/main/java/stirling/software/SPDF/utils/GeneralUtils.java +++ b/src/main/java/stirling/software/SPDF/utils/GeneralUtils.java @@ -13,6 +13,8 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.simpleyaml.configuration.file.YamlFile; import org.simpleyaml.configuration.file.YamlFileWrapper; @@ -220,32 +222,51 @@ public class GeneralUtils { throw new IllegalArgumentException("Invalid expression"); } - int n = 0; - while (true) { + for (int n = 1; n <= maxValue; n++) { // Replace 'n' with the current value of n, correctly handling numbers before // 'n' - String sanitizedExpression = insertMultiplicationBeforeN(expression, n); + String sanitizedExpression = sanitizeNFunction(expression, n); Double result = evaluator.evaluate(sanitizedExpression); // Check if the result is null or not within bounds - if (result == null || result <= 0 || result.intValue() > maxValue) { - if (n != 0) break; - } else { + if (result == null) + break; + + if (result.intValue() > 0 && result.intValue() <= maxValue) results.add(result.intValue()); - } - n++; } return results; } + private static String sanitizeNFunction(String expression, int nValue) { + String sanitizedExpression = expression.replace(" ", ""); + String multiplyByOpeningRoundBracketPattern = "([0-9n)])\\("; // example: n(n-1), 9(n-1), (n-1)(n-2) + sanitizedExpression = sanitizedExpression.replaceAll(multiplyByOpeningRoundBracketPattern, "$1*("); + + String multiplyByClosingRoundBracketPattern = "\\)([0-9n)])"; // example: (n-1)n, (n-1)9, (n-1)(n-2) + sanitizedExpression = sanitizedExpression.replaceAll(multiplyByClosingRoundBracketPattern, ")*$1"); + + sanitizedExpression = insertMultiplicationBeforeN(sanitizedExpression, nValue); + return sanitizedExpression; + } + private static String insertMultiplicationBeforeN(String expression, int nValue) { // Insert multiplication between a number and 'n' (e.g., "4n" becomes "4*n") String withMultiplication = expression.replaceAll("(\\d)n", "$1*n"); + withMultiplication = formatConsecutiveNsForNFunction(withMultiplication); // Now replace 'n' with its current value return withMultiplication.replace("n", String.valueOf(nValue)); } + private static String formatConsecutiveNsForNFunction(String expression) { + String text = expression; + while (text.matches(".*n{2,}.*")) { + text = text.replaceAll("(? handlePart(String part, int totalPages, int offset) { List partResult = new ArrayList<>(); diff --git a/src/test/java/stirling/software/SPDF/utils/GeneralUtilsTest.java b/src/test/java/stirling/software/SPDF/utils/GeneralUtilsTest.java index be63e8d36..18afcad62 100644 --- a/src/test/java/stirling/software/SPDF/utils/GeneralUtilsTest.java +++ b/src/test/java/stirling/software/SPDF/utils/GeneralUtilsTest.java @@ -52,14 +52,68 @@ public class GeneralUtilsTest { @Test void nFuncAdvanced3() { List result = GeneralUtils.parsePageList(new String[]{"4n+1"}, 9, true); - assertEquals(List.of(1, 5, 9), result, "'All' keyword should return all pages."); + assertEquals(List.of(5, 9), result, "'All' keyword should return all pages."); + } + + @Test + void nFunc_spaces() { + List result = GeneralUtils.parsePageList(new String[]{"n + 1"}, 9, true); + assertEquals(List.of(2, 3, 4, 5, 6, 7, 8, 9), result); + } + + @Test + void nFunc_consecutive_Ns_nnn() { + List result = GeneralUtils.parsePageList(new String[]{"nnn"}, 9, true); + assertEquals(List.of(1, 8), result); + } + + @Test + void nFunc_consecutive_Ns_nn() { + List result = GeneralUtils.parsePageList(new String[]{"nn"}, 9, true); + assertEquals(List.of(1, 4, 9), result); + } + + @Test + void nFunc_opening_closing_round_brackets() { + List result = GeneralUtils.parsePageList(new String[]{"(n-1)(n-2)"}, 9, true); + assertEquals(List.of(2, 6), result); + } + + @Test + void nFunc_opening_round_brackets() { + List result = GeneralUtils.parsePageList(new String[]{"2(n-1)"}, 9, true); + assertEquals(List.of(2, 4, 6, 8), result); + } + + @Test + void nFunc_opening_round_brackets_n() { + List result = GeneralUtils.parsePageList(new String[]{"n(n-1)"}, 9, true); + assertEquals(List.of(2, 6), result); + } + + @Test + void nFunc_closing_round_brackets() { + List result = GeneralUtils.parsePageList(new String[]{"(n-1)2"}, 9, true); + assertEquals(List.of(2, 4, 6, 8), result); + } + + @Test + void nFunc_closing_round_brackets_n() { + List result = GeneralUtils.parsePageList(new String[]{"(n-1)n"}, 9, true); + assertEquals(List.of(2, 6), result); + } + + @Test + void nFunc_function_surrounded_with_brackets() { + List result = GeneralUtils.parsePageList(new String[]{"(n-1)"}, 9, true); + assertEquals(List.of(1, 2, 3, 4, 5, 6, 7, 8), result); } @Test void nFuncAdvanced4() { List result = GeneralUtils.parsePageList(new String[]{"3+2n"}, 9, true); - assertEquals(List.of(3, 5, 7, 9), result, "'All' keyword should return all pages."); + assertEquals(List.of(5, 7, 9), result, "'All' keyword should return all pages."); } @Test @@ -80,7 +134,6 @@ public class GeneralUtilsTest { assertEquals(List.of(1, 2, 3), result, "Range should be parsed correctly."); } - @Test void testParsePageListWithRangeZeroBaseOutput() { List result = GeneralUtils.parsePageList(new String[]{"1-3"}, 5, false);