diff --git a/src/main/java/nl/hsac/fitnesse/util/BsnUtil.java b/src/main/java/nl/hsac/fitnesse/util/BsnUtil.java index 598c373..6cf9fd3 100755 --- a/src/main/java/nl/hsac/fitnesse/util/BsnUtil.java +++ b/src/main/java/nl/hsac/fitnesse/util/BsnUtil.java @@ -1,17 +1,77 @@ package nl.hsac.fitnesse.util; +import java.util.HashSet; +import java.util.Set; + /** * Helpers for BSNs. */ public class BsnUtil { private RandomUtil randomUtil = new RandomUtil(); + private final Set bsnsToExclude = new HashSet<>(); /** * Generates random number that could be a BSN. - * Based on: http://www.testnummers.nl/bsn.js * @return random BSN. */ public String generateBsn() { + String result; + int attempts = 0; + do { + if (attempts > 1000) { + throw new RuntimeException("Unable to generate new random BSN"); + } + attempts++; + result = generateNextBsn(); + } while (!bsnsToExclude.add(result)); + return result; + } + + /** + * Checks whether BSN is valid. + * Based on: https://mxforum.mendix.com/questions/2162/ + * @param bsn BSN to check. + * @return true if it is structurally sound. + */ + public boolean testBsn(String bsn) { + try { + Double.parseDouble(bsn); + } catch (Exception e) { + return false; + } + if (bsn.length() != 9) { + return false; + } else { + int checksum = 0; + for (int i = 0; i < 8; i++) { + checksum += (Integer.parseInt(Character.toString(bsn.charAt(i))) * (9 - i)); + } + checksum -= Integer.parseInt(Character.toString(bsn.charAt(8))); + if (checksum % 11 != 0) { + return false; + } + } + return true; + + } + + public void addBsnToExclude(String bsn) { + bsnsToExclude.add(bsn); + } + + public Set getBsnsToExclude() { + return bsnsToExclude; + } + + public void resetExcludedBsns() { + bsnsToExclude.clear(); + } + + /** + * Based on: http://www.testnummers.nl/bsn.js + * @return String that passes BSN test. + */ + private String generateNextBsn() { String Result1 = ""; int Nr9 = randomUtil.random(3); int Nr8 = randomUtil.random(10); @@ -49,34 +109,6 @@ public String generateBsn() { return Result1; } - /** - * Checks whether BSN is valid. - * Based on: https://mxforum.mendix.com/questions/2162/ - * @param bsn BSN to check. - * @return true if it is structurally sound. - */ - public boolean testBsn(String bsn) { - try { - Double.parseDouble(bsn); - } catch (Exception e) { - return false; - } - if (bsn.length() != 9) { - return false; - } else { - int checksum = 0; - for (int i = 0; i < 8; i++) { - checksum += (Integer.parseInt(Character.toString(bsn.charAt(i))) * (9 - i)); - } - checksum -= Integer.parseInt(Character.toString(bsn.charAt(8))); - if (checksum % 11 != 0) { - return false; - } - } - return true; - - } - private int floor(double d) { return (int) d; } diff --git a/src/test/java/nl/hsac/fitnesse/symbols/RandomBsnTest.java b/src/test/java/nl/hsac/fitnesse/symbols/RandomBsnTest.java new file mode 100644 index 0000000..3cc1008 --- /dev/null +++ b/src/test/java/nl/hsac/fitnesse/symbols/RandomBsnTest.java @@ -0,0 +1,20 @@ +package nl.hsac.fitnesse.symbols; + +import org.junit.Test; + +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.assertFalse; + +public class RandomBsnTest { + @Test + public void ensureNoDuplicates() { + Set generatedBsns = new HashSet<>(); + for (int i = 0; i < 10000; i++) { + String bsn = new RandomBsn().toTarget(null, null); + assertFalse("Duplicated value at loop: " + i, generatedBsns.contains(bsn)); + generatedBsns.add(bsn); + } + } +} diff --git a/src/test/java/nl/hsac/fitnesse/util/BsnUtilTest.java b/src/test/java/nl/hsac/fitnesse/util/BsnUtilTest.java index f517e0c..43cd5c0 100755 --- a/src/test/java/nl/hsac/fitnesse/util/BsnUtilTest.java +++ b/src/test/java/nl/hsac/fitnesse/util/BsnUtilTest.java @@ -1,8 +1,14 @@ package nl.hsac.fitnesse.util; +import org.junit.After; import org.junit.Test; -import static org.junit.Assert.*; +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; /** * Tests BsnUtil. @@ -10,15 +16,48 @@ public class BsnUtilTest { private final BsnUtil generator = new BsnUtil(); + @After + public void resetGenerator() { + generator.resetExcludedBsns(); + } + /** * Tests basic generation. */ @Test public void testGenerate() { - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 1000; i++) { String result = generator.generateBsn(); assertEquals("Got: " + result, 9, result.length()); assertTrue("Got: " + result, generator.testBsn(result)); } } + + @Test + public void ensureNoDuplicates() { + Set generatedBsns = new HashSet<>(); + for (int i = 0; i < 100_000; i++) { + String result = generator.generateBsn(); + assertFalse("Duplicated value at loop: " + i, generatedBsns.contains(result)); + generatedBsns.add(result); + } + + assertEquals(generatedBsns, generator.getBsnsToExclude()); + } + + @Test + public void resetClears() { + generator.generateBsn(); + assertFalse(generator.getBsnsToExclude().isEmpty()); + + generator.resetExcludedBsns(); + assertTrue(generator.getBsnsToExclude().isEmpty()); + } + + @Test + public void testAddBsnToExclude() { + assertFalse(generator.getBsnsToExclude().contains("abc")); + generator.addBsnToExclude("abc"); + assertTrue(generator.getBsnsToExclude().contains("abc")); + } }