Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write tests for import and export function #200

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3d4c560
FileUtil.java: Refactor for readability
jitwei98 Nov 10, 2018
aa0c810
Export.java: Rename saveFilteredAddressbook to saveFilteredPersons
jitwei98 Nov 10, 2018
d6ea7d1
FileUtilTest.java: Remove unused import
jitwei98 Nov 10, 2018
d382344
Pass data to export in an ObservableList instead of FilteredList in o…
jitwei98 Nov 10, 2018
4027640
Remove unused import
jitwei98 Nov 10, 2018
2b62539
ExportCommandParserTest.java: Update according to the new ExportComma…
jitwei98 Nov 10, 2018
26b2d86
ImportCommandParserTest.java: Create tests
jitwei98 Nov 10, 2018
e96474d
ImportCommand.java: Throw CommandException if file not found
jitwei98 Nov 10, 2018
3406ddc
ImportCommandParserTest.java: Modify MESSAGE_INVALID_FORMAT
jitwei98 Nov 10, 2018
cf7478d
CsvWriterTest.java: check if output file exists after calling write()
jitwei98 Nov 10, 2018
72ead57
ModelManagerTest.java: test importPersonsFromAddressBook() and export…
jitwei98 Nov 10, 2018
90dd121
ImportCommandTest.java: Write tests for ImportCommand
jitwei98 Nov 10, 2018
21bd22d
ImportCommandTest.java: Update according to ImportCommand implementation
jitwei98 Nov 10, 2018
8762c75
ModelManager.java: Check if the person exists in the addressbook befo…
jitwei98 Nov 10, 2018
efe1d54
ImportCommand.java#execute(): check the number of persons imported th…
jitwei98 Nov 10, 2018
734fe4e
ImportCommand.java: Commit AddressBook after import
jitwei98 Nov 11, 2018
d9032a5
ImportPersonsFromAddressBook(): only updateFilteredPersonList and ind…
jitwei98 Nov 11, 2018
0103e1e
ImportCommandTest.java: Compare commandResult only for now
jitwei98 Nov 11, 2018
e9f844e
Throw IllegalValueException when user wants to export an empty addres…
jitwei98 Nov 11, 2018
ea07f61
CsvWriterTest.java: Modify path of output file
jitwei98 Nov 11, 2018
cf52555
ExportManager.java: Fix styling
jitwei98 Nov 11, 2018
20c059d
ModelManagerTest.java#exportFilteredAddressBook(): Pass in exportPath…
jitwei98 Nov 11, 2018
24ef6e3
MModelManagerTest.java#exportFilteredAddressBook(): Rename export fil…
jitwei98 Nov 11, 2018
d3ccbae
ExportManagerTest.java: Write tests
jitwei98 Nov 11, 2018
edd21a5
ModelManagerTest.java: Write tests for importPersonsFromAddressBook()
jitwei98 Nov 11, 2018
768984b
ModelManagerTest.java: Use @Before to generate xml files to be import…
jitwei98 Nov 11, 2018
d144b4f
ImportManagerTest.java: Write tests for ImportManager
jitwei98 Nov 11, 2018
4d42aa5
ModelManager.java: Remove trailing whitespace
jitwei98 Nov 11, 2018
9875ea1
ImportManagerTest.java: Add negative test cases
jitwei98 Nov 11, 2018
badcf74
ImportCommandTest.java: Compare person list in addressbook after import
jitwei98 Nov 11, 2018
5449012
Add a new Import interface
jitwei98 Nov 11, 2018
e9b899f
CsvWriterTest.java: Remove testWriteToCsv()
jitwei98 Nov 11, 2018
d1424a4
ImportManager.java: Override readAddressBook()
jitwei98 Nov 11, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/main/java/seedu/address/commons/util/FileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ public static boolean isValidXmlFilename(String filename) {
}

// Compares the filename extension with the expected xml file extension
String filenameExtension = filename.substring(filename.length() - XML_FILE_EXTENSION.length());
return filenameExtension.equals(XML_FILE_EXTENSION);
int indexOfExtension = filename.length() - XML_FILE_EXTENSION.length();
String fileExtension = filename.substring(indexOfExtension);
String lowercaseFileExtension = fileExtension.toLowerCase();
return lowercaseFileExtension.equals(XML_FILE_EXTENSION);
}

/**
Expand Down
12 changes: 7 additions & 5 deletions src/main/java/seedu/address/export/Export.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import java.io.IOException;
import java.nio.file.Path;

import javafx.collections.transformation.FilteredList;
import javafx.collections.ObservableList;
import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.model.person.Person;

/**
Expand All @@ -14,13 +15,14 @@ public interface Export {
/**
* Saves the filteredPersons to the storage.
* @throws IOException if there was any problem writing to the file.
* @throws IllegalValueException if the current addressbook is empty.
*/
void saveFilteredAddressBook() throws IOException;
void saveFilteredPersons() throws IOException, IllegalValueException;

/**
* @see #saveFilteredAddressBook()
* @see #saveFilteredPersons()
*/
void saveFilteredAddressBook(FilteredList<Person> filteredPersons, Path filePath)
throws IOException;
void saveFilteredPersons(ObservableList<Person> filteredPersons, Path filePath)
throws IOException, IllegalValueException;

}
34 changes: 24 additions & 10 deletions src/main/java/seedu/address/export/ExportManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
import java.nio.file.Path;
import java.util.logging.Logger;

import javafx.collections.transformation.FilteredList;
import javafx.collections.ObservableList;
import seedu.address.commons.core.LogsCenter;
import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.commons.util.FileUtil;
import seedu.address.model.person.Person;
import seedu.address.storage.XmlFileStorage;
Expand All @@ -19,36 +20,49 @@
*/
public class ExportManager implements Export {

private static final String MESSAGE_NOTHING_TO_EXPORT = "There is nothing to export!";
private static final Logger logger = LogsCenter.getLogger(seedu.address.export.ExportManager.class);

private FilteredList<Person> filteredPersons;
private ObservableList<Person> filteredPersons;
private Path exportPath;

public ExportManager(FilteredList<Person> filteredPersons, Path filePath) {
public ExportManager(ObservableList<Person> filteredPersons, Path filePath) {
this.filteredPersons = filteredPersons;
this.exportPath = filePath;
}

public Path getExportPath() {
public Path getExportFilePath() {
return exportPath;
}


// TODO: add header in the interface header, refer to XmlAddressBookStorage
/**
* Saves the {@code filteredPersons} to the {@code exportPath}.
* @throws IOException if there was any problem writing to the file.
* @throws IllegalValueException if the current addressbook is empty.
*/
@Override
public void saveFilteredAddressBook() throws IOException {
saveFilteredAddressBook(filteredPersons, exportPath);
public void saveFilteredPersons() throws IOException, IllegalValueException {
saveFilteredPersons(filteredPersons, exportPath);
}

/**
* Similar to {@link #saveFilteredAddressBook()}
*
* @param filePath location of the data. Cannot be null
* Similar to {@link #saveFilteredPersons()}
* @param filteredPersons cannot be null.
* @param filePath file path of the data. Cannot be null
*/
@Override
public void saveFilteredAddressBook(FilteredList<Person> filteredPersons, Path filePath) throws IOException {
public void saveFilteredPersons(ObservableList<Person> filteredPersons, Path filePath)
throws IOException, IllegalValueException {
requireNonNull(filteredPersons);
requireNonNull(filePath);

if (filteredPersons.size() <= 0) {
logger.warning("There is nothing to export!");
throw new IllegalValueException(MESSAGE_NOTHING_TO_EXPORT);
}

if (FileUtil.isFileExists(filePath)) {
logger.fine("File exists. Overwriting output file: " + filePath.toString());
} else {
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/seedu/address/export/Import.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package seedu.address.export;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Optional;

import seedu.address.commons.exceptions.DataConversionException;
import seedu.address.model.ReadOnlyAddressBook;

//@@author jitwei98
/**
* The API of the Import component.
*/
public interface Import {

/**
* Returns the addressBook from the xml file specified.
* @throws DataConversionException if the file is not in the correct format.
* @throws FileNotFoundException if the file does not exist
*/
Optional<ReadOnlyAddressBook> readAddressBook() throws DataConversionException, IOException;

/**
* Similar to {@link #readAddressBook()}
* @param filePath location of the data. Cannot be null
*/
Optional<ReadOnlyAddressBook> readAddressBook(Path filePath) throws DataConversionException, FileNotFoundException;

}
11 changes: 3 additions & 8 deletions src/main/java/seedu/address/export/ImportManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
/**
* Manages importing of AddressBook data.
*/
public class ImportManager {
public class ImportManager implements Import {

private static final Logger logger = LogsCenter.getLogger(ImportManager.class);

Expand All @@ -35,17 +35,12 @@ public Path getImportPath() {
return importPath;
}

// @Override
@Override
public Optional<ReadOnlyAddressBook> readAddressBook() throws DataConversionException, IOException {
return readAddressBook(importPath);
}

/**
* Similar to {@link #readAddressBook()}
*
* @param filePath location of the data. Cannot be null
* @throws DataConversionException if the file is not in the correct format.
*/
@Override
public Optional<ReadOnlyAddressBook> readAddressBook(Path filePath) throws DataConversionException,
FileNotFoundException {
requireNonNull(filePath);
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/seedu/address/logic/commands/ExportCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.io.IOException;
import java.nio.file.Path;

import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.logic.CommandHistory;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
Expand All @@ -25,6 +26,7 @@ public class ExportCommand extends Command {

public static final String MESSAGE_EXPORT_SUCCESS = "Exported persons listed to %1$s";
public static final String MESSAGE_FAILURE = "Export failed!";
public static final String MESSAGE_FAILURE_EMPTY_AB = "There is nothing to export!";

private final Path filePath;

Expand All @@ -42,6 +44,8 @@ public CommandResult execute(Model model, CommandHistory history) throws Command
model.exportFilteredAddressBook(filePath);
} catch (IOException e) {
throw new CommandException(MESSAGE_FAILURE);
} catch (IllegalValueException e) {
throw new CommandException(MESSAGE_FAILURE_EMPTY_AB);
}

return new CommandResult(String.format(MESSAGE_EXPORT_SUCCESS, filePath));
Expand Down
16 changes: 14 additions & 2 deletions src/main/java/seedu/address/logic/commands/ImportCommand.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.FileUtil.isFileExists;

import java.io.IOException;
import java.nio.file.Path;

import javafx.collections.ObservableList;
import seedu.address.commons.exceptions.DataConversionException;
import seedu.address.logic.CommandHistory;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.ReadOnlyAddressBook;
import seedu.address.model.person.Person;

//@@author jitwei98
/**
Expand All @@ -26,6 +30,7 @@ public class ImportCommand extends Command {
public static final String MESSAGE_IMPORT_SUCCESS = "Imported %1$s persons.";
private static final String MESSAGE_FAILURE = "Import failed! Error: %1$s";
private static final String MESSAGE_INVALID_LIST_SIZE = "Invalid list size.";
private static final String MESSAGE_FILE_NOT_FOUND = "File not found!";

private final Path filePath;

Expand All @@ -39,7 +44,13 @@ public ImportCommand(Path filePath) {
public CommandResult execute(Model model, CommandHistory history) throws CommandException {
requireNonNull(model);

int initialNumberOfPersons = model.getFilteredPersonList().size();
ReadOnlyAddressBook readOnlyAddressBook = model.getAddressBook();
ObservableList<Person> personList = readOnlyAddressBook.getPersonList();
int initialNumberOfPersons = personList.size();

if (!isFileExists(filePath)) {
throw new CommandException(MESSAGE_FILE_NOT_FOUND);
}

// TODO: Write better Exception messages
try {
Expand All @@ -50,9 +61,10 @@ public CommandResult execute(Model model, CommandHistory history) throws Command
throw new CommandException(String.format(MESSAGE_FAILURE, dce));
}

int finalNumberOfPersons = model.getFilteredPersonList().size();
int finalNumberOfPersons = personList.size();
int personsImported = calculateImportedEntries(initialNumberOfPersons, finalNumberOfPersons);

model.commitAddressBook();
return new CommandResult(String.format(MESSAGE_IMPORT_SUCCESS, personsImported));
}

Expand Down
6 changes: 4 additions & 2 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import javafx.collections.ObservableList;
import seedu.address.commons.exceptions.DataConversionException;
import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.model.person.Person;
import seedu.address.model.tag.Tag;
import seedu.address.model.todo.Todo;
Expand Down Expand Up @@ -96,13 +97,14 @@ public interface Model {

/**
* Adds all the persons in {@code addressBookImported} to the current address book.
* @return hasChanged is true if the addressBook is modified, returns false otherwise.
*/
void addPersonsToAddressBook(ReadOnlyAddressBook addressBookToImported);
boolean addPersonsToAddressBook(ReadOnlyAddressBook addressBookToImported);

/**
* Exports the current filtered person list to a xml file at {@code exportFilePath}.
*/
void exportFilteredAddressBook(Path exportFilePath) throws IOException;
void exportFilteredAddressBook(Path exportFilePath) throws IOException, IllegalValueException;

/**
* Exports the current address book state to a .csv file.
Expand Down
32 changes: 20 additions & 12 deletions src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import java.io.IOException;
import java.nio.file.Path;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.logging.Logger;

Expand All @@ -15,9 +16,11 @@
import seedu.address.commons.core.LogsCenter;
import seedu.address.commons.events.model.AddressBookChangedEvent;
import seedu.address.commons.exceptions.DataConversionException;
import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.export.CsvWriter;
import seedu.address.export.Export;
import seedu.address.export.ExportManager;
import seedu.address.export.Import;
import seedu.address.export.ImportManager;
import seedu.address.model.person.Person;
import seedu.address.model.tag.Tag;
Expand Down Expand Up @@ -188,29 +191,34 @@ public void deleteTag(Tag tag) {
//=========== Import/ Export ==============================================================================
@Override
public void importPersonsFromAddressBook(Path importFilePath) throws IOException, DataConversionException {
ImportManager importManager = new ImportManager(importFilePath);
Import importManager = new ImportManager(importFilePath);
ReadOnlyAddressBook addressBookImported = importManager.readAddressBook().orElseThrow(IOException::new);
boolean hasChanged = addPersonsToAddressBook(addressBookImported);

// TODO: dont use null in orElse(), use orElseThrow()
ReadOnlyAddressBook addressBookImported = importManager.readAddressBook().orElse(null);
addPersonsToAddressBook(addressBookImported);

updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
indicateAddressBookChanged();
if (hasChanged) {
updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
indicateAddressBookChanged();
}
}

@Override
public void addPersonsToAddressBook(ReadOnlyAddressBook addressBookImported) {
public boolean addPersonsToAddressBook(ReadOnlyAddressBook addressBookImported) {
ObservableList<Person> persons = addressBookImported.getPersonList();
AtomicBoolean hasChanged = new AtomicBoolean(false);
persons.forEach((person) -> {
// TODO: explain why this instead of addPerson() above in developer guide (indicate ab changed at the end)
versionedAddressBook.addPerson(person);
if (!hasPerson(person)) {
hasChanged.set(true);
versionedAddressBook.addPerson(person);
}
});
return hasChanged.get();
}

@Override
public void exportFilteredAddressBook(Path exportFilePath) throws IOException {
Export export = new ExportManager(filteredPersons, exportFilePath);
export.saveFilteredAddressBook();
public void exportFilteredAddressBook(Path exportFilePath) throws IOException, IllegalValueException {
Export export = new ExportManager(getFilteredPersonList(), exportFilePath);
export.saveFilteredPersons();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import javafx.collections.transformation.FilteredList;
import javafx.collections.ObservableList;
import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.model.AddressBook;
import seedu.address.model.ReadOnlyAddressBook;
Expand Down Expand Up @@ -50,7 +50,7 @@ public XmlSerializableAddressBook(ReadOnlyAddressBook src) {
/**
* Conversion with filtered Persons instead of the whole address book.
*/
public XmlSerializableAddressBook(FilteredList<Person> filteredPersons) {
public XmlSerializableAddressBook(ObservableList<Person> filteredPersons) {
this();
persons.addAll(filteredPersons.stream().map(XmlAdaptedPerson::new).collect(Collectors.toList()));
}
Expand Down
21 changes: 21 additions & 0 deletions src/test/java/seedu/address/commons/util/FileUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,25 @@ public void isValidPath() {
Assert.assertThrows(NullPointerException.class, () -> FileUtil.isValidPath(null));
}

@Test
public void isValidXmlFilename() {
// valid xml filename
assertTrue(FileUtil.isValidXmlFilename("someXmlFile.xml"));
assertTrue(FileUtil.isValidXmlFilename("anotherXmlFile.xml"));
assertTrue(FileUtil.isValidXmlFilename("someXmlFile.XML"));

// invalid filename, not .xml
assertFalse(FileUtil.isValidXmlFilename("someXmlFile.pdf"));

// invalid filename, empty string
assertFalse(FileUtil.isValidXmlFilename(""));

// invalid filename, no extension
assertFalse(FileUtil.isValidXmlFilename("someXmlFile"));

// null filename -> throws NullPointerException
Assert.assertThrows(NullPointerException.class, () -> FileUtil.isValidXmlFilename(null));

}

}