From f4fe97b93cb166da459d1301f4d11f0a99d6635c Mon Sep 17 00:00:00 2001 From: eetian <57387212+eetian@users.noreply.github.com> Date: Mon, 16 Mar 2020 22:27:36 -0700 Subject: [PATCH] Fix warning display issue for entering a title made of two words (#6054) --- CHANGELOG.md | 1 + .../jabref/logic/integrity/TitleChecker.java | 28 ++++--- .../logic/integrity/IntegrityCheckTest.java | 22 ++++++ .../logic/integrity/TitleCheckerTest.java | 79 +++++++++++++++++++ 4 files changed, 119 insertions(+), 11 deletions(-) create mode 100644 src/test/java/org/jabref/logic/integrity/TitleCheckerTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 89470a03de6..86642cc2bf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We fixed an issue where the group and the link column were not updated after changing the entry in the main table. [#5985](https://github.com/JabRef/jabref/issues/5985) - We fixed an issue where reordering the groups was not possible after inserting an article. [#6008](https://github.com/JabRef/jabref/issues/6008) - We fixed an issue where citation styles except the default "Preview" could not be used. [#56220](https://github.com/JabRef/jabref/issues/5622) +- We fixed an issue where a warning was displayed when the title content is made up of two sentences. [#5832](https://github.com/JabRef/jabref/issues/5832) - We fixed an issue where an exception was thrown when adding a save action without a selected formatter in the library properties [#6069](https://github.com/JabRef/jabref/issues/6069) ### Removed diff --git a/src/main/java/org/jabref/logic/integrity/TitleChecker.java b/src/main/java/org/jabref/logic/integrity/TitleChecker.java index c2725949d24..43c77df59bc 100644 --- a/src/main/java/org/jabref/logic/integrity/TitleChecker.java +++ b/src/main/java/org/jabref/logic/integrity/TitleChecker.java @@ -12,6 +12,7 @@ public class TitleChecker implements ValueChecker { private static final Pattern INSIDE_CURLY_BRAKETS = Pattern.compile("\\{[^}\\{]*\\}"); + private static final Pattern DELIMITERS = Pattern.compile("\\.|\\!|\\?|\\;|\\:"); private static final Predicate HAS_CAPITAL_LETTERS = Pattern.compile("[\\p{Lu}\\p{Lt}]").asPredicate(); private final BibDatabaseContext databaseContext; @@ -22,10 +23,13 @@ public TitleChecker(BibDatabaseContext databaseContext) { /** * Algorithm: - * - remove trailing whitespaces - * - ignore first letter as this can always be written in caps * - remove everything that is in brackets - * - check if at least one capital letter is in the title + * - split the title into sub titles based on the delimiters + * (defined in the local variable DELIMITERS, currently . ! ? ; :) + * - for each sub title: + * - remove trailing whitespaces + * - ignore first letter as this can always be written in caps + * - check if at least one capital letter is in the sub title */ @Override public Optional checkValue(String value) { @@ -37,9 +41,7 @@ public Optional checkValue(String value) { return Optional.empty(); } - String valueTrimmed = value.trim(); - String valueIgnoringFirstLetter = valueTrimmed.startsWith("{") ? valueTrimmed : valueTrimmed.substring(1); - String valueOnlySpacesWithinCurlyBraces = valueIgnoringFirstLetter; + String valueOnlySpacesWithinCurlyBraces = value; while (true) { Matcher matcher = INSIDE_CURLY_BRAKETS.matcher(valueOnlySpacesWithinCurlyBraces); if (!matcher.find()) { @@ -48,11 +50,15 @@ public Optional checkValue(String value) { valueOnlySpacesWithinCurlyBraces = matcher.replaceAll(""); } - boolean hasCapitalLettersThatBibtexWillConvertToSmallerOnes = HAS_CAPITAL_LETTERS - .test(valueOnlySpacesWithinCurlyBraces); - - if (hasCapitalLettersThatBibtexWillConvertToSmallerOnes) { - return Optional.of(Localization.lang("capital letters are not masked using curly brackets {}")); + String[] splitTitle = DELIMITERS.split(valueOnlySpacesWithinCurlyBraces); + for (String subTitle : splitTitle) { + subTitle = subTitle.trim(); + if (!subTitle.isEmpty()) { + subTitle = subTitle.substring(1); + if (HAS_CAPITAL_LETTERS.test(subTitle)) { + return Optional.of(Localization.lang("capital letters are not masked using curly brackets {}")); + } + } } return Optional.empty(); diff --git a/src/test/java/org/jabref/logic/integrity/IntegrityCheckTest.java b/src/test/java/org/jabref/logic/integrity/IntegrityCheckTest.java index 2e096753fed..6f5639e9c13 100644 --- a/src/test/java/org/jabref/logic/integrity/IntegrityCheckTest.java +++ b/src/test/java/org/jabref/logic/integrity/IntegrityCheckTest.java @@ -186,6 +186,17 @@ void testTitleChecks() { assertCorrect(withMode(createContext(StandardField.TITLE, "This is a {Title}"), BibDatabaseMode.BIBTEX)); assertCorrect(withMode(createContext(StandardField.TITLE, "{C}urrent {C}hronicle"), BibDatabaseMode.BIBTEX)); assertCorrect(withMode(createContext(StandardField.TITLE, "{A Model-Driven Approach for Monitoring {ebBP} BusinessTransactions}"), BibDatabaseMode.BIBTEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is a sub title 1: This is a sub title 2"), BibDatabaseMode.BIBTEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is a sub title 1: this is a sub title 2"), BibDatabaseMode.BIBTEX)); + assertWrong(withMode(createContext(StandardField.TITLE, "This is a sub title 1: This is A sub title 2"), BibDatabaseMode.BIBTEX)); + assertWrong(withMode(createContext(StandardField.TITLE, "This is a sub title 1: this is A sub title 2"), BibDatabaseMode.BIBTEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is a sub title 1: This is {A} sub title 2"), BibDatabaseMode.BIBTEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is a sub title 1: this is {A} sub title 2"), BibDatabaseMode.BIBTEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is a sub title 1...This is a sub title 2"), BibDatabaseMode.BIBTEX)); + assertWrong(withMode(createContext(StandardField.TITLE, "This is a sub title 1... this is a sub Title 2"), BibDatabaseMode.BIBTEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is; A sub title 1.... This is a sub title 2"), BibDatabaseMode.BIBTEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This!is!!A!Title??"), BibDatabaseMode.BIBTEX)); + assertWrong(withMode(createContext(StandardField.TITLE, "This!is!!A!TitlE??"), BibDatabaseMode.BIBTEX)); assertCorrect(withMode(createContext(StandardField.TITLE, "This is a title"), BibDatabaseMode.BIBLATEX)); assertCorrect(withMode(createContext(StandardField.TITLE, "This is a Title"), BibDatabaseMode.BIBLATEX)); @@ -194,6 +205,17 @@ void testTitleChecks() { assertCorrect(withMode(createContext(StandardField.TITLE, "This is a {Title}"), BibDatabaseMode.BIBLATEX)); assertCorrect(withMode(createContext(StandardField.TITLE, "{C}urrent {C}hronicle"), BibDatabaseMode.BIBLATEX)); assertCorrect(withMode(createContext(StandardField.TITLE, "{A Model-Driven Approach for Monitoring {ebBP} BusinessTransactions}"), BibDatabaseMode.BIBLATEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is a sub title 1: This is a sub title 2"), BibDatabaseMode.BIBLATEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is a sub title 1: this is a sub title 2"), BibDatabaseMode.BIBLATEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is a sub title 1: This is A sub title 2"), BibDatabaseMode.BIBLATEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is a sub title 1: this is A sub title 2"), BibDatabaseMode.BIBLATEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is a sub title 1: This is {A} sub title 2"), BibDatabaseMode.BIBLATEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is a sub title 1: this is {A} sub title 2"), BibDatabaseMode.BIBLATEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is a sub title 1...This is a sub title 2"), BibDatabaseMode.BIBLATEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is a sub title 1... this is a sub Title 2"), BibDatabaseMode.BIBLATEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This is; A sub title 1.... This is a sub title 2"), BibDatabaseMode.BIBLATEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This!is!!A!Title??"), BibDatabaseMode.BIBLATEX)); + assertCorrect(withMode(createContext(StandardField.TITLE, "This!is!!A!TitlE??"), BibDatabaseMode.BIBLATEX)); } @Test diff --git a/src/test/java/org/jabref/logic/integrity/TitleCheckerTest.java b/src/test/java/org/jabref/logic/integrity/TitleCheckerTest.java new file mode 100644 index 00000000000..930f1598129 --- /dev/null +++ b/src/test/java/org/jabref/logic/integrity/TitleCheckerTest.java @@ -0,0 +1,79 @@ +package org.jabref.logic.integrity; + +import java.util.Optional; + +import org.jabref.model.database.BibDatabaseContext; +import org.jabref.model.database.BibDatabaseMode; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +public class TitleCheckerTest { + + private TitleChecker checker; + + @BeforeEach + public void setUp() { + BibDatabaseContext databaseContext = new BibDatabaseContext(); + databaseContext.setMode(BibDatabaseMode.BIBTEX); + checker = new TitleChecker(databaseContext); + } + + @Test + public void FirstLetterAsOnlyCapitalLetterInSubTitle2() { + assertEquals(Optional.empty(), checker.checkValue("This is a sub title 1: This is a sub title 2")); + } + + @Test + public void NoCapitalLetterInSubTitle2() { + assertEquals(Optional.empty(), checker.checkValue("This is a sub title 1: this is a sub title 2")); + } + + @Test + public void TwoCapitalLettersInSubTitle2() { + assertNotEquals(Optional.empty(), checker.checkValue("This is a sub title 1: This is A sub title 2")); + } + + @Test + public void MiddleLetterAsOnlyCapitalLetterInSubTitle2() { + assertNotEquals(Optional.empty(), checker.checkValue("This is a sub title 1: this is A sub title 2")); + } + + @Test + public void TwoCapitalLettersInSubTitle2WithCurlyBrackets() { + assertEquals(Optional.empty(), checker.checkValue("This is a sub title 1: This is {A} sub title 2")); + } + + @Test + public void MiddleLetterAsOnlyCapitalLetterInSubTitle2WithCurlyBrackets() { + assertEquals(Optional.empty(), checker.checkValue("This is a sub title 1: this is {A} sub title 2")); + } + + @Test + public void FirstLetterAsOnlyCapitalLetterInSubTitle2AfterContinuousDelimiters() { + assertEquals(Optional.empty(), checker.checkValue("This is a sub title 1...This is a sub title 2")); + } + + @Test + public void MiddleLetterAsOnlyCapitalLetterInSubTitle2AfterContinuousDelimiters() { + assertNotEquals(Optional.empty(), checker.checkValue("This is a sub title 1... this is a sub Title 2")); + } + + @Test + public void FirstLetterAsOnlyCapitalLetterInEverySubTitleWithContinuousDelimiters() { + assertEquals(Optional.empty(), checker.checkValue("This is; A sub title 1.... This is a sub title 2")); + } + + @Test + public void FirstLetterAsOnlyCapitalLetterInEverySubTitleWithRandomDelimiters() { + assertEquals(Optional.empty(), checker.checkValue("This!is!!A!Title??")); + } + + @Test + public void MoreThanOneCapitalLetterInSubTitleWithoutCurlyBrackets() { + assertNotEquals(Optional.empty(), checker.checkValue("This!is!!A!TitlE??")); + } +}