diff --git a/src/main/java/org/iban4j/Iban.java b/src/main/java/org/iban4j/Iban.java index f7b1980..2998b21 100644 --- a/src/main/java/org/iban4j/Iban.java +++ b/src/main/java/org/iban4j/Iban.java @@ -413,11 +413,17 @@ public Iban build(boolean validate) throws IbanFormatException, */ public Iban buildRandom() throws IbanFormatException, IllegalArgumentException, UnsupportedCountryException { + + // Create a new seeded Random, so it doesn't matter how this Random is used, it won't affect subsequent usages + // of the original Random. (which can impact seeded behaviour when many IBANs are generated or the number of + // IBAN entries change). + final Random random = new Random(this.random.nextInt()); + if (countryCode == null) { List countryCodes = BbanStructure.supportedCountries(); this.countryCode(countryCodes.get(random.nextInt(countryCodes.size()))); } - fillMissingFieldsRandomly(); + fillMissingFieldsRandomly(random); return build(); } @@ -511,7 +517,7 @@ private void require(final CountryCode countryCode, } } - private void fillMissingFieldsRandomly() { + private void fillMissingFieldsRandomly(final Random random) { final BbanStructure structure = BbanStructure.forCountry(countryCode); if (structure == null) { diff --git a/src/main/java/org/iban4j/bban/BbanStructureEntry.java b/src/main/java/org/iban4j/bban/BbanStructureEntry.java index d0c5152..f06cd50 100644 --- a/src/main/java/org/iban4j/bban/BbanStructureEntry.java +++ b/src/main/java/org/iban4j/bban/BbanStructureEntry.java @@ -122,6 +122,12 @@ public String getRandom() { } public String getRandom(Random random) { + + // Create a new seeded Random, so it doesn't matter how this Random is used, it won't affect subsequent usages + // of the original Random. (which can impact seeded behaviour when many IBANs are generated or the number of + // IBAN entries change). + random = new Random(random.nextInt()); + StringBuilder s = new StringBuilder(); char[] charChoices = charByCharacterType.get(characterType); if (charChoices == null) { diff --git a/src/test/java/org/iban4j/IbanTest.java b/src/test/java/org/iban4j/IbanTest.java index 5626083..6deab51 100644 --- a/src/test/java/org/iban4j/IbanTest.java +++ b/src/test/java/org/iban4j/IbanTest.java @@ -15,22 +15,26 @@ */ package org.iban4j; -import org.junit.jupiter.api.Disabled; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.iban4j.TestDataHelper.defaultExceptionMessage; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.Random; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.util.Random; - -import static org.hamcrest.CoreMatchers.*; -import static org.hamcrest.MatcherAssert.*; -import static org.iban4j.TestDataHelper.defaultExceptionMessage; -import static org.junit.jupiter.api.Assertions.*; @DisplayName("Iban general test") public class IbanTest { - public static class IbanGenerationTest { - - @DisplayName("IBANs With Same Data Should Be Equal") + @DisplayName("IBANs With Same Data Should Be Equal") @Test public void ibansWithSameDataShouldBeEqual() { Iban iban1 = new Iban.Builder() @@ -287,14 +291,15 @@ public void ibanConstructionRandom() { } @Test - @Disabled public void ibanConstructionSeeded() { - assertIbanUtilRandomWithSeedEquals("FR87 8734 4468 89P1 RIYK UO5K 809", 1); - assertIbanUtilRandomWithSeedEquals("FI79 2079 0697 8464 44", 2); - assertIbanUtilRandomWithSeedEquals("FO71 0018 2949 1527 41", 3); + assertAll( + () -> assertIbanUtilRandomWithSeedEquals("GL41 1918 0836 9682 13", 1), + () -> assertIbanUtilRandomWithSeedEquals("FR17 0679 7098 8804 5NYW S75F D50", 2), + () -> assertIbanUtilRandomWithSeedEquals("EG45 0882 2804 0304 6660 9507 6091 3", 3) + ); } - private static void assertIbanUtilRandomWithSeedEquals( + private void assertIbanUtilRandomWithSeedEquals( String expected, int seed ) { @@ -307,11 +312,12 @@ private static void assertIbanUtilRandomWithSeedEquals( } @Test - @Disabled public void ibanBuilderConstructionSeeded() { - assertIbanBuilderRandomWithSeedEquals("FR87 8734 4468 89P1 RIYK UO5K 809", 1); - assertIbanBuilderRandomWithSeedEquals("FI79 2079 0697 8464 44", 2); - assertIbanBuilderRandomWithSeedEquals("FO71 0018 2949 1527 41", 3); + assertAll( + () -> assertIbanBuilderRandomWithSeedEquals("GL41 1918 0836 9682 13", 1), + () -> assertIbanBuilderRandomWithSeedEquals("FR17 0679 7098 8804 5NYW S75F D50", 2), + () -> assertIbanBuilderRandomWithSeedEquals("EG45 0882 2804 0304 6660 9507 6091 3", 3) + ); } private static void assertIbanBuilderRandomWithSeedEquals( @@ -430,5 +436,4 @@ public void ibanConstructionWithLackingNationalCheckDigitShouldThrowExceptionIfV defaultExceptionMessage); assertThat(thrown.getMessage(), containsString("nationalCheckDigit is required; it cannot be null")); } - } } diff --git a/src/test/java/org/iban4j/bban/BbanStructureEntryTest.java b/src/test/java/org/iban4j/bban/BbanStructureEntryTest.java index 14f95f5..a780341 100644 --- a/src/test/java/org/iban4j/bban/BbanStructureEntryTest.java +++ b/src/test/java/org/iban4j/bban/BbanStructureEntryTest.java @@ -1,11 +1,12 @@ package org.iban4j.bban; +import org.junit.jupiter.api.Test; + import java.nio.CharBuffer; import java.util.Objects; import java.util.Random; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -15,27 +16,33 @@ public class BbanStructureEntryTest { public void expectRandomAccountNumberIsDeterministicWhenSeeded() { BbanStructureEntry entry = BbanStructureEntry.accountNumber(10, 'a'); - assertSeededRandomBbanStructureEntryEquals(entry, "RAHJMYUWWK", 1); - assertSeededRandomBbanStructureEntryEquals(entry, "SGAVREIZNE", 2); - assertSeededRandomBbanStructureEntryEquals(entry, "SMMHQUVGJX", 3); + assertAll( + () -> assertSeededRandomBbanStructureEntryEquals(entry, "GYNPNTQMPP", 1), + () -> assertSeededRandomBbanStructureEntryEquals(entry, "ZBFUFVOHNJ", 2), + () -> assertSeededRandomBbanStructureEntryEquals(entry, "FHTOSEFCAR", 3) + ); } @Test public void expectRandomOwnerAccountNumberIsDeterministicWhenSeeded() { BbanStructureEntry entry = BbanStructureEntry.ownerAccountNumber(11, 'n'); - assertSeededRandomBbanStructureEntryEquals(entry, "58734446889", 1); - assertSeededRandomBbanStructureEntryEquals(entry, "82079069784", 2); - assertSeededRandomBbanStructureEntryEquals(entry, "40018294915", 3); + assertAll( + () -> assertSeededRandomBbanStructureEntryEquals(entry, "88511786533", 1), + () -> assertSeededRandomBbanStructureEntryEquals(entry, "33705581952", 2), + () -> assertSeededRandomBbanStructureEntryEquals(entry, "13164650831", 3) + ); } @Test public void expectRandomBankCodeIsDeterministicWhenSeeded() { BbanStructureEntry entry = BbanStructureEntry.bankCode(12, 'c'); - assertSeededRandomBbanStructureEntryEquals(entry, "XSJXQ4EAASPP", 1); - assertSeededRandomBbanStructureEntryEquals(entry, "4OKJX66R7O22", 2); - assertSeededRandomBbanStructureEntryEquals(entry, "EK6POILGJDLA", 3); + assertAll( + () -> assertSeededRandomBbanStructureEntryEquals(entry, "88FV9Z62HZ1T", 1), + () -> assertSeededRandomBbanStructureEntryEquals(entry, "T7F8TRELZ3I9", 2), + () -> assertSeededRandomBbanStructureEntryEquals(entry, "TXTOAA7SCPXB", 3) + ); } private static void assertSeededRandomBbanStructureEntryEquals( @@ -119,7 +126,7 @@ public void expectAlphabeticEntryGeneratesAllUppercaseLetters() { String distinctChars = getDistinctSortedChars(generated); assertEquals( - "ABCDEFGHIJKLMNOPQRSTUVWXYZ", + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", distinctChars ); }