001/*
002 * Copyright © 2025 CUI-OpenSource-Software (info@cuioss.de)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.cuioss.test.generator.impl;
017
018import de.cuioss.test.generator.TypedGenerator;
019
020import static de.cuioss.test.generator.Generators.nonEmptyStrings;
021
022/**
023 * Generates non-empty and non-blank string values for testing purposes.
024 * This generator ensures that the produced strings contain at least one
025 * non-whitespace character.
026 * 
027 * <p>Generation rules:</p>
028 * <ul>
029 *   <li>Uses {@link de.cuioss.test.generator.Generators#nonEmptyStrings()} as base generator</li>
030 *   <li>Validates that the string contains non-whitespace characters</li>
031 *   <li>Retries up to 100 times to generate a valid string</li>
032 *   <li>Throws {@link IllegalStateException} if no valid string can be generated</li>
033 * </ul>
034 * 
035 * <p><em>Example usage:</em></p>
036 * <pre>
037 * var generator = new NonBlankStringGenerator();
038 * String value = generator.next(); // Returns a string with at least one non-whitespace char
039 * </pre>
040 * 
041 * <p>This generator is particularly useful for testing input validation
042 * where whitespace-only strings should be treated differently from
043 * strings with actual content.</p>
044 *
045 * @author Oliver Wolff
046 * @see de.cuioss.test.generator.Generators#nonEmptyStrings()
047 */
048public class NonBlankStringGenerator implements TypedGenerator<String> {
049
050    private static final TypedGenerator<String> SOME_NONEMPTY_STRING = nonEmptyStrings();
051
052    @Override
053    public Class<String> getType() {
054        return String.class;
055    }
056
057    @Override
058    public String next() {
059        var tries = 0;
060        while (tries < 100) {
061            tries++;
062            var candidate = SOME_NONEMPTY_STRING.next();
063            if (!candidate.isBlank()) {
064                return candidate;
065            }
066        }
067        throw new IllegalStateException("Could not generate non blank string after %d tries".formatted(tries));
068    }
069
070}