Skip to content

Commit

Permalink
Adds testcases for export and import commands (#155)
Browse files Browse the repository at this point in the history
* Import from excel function

* Adds implementation for ExcelReader

* debug importExcel classes

* Check style for Import branch

* Reads csv file correctly

* Finished up import interviewers feature

* Integrated with Schedule class and removed ScheduleStub

* Handles import exceptions

* Corrected Styling

* Adds test for Import commands

* Corrects styling for Import Tests

* Rename ExcelReader to CsvReader

* handles exceptions for import interviewers

* Adds intervieweesList attribute to model

* Travis fix

* Travis fix

* Style fix

* UML Diagrams

* Update Developer's Guide

* Resized diagrams

* Resize diagrams

* Style fix

* Fixed styling issues in devdocs

* Updates import interviewer's feature

* Fix JSON parsing error

* Use a factory method instead to allow for IllegalArgumentException

* Import interviewee's data feature completed

* Fixed bugs

* Implements generateEmptyScheduleList feature

* Commit to pull

* Fix styling issues

* Fix styling issues

* Implement listener to Schedule data change

* Fix travis issue

* Fix bug in refreshing schedule

* Merged updated refreshlistener

* Updates user guide

* Update ImportCommand.java

* Add catch for exception for import command

* Update ImportCommand.java

* Added assertions

* Removes some bugs and updates userguide

* Fix style

* Adds test cases for import command and model manager

* Small change to remove whitespace

* Implements csv writer

* Refactors import command to use prefix format

* Updates Export Command

* Completes implementation of Export Command

* Updates userguide and debug tests

* Check style

* Added tests for Export and Import commands

* Style check

* Fixed testcases

* Fix testcases
  • Loading branch information
mirozo authored Nov 6, 2019
1 parent 839bed1 commit 6f121e9
Show file tree
Hide file tree
Showing 15 changed files with 274 additions and 8 deletions.
10 changes: 9 additions & 1 deletion src/main/java/seedu/scheduler/logic/commands/ClearCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import static java.util.Objects.requireNonNull;

import java.text.ParseException;
import java.util.List;

import seedu.scheduler.logic.commands.exceptions.CommandException;
import seedu.scheduler.model.Model;

/**
Expand All @@ -15,10 +17,16 @@ public class ClearCommand extends Command {
public static final String MESSAGE_SUCCESS = "List of Interviewees and Interviewers has been cleared!";

@Override
public CommandResult execute(Model model) {
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
model.setIntervieweeList(List.of());
model.setInterviewerList(List.of());
try {
model.setEmptyScheduleList();
model.setSchedulesList(model.getEmptyScheduleList());
} catch (ParseException pe) {
throw new CommandException("Could not regenerate table");
}
return new CommandResult(MESSAGE_SUCCESS);
}
}
14 changes: 13 additions & 1 deletion src/main/java/seedu/scheduler/logic/commands/ExportCommand.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
package seedu.scheduler.logic.commands;

import static seedu.scheduler.logic.parser.CliSyntax.PREFIX_FILE_PATH;

import java.io.IOException;

import seedu.scheduler.logic.commands.exceptions.CommandException;
import seedu.scheduler.model.FilePath;
import seedu.scheduler.model.Model;
import seedu.scheduler.model.util.CsvWriter;


/**
* Exports schedules to target .csv file.
*/

public class ExportCommand extends Command {
public static final String COMMAND_WORD = "export";
public static final String MESSAGE_USAGE = COMMAND_WORD + ": export schedules to specified .csv file. \n"
+ "Example: " + COMMAND_WORD + "<FULL_FILE_PATH>";
+ "Example: "
+ COMMAND_WORD
+ " " + PREFIX_FILE_PATH + " <FULL_FILE_PATH>";
public static final String SUCCESS_MESSAGE = "Data exported successfully.";
public static final String NOT_SCHEDULED_ERROR = "Interview slots have not been scheduled. Please ensure that "
+ "data has been imported and 'schedule' command has been ran.";
Expand Down Expand Up @@ -43,4 +48,11 @@ public CommandResult execute(Model model) throws CommandException {
throw new CommandException(ERROR_MESSAGE, ioe);
}
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof ExportCommand // instanceof handles nulls
&& destinationFile.equals(((ExportCommand) other).destinationFile));
}
}
16 changes: 15 additions & 1 deletion src/main/java/seedu/scheduler/logic/commands/ImportCommand.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package seedu.scheduler.logic.commands;

import static seedu.scheduler.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.scheduler.logic.parser.CliSyntax.PREFIX_FILE_PATH;

import java.io.FileNotFoundException;
import java.io.IOException;
Expand All @@ -27,7 +28,10 @@ public class ImportCommand extends Command {
public static final String COMMAND_WORD = "import";
public static final String MESSAGE_USAGE = COMMAND_WORD + ": Import .csv file containing "
+ "interviewer or interviewee's information.\n"
+ "Example: " + COMMAND_WORD + " interviewer " + "<csvFilePath>";
+ "Parameters: "
+ "Type of Data (Can be only interviewer or interviewee) "
+ PREFIX_FILE_PATH + "FILE_PATH \n"
+ "Example: " + COMMAND_WORD + " interviewer " + PREFIX_FILE_PATH + "C:\\Users\\john\\Desktop\\test.csv";
public static final String SUCCESS_MESSAGE = "Data imported successfully.";
public static final String MESSAGE_NOT_IMPLEMENTED_YET = "Command not implemented yet";
public static final String INCORRECT_FORMAT = "Data is in incorrect format. Please refer to the "
Expand Down Expand Up @@ -61,6 +65,7 @@ public CommandResult execute(Model model) throws CommandException {
for (Interviewer interviewer: interviewers) {
model.addInterviewer(interviewer);
}
model.setScheduled(false);
return new CommandResult(SUCCESS_MESSAGE, false, false);
} else if (type.getRole().equals(RoleType.INTERVIEWEE)) {
CsvReader csvReader = new CsvReader(filePath.getValue());
Expand All @@ -71,6 +76,7 @@ public CommandResult execute(Model model) throws CommandException {
for (Interviewee interviewee: interviewees) {
model.addInterviewee(interviewee);
}
model.setScheduled(false);
return new CommandResult(SUCCESS_MESSAGE, false, false);
} else {
throw new CommandException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, MESSAGE_USAGE));
Expand Down Expand Up @@ -115,4 +121,12 @@ private static String stringifyInterviewees(ArrayList<Interviewee> interviewees)
}
return resultBuilder.toString();
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof ImportCommand // instanceof handles nulls
&& type.equals(((ImportCommand) other).type)
&& filePath.equals(((ImportCommand) other).filePath));
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package seedu.scheduler.logic.parser;

import static seedu.scheduler.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.scheduler.logic.commands.ImportCommand.MESSAGE_USAGE;
import static seedu.scheduler.logic.commands.ExportCommand.MESSAGE_USAGE;
import static seedu.scheduler.logic.parser.CliSyntax.PREFIX_FILE_PATH;

import seedu.scheduler.logic.commands.ExportCommand;
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/seedu/scheduler/model/FilePath.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,12 @@ public boolean exists() {
public String toString() {
return value;
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof FilePath // instanceof handles nulls
&& value.equals(((FilePath) other).value)); // state check
}

}
3 changes: 2 additions & 1 deletion src/main/java/seedu/scheduler/model/util/CsvReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ public static Department getInterviewerDepartment(String cell) {
* @param date Date of availability
*/
public static void updateInterviewersSlotsFromData(ArrayList<Interviewer> interviewers,
String[] rowData, String date) {
String[] rowData, String date) {

String timing = rowData[0];
String startTime = getStartTime(timing);
String endTime = getEndTime(timing);
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/seedu/scheduler/model/util/CsvWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javafx.collections.ObservableList;
Expand All @@ -27,22 +28,30 @@ public CsvWriter(String destinationFile, Model model) {

/**
* Writes current scheduleList from model into destination file.
* @return ArrayList of exported table for testing purposes.
* @throws IOException when FileWriter fails.
*/
public void writeSchedulesToFile() throws IOException {
public ArrayList<String> writeSchedulesToFile() throws IOException {
FileWriter csvWriter = new FileWriter(destinationFile);
List<Schedule> schedules = model.getSchedulesList();
ArrayList<String> table = new ArrayList<>();
for (Schedule schedule: schedules) {
ObservableList<ObservableList<String>> rows = schedule.getObservableList();
csvWriter.append(String.join(",", schedule.getTitles()));
csvWriter.append("\n");

table.add(String.join(",", schedule.getTitles()));

for (ObservableList<String> rowData: rows) {
csvWriter.append(String.join(",", rowData));
csvWriter.append("\n");

table.add(String.join(",", rowData));
}
csvWriter.append("\n").append("\n");
}
csvWriter.flush();
csvWriter.close();
return table;
}
}
9 changes: 9 additions & 0 deletions src/test/data/ImportsTest/storage.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
10/09/2019,Welfare - Hazel,Technical - Johnathan,Publicity - Lucia
18:00-18:30,John,Steven,0
18:30-19:00,Alex,Clark,John
19:00-19:30,Alicia,0,charlie
19:30-20:00,Charlie,0,Selina
20:00-20:30,Selina,0,0
20:30-21:00,Natal,0,0


21 changes: 21 additions & 0 deletions src/test/java/seedu/scheduler/logic/commands/CommandTestUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static seedu.scheduler.logic.parser.CliSyntax.PREFIX_DEPARTMENT;
import static seedu.scheduler.logic.parser.CliSyntax.PREFIX_FACULTY;
import static seedu.scheduler.logic.parser.CliSyntax.PREFIX_FILE_PATH;
import static seedu.scheduler.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.scheduler.logic.parser.CliSyntax.PREFIX_NUS_WORK_EMAIL;
import static seedu.scheduler.logic.parser.CliSyntax.PREFIX_PERSONAL_EMAIL;
Expand Down Expand Up @@ -54,6 +55,7 @@ public class CommandTestUtil {
public static final String VALID_NUS_WORK_EMAIL_AMY = "amy_infamy@u.nus.edu";
public static final String VALID_PERSONAL_EMAIL_BOB = "bob_cat@gmail.com";
public static final String VALID_NUS_WORK_EMAIL_BOB = "bob_cat@u.nus.edu";
public static final String VALID_FILE_PATH = "src/test/data/ImportsTest/storage.csv";

public static final String ROLE_DESC_AMY_INTVR = " " + PREFIX_ROLE + VALID_ROLE_AMY_INTVR;
public static final String ROLE_DESC_BOB_INTVE = " " + PREFIX_ROLE + VALID_ROLE_BOB_INTVE;
Expand All @@ -75,6 +77,7 @@ public class CommandTestUtil {
public static final String EMAIL_NUS_WORK_DESC_AMY = " " + PREFIX_NUS_WORK_EMAIL + VALID_NUS_WORK_EMAIL_AMY;
public static final String EMAIL_PERSONAL_DESC_BOB = " " + PREFIX_PERSONAL_EMAIL + VALID_PERSONAL_EMAIL_BOB;
public static final String EMAIL_NUS_WORK_DESC_BOB = " " + PREFIX_NUS_WORK_EMAIL + VALID_NUS_WORK_EMAIL_BOB;
public static final String FILE_PATH_DESC = " " + PREFIX_FILE_PATH + VALID_FILE_PATH;

public static final String INVALID_NAME_DESC = " " + PREFIX_NAME + "James&"; // '&' not allowed in names
public static final String INVALID_PHONE_DESC = " " + PREFIX_PHONE + "911a"; // 'a' not allowed in phones
Expand All @@ -85,6 +88,8 @@ public class CommandTestUtil {
public static final String INVALID_SLOT_DESC = " " + PREFIX_SLOT + "123456"; // invalid format
public static final String INVALID_PERSONAL_EMAIL_DESC = " " + PREFIX_PERSONAL_EMAIL + "bool sheet";
public static final String INVALID_NUS_WORK_EMAIL_DESC = " " + PREFIX_NUS_WORK_EMAIL + "long dong";
public static final String INVALID_FILE_PATH_DESC = " " + PREFIX_FILE_PATH
+ "src/test/data/ImportsTest/InterviewerInvalidTestData.csv";

public static final String PREAMBLE_WHITESPACE = "\t \r \n";
public static final String PREAMBLE_NON_EMPTY = "NonEmptyPreamble";
Expand Down Expand Up @@ -184,4 +189,20 @@ public static void showInterviewerWithName(Model model, Name name) {
throw new AssertionError("Name should exist in the model beforehand!");
}
}

/**
* Generates test data for export command.
* @return expected results for export function.
*/
public static ArrayList<String> getExpectedExportedData() {
ArrayList<String> exportedData = new ArrayList<>();
exportedData.add("10/09/2019,Welfare - Hazel,Technical - Johnathan,Publicity - Lucia");
exportedData.add("18:00-18:30,John,Steven,0");
exportedData.add("18:30-19:00,Alex,Clark,John");
exportedData.add("19:00-19:30,Alicia,0,charlie");
exportedData.add("19:30-20:00,Charlie,0,Selina");
exportedData.add("20:00-20:30,Selina,0,0");
exportedData.add("20:30-21:00,Natal,0,0");
return exportedData;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package seedu.scheduler.logic.commands;

import static seedu.scheduler.logic.commands.CommandTestUtil.assertCommandFailure;
import static seedu.scheduler.logic.commands.CommandTestUtil.assertCommandSuccess;

import org.junit.jupiter.api.Test;

import seedu.scheduler.model.FilePath;
import seedu.scheduler.model.Model;
import seedu.scheduler.model.ModelManager;


public class ExportCommandTest {
public static final String DESTINATION_FILE = "src/test/data/ImportsTest/storage.csv";
private static Model model = new ModelManager();

@Test
public void execute_exportCommand_success() {
ExportCommand exportCommand = new ExportCommand(new FilePath(DESTINATION_FILE));
CommandResult expectedCommandResult = new CommandResult(ExportCommand.SUCCESS_MESSAGE, false, false);
model.setScheduled(true);
assertCommandSuccess(exportCommand, model, expectedCommandResult, model);
}

@Test
public void execute_exportCommand_throwsCommandException() {
ExportCommand exportCommand = new ExportCommand(new FilePath(DESTINATION_FILE));
model.setScheduled(false);
assertCommandFailure(exportCommand, model, ExportCommand.NOT_SCHEDULED_ERROR);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static seedu.scheduler.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.scheduler.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND;
import static seedu.scheduler.logic.commands.ImportCommand.FILE_DOES_NOT_EXIST;
import static seedu.scheduler.logic.parser.CliSyntax.PREFIX_FILE_PATH;
import static seedu.scheduler.logic.parser.CliSyntax.PREFIX_ROLE;
import static seedu.scheduler.testutil.Assert.assertThrows;
import static seedu.scheduler.testutil.TypicalPersons.ALICE_INTERVIEWEE;
Expand All @@ -23,8 +25,10 @@
import seedu.scheduler.logic.commands.EditIntervieweeCommand;
import seedu.scheduler.logic.commands.EmailCommand;
import seedu.scheduler.logic.commands.ExitCommand;
import seedu.scheduler.logic.commands.ExportCommand;
import seedu.scheduler.logic.commands.FindCommand;
import seedu.scheduler.logic.commands.HelpCommand;
import seedu.scheduler.logic.commands.ImportCommand;
import seedu.scheduler.logic.commands.ListCommand;
import seedu.scheduler.logic.parser.exceptions.ParseException;
import seedu.scheduler.model.person.Interviewee;
Expand Down Expand Up @@ -113,6 +117,71 @@ public void parseCommand_email() throws Exception {
EmailCommand.COMMAND_WORD + " ct/timeslot n/Alice") instanceof EmailCommand);
}

@Test
public void parseCommand_import() throws Exception {
assertThrows(ParseException.class,
String.format(MESSAGE_INVALID_COMMAND_FORMAT, ImportCommand.MESSAGE_USAGE), ()
-> parser.parseCommand(ImportCommand.COMMAND_WORD));
//No File Path, interviewer
assertThrows(ParseException.class,
String.format(MESSAGE_INVALID_COMMAND_FORMAT, ImportCommand.MESSAGE_USAGE), ()
-> parser.parseCommand(ImportCommand.COMMAND_WORD + " interviewer"));
//No File Path, interviewee
assertThrows(ParseException.class,
String.format(MESSAGE_INVALID_COMMAND_FORMAT, ImportCommand.MESSAGE_USAGE), ()
-> parser.parseCommand(ImportCommand.COMMAND_WORD + " interviewee"));
//No prefix, interviewee
assertThrows(ParseException.class,
String.format(MESSAGE_INVALID_COMMAND_FORMAT, ImportCommand.MESSAGE_USAGE), ()
-> parser.parseCommand(ImportCommand.COMMAND_WORD
+ " interviewer src/test/data/ImportsTest/InterviewerTestData.csv"));
//No prefix, interviewee
assertThrows(ParseException.class,
String.format(MESSAGE_INVALID_COMMAND_FORMAT, ImportCommand.MESSAGE_USAGE), ()
-> parser.parseCommand(ImportCommand.COMMAND_WORD
+ " interviewee src/test/data/ImportsTest/InterviewerTestData.csv"));
//No type
assertThrows(ParseException.class,
String.format(MESSAGE_INVALID_COMMAND_FORMAT, ImportCommand.MESSAGE_USAGE), ()
-> parser.parseCommand(ImportCommand.COMMAND_WORD
+ " " + PREFIX_FILE_PATH + "src/test/data/ImportsTest/InterviewerTestData.csv"));
//File does not exist
assertThrows(ParseException.class,
FILE_DOES_NOT_EXIST, () -> parser.parseCommand(ImportCommand.COMMAND_WORD
+ " interviewer " + PREFIX_FILE_PATH + "src/test/data/ImportsTest/InterviewerInvalidTestData.csv"));
//Success
assertTrue(parser.parseCommand(
ImportCommand.COMMAND_WORD
+ " interviewer " + PREFIX_FILE_PATH + "src/test/data/ImportsTest/InterviewerTestData.csv")
instanceof ImportCommand);
//Success
assertTrue(parser.parseCommand(
ImportCommand.COMMAND_WORD
+ " interviewee " + PREFIX_FILE_PATH + "src/test/data/ImportsTest/InterviewerTestData.csv")
instanceof ImportCommand);
}

@Test
public void parseCommand_export() throws Exception {
assertTrue(parser.parseCommand(ExportCommand.COMMAND_WORD
+ " " + PREFIX_FILE_PATH + "src/test/data/ImportsTest/storage.csv")
instanceof ExportCommand);
//File does not exist, still works, should create a new file.
assertTrue(parser.parseCommand(
ExportCommand.COMMAND_WORD
+ " " + PREFIX_FILE_PATH + "src/test/data/ImportsTest/InvalidTestData.csv")
instanceof ExportCommand);
//No prefix
assertThrows(ParseException.class,
String.format(MESSAGE_INVALID_COMMAND_FORMAT, ExportCommand.MESSAGE_USAGE), ()
-> parser.parseCommand(ExportCommand.COMMAND_WORD
+ " src/test/data/ImportsTest/storage.csv"));
//Only command word
assertThrows(ParseException.class,
String.format(MESSAGE_INVALID_COMMAND_FORMAT, ExportCommand.MESSAGE_USAGE), ()
-> parser.parseCommand(ExportCommand.COMMAND_WORD));
}

@Test
public void parseCommand_unrecognisedInput_throwsParseException() {
assertThrows(ParseException.class, String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE), ()
Expand All @@ -121,6 +190,7 @@ public void parseCommand_unrecognisedInput_throwsParseException() {

@Test
public void parseCommand_unknownCommand_throwsParseException() {
assertThrows(ParseException.class, MESSAGE_UNKNOWN_COMMAND, () -> parser.parseCommand("unknownCommand"));
assertThrows(ParseException.class,
MESSAGE_UNKNOWN_COMMAND, () -> parser.parseCommand("unknownCommand"));
}
}
Loading

0 comments on commit 6f121e9

Please sign in to comment.