Skip to content

Commit

Permalink
Merge branch 'master' into change-tag-colour
Browse files Browse the repository at this point in the history
  • Loading branch information
xantho09 committed Oct 17, 2018
2 parents 228b90d + 89973d1 commit 5f34e95
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 0 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();
}
}
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"));
}
}

0 comments on commit 5f34e95

Please sign in to comment.