Skip to content

Commit

Permalink
Implement Prerequisite and its tests
Browse files Browse the repository at this point in the history
  • Loading branch information
yyyaohhh committed Oct 25, 2023
1 parent 9900904 commit 4c026a2
Show file tree
Hide file tree
Showing 4 changed files with 279 additions and 1 deletion.
7 changes: 7 additions & 0 deletions src/main/java/seedu/address/model/module/Module.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class Module {
private final Semester semesterTaken;
private final Grade grade;
private final ModularCredit modularCredit;
private final Prerequisite prerequisite;

/**
* Every field must be present and not null.
Expand All @@ -37,6 +38,7 @@ public Module(ModuleCode moduleCode, Year yearTaken, Semester semesterTaken, Gra
this.semesterTaken = semesterTaken;
this.grade = grade;
this.modularCredit = modularCredit;
this.prerequisite = new Prerequisite();
}

/**
Expand All @@ -53,6 +55,7 @@ public Module(ModuleCode moduleCode, Year year, Semester semester, Grade grade)
this.description = null;
this.lecturers = null;
this.modularCredit = null;
this.prerequisite = new Prerequisite();
}

public ModuleName getName() {
Expand Down Expand Up @@ -87,6 +90,10 @@ public ModularCredit getModularCredit() {
return modularCredit;
}

public Prerequisite getPrerequisite() {
return prerequisite;
}

/**
* Checks if two modules are the same module.
* @param otherModule the other module to check.
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/seedu/address/model/module/ModuleCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ public ModuleCode(String moduleCode) {
}

/**
* Returns if a given string is a valid email.
* Checks if the given input string is a valid module code.
*
* @param test The input string to be checked.
* @return true if the input string is a valid module code, false otherwise.
*/
public static boolean isValidModuleCode(String test) {
return test.matches(VALIDATION_REGEX);
Expand Down
138 changes: 138 additions & 0 deletions src/main/java/seedu/address/model/module/Prerequisite.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package seedu.address.model.module;

import static java.util.Objects.requireNonNull;

import java.util.LinkedList;

/**
* Represents a Module's prerequisites in the system.
* */
public class Prerequisite {
private LinkedList<LinkedList<Module>> prerequisites;

/**
* Constructs a new {@code Prerequisite} where modules are stored in linked lists.
*/
public Prerequisite() {
this.prerequisites = new LinkedList<>();
}

/**
* Adds a module that is prerequisites with an "AND" relationship with the list of modules.
*
* @param andPrerequisite A module that is prerequisite and must all be completed to satisfy the requirement.
*/
public void addAndPrerequisite(Module andPrerequisite) {
requireNonNull(andPrerequisite);

LinkedList<Module> toAdd = new LinkedList<>();
toAdd.add(andPrerequisite);
this.prerequisites.add(toAdd);
}

/**
* Deletes a module that is prerequisites with an "AND" relationship with the list of modules.
*
* @param toDelete A module to be removed from the list of "AND" prerequisites.
*/
public void deleteAndPrerequisite(Module toDelete) {
requireNonNull(toDelete);

for (int i = 0; i < prerequisites.size(); i++) {
if (prerequisites.get(i).contains(toDelete)) {
prerequisites.remove(i);
}
}
}

/**
* Adds the specified module as an "OR" prerequisite for this module in the context of another module.
*
* @param toAdd The module to be added as an "OR" prerequisite.
* @param orRelationship The module is an "OR" prerequisite to the module being added.
*/
public void addOrPrerequisite(Module toAdd, Module orRelationship) {
requireNonNull(toAdd);
requireNonNull(orRelationship);

for (int i = 0; i < prerequisites.size(); i++) {
if (prerequisites.get(i).contains(orRelationship)) {
prerequisites.get(i).add(toAdd);
}
}
}

/**
* Deletes the specified module from the list of "OR" prerequisites for this module in the context of another module.
*
* @param toDelete The module to be removed from the list of "OR" prerequisites.
* @param orRelationship TThe module is an "OR" prerequisite to the module being removed.
*/
public void deleteOrPrerequisite(Module toDelete, Module orRelationship) {
requireNonNull(toDelete);
requireNonNull(orRelationship);

for (int i = 0; i < prerequisites.size(); i++) {
if (prerequisites.get(i).contains(orRelationship)) {
prerequisites.get(i).remove(toDelete);
}
}
}

/**
* Checks if the given module is a prerequisite for this module.
*
* @param module The module to be checked as a prerequisite.
* @return true if the given module is a prerequisite for this module, false otherwise.
*/
public boolean isPrerequisite(Module module) {
requireNonNull(module);

for (int i = 0; i < prerequisites.size(); i++) {
if (prerequisites.get(i).contains(module)) {
return true;
}
}
return false;
}

@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof Module)) {
return false;
}

Prerequisite otherPrerequisite = (Prerequisite) other;
return this.prerequisites.equals(otherPrerequisite.prerequisites);
}

/**
* Returns a string representation of the prerequisites for this module in a readable format.
*
* @return A string containing the prerequisites for this module with "AND" and "OR" relationships.
*/
@Override
public String toString() {
String output = "";
for (int i = 0; i < prerequisites.size(); i++) {
output = output.concat("(");
for (int j = 0; j < prerequisites.get(i).size(); j++) {
output = output.concat(prerequisites.get(i).get(j).getModuleCode().toString());
if (j != prerequisites.get(i).size() - 1) {
output = output.concat(" OR ");
}
}
output = output.concat(")");
if (i != prerequisites.size() - 1) {
output = output.concat(" AND ");
}
}
return output;
}

}
130 changes: 130 additions & 0 deletions src/test/java/seedu/address/model/module/PrerequisiteTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package seedu.address.model.module;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static seedu.address.testutil.Assert.assertThrows;
import static seedu.address.testutil.TypicalModules.CS2030S;
import static seedu.address.testutil.TypicalModules.CS2040S;
import static seedu.address.testutil.TypicalModules.CS2101;


import org.junit.jupiter.api.Test;

public class PrerequisiteTest {
@Test
public void addAndPrerequisite() {
Prerequisite testPrerequisite = new Prerequisite();
// null module
assertThrows(NullPointerException.class, () -> testPrerequisite.addAndPrerequisite(null));

testPrerequisite.addAndPrerequisite(CS2040S);
assertTrue(testPrerequisite.isPrerequisite(CS2040S));
}

@Test
public void deleteAndPrerequisite() {
Prerequisite testPrerequisite = new Prerequisite();
// null module
assertThrows(NullPointerException.class, () -> testPrerequisite.deleteAndPrerequisite(null));

testPrerequisite.deleteAndPrerequisite(CS2040S);
assertFalse(testPrerequisite.isPrerequisite(CS2040S));
}

@Test
public void addOrPrerequisite() {
Prerequisite testPrerequisite = new Prerequisite();
// null module, null orRelationship
assertThrows(NullPointerException.class, () -> testPrerequisite.addOrPrerequisite(null, null));
// null module
assertThrows(NullPointerException.class, () -> testPrerequisite.addOrPrerequisite(null, CS2040S));
// null orRelationship
assertThrows(NullPointerException.class, () -> testPrerequisite.addOrPrerequisite(CS2101, null));

//contains orRelationship
testPrerequisite.addAndPrerequisite(CS2040S);
testPrerequisite.addOrPrerequisite(CS2101, CS2040S);
assertTrue(testPrerequisite.isPrerequisite(CS2101));

//does not contain orRelationship
Prerequisite testNoORPrerequisite = new Prerequisite();
testNoORPrerequisite.addOrPrerequisite(CS2101, CS2040S);
assertFalse(testNoORPrerequisite.isPrerequisite(CS2101));
}

@Test
public void deleteOrPrerequisite() {
Prerequisite testPrerequisite = new Prerequisite();
// null module, null orRelationship
assertThrows(NullPointerException.class, () -> testPrerequisite.deleteOrPrerequisite(null, null));
// null module
assertThrows(NullPointerException.class, () -> testPrerequisite.deleteOrPrerequisite(null, CS2040S));
// null orRelationship
assertThrows(NullPointerException.class, () -> testPrerequisite.deleteOrPrerequisite(CS2101, null));

//contains orRelationship
testPrerequisite.addAndPrerequisite(CS2040S);
testPrerequisite.addOrPrerequisite(CS2101, CS2040S);
testPrerequisite.deleteOrPrerequisite(CS2101, CS2040S);
assertFalse(testPrerequisite.isPrerequisite(CS2101));

//wrong orRelationship, not bring deleted
Prerequisite testNoORPrerequisite = new Prerequisite();
testNoORPrerequisite.addAndPrerequisite(CS2040S);
testNoORPrerequisite.addOrPrerequisite(CS2101, CS2040S);
testNoORPrerequisite.deleteOrPrerequisite(CS2101, CS2030S);
assertTrue(testNoORPrerequisite.isPrerequisite(CS2101));
}

@Test
public void isPrerequisite() {
Prerequisite testPrerequisite = new Prerequisite();
assertThrows(NullPointerException.class, () -> testPrerequisite.isPrerequisite(null));

testPrerequisite.addAndPrerequisite(CS2040S);
assertTrue(testPrerequisite.isPrerequisite(CS2040S));
assertFalse(testPrerequisite.isPrerequisite(CS2101));
}

@Test
public void equals() {
Prerequisite cs2030s = new Prerequisite();
cs2030s.addAndPrerequisite(CS2030S);

Prerequisite cs2040s = new Prerequisite();
cs2040s.addAndPrerequisite(CS2040S);

//same object
assertTrue(cs2030s.equals(cs2030s));

// null -> returns false
assertFalse(cs2030s.equals(null));

// different type -> returns false
assertFalse(cs2030s.equals(5));

// different AND prerequisites -> returns false
assertFalse(cs2030s.equals(cs2040s));

// different OR prerequisites -> returns false
Prerequisite cs2101 = new Prerequisite();
cs2101.addAndPrerequisite(CS2101);
cs2101.addOrPrerequisite(CS2030S, CS2101);
Prerequisite cs2101Compare = new Prerequisite();
cs2101Compare.addAndPrerequisite(CS2101);
cs2101Compare.addOrPrerequisite(CS2040S, CS2101);

assertFalse(cs2101.equals(cs2101Compare));
}

@Test
public void toStringMethod() {
Prerequisite cs2101 = new Prerequisite();
cs2101.addAndPrerequisite(CS2101);
cs2101.addAndPrerequisite(CS2030S);
cs2101.addOrPrerequisite(CS2040S, CS2101);
String expected = "(CS2101 OR CS2040S) AND (CS2030S)";
assertEquals(expected, cs2101.toString());
}
}

0 comments on commit 4c026a2

Please sign in to comment.