From 3ddb9e0a6e2ff0f0d151ba64aa1cd62fa0035fbc Mon Sep 17 00:00:00 2001 From: Loay Ghreeb <52158423+LoayGhreeb@users.noreply.github.com> Date: Thu, 11 Apr 2024 22:16:48 +0200 Subject: [PATCH] Refactor DefaultLatexParser, LatexParserResult classes (#11158) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Convert Citation class to record * Add citation key to the Citation record We need to represent the citations in a map of `Path` and  `Set` to update each file individually. * Remove fileList and nestedFiles list from LatexParserResult `fileList` and `nestedFiles` are not used anywhere. * Modified DefaultTexParser to parse file by file * Adapt test classes * Minor changes * Fix MainArchitectureTest * Update DefaultLatexParser.java * Normalize Path to avoid duplications * Add CitationFinder class * new CitationFinder instance if the directory changed * Update parse method to return Optional * Fix refresh button * Fix refresh button --- .../LatexCitationsTabViewModel.java | 50 ++---- .../gui/texparser/CitationsDisplay.java | 12 +- .../texparser/ParseLatexDialogViewModel.java | 7 +- .../logic/texparser/CitationFinder.java | 56 +++++++ .../logic/texparser/DefaultLatexParser.java | 111 ++++++------- .../jabref/logic/texparser/LatexParser.java | 10 +- .../texparser/TexBibEntriesResolver.java | 53 +++--- .../org/jabref/model/texparser/Citation.java | 53 +----- .../LatexBibEntriesResolverResult.java | 31 +--- .../model/texparser/LatexParserResult.java | 91 ++++------- .../model/texparser/LatexParserResults.java | 87 ++++++++++ .../logic/texparser/DefaultTexParserTest.java | 153 ++++++++---------- .../logic/texparser/LatexParserTest.java | 48 +++--- .../texparser/TexBibEntriesResolverTest.java | 52 +++--- .../jabref/model/texparser/CitationTest.java | 29 ++-- 15 files changed, 419 insertions(+), 424 deletions(-) create mode 100644 src/main/java/org/jabref/logic/texparser/CitationFinder.java create mode 100644 src/main/java/org/jabref/model/texparser/LatexParserResults.java diff --git a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java index 2cd206eab43..833ce40ef63 100644 --- a/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java +++ b/src/main/java/org/jabref/gui/entryeditor/LatexCitationsTabViewModel.java @@ -1,10 +1,6 @@ package org.jabref.gui.entryeditor; -import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.Collection; -import java.util.List; import java.util.Optional; import java.util.concurrent.Future; @@ -22,12 +18,11 @@ import org.jabref.gui.util.DirectoryDialogConfiguration; import org.jabref.gui.util.TaskExecutor; import org.jabref.logic.l10n.Localization; -import org.jabref.logic.texparser.DefaultLatexParser; +import org.jabref.logic.texparser.CitationFinder; import org.jabref.logic.util.io.FileUtil; import org.jabref.model.database.BibDatabaseContext; import org.jabref.model.entry.BibEntry; import org.jabref.model.texparser.Citation; -import org.jabref.model.texparser.LatexParserResult; import org.jabref.preferences.PreferencesService; import org.slf4j.Logger; @@ -49,11 +44,11 @@ enum Status { private final TaskExecutor taskExecutor; private final DialogService dialogService; private final ObjectProperty directory; + private CitationFinder citationFinder; private final ObservableList citationList; private final ObjectProperty status; private final StringProperty searchError; private Future searchTask; - private LatexParserResult latexParserResult; private BibEntry currentEntry; public LatexCitationsTabViewModel(BibDatabaseContext databaseContext, @@ -66,6 +61,8 @@ public LatexCitationsTabViewModel(BibDatabaseContext databaseContext, this.dialogService = dialogService; this.directory = new SimpleObjectProperty<>(databaseContext.getMetaData().getLatexFileDirectory(preferencesService.getFilePreferences().getUserAndHost()) .orElse(FileUtil.getInitialDirectory(databaseContext, preferencesService.getFilePreferences().getWorkingDirectory()))); + + this.citationFinder = new CitationFinder(directory.get()); this.citationList = FXCollections.observableArrayList(); this.status = new SimpleObjectProperty<>(Status.IN_PROGRESS); this.searchError = new SimpleStringProperty(""); @@ -102,7 +99,10 @@ public StringProperty searchErrorProperty() { } private void startSearch(String citeKey) { - searchTask = BackgroundTask.wrap(() -> searchAndParse(citeKey)) + // we need to check whether the user meanwhile set the LaTeX file directory or the database changed locations + checkAndUpdateDirectory(); + + searchTask = BackgroundTask.wrap(() -> citationFinder.searchAndParse(citeKey)) .onRunning(() -> status.set(Status.IN_PROGRESS)) .onSuccess(result -> { citationList.setAll(result); @@ -124,39 +124,13 @@ private void cancelSearch() { searchTask.cancel(true); } - private Collection searchAndParse(String citeKey) throws IOException { - // we need to check whether the user meanwhile set the LaTeX file directory or the database changed locations + public void checkAndUpdateDirectory() { Path newDirectory = databaseContext.getMetaData().getLatexFileDirectory(preferencesService.getFilePreferences().getUserAndHost()) .orElse(FileUtil.getInitialDirectory(databaseContext, preferencesService.getFilePreferences().getWorkingDirectory())); - if (latexParserResult == null || !newDirectory.equals(directory.get())) { + if (!newDirectory.equals(directory.get())) { directory.set(newDirectory); - - if (!newDirectory.toFile().exists()) { - throw new IOException("Current search directory does not exist: %s".formatted(newDirectory)); - } - - List texFiles = searchDirectory(newDirectory); - LOGGER.debug("Found tex files: {}", texFiles); - latexParserResult = new DefaultLatexParser().parse(texFiles); - } - - return latexParserResult.getCitationsByKey(citeKey); - } - - /** - * @param directory the directory to search for. It is recursively searched. - */ - private List searchDirectory(Path directory) { - LOGGER.debug("Searching directory {}", directory); - try { - return Files.walk(directory) - .filter(Files::isRegularFile) - .filter(path -> path.toString().endsWith(TEX_EXT)) - .toList(); - } catch (IOException e) { - LOGGER.error("Error while searching files", e); - return List.of(); + citationFinder = new CitationFinder(newDirectory); } } @@ -171,7 +145,7 @@ public void setLatexDirectory() { } public void refreshLatexDirectory() { - latexParserResult = null; + citationFinder = new CitationFinder(directory.get()); init(currentEntry); } diff --git a/src/main/java/org/jabref/gui/texparser/CitationsDisplay.java b/src/main/java/org/jabref/gui/texparser/CitationsDisplay.java index e8a3a781e4a..184ec2613be 100644 --- a/src/main/java/org/jabref/gui/texparser/CitationsDisplay.java +++ b/src/main/java/org/jabref/gui/texparser/CitationsDisplay.java @@ -40,7 +40,7 @@ public ObjectProperty basePathProperty() { private Node getDisplayGraphic(Citation item) { if (basePath.get() == null) { - basePath.set(item.getPath().getRoot()); + basePath.set(item.path().getRoot()); } Node citationIcon = IconTheme.JabRefIcons.LATEX_COMMENT.getGraphicNode(); @@ -49,9 +49,9 @@ private Node getDisplayGraphic(Citation item) { HBox contextBox = new HBox(8, citationIcon, contextText); contextBox.getStyleClass().add("contextBox"); - Label fileNameLabel = new Label(String.format("%s", basePath.get().relativize(item.getPath()))); + Label fileNameLabel = new Label(String.format("%s", basePath.get().relativize(item.path()))); fileNameLabel.setGraphic(IconTheme.JabRefIcons.LATEX_FILE.getGraphicNode()); - Label positionLabel = new Label("(%s:%s-%s)".formatted(item.getLine(), item.getColStart(), item.getColEnd())); + Label positionLabel = new Label("(%s:%s-%s)".formatted(item.line(), item.colStart(), item.colEnd())); positionLabel.setGraphic(IconTheme.JabRefIcons.LATEX_LINE.getGraphicNode()); HBox dataBox = new HBox(5, fileNameLabel, positionLabel); @@ -59,9 +59,9 @@ private Node getDisplayGraphic(Citation item) { } private Tooltip getDisplayTooltip(Citation item) { - String line = item.getLineText(); - int start = item.getColStart(); - int end = item.getColEnd(); + String line = item.lineText(); + int start = item.colStart(); + int end = item.colEnd(); List texts = new ArrayList<>(3); diff --git a/src/main/java/org/jabref/gui/texparser/ParseLatexDialogViewModel.java b/src/main/java/org/jabref/gui/texparser/ParseLatexDialogViewModel.java index b909956ee17..257c5e797d3 100644 --- a/src/main/java/org/jabref/gui/texparser/ParseLatexDialogViewModel.java +++ b/src/main/java/org/jabref/gui/texparser/ParseLatexDialogViewModel.java @@ -170,7 +170,7 @@ private FileNodeViewModel searchDirectory(Path directory) throws IOException { List files = fileListPartition.get(false) .stream() .filter(path -> path.toString().endsWith(TEX_EXT)) - .collect(Collectors.toList()); + .toList(); int fileCount = 0; for (Path subDirectory : subDirectories) { @@ -185,7 +185,7 @@ private FileNodeViewModel searchDirectory(Path directory) throws IOException { parent.setFileCount(files.size() + fileCount); parent.getChildren().addAll(files.stream() .map(FileNodeViewModel::new) - .collect(Collectors.toList())); + .toList()); return parent; } @@ -196,7 +196,7 @@ public void parseButtonClicked() { List fileList = checkedFileList.stream() .map(item -> item.getValue().getPath()) .filter(path -> path.toFile().isFile()) - .collect(Collectors.toList()); + .toList(); if (fileList.isEmpty()) { LOGGER.warn("There are no valid files checked"); return; @@ -204,7 +204,6 @@ public void parseButtonClicked() { TexBibEntriesResolver entriesResolver = new TexBibEntriesResolver( databaseContext.getDatabase(), - preferencesService.getLibraryPreferences(), preferencesService.getImportFormatPreferences(), fileMonitor); diff --git a/src/main/java/org/jabref/logic/texparser/CitationFinder.java b/src/main/java/org/jabref/logic/texparser/CitationFinder.java new file mode 100644 index 00000000000..fac31569876 --- /dev/null +++ b/src/main/java/org/jabref/logic/texparser/CitationFinder.java @@ -0,0 +1,56 @@ +package org.jabref.logic.texparser; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collection; +import java.util.List; +import java.util.stream.Stream; + +import org.jabref.model.texparser.Citation; +import org.jabref.model.texparser.LatexParserResults; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CitationFinder { + + private static final Logger LOGGER = LoggerFactory.getLogger(CitationFinder.class); + private static final String TEX_EXT = ".tex"; + private final Path directory; + + private LatexParserResults latexParserResults; + + public CitationFinder(Path directory) { + this.directory = directory; + } + + public Collection searchAndParse(String citeKey) throws IOException { + if (latexParserResults == null) { + if (!Files.exists(directory)) { + throw new IOException("Current search directory does not exist: %s".formatted(directory)); + } + + List texFiles = searchDirectory(directory); + LOGGER.debug("Found tex files: {}", texFiles); + latexParserResults = new DefaultLatexParser().parse(texFiles); + } + + return latexParserResults.getCitationsByKey(citeKey); + } + + /** + * @param directory the directory to search for. It is recursively searched. + */ + private List searchDirectory(Path directory) { + LOGGER.debug("Searching directory {}", directory); + try (Stream paths = Files.walk(directory)) { + return paths.filter(Files::isRegularFile) + .filter(path -> path.toString().endsWith(TEX_EXT)) + .toList(); + } catch (IOException e) { + LOGGER.error("Error while searching files", e); + return List.of(); + } + } +} diff --git a/src/main/java/org/jabref/logic/texparser/DefaultLatexParser.java b/src/main/java/org/jabref/logic/texparser/DefaultLatexParser.java index 14c8c2ec8d7..385c3b8b94e 100644 --- a/src/main/java/org/jabref/logic/texparser/DefaultLatexParser.java +++ b/src/main/java/org/jabref/logic/texparser/DefaultLatexParser.java @@ -10,13 +10,14 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; +import java.util.Optional; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.jabref.model.texparser.LatexParserResult; +import org.jabref.model.texparser.LatexParserResults; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,75 +50,75 @@ public class DefaultLatexParser implements LatexParser { private static final Pattern INCLUDE_PATTERN = Pattern.compile( "\\\\(?:include|input)\\{(?<%s>[^\\}]*)\\}".formatted(INCLUDE_GROUP)); - private final LatexParserResult latexParserResult; + private final LatexParserResults latexParserResults; public DefaultLatexParser() { - this.latexParserResult = new LatexParserResult(); - } - - public LatexParserResult getLatexParserResult() { - return latexParserResult; + this.latexParserResults = new LatexParserResults(); } @Override public LatexParserResult parse(String citeString) { - matchCitation(Path.of(""), 1, citeString); + Path path = Path.of(""); + LatexParserResult latexParserResult = new LatexParserResult(path); + matchCitation(path, 1, citeString, latexParserResult); return latexParserResult; } @Override - public LatexParserResult parse(Path latexFile) { - return parse(Collections.singletonList(latexFile)); + public Optional parse(Path latexFile) { + if (!Files.exists(latexFile)) { + LOGGER.error("File does not exist: {}", latexFile); + return Optional.empty(); + } + LatexParserResult latexParserResult = new LatexParserResult(latexFile); + + try (InputStream inputStream = Files.newInputStream(latexFile); + Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); + LineNumberReader lineNumberReader = new LineNumberReader(reader)) { + for (String line = lineNumberReader.readLine(); line != null; line = lineNumberReader.readLine()) { + // Skip comments and blank lines. + if (line.trim().isEmpty() || line.trim().charAt(0) == '%') { + continue; + } + matchCitation(latexFile, lineNumberReader.getLineNumber(), line, latexParserResult); + matchBibFile(latexFile, line, latexParserResult); + matchNestedFile(latexFile, line, latexParserResult); + } + } catch (ClosedChannelException e) { + // User changed the underlying LaTeX file + // We ignore this error and just continue with parsing + LOGGER.info("Parsing has been interrupted"); + } catch (IOException | UncheckedIOException e) { + // Some weired error during reading + // We ignore this error and just continue with parsing + LOGGER.info("Error while parsing file {}", latexFile, e); + } + + return Optional.of(latexParserResult); } @Override - public LatexParserResult parse(List latexFiles) { - latexParserResult.addFiles(latexFiles); - List referencedFiles = new ArrayList<>(); - - for (Path file : latexFiles) { - if (!Files.exists(file)) { - LOGGER.error("File does not exist: {}", file); - continue; - } - - try ( - InputStream inputStream = Files.newInputStream(file); - Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); - LineNumberReader lineNumberReader = new LineNumberReader(reader)) { - for (String line = lineNumberReader.readLine(); line != null; line = lineNumberReader.readLine()) { - // Skip comments and blank lines. - if (line.trim().isEmpty() || line.trim().charAt(0) == '%') { - continue; - } - matchCitation(file, lineNumberReader.getLineNumber(), line); - matchBibFile(file, line); - matchNestedFile(file, latexFiles, referencedFiles, line); - } - } catch (ClosedChannelException e) { - // User changed the underlying LaTeX file - // We ignore this error and just continue with parsing - LOGGER.info("Parsing has been interrupted"); - } catch (IOException | UncheckedIOException e) { - // Some weired error during reading - // We ignore this error and just continue with parsing - LOGGER.info("Error while parsing file {}", file, e); + public LatexParserResults parse(List latexFiles) { + for (Path latexFile : latexFiles) { + if (!latexParserResults.isParsed(latexFile)) { + parse(latexFile).ifPresent(parsedTex -> latexParserResults.add(latexFile, parsedTex)); } } - // Parse all files referenced by TEX files, recursively. - if (!referencedFiles.isEmpty()) { - // modifies class variable latexParserResult - parse(referencedFiles); + Set nonParsedNestedFiles = latexParserResults.getNonParsedNestedFiles(); + // Parse all "non-parsed" files referenced by TEX files, recursively. + if (!nonParsedNestedFiles.isEmpty()) { + // modifies class variable latexParserResults + parse(nonParsedNestedFiles.stream().toList()); } - return latexParserResult; + return latexParserResults; } /** * Find cites along a specific line and store them. */ - private void matchCitation(Path file, int lineNumber, String line) { + private void matchCitation(Path file, int lineNumber, String line, LatexParserResult latexParserResult) { Matcher citeMatch = CITE_PATTERN.matcher(line); while (citeMatch.find()) { @@ -130,7 +131,7 @@ private void matchCitation(Path file, int lineNumber, String line) { /** * Find BIB files along a specific line and store them. */ - private void matchBibFile(Path file, String line) { + private void matchBibFile(Path file, String line, LatexParserResult latexParserResult) { Matcher bibliographyMatch = BIBLIOGRAPHY_PATTERN.matcher(line); while (bibliographyMatch.find()) { @@ -139,10 +140,10 @@ private void matchBibFile(Path file, String line) { Path bibFile = file.getParent().resolve( bibString.endsWith(BIB_EXT) ? bibString - : "%s%s".formatted(bibString, BIB_EXT)); + : "%s%s".formatted(bibString, BIB_EXT)).normalize(); if (Files.exists(bibFile)) { - latexParserResult.addBibFile(file, bibFile); + latexParserResult.addBibFile(bibFile); } } } @@ -151,7 +152,7 @@ private void matchBibFile(Path file, String line) { /** * Find inputs and includes along a specific line and store them for parsing later. */ - private void matchNestedFile(Path texFile, List texFiles, List referencedFiles, String line) { + private void matchNestedFile(Path texFile, String line, LatexParserResult latexParserResult) { Matcher includeMatch = INCLUDE_PATTERN.matcher(line); while (includeMatch.find()) { @@ -159,9 +160,9 @@ private void matchNestedFile(Path texFile, List texFiles, List refer String texFileName = filenamePassedToInclude.endsWith(TEX_EXT) ? filenamePassedToInclude : "%s%s".formatted(filenamePassedToInclude, TEX_EXT); - Path nestedFile = texFile.getParent().resolve(texFileName); - if (Files.exists(nestedFile) && !texFiles.contains(nestedFile)) { - referencedFiles.add(nestedFile); + Path nestedFile = texFile.getParent().resolve(texFileName).normalize(); + if (Files.exists(nestedFile)) { + latexParserResult.addNestedFile(nestedFile); } } } diff --git a/src/main/java/org/jabref/logic/texparser/LatexParser.java b/src/main/java/org/jabref/logic/texparser/LatexParser.java index 9c64ff9a810..fa3af3c494b 100644 --- a/src/main/java/org/jabref/logic/texparser/LatexParser.java +++ b/src/main/java/org/jabref/logic/texparser/LatexParser.java @@ -2,8 +2,10 @@ import java.nio.file.Path; import java.util.List; +import java.util.Optional; import org.jabref.model.texparser.LatexParserResult; +import org.jabref.model.texparser.LatexParserResults; /** * Parses a LaTeX file @@ -22,15 +24,15 @@ public interface LatexParser { * Parse a single LaTeX file. * * @param latexFile Path to a LaTeX file - * @return a LatexParserResult, which contains all data related to the bibliographic entries + * @return Optional LatexParserResult, which contains all data related to the bibliographic entries, or empty if the file does not exist */ - LatexParserResult parse(Path latexFile); + Optional parse(Path latexFile); /** * Parse a list of LaTeX files. * * @param latexFiles List of Path objects linked to a LaTeX file - * @return a LatexParserResult, which contains all data related to the bibliographic entries + * @return a LatexParserResults, which contains all data related to the bibliographic entries */ - LatexParserResult parse(List latexFiles); + LatexParserResults parse(List latexFiles); } diff --git a/src/main/java/org/jabref/logic/texparser/TexBibEntriesResolver.java b/src/main/java/org/jabref/logic/texparser/TexBibEntriesResolver.java index 50bbbb495e1..c7c8afa7119 100644 --- a/src/main/java/org/jabref/logic/texparser/TexBibEntriesResolver.java +++ b/src/main/java/org/jabref/logic/texparser/TexBibEntriesResolver.java @@ -1,23 +1,17 @@ package org.jabref.logic.texparser; import java.io.IOException; -import java.nio.file.Path; -import java.util.Map; +import java.util.List; import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.logic.importer.OpenDatabase; import org.jabref.logic.importer.ParserResult; import org.jabref.model.database.BibDatabase; import org.jabref.model.entry.BibEntry; -import org.jabref.model.texparser.Citation; import org.jabref.model.texparser.LatexBibEntriesResolverResult; -import org.jabref.model.texparser.LatexParserResult; +import org.jabref.model.texparser.LatexParserResults; import org.jabref.model.util.FileUpdateMonitor; -import org.jabref.preferences.LibraryPreferences; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,13 +21,11 @@ public class TexBibEntriesResolver { private static final Logger LOGGER = LoggerFactory.getLogger(TexBibEntriesResolver.class); private final BibDatabase masterDatabase; - private final LibraryPreferences libraryPreferences; private final ImportFormatPreferences importFormatPreferences; private final FileUpdateMonitor fileMonitor; - public TexBibEntriesResolver(BibDatabase masterDatabase, LibraryPreferences libraryPreferences, ImportFormatPreferences importFormatPreferences, FileUpdateMonitor fileMonitor) { + public TexBibEntriesResolver(BibDatabase masterDatabase, ImportFormatPreferences importFormatPreferences, FileUpdateMonitor fileMonitor) { this.masterDatabase = masterDatabase; - this.libraryPreferences = libraryPreferences; this.importFormatPreferences = importFormatPreferences; this.fileMonitor = fileMonitor; } @@ -41,43 +33,42 @@ public TexBibEntriesResolver(BibDatabase masterDatabase, LibraryPreferences libr /** * Resolve all BibTeX entries and check if they are in the given database. */ - public LatexBibEntriesResolverResult resolve(LatexParserResult latexParserResult) { - LatexBibEntriesResolverResult resolverResult = new LatexBibEntriesResolverResult(latexParserResult); + public LatexBibEntriesResolverResult resolve(LatexParserResults latexParserResults) { + LatexBibEntriesResolverResult resolverResult = new LatexBibEntriesResolverResult(latexParserResults); // Preload databases from BIB files. - Map bibDatabases = resolverResult.getBibFiles().values().stream().distinct().collect(Collectors.toMap( - Function.identity(), path -> { + List bibDatabases = + latexParserResults.getBibFiles().stream().map(path -> { try { return OpenDatabase.loadDatabase(path, importFormatPreferences, fileMonitor).getDatabase(); } catch (IOException e) { LOGGER.error("Error opening file '{}'", path, e); return ParserResult.fromError(e).getDatabase(); } - })); - - // Get all pairs Entry. - Stream> citationsStream = latexParserResult.getCitations().entries().stream().distinct(); - - Set newEntries = citationsStream.flatMap(mapEntry -> apply(mapEntry, latexParserResult, bibDatabases)).collect(Collectors.toSet()); + }).toList(); // Add all new entries to the newEntries set. + List newEntries = findNewEntries(bibDatabases, latexParserResults.getCitations().keySet()); resolverResult.getNewEntries().addAll(newEntries); return resolverResult; } - private Stream apply(Map.Entry mapEntry, LatexParserResult latexParserResult, Map bibDatabases) { - return latexParserResult.getBibFiles().get(mapEntry.getValue().getPath()).stream().distinct().flatMap(bibFile -> - // Get a specific entry from an entryKey and a BIB file. - bibDatabases.get(bibFile).getEntriesByCitationKey(mapEntry.getKey()).stream().distinct() - // Check if there is already an entry with the same key in the given database. - .filter(entry -> !entry.equals(masterDatabase.getEntryByCitationKey(entry.getCitationKey().orElse("")).orElse(new BibEntry()))) - // Add cross-referencing data to the entry (fill empty fields). - .map(entry -> addCrossReferencingData(entry, bibFile, bibDatabases))); + private List findNewEntries(List bibDatabases, Set citations) { + return bibDatabases + .stream() + .flatMap(database -> + citations.stream() + .flatMap(citation -> database.getEntriesByCitationKey(citation).stream()) + // Check if there is already an entry with the same key in the given database. + .filter(entry -> !entry.equals(masterDatabase.getEntryByCitationKey(entry.getCitationKey().orElse("")).orElse(new BibEntry()))) + // Add cross-referencing data to the entry (fill empty fields). + .map(entry -> addCrossReferencingData(entry, database))) + .toList(); } - private BibEntry addCrossReferencingData(BibEntry entry, Path bibFile, Map bibDatabases) { - bibDatabases.get(bibFile).getReferencedEntry(entry).ifPresent(refEntry -> + private BibEntry addCrossReferencingData(BibEntry entry, BibDatabase bibDatabase) { + bibDatabase.getReferencedEntry(entry).ifPresent(refEntry -> refEntry.getFields().forEach(field -> entry.getFieldMap().putIfAbsent(field, refEntry.getFieldOrAlias(field).orElse("")))); return entry; diff --git a/src/main/java/org/jabref/model/texparser/Citation.java b/src/main/java/org/jabref/model/texparser/Citation.java index 4288cded53a..87911525e5a 100644 --- a/src/main/java/org/jabref/model/texparser/Citation.java +++ b/src/main/java/org/jabref/model/texparser/Citation.java @@ -3,19 +3,12 @@ import java.nio.file.Path; import java.util.Objects; -public class Citation { - +public record Citation(Path path, int line, int colStart, int colEnd, String lineText) { /** * The total number of characters that are shown around a cite (cite width included). */ private static final int CONTEXT_WIDTH = 300; - private final Path path; - private final int line; - private final int colStart; - private final int colEnd; - private final String lineText; - public Citation(Path path, int line, int colStart, int colEnd, String lineText) { if (line <= 0) { throw new IllegalArgumentException("Line has to be greater than 0."); @@ -32,26 +25,6 @@ public Citation(Path path, int line, int colStart, int colEnd, String lineText) this.lineText = lineText; } - public Path getPath() { - return path; - } - - public int getLine() { - return line; - } - - public int getColStart() { - return colStart; - } - - public int getColEnd() { - return colEnd; - } - - public String getLineText() { - return lineText; - } - /** * Get a fixed-width string that contains a cite and the text that surrounds it along the same line. */ @@ -80,28 +53,4 @@ public String toString() { this.colEnd, this.lineText); } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - - if (obj == null || getClass() != obj.getClass()) { - return false; - } - - Citation that = (Citation) obj; - - return Objects.equals(path, that.path) - && Objects.equals(line, that.line) - && Objects.equals(colStart, that.colStart) - && Objects.equals(colEnd, that.colEnd) - && Objects.equals(lineText, that.lineText); - } - - @Override - public int hashCode() { - return Objects.hash(path, line, colStart, colEnd, lineText); - } } diff --git a/src/main/java/org/jabref/model/texparser/LatexBibEntriesResolverResult.java b/src/main/java/org/jabref/model/texparser/LatexBibEntriesResolverResult.java index f52ea7fb308..eb0100eb9ad 100644 --- a/src/main/java/org/jabref/model/texparser/LatexBibEntriesResolverResult.java +++ b/src/main/java/org/jabref/model/texparser/LatexBibEntriesResolverResult.java @@ -1,6 +1,5 @@ package org.jabref.model.texparser; -import java.nio.file.Path; import java.util.HashSet; import java.util.Objects; import java.util.Set; @@ -11,18 +10,14 @@ public class LatexBibEntriesResolverResult { - private final LatexParserResult latexParserResult; + private final LatexParserResults latexParserResults; private final Set newEntries; - public LatexBibEntriesResolverResult(LatexParserResult latexParserResult) { - this.latexParserResult = latexParserResult; + public LatexBibEntriesResolverResult(LatexParserResults latexParserResults) { + this.latexParserResults = latexParserResults; this.newEntries = new HashSet<>(); } - public LatexParserResult getLatexParserResult() { - return latexParserResult; - } - public Set getNewEntries() { return newEntries; } @@ -31,24 +26,14 @@ public void addEntry(BibEntry entry) { newEntries.add(entry); } - /** - * @return the BIB files multimap from the LatexParserResult object. - */ - public Multimap getBibFiles() { - return latexParserResult.getBibFiles(); - } - - /** - * @return the citations multimap from the LatexParserResult object. - */ public Multimap getCitations() { - return latexParserResult.getCitations(); + return latexParserResults.getCitations(); } @Override public String toString() { - return "TexBibEntriesResolverResult{texParserResult=%s, newEntries=%s}".formatted( - this.latexParserResult, + return "TexBibEntriesResolverResult{latexParserResults=%s, newEntries=%s}".formatted( + this.latexParserResults, this.newEntries); } @@ -64,12 +49,12 @@ public boolean equals(Object obj) { LatexBibEntriesResolverResult that = (LatexBibEntriesResolverResult) obj; - return Objects.equals(latexParserResult, that.latexParserResult) + return Objects.equals(latexParserResults, that.latexParserResults) && Objects.equals(newEntries, that.newEntries); } @Override public int hashCode() { - return Objects.hash(latexParserResult, newEntries); + return Objects.hash(latexParserResults, newEntries); } } diff --git a/src/main/java/org/jabref/model/texparser/LatexParserResult.java b/src/main/java/org/jabref/model/texparser/LatexParserResult.java index 848fd7383e6..fe243b099c2 100644 --- a/src/main/java/org/jabref/model/texparser/LatexParserResult.java +++ b/src/main/java/org/jabref/model/texparser/LatexParserResult.java @@ -3,55 +3,34 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.Set; - -import org.jabref.model.entry.BibEntry; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; public class LatexParserResult { - private final List fileList; - private final List nestedFiles; - private final Multimap bibFiles; - - // BibTeXKey --> set of citations + private final Path path; private final Multimap citations; + private final List nestedFiles; + private final List bibFiles; - public LatexParserResult() { - this.fileList = new ArrayList<>(); - this.nestedFiles = new ArrayList<>(); - this.bibFiles = HashMultimap.create(); + public LatexParserResult(Path path) { + this.path = path; this.citations = HashMultimap.create(); + this.nestedFiles = new ArrayList<>(); + this.bibFiles = new ArrayList<>(); } - public List getFileList() { - return fileList; - } - - public List getNestedFiles() { - return nestedFiles; - } - - public Multimap getBibFiles() { - return bibFiles; + public Path getPath() { + return path; } public Multimap getCitations() { return citations; } - /** - * Return a set of strings with the keys of the citations multimap. - */ - public Set getCitationsKeySet() { - return citations.keySet(); - } - /** * Return a collection of citations using a string as key reference. */ @@ -60,45 +39,35 @@ public Collection getCitationsByKey(String key) { } /** - * Return a collection of citations using a BibEntry as reference. + * Add a citation to the citations multimap. */ - public Collection getCitationsByKey(BibEntry entry) { - return entry.getCitationKey().map(this::getCitationsByKey).orElse(Collections.emptyList()); + public void addKey(String key, Path path, int lineNumber, int start, int end, String line) { + citations.put(key, new Citation(path, lineNumber, start, end, line)); } - /** - * Add a list of files to fileList or nestedFiles, depending on whether this is the first list. - */ - public void addFiles(List texFiles) { - if (fileList.isEmpty()) { - fileList.addAll(texFiles); - } else { - nestedFiles.addAll(texFiles); - } + public List getNestedFiles() { + return nestedFiles; } - /** - * Add a bibliography file to the BIB files set. - */ - public void addBibFile(Path file, Path bibFile) { - bibFiles.put(file, bibFile); + public void addNestedFile(Path nestedFile) { + nestedFiles.add(nestedFile); } - /** - * Add a citation to the citations multimap. - */ - public void addKey(String key, Path file, int lineNumber, int start, int end, String line) { - Citation citation = new Citation(file, lineNumber, start, end, line); - citations.put(key, citation); + public List getBibFiles() { + return bibFiles; + } + + public void addBibFile(Path bibFile) { + bibFiles.add(bibFile); } @Override public String toString() { - return String.format("TexParserResult{fileList=%s, nestedFiles=%s, bibFiles=%s, citations=%s}", - this.fileList, + return String.format("TexParserResult{path=%s, citations=%s, nestedFiles=%s, bibFiles=%s}", + this.path, + this.citations, this.nestedFiles, - this.bibFiles, - this.citations); + this.bibFiles); } @Override @@ -113,14 +82,14 @@ public boolean equals(Object obj) { LatexParserResult that = (LatexParserResult) obj; - return Objects.equals(fileList, that.fileList) + return Objects.equals(path, that.path) + && Objects.equals(citations, that.citations) && Objects.equals(nestedFiles, that.nestedFiles) - && Objects.equals(bibFiles, that.bibFiles) - && Objects.equals(citations, that.citations); + && Objects.equals(bibFiles, that.bibFiles); } @Override public int hashCode() { - return Objects.hash(fileList, nestedFiles, bibFiles, citations); + return Objects.hash(path, citations, nestedFiles, bibFiles); } } diff --git a/src/main/java/org/jabref/model/texparser/LatexParserResults.java b/src/main/java/org/jabref/model/texparser/LatexParserResults.java new file mode 100644 index 00000000000..63245fea4ea --- /dev/null +++ b/src/main/java/org/jabref/model/texparser/LatexParserResults.java @@ -0,0 +1,87 @@ +package org.jabref.model.texparser; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; + +public class LatexParserResults { + private final Map parsedTexFiles; + + public LatexParserResults() { + this.parsedTexFiles = new HashMap<>(); + } + + @VisibleForTesting + public LatexParserResults(LatexParserResult... parsedFiles) { + this(); + for (LatexParserResult parsedFile : parsedFiles) { + add(parsedFile.getPath(), parsedFile); + } + } + + public boolean isParsed(Path texFile) { + return parsedTexFiles.containsKey(texFile); + } + + public void add(Path texFile, LatexParserResult parsedFile) { + parsedTexFiles.put(texFile, parsedFile); + } + + public Set getBibFiles() { + Set bibFiles = new HashSet<>(); + parsedTexFiles.values().forEach(result -> bibFiles.addAll(result.getBibFiles())); + return bibFiles; + } + + public Set getNonParsedNestedFiles() { + Set nonParsedNestedFiles = new HashSet<>(); + for (LatexParserResult result : parsedTexFiles.values()) { + nonParsedNestedFiles.addAll(result.getNestedFiles() + .stream() + .filter(nestedFile -> !parsedTexFiles.containsKey(nestedFile)) + .toList()); + } + return nonParsedNestedFiles; + } + + public Multimap getCitations() { + Multimap citations = HashMultimap.create(); + parsedTexFiles.forEach((path, result) -> citations.putAll(result.getCitations())); + return citations; + } + + public Collection getCitationsByKey(String key) { + Collection citations = new ArrayList<>(); + parsedTexFiles.values().forEach(result -> citations.addAll(result.getCitationsByKey(key))); + return citations; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null || getClass() != obj.getClass()) { + return false; + } + + LatexParserResults that = (LatexParserResults) obj; + + return Objects.equals(parsedTexFiles, that.parsedTexFiles); + } + + @Override + public int hashCode() { + return Objects.hash(parsedTexFiles); + } +} diff --git a/src/test/java/org/jabref/logic/texparser/DefaultTexParserTest.java b/src/test/java/org/jabref/logic/texparser/DefaultTexParserTest.java index c8a2608c2ef..72cdab07c44 100644 --- a/src/test/java/org/jabref/logic/texparser/DefaultTexParserTest.java +++ b/src/test/java/org/jabref/logic/texparser/DefaultTexParserTest.java @@ -2,9 +2,11 @@ import java.net.URISyntaxException; import java.nio.file.Path; -import java.util.Arrays; +import java.util.List; +import java.util.Optional; import org.jabref.model.texparser.LatexParserResult; +import org.jabref.model.texparser.LatexParserResults; import org.junit.jupiter.api.Test; @@ -21,17 +23,18 @@ public class DefaultTexParserTest { private final static String UNKNOWN = "UnknownKey"; private void testMatchCite(String key, String citeString) { + Path path = Path.of(""); LatexParserResult latexParserResult = new DefaultLatexParser().parse(citeString); - LatexParserResult expectedParserResult = new LatexParserResult(); + LatexParserResult expectedParserResult = new LatexParserResult(path); - expectedParserResult.addKey(key, Path.of(""), 1, 0, citeString.length(), citeString); + expectedParserResult.addKey(key, path, 1, 0, citeString.length(), citeString); assertEquals(expectedParserResult, latexParserResult); } private void testNonMatchCite(String citeString) { LatexParserResult latexParserResult = new DefaultLatexParser().parse(citeString); - LatexParserResult expectedParserResult = new LatexParserResult(); + LatexParserResult expectedParserResult = new LatexParserResult(Path.of("")); assertEquals(expectedParserResult, latexParserResult); } @@ -56,13 +59,14 @@ public void citeCommands() { @Test public void twoCitationsSameLine() { + Path path = Path.of(""); String citeString = "\\citep{Einstein1920c} and \\citep{Einstein1920a}"; LatexParserResult latexParserResult = new DefaultLatexParser().parse(citeString); - LatexParserResult expectedParserResult = new LatexParserResult(); + LatexParserResult expectedParserResult = new LatexParserResult(path); - expectedParserResult.addKey(EINSTEIN_C, Path.of(""), 1, 0, 21, citeString); - expectedParserResult.addKey(EINSTEIN_A, Path.of(""), 1, 26, 47, citeString); + expectedParserResult.addKey(EINSTEIN_C, path, 1, 0, 21, citeString); + expectedParserResult.addKey(EINSTEIN_A, path, 1, 26, 47, citeString); assertEquals(expectedParserResult, latexParserResult); } @@ -71,10 +75,9 @@ public void twoCitationsSameLine() { public void fileEncodingUtf8() throws URISyntaxException { Path texFile = Path.of(DefaultTexParserTest.class.getResource("utf-8.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(texFile); - LatexParserResult expectedParserResult = new LatexParserResult(); + LatexParserResult parserResult = new DefaultLatexParser().parse(texFile).get(); + LatexParserResult expectedParserResult = new LatexParserResult(texFile); - expectedParserResult.getFileList().add(texFile); expectedParserResult.addKey("anykey", texFile, 1, 32, 45, "Danach wir anschließend mittels \\cite{anykey}."); assertEquals(expectedParserResult, parserResult); @@ -84,13 +87,11 @@ public void fileEncodingUtf8() throws URISyntaxException { public void fileEncodingIso88591() throws URISyntaxException { Path texFile = Path.of(DefaultTexParserTest.class.getResource("iso-8859-1.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(texFile); - LatexParserResult expectedParserResult = new LatexParserResult(); + LatexParserResult parserResult = new DefaultLatexParser().parse(texFile).get(); + LatexParserResult expectedParserResult = new LatexParserResult(texFile); - expectedParserResult.getFileList().add(texFile); // The character � is on purpose - we cannot use Apache Tika's CharsetDetector - see ADR-0005 - expectedParserResult - .addKey("anykey", texFile, 1, 32, 45, "Danach wir anschlie�end mittels \\cite{anykey}."); + expectedParserResult.addKey("anykey", texFile, 1, 32, 45, "Danach wir anschlie�end mittels \\cite{anykey}."); assertEquals(expectedParserResult, parserResult); } @@ -99,13 +100,11 @@ public void fileEncodingIso88591() throws URISyntaxException { public void fileEncodingIso885915() throws URISyntaxException { Path texFile = Path.of(DefaultTexParserTest.class.getResource("iso-8859-15.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(texFile); - LatexParserResult expectedParserResult = new LatexParserResult(); + LatexParserResult parserResult = new DefaultLatexParser().parse(texFile).get(); + LatexParserResult expectedParserResult = new LatexParserResult(texFile); - expectedParserResult.getFileList().add(texFile); // The character � is on purpose - we cannot use Apache Tika's CharsetDetector - see ADR-0005 - expectedParserResult - .addKey("anykey", texFile, 1, 32, 45, "Danach wir anschlie�end mittels \\cite{anykey}."); + expectedParserResult.addKey("anykey", texFile, 1, 32, 45, "Danach wir anschlie�end mittels \\cite{anykey}."); assertEquals(expectedParserResult, parserResult); } @@ -116,30 +115,28 @@ public void fileEncodingForThreeFiles() throws URISyntaxException { Path texFile2 = Path.of(DefaultTexParserTest.class.getResource("iso-8859-1.tex").toURI()); Path texFile3 = Path.of(DefaultTexParserTest.class.getResource("iso-8859-15.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser() - .parse(Arrays.asList(texFile, texFile2, texFile3)); - LatexParserResult expectedParserResult = new LatexParserResult(); + LatexParserResults parserResults = new DefaultLatexParser().parse(List.of(texFile, texFile2, texFile3)); - expectedParserResult.getFileList().addAll(Arrays.asList(texFile, texFile2, texFile3)); - expectedParserResult - .addKey("anykey", texFile, 1, 32, 45, "Danach wir anschließend mittels \\cite{anykey}."); - expectedParserResult - .addKey("anykey", texFile2, 1, 32, 45, "Danach wir anschlie�end mittels \\cite{anykey}."); - expectedParserResult - .addKey("anykey", texFile3, 1, 32, 45, "Danach wir anschlie�end mittels \\cite{anykey}."); + LatexParserResult result1 = new LatexParserResult(texFile); + result1.addKey("anykey", texFile, 1, 32, 45, "Danach wir anschließend mittels \\cite{anykey}."); + LatexParserResult result2 = new LatexParserResult(texFile2); + result2.addKey("anykey", texFile2, 1, 32, 45, "Danach wir anschlie�end mittels \\cite{anykey}."); + LatexParserResult result3 = new LatexParserResult(texFile3); + result3.addKey("anykey", texFile3, 1, 32, 45, "Danach wir anschlie�end mittels \\cite{anykey}."); - assertEquals(expectedParserResult, parserResult); + LatexParserResults expectedParserResults = new LatexParserResults(result1, result2, result3); + + assertEquals(expectedParserResults, parserResults); } @Test public void singleFile() throws URISyntaxException { Path texFile = Path.of(DefaultTexParserTest.class.getResource("paper.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(texFile); - LatexParserResult expectedParserResult = new LatexParserResult(); + LatexParserResult parserResult = new DefaultLatexParser().parse(texFile).get(); + LatexParserResult expectedParserResult = new LatexParserResult(texFile); - expectedParserResult.getFileList().add(texFile); - expectedParserResult.addBibFile(texFile, texFile.getParent().resolve("origin.bib")); + expectedParserResult.addBibFile(texFile.getParent().resolve("origin.bib")); expectedParserResult.addKey(EINSTEIN, texFile, 4, 0, 19, "\\cite{Einstein1920}"); expectedParserResult.addKey(DARWIN, texFile, 5, 0, 17, "\\cite{Darwin1888}."); expectedParserResult.addKey(EINSTEIN, texFile, 6, 14, 33, "Einstein said \\cite{Einstein1920} that lorem impsum, consectetur adipiscing elit."); @@ -153,49 +150,53 @@ public void twoFiles() throws URISyntaxException { Path texFile = Path.of(DefaultTexParserTest.class.getResource("paper.tex").toURI()); Path texFile2 = Path.of(DefaultTexParserTest.class.getResource("paper2.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(Arrays.asList(texFile, texFile2)); - LatexParserResult expectedParserResult = new LatexParserResult(); + LatexParserResults parserResults = new DefaultLatexParser().parse(List.of(texFile, texFile2)); - expectedParserResult.getFileList().addAll(Arrays.asList(texFile, texFile2)); - expectedParserResult.addBibFile(texFile, texFile.getParent().resolve("origin.bib")); - expectedParserResult.addBibFile(texFile2, texFile2.getParent().resolve("origin.bib")); - expectedParserResult.addKey(EINSTEIN, texFile, 4, 0, 19, "\\cite{Einstein1920}"); - expectedParserResult.addKey(DARWIN, texFile, 5, 0, 17, "\\cite{Darwin1888}."); - expectedParserResult.addKey(EINSTEIN, texFile, 6, 14, 33, "Einstein said \\cite{Einstein1920} that lorem impsum, consectetur adipiscing elit."); - expectedParserResult.addKey(DARWIN, texFile, 7, 67, 84, "Nunc ultricies leo nec libero rhoncus, eu vehicula enim efficitur. \\cite{Darwin1888}"); - expectedParserResult.addKey(DARWIN, texFile2, 4, 48, 65, "This is some content trying to cite a bib file: \\cite{Darwin1888}"); - expectedParserResult.addKey(EINSTEIN, texFile2, 5, 48, 67, "This is some content trying to cite a bib file: \\cite{Einstein1920}"); - expectedParserResult.addKey(NEWTON, texFile2, 6, 48, 65, "This is some content trying to cite a bib file: \\cite{Newton1999}"); + LatexParserResult result1 = new LatexParserResult(texFile); + result1.addBibFile(texFile.getParent().resolve("origin.bib")); + result1.addKey(EINSTEIN, texFile, 4, 0, 19, "\\cite{Einstein1920}"); + result1.addKey(DARWIN, texFile, 5, 0, 17, "\\cite{Darwin1888}."); + result1.addKey(EINSTEIN, texFile, 6, 14, 33, "Einstein said \\cite{Einstein1920} that lorem impsum, consectetur adipiscing elit."); + result1.addKey(DARWIN, texFile, 7, 67, 84, "Nunc ultricies leo nec libero rhoncus, eu vehicula enim efficitur. \\cite{Darwin1888}"); - assertEquals(expectedParserResult, parserResult); + LatexParserResult result2 = new LatexParserResult(texFile2); + result2.addBibFile(texFile2.getParent().resolve("origin.bib")); + result2.addKey(DARWIN, texFile2, 4, 48, 65, "This is some content trying to cite a bib file: \\cite{Darwin1888}"); + result2.addKey(EINSTEIN, texFile2, 5, 48, 67, "This is some content trying to cite a bib file: \\cite{Einstein1920}"); + result2.addKey(NEWTON, texFile2, 6, 48, 65, "This is some content trying to cite a bib file: \\cite{Newton1999}"); + + LatexParserResults expectedParserResults = new LatexParserResults(result1, result2); + + assertEquals(expectedParserResults, parserResults); } @Test public void duplicateFiles() throws URISyntaxException { Path texFile = Path.of(DefaultTexParserTest.class.getResource("paper.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(Arrays.asList(texFile, texFile)); - LatexParserResult expectedParserResult = new LatexParserResult(); + LatexParserResults parserResults = new DefaultLatexParser().parse(List.of(texFile, texFile)); - expectedParserResult.getFileList().addAll(Arrays.asList(texFile, texFile)); - expectedParserResult.addBibFile(texFile, texFile.getParent().resolve("origin.bib")); - expectedParserResult.addKey(EINSTEIN, texFile, 4, 0, 19, "\\cite{Einstein1920}"); - expectedParserResult.addKey(DARWIN, texFile, 5, 0, 17, "\\cite{Darwin1888}."); - expectedParserResult.addKey(EINSTEIN, texFile, 6, 14, 33, "Einstein said \\cite{Einstein1920} that lorem impsum, consectetur adipiscing elit."); - expectedParserResult.addKey(DARWIN, texFile, 7, 67, 84, "Nunc ultricies leo nec libero rhoncus, eu vehicula enim efficitur. \\cite{Darwin1888}"); + LatexParserResult result = new LatexParserResult(texFile); - assertEquals(expectedParserResult, parserResult); + result.addBibFile(texFile.getParent().resolve("origin.bib")); + result.addKey(EINSTEIN, texFile, 4, 0, 19, "\\cite{Einstein1920}"); + result.addKey(DARWIN, texFile, 5, 0, 17, "\\cite{Darwin1888}."); + result.addKey(EINSTEIN, texFile, 6, 14, 33, "Einstein said \\cite{Einstein1920} that lorem impsum, consectetur adipiscing elit."); + result.addKey(DARWIN, texFile, 7, 67, 84, "Nunc ultricies leo nec libero rhoncus, eu vehicula enim efficitur. \\cite{Darwin1888}"); + + LatexParserResults expectedParserResults = new LatexParserResults(result, result); + + assertEquals(expectedParserResults, parserResults); } @Test public void unknownKey() throws URISyntaxException { Path texFile = Path.of(DefaultTexParserTest.class.getResource("unknown_key.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(texFile); - LatexParserResult expectedParserResult = new LatexParserResult(); + LatexParserResult parserResult = new DefaultLatexParser().parse(texFile).get(); + LatexParserResult expectedParserResult = new LatexParserResult(texFile); - expectedParserResult.getFileList().add(texFile); - expectedParserResult.addBibFile(texFile, texFile.getParent().resolve("origin.bib")); + expectedParserResult.addBibFile(texFile.getParent().resolve("origin.bib")); expectedParserResult.addKey(DARWIN, texFile, 4, 48, 65, "This is some content trying to cite a bib file: \\cite{Darwin1888}"); expectedParserResult.addKey(EINSTEIN, texFile, 5, 48, 67, "This is some content trying to cite a bib file: \\cite{Einstein1920}"); expectedParserResult.addKey(UNKNOWN, texFile, 6, 48, 65, "This is some content trying to cite a bib file: \\cite{UnknownKey}"); @@ -206,33 +207,19 @@ public void unknownKey() throws URISyntaxException { @Test public void fileNotFound() { Path texFile = Path.of("file_not_found.tex"); - - LatexParserResult parserResult = new DefaultLatexParser().parse(texFile); - LatexParserResult expectedParserResult = new LatexParserResult(); - - expectedParserResult.getFileList().add(texFile); - - assertEquals(expectedParserResult, parserResult); + Optional parserResult = new DefaultLatexParser().parse(texFile); + assertEquals(Optional.empty(), parserResult); } @Test public void nestedFiles() throws URISyntaxException { Path texFile = Path.of(DefaultTexParserTest.class.getResource("nested.tex").toURI()); - Path texFile2 = Path.of(DefaultTexParserTest.class.getResource("nested2.tex").toURI()); - Path texFile3 = Path.of(DefaultTexParserTest.class.getResource("paper.tex").toURI()); - - LatexParserResult parserResult = new DefaultLatexParser().parse(texFile); - LatexParserResult expectedParserResult = new LatexParserResult(); - - expectedParserResult.getFileList().add(texFile); - expectedParserResult.getNestedFiles().addAll(Arrays.asList(texFile2, texFile3)); - expectedParserResult.addBibFile(texFile, texFile.getParent().resolve("origin.bib")); - expectedParserResult.addBibFile(texFile2, texFile2.getParent().resolve("origin.bib")); - expectedParserResult.addBibFile(texFile3, texFile3.getParent().resolve("origin.bib")); - expectedParserResult.addKey(EINSTEIN, texFile3, 4, 0, 19, "\\cite{Einstein1920}"); - expectedParserResult.addKey(DARWIN, texFile3, 5, 0, 17, "\\cite{Darwin1888}."); - expectedParserResult.addKey(EINSTEIN, texFile3, 6, 14, 33, "Einstein said \\cite{Einstein1920} that lorem impsum, consectetur adipiscing elit."); - expectedParserResult.addKey(DARWIN, texFile3, 7, 67, 84, "Nunc ultricies leo nec libero rhoncus, eu vehicula enim efficitur. \\cite{Darwin1888}"); + + LatexParserResult parserResult = new DefaultLatexParser().parse(texFile).get(); + LatexParserResult expectedParserResult = new LatexParserResult(texFile); + + expectedParserResult.addBibFile(texFile.getParent().resolve("origin.bib")); + expectedParserResult.addNestedFile(texFile.getParent().resolve("nested2.tex")); assertEquals(expectedParserResult, parserResult); } diff --git a/src/test/java/org/jabref/logic/texparser/LatexParserTest.java b/src/test/java/org/jabref/logic/texparser/LatexParserTest.java index 135d907f874..1a03356cc93 100644 --- a/src/test/java/org/jabref/logic/texparser/LatexParserTest.java +++ b/src/test/java/org/jabref/logic/texparser/LatexParserTest.java @@ -2,7 +2,7 @@ import java.net.URISyntaxException; import java.nio.file.Path; -import java.util.Arrays; +import java.util.List; import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.model.database.BibDatabase; @@ -11,9 +11,9 @@ import org.jabref.model.entry.types.StandardEntryType; import org.jabref.model.texparser.LatexBibEntriesResolverResult; import org.jabref.model.texparser.LatexParserResult; +import org.jabref.model.texparser.LatexParserResults; import org.jabref.model.util.DummyFileUpdateMonitor; import org.jabref.model.util.FileUpdateMonitor; -import org.jabref.preferences.LibraryPreferences; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -31,14 +31,12 @@ public class LatexParserTest { private final static String EINSTEIN_C = "Einstein1920c"; private final FileUpdateMonitor fileMonitor = new DummyFileUpdateMonitor(); - private LibraryPreferences libraryPreferences; private ImportFormatPreferences importFormatPreferences; private BibDatabase database; private BibDatabase database2; @BeforeEach void setUp() { - libraryPreferences = mock(LibraryPreferences.class, Answers.RETURNS_DEEP_STUBS); importFormatPreferences = mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS); database = new BibDatabase(); @@ -92,23 +90,22 @@ void setUp() { public void sameFileDifferentDatabases() throws URISyntaxException { Path texFile = Path.of(LatexParserTest.class.getResource("paper.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(texFile); - LatexParserResult expectedParserResult = new LatexParserResult(); + LatexParserResult parserResult = new DefaultLatexParser().parse(texFile).get(); - expectedParserResult.getFileList().add(texFile); - expectedParserResult.addBibFile(texFile, texFile.getParent().resolve("origin.bib")); + LatexParserResult expectedParserResult = new LatexParserResult(texFile); + expectedParserResult.addBibFile(texFile.getParent().resolve("origin.bib")); expectedParserResult.addKey(EINSTEIN, texFile, 4, 0, 19, "\\cite{Einstein1920}"); expectedParserResult.addKey(DARWIN, texFile, 5, 0, 17, "\\cite{Darwin1888}."); expectedParserResult.addKey(EINSTEIN, texFile, 6, 14, 33, "Einstein said \\cite{Einstein1920} that lorem impsum, consectetur adipiscing elit."); expectedParserResult.addKey(DARWIN, texFile, 7, 67, 84, "Nunc ultricies leo nec libero rhoncus, eu vehicula enim efficitur. \\cite{Darwin1888}"); - LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, libraryPreferences, importFormatPreferences, fileMonitor).resolve(parserResult); - LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(expectedParserResult); + LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, importFormatPreferences, fileMonitor).resolve(new LatexParserResults(parserResult)); + LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(new LatexParserResults(expectedParserResult)); assertEquals(expectedCrossingResult, crossingResult); - LatexBibEntriesResolverResult crossingResult2 = new TexBibEntriesResolver(database2, libraryPreferences, importFormatPreferences, fileMonitor).resolve(parserResult); - LatexBibEntriesResolverResult expectedCrossingResult2 = new LatexBibEntriesResolverResult(expectedParserResult); + LatexBibEntriesResolverResult crossingResult2 = new TexBibEntriesResolver(database2, importFormatPreferences, fileMonitor).resolve(new LatexParserResults(parserResult)); + LatexBibEntriesResolverResult expectedCrossingResult2 = new LatexBibEntriesResolverResult(new LatexParserResults(expectedParserResult)); expectedCrossingResult2.addEntry(database.getEntryByCitationKey(EINSTEIN).get()); expectedCrossingResult2.addEntry(database.getEntryByCitationKey(DARWIN).get()); @@ -121,27 +118,30 @@ public void twoFilesDifferentDatabases() throws URISyntaxException { Path texFile = Path.of(LatexParserTest.class.getResource("paper.tex").toURI()); Path texFile2 = Path.of(LatexParserTest.class.getResource("paper2.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(Arrays.asList(texFile, texFile2)); - LatexParserResult expectedParserResult = new LatexParserResult(); + LatexParserResults parserResults = new DefaultLatexParser().parse(List.of(texFile, texFile2)); + LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, importFormatPreferences, fileMonitor).resolve(parserResults); - expectedParserResult.getFileList().addAll(Arrays.asList(texFile, texFile2)); - expectedParserResult.addBibFile(texFile, texFile.getParent().resolve("origin.bib")); - expectedParserResult.addBibFile(texFile2, texFile2.getParent().resolve("origin.bib")); + LatexParserResult expectedParserResult = new LatexParserResult(texFile); + expectedParserResult.addBibFile(texFile.getParent().resolve("origin.bib")); expectedParserResult.addKey(EINSTEIN, texFile, 4, 0, 19, "\\cite{Einstein1920}"); expectedParserResult.addKey(DARWIN, texFile, 5, 0, 17, "\\cite{Darwin1888}."); expectedParserResult.addKey(EINSTEIN, texFile, 6, 14, 33, "Einstein said \\cite{Einstein1920} that lorem impsum, consectetur adipiscing elit."); expectedParserResult.addKey(DARWIN, texFile, 7, 67, 84, "Nunc ultricies leo nec libero rhoncus, eu vehicula enim efficitur. \\cite{Darwin1888}"); - expectedParserResult.addKey(DARWIN, texFile2, 4, 48, 65, "This is some content trying to cite a bib file: \\cite{Darwin1888}"); - expectedParserResult.addKey(EINSTEIN, texFile2, 5, 48, 67, "This is some content trying to cite a bib file: \\cite{Einstein1920}"); - expectedParserResult.addKey(NEWTON, texFile2, 6, 48, 65, "This is some content trying to cite a bib file: \\cite{Newton1999}"); - LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, libraryPreferences, importFormatPreferences, fileMonitor).resolve(parserResult); - LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(expectedParserResult); + LatexParserResult expectedParserResult2 = new LatexParserResult(texFile2); + expectedParserResult2.addBibFile(texFile2.getParent().resolve("origin.bib")); + expectedParserResult2.addKey(DARWIN, texFile2, 4, 48, 65, "This is some content trying to cite a bib file: \\cite{Darwin1888}"); + expectedParserResult2.addKey(EINSTEIN, texFile2, 5, 48, 67, "This is some content trying to cite a bib file: \\cite{Einstein1920}"); + expectedParserResult2.addKey(NEWTON, texFile2, 6, 48, 65, "This is some content trying to cite a bib file: \\cite{Newton1999}"); + + LatexParserResults expectedParserResults = new LatexParserResults(expectedParserResult, expectedParserResult2); + + LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(expectedParserResults); assertEquals(expectedCrossingResult, crossingResult); - LatexBibEntriesResolverResult crossingResult2 = new TexBibEntriesResolver(database2, libraryPreferences, importFormatPreferences, fileMonitor).resolve(parserResult); - LatexBibEntriesResolverResult expectedCrossingResult2 = new LatexBibEntriesResolverResult(expectedParserResult); + LatexBibEntriesResolverResult crossingResult2 = new TexBibEntriesResolver(database2, importFormatPreferences, fileMonitor).resolve(parserResults); + LatexBibEntriesResolverResult expectedCrossingResult2 = new LatexBibEntriesResolverResult(expectedParserResults); expectedCrossingResult2.addEntry(database.getEntryByCitationKey(EINSTEIN).get()); expectedCrossingResult2.addEntry(database.getEntryByCitationKey(DARWIN).get()); diff --git a/src/test/java/org/jabref/logic/texparser/TexBibEntriesResolverTest.java b/src/test/java/org/jabref/logic/texparser/TexBibEntriesResolverTest.java index a39da7fe0a2..a6258ff4d04 100644 --- a/src/test/java/org/jabref/logic/texparser/TexBibEntriesResolverTest.java +++ b/src/test/java/org/jabref/logic/texparser/TexBibEntriesResolverTest.java @@ -2,7 +2,7 @@ import java.net.URISyntaxException; import java.nio.file.Path; -import java.util.Arrays; +import java.util.List; import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.model.database.BibDatabase; @@ -10,10 +10,9 @@ import org.jabref.model.entry.field.StandardField; import org.jabref.model.entry.types.StandardEntryType; import org.jabref.model.texparser.LatexBibEntriesResolverResult; -import org.jabref.model.texparser.LatexParserResult; +import org.jabref.model.texparser.LatexParserResults; import org.jabref.model.util.DummyFileUpdateMonitor; import org.jabref.model.util.FileUpdateMonitor; -import org.jabref.preferences.LibraryPreferences; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -31,19 +30,15 @@ public class TexBibEntriesResolverTest { private final static String EINSTEIN_C = "Einstein1920c"; private final FileUpdateMonitor fileMonitor = new DummyFileUpdateMonitor(); - private LibraryPreferences libraryPreferences; private ImportFormatPreferences importFormatPreferences; private BibDatabase database; - private BibDatabase database2; private BibEntry bibEntry; @BeforeEach void setUp() { - libraryPreferences = mock(LibraryPreferences.class, Answers.RETURNS_DEEP_STUBS); importFormatPreferences = mock(ImportFormatPreferences.class, Answers.RETURNS_DEEP_STUBS); database = new BibDatabase(); - database2 = new BibDatabase(); BibEntry darwin = new BibEntry(StandardEntryType.Book) .withCitationKey(DARWIN) @@ -69,12 +64,6 @@ void setUp() { .withField(StandardField.AUTHOR, "Newton, Isaac"); database.insertEntry(newton); - BibEntry einsteinA = new BibEntry(StandardEntryType.InBook) - .withCitationKey(EINSTEIN_A) - .withField(StandardField.CROSSREF, EINSTEIN) - .withField(StandardField.PAGES, "22--23"); - database2.insertEntry(einsteinA); - BibEntry einsteinB = new BibEntry(StandardEntryType.InBook) .withCitationKey(EINSTEIN_B) .withField(StandardField.CROSSREF, "Einstein1921") @@ -100,10 +89,11 @@ void setUp() { @Test public void singleFile() throws URISyntaxException { Path texFile = Path.of(TexBibEntriesResolverTest.class.getResource("paper.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(texFile); + LatexParserResults latexParserResults = new DefaultLatexParser().parse(List.of(texFile)); + + LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, importFormatPreferences, fileMonitor).resolve(latexParserResults); - LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, libraryPreferences, importFormatPreferences, fileMonitor).resolve(parserResult); - LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(parserResult); + LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(latexParserResults); assertEquals(expectedCrossingResult, crossingResult); } @@ -112,10 +102,10 @@ public void singleFile() throws URISyntaxException { public void twoFiles() throws URISyntaxException { Path texFile = Path.of(TexBibEntriesResolverTest.class.getResource("paper.tex").toURI()); Path texFile2 = Path.of(TexBibEntriesResolverTest.class.getResource("paper2.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(Arrays.asList(texFile, texFile2)); + LatexParserResults latexParserResults = new DefaultLatexParser().parse(List.of(texFile, texFile2)); - LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, libraryPreferences, importFormatPreferences, fileMonitor).resolve(parserResult); - LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(parserResult); + LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, importFormatPreferences, fileMonitor).resolve(latexParserResults); + LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(latexParserResults); assertEquals(expectedCrossingResult, crossingResult); } @@ -123,10 +113,10 @@ public void twoFiles() throws URISyntaxException { @Test public void duplicateFiles() throws URISyntaxException { Path texFile = Path.of(TexBibEntriesResolverTest.class.getResource("paper.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(texFile); + LatexParserResults parserResults = new DefaultLatexParser().parse(List.of(texFile)); - LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, libraryPreferences, importFormatPreferences, fileMonitor).resolve(parserResult); - LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(parserResult); + LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, importFormatPreferences, fileMonitor).resolve(parserResults); + LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(parserResults); assertEquals(expectedCrossingResult, crossingResult); } @@ -134,10 +124,10 @@ public void duplicateFiles() throws URISyntaxException { @Test public void unknownKey() throws URISyntaxException { Path texFile = Path.of(TexBibEntriesResolverTest.class.getResource("unknown_key.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(texFile); + LatexParserResults parserResults = new DefaultLatexParser().parse(List.of(texFile)); - LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, libraryPreferences, importFormatPreferences, fileMonitor).resolve(parserResult); - LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(parserResult); + LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, importFormatPreferences, fileMonitor).resolve(parserResults); + LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(parserResults); assertEquals(expectedCrossingResult, crossingResult); } @@ -145,10 +135,10 @@ public void unknownKey() throws URISyntaxException { @Test public void nestedFiles() throws URISyntaxException { Path texFile = Path.of(TexBibEntriesResolverTest.class.getResource("nested.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(texFile); + LatexParserResults parserResults = new DefaultLatexParser().parse(List.of(texFile)); - LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, libraryPreferences, importFormatPreferences, fileMonitor).resolve(parserResult); - LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(parserResult); + LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, importFormatPreferences, fileMonitor).resolve(parserResults); + LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(parserResults); assertEquals(expectedCrossingResult, crossingResult); } @@ -156,10 +146,10 @@ public void nestedFiles() throws URISyntaxException { @Test public void crossRef() throws URISyntaxException { Path texFile = Path.of(TexBibEntriesResolverTest.class.getResource("crossref.tex").toURI()); - LatexParserResult parserResult = new DefaultLatexParser().parse(texFile); + LatexParserResults parserResults = new DefaultLatexParser().parse(List.of(texFile)); - LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, libraryPreferences, importFormatPreferences, fileMonitor).resolve(parserResult); - LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(parserResult); + LatexBibEntriesResolverResult crossingResult = new TexBibEntriesResolver(database, importFormatPreferences, fileMonitor).resolve(parserResults); + LatexBibEntriesResolverResult expectedCrossingResult = new LatexBibEntriesResolverResult(parserResults); expectedCrossingResult.addEntry(bibEntry); diff --git a/src/test/java/org/jabref/model/texparser/CitationTest.java b/src/test/java/org/jabref/model/texparser/CitationTest.java index 36b7df4f2c0..e233ec013e1 100644 --- a/src/test/java/org/jabref/model/texparser/CitationTest.java +++ b/src/test/java/org/jabref/model/texparser/CitationTest.java @@ -18,12 +18,17 @@ public class CitationTest { Path path; + int line; + String key; + String lineText; Citation citation; @BeforeEach public void init() { path = Path.of("test"); - citation = new Citation(path, 10, 1, 4, "lineText"); + line = 10; + lineText = "lineText"; + citation = new Citation(path, line, 1, 4, lineText); } private static Stream colStartColEndNotInBounds() { @@ -43,62 +48,62 @@ private static Stream colStartColEndInBounds() { @ParameterizedTest @ValueSource(ints = {-1, 0}) public void constructorLineSmallerEqualZeroTest(int line) { - Exception e = assertThrows(IllegalArgumentException.class, () -> new Citation(path, line, 1, 5, "lineText")); + Exception e = assertThrows(IllegalArgumentException.class, () -> new Citation(path, line, 1, 5, lineText)); assertEquals("Line has to be greater than 0.", e.getMessage()); } @ParameterizedTest @ValueSource(ints = {1, 2}) public void constructorLineLargerZeroTest(int line) { - Citation citation = new Citation(path, line, 1, 5, "lineText"); + Citation citation = new Citation(path, line, 1, 5, lineText); } @ParameterizedTest @MethodSource("colStartColEndNotInBounds") public void constructorColStartColEndNotInBoundsTest(int colStart, int colEnd) { - Exception e = assertThrows(IllegalArgumentException.class, () -> new Citation(path, 10, colStart, colEnd, "lineText")); + Exception e = assertThrows(IllegalArgumentException.class, () -> new Citation(path, line, colStart, colEnd, lineText)); assertEquals("Citation has to be between 0 and line length.", e.getMessage()); } @ParameterizedTest @MethodSource("colStartColEndInBounds") public void constructorColStartColEndInBoundsTest(int colStart, int colEnd) { - Citation citation = new Citation(path, 10, colStart, colEnd, "lineText"); + Citation citation = new Citation(path, line, colStart, colEnd, lineText); } @Test public void getPathTest() { - assertEquals(path, citation.getPath()); + assertEquals(path, citation.path()); } @Test public void getLineTest() { - assertEquals(10, citation.getLine()); + assertEquals(10, citation.line()); } @Test public void getColStartTest() { - assertEquals(1, citation.getColStart()); + assertEquals(1, citation.colStart()); } @Test public void getColEndTest() { - assertEquals(4, citation.getColEnd()); + assertEquals(4, citation.colEnd()); } @Test public void getLineTextTest() { - assertEquals("lineText", citation.getLineText()); + assertEquals(lineText, citation.lineText()); } @Test public void getContextTest() { - assertEquals("lineText", citation.getContext()); + assertEquals(lineText, citation.getContext()); } @Test public void equalsTest() { - Citation citation1 = new Citation(path, 10, 1, 4, "lineText"); + Citation citation1 = new Citation(path, line, 1, 4, lineText); Citation citation2 = null; assertEquals(citation, citation1); assertNotEquals(citation, citation2);