### Question:
RecoveryCodeGenerator { public String[] generateDelimitedCodes(int numCodes, CodeGeneratorSource alphabet, char delimiter, boolean allowDuplicates, int... groups) throws CodeException { Reject.ifTrue(numCodes < 1, "numCodes must be greater than or equal to 1."); String[] recoveryCodes = new String[numCodes]; String result; for (int i = 0; i < numCodes; i++) { int counter = 0; do { result = generateDelimitedCode(alphabet, delimiter, groups); } while (!allowDuplicates && Arrays.asList(recoveryCodes).contains(result) && counter++ <= retryMaximum); if (counter >= retryMaximum) { throw new CodeException("Unable to generate unique codes with the given constraints."); } recoveryCodes[i] = result; } return recoveryCodes; } RecoveryCodeGenerator(SecureRandom secureRandom, int retryMaximum); @Inject  RecoveryCodeGenerator(SecureRandom secureRandom); String generateCode(CodeGeneratorSource alphabet, int length); String generateDelimitedCode(CodeGeneratorSource alphabet, char delimiter, int... groups); String generateDelimitedCodeWithSpecifics(CodeGeneratorSource alphabet, char delimiter,
                                                       Map<Integer, Character> specifics, int... groups); String[] generateCodes(int numCodes, CodeGeneratorSource alphabet, boolean allowDuplicates); String[] generateCodes(int numCodes, CodeGeneratorSource alphabet, int length, boolean allowDuplicates); String[] generateDelimitedCodes(int numCodes, CodeGeneratorSource alphabet,
                                           char delimiter, boolean allowDuplicates, int... groups); String[] generateDelimitedCodesWithSpecifics(int numCodes, CodeGeneratorSource alphabet,
                                                        char delimiter, Map<Integer, Character> specifics,
                                                        boolean allowDuplicates, int... groups); final static int DEFAULT_LENGTH; final static int DEFAULT_RETRIES; }### Answer:
@Test public void shouldGenerateDelimitedHexRandomCode() throws CodeException { String[] codes = recoveryCodeGenerator.generateDelimitedCodes(100, Alphabet.HEX_DIGITS, '-', true, 4, 4); for (String code : codes) { assertThat(HEX.matcher(code).matches()).isTrue(); assertThat(code.charAt(4)).isEqualTo('-'); assertThat(code.length()).isEqualTo(9); } }
@Test public void shouldGenerateDuplicateCodes2() throws CodeException { String[] codes = recoveryCodeGenerator.generateDelimitedCodes(2, new TestAlphabet(), '-', true, 1, 1); for (String code : codes) { assertThat(code).isEqualTo("A-A"); } }
@Test (expectedExceptions = CodeException.class) public void shouldErrorGeneratingDuplicateCodes2() throws CodeException { recoveryCodeGenerator.generateDelimitedCodes(2, new TestAlphabet(), '-', false, 1); }
@Test (expectedExceptions = IllegalArgumentException.class) public void shouldErrorRequestedSizeTooSmall2() throws CodeException { recoveryCodeGenerator.generateDelimitedCodes(0, new TestAlphabet(), '-', true, 1); }
@Test (expectedExceptions = NullPointerException.class) public void shouldErrorNullAlphabet2() throws CodeException { recoveryCodeGenerator.generateDelimitedCodes(10, null, '-', true, 1); }
@Test (expectedExceptions = IllegalArgumentException.class) public void shouldErrorNullGroups2() throws CodeException { recoveryCodeGenerator.generateDelimitedCodes(10, new TestAlphabet(), '-', true); }
@Test (expectedExceptions = IllegalArgumentException.class) public void shouldErrorGroupsUndefined() throws CodeException { recoveryCodeGenerator.generateDelimitedCodes(10, new TestAlphabet(), '-', true); }
@Test (expectedExceptions = IllegalArgumentException.class) public void shouldErrorGroupTooSmall2() throws CodeException { recoveryCodeGenerator.generateDelimitedCodes(10, new TestAlphabet(), '-', true, 1, 0); }