Package net.java.quickcheck.generator

Source Code of net.java.quickcheck.generator.CombinedGenerators

/*
*  Licensed to the author under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package net.java.quickcheck.generator;

import static net.java.quickcheck.generator.PrimitiveGenerators.*;
import static net.java.quickcheck.generator.support.ListGenerator.*;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import net.java.quickcheck.ExtendibleGenerator;
import net.java.quickcheck.FrequencyGenerator;
import net.java.quickcheck.Generator;
import net.java.quickcheck.GeneratorException;
import net.java.quickcheck.StatefulGenerator;
import net.java.quickcheck.collection.Pair;
import net.java.quickcheck.collection.Triple;
import net.java.quickcheck.generator.distribution.Distribution;
import net.java.quickcheck.generator.support.ArrayGenerator;
import net.java.quickcheck.generator.support.ByteArrayGenerator;
import net.java.quickcheck.generator.support.DefaultFrequencyGenerator;
import net.java.quickcheck.generator.support.EnsuredValuesGenerator;
import net.java.quickcheck.generator.support.ExcludingGenerator;
import net.java.quickcheck.generator.support.FixedValuesGenerator;
import net.java.quickcheck.generator.support.IntegerArrayGenerator;
import net.java.quickcheck.generator.support.IntegerGenerator;
import net.java.quickcheck.generator.support.IteratorGenerator;
import net.java.quickcheck.generator.support.ListGenerator;
import net.java.quickcheck.generator.support.SetGenerator;
import net.java.quickcheck.generator.support.SortedListGenerator;
import net.java.quickcheck.generator.support.TupleGenerator;
import net.java.quickcheck.generator.support.UniqueValuesGenerator;
import net.java.quickcheck.srcgenerator.Iterables;
import net.java.quickcheck.srcgenerator.Samples;

/**
* {@link CombinedGenerators} can be used to create custom {@link Generator}s.
*/
@Iterables
@Samples
public class CombinedGenerators {

  public static final int DEFAULT_COLLECTION_MAX_SIZE = ListGenerator.MAX_SIZE;
 
  /**
   * <p>
   * Create a frequency generator. The frequency of {@link Generator} usage
   * depends on the generator weight.
   * </p>
   *
   * @param generator
   *            pairs of generators and their weights used to created the
   *            values
   * @param <T>
   *            type of values generated by the generators.
   */
  public static <T> FrequencyGenerator<T> frequency(Generator<T> generator,
      int weight) {
    return new DefaultFrequencyGenerator<T>(generator, weight);
  }

  /**
   * OneOf is a convenience method for
   * {@link CombinedGenerators#frequency(Generator, int)} when all generator
   * share the same weight.
   */
  public static <T> ExtendibleGenerator<T, T> oneOf(Generator<T> generator) {
    return frequency(generator, 1);
  }

  /**
   * Create a generator which will create vectors (here lists) of type T.
   *
   * @param <T>
   *            Type of the list values.
   * @param size
   *            Number of element in the vector.
   */
  public static <T> Generator<List<T>> vectors(Generator<T> content, int size) {
    return new ListGenerator<T>(content, new FixedValuesGenerator<Integer>(size));
  }

  /**
   * Create a generator of pairs of type A for the left value and type B for
   * the right value.
   *
   * @param <A>
   *            Type of left value.
   * @param <B>
   *            Type of right value.
   * @param first
   *            Generator for left values.
   * @param second
   *            Generator for right values.
   */
  public static <A, B> Generator<Pair<A, B>> pairs(Generator<A> first, Generator<B> second) {
    final TupleGenerator generator = new TupleGenerator(first, second);
    return new Generator<Pair<A, B>>() {
      @SuppressWarnings("unchecked")
      public Pair<A, B> next() {
        Object[] next = generator.next();
        return new Pair(next[0], next[1]);
      }
    };
  }

  /**
   * Create a generator of triples of the types A, B and C for first, second
   * and third value.
   *
   * @param <A>
   *            Type of first value.
   * @param <B>
   *            Type of second value.
   * @param <C>
   *            Type of third value.
   * @param first
   *            Generator for first values.
   * @param second
   *            Generator for second values.
   * @param third
   *            Generator for third values.
   */
  public static <A, B, C> Generator<Triple<A, B, C>> triples(Generator<A> first, Generator<B> second,
      Generator<C> third) {
    final TupleGenerator generator = new TupleGenerator(first, second, third);
    return new Generator<Triple<A, B, C>>() {
      @SuppressWarnings("unchecked")
      public Triple<A, B, C> next() {
        Object[] next = generator.next();
        return new Triple<A, B, C>((A) next[0], (B) next[1], (C) next[2]);
      }
    };
  }
 
  /**
   * Create a generator as a combination of a null value generator and
   * generator of type T.
   *
   * @param <T>
   *            Type of the values generated.
   */
  public static <T> Generator<T> nullsAnd(Generator<T> generator) {
    return nullsAnd(generator, 5);
  }

  /**
   * Create a generator as a combination of a null value generator and
   * generator of type T.
   *
   * @param <T>
   *            Type of the values generated.
   * @param weight
   *            weight of the provided generator
   */
  public static <T> Generator<T> nullsAnd(Generator<T> generator, int weight) {
    return new DefaultFrequencyGenerator<T>(PrimitiveGenerators.<T> nulls(), 1).add(generator, weight);
  }

  /**
   * Create a generator of sets with values from the content generator.
   *
   * @param <T>
   *            type of set elements generated
   * @param content
   *            generator providing the content of sets generated
   */
  public static <T> Generator<Set<T>> sets(Generator<T> content) {
    return new SetGenerator<T>(content);
  }

  /**
   * Create a generator of sets with values from the content generator.
   *
   * @param <T>
   *            type of set elements generated
   * @param content
   *            generator providing the content of sets generated
   * @param size
   *            size of the sets generated
   */
  public static <T> Generator<Set<T>> sets(Generator<T> content,
      Generator<Integer> size) {
    return new SetGenerator<T>(content, size);
  }

  /**
   * Create a generator of sets with values from the content generator. Length
   * is between high and low.
   *
   * @param <T>
   *            type of set elements generated
   * @param content
   *            generator providing the content of sets generated
   * @param low
   *            minimal size
   * @param high
   *            max size
   */
  public static <T> Generator<Set<T>> sets(Generator<T> content, int low,
      int high) {
    return new SetGenerator<T>(content, integers(low, high));
  }

  /**
   * Create a generator of sets that are not empty.
   *
   * @param <T>
   *            type of set elements generated
   * @param content
   *            generator providing the content of sets generated
   */
  public static <T> Generator<Set<T>> nonEmptySets(Generator<T> content) {
    return sets(content, 1, SetGenerator.MAX_SIZE);
  }

  /**
   * Create a generator of iterators.
   *
   * <p>
   * Values of the elements will be taken from the content generator.
   * </p>
   *
   * @param <T>
   *            type of iterator elements generated
   * @param content
   *            generator providing the content of iterators generated
   */
  public static <T> Generator<Iterator<T>> iterators(Generator<T> content) {
    return new IteratorGenerator<T>(content);
  }

  /**
   * Create a generator of iterators.
   *
   * <p>
   * Values of the elements will be taken from the content generator. The
   * generated iterator will have at least one element.
   * </p>
   *
   * @param <T>
   *            type of iterator elements generated
   * @param content
   *            generator providing the content of iterators generated
   */
  public static <T> Generator<Iterator<T>> nonEmptyIterators(
      Generator<T> content) {
    return new IteratorGenerator<T>(content, 1, IteratorGenerator.MAX_SIZE);
  }

  /**
   * Create a generator of iterators.
   *
   * <p>
   * Values of the elements will be taken from the content generator. The
   * length of the iterators will be determined with the size generator.
   * </p>
   *
   * @param <T>
   *            type of iterator elements generated
   * @param content
   *            generator providing the content of iterators generated
   * @param size
   *            used to determine the number of elements of the iterator
   */
  public static <T> Generator<Iterator<T>> iterators(Generator<T> content,
      Generator<Integer> size) {
    return new IteratorGenerator<T>(content, size);
  }

  /**
   * Create a generator of lists with values from the content generator.
   * Length values of lists generated will be created with
   * {@link Distribution#UNIFORM}.
   *
   * @param <T>
   *            type of list elements generated
   * @param content
   *            generator providing the content of lists generated
   */
  public static <T> Generator<List<T>> lists(Generator<T> content) {
    return new ListGenerator<T>(content);
  }

  /**
   * Create a generator of non-empty lists with values from the content
   * generator. Length values of lists generated will be created with
   * {@link Distribution#UNIFORM}.
   *
   * @param <T>
   *            type of list elements generated
   * @param content
   *            generator providing the content of lists generated
   */
  public static <T> Generator<List<T>> nonEmptyLists(Generator<T> content) {
    return lists(content, positiveIntegers(MAX_SIZE));
  }

  /**
   * Create a generator of lists with values from the content generator.
   * Length values of lists generated will be created with size generator.
   *
   * @param <T>
   *            type of list elements generated
   * @param content
   *            generator providing the content of lists generated
   * @param size
   *            integer used to determine the list size
   */
  public static <T> Generator<List<T>> lists(Generator<T> content,
      Generator<Integer> size) {
    return new ListGenerator<T>(content, size);
  }

  /**
   * Create a generator of lists with values from the content generator.
   * Length is between high and low.
   *
   * @param <T>
   *            type of list elements generated
   * @param content
   *            generator providing the content of lists generated
   * @param low
   *            minimal size
   * @param high
   *            max size
   */
  public static <T> Generator<List<T>> lists(Generator<T> content, int low,
      int high) {
    return lists(content, new IntegerGenerator(low, high));
  }

  /**
   * Create a generator of lists with values from the content generator.
   * Length is at least low.
   *
   * @param <T>
   *            type of list elements generated
   * @param content
   *            generator providing the content of lists generated
   * @param low
   *            minimal size
   */
  //TODO bug if low is > MAX_SIZE
  public static <T> Generator<List<T>> lists(Generator<T> content, int low) {
    return lists(content, low, ListGenerator.MAX_SIZE);
  }

  /**
   * Create a generator of sorted lists with values from the content
   * generator.
   *
   * @param <T>
   *            type of list elements generated
   * @param content
   *            generator providing the content of lists generated
   */
  public static <T extends Comparable<T>> Generator<List<T>> sortedLists(
      Generator<T> content) {
    return new SortedListGenerator<T>(content);

  }

  /**
   * Create a generator of sorted lists with values from the content
   * generator. Length is between high and low.
   *
   * @param <T>
   *            type of list elements generated
   * @param content
   *            generator providing the content of lists generated
   * @param low
   *            minimal size
   * @param high
   *            max size
   */
  public static <T extends Comparable<T>> Generator<List<T>> sortedLists(
      Generator<T> content, int low, int high) {
    return sortedLists(content, integers(low, high));

  }

  /**
   * Create a generator of sorted lists with values from the content
   * generator. Length is between high and low.
   *
   * @param <T>
   *            type of list elements generated
   * @param content
   *            generator providing the content of lists generated
   * @param size
   *            integer used to determine the list size
   */
  public static <T extends Comparable<T>> Generator<List<T>> sortedLists(
      Generator<T> content, Generator<Integer> size) {
    return new SortedListGenerator<T>(content, size);
  }

  /**
   * Create a generator of arrays with values from the content generator.
   * Length values of array generated will be created with
   * {@link Distribution#UNIFORM}.
   *
   * @param <T>
   *            type of arrays elements generated
   * @param content
   *            generator providing the content of arrays generated
   * @param type
   *            type of arrays generated
   */
  public static <T> Generator<T[]> arrays(Generator<T> content, Class<T> type) {
    return new ArrayGenerator<T>(content, type);
  }

  /**
   * Create a generator of arrays that are not empty.
   *
   * @param <T>
   *            type of arrays elements generated
   * @param content
   *            generator providing the content of arrays generated
   * @param type
   *            type of arrays generated
   */
  public static <T> Generator<T[]> nonEmptyArrays(Generator<T> content,
      Class<T> type) {
    return arrays(content, positiveIntegers(MAX_SIZE), type);
  }

  /**
   * Create a generator of arrays with values from the content generator.
   * Length values of arrays generated will be created with size generator.
   *
   * @param <T>
   *            type of arrays elements generated
   * @param content
   *            generator providing the content of arrays generated
   * @param size
   *            integer used to determine the array size
   * @param type
   *            type of arrays generated
   */
  public static <T> Generator<T[]> arrays(Generator<T> content,
      Generator<Integer> size, Class<T> type) {
    return new ArrayGenerator<T>(content, size, type);
  }

  /**
   * Create a generator of byte arrays. The length of arrays generated will be
   * determined by the {@link ByteArrayGenerator#MIN_SIZE} and
   * {@link ByteArrayGenerator#MAX_SIZE} constants.
   *
   */
  public static Generator<byte[]> byteArrays() {
    return new ByteArrayGenerator();
  }

  /**
   * Create a generator of byte arrays. Length values of arrays generated will
   * be created with size generator.
   *
   * @param size
   *            integer used to determine the array size
   */
  public static Generator<byte[]> byteArrays(Generator<Integer> size) {
    return new ByteArrayGenerator(size);
  }

  /**
   * Create a generator of byte arrays. Length values of arrays generated will
   * be created with size generator.
   *
   * @param size
   *            integer used to determine the array size
   * @param content
   *            generator for the byte array content
   */
  public static Generator<byte[]> byteArrays(Generator<Byte> content,
      Generator<Integer> size) {
    return new ByteArrayGenerator(content, size);
  }

  /**
   * Create a generator of integer arrays.
   *
   */
  public static Generator<int[]> intArrays() {
    return new IntegerArrayGenerator();
  }

  /**
   * Create a generator of integer arrays. Length values of arrays generated
   * will be created with size generator.
   *
   * @param size
   *            integer used to determine the array size
   */
  public static Generator<int[]> intArrays(Generator<Integer> size) {
    return new IntegerArrayGenerator(size);
  }

  /**
   * Create a generator of integer arrays. Length values of arrays generated
   * will be created with size generator.
   *
   * @param size
   *            integer used to determine the array size
   * @param content
   *            generator for the integer array content
   */
  public static Generator<int[]> intArrays(Generator<Integer> content,
      Generator<Integer> size) {
    return new IntegerArrayGenerator(content, size);
  }

  /**
   * Create a deterministic generator which guarantees that all values from
   * the ensuredValues collection will be returned if enough calls to
   * {@link Generator#next()} are issued (i.e. ensuredValues.size() <= # of
   * runs). The order of values is undefined.
   *
   * @param <T>
   *            type of values return by the generator
   */
  public static <T> StatefulGenerator<T> ensureValues(
      Collection<T> ensuredValues) {
    return new EnsuredValuesGenerator<T>(ensuredValues);
  }

  /**
   * Create a deterministic generator which guarantees that all values from
   * the ensuredValues array will be returned if enough calls to
   * {@link Generator#next()} are issued (i.e. ensuredValues.size() <= # of
   * runs). The order of values is undefined.
   *
   * @param <T>
   *            type of values return by the generator
   */
  public static <T> StatefulGenerator<T> ensureValues(T... content) {
    return ensureValues(Arrays.asList(content));
  }

  /**
   * <p>
   * Create a deterministic generator which guarantees that all values from
   * the ensuredValues collection will be returned if enough calls to
   * {@link Generator#next()} are issued (i.e. ensuredValues.size() <= # of
   * runs). The order of values is undefined.
   * </p>
   * <p>
   * If all values of ensuredValues are generated calls to
   * {@link Generator#next()} will return values from the otherValues
   * generator.
   * </p>
   *
   * @param <T>
   *            type of values return by the generator
   */
  public static <T> StatefulGenerator<T> ensureValues(
      Collection<T> ensuredValues, Generator<T> otherValues) {
    return new EnsuredValuesGenerator<T>(ensuredValues, otherValues);
  }

  /**
   * <p>
   * Create a generator that ensures unique values.
   * </p>
   * <p>
   * The actual values are created with an arbitrary generator.
   * </p>
   * <p>
   * Note: unique generator depends on valid implementation of equals and
   * hashCode method of the content type generated.
   * </p>
   *
   * @param <T>
   *            type of values return by the generator
   * @param generator
   *            used to create the raw values. This generator can
   *            create duplicate values
   * @param tries
   *            Number of tries to create a new unique value. After this
   *            number of tries is exceeded the generation aborts with a
   *            {@link GeneratorException}.
   * @return create generator.
   */
  public static <T> StatefulGenerator<T> uniqueValues(Generator<T> generator,
      int tries) {
    return new UniqueValuesGenerator<T>(generator, tries);
  }

  /**
   * <p>
   * Create a generator that ensures unique values
   * </p>
   * <p>
   *  The actual values are created with an arbitrary generator.
   * </p>
   * <p>
   * Note: unique generator depends on valid implementation of equals and
   * hashCode method of the content type generated.
   * </p>
   *
   * @param <T>
   *            type of values return by the generator
   * @param generator
   *            used to create the raw values. This generator can
   *            create duplicate values
   * @return create generator.
   */
  public static <T> StatefulGenerator<T> uniqueValues(Generator<T> generator) {
    return new UniqueValuesGenerator<T>(generator);
  }

  /**
   * Create a generator that omits a given set of values.
   *
   * @param generator used to create the raw values.
   * @param excluded values. These values will not be returned.
   */
  public static <T> Generator<T> excludeValues(Generator<T> generator, T... excluded) {
    return excludeValues(generator, Arrays.asList(excluded));
  }
 
  /**
   * Create a generator that omits a given set of values.
   *
   * @param generator used to create the raw values.
   * @param excluded values. These values will not be returned.
   */
  public static <T> Generator<T> excludeValues(Generator<T> generator, Collection<T> excluded) {
    return new ExcludingGenerator<T>(generator, excluded);
  }
}
TOP

Related Classes of net.java.quickcheck.generator.CombinedGenerators

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.