diff --git a/src/main/java/peoplesoft/commons/core/JobIdFactory.java b/src/main/java/peoplesoft/commons/core/JobIdFactory.java index baa59782d78..1ee44810339 100644 --- a/src/main/java/peoplesoft/commons/core/JobIdFactory.java +++ b/src/main/java/peoplesoft/commons/core/JobIdFactory.java @@ -13,7 +13,6 @@ public class JobIdFactory { * * @return JobId. */ - // TODO: currently missing functionality with serdes public static ID nextId() { return new ID(++id); } diff --git a/src/main/java/peoplesoft/commons/core/Messages.java b/src/main/java/peoplesoft/commons/core/Messages.java index 08c10b79104..57c8653924f 100644 --- a/src/main/java/peoplesoft/commons/core/Messages.java +++ b/src/main/java/peoplesoft/commons/core/Messages.java @@ -7,7 +7,9 @@ public class Messages { public static final String MESSAGE_UNKNOWN_COMMAND = "Unknown command"; public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s"; - public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid"; + public static final String MESSAGE_INVALID_JOB_DISPLAYED_INDEX = "Invalid index for job"; + public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "Invalid index for person"; public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!"; + public static final String MESSAGE_JOBS_LISTED_OVERVIEW = "%1$d jobs listed!"; } diff --git a/src/main/java/peoplesoft/commons/core/PersonIdFactory.java b/src/main/java/peoplesoft/commons/core/PersonIdFactory.java index 42b05248316..619ed6919ab 100644 --- a/src/main/java/peoplesoft/commons/core/PersonIdFactory.java +++ b/src/main/java/peoplesoft/commons/core/PersonIdFactory.java @@ -13,7 +13,6 @@ public class PersonIdFactory { * * @return JobId. */ - // TODO: currently missing functionality with serdes public static ID nextId() { return new ID(++id); } diff --git a/src/main/java/peoplesoft/commons/core/index/Index.java b/src/main/java/peoplesoft/commons/core/index/Index.java index a9dcec46da4..14b626de756 100644 --- a/src/main/java/peoplesoft/commons/core/index/Index.java +++ b/src/main/java/peoplesoft/commons/core/index/Index.java @@ -9,6 +9,8 @@ * convert it back to an int if the index will not be passed to a different component again. */ public class Index { + public static final String MESSAGE_CONSTRAINTS = "Index should be a non-zero positive integer."; + private int zeroBasedIndex; /** @@ -45,6 +47,11 @@ public static Index fromOneBased(int oneBasedIndex) { return new Index(oneBasedIndex - 1); } + @Override + public int hashCode() { + return Integer.hashCode(zeroBasedIndex); + } + @Override public boolean equals(Object other) { return other == this // short circuit if same object diff --git a/src/main/java/peoplesoft/logic/commands/DeleteCommand.java b/src/main/java/peoplesoft/logic/commands/DeleteCommand.java index dd20c831e72..4ec0d392c8a 100644 --- a/src/main/java/peoplesoft/logic/commands/DeleteCommand.java +++ b/src/main/java/peoplesoft/logic/commands/DeleteCommand.java @@ -20,7 +20,7 @@ public class DeleteCommand extends Command { public static final String MESSAGE_USAGE = COMMAND_WORD + ": Deletes the person identified by the index number used in the displayed person list.\n" - + "Parameters: INDEX (must be a positive integer)\n" + + "Parameters: PERSON_INDEX (must be a positive integer)\n" + "Example: " + COMMAND_WORD + " 1"; public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s"; diff --git a/src/main/java/peoplesoft/logic/commands/EditCommand.java b/src/main/java/peoplesoft/logic/commands/EditCommand.java index 2c9ed067bf6..b304e982dfa 100644 --- a/src/main/java/peoplesoft/logic/commands/EditCommand.java +++ b/src/main/java/peoplesoft/logic/commands/EditCommand.java @@ -41,7 +41,7 @@ public class EditCommand extends Command { public static final String MESSAGE_USAGE = COMMAND_WORD + ": Edits the details of the person identified " + "by the index number used in the displayed person list. " + "Existing values will be overwritten by the input values.\n" - + "Parameters: INDEX (must be a positive integer) " + + "Parameters: PERSON_INDEX (must be a positive integer) " + "[" + PREFIX_NAME + "NAME] " + "[" + PREFIX_PHONE + "PHONE] " + "[" + PREFIX_EMAIL + "EMAIL] " diff --git a/src/main/java/peoplesoft/logic/commands/job/JobAddCommand.java b/src/main/java/peoplesoft/logic/commands/job/JobAddCommand.java index c21dbde921c..8e8bee1f1c6 100644 --- a/src/main/java/peoplesoft/logic/commands/job/JobAddCommand.java +++ b/src/main/java/peoplesoft/logic/commands/job/JobAddCommand.java @@ -9,7 +9,6 @@ import peoplesoft.logic.commands.CommandResult; import peoplesoft.logic.commands.exceptions.CommandException; import peoplesoft.logic.parser.exceptions.ParseException; -import peoplesoft.logic.parser.job.JobAddCommandParser; import peoplesoft.model.Model; import peoplesoft.model.job.Job; @@ -18,12 +17,10 @@ */ public class JobAddCommand extends Command { - // TODO: change if needed public static final String COMMAND_WORD = "job"; public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a job to the database. " + "Parameters: " - + "[JOBID] " + PREFIX_NAME + "NAME " + PREFIX_RATE + "RATE " + PREFIX_DURATION + "DURATION "; @@ -34,14 +31,14 @@ public class JobAddCommand extends Command { private final Job toAdd; /** - * Creates a {@code JobAddCommand} to add a {@code Job} parsed from the arguments. + * Creates a {@code JobAddCommand} to add a {@code Job}. * - * @param args Arguments. + * @param toAdd Job. * @throws ParseException Thrown if there is an error with parsing. */ - public JobAddCommand(String args) throws ParseException { - requireNonNull(args); - toAdd = new JobAddCommandParser().parse(args); + public JobAddCommand(Job toAdd) { + requireNonNull(toAdd); + this.toAdd = toAdd; } @Override diff --git a/src/main/java/peoplesoft/logic/commands/job/JobAssignCommand.java b/src/main/java/peoplesoft/logic/commands/job/JobAssignCommand.java index 87971d93b6e..aa43b84c2f6 100644 --- a/src/main/java/peoplesoft/logic/commands/job/JobAssignCommand.java +++ b/src/main/java/peoplesoft/logic/commands/job/JobAssignCommand.java @@ -1,102 +1,128 @@ package peoplesoft.logic.commands.job; import static java.util.Objects.requireNonNull; -import static peoplesoft.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static peoplesoft.commons.util.CollectionUtil.requireAllNonNull; import static peoplesoft.logic.parser.CliSyntax.PREFIX_INDEX; +import java.util.HashSet; import java.util.List; +import java.util.Set; import peoplesoft.commons.core.Messages; import peoplesoft.commons.core.index.Index; import peoplesoft.logic.commands.Command; import peoplesoft.logic.commands.CommandResult; import peoplesoft.logic.commands.exceptions.CommandException; -import peoplesoft.logic.parser.ArgumentMultimap; -import peoplesoft.logic.parser.ParserUtil; -import peoplesoft.logic.parser.exceptions.ParseException; -import peoplesoft.logic.parser.job.JobAssignCommandParser; import peoplesoft.model.Model; import peoplesoft.model.employment.Employment; import peoplesoft.model.employment.exceptions.DuplicateEmploymentException; import peoplesoft.model.job.Job; import peoplesoft.model.person.Person; -import peoplesoft.model.util.ID; /** * Assigns a {@code Job} to a {@code Person}. */ public class JobAssignCommand extends Command { - //TODO: change if needed public static final String COMMAND_WORD = "assign"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Assigns a job to a person. " + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Assigns a job to one or more person(s). " + "Parameters: " - + "JOBID " - + PREFIX_INDEX + "INDEX "; + + "JOB_INDEX " + + PREFIX_INDEX + "PERSON_INDEX [PERSON_INDEX]..."; - public static final String MESSAGE_SUCCESS = "Assigned Job %s to %s\n%s has the following jobs: %s"; - public static final String MESSAGE_JOB_NOT_FOUND = "This job does not exist"; - public static final String MESSAGE_DUPLICATE_EMPLOYMENT = "This person is already assigned to this job"; + public static final String MESSAGE_SUCCESS = "Assigned Job %s to %s."; + public static final String MESSAGE_DUPLICATE_EMPLOYMENT = + "%s person(s) have already been assigned to this job."; - private ID jobId; - private Index personIndex; + private Index jobIndex; + private Set personIndexes; + private Employment instance; /** - * Creates a {@code JobAssignCommand} to assign a {@code Job} to a {@code Person}. + * Creates a {@code JobAssignCommand} to assign a {@code Job} to a set of {@code Person}s. * - * @param args Arguments. - * @throws ParseException Thrown if there is an error with parsing. + * @param jobIndex Index of the job. + * @param personIndexes Set of indexes of persons + * @param employment Employment to use (for easier testing) */ - public JobAssignCommand(String args) throws ParseException { - requireNonNull(args); - parseArgs(args); + public JobAssignCommand(Index jobIndex, Set personIndexes, Employment employment) { + requireAllNonNull(jobIndex, personIndexes, employment); + this.jobIndex = jobIndex; + this.personIndexes = personIndexes; + this.instance = employment; } - private void parseArgs(String args) throws ParseException { - // TODO: Arguably does not follow SRP/LoD - ArgumentMultimap argumentMultimap = new JobAssignCommandParser().parse(args); - try { - jobId = new ID(ParserUtil.parseString(argumentMultimap.getPreamble())); - } catch (IllegalArgumentException e) { // from ID constructor - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, - JobAssignCommand.MESSAGE_USAGE)); - } - personIndex = ParserUtil.parseIndex(argumentMultimap.getValue(PREFIX_INDEX).get()); - } - - // TODO: Change implementation if needed. @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); + List lastShownJobs = model.getFilteredJobList(); + List lastShownPersons = model.getFilteredPersonList(); + + if (jobIndex.getZeroBased() >= lastShownJobs.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_JOB_DISPLAYED_INDEX); + } - if (!model.hasJob(jobId)) { - throw new CommandException(MESSAGE_JOB_NOT_FOUND); + for (Index i : personIndexes) { + if (i.getZeroBased() >= lastShownPersons.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + } } - List lastShownList = model.getFilteredPersonList(); + Job job = lastShownJobs.get(jobIndex.getZeroBased()); + Set persons = getPersons(personIndexes, lastShownPersons); + + int dupeCount = 0; + StringBuilder stringPersons = new StringBuilder(); - if (personIndex.getZeroBased() >= lastShownList.size()) { - throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + for (Person p : persons) { + try { + instance.associate(job, p); + stringPersons.append(p.getName()).append(", "); + } catch (DuplicateEmploymentException e) { + dupeCount++; + } + } + if (stringPersons.length() > 0) { + stringPersons.delete(stringPersons.length() - 2, stringPersons.length()); + } + String successPersons = stringPersons.toString(); + + if (dupeCount > 0) { + if (successPersons.isBlank()) { + throw new CommandException(String.format(MESSAGE_DUPLICATE_EMPLOYMENT, dupeCount)); + } else { + throw new CommandException(String.format(MESSAGE_DUPLICATE_EMPLOYMENT, dupeCount) + "\n" + + String.format(MESSAGE_SUCCESS, job.getDesc(), successPersons)); + } } - Person person = lastShownList.get(personIndex.getZeroBased()); - try { - // TODO: This code breaks LoD. - Job assignedJob = model.getAddressBook().getJobList() - .filtered(job -> job.getJobId().equals(jobId)).get(0); - Employment.getInstance().associate(assignedJob, person); - } catch (IndexOutOfBoundsException e) { - // Asserts that filtered list should always contain exactly the filtered element - assert false; - } catch (DuplicateEmploymentException e) { - throw new CommandException(MESSAGE_DUPLICATE_EMPLOYMENT); + return new CommandResult(String.format(MESSAGE_SUCCESS, job.getDesc(), successPersons)); + } + + private Set getPersons(Set personIndexes, List personList) { + Set persons = new HashSet<>(); + for (Index i : personIndexes) { + persons.add(personList.get(i.getZeroBased())); } + return persons; + } - List jobs = Employment.getInstance().getJobs(person, model); + @Override + public boolean equals(Object other) { + // short circuit if same object + if (other == this) { + return true; + } + + // instanceof handles nulls + if (!(other instanceof JobAssignCommand)) { + return false; + } - // TODO: For now just prints a list of the jobs associated with a person to console. - return new CommandResult(String.format(MESSAGE_SUCCESS, jobId, person.getName(), - person.getName(), jobs)); + // state check + JobAssignCommand c = (JobAssignCommand) other; + return jobIndex.equals(c.jobIndex) + && personIndexes.equals(c.personIndexes); } } diff --git a/src/main/java/peoplesoft/logic/commands/job/JobDeleteCommand.java b/src/main/java/peoplesoft/logic/commands/job/JobDeleteCommand.java index 3c824766b80..27ee845cb03 100644 --- a/src/main/java/peoplesoft/logic/commands/job/JobDeleteCommand.java +++ b/src/main/java/peoplesoft/logic/commands/job/JobDeleteCommand.java @@ -2,68 +2,58 @@ import static java.util.Objects.requireNonNull; -import java.time.Duration; +import java.util.List; +import peoplesoft.commons.core.Messages; +import peoplesoft.commons.core.index.Index; import peoplesoft.logic.commands.Command; import peoplesoft.logic.commands.CommandResult; import peoplesoft.logic.commands.exceptions.CommandException; -import peoplesoft.logic.parser.exceptions.ParseException; -import peoplesoft.logic.parser.job.JobDeleteCommandParser; import peoplesoft.model.Model; import peoplesoft.model.employment.Employment; import peoplesoft.model.job.Job; -import peoplesoft.model.job.Money; -import peoplesoft.model.job.Rate; -import peoplesoft.model.util.ID; /** * Deletes a {@code Job} with a given {@code JobId}. */ public class JobDeleteCommand extends Command { - //TODO: change if needed public static final String COMMAND_WORD = "jobdelete"; public static final String MESSAGE_USAGE = COMMAND_WORD - + ": Deletes the job identified by the job ID.\n" - + "Parameters: JOBID\n" + + ": Deletes the job identified by the index.\n" + + "Parameters: JOB_INDEX\n" + "Example: " + COMMAND_WORD + " 1"; public static final String MESSAGE_SUCCESS = "Deleted Job: %s"; - public static final String MESSAGE_JOB_NOT_FOUND = "This job does not exist"; - private final ID toDelete; + private final Index toDelete; /** - * Creates a {@code JobDeleteCommand} to delete a {@code Job} by {@code JobId}. + * Creates a {@code JobDeleteCommand} to delete a {@code Job} by {@code Index}. * - * @param args Arguments. - * @throws ParseException Thrown if there is an error with parsing. + * @param toDelete Index of job to delete. */ - public JobDeleteCommand(String args) throws ParseException { - requireNonNull(args); - toDelete = new JobDeleteCommandParser().parse(args); + public JobDeleteCommand(Index toDelete) { + requireNonNull(toDelete); + this.toDelete = toDelete; } @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); + List lastShownList = model.getFilteredJobList(); - if (!model.hasJob(toDelete)) { - throw new CommandException(MESSAGE_JOB_NOT_FOUND); + if (toDelete.getZeroBased() >= lastShownList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_JOB_DISPLAYED_INDEX); } - try { - Job jobToDelete = new Job(toDelete, "empty", - new Rate(new Money(1), Duration.ofHours(1)), Duration.ofHours(1), false); - // Currently handles deletions in JobList implementation (by jobId) - model.deleteJob(jobToDelete); - Employment.getInstance().deleteJob(jobToDelete); - } catch (IndexOutOfBoundsException e) { - // Asserts that filtered list should always contain exactly the filtered element - assert false; - } - return new CommandResult(String.format(MESSAGE_SUCCESS, toDelete)); + Job jobToDelete = lastShownList.get(toDelete.getZeroBased()); + model.deleteJob(jobToDelete); + // Deletes employment associations + Employment.getInstance().deleteJob(jobToDelete); + + return new CommandResult(String.format(MESSAGE_SUCCESS, jobToDelete.getDesc())); } @Override diff --git a/src/main/java/peoplesoft/logic/commands/job/JobFindCommand.java b/src/main/java/peoplesoft/logic/commands/job/JobFindCommand.java new file mode 100644 index 00000000000..cc93a74b91f --- /dev/null +++ b/src/main/java/peoplesoft/logic/commands/job/JobFindCommand.java @@ -0,0 +1,40 @@ +package peoplesoft.logic.commands.job; + +import static java.util.Objects.requireNonNull; + +import peoplesoft.commons.core.Messages; +import peoplesoft.logic.commands.Command; +import peoplesoft.logic.commands.CommandResult; +import peoplesoft.model.Model; +import peoplesoft.model.job.JobContainsKeywordsPredicate; + +public class JobFindCommand extends Command { + + public static final String COMMAND_WORD = "jobfind"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all jobs whose description contain any of " + + "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n" + + "Parameters: KEYWORD [MORE_KEYWORDS]...\n" + + "Example: " + COMMAND_WORD + " electric aircon appliances"; + + private final JobContainsKeywordsPredicate predicate; + + public JobFindCommand(JobContainsKeywordsPredicate predicate) { + this.predicate = predicate; + } + + @Override + public CommandResult execute(Model model) { + requireNonNull(model); + model.updateFilteredJobList(predicate); + return new CommandResult( + String.format(Messages.MESSAGE_JOBS_LISTED_OVERVIEW, model.getFilteredJobList().size())); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof JobFindCommand // instanceof handles nulls + && predicate.equals(((JobFindCommand) other).predicate)); // state check + } +} diff --git a/src/main/java/peoplesoft/logic/commands/job/JobMarkCommand.java b/src/main/java/peoplesoft/logic/commands/job/JobMarkCommand.java index e4160a37ec3..6fe0f79ce9a 100644 --- a/src/main/java/peoplesoft/logic/commands/job/JobMarkCommand.java +++ b/src/main/java/peoplesoft/logic/commands/job/JobMarkCommand.java @@ -2,71 +2,65 @@ import static java.util.Objects.requireNonNull; +import java.util.List; + +import peoplesoft.commons.core.Messages; +import peoplesoft.commons.core.index.Index; import peoplesoft.logic.commands.Command; import peoplesoft.logic.commands.CommandResult; import peoplesoft.logic.commands.exceptions.CommandException; -import peoplesoft.logic.parser.exceptions.ParseException; -import peoplesoft.logic.parser.job.JobMarkCommandParser; import peoplesoft.model.Model; import peoplesoft.model.job.Job; -import peoplesoft.model.util.ID; /** * Marks a {@code Job} as paid or unpaid. */ public class JobMarkCommand extends Command { - // TODO: change if needed public static final String COMMAND_WORD = "mark"; public static final String MESSAGE_USAGE = COMMAND_WORD + ": Marks the job identified by the index number used in the displayed job list.\n" - + "Parameters: JOBID\n" + + "Parameters: JOB_INDEX\n" + "Example: " + COMMAND_WORD + " 1"; public static final String MESSAGE_SUCCESS = "Marked Job %s as %s"; public static final String MESSAGE_JOB_NOT_FOUND = "This job does not exist"; - private final ID toMark; + private final Index toMark; private boolean state; /** - * Creates a {@code JobDeleteCommand} to delete a {@code Job} by {@code JobId}. + * Creates a {@code JobMarkCommand} to mark a {@code Job} by {@code Index}. * - * @param args Arguments. - * @throws ParseException Thrown if there is an error with parsing. + * @param toMark Index of job to mark. */ - public JobMarkCommand(String args) throws ParseException { - requireNonNull(args); - toMark = new JobMarkCommandParser().parse(args); + public JobMarkCommand(Index toMark) { + requireNonNull(toMark); + this.toMark = toMark; } @Override public CommandResult execute(Model model) throws CommandException { requireNonNull(model); + List lastShownList = model.getFilteredJobList(); - if (!model.hasJob(toMark)) { - throw new CommandException(MESSAGE_JOB_NOT_FOUND); + if (toMark.getZeroBased() >= lastShownList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_JOB_DISPLAYED_INDEX); } - try { - // TODO: This line breaks LoD - Job jobToMark = model.getAddressBook().getJobList() - .filtered(job -> job.getJobId().equals(toMark)).get(0); - // Creates immutable instances and replaces the existing ones - if (jobToMark.hasPaid()) { - state = true; - model.setJob(jobToMark, jobToMark.setAsNotPaid()); - } else { - state = false; - model.setJob(jobToMark, jobToMark.setAsPaid()); - } - } catch (IndexOutOfBoundsException e) { - // Asserts that filtered list should always contain exactly the filtered element - assert false; + Job jobToMark = lastShownList.get(toMark.getZeroBased()); + + if (jobToMark.hasPaid()) { + state = true; + model.setJob(jobToMark, jobToMark.setAsNotPaid()); + } else { + state = false; + model.setJob(jobToMark, jobToMark.setAsPaid()); } - // TODO: rudimentary result message - return new CommandResult(String.format(MESSAGE_SUCCESS, toMark, state ? "not paid" : "paid")); + + return new CommandResult(String.format(MESSAGE_SUCCESS, jobToMark.getDesc(), + state ? "not paid" : "paid")); } @Override diff --git a/src/main/java/peoplesoft/logic/parser/AddressBookParser.java b/src/main/java/peoplesoft/logic/parser/AddressBookParser.java index 9a64722ca02..a54973af90a 100644 --- a/src/main/java/peoplesoft/logic/parser/AddressBookParser.java +++ b/src/main/java/peoplesoft/logic/parser/AddressBookParser.java @@ -19,9 +19,15 @@ import peoplesoft.logic.commands.job.JobAddCommand; import peoplesoft.logic.commands.job.JobAssignCommand; import peoplesoft.logic.commands.job.JobDeleteCommand; +import peoplesoft.logic.commands.job.JobFindCommand; import peoplesoft.logic.commands.job.JobListCommand; import peoplesoft.logic.commands.job.JobMarkCommand; import peoplesoft.logic.parser.exceptions.ParseException; +import peoplesoft.logic.parser.job.JobAddCommandParser; +import peoplesoft.logic.parser.job.JobAssignCommandParser; +import peoplesoft.logic.parser.job.JobDeleteCommandParser; +import peoplesoft.logic.parser.job.JobFindCommandParser; +import peoplesoft.logic.parser.job.JobMarkCommandParser; /** * Parses user input. @@ -80,19 +86,22 @@ public Command parseCommand(String userInput) throws ParseException { // Job related commands case JobAddCommand.COMMAND_WORD: - return new JobAddCommand(arguments); + return new JobAddCommandParser().parse(arguments); case JobListCommand.COMMAND_WORD: return new JobListCommand(); case JobDeleteCommand.COMMAND_WORD: - return new JobDeleteCommand(arguments); + return new JobDeleteCommandParser().parse(arguments); case JobMarkCommand.COMMAND_WORD: - return new JobMarkCommand(arguments); + return new JobMarkCommandParser().parse(arguments); + + case JobFindCommand.COMMAND_WORD: + return new JobFindCommandParser().parse(arguments); case JobAssignCommand.COMMAND_WORD: - return new JobAssignCommand(arguments); + return new JobAssignCommandParser().parse(arguments); default: throw new ParseException(MESSAGE_UNKNOWN_COMMAND); diff --git a/src/main/java/peoplesoft/logic/parser/CliSyntax.java b/src/main/java/peoplesoft/logic/parser/CliSyntax.java index b9f9ca2f966..de3a6cf4e85 100644 --- a/src/main/java/peoplesoft/logic/parser/CliSyntax.java +++ b/src/main/java/peoplesoft/logic/parser/CliSyntax.java @@ -13,7 +13,5 @@ public class CliSyntax { public static final Prefix PREFIX_TAG = new Prefix("t/"); public static final Prefix PREFIX_RATE = new Prefix("r/"); public static final Prefix PREFIX_DURATION = new Prefix("d/"); - - // TODO: For {@code JobAssignCommand}, change if needed public static final Prefix PREFIX_INDEX = new Prefix("i/"); } diff --git a/src/main/java/peoplesoft/logic/parser/FindCommandParser.java b/src/main/java/peoplesoft/logic/parser/FindCommandParser.java index b4ff6d5d525..6caf194ae86 100644 --- a/src/main/java/peoplesoft/logic/parser/FindCommandParser.java +++ b/src/main/java/peoplesoft/logic/parser/FindCommandParser.java @@ -19,10 +19,12 @@ public class FindCommandParser implements Parser { * @throws ParseException if the user input does not conform the expected format */ public FindCommand parse(String args) throws ParseException { - String trimmedArgs = args.trim(); - if (trimmedArgs.isEmpty()) { + String trimmedArgs; + try { + trimmedArgs = ParserUtil.parseString(args); + } catch (ParseException pe) { throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE)); + String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE), pe); } String[] nameKeywords = trimmedArgs.split("\\s+"); diff --git a/src/main/java/peoplesoft/logic/parser/ParserUtil.java b/src/main/java/peoplesoft/logic/parser/ParserUtil.java index 8803364b611..338b5c2555b 100644 --- a/src/main/java/peoplesoft/logic/parser/ParserUtil.java +++ b/src/main/java/peoplesoft/logic/parser/ParserUtil.java @@ -17,27 +17,43 @@ import peoplesoft.model.person.Name; import peoplesoft.model.person.Phone; import peoplesoft.model.tag.Tag; +import peoplesoft.model.util.ID; /** * Contains utility methods used for parsing strings in the various *Parser classes. */ public class ParserUtil { - - public static final String MESSAGE_INVALID_INDEX = "Index is not a non-zero unsigned integer."; + public static final String STRING_MESSAGE_CONSTRAINTS = "Empty string not allowed."; + public static final String DURATION_MESSAGE_CONSTRAINTS = "Expects a number for duration (in hours)."; /** - * Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading and trailing whitespaces will be + * Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading and trailing white;spaces will be * trimmed. * @throws ParseException if the specified index is invalid (not non-zero unsigned integer). */ public static Index parseIndex(String oneBasedIndex) throws ParseException { + requireNonNull(oneBasedIndex); String trimmedIndex = oneBasedIndex.trim(); if (!StringUtil.isNonZeroUnsignedInteger(trimmedIndex)) { - throw new ParseException(MESSAGE_INVALID_INDEX); + throw new ParseException(Index.MESSAGE_CONSTRAINTS); } return Index.fromOneBased(Integer.parseInt(trimmedIndex)); } + /** + * Parses {@code oneBasedIndex} into an {@code Index} and returns it. Leading and trailing whitespaces will be + * trimmed. + * @throws ParseException if the specified index is invalid (not non-zero unsigned integer). + */ + public static Set parseIndexes(Collection oneBasedIndexes) throws ParseException { + requireNonNull(oneBasedIndexes); + final Set indexSet = new HashSet<>(); + for (String index : oneBasedIndexes) { + indexSet.add(parseIndex(index)); + } + return indexSet; + } + /** * Parses a {@code String name} into a {@code Name}. * Leading and trailing whitespaces will be trimmed. @@ -135,8 +151,7 @@ public static String parseString(String str) throws ParseException { requireNonNull(str); String res = str.trim(); if (res.isBlank()) { - // TODO: add message - throw new ParseException("Empty string not allowed."); + throw new ParseException(STRING_MESSAGE_CONSTRAINTS); } return res; } @@ -171,12 +186,25 @@ public static Duration parseDuration(String str) throws ParseException { String trim = str.trim(); Duration res; try { - // TODO: Improve scuffed representation - res = Duration.ofSeconds((long) (Double.parseDouble(trim) * 3600)); + res = Duration.ofSeconds(Math.round(Double.parseDouble(trim) * 3600)); } catch (NumberFormatException e) { - // TODO: add message - throw new ParseException("Invalid value for duration"); + throw new ParseException(DURATION_MESSAGE_CONSTRAINTS); } return res; } + + /** + * Parses a {@code String id} into an {@code ID}. + * Leading and trailing whitespaces will be trimmed. + * + * @throws ParseException if the given {@code id} is invalid. + */ + public static ID parseID(String id) throws ParseException { + requireNonNull(id); + String trimmedId = id.trim(); + if (!ID.isValidId(trimmedId)) { + throw new ParseException(ID.MESSAGE_CONSTRAINTS); + } + return new ID(trimmedId); + } } diff --git a/src/main/java/peoplesoft/logic/parser/job/JobAddCommandParser.java b/src/main/java/peoplesoft/logic/parser/job/JobAddCommandParser.java index 1252891274c..2475807d136 100644 --- a/src/main/java/peoplesoft/logic/parser/job/JobAddCommandParser.java +++ b/src/main/java/peoplesoft/logic/parser/job/JobAddCommandParser.java @@ -12,6 +12,7 @@ import peoplesoft.logic.commands.job.JobAddCommand; import peoplesoft.logic.parser.ArgumentMultimap; import peoplesoft.logic.parser.ArgumentTokenizer; +import peoplesoft.logic.parser.Parser; import peoplesoft.logic.parser.ParserUtil; import peoplesoft.logic.parser.Prefix; import peoplesoft.logic.parser.exceptions.ParseException; @@ -22,36 +23,30 @@ /** * Parses input parameters and returns a {@code Job}. */ -public class JobAddCommandParser { +public class JobAddCommandParser implements Parser { /** * Parses the given {@code String} of arguments in the context of the {@code JobAddCommand} - * and returns a {@code Job} object for {@code JobAddCommand}. + * and returns a {@code JobAddCommand} object for execution. * @throws ParseException if the user input does not conform the expected format */ - public Job parse(String args) throws ParseException { + public JobAddCommand parse(String args) throws ParseException { ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_RATE, PREFIX_DURATION); - if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_RATE, PREFIX_DURATION)) { + if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_RATE, PREFIX_DURATION) + || !argMultimap.getPreamble().isBlank()) { throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, JobAddCommand.MESSAGE_USAGE)); } String name = ParserUtil.parseString(argMultimap.getValue(PREFIX_NAME).get()); Rate rate = ParserUtil.parseRate(argMultimap.getValue(PREFIX_RATE).get()); Duration duration = ParserUtil.parseDuration(argMultimap.getValue(PREFIX_DURATION).get()); + ID id = JobIdFactory.nextId(); - ID id; - try { - id = !argMultimap.getPreamble().isBlank() - ? new ID(ParserUtil.parseString(argMultimap.getPreamble())) - : JobIdFactory.nextId(); // Short circuit does not increment - } catch (IllegalArgumentException e) { - throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, - JobAddCommand.MESSAGE_USAGE)); - } + Job toAdd = new Job(id, name, rate, duration, false); - return new Job(id, name, rate, duration, false); + return new JobAddCommand(toAdd); } /** diff --git a/src/main/java/peoplesoft/logic/parser/job/JobAssignCommandParser.java b/src/main/java/peoplesoft/logic/parser/job/JobAssignCommandParser.java index 5904b337774..ff7732435b2 100644 --- a/src/main/java/peoplesoft/logic/parser/job/JobAssignCommandParser.java +++ b/src/main/java/peoplesoft/logic/parser/job/JobAssignCommandParser.java @@ -3,24 +3,29 @@ import static peoplesoft.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; import static peoplesoft.logic.parser.CliSyntax.PREFIX_INDEX; +import java.util.Set; import java.util.stream.Stream; +import peoplesoft.commons.core.index.Index; import peoplesoft.logic.commands.job.JobAssignCommand; import peoplesoft.logic.parser.ArgumentMultimap; import peoplesoft.logic.parser.ArgumentTokenizer; +import peoplesoft.logic.parser.Parser; +import peoplesoft.logic.parser.ParserUtil; import peoplesoft.logic.parser.Prefix; import peoplesoft.logic.parser.exceptions.ParseException; +import peoplesoft.model.employment.Employment; /** - * Parses a {@code jobId} and an {@code index} for {@code Person}. + * Parses an {@code Index} for {@code Job} and {@code Indexes} for {@code Person}. */ -public class JobAssignCommandParser { +public class JobAssignCommandParser implements Parser { /** * Parses the given {@code String} of arguments in the context of the {@code JobAssignCommand} * and returns an {@code ArgumentMultimap} for {@code JobAssignCommand}. * @throws ParseException if the user input does not conform the expected format */ - public ArgumentMultimap parse(String args) throws ParseException { + public JobAssignCommand parse(String args) throws ParseException { ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_INDEX); if (!arePrefixesPresent(argMultimap, PREFIX_INDEX) @@ -28,7 +33,18 @@ public ArgumentMultimap parse(String args) throws ParseException { throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, JobAssignCommand.MESSAGE_USAGE)); } - return argMultimap; + Index jobIndex; + Set personIndexes; + + try { + jobIndex = ParserUtil.parseIndex(argMultimap.getPreamble()); + personIndexes = ParserUtil.parseIndexes(argMultimap.getAllValues(PREFIX_INDEX)); + } catch (ParseException e) { + throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, + JobAssignCommand.MESSAGE_USAGE)); + } + + return new JobAssignCommand(jobIndex, personIndexes, Employment.getInstance()); } /** diff --git a/src/main/java/peoplesoft/logic/parser/job/JobDeleteCommandParser.java b/src/main/java/peoplesoft/logic/parser/job/JobDeleteCommandParser.java index 36640ca2983..05b23d1a70b 100644 --- a/src/main/java/peoplesoft/logic/parser/job/JobDeleteCommandParser.java +++ b/src/main/java/peoplesoft/logic/parser/job/JobDeleteCommandParser.java @@ -2,27 +2,28 @@ import static peoplesoft.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import peoplesoft.commons.core.index.Index; import peoplesoft.logic.commands.job.JobDeleteCommand; +import peoplesoft.logic.parser.Parser; import peoplesoft.logic.parser.ParserUtil; import peoplesoft.logic.parser.exceptions.ParseException; -import peoplesoft.model.util.ID; /** - * Parses a {@code jobId} to delete. + * Parses an {@code Index} to delete. */ -public class JobDeleteCommandParser { +public class JobDeleteCommandParser implements Parser { /** * Parses the given {@code String} of arguments in the context of the {@code JobDeleteCommand} - * and returns a {@code JobId} string for {@code JobDeleteCommand}. + * and returns a {@code JobDeleteCommand} object for execution. * @throws ParseException if the user input does not conform the expected format */ - public ID parse(String args) throws ParseException { + public JobDeleteCommand parse(String args) throws ParseException { try { - String strVal = ParserUtil.parseString(args); // throws ParseException? - return new ID(strVal); // throws IllegalArgumentException - } catch (ParseException | IllegalArgumentException e) { + Index index = ParserUtil.parseIndex(args); + return new JobDeleteCommand(index); + } catch (ParseException pe) { throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, JobDeleteCommand.MESSAGE_USAGE)); + String.format(MESSAGE_INVALID_COMMAND_FORMAT, JobDeleteCommand.MESSAGE_USAGE), pe); } } } diff --git a/src/main/java/peoplesoft/logic/parser/job/JobFindCommandParser.java b/src/main/java/peoplesoft/logic/parser/job/JobFindCommandParser.java new file mode 100644 index 00000000000..306bd47b889 --- /dev/null +++ b/src/main/java/peoplesoft/logic/parser/job/JobFindCommandParser.java @@ -0,0 +1,33 @@ +package peoplesoft.logic.parser.job; + +import static peoplesoft.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; + +import java.util.Arrays; + +import peoplesoft.logic.commands.job.JobFindCommand; +import peoplesoft.logic.parser.Parser; +import peoplesoft.logic.parser.ParserUtil; +import peoplesoft.logic.parser.exceptions.ParseException; +import peoplesoft.model.job.JobContainsKeywordsPredicate; + +public class JobFindCommandParser implements Parser { + + /** + * Parses the given {@code String} of arguments in the context of the {@code JobFindCommand} + * and returns a {@code JobFindCommand} object for execution. + * @throws ParseException if the user input does not conform the expected format + */ + public JobFindCommand parse(String args) throws ParseException { + String trimmedArgs; + try { + trimmedArgs = ParserUtil.parseString(args); + } catch (ParseException pe) { + throw new ParseException( + String.format(MESSAGE_INVALID_COMMAND_FORMAT, JobFindCommand.MESSAGE_USAGE), pe); + } + + String[] nameKeywords = trimmedArgs.split("\\s+"); + + return new JobFindCommand(new JobContainsKeywordsPredicate(Arrays.asList(nameKeywords))); + } +} diff --git a/src/main/java/peoplesoft/logic/parser/job/JobMarkCommandParser.java b/src/main/java/peoplesoft/logic/parser/job/JobMarkCommandParser.java index ea5408745cc..90570276f95 100644 --- a/src/main/java/peoplesoft/logic/parser/job/JobMarkCommandParser.java +++ b/src/main/java/peoplesoft/logic/parser/job/JobMarkCommandParser.java @@ -2,27 +2,28 @@ import static peoplesoft.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import peoplesoft.commons.core.index.Index; import peoplesoft.logic.commands.job.JobMarkCommand; +import peoplesoft.logic.parser.Parser; import peoplesoft.logic.parser.ParserUtil; import peoplesoft.logic.parser.exceptions.ParseException; -import peoplesoft.model.util.ID; /** - * Parses a {@code JobId} to mark. + * Parses an {@code Index} to mark. */ -public class JobMarkCommandParser { +public class JobMarkCommandParser implements Parser { /** * Parses the given {@code String} of arguments in the context of the {@code JobMarkCommand} - * and returns a {@code JobId} string for {@code JobMarkCommand}. + * and returns a {@code JobMarkCommand} object for execution. * @throws ParseException if the user input does not conform the expected format */ - public ID parse(String args) throws ParseException { + public JobMarkCommand parse(String args) throws ParseException { try { - String strVal = ParserUtil.parseString(args); // throws ParseException? - return new ID(strVal); // throws IllegalArgumentException + Index index = ParserUtil.parseIndex(args); + return new JobMarkCommand(index); } catch (ParseException pe) { throw new ParseException( - String.format(MESSAGE_INVALID_COMMAND_FORMAT, JobMarkCommand.MESSAGE_USAGE)); + String.format(MESSAGE_INVALID_COMMAND_FORMAT, JobMarkCommand.MESSAGE_USAGE), pe); } } } diff --git a/src/main/java/peoplesoft/model/employment/Employment.java b/src/main/java/peoplesoft/model/employment/Employment.java index 04f310fc817..fe65aaa4848 100644 --- a/src/main/java/peoplesoft/model/employment/Employment.java +++ b/src/main/java/peoplesoft/model/employment/Employment.java @@ -83,11 +83,10 @@ public void associate(Job job, Person person) { if (!map.containsKey(job.getJobId())) { map.put(job.getJobId(), new TreeSet<>()); } - if (map.get(job.getJobId()).contains(person.getPersonId())) { + // Guaranteed to be non-null and Set handles duplicates + if (!map.get(job.getJobId()).add(person.getPersonId())) { throw new DuplicateEmploymentException(); } - // Guaranteed to be non-null - map.get(job.getJobId()).add(person.getPersonId()); } /** diff --git a/src/main/java/peoplesoft/model/job/JobContainsKeywordsPredicate.java b/src/main/java/peoplesoft/model/job/JobContainsKeywordsPredicate.java new file mode 100644 index 00000000000..b51855153d5 --- /dev/null +++ b/src/main/java/peoplesoft/model/job/JobContainsKeywordsPredicate.java @@ -0,0 +1,28 @@ +package peoplesoft.model.job; + +import java.util.List; +import java.util.function.Predicate; + +import peoplesoft.commons.util.StringUtil; + +public class JobContainsKeywordsPredicate implements Predicate { + + private final List keywords; + + public JobContainsKeywordsPredicate(List keywords) { + this.keywords = keywords; + } + + @Override + public boolean test(Job job) { + return !keywords.isEmpty() && keywords.stream() + .allMatch(keyword -> StringUtil.containsWordIgnoreCase(job.getDesc(), keyword)); + } + + @Override + public boolean equals(Object other) { + return other == this // short circuit if same object + || (other instanceof JobContainsKeywordsPredicate // instanceof handles nulls + && keywords.equals(((JobContainsKeywordsPredicate) other).keywords)); // state check + } +} diff --git a/src/test/java/peoplesoft/logic/commands/job/JobAddCommandTest.java b/src/test/java/peoplesoft/logic/commands/job/JobAddCommandTest.java index 9194a8304ec..6f6fd76ae43 100644 --- a/src/test/java/peoplesoft/logic/commands/job/JobAddCommandTest.java +++ b/src/test/java/peoplesoft/logic/commands/job/JobAddCommandTest.java @@ -2,11 +2,19 @@ import static peoplesoft.testutil.Assert.assertThrows; +import java.time.Duration; + import org.junit.jupiter.api.Test; +import peoplesoft.model.job.Job; +import peoplesoft.model.job.Money; +import peoplesoft.model.job.Rate; +import peoplesoft.model.util.ID; + public class JobAddCommandTest { - private static final String CORRECT_ARGS = " n/name r/1.0 d/3"; + private static final Job EATING = new Job(new ID(1043), "Eating", + new Rate(new Money(5.5), Duration.ofHours(1)), Duration.ofDays(1), false); @Test public void constructor_nullArgs_throwsNullPointerException() { @@ -15,7 +23,7 @@ public void constructor_nullArgs_throwsNullPointerException() { @Test public void execute_nullModel_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new JobAddCommand(CORRECT_ARGS).execute(null)); + assertThrows(NullPointerException.class, () -> new JobAddCommand(EATING).execute(null)); } // TODO: Add model stubs to test command. diff --git a/src/test/java/peoplesoft/logic/commands/job/JobAssignCommandTest.java b/src/test/java/peoplesoft/logic/commands/job/JobAssignCommandTest.java index e654ec7c132..98dec1a74c8 100644 --- a/src/test/java/peoplesoft/logic/commands/job/JobAssignCommandTest.java +++ b/src/test/java/peoplesoft/logic/commands/job/JobAssignCommandTest.java @@ -2,38 +2,29 @@ import static peoplesoft.testutil.Assert.assertThrows; +import java.util.Set; + import org.junit.jupiter.api.Test; -import peoplesoft.logic.parser.exceptions.ParseException; +import peoplesoft.commons.core.index.Index; +import peoplesoft.model.employment.Employment; public class JobAssignCommandTest { - - private static final String CORRECT_ARGS = " 1ef4 i/1"; - @Test public void constructor_nullArgs_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new JobAssignCommand(null)); + assertThrows(NullPointerException.class, () -> new JobAssignCommand(null, Set.of(), + new Employment())); + assertThrows(NullPointerException.class, () -> new JobAssignCommand(Index.fromOneBased(1), null, + new Employment())); + assertThrows(NullPointerException.class, () -> new JobAssignCommand(Index.fromOneBased(1), Set.of(), + null)); } @Test public void execute_nullModel_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new JobAssignCommand(CORRECT_ARGS).execute(null)); + assertThrows(NullPointerException.class, () -> new JobAssignCommand(Index.fromOneBased(1), Set.of(), + new Employment()).execute(null)); } - @Test - public void execute_incorrectArgs_throwsCommandException() { - // TODO - } - - // TODO: Add model stubs to test command. - // Perhaps a common model stub class can be made. - - // TODO: May shift to parser depending on implementation - @Test - public void constructor_wrongFormatArgs_throwsParseException() { - // Empty name - assertThrows(ParseException.class, () -> new JobAssignCommand(" i/1")); - // Incorrect index parse - assertThrows(ParseException.class, () -> new JobAssignCommand("n/correct i/0")); - } + // TODO Valid cases } diff --git a/src/test/java/peoplesoft/logic/commands/job/JobDeleteCommandTest.java b/src/test/java/peoplesoft/logic/commands/job/JobDeleteCommandTest.java index 4fb9b41b25a..b097ac3cde9 100644 --- a/src/test/java/peoplesoft/logic/commands/job/JobDeleteCommandTest.java +++ b/src/test/java/peoplesoft/logic/commands/job/JobDeleteCommandTest.java @@ -9,6 +9,8 @@ import org.junit.jupiter.api.Test; +import peoplesoft.commons.core.Messages; +import peoplesoft.commons.core.index.Index; import peoplesoft.model.Model; import peoplesoft.model.ModelManager; import peoplesoft.model.UserPrefs; @@ -19,12 +21,11 @@ public class JobDeleteCommandTest { - private static final String CORRECT_ARGS = "correct"; - private static final String INCORRECT_ARGS = "incorrect"; + private static final String TEST_ID = "test"; + private static final Job JOB = new Job(new ID(TEST_ID), "The Right Job", + new Rate(new Money(1), Duration.ofHours(1)), Duration.ofHours(2), false); private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs()); - private Job job = new Job(new ID(CORRECT_ARGS), "The Right Job", - new Rate(new Money(1), Duration.ofHours(1)), Duration.ofHours(2), false); @Test public void constructor_nullArgs_throwsNullPointerException() { @@ -33,21 +34,23 @@ public void constructor_nullArgs_throwsNullPointerException() { @Test public void execute_nullModel_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new JobDeleteCommand(CORRECT_ARGS).execute(null)); + assertThrows(NullPointerException.class, () -> new JobDeleteCommand(Index.fromOneBased(1)) + .execute(null)); } @Test - public void execute_incorrectArgs_throwsCommandException() throws Exception { - JobDeleteCommand cmd = new JobDeleteCommand(INCORRECT_ARGS); - assertCommandFailure(cmd, expectedModel, JobDeleteCommand.MESSAGE_JOB_NOT_FOUND); + public void execute_incorrectArgs_throwsCommandException() { + // No job at index 3 + JobDeleteCommand cmd = new JobDeleteCommand(Index.fromOneBased(3)); + assertCommandFailure(cmd, expectedModel, Messages.MESSAGE_INVALID_JOB_DISPLAYED_INDEX); } @Test - public void execute_correctArgs_success() throws Exception { + public void execute_correctArgs_success() { Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); - model.addJob(job); - JobDeleteCommand cmd = new JobDeleteCommand(CORRECT_ARGS); - assertCommandSuccess(cmd, model, String.format(JobDeleteCommand.MESSAGE_SUCCESS, job.getJobId()), + model.addJob(JOB); + JobDeleteCommand cmd = new JobDeleteCommand(Index.fromOneBased(1)); + assertCommandSuccess(cmd, model, String.format(JobDeleteCommand.MESSAGE_SUCCESS, JOB.getDesc()), expectedModel); } } diff --git a/src/test/java/peoplesoft/logic/commands/job/JobFindCommandTest.java b/src/test/java/peoplesoft/logic/commands/job/JobFindCommandTest.java new file mode 100644 index 00000000000..b1e9dd9fa4c --- /dev/null +++ b/src/test/java/peoplesoft/logic/commands/job/JobFindCommandTest.java @@ -0,0 +1,62 @@ +package peoplesoft.logic.commands.job; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static peoplesoft.logic.commands.CommandTestUtil.assertCommandSuccess; +import static peoplesoft.testutil.TypicalPersons.getTypicalAddressBook; + +import java.time.Duration; +import java.util.Arrays; +import java.util.Collections; + +import org.junit.jupiter.api.Test; + +import peoplesoft.commons.core.Messages; +import peoplesoft.model.Model; +import peoplesoft.model.ModelManager; +import peoplesoft.model.UserPrefs; +import peoplesoft.model.job.Job; +import peoplesoft.model.job.JobContainsKeywordsPredicate; +import peoplesoft.model.job.Money; +import peoplesoft.model.job.Rate; +import peoplesoft.model.util.ID; + +public class JobFindCommandTest { + private static final String TEST_ID = "test"; + private static final Job JOB = new Job(new ID(TEST_ID), "The Right Job", + new Rate(new Money(1), Duration.ofHours(1)), Duration.ofHours(2), false); + + private Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + + @Test + public void execute_zeroKeywords_noPersonFound() { + model.addJob(JOB); + expectedModel.addJob(JOB); + String expectedMessage = String.format(Messages.MESSAGE_JOBS_LISTED_OVERVIEW, 0); + JobContainsKeywordsPredicate predicate = preparePredicate(" "); + JobFindCommand command = new JobFindCommand(predicate); + expectedModel.updateFilteredJobList(predicate); + assertCommandSuccess(command, model, expectedMessage, expectedModel); + assertEquals(Collections.emptyList(), model.getFilteredJobList()); + } + + @Test + public void execute_multipleKeywords_multiplePersonsFound() { + model.addJob(JOB); + expectedModel.addJob(JOB); + String expectedMessage = String.format(Messages.MESSAGE_JOBS_LISTED_OVERVIEW, 1); + JobContainsKeywordsPredicate predicate = preparePredicate("right"); + JobFindCommand command = new JobFindCommand(predicate); + expectedModel.updateFilteredJobList(predicate); + assertCommandSuccess(command, model, expectedMessage, expectedModel); + assertEquals(Arrays.asList(JOB), model.getFilteredJobList()); + } + + /** + * Parses {@code userInput} into a {@code JobontainsKeywordsPredicate}. + * @return + */ + private JobContainsKeywordsPredicate preparePredicate(String userInput) { + return new JobContainsKeywordsPredicate(Arrays.asList(userInput.split("\\s+"))); + } +} diff --git a/src/test/java/peoplesoft/logic/commands/job/JobMarkCommandTest.java b/src/test/java/peoplesoft/logic/commands/job/JobMarkCommandTest.java index 0fc290b8f2c..4165ec90758 100644 --- a/src/test/java/peoplesoft/logic/commands/job/JobMarkCommandTest.java +++ b/src/test/java/peoplesoft/logic/commands/job/JobMarkCommandTest.java @@ -1,13 +1,33 @@ package peoplesoft.logic.commands.job; +import static peoplesoft.logic.commands.CommandTestUtil.assertCommandFailure; +import static peoplesoft.logic.commands.CommandTestUtil.assertCommandSuccess; import static peoplesoft.testutil.Assert.assertThrows; +import static peoplesoft.testutil.TypicalPersons.getTypicalAddressBook; + +import java.time.Duration; import org.junit.jupiter.api.Test; +import peoplesoft.commons.core.Messages; +import peoplesoft.commons.core.index.Index; +import peoplesoft.model.Model; +import peoplesoft.model.ModelManager; +import peoplesoft.model.UserPrefs; +import peoplesoft.model.job.Job; +import peoplesoft.model.job.Money; +import peoplesoft.model.job.Rate; +import peoplesoft.model.util.ID; + public class JobMarkCommandTest { - private static final String CORRECT_ARGS = "correct"; - private static final String INCORRECT_ARGS = "incorrect"; + private static final String TEST_ID = "test"; + private static final Job UNPAID = new Job(new ID(TEST_ID), "The Right Job", + new Rate(new Money(1), Duration.ofHours(1)), Duration.ofHours(2), false); + private static final Job PAID = new Job(new ID(TEST_ID), "The Right Job", + new Rate(new Money(1), Duration.ofHours(1)), Duration.ofHours(2), true); + + private Model expectedModel = new ModelManager(getTypicalAddressBook(), new UserPrefs()); @Test public void constructor_nullArgs_throwsNullPointerException() { @@ -16,12 +36,32 @@ public void constructor_nullArgs_throwsNullPointerException() { @Test public void execute_nullModel_throwsNullPointerException() { - assertThrows(NullPointerException.class, () -> new JobMarkCommand(CORRECT_ARGS).execute(null)); + assertThrows(NullPointerException.class, () -> new JobMarkCommand(Index.fromOneBased(1)) + .execute(null)); } @Test public void execute_incorrectArgs_throwsCommandException() { - // TODO + // No job at index 3 + JobMarkCommand cmd = new JobMarkCommand(Index.fromOneBased(3)); + assertCommandFailure(cmd, expectedModel, Messages.MESSAGE_INVALID_JOB_DISPLAYED_INDEX); + } + + @Test + public void execute_correctArgs_success() { + Model model = new ModelManager(getTypicalAddressBook(), new UserPrefs()); + model.addJob(UNPAID); + + // Mark as paid + expectedModel.addJob(PAID); + JobMarkCommand cmd = new JobMarkCommand(Index.fromOneBased(1)); + assertCommandSuccess(cmd, model, String.format(JobMarkCommand.MESSAGE_SUCCESS, PAID.getDesc(), "paid"), + expectedModel); + + // Mark as not paid + expectedModel.setJob(PAID, UNPAID); + cmd = new JobMarkCommand(Index.fromOneBased(1)); + assertCommandSuccess(cmd, model, String.format(JobMarkCommand.MESSAGE_SUCCESS, UNPAID.getDesc(), "not paid"), + expectedModel); } - // TODO: Model stub } diff --git a/src/test/java/peoplesoft/logic/parser/ParserUtilTest.java b/src/test/java/peoplesoft/logic/parser/ParserUtilTest.java index 0f6d21b73b1..54c76f18c8a 100644 --- a/src/test/java/peoplesoft/logic/parser/ParserUtilTest.java +++ b/src/test/java/peoplesoft/logic/parser/ParserUtilTest.java @@ -2,7 +2,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import static peoplesoft.logic.parser.ParserUtil.MESSAGE_INVALID_INDEX; import static peoplesoft.testutil.Assert.assertThrows; import static peoplesoft.testutil.TypicalIndexes.INDEX_FIRST_PERSON; @@ -14,6 +13,7 @@ import org.junit.jupiter.api.Test; +import peoplesoft.commons.core.index.Index; import peoplesoft.logic.parser.exceptions.ParseException; import peoplesoft.model.job.Money; import peoplesoft.model.job.Rate; @@ -22,6 +22,7 @@ import peoplesoft.model.person.Name; import peoplesoft.model.person.Phone; import peoplesoft.model.tag.Tag; +import peoplesoft.model.util.ID; public class ParserUtilTest { private static final String INVALID_NAME = "R@chel"; @@ -31,6 +32,7 @@ public class ParserUtilTest { private static final String INVALID_TAG = "#friend"; private static final String INVALID_RATE = "hello"; private static final String INVALID_DURATION = "world"; + private static final String INVALID_ID = "@special_characters"; private static final String VALID_NAME = "Rachel Walker"; private static final String VALID_PHONE = "123456"; @@ -41,6 +43,7 @@ public class ParserUtilTest { private static final String VALID_STRING = "hello"; private static final String VALID_RATE = "3.0"; private static final String VALID_DURATION = "1.5"; + private static final String VALID_ID = "a123-12ab3"; private static final String WHITESPACE = " \t\r\n"; @@ -51,7 +54,7 @@ public void parseIndex_invalidInput_throwsParseException() { @Test public void parseIndex_outOfRangeInput_throwsParseException() { - assertThrows(ParseException.class, MESSAGE_INVALID_INDEX, () + assertThrows(ParseException.class, Index.MESSAGE_CONSTRAINTS, () -> ParserUtil.parseIndex(Long.toString(Integer.MAX_VALUE + 1))); } @@ -64,6 +67,30 @@ public void parseIndex_validInput_success() throws Exception { assertEquals(INDEX_FIRST_PERSON, ParserUtil.parseIndex(" 1 ")); } + @Test + public void parseIndexes_null_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> ParserUtil.parseIndexes(null)); + } + + @Test + public void parseIndexes_collectionWithInvalidIndexes_throwsParseException() { + assertThrows(ParseException.class, () -> ParserUtil.parseIndexes(Arrays.asList("1", "ahh"))); + } + + @Test + public void parseIndexes_emptyCollection_returnsEmptySet() throws Exception { + assertTrue(ParserUtil.parseIndexes(Collections.emptyList()).isEmpty()); + } + + @Test + public void parseIndexes_collectionWithValidIndexes_returnsIndexSet() throws Exception { + Set actualIndexSet = ParserUtil.parseIndexes(Arrays.asList("4", "3")); + Set expectedIndexSet = new HashSet(Arrays.asList(Index.fromOneBased(4), + Index.fromOneBased(3))); + + assertEquals(expectedIndexSet, actualIndexSet); + } + @Test public void parseName_null_throwsNullPointerException() { assertThrows(NullPointerException.class, () -> ParserUtil.parseName((String) null)); @@ -215,6 +242,7 @@ public void parseString_whitespace_throwsParseException() { @Test public void parseString_validValue_returnsString() throws Exception { assertEquals(VALID_STRING, ParserUtil.parseString(VALID_STRING)); + // With whitespace assertEquals(VALID_STRING, ParserUtil.parseString(WHITESPACE + VALID_STRING + WHITESPACE)); } @@ -233,6 +261,7 @@ public void parseRate_invalidValue_throwsParseException() { public void parseRate_validValue_returnsRate() throws Exception { Rate expectedRate = new Rate(new Money(3.0), Duration.ofHours(1)); assertEquals(expectedRate, ParserUtil.parseRate(VALID_RATE)); + // With whitespace assertEquals(expectedRate, ParserUtil.parseRate(WHITESPACE + VALID_RATE + WHITESPACE)); } @@ -244,14 +273,34 @@ public void parseDuration_null_throwsNullPointerException() { @Test public void parseDuration_invalidValue_throwsParseException() { - assertThrows(ParseException.class, () -> ParserUtil.parseDuration(INVALID_RATE)); + assertThrows(ParseException.class, () -> ParserUtil.parseDuration(INVALID_DURATION)); } @Test public void parseDuration_validValue_returnsDuration() throws Exception { Duration expectedDuration = Duration.ofMinutes(90); assertEquals(expectedDuration, ParserUtil.parseDuration(VALID_DURATION)); + // With whitespace assertEquals(expectedDuration, ParserUtil.parseDuration(WHITESPACE + VALID_DURATION + WHITESPACE)); } + + @Test + public void parseID_null_throwsNullPointerException() { + assertThrows(NullPointerException.class, () -> ParserUtil.parseID(null)); + } + + @Test + public void parseID_invalidValue_throwsParseException() { + assertThrows(ParseException.class, () -> ParserUtil.parseID(INVALID_ID)); + } + + @Test + public void parseID_validValue_returnsString() throws Exception { + ID expectedId = new ID(VALID_ID); + assertEquals(expectedId, ParserUtil.parseID(VALID_ID)); + + // With whitespace + assertEquals(expectedId, ParserUtil.parseID(WHITESPACE + VALID_ID + WHITESPACE)); + } } diff --git a/src/test/java/peoplesoft/logic/parser/job/JobAddCommandParserTest.java b/src/test/java/peoplesoft/logic/parser/job/JobAddCommandParserTest.java index c5f515f3e46..b6bbbb89496 100644 --- a/src/test/java/peoplesoft/logic/parser/job/JobAddCommandParserTest.java +++ b/src/test/java/peoplesoft/logic/parser/job/JobAddCommandParserTest.java @@ -1,32 +1,59 @@ package peoplesoft.logic.parser.job; -import static peoplesoft.testutil.Assert.assertThrows; +import static peoplesoft.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static peoplesoft.logic.parser.CliSyntax.PREFIX_DURATION; +import static peoplesoft.logic.parser.CliSyntax.PREFIX_NAME; +import static peoplesoft.logic.parser.CliSyntax.PREFIX_RATE; +import static peoplesoft.logic.parser.CommandParserTestUtil.assertParseFailure; import org.junit.jupiter.api.Test; -import peoplesoft.logic.parser.exceptions.ParseException; +import peoplesoft.logic.commands.job.JobAddCommand; +import peoplesoft.logic.parser.ParserUtil; +import peoplesoft.model.job.Rate; public class JobAddCommandParserTest { + private static final String MESSAGE_INVALID_FORMAT = + String.format(MESSAGE_INVALID_COMMAND_FORMAT, JobAddCommand.MESSAGE_USAGE); + + private static final String VALID_NAME = " " + PREFIX_NAME + "name"; + private static final String VALID_RATE = " " + PREFIX_RATE + "1.0"; + private static final String VALID_DURATION = " " + PREFIX_DURATION + "3"; + + private static final String PREAMBLE = "preamble"; + private static final String INVALID_NAME = " " + PREFIX_NAME + ""; + private static final String INVALID_RATE = " " + PREFIX_RATE + "hello"; + private static final String INVALID_DURATION = " " + PREFIX_DURATION + "world"; + + private JobAddCommandParser parser = new JobAddCommandParser(); @Test public void parse_missingArgs_throwsParseException() { - assertThrows(ParseException.class, () -> parser.parse(" n/name r/1.0")); - assertThrows(ParseException.class, () -> parser.parse(" n/name d/3")); - assertThrows(ParseException.class, () -> parser.parse(" r/1.0 d/3")); + assertParseFailure(parser, VALID_NAME + VALID_RATE, MESSAGE_INVALID_FORMAT); + assertParseFailure(parser, VALID_NAME + VALID_DURATION, MESSAGE_INVALID_FORMAT); + assertParseFailure(parser, VALID_RATE + VALID_DURATION, MESSAGE_INVALID_FORMAT); + } + + @Test + public void parse_hasPreamble_throwsParseException() { + assertParseFailure(parser, PREAMBLE + VALID_NAME + VALID_RATE + VALID_DURATION, + MESSAGE_INVALID_FORMAT); } @Test public void parse_wrongFormatArgs_throwsParseException() { // Empty name - assertThrows(ParseException.class, () -> parser.parse(" n/ r/1.0 d/3")); + assertParseFailure(parser, INVALID_NAME + VALID_RATE + VALID_DURATION, + ParserUtil.STRING_MESSAGE_CONSTRAINTS); + // Incorrect rate parse - assertThrows(ParseException.class, () -> parser.parse(" n/name r/hello d/3")); + assertParseFailure(parser, VALID_NAME + INVALID_RATE + VALID_DURATION, + Rate.MESSAGE_CONSTRAINTS); + // Incorrect duration parse - assertThrows(ParseException.class, () -> parser.parse(" n/name r/1.0 d/world")); + assertParseFailure(parser, VALID_NAME + VALID_RATE + INVALID_DURATION, + ParserUtil.DURATION_MESSAGE_CONSTRAINTS); } - - // TODO: create test for successful construction - // Current issue is that a new jobId will be made and that may not be deterministic } diff --git a/src/test/java/peoplesoft/logic/parser/job/JobAssignCommandParserTest.java b/src/test/java/peoplesoft/logic/parser/job/JobAssignCommandParserTest.java index 68761ac1634..4b367b00c63 100644 --- a/src/test/java/peoplesoft/logic/parser/job/JobAssignCommandParserTest.java +++ b/src/test/java/peoplesoft/logic/parser/job/JobAssignCommandParserTest.java @@ -1,23 +1,71 @@ package peoplesoft.logic.parser.job; -import static peoplesoft.testutil.Assert.assertThrows; +import static peoplesoft.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static peoplesoft.logic.parser.CommandParserTestUtil.assertParseFailure; +import static peoplesoft.logic.parser.CommandParserTestUtil.assertParseSuccess; + +import java.util.Arrays; +import java.util.HashSet; import org.junit.jupiter.api.Test; -import peoplesoft.logic.parser.exceptions.ParseException; +import peoplesoft.commons.core.index.Index; +import peoplesoft.logic.commands.job.JobAssignCommand; +import peoplesoft.model.employment.Employment; public class JobAssignCommandParserTest { + private static final String MESSAGE_INVALID_FORMAT = + String.format(MESSAGE_INVALID_COMMAND_FORMAT, JobAssignCommand.MESSAGE_USAGE); + private JobAssignCommandParser parser = new JobAssignCommandParser(); @Test - public void parse_missingArgs_throwsParseException() { - // Missing index - assertThrows(ParseException.class, () -> parser.parse(" test")); - // Missing preamble - assertThrows(ParseException.class, () -> parser.parse(" i/1")); + public void parse_missingArgs_failure() { + // Missing index for person + assertParseFailure(parser, "1", MESSAGE_INVALID_FORMAT); + + // Missing index for job + assertParseFailure(parser, "i/1", MESSAGE_INVALID_FORMAT); + } + + @Test + public void parse_invalidPreamble_failure() { + // Negative index + assertParseFailure(parser, "-5 i/1", MESSAGE_INVALID_FORMAT); + + // Zero index + assertParseFailure(parser, "0 i/1", MESSAGE_INVALID_FORMAT); + + // Invalid arguments being parsed as preamble + assertParseFailure(parser, "1 some random string", MESSAGE_INVALID_FORMAT); + + // Invalid prefix being parsed as preamble + assertParseFailure(parser, "1 n/ string", MESSAGE_INVALID_FORMAT); } - // TODO: create test for successful construction - // Current issue is that a new jobId will be made and that may not be deterministic + @Test + public void parse_invalidValue_failure() { + // Negative index + assertParseFailure(parser, "1 i/-5", MESSAGE_INVALID_FORMAT); + + // Zero index + assertParseFailure(parser, "1 i/0", MESSAGE_INVALID_FORMAT); + + // Invalid arguments being parsed as preamble + assertParseFailure(parser, "1 i/1 some random string", MESSAGE_INVALID_FORMAT); + } + + @Test + public void parse_validArgs_success() { + // One index for person + JobAssignCommand expected = new JobAssignCommand(Index.fromOneBased(3), + new HashSet(Arrays.asList(Index.fromOneBased(2))), new Employment()); + assertParseSuccess(parser, "3 i/2", expected); + + // Multiple indexes for person + expected = new JobAssignCommand(Index.fromOneBased(2), new HashSet(Arrays.asList( + Index.fromOneBased(1), Index.fromOneBased(3), Index.fromOneBased(4))), new Employment()); + assertParseSuccess(parser, "2 i/1 i/4 i/3", expected); + } } diff --git a/src/test/java/peoplesoft/logic/parser/job/JobDeleteCommandParserTest.java b/src/test/java/peoplesoft/logic/parser/job/JobDeleteCommandParserTest.java index 53fccef37cb..88d9530bd51 100644 --- a/src/test/java/peoplesoft/logic/parser/job/JobDeleteCommandParserTest.java +++ b/src/test/java/peoplesoft/logic/parser/job/JobDeleteCommandParserTest.java @@ -1,29 +1,48 @@ package peoplesoft.logic.parser.job; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static peoplesoft.testutil.Assert.assertThrows; +import static peoplesoft.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static peoplesoft.logic.parser.CommandParserTestUtil.assertParseFailure; +import static peoplesoft.logic.parser.CommandParserTestUtil.assertParseSuccess; import org.junit.jupiter.api.Test; -import peoplesoft.logic.parser.exceptions.ParseException; +import peoplesoft.commons.core.index.Index; +import peoplesoft.logic.commands.job.JobDeleteCommand; public class JobDeleteCommandParserTest { - private static final String VALID_STRING = "valid"; + private static final String MESSAGE_INVALID_FORMAT = + String.format(MESSAGE_INVALID_COMMAND_FORMAT, JobDeleteCommand.MESSAGE_USAGE); + private static final String WHITESPACE = " \t\r\n"; private JobDeleteCommandParser parser = new JobDeleteCommandParser(); @Test - public void parse_whitespace_throwsParseException() { - assertThrows(ParseException.class, () -> parser.parse(WHITESPACE)); + public void parse_invalidPreamble_failure() { + // Whitespace + assertParseFailure(parser, WHITESPACE, MESSAGE_INVALID_FORMAT); + + // Negative index + assertParseFailure(parser, "-5", MESSAGE_INVALID_FORMAT); + + // Zero index + assertParseFailure(parser, "0", MESSAGE_INVALID_FORMAT); + + // Invalid arguments being parsed as preamble + assertParseFailure(parser, "1 some random string", MESSAGE_INVALID_FORMAT); + + // Invalid prefix being parsed as preamble + assertParseFailure(parser, "1 n/ string", MESSAGE_INVALID_FORMAT); } @Test public void parse_validValue_returnsString() throws Exception { - assertEquals(VALID_STRING, parser.parse(VALID_STRING).toString()); + JobDeleteCommand expected = new JobDeleteCommand(Index.fromOneBased(1)); + assertParseSuccess(parser, "1", expected); + // With whitespace - assertEquals(VALID_STRING, parser.parse(WHITESPACE + VALID_STRING + WHITESPACE).toString()); - // TODO: Currently exactly the same as ParserUtil.parseString() + expected = new JobDeleteCommand(Index.fromOneBased(5)); + assertParseSuccess(parser, WHITESPACE + "5" + WHITESPACE, expected); } } diff --git a/src/test/java/peoplesoft/logic/parser/job/JobFindCommandParserTest.java b/src/test/java/peoplesoft/logic/parser/job/JobFindCommandParserTest.java new file mode 100644 index 00000000000..73d662a20ca --- /dev/null +++ b/src/test/java/peoplesoft/logic/parser/job/JobFindCommandParserTest.java @@ -0,0 +1,34 @@ +package peoplesoft.logic.parser.job; + +import static peoplesoft.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static peoplesoft.logic.parser.CommandParserTestUtil.assertParseFailure; +import static peoplesoft.logic.parser.CommandParserTestUtil.assertParseSuccess; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import peoplesoft.logic.commands.job.JobFindCommand; +import peoplesoft.model.job.JobContainsKeywordsPredicate; + +public class JobFindCommandParserTest { + + private JobFindCommandParser parser = new JobFindCommandParser(); + + @Test + public void parse_emptyArg_throwsParseException() { + assertParseFailure(parser, " \r\t\n", String.format(MESSAGE_INVALID_COMMAND_FORMAT, + JobFindCommand.MESSAGE_USAGE)); + } + + @Test + public void parse_validArgs_returnsFindCommand() { + // no leading and trailing whitespaces + JobFindCommand expected = + new JobFindCommand(new JobContainsKeywordsPredicate(Arrays.asList("Power", "Puff"))); + assertParseSuccess(parser, "Power Puff", expected); + + // multiple whitespaces between keywords + assertParseSuccess(parser, " \n Power \n \t Puff \t", expected); + } +} diff --git a/src/test/java/peoplesoft/logic/parser/job/JobMarkCommandParserTest.java b/src/test/java/peoplesoft/logic/parser/job/JobMarkCommandParserTest.java index fb58ac285d0..c8efd37b2f1 100644 --- a/src/test/java/peoplesoft/logic/parser/job/JobMarkCommandParserTest.java +++ b/src/test/java/peoplesoft/logic/parser/job/JobMarkCommandParserTest.java @@ -1,29 +1,48 @@ package peoplesoft.logic.parser.job; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static peoplesoft.testutil.Assert.assertThrows; +import static peoplesoft.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT; +import static peoplesoft.logic.parser.CommandParserTestUtil.assertParseFailure; +import static peoplesoft.logic.parser.CommandParserTestUtil.assertParseSuccess; import org.junit.jupiter.api.Test; -import peoplesoft.logic.parser.exceptions.ParseException; +import peoplesoft.commons.core.index.Index; +import peoplesoft.logic.commands.job.JobMarkCommand; public class JobMarkCommandParserTest { - private static final String VALID_STRING = "valid"; + private static final String MESSAGE_INVALID_FORMAT = + String.format(MESSAGE_INVALID_COMMAND_FORMAT, JobMarkCommand.MESSAGE_USAGE); + private static final String WHITESPACE = " \t\r\n"; private JobMarkCommandParser parser = new JobMarkCommandParser(); @Test - public void parse_whitespace_throwsParseException() { - assertThrows(ParseException.class, () -> parser.parse(WHITESPACE)); + public void parse_invalidPreamble_failure() { + // Whitespace + assertParseFailure(parser, WHITESPACE, MESSAGE_INVALID_FORMAT); + + // Negative index + assertParseFailure(parser, "-5", MESSAGE_INVALID_FORMAT); + + // Zero index + assertParseFailure(parser, "0", MESSAGE_INVALID_FORMAT); + + // Invalid arguments being parsed as preamble + assertParseFailure(parser, "1 some random string", MESSAGE_INVALID_FORMAT); + + // Invalid prefix being parsed as preamble + assertParseFailure(parser, "1 n/ string", MESSAGE_INVALID_FORMAT); } @Test public void parse_validValue_returnsString() throws Exception { - assertEquals(VALID_STRING, parser.parse(VALID_STRING).toString()); + JobMarkCommand expected = new JobMarkCommand(Index.fromOneBased(1)); + assertParseSuccess(parser, "1", expected); + // With whitespace - assertEquals(VALID_STRING, parser.parse(WHITESPACE + VALID_STRING + WHITESPACE).toString()); - // TODO: Currently exactly the same as ParserUtil.parseString() + expected = new JobMarkCommand(Index.fromOneBased(5)); + assertParseSuccess(parser, WHITESPACE + "5" + WHITESPACE, expected); } }