From c782520853c58b13bebe644ba69ea6aef738cf1a Mon Sep 17 00:00:00 2001 From: Vitalii Ananev Date: Sun, 21 Apr 2024 20:41:27 +0300 Subject: [PATCH 1/9] fix codecov --- .github/workflows/unit-tests.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 9c61d32..1d4fc8b 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -30,7 +30,9 @@ jobs: run: mvn --batch-mode clean test - name: Test Coverage - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4.0.1 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - name: SonarCloud Analyze run: > From bc3de6f73be54e33e678a77e736e13ff26401cd6 Mon Sep 17 00:00:00 2001 From: Vitalii Ananev Date: Fri, 18 Oct 2024 00:41:29 +0300 Subject: [PATCH 2/9] update deps --- pom.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 5cd605b..3d8081f 100644 --- a/pom.xml +++ b/pom.xml @@ -49,8 +49,8 @@ 11 UTF-8 UTF-8 - 1.18.28 - 3.32.0 + 1.18.34 + 3.48.1 @@ -76,19 +76,19 @@ org.junit.jupiter junit-jupiter - 5.9.2 + 5.11.2 test org.mockito mockito-junit-jupiter - 5.2.0 + 5.14.2 test nl.jqno.equalsverifier equalsverifier - 3.14.1 + 3.17.1 test @@ -98,7 +98,7 @@ maven-surefire-plugin - 2.22.2 + 3.5.1 @@ -106,7 +106,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.10.1 + 3.13.0 true true @@ -149,7 +149,7 @@ org.jacoco jacoco-maven-plugin - 0.8.8 + 0.8.12 prepare-agent @@ -169,7 +169,7 @@ org.apache.maven.plugins maven-source-plugin - 3.2.1 + 3.3.1 attach-sources From f4572e78481d0906da64b2ad255265acfebc47c7 Mon Sep 17 00:00:00 2001 From: Vitalii Ananev Date: Fri, 18 Oct 2024 00:41:53 +0300 Subject: [PATCH 3/9] add @PolyNull annotation --- .../spacious_team/table_wrapper/api/TableCell.java | 12 +++++++----- .../spacious_team/table_wrapper/api/TableRow.java | 12 +++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/spacious_team/table_wrapper/api/TableCell.java b/src/main/java/org/spacious_team/table_wrapper/api/TableCell.java index bc7aeb9..0173886 100644 --- a/src/main/java/org/spacious_team/table_wrapper/api/TableCell.java +++ b/src/main/java/org/spacious_team/table_wrapper/api/TableCell.java @@ -19,6 +19,8 @@ package org.spacious_team.table_wrapper.api; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.nullness.qual.PolyNull; + import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDateTime; @@ -125,7 +127,7 @@ default double getDoubleValueOrDefault(double defaultValue) { /** * @return return cell value or defaultValue if the cell is missing or the type does not match the expected */ - default BigDecimal getBigDecimalValueOrDefault(BigDecimal defaultValue) { + default @PolyNull BigDecimal getBigDecimalValueOrDefault(@PolyNull BigDecimal defaultValue) { try { return getBigDecimalValue(); } catch (Exception e) { @@ -136,7 +138,7 @@ default BigDecimal getBigDecimalValueOrDefault(BigDecimal defaultValue) { /** * @return return cell value or defaultValue if the cell is missing or the type does not match the expected */ - default String getStringValueOrDefault(String defaultValue) { + default @PolyNull String getStringValueOrDefault(@PolyNull String defaultValue) { try { return getStringValue(); } catch (Exception e) { @@ -147,7 +149,7 @@ default String getStringValueOrDefault(String defaultValue) { /** * @return return cell value or defaultValue if the cell is missing or the type does not match the expected */ - default Instant getInstantValueOrDefault(Instant defaultValue) { + default @PolyNull Instant getInstantValueOrDefault(@PolyNull Instant defaultValue) { try { return getInstantValue(); } catch (Exception e) { @@ -158,7 +160,7 @@ default Instant getInstantValueOrDefault(Instant defaultValue) { /** * @return return cell value or defaultValue if the cell is missing or the type does not match the expected */ - default LocalDateTime getLocalDateTimeValueOrDefault(LocalDateTime defaultValue) { + default @PolyNull LocalDateTime getLocalDateTimeValueOrDefault(@PolyNull LocalDateTime defaultValue) { try { return getLocalDateTimeValue(); } catch (Exception e) { @@ -169,7 +171,7 @@ default LocalDateTime getLocalDateTimeValueOrDefault(LocalDateTime defaultValue) /** * @return return cell value or defaultValue if the cell is missing or the type does not match the expected */ - default LocalDateTime getLocalDateTimeValueOrDefault(ZoneId zoneId, LocalDateTime defaultValue) { + default @PolyNull LocalDateTime getLocalDateTimeValueOrDefault(ZoneId zoneId, @PolyNull LocalDateTime defaultValue) { try { return getLocalDateTimeValue(zoneId); } catch (Exception e) { diff --git a/src/main/java/org/spacious_team/table_wrapper/api/TableRow.java b/src/main/java/org/spacious_team/table_wrapper/api/TableRow.java index 792ad54..9bd359f 100644 --- a/src/main/java/org/spacious_team/table_wrapper/api/TableRow.java +++ b/src/main/java/org/spacious_team/table_wrapper/api/TableRow.java @@ -19,6 +19,8 @@ package org.spacious_team.table_wrapper.api; import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.nullness.qual.PolyNull; + import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDateTime; @@ -128,7 +130,7 @@ default double getDoubleCellValueOrDefault(TableHeaderColumn column, double defa /** * @return return cell value or defaultValue if the cell is missing or the type does not match the expected */ - default BigDecimal getBigDecimalCellValueOrDefault(TableHeaderColumn column, BigDecimal defaultValue) { + default @PolyNull BigDecimal getBigDecimalCellValueOrDefault(TableHeaderColumn column, @PolyNull BigDecimal defaultValue) { try { return getBigDecimalCellValue(column); } catch (Exception e) { @@ -139,7 +141,7 @@ default BigDecimal getBigDecimalCellValueOrDefault(TableHeaderColumn column, Big /** * @return return cell value or defaultValue if the cell is missing or the type does not match the expected */ - default String getStringCellValueOrDefault(TableHeaderColumn column, String defaultValue) { + default @PolyNull String getStringCellValueOrDefault(TableHeaderColumn column, @PolyNull String defaultValue) { try { return getStringCellValue(column); } catch (Exception e) { @@ -150,7 +152,7 @@ default String getStringCellValueOrDefault(TableHeaderColumn column, String defa /** * @return return cell value or defaultValue if the cell is missing or the type does not match the expected */ - default Instant getInstantCellValueOrDefault(TableHeaderColumn column, Instant defaultValue) { + default @PolyNull Instant getInstantCellValueOrDefault(TableHeaderColumn column, @PolyNull Instant defaultValue) { try { return getInstantCellValue(column); } catch (Exception e) { @@ -161,7 +163,7 @@ default Instant getInstantCellValueOrDefault(TableHeaderColumn column, Instant d /** * @return return cell value or defaultValue if the cell is missing or the type does not match the expected */ - default LocalDateTime getLocalDateTimeCellValueOrDefault(TableHeaderColumn column, LocalDateTime defaultValue) { + default @PolyNull LocalDateTime getLocalDateTimeCellValueOrDefault(TableHeaderColumn column, @PolyNull LocalDateTime defaultValue) { try { return getLocalDateTimeCellValue(column); } catch (Exception e) { @@ -172,7 +174,7 @@ default LocalDateTime getLocalDateTimeCellValueOrDefault(TableHeaderColumn colum /** * @return return cell value or defaultValue if the cell is missing or the type does not match the expected */ - default LocalDateTime getLocalDateTimeCellValueOrDefault(TableHeaderColumn column, ZoneId zoneId, LocalDateTime defaultValue) { + default @PolyNull LocalDateTime getLocalDateTimeCellValueOrDefault(TableHeaderColumn column, ZoneId zoneId, @PolyNull LocalDateTime defaultValue) { try { return getLocalDateTimeCellValue(column, zoneId); } catch (Exception e) { From f4549dd078313c71f027f1c0672f4aafa65d0592 Mon Sep 17 00:00:00 2001 From: Vitalii Ananev Date: Sun, 20 Oct 2024 22:42:40 +0300 Subject: [PATCH 4/9] do not pollute heap by string comparing --- .../table_wrapper/api/ReportPage.java | 10 +- .../table_wrapper/api/ReportPageHelper.java | 52 ------- .../api/StringPrefixPredicate.java | 87 ++++++++++++ .../api/ReportPageHelperTest.java | 58 -------- .../table_wrapper/api/ReportPageTest.java | 6 +- .../api/StringPrefixPredicateTest.java | 131 ++++++++++++++++++ 6 files changed, 226 insertions(+), 118 deletions(-) delete mode 100644 src/main/java/org/spacious_team/table_wrapper/api/ReportPageHelper.java create mode 100644 src/main/java/org/spacious_team/table_wrapper/api/StringPrefixPredicate.java delete mode 100644 src/test/java/org/spacious_team/table_wrapper/api/ReportPageHelperTest.java create mode 100644 src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java diff --git a/src/main/java/org/spacious_team/table_wrapper/api/ReportPage.java b/src/main/java/org/spacious_team/table_wrapper/api/ReportPage.java index 8964ee4..f407a82 100644 --- a/src/main/java/org/spacious_team/table_wrapper/api/ReportPage.java +++ b/src/main/java/org/spacious_team/table_wrapper/api/ReportPage.java @@ -23,7 +23,7 @@ import java.util.function.Predicate; import static java.util.Objects.requireNonNull; -import static org.spacious_team.table_wrapper.api.ReportPageHelper.getCellStringValueIgnoreCasePrefixPredicate; +import static org.spacious_team.table_wrapper.api.StringPrefixPredicate.ignoreCaseStringPrefixPredicateOnObject; @SuppressWarnings({"unused", "UnusedReturnValue"}) public interface ReportPage { @@ -157,7 +157,7 @@ default TableCellAddress findByPrefix(String prefix, int startRow, int endRow) { default TableCellAddress findByPrefix(@Nullable String prefix, int startRow, int endRow, int startColumn, int endColumn) { return (prefix == null || prefix.isEmpty()) ? TableCellAddress.NOT_FOUND : - find(startRow, endRow, startColumn, endColumn, getCellStringValueIgnoreCasePrefixPredicate(prefix)); + find(startRow, endRow, startColumn, endColumn, ignoreCaseStringPrefixPredicateOnObject(prefix)); } /** @@ -208,9 +208,9 @@ default TableCellRange getTableCellRange(@Nullable String firstRowPrefix, return TableCellRange.EMPTY_RANGE; } return getTableCellRange( - getCellStringValueIgnoreCasePrefixPredicate(firstRowPrefix), + ignoreCaseStringPrefixPredicateOnObject(firstRowPrefix), headersRowCount, - getCellStringValueIgnoreCasePrefixPredicate(lastRowPrefix)); + ignoreCaseStringPrefixPredicateOnObject(lastRowPrefix)); } /** @@ -250,7 +250,7 @@ default TableCellRange getTableCellRange(@Nullable String firstRowPrefix, int he return TableCellRange.EMPTY_RANGE; } return getTableCellRange( - getCellStringValueIgnoreCasePrefixPredicate(firstRowPrefix), + ignoreCaseStringPrefixPredicateOnObject(firstRowPrefix), headersRowCount); } diff --git a/src/main/java/org/spacious_team/table_wrapper/api/ReportPageHelper.java b/src/main/java/org/spacious_team/table_wrapper/api/ReportPageHelper.java deleted file mode 100644 index 3fdcd65..0000000 --- a/src/main/java/org/spacious_team/table_wrapper/api/ReportPageHelper.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Table Wrapper API - * Copyright (C) 2022 Spacious Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.spacious_team.table_wrapper.api; - -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.ToString; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.function.Predicate; - -import static lombok.AccessLevel.PRIVATE; - -@RequiredArgsConstructor(access = PRIVATE) -final class ReportPageHelper { - - static Predicate<@Nullable Object> getCellStringValueIgnoreCasePrefixPredicate(String prefix) { - return new StringIgnoreCasePrefixPredicate(prefix); - } - - @ToString - @EqualsAndHashCode - static final class StringIgnoreCasePrefixPredicate implements Predicate<@Nullable Object> { - private final String lowercasePrefix; - - private StringIgnoreCasePrefixPredicate(String prefix) { - this.lowercasePrefix = prefix.trim().toLowerCase(); - } - - @Override - public boolean test(@Nullable Object cell) { - return (cell instanceof String) && - ((String) cell).trim().toLowerCase().startsWith(lowercasePrefix); - } - } -} diff --git a/src/main/java/org/spacious_team/table_wrapper/api/StringPrefixPredicate.java b/src/main/java/org/spacious_team/table_wrapper/api/StringPrefixPredicate.java new file mode 100644 index 0000000..5775316 --- /dev/null +++ b/src/main/java/org/spacious_team/table_wrapper/api/StringPrefixPredicate.java @@ -0,0 +1,87 @@ +/* + * Table Wrapper API + * Copyright (C) 2022 Spacious Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.spacious_team.table_wrapper.api; + +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.ToString; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.function.Predicate; + +import static java.lang.Character.isWhitespace; +import static lombok.AccessLevel.PRIVATE; + +@NoArgsConstructor(access = PRIVATE) +public final class StringPrefixPredicate { + + public static Predicate<@Nullable Object> ignoreCaseStringPrefixPredicateOnObject(CharSequence prefix) { + Predicate predicate = ignoreCaseStringPrefixPredicate(prefix); + return PredicateOnObjectWrapper.of(predicate); + } + + public static Predicate ignoreCaseStringPrefixPredicate(CharSequence prefix) { + return new IgnoreCaseStringPrefixPredicate(prefix); + } + + + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor(staticName = "of", access = PRIVATE) + static final class PredicateOnObjectWrapper implements Predicate<@Nullable Object> { + private final Predicate predicate; + + @Override + public boolean test(@Nullable Object o) { + return (o instanceof CharSequence) && predicate.test((CharSequence) o); + } + } + + + @ToString + @EqualsAndHashCode + static final class IgnoreCaseStringPrefixPredicate implements Predicate { + private final String prefix; + + private IgnoreCaseStringPrefixPredicate(CharSequence prefix) { + this.prefix = prefix.toString().strip(); + } + + @Override + public boolean test(CharSequence cs) { + int nonWhitespaceIndex = getIndexOfNonWhitespace(cs); + if (nonWhitespaceIndex == -1) { + return false; + } + String string = cs.toString(); + return string.regionMatches(true, nonWhitespaceIndex, prefix, 0, prefix.length()); + } + + private static int getIndexOfNonWhitespace(CharSequence cs) { + for (int i = 0, n = cs.length(); i < n; i++) { + char c = cs.charAt(i); + if (!isWhitespace(c)) { + return i; + } + } + return -1; + } + } +} diff --git a/src/test/java/org/spacious_team/table_wrapper/api/ReportPageHelperTest.java b/src/test/java/org/spacious_team/table_wrapper/api/ReportPageHelperTest.java deleted file mode 100644 index 8e36ac1..0000000 --- a/src/test/java/org/spacious_team/table_wrapper/api/ReportPageHelperTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Table Wrapper API - * Copyright (C) 2022 Spacious Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package org.spacious_team.table_wrapper.api; - -import nl.jqno.equalsverifier.EqualsVerifier; -import org.junit.jupiter.api.Test; -import org.spacious_team.table_wrapper.api.ReportPageHelper.StringIgnoreCasePrefixPredicate; - -import static org.junit.jupiter.api.Assertions.*; -import static org.spacious_team.table_wrapper.api.ReportPageHelper.getCellStringValueIgnoreCasePrefixPredicate; - -class ReportPageHelperTest { - - @Test - void test() { - assertTrue(getCellStringValueIgnoreCasePrefixPredicate("First").test("First second")); - assertTrue(getCellStringValueIgnoreCasePrefixPredicate("First").test("first second")); - assertTrue(getCellStringValueIgnoreCasePrefixPredicate("first").test("First second")); - assertTrue(getCellStringValueIgnoreCasePrefixPredicate("first").test("first second")); - assertTrue(getCellStringValueIgnoreCasePrefixPredicate("FIRST").test("first second")); - assertFalse(getCellStringValueIgnoreCasePrefixPredicate("First").test("One two")); - //noinspection ConstantConditions - assertFalse(getCellStringValueIgnoreCasePrefixPredicate("First").test(null)); - assertFalse(getCellStringValueIgnoreCasePrefixPredicate("First").test(1)); - assertFalse(getCellStringValueIgnoreCasePrefixPredicate("First").test(1.1)); - assertFalse(getCellStringValueIgnoreCasePrefixPredicate("First").test(new Object())); - } - - @Test - void testEqualsAndHashCode() { - EqualsVerifier - .forClass(StringIgnoreCasePrefixPredicate.class) - .verify(); - } - - @Test - void testToString() { - assertEquals( - "ReportPageHelper.StringIgnoreCasePrefixPredicate(lowercasePrefix=first)", - getCellStringValueIgnoreCasePrefixPredicate("First").toString()); - } -} \ No newline at end of file diff --git a/src/test/java/org/spacious_team/table_wrapper/api/ReportPageTest.java b/src/test/java/org/spacious_team/table_wrapper/api/ReportPageTest.java index c850360..c040091 100644 --- a/src/test/java/org/spacious_team/table_wrapper/api/ReportPageTest.java +++ b/src/test/java/org/spacious_team/table_wrapper/api/ReportPageTest.java @@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; -import static org.spacious_team.table_wrapper.api.ReportPageHelper.getCellStringValueIgnoreCasePrefixPredicate; +import static org.spacious_team.table_wrapper.api.StringPrefixPredicate.ignoreCaseStringPrefixPredicateOnObject; import static org.spacious_team.table_wrapper.api.ReportPageRowHelper.cell; import static org.spacious_team.table_wrapper.api.ReportPageRowHelper.getRow; import static org.spacious_team.table_wrapper.api.TableCellAddress.NOT_FOUND; @@ -50,8 +50,8 @@ class ReportPageTest { TableCellAddress address2 = TableCellAddress.of(3, 4); String prefix1 = "A"; String prefix2 = "B"; - Predicate predicate1 = getCellStringValueIgnoreCasePrefixPredicate(prefix1); - Predicate predicate2 = getCellStringValueIgnoreCasePrefixPredicate(prefix2); + Predicate predicate1 = ignoreCaseStringPrefixPredicateOnObject(prefix1); + Predicate predicate2 = ignoreCaseStringPrefixPredicateOnObject(prefix2); String tableName = "table name"; String headerRow = "header row"; String tableFooterString = "footer"; diff --git a/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java b/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java new file mode 100644 index 0000000..912bfb6 --- /dev/null +++ b/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java @@ -0,0 +1,131 @@ +/* + * Table Wrapper API + * Copyright (C) 2022 Spacious Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.spacious_team.table_wrapper.api; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.spacious_team.table_wrapper.api.StringPrefixPredicate.IgnoreCaseStringPrefixPredicate; +import org.spacious_team.table_wrapper.api.StringPrefixPredicate.PredicateOnObjectWrapper; + +import static org.junit.jupiter.api.Assertions.*; +import static org.spacious_team.table_wrapper.api.StringPrefixPredicate.ignoreCaseStringPrefixPredicate; +import static org.spacious_team.table_wrapper.api.StringPrefixPredicate.ignoreCaseStringPrefixPredicateOnObject; + +class StringPrefixPredicateTest { + + static Object[][] prefixAndMatchingString() { + return new Object[][]{ + {"First", "First second"}, + {"First", "first second"}, + {"first", "First second"}, + {"first", "first second"}, + {"FIRST", "first second"}, + {" FIRST", "first second"}, + {" FIRST", " first second"}, + {"\tfirst\n", "\n first \tsecond"}, + {"first", "\t \nfirst\n\tsecond"}, + {"\nfirst\n", "\t \n\rfirst\r\n\tsecond"}, + }; + } + + static Object[][] prefixAndNotMatchingSting() { + return new Object[][]{ + {"First", "One two"}, + {"first", "fir st two"}, + {"first", "zero first"}, + {"first", "zero first second"}, + }; + } + + static Object[][] prefixAndObject() { + return new Object[][]{ + {"First", 1}, + {"First", 1.1}, + {"First", new Object()}, + }; + } + + // ignoreCaseStringPrefixPredicateOnObject(CharSequence) tests + + @ParameterizedTest + @MethodSource("prefixAndMatchingString") + void ignoreCaseStringPrefixPredicateOnObject_matched(String prefix, String testingString) { + assertTrue(ignoreCaseStringPrefixPredicateOnObject(prefix).test(testingString)); + } + + @ParameterizedTest + @MethodSource("prefixAndNotMatchingSting") + void ignoreCaseStringPrefixPredicateOnObject_notMatchedString(String prefix, String testingString) { + assertFalse(ignoreCaseStringPrefixPredicateOnObject(prefix).test(testingString)); + } + + @ParameterizedTest + @MethodSource("prefixAndObject") + void ignoreCaseStringPrefixPredicateOnObject_object(String prefix, Object testingObject) { + assertFalse(ignoreCaseStringPrefixPredicateOnObject(prefix).test(testingObject)); + } + + @Test + void ignoreCaseStringPrefixPredicateOnObject_null() { + assertFalse(ignoreCaseStringPrefixPredicateOnObject("any").test(null)); + } + + + // ignoreCaseStringPrefixPredicate(CharSequence) tests + + @ParameterizedTest + @MethodSource("prefixAndMatchingString") + void ignoreCaseStringPrefixPredicate_matched(String prefix, String testingString) { + assertTrue(ignoreCaseStringPrefixPredicate(prefix).test(testingString)); + } + + @ParameterizedTest + @MethodSource("prefixAndNotMatchingSting") + void ignoreCaseStringPrefixPredicate_notMatchedString(String prefix, String testingString) { + assertFalse(ignoreCaseStringPrefixPredicate(prefix).test(testingString)); + } + + @Test + @SuppressWarnings("DataFlowIssue") + void ignoreCaseStringPrefixPredicate_null() { + assertThrows(NullPointerException.class, () -> ignoreCaseStringPrefixPredicate("any").test(null)); + } + + @Test + void testEqualsAndHashCode() { + EqualsVerifier + .forClass(IgnoreCaseStringPrefixPredicate.class) + .verify(); + EqualsVerifier + .forClass(PredicateOnObjectWrapper.class) + .verify(); + } + + @Test + void testToString() { + assertEquals( + "StringPrefixPredicate.PredicateOnObjectWrapper(predicate=StringPrefixPredicate.IgnoreCaseStringPrefixPredicate(prefix=First))", + ignoreCaseStringPrefixPredicateOnObject("First").toString()); + assertEquals( + "StringPrefixPredicate.IgnoreCaseStringPrefixPredicate(prefix=First)", + ignoreCaseStringPrefixPredicate("First").toString()); + } +} \ No newline at end of file From 2c4d161426e396b5178c93642cc1f9510ca34f4b Mon Sep 17 00:00:00 2001 From: Vitalii Ananev Date: Sun, 20 Oct 2024 23:39:06 +0300 Subject: [PATCH 5/9] parameterize class --- .../table_wrapper/api/StringPrefixPredicate.java | 8 ++++---- .../table_wrapper/api/StringPrefixPredicateTest.java | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/spacious_team/table_wrapper/api/StringPrefixPredicate.java b/src/main/java/org/spacious_team/table_wrapper/api/StringPrefixPredicate.java index 5775316..de2efd4 100644 --- a/src/main/java/org/spacious_team/table_wrapper/api/StringPrefixPredicate.java +++ b/src/main/java/org/spacious_team/table_wrapper/api/StringPrefixPredicate.java @@ -37,8 +37,8 @@ public final class StringPrefixPredicate { return PredicateOnObjectWrapper.of(predicate); } - public static Predicate ignoreCaseStringPrefixPredicate(CharSequence prefix) { - return new IgnoreCaseStringPrefixPredicate(prefix); + public static Predicate ignoreCaseStringPrefixPredicate(CharSequence prefix) { + return new IgnoreCaseStringPrefixPredicate<>(prefix); } @@ -57,7 +57,7 @@ public boolean test(@Nullable Object o) { @ToString @EqualsAndHashCode - static final class IgnoreCaseStringPrefixPredicate implements Predicate { + static final class IgnoreCaseStringPrefixPredicate implements Predicate { private final String prefix; private IgnoreCaseStringPrefixPredicate(CharSequence prefix) { @@ -65,7 +65,7 @@ private IgnoreCaseStringPrefixPredicate(CharSequence prefix) { } @Override - public boolean test(CharSequence cs) { + public boolean test(T cs) { int nonWhitespaceIndex = getIndexOfNonWhitespace(cs); if (nonWhitespaceIndex == -1) { return false; diff --git a/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java b/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java index 912bfb6..dd7bfa9 100644 --- a/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java +++ b/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java @@ -104,7 +104,6 @@ void ignoreCaseStringPrefixPredicate_notMatchedString(String prefix, String test } @Test - @SuppressWarnings("DataFlowIssue") void ignoreCaseStringPrefixPredicate_null() { assertThrows(NullPointerException.class, () -> ignoreCaseStringPrefixPredicate("any").test(null)); } From f2341ce2649da99de876371409cf17007683dc14 Mon Sep 17 00:00:00 2001 From: Vitalii Ananev Date: Mon, 21 Oct 2024 22:39:48 +0300 Subject: [PATCH 6/9] add tests --- .../api/StringPrefixPredicateTest.java | 1 + .../table_wrapper/api/TableCellTest.java | 28 +++++++++++++++++- .../table_wrapper/api/TableRowTest.java | 29 ++++++++++++++----- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java b/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java index dd7bfa9..c5c07c1 100644 --- a/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java +++ b/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java @@ -48,6 +48,7 @@ static Object[][] prefixAndMatchingString() { static Object[][] prefixAndNotMatchingSting() { return new Object[][]{ + {"First", " \n\r\n\t"}, {"First", "One two"}, {"first", "fir st two"}, {"first", "zero first"}, diff --git a/src/test/java/org/spacious_team/table_wrapper/api/TableCellTest.java b/src/test/java/org/spacious_team/table_wrapper/api/TableCellTest.java index b617924..b0302b9 100644 --- a/src/test/java/org/spacious_team/table_wrapper/api/TableCellTest.java +++ b/src/test/java/org/spacious_team/table_wrapper/api/TableCellTest.java @@ -27,6 +27,7 @@ import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDateTime; +import java.time.ZoneOffset; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; @@ -49,7 +50,8 @@ void getValueOrDefaultExceptionally() { Object expectedDefault = new Object(); doThrow(RuntimeException.class).when(cell).getValue(); - @Nullable Object result = cell.getValueOrDefault(expectedDefault); + @SuppressWarnings("DataFlowIssue") @Nullable + Object result = cell.getValueOrDefault(expectedDefault); assertSame(expectedDefault, result); verify(cell).getValue(); @@ -203,4 +205,28 @@ void getLocalDateTimeValueOrDefaultExceptionally() { assertSame(expectedDefault, result); verify(cell).getLocalDateTimeValue(); } + + @Test + void getLocalDateTimeValueOnZoneIdOrDefault() { + ZoneOffset expectedZone = ZoneOffset.UTC; + LocalDateTime expected = LocalDateTime.now(); + doReturn(expected).when(cell).getLocalDateTimeValue(any()); + + LocalDateTime result = cell.getLocalDateTimeValueOrDefault(expectedZone, LocalDateTime.MIN); + + assertEquals(expected, result); + verify(cell).getLocalDateTimeValue(expectedZone); + } + + @Test + void getZoneIdLocalDateTimeValueOnZoneIdOrDefaultExceptionally() { + ZoneOffset expectedZone = ZoneOffset.UTC; + LocalDateTime expectedDefault = LocalDateTime.now(); + doThrow(RuntimeException.class).when(cell).getLocalDateTimeValue(any()); + + LocalDateTime result = cell.getLocalDateTimeValueOrDefault(expectedZone, expectedDefault); + + assertSame(expectedDefault, result); + verify(cell).getLocalDateTimeValue(expectedZone); + } } \ No newline at end of file diff --git a/src/test/java/org/spacious_team/table_wrapper/api/TableRowTest.java b/src/test/java/org/spacious_team/table_wrapper/api/TableRowTest.java index 292d20a..29e9172 100644 --- a/src/test/java/org/spacious_team/table_wrapper/api/TableRowTest.java +++ b/src/test/java/org/spacious_team/table_wrapper/api/TableRowTest.java @@ -27,6 +27,7 @@ import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDateTime; +import java.time.ZoneOffset; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertSame; @@ -124,28 +125,42 @@ void getStringCellValueOrDefaultThrowable() { @Test void getInstantCellValueOrDefault() { Instant expectedInstant = Instant.now(); - when(row.getInstantCellValue(any())).thenThrow(RuntimeException.class); - assertSame(expectedInstant, row.getInstantCellValueOrDefault(column, expectedInstant)); + when(row.getInstantCellValue(any())).thenReturn(expectedInstant); + assertSame(expectedInstant, row.getInstantCellValueOrDefault(column, Instant.MIN)); } @Test void getInstantCellValueOrDefaultThrowable() { Instant expectedInstant = Instant.now(); - when(row.getInstantCellValue(any())).thenReturn(expectedInstant); - assertSame(expectedInstant, row.getInstantCellValueOrDefault(column, Instant.MIN)); + when(row.getInstantCellValue(any())).thenThrow(RuntimeException.class); + assertSame(expectedInstant, row.getInstantCellValueOrDefault(column, expectedInstant)); } @Test void getLocalDateTimeCellValueOrDefault() { + LocalDateTime expectedLocalDateTime = LocalDateTime.now(); + when(row.getLocalDateTimeCellValue(any())).thenReturn(expectedLocalDateTime); + assertSame(expectedLocalDateTime, row.getLocalDateTimeCellValueOrDefault(column, LocalDateTime.MIN)); + } + + @Test + void getLocalDateTimeCellValueOrDefaultThrowable() { LocalDateTime expectedLocalDateTime = LocalDateTime.now(); when(row.getLocalDateTimeCellValue(any())).thenThrow(RuntimeException.class); assertSame(expectedLocalDateTime, row.getLocalDateTimeCellValueOrDefault(column, expectedLocalDateTime)); } @Test - void getLocalDateTimeCellValueOrDefaultThrowable() { + void getLocalDateTimeCellValueOnZoneIdOrDefault() { LocalDateTime expectedLocalDateTime = LocalDateTime.now(); - when(row.getLocalDateTimeCellValue(any())).thenReturn(expectedLocalDateTime); - assertSame(expectedLocalDateTime, row.getLocalDateTimeCellValueOrDefault(column, LocalDateTime.MIN)); + when(row.getLocalDateTimeCellValue(any(), any())).thenReturn(expectedLocalDateTime); + assertSame(expectedLocalDateTime, row.getLocalDateTimeCellValueOrDefault(column, ZoneOffset.UTC, LocalDateTime.MIN)); + } + + @Test + void getLocalDateTimeCellValueOnZoneIdOrDefaultThrowable() { + LocalDateTime expectedLocalDateTime = LocalDateTime.now(); + when(row.getLocalDateTimeCellValue(any(), any())).thenThrow(RuntimeException.class); + assertSame(expectedLocalDateTime, row.getLocalDateTimeCellValueOrDefault(column, ZoneOffset.UTC, expectedLocalDateTime)); } } \ No newline at end of file From dc4c82ac7f1cba436bdd77e949e5cda2de6e35ce Mon Sep 17 00:00:00 2001 From: Vitalii Ananev Date: Fri, 25 Apr 2025 23:53:39 +0300 Subject: [PATCH 7/9] update dep versions --- pom.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 3d8081f..d6cf3f7 100644 --- a/pom.xml +++ b/pom.xml @@ -49,8 +49,8 @@ 11 UTF-8 UTF-8 - 1.18.34 - 3.48.1 + 1.18.38 + 3.49.2 @@ -76,19 +76,19 @@ org.junit.jupiter junit-jupiter - 5.11.2 + 5.12.2 test org.mockito mockito-junit-jupiter - 5.14.2 + 5.17.0 test nl.jqno.equalsverifier equalsverifier - 3.17.1 + 3.19.3 test @@ -98,7 +98,7 @@ maven-surefire-plugin - 3.5.1 + 3.5.3 @@ -106,7 +106,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.13.0 + 3.14.0 true true @@ -149,7 +149,7 @@ org.jacoco jacoco-maven-plugin - 0.8.12 + 0.8.13 prepare-agent From 857cb29a08f6199f36373f2290f0fbc960b3f5df Mon Sep 17 00:00:00 2001 From: Vitalii Ananev Date: Sat, 26 Apr 2025 00:30:52 +0300 Subject: [PATCH 8/9] fix npe check test --- .github/workflows/unit-tests.yml | 2 +- .../table_wrapper/api/StringPrefixPredicateTest.java | 6 +++++- .../org/spacious_team/table_wrapper/api/TableCellTest.java | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 1d4fc8b..53aabcc 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -30,7 +30,7 @@ jobs: run: mvn --batch-mode clean test - name: Test Coverage - uses: codecov/codecov-action@v4.0.1 + uses: codecov/codecov-action@v5 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java b/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java index c5c07c1..a0ae803 100644 --- a/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java +++ b/src/test/java/org/spacious_team/table_wrapper/api/StringPrefixPredicateTest.java @@ -25,6 +25,8 @@ import org.spacious_team.table_wrapper.api.StringPrefixPredicate.IgnoreCaseStringPrefixPredicate; import org.spacious_team.table_wrapper.api.StringPrefixPredicate.PredicateOnObjectWrapper; +import java.util.function.Predicate; + import static org.junit.jupiter.api.Assertions.*; import static org.spacious_team.table_wrapper.api.StringPrefixPredicate.ignoreCaseStringPrefixPredicate; import static org.spacious_team.table_wrapper.api.StringPrefixPredicate.ignoreCaseStringPrefixPredicateOnObject; @@ -105,8 +107,10 @@ void ignoreCaseStringPrefixPredicate_notMatchedString(String prefix, String test } @Test + @SuppressWarnings("DataFlowIssue") void ignoreCaseStringPrefixPredicate_null() { - assertThrows(NullPointerException.class, () -> ignoreCaseStringPrefixPredicate("any").test(null)); + Predicate predicate = ignoreCaseStringPrefixPredicate("any"); + assertThrows(NullPointerException.class, () -> predicate.test(null)); } @Test diff --git a/src/test/java/org/spacious_team/table_wrapper/api/TableCellTest.java b/src/test/java/org/spacious_team/table_wrapper/api/TableCellTest.java index b0302b9..109cef6 100644 --- a/src/test/java/org/spacious_team/table_wrapper/api/TableCellTest.java +++ b/src/test/java/org/spacious_team/table_wrapper/api/TableCellTest.java @@ -50,8 +50,8 @@ void getValueOrDefaultExceptionally() { Object expectedDefault = new Object(); doThrow(RuntimeException.class).when(cell).getValue(); - @SuppressWarnings("DataFlowIssue") @Nullable - Object result = cell.getValueOrDefault(expectedDefault); + @SuppressWarnings("DataFlowIssue") + @Nullable Object result = cell.getValueOrDefault(expectedDefault); assertSame(expectedDefault, result); verify(cell).getValue(); From a322204718afbc02fb1e8ce87e41ad091837d47e Mon Sep 17 00:00:00 2001 From: Vitalii Ananev Date: Sat, 26 Apr 2025 00:38:38 +0300 Subject: [PATCH 9/9] version 2025.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d6cf3f7..d25cd22 100644 --- a/pom.xml +++ b/pom.xml @@ -24,7 +24,7 @@ org.spacious-team table-wrapper-api - 2023.1 + 2025.1 jar Table Wrapper API