Skip to content

Commit

Permalink
Merge branch 'master' into add-pass-to-delete
Browse files Browse the repository at this point in the history
  • Loading branch information
wn committed Oct 17, 2018
2 parents 0c4cf51 + d5b6320 commit b3534f8
Show file tree
Hide file tree
Showing 6 changed files with 265 additions and 3 deletions.
83 changes: 83 additions & 0 deletions src/main/java/seedu/address/model/loan/Nric.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package seedu.address.model.loan;

import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.AppUtil.checkArgument;

/**
* Class that stores the NRIC of a person.
*/
public class Nric {

public static final String MESSAGE_NRIC_CONSTRAINTS =
"NRIC should be Singapore issued. It may be blank. ";

public static final String NRIC_VALIDATION_REGEX = "^[ST]\\d{7}[A-JZ]|[FG]\\d{7}[K-NPQRTUWX]$";

public final String nric;

/**
* Constructs a {@code Nric}.
*
* @param ic A valid nric.
*/
public Nric(String ic) {
requireNonNull(ic);
ic = ic.toUpperCase();
checkArgument(isValidNric(ic), MESSAGE_NRIC_CONSTRAINTS);
nric = ic;
}

/**
* Returns true if a given string is a valid nric.
* Precondition: test is not null.
*/
public static boolean isValidNric(String test) {
String ic = test.toUpperCase();

if (!ic.matches(NRIC_VALIDATION_REGEX)) {
return false;
}

String prefix = String.valueOf(ic.charAt(0));
String checksum = String.valueOf(ic.charAt(8));
String digits = ic.substring(1, 8);

int[] weights = {2, 7, 6, 5, 4, 3, 2};
int sum = 0;

// Generate checksum
for (int i = 0; i < digits.length(); i++) {
sum += Integer.parseInt(String.valueOf(digits.charAt(i))) * weights[i];
}

// Add 4 to IC issued in 21th century. This rule was designed by the Singapore government.
if ("G".equals(prefix) || "T".equals(prefix)) {
sum += 4;
}

if ("S".equals(prefix) || "T".equals(prefix)) {
String[] nricCheckDigits = {"J", "Z", "I", "H", "G", "F", "E", "D", "C", "B", "A"};
return nricCheckDigits[sum % 11].equals(checksum);
} else {
String[] finCheckDigits = {"X", "W", "U", "T", "R", "Q", "P", "N", "M", "L", "K"};
return finCheckDigits[sum % 11].equals(checksum);
}
}

@Override
public String toString() {
return nric;
}

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

@Override
public int hashCode() {
return nric.hashCode();
}
}
24 changes: 23 additions & 1 deletion src/main/java/seedu/address/ui/LoanCard.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
public class LoanCard extends UiPart<Region> {

private static final String FXML = "LoanListCard.fxml";
private static final String[] TAG_COLOR_STYLES =
{"teal", "red", "yellow", "blue", "orange", "brown", "green", "pink", "black", "grey"};

/**
* Note: Certain keywords such as "location" and "resources" are reserved keywords in JavaFX.
Expand Down Expand Up @@ -47,7 +49,27 @@ public LoanCard(Loan loan, int displayedIndex) {
phone.setText(loan.getPhone().value);
address.setText(loan.getAddress().value);
email.setText(loan.getEmail().value);
loan.getTags().forEach(tag -> tags.getChildren().add(new Label(tag.value)));
initTags(loan);
}

/**
* Returns the color style for {@code tagName}'s label.
*/
private String getTagColorStyleFor(String tagName) {
// we use the hash code of the tag name to generate a random color, so that the color remain consistent
// between different runs of the program while still making it random enough between tags.
return TAG_COLOR_STYLES[Math.abs(tagName.hashCode()) % TAG_COLOR_STYLES.length];
}

/**
* Creates the tag labels for {@code person}.
*/
private void initTags(Loan loan) {
loan.getTags().forEach(tag -> {
Label tagLabel = new Label(tag.value);
tagLabel.getStyleClass().add(getTagColorStyleFor(tag.value));
tags.getChildren().add(tagLabel);
});
}

@Override
Expand Down
50 changes: 50 additions & 0 deletions src/main/resources/view/DarkTheme.css
Original file line number Diff line number Diff line change
Expand Up @@ -349,3 +349,53 @@
-fx-background-radius: 2;
-fx-font-size: 11;
}

#tags .teal {
-fx-text-fill: white;
-fx-background-color: #3e7b91;
}

#tags .red {
-fx-text-fill: black;
-fx-background-color: red;
}

#tags .yellow {
-fx-background-color: yellow;
-fx-text-fill: black;
}

#tags .blue {
-fx-text-fill: white;
-fx-background-color: blue;
}

#tags .orange {
-fx-text-fill: black;
-fx-background-color: orange;
}

#tags .brown {
-fx-text-fill: white;
-fx-background-color: brown;
}

#tags .green {
-fx-text-fill: black;
-fx-background-color: green;
}

#tags .pink {
-fx-text-fill: black;
-fx-background-color: pink;
}

#tags .black {
-fx-text-fill: white;
-fx-background-color: black;
}

#tags .grey {
-fx-text-fill: black;
-fx-background-color: grey;
}
9 changes: 9 additions & 0 deletions src/test/java/guitests/guihandles/LoanCardHandle.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ public List<String> getTags() {
.collect(Collectors.toList());
}

public List<String> getTagStyleClasses(String tag) {
return tagLabels
.stream()
.filter(label -> label.getText().equals(tag))
.map(Label::getStyleClass)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No such tag."));
}

/**
* Returns true if this handle contains {@code loan}.
*/
Expand Down
51 changes: 51 additions & 0 deletions src/test/java/seedu/address/model/loan/NricTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package seedu.address.model.loan;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;

import seedu.address.testutil.Assert;

public class NricTest {
@Test
public void constructor_null_throwsNullPointerException() {
Assert.assertThrows(NullPointerException.class, () -> new Nric(null));
}

@Test
public void constructor_invalidNric_throwsIllegalArgumentException() {
String invalidNric = "";
Assert.assertThrows(IllegalArgumentException.class, () -> new Nric(invalidNric));
}

@Test
public void isValidNric() {
// null nric
Assert.assertThrows(NullPointerException.class, () -> Nric.isValidNric(null));

// invalid nric
assertFalse(Nric.isValidNric("")); // empty string
assertFalse(Nric.isValidNric(" ")); // spaces only
assertFalse(Nric.isValidNric("^")); // only non-alphanumeric characters
assertFalse(Nric.isValidNric("njkakjsdnfa")); // contains random alphanumeric characters

// Wrong checksum
assertFalse(Nric.isValidNric("S1234567Z"));
assertFalse(Nric.isValidNric("T1234567Z"));
assertFalse(Nric.isValidNric("F1234567Z"));
assertFalse(Nric.isValidNric("G1234567Z"));

// valid nric
assertTrue(Nric.isValidNric("S1234567D")); // IC for citizens born in 20th century
assertTrue(Nric.isValidNric("T1234567J")); // IC for citizens born in 21th century
assertTrue(Nric.isValidNric("F1234567N")); // Foreign IC F
assertTrue(Nric.isValidNric("G1234567X")); // Foreign IC G

// Inconsistant case
assertTrue(Nric.isValidNric("s1234567d"));
assertTrue(Nric.isValidNric("t1234567j"));
assertTrue(Nric.isValidNric("f1234567N"));
assertTrue(Nric.isValidNric("G1234567x"));
}
}
51 changes: 49 additions & 2 deletions src/test/java/seedu/address/ui/testutil/GuiTestAssert.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@

import static org.junit.Assert.assertEquals;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import guitests.guihandles.LoanCardHandle;
import guitests.guihandles.LoanListPanelHandle;
import guitests.guihandles.ResultDisplayHandle;
import seedu.address.model.loan.Loan;
import seedu.address.ui.LoanCard;

/**
* A set of assertion methods useful for writing GUI tests.
*/
public class GuiTestAssert {
private static final String LABEL_DEFAULT_STYLE = "label";
/**
* Asserts that {@code actualCard} displays the same values as {@code expectedCard}.
*/
Expand All @@ -24,6 +27,11 @@ public static void assertCardEquals(LoanCardHandle expectedCard, LoanCardHandle
assertEquals(expectedCard.getName(), actualCard.getName());
assertEquals(expectedCard.getPhone(), actualCard.getPhone());
assertEquals(expectedCard.getTags(), actualCard.getTags());

expectedCard
.getTags()
.forEach(tag ->
assertEquals(expectedCard.getTagStyleClasses(tag), actualCard.getTagStyleClasses(tag)));
}

/**
Expand All @@ -34,8 +42,47 @@ public static void assertCardDisplaysLoan(Loan expectedLoan, LoanCardHandle actu
assertEquals(expectedLoan.getPhone().value, actualCard.getPhone());
assertEquals(expectedLoan.getEmail().value, actualCard.getEmail());
assertEquals(expectedLoan.getAddress().value, actualCard.getAddress());
assertEquals(expectedLoan.getTags().stream().map(tag -> tag.value).collect(Collectors.toList()),
actualCard.getTags());
assertTagsEqual(expectedLoan, actualCard);
}

/**
* Returns the color style for {@code tagName}'s label. The tag's color is determined by looking up the color
* in {@code LoanCard#TAG_COLOR_STYLES}, using an index generated by the hash code of the tag's content.
*
* @see LoanCard#getTagColorStyleFor(String)
*/
private static String getTagColorStyleFor(String tagName) {
switch (tagName) {
case "classmates":
case "owesMoney":
return "teal";
case "colleagues":
case "neighbours":
return "yellow";
case "family":
case "friend":
return "orange";
case "friends":
return "brown";
case "husband":
return "grey";
default:
throw new AssertionError(tagName + " does not have a color assigned.");
}
}

/**
* Asserts that the tags in {@code actualCard} matches all the tags in {@code expectedPerson} with the correct
* color.
*/
private static void assertTagsEqual(Loan expectedLoan, LoanCardHandle actualCard) {
List<String> expectedTags = expectedLoan.getTags().stream()
.map(tag -> tag.value).collect(Collectors.toList());
assertEquals(expectedTags, actualCard.getTags());
expectedTags.forEach(tag -> assertEquals(
Arrays.asList(LABEL_DEFAULT_STYLE, getTagColorStyleFor(tag)),
actualCard.getTagStyleClasses(tag)
));
}

/**
Expand Down

0 comments on commit b3534f8

Please sign in to comment.