001// Generated by delombok at Fri Mar 03 18:26:02 UTC 2023
002package de.cuioss.test.generator;
003
004import static de.cuioss.tools.collect.CollectionLiterals.mutableList;
005import static java.util.Objects.requireNonNull;
006import java.io.Serializable;
007import java.net.URL;
008import java.time.LocalDate;
009import java.time.LocalDateTime;
010import java.time.LocalTime;
011import java.time.ZoneId;
012import java.time.ZoneOffset;
013import java.time.ZonedDateTime;
014import java.time.temporal.Temporal;
015import java.util.ArrayList;
016import java.util.Arrays;
017import java.util.Collection;
018import java.util.Date;
019import java.util.List;
020import java.util.Locale;
021import java.util.Optional;
022import java.util.TimeZone;
023import java.util.stream.Collectors;
024import de.cuioss.test.generator.impl.CollectionGenerator;
025import de.cuioss.test.generator.impl.DecoratorGenerator;
026import de.cuioss.test.generator.impl.FloatObjectGenerator;
027import de.cuioss.test.generator.impl.LocalDateGenerator;
028import de.cuioss.test.generator.impl.LocalDateTimeGenerator;
029import de.cuioss.test.generator.impl.LocalTimeGenerator;
030import de.cuioss.test.generator.impl.NonBlankStringGenerator;
031import de.cuioss.test.generator.impl.NumberGenerator;
032import de.cuioss.test.generator.impl.ShortObjectGenerator;
033import de.cuioss.test.generator.impl.URLGenerator;
034import de.cuioss.test.generator.impl.ZoneOffsetGenerator;
035import de.cuioss.test.generator.impl.ZonedDateTimeGenerator;
036import de.cuioss.test.generator.internal.net.QuickCheckGeneratorAdapter;
037import de.cuioss.test.generator.internal.net.java.quickcheck.Generator;
038import de.cuioss.test.generator.internal.net.java.quickcheck.generator.CombinedGenerators;
039import de.cuioss.test.generator.internal.net.java.quickcheck.generator.PrimitiveGenerators;
040import de.cuioss.test.generator.internal.net.java.quickcheck.generator.support.FixedValuesGenerator;
041
042/**
043 * Provides a number of {@link TypedGenerator} for arbitrary java-types
044 *
045 * @author Oliver Wolff
046 */
047public final class Generators {
048    /**
049     * Factory method for creating a generator for a possible given enum.
050     *
051     * @param type to be checked must represent an enum
052     * @return an {@link Optional} on the corresponding {@link TypedGenerator} if the given type is
053     *         an enum can be found, {@link Optional#empty()} otherwise
054     */
055    @SuppressWarnings({"rawtypes", "unchecked"})
056    public static <T> Optional<TypedGenerator<T>> enumValuesIfAvailable(final Class<T> type) {
057        if (null == type || !type.isEnum()) {
058            return Optional.empty();
059        }
060        return Optional.of(new QuickCheckGeneratorAdapter(type, PrimitiveGenerators.enumValues((Class<Enum>) type)));
061    }
062
063    /**
064     * Factory method for creating a generator for a given enum.
065     *
066     * @param type to be checked must represent an enum
067     * @return A {@link TypedGenerator} for the given enmu
068     */
069    public static <T extends Enum<T>> TypedGenerator<T> enumValues(final Class<T> type) {
070        requireNonNull(type);
071        return new QuickCheckGeneratorAdapter<>(type, PrimitiveGenerators.enumValues(type));
072    }
073
074    /**
075     * Factory method for creating a {@link TypedGenerator} for non-empty Strings.
076     *
077     * @return a {@link TypedGenerator} for non-empty Strings
078     */
079    public static TypedGenerator<String> nonEmptyStrings() {
080        return new QuickCheckGeneratorAdapter<>(String.class, PrimitiveGenerators.nonEmptyStrings());
081    }
082
083    /**
084     * Factory method for creating a {@link TypedGenerator} for non-blank Strings.
085     *
086     * @return a {@link TypedGenerator} for non-blank Strings.
087     */
088    public static TypedGenerator<String> nonBlankStrings() {
089        return new NonBlankStringGenerator();
090    }
091
092    /**
093     * Factory method for creating a {@link TypedGenerator} for Strings.
094     *
095     * @param minSize lower bound of size
096     * @param maxSize upper bound of size
097     * @return a {@link TypedGenerator} for Strings
098     */
099    public static TypedGenerator<String> strings(final int minSize, final int maxSize) {
100        return new QuickCheckGeneratorAdapter<>(String.class, PrimitiveGenerators.strings(minSize, maxSize));
101    }
102
103    /**
104     * Factory method for creating strings with given characters and size.
105     *
106     * @param chars to be generated
107     * @param minSize lower bound of size
108     * @param maxSize upper bound of size
109     * @return a {@link TypedGenerator} for Strings
110     */
111    public static TypedGenerator<String> strings(final String chars, final int minSize, final int maxSize) {
112        return new QuickCheckGeneratorAdapter<>(String.class, PrimitiveGenerators.strings(chars, minSize, maxSize));
113    }
114
115    /**
116     * Factory method for creating a {@link TypedGenerator} for any Strings, may be null or empty.
117     *
118     * @return a {@link TypedGenerator} for Strings
119     */
120    public static TypedGenerator<String> strings() {
121        return new QuickCheckGeneratorAdapter<>(String.class, PrimitiveGenerators.strings());
122    }
123
124    /**
125     * Factory method for creating a {@link TypedGenerator} for letter Strings.
126     *
127     * @param minSize lower bound of size
128     * @param maxSize upper bound of size
129     * @return a {@link TypedGenerator} for Strings
130     */
131    public static TypedGenerator<String> letterStrings(final int minSize, final int maxSize) {
132        return new QuickCheckGeneratorAdapter<>(String.class, PrimitiveGenerators.letterStrings(minSize, maxSize));
133    }
134
135    /**
136     * Factory method for creating a {@link TypedGenerator} for sensible / simple non empty letter
137     * Strings. The mininmal size is 3, the maximal size between 3 and 256 characters
138     *
139     * @return a {@link TypedGenerator} for Strings
140     */
141    public static TypedGenerator<String> letterStrings() {
142        return letterStrings(3, integers(3, 256).next());
143    }
144
145    /**
146     * Factory method for creating a {@link TypedGenerator} for a number of fixed values.
147     *
148     * @param type of the value
149     * @param values to be generated from.
150     * @return a {@link TypedGenerator} for the given values
151     */
152    @SafeVarargs
153    public static <T> TypedGenerator<T> fixedValues(final Class<T> type, final T... values) {
154        return fixedValues(type, Arrays.asList(values));
155    }
156
157    /**
158     * Factory method for creating a {@link TypedGenerator} for a number of fixed values.
159     *
160     * @param values to be generated from.
161     * @return a {@link TypedGenerator} for the given values
162     */
163    @SafeVarargs
164    public static <T> TypedGenerator<T> fixedValues(final T... values) {
165        return fixedValues(Arrays.asList(values));
166    }
167
168    /**
169     * Factory method for creating a {@link TypedGenerator} for a number of fixed values.
170     *
171     * @param type of the value
172     * @param values to be generated from.
173     * @return a {@link TypedGenerator} for the given values
174     */
175    public static <T> TypedGenerator<T> fixedValues(final Class<T> type, final Iterable<T> values) {
176        return new QuickCheckGeneratorAdapter<>(type, new FixedValuesGenerator<>(mutableList(values)));
177    }
178
179    /**
180     * Factory method for creating a {@link TypedGenerator} for a number of fixed values.
181     *
182     * @param values to be generated from.
183     * @return a {@link TypedGenerator} for the given values
184     */
185    public static <T> TypedGenerator<T> fixedValues(final Iterable<T> values) {
186        return fixedValues(determineSupertypeFromIterable(values), values);
187    }
188
189    /* Combined generators */
190    // Check not needed, because given TypedGenerator provides
191    // correct type
192    /**
193     * Factory method for creating a {@link TypedGenerator} generating unique values. In case this
194     * does not work it will throw an {@link RuntimeException}
195     *
196     * @param source to be generated from.
197     * @return a {@link TypedGenerator} for the given values
198     */
199    @SuppressWarnings("unchecked")
200    public static <T> TypedGenerator<T> uniqueValues(final TypedGenerator<T> source) {
201        return new QuickCheckGeneratorAdapter<>((Class<T>) source.getClass(), CombinedGenerators.uniqueValues(unwrap(source)));
202    }
203
204    /**
205     * Factory method for creating a {@link CollectionGenerator} generating {@link Collection}s from
206     * the given {@link TypedGenerator} .
207     *
208     * @param source to be generated from.
209     * @return a {@link TypedGenerator} for the given values
210     */
211    public static <T> CollectionGenerator<T> asCollectionGenerator(final TypedGenerator<T> source) {
212        return new CollectionGenerator<>(source);
213    }
214
215    // Basic Java Types
216    /**
217     * Factory method for creating a {@link TypedGenerator} for boolean primitives.
218     *
219     * @return a {@link TypedGenerator} for boolean primitives
220     */
221    public static TypedGenerator<Boolean> booleans() {
222        return new QuickCheckGeneratorAdapter<>(boolean.class, PrimitiveGenerators.booleans());
223    }
224
225    /**
226     * Factory method for creating a {@link TypedGenerator} for {@link Boolean}.
227     *
228     * @return a {@link TypedGenerator} for {@link Boolean}
229     */
230    public static TypedGenerator<Boolean> booleanObjects() {
231        return new QuickCheckGeneratorAdapter<>(Boolean.class, PrimitiveGenerators.booleans());
232    }
233
234    /**
235     * Factory method for creating a {@link TypedGenerator} for byte primitives.
236     *
237     * @return a {@link TypedGenerator} for byte primitives
238     */
239    public static TypedGenerator<Byte> bytes() {
240        return new QuickCheckGeneratorAdapter<>(byte.class, PrimitiveGenerators.bytes());
241    }
242
243    /**
244     * Factory method for creating a {@link TypedGenerator} for {@link Byte}.
245     *
246     * @return a {@link TypedGenerator} for {@link Byte}
247     */
248    public static TypedGenerator<Byte> byteObjects() {
249        return new QuickCheckGeneratorAdapter<>(Byte.class, PrimitiveGenerators.bytes());
250    }
251
252    /**
253     * Factory method for creating a {@link TypedGenerator} for char primitives.
254     *
255     * @return a {@link TypedGenerator} for char primitives
256     */
257    public static TypedGenerator<Character> characters() {
258        return new QuickCheckGeneratorAdapter<>(char.class, PrimitiveGenerators.characters());
259    }
260
261    /**
262     * Factory method for creating a {@link TypedGenerator} for {@link Character}.
263     *
264     * @return a {@link TypedGenerator} for {@link Character}
265     */
266    public static TypedGenerator<Character> characterObjects() {
267        return new QuickCheckGeneratorAdapter<>(Character.class, PrimitiveGenerators.characters());
268    }
269
270    /**
271     * Factory method for creating a {@link TypedGenerator} for double primitives.
272     *
273     * @return a {@link TypedGenerator} for double primitives
274     */
275    public static TypedGenerator<Double> doubles() {
276        return new QuickCheckGeneratorAdapter<>(double.class, PrimitiveGenerators.doubles());
277    }
278
279    /**
280     * Factory method for creating a {@link TypedGenerator} for {@link Double}.
281     *
282     * @param low lower bound of range
283     * @param high upper bound of range
284     * @return a {@link TypedGenerator} for {@link Double}
285     */
286    public static TypedGenerator<Double> doubles(final double low, final double high) {
287        return new QuickCheckGeneratorAdapter<>(Double.class, PrimitiveGenerators.doubles(low, high));
288    }
289
290    /**
291     * Factory method for creating a {@link TypedGenerator} for {@link Double}.
292     *
293     * @return a {@link TypedGenerator} for {@link Double}
294     */
295    public static TypedGenerator<Double> doubleObjects() {
296        return new QuickCheckGeneratorAdapter<>(Double.class, PrimitiveGenerators.doubles());
297    }
298
299    /**
300     * Factory method for creating a {@link TypedGenerator} for float primitives.
301     *
302     * @return a {@link TypedGenerator} for float primitives
303     */
304    public static TypedGenerator<Float> floats() {
305        return new DecoratorGenerator<>(float.class, floatObjects());
306    }
307
308    /**
309     * Factory method for creating a {@link TypedGenerator} for {@link Float}.
310     *
311     * @param low lower bound of range
312     * @param high upper bound of range
313     * @return a {@link TypedGenerator} for {@link Float}
314     */
315    public static TypedGenerator<Float> floats(final float low, final float high) {
316        return new FloatObjectGenerator(low, high);
317    }
318
319    /**
320     * Factory method for creating a {@link TypedGenerator} for {@link Float}.
321     *
322     * @return a {@link TypedGenerator} for {@link Float}
323     */
324    public static TypedGenerator<Float> floatObjects() {
325        return new FloatObjectGenerator();
326    }
327
328    /**
329     * Factory method for creating a {@link TypedGenerator} for integer primitives.
330     *
331     * @return a {@link TypedGenerator} for integer primitives
332     */
333    public static TypedGenerator<Integer> integers() {
334        return new QuickCheckGeneratorAdapter<>(int.class, PrimitiveGenerators.integers());
335    }
336
337    /**
338     * Factory method for creating a {@link TypedGenerator} for {@link Integer}.
339     *
340     * @param low lower bound of range
341     * @param high upper bound of range
342     * @return a {@link TypedGenerator} for {@link Integer}
343     */
344    public static TypedGenerator<Integer> integers(final int low, final int high) {
345        return new QuickCheckGeneratorAdapter<>(Integer.class, PrimitiveGenerators.integers(low, high));
346    }
347
348    /**
349     * Factory method for creating a {@link TypedGenerator} for {@link Integer}.
350     *
351     * @return a {@link TypedGenerator} for {@link Integer}
352     */
353    public static TypedGenerator<Integer> integerObjects() {
354        return new QuickCheckGeneratorAdapter<>(Integer.class, PrimitiveGenerators.integers());
355    }
356
357    /**
358     * Factory method for creating a {@link TypedGenerator} for {@link Number}.
359     *
360     * @return a {@link TypedGenerator} for {@link Number}
361     */
362    public static TypedGenerator<Number> numbers() {
363        return new NumberGenerator();
364    }
365
366    /**
367     * Factory method for creating a {@link TypedGenerator} for short primitives.
368     *
369     * @return a {@link TypedGenerator} for short primitives
370     */
371    public static TypedGenerator<Short> shorts() {
372        return new DecoratorGenerator<>(short.class, shortObjects());
373    }
374
375    /**
376     * Factory method for creating a {@link TypedGenerator} for {@link Short}.
377     *
378     * @return a {@link TypedGenerator} for {@link Short}
379     */
380    public static TypedGenerator<Short> shortObjects() {
381        return new ShortObjectGenerator();
382    }
383
384    /**
385     * Factory method for creating a {@link TypedGenerator} for long primitives.
386     *
387     * @return a {@link TypedGenerator} for long primitives
388     */
389    public static TypedGenerator<Long> longs() {
390        return new QuickCheckGeneratorAdapter<>(long.class, PrimitiveGenerators.longs());
391    }
392
393    /**
394     * Factory method for creating a {@link TypedGenerator} for Long primitives.
395     *
396     * @param low lower bound of range
397     * @param high upper bound of range
398     * @return a {@link TypedGenerator} for long primitives
399     */
400    public static TypedGenerator<Long> longs(final long low, final long high) {
401        return new QuickCheckGeneratorAdapter<>(long.class, PrimitiveGenerators.longs(low, high));
402    }
403
404    /**
405     * Factory method for creating a {@link TypedGenerator} for {@link Long}.
406     *
407     * @return a {@link TypedGenerator} for {@link Long}
408     */
409    public static TypedGenerator<Long> longObjects() {
410        return new QuickCheckGeneratorAdapter<>(Long.class, PrimitiveGenerators.longs());
411    }
412
413    /**
414     * Factory method for creating a {@link TypedGenerator} for {@link Date}.
415     *
416     * @return a {@link TypedGenerator} for {@link Date}
417     */
418    public static TypedGenerator<Date> dates() {
419        return new QuickCheckGeneratorAdapter<>(Date.class, PrimitiveGenerators.dates());
420    }
421
422    /**
423     * Factory method for creating a {@link TypedGenerator} for {@link LocalDate}.
424     *
425     * @return a {@link TypedGenerator} for {@link LocalDate}
426     */
427    public static TypedGenerator<LocalDate> localDates() {
428        return new LocalDateGenerator();
429    }
430
431    /**
432     * Factory method for creating a {@link TypedGenerator} for {@link LocalTime}.
433     *
434     * @return a {@link TypedGenerator} for {@link LocalTime}
435     */
436    public static TypedGenerator<LocalTime> localTimes() {
437        return new LocalTimeGenerator();
438    }
439
440    /**
441     * Factory method for creating a {@link TypedGenerator} for {@link LocalDateTime}.
442     *
443     * @return a {@link TypedGenerator} for {@link LocalDateTime}
444     */
445    public static TypedGenerator<LocalDateTime> localDateTimes() {
446        return new LocalDateTimeGenerator();
447    }
448
449    /**
450     * Factory method for creating a {@link TypedGenerator} for {@link ZonedDateTime}.
451     *
452     * @return a {@link TypedGenerator} for {@link ZonedDateTime}
453     */
454    public static TypedGenerator<ZonedDateTime> zonedDateTimes() {
455        return new ZonedDateTimeGenerator();
456    }
457
458    /**
459     * Factory method for creating a {@link TypedGenerator} for {@link TimeZone}.
460     *
461     * @return a {@link TypedGenerator} for {@link TimeZone}
462     */
463    public static TypedGenerator<TimeZone> timeZones() {
464        final List<TimeZone> timezones = new ArrayList<>();
465        for (final String id : TimeZone.getAvailableIDs()) {
466            timezones.add(TimeZone.getTimeZone(id));
467        }
468        return fixedValues(TimeZone.class, timezones);
469    }
470
471    /**
472     * Factory method for creating a {@link TypedGenerator} for {@link ZoneId}.
473     *
474     * @return a {@link TypedGenerator} for {@link ZoneId}
475     */
476    public static TypedGenerator<ZoneId> zoneIds() {
477        return fixedValues(ZoneId.class, ZoneId.getAvailableZoneIds().stream().map(ZoneId::of).collect(Collectors.toList()));
478    }
479
480    /**
481     * Factory method for creating a {@link TypedGenerator} for {@link ZoneOffset}.
482     *
483     * @return a {@link TypedGenerator} for {@link ZoneOffset}
484     */
485    public static TypedGenerator<ZoneOffset> zoneOffsets() {
486        return new ZoneOffsetGenerator();
487    }
488
489    /**
490     * Factory method for creating a {@link TypedGenerator} for {@link Temporal}s.
491     *
492     * @return a {@link TypedGenerator} for {@link Temporal}s
493     */
494    public static TypedGenerator<Temporal> temporals() {
495        return new TypedGenerator<>() {
496            @Override
497            public Class<Temporal> getType() {
498                return Temporal.class;
499            }
500            @Override
501            public Temporal next() {
502                return zonedDateTimes().next().toInstant();
503            }
504        };
505    }
506
507    // Advanced Java Types
508    /**
509     * Factory method for creating a {@link TypedGenerator} arbitrary {@link Class} Objects
510     *
511     * @return a {@link TypedGenerator} for the given values
512     */
513    @SuppressWarnings("rawtypes")
514    public static TypedGenerator<Class> classTypes() {
515        return fixedValues(Class.class, Integer.class, String.class, Boolean.class, Float.class);
516    }
517
518    /**
519     * Factory method for creating a {@link TypedGenerator} arbitrary {@link Locale} Objects
520     *
521     * @return a {@link TypedGenerator} for all {@link Locale}s
522     */
523    public static TypedGenerator<Locale> locales() {
524        return fixedValues(Locale.class, Locale.getAvailableLocales());
525    }
526
527    /**
528     * Factory method for creating a {@link TypedGenerator} arbitrary {@link Serializable} Objects
529     *
530     * @return a {@link TypedGenerator} for all {@link Serializable}s
531     */
532    @SuppressWarnings({"unchecked", "rawtypes"})
533    public static TypedGenerator<Serializable> serializables() {
534        return new QuickCheckGeneratorAdapter(Serializable.class, PrimitiveGenerators.nonEmptyStrings());
535    }
536
537    /**
538     * Factory method for creating a {@link TypedGenerator} arbitrary {@link RuntimeException}
539     * Objects
540     *
541     * @return a {@link TypedGenerator} for all {@link RuntimeException}s
542     */
543    public static TypedGenerator<RuntimeException> runtimeExceptions() {
544        return fixedValues(RuntimeException.class, new RuntimeException(), new IllegalArgumentException(), new IllegalStateException(), new NullPointerException());
545    }
546
547    /**
548     * Factory method for creating a {@link TypedGenerator} arbitrary {@link Throwable}
549     * Objects
550     *
551     * @return a {@link TypedGenerator} for all {@link Throwable}s
552     */
553    public static TypedGenerator<Throwable> throwables() {
554        return fixedValues(Throwable.class, new RuntimeException(), new IllegalArgumentException(), new IllegalStateException(), new NullPointerException());
555    }
556
557    /**
558     * Factory method for creating a {@link TypedGenerator} arbitrary {@link URL}s
559     * Objects
560     *
561     * @return a {@link TypedGenerator} for all {@link URL}s
562     */
563    public static TypedGenerator<URL> urls() {
564        return new URLGenerator();
565    }
566
567    /**
568     * Factory method for creating a {@link TypedGenerator} from an existing QuickCheck
569     * {@link Generator}. Note: This method is for internal use only and will be removed soon!!!
570     *
571     * @param qcGenerator to be wrapped
572     * @param type of the value
573     * @return a {@link TypedGenerator} for the given {@link Generator}
574     */
575    static <T> TypedGenerator<T> wrap(final Class<T> type, final Generator<T> qcGenerator) {
576        return new QuickCheckGeneratorAdapter<>(type, qcGenerator);
577    }
578
579    /**
580     * Factory method for creating a QuickCheck {@link Generator} from an existing
581     * {@link TypedGenerator}. Note: This method is for internal
582     * use only and will be removed soon!!!
583     *
584     * @param generator to be un-wrapped
585     * @return a {@link TypedGenerator} for the given {@link Generator}
586     */
587    static <T> Generator<T> unwrap(final TypedGenerator<T> generator) {
588        return generator::next;
589    }
590
591    /**
592     * Helper method that determines the actual type of a given {@link Iterable} by peeking into it.
593     * <em>For testing only, should never be used in productive code</em>
594     *
595     * @param iterable must not be null nor empty, the iterator must be reentrant.
596     * @return The Class of the given {@link Iterable}.
597     */
598    @SuppressWarnings("unchecked")
599    private static <T> Class<T> determineSupertypeFromIterable(final Iterable<T> iterable) {
600        requireNonNull(iterable, "iterable must not be null");
601        final var iterator = iterable.iterator();
602        if (iterator.hasNext()) {
603            return (Class<T>) iterator.next().getClass();
604        }
605        throw new IllegalArgumentException("Must contain at least a single element");
606    }
607
608    @java.lang.SuppressWarnings("all")
609    @lombok.Generated
610    private Generators() {
611        throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated");
612    }
613}