Skip to content

invio/Peddler

Repository files navigation

Peddler

Appveyor Travis CI NuGet Coverage

A collection of interfaces and base implementations that can be used to create data objects. These can be useful for creating objects for generative and performance testing, as well as empowering the test writer to focus the content of the test on what is actually being tested by randomly generating valid, irrelevant data on the object.

Installation

The latest version of this package is available on NuGet. To install, run the following command:

PM> Install-Package Peddler

Basic Usage

Peddler provides two things: Interfaces for how to design and compose your own data generation, as well as a collection of out-of-the-box generator implementations over the basic .NET types, such as DateTime, String, Guid, and Int32. All implementations are thread-safe.

Interfaces

There are three main interfaces. The out-of-the-box generators implement at least one (but generally all three) of them, depending on their data type.

This generates random values of T when the caller invokes its Next() method. Example:

using Peddler;

public static void Main(string[] args) {
    GuidGenerator generator = new GuidGenerator();
    Guid randomGuid1 = generator.Next(); // A random GUID
    Guid randomGuid2 = generator.Next(); // Another random GUID

    GuidGenerator generator = new Int32Generator(1, 10);
    Int32 randomInt1 = generator.Next(); // A random Int32 between 1 (inclusively) and 10 (exclusively)
    Int32 randomInt2 = generator.Next(); // Possibly equal to randomInt1, possibly distinct.
}

This generates random values of T when the caller invokes its NextDistinct(T) method. The resultant value of T is guaranteed to be distinct from (or "not equal to") the provided value of T. This interface inherits from IGenerator<T>. Example:

using Peddler;

public static void Main(string[] args) {
    DateTimeGenerator generator = new DateTimeGenerator();
    DateTime dumped = new DateTime(2015, 1, 5, 20, 45, 13, 573, DateTimeKind.Utc);
    DateTime letMeForget = generator.NextDistinct(dumped);

    Int32Generator generator = new Int32Generator(1, 10);
    Int32 randomInt1 = generator.Next();
    Int32 randomInt2 = generator.NextDistinct(randomInt1); // Guaranteed to be distinct from randomInt1
    Int32 randomInt3 = generator.NextDistinct(15);         // 15 is out of the range, so this is functionally identical to generator.Next();
}

This generates random values of T when the caller invokes one of its NextLessThan(T), NextLessThanOrEqualTo(T), NextGreaterThan(T), or NextGreaterThanOrEqualTo(T) methods. Depending upon which method is used, the resultant value of T is guaranteed to be greater than, less than, or equal to the provided value of T. This interface inherits from IDistinctGenerator<T>. Example:

using Peddler;

public static void Main(string[] args) {
    Int32Generator generator = new Int32Generator(1, 10);
    Int32 betweenFiveAndNine = generator.GreaterThan(5);   // 10 is an exclusive boundary
    Int32 mustBeOne = generator.LessThan(2);               // 1 is an inclusive boundary

    Int32Generator generator = new Int32Generator(1, 10);
    Int32 randomInt1 = generator.Next();
    Int32 randomInt2 = generator.NextDistinct(randomInt1); // Guaranteed to be distinct from randomInt1
    Int32 randomInt3 = generator.NextDistinct(15);         // 15 is out of the range, so functionally identical to generator.Next();
}

Base Implementations

Peddler includes implementations for many of the basic data types of the .NET Framework. While you can always create (or submit a pull request with) your own variant of any of these data types, the flexibility provided by the various constructors on each of these implementations will fill most use cases for raw, randomized data generation.

Type IGenerator<T> IDistinctGenerator<T> IComparableGenerator<T> Notes
SByte X X X
Byte X X X
Int16 X X X
UInt16 X X X
Int32 X X X
UInt32 X X X
Int64 X X X
UInt64 X X X
Single X X X
Double X X X
Guid X X
SequentialGuid X X Uses 6 bytes of timestamp data and 10 bytes of random data to generate GUIDs sequentially
DateTime X X X Enforces consistent use of DateTimeKind
TimeSpan X X X
String X X Uses StringComparison.Ordinal rules
Enum<T> X X
Boolean X X
Color X X

Wrapper Implementations

Peddler also includes implementations that wrap around base implementations or collections in order to mutate their functionality. For example, a caller may want to periodically produce null, or convert value type T into Nullable<T>, without having to write a whole new generator. Perhaps the caller wants to generate values from a predefined set. These implementations wrap around a lower-level concept to to provide that type of functionality.

Type IGenerator<T> IDistinctGenerator<T> IComparableGenerator<T> Notes
MaybeDefault<T> X Returns predefined "default value" periodically
MaybeDefaultDistinct<T> X X Returns predefined "default value" periodically
MaybeDefaultComparable<T> X X X Returns predefined "default value" periodically
Nullable<T> X Converts <T> to Nullable<T>
NullableDistinct<T> X X Converts <T> to Nullable<T>
NullableComparable<T> X X X Converts <T> to Nullable<T>
Set<T> X X Returns values from injected ISet<T>
ListOf<T> X Returns immutable lists with values of type T

Constraints

If you ever ask a generator to return a value that is impossible (such as asking for a UInt32 that is less than 0), it will throw an UnableToGenerateValueException. Example:

using Peddler;

public static void Main(string[] args) {
    Int32Generator generator = new Int32Generator(1, 10);

    try {
        generator.GreaterThan(15);
    } catch (UnableToGenerateValueException) {
        Console.WriteLine(
            "15 is greater than the 10, " +
            "so Int32Generator cannot create a compliant value."
        );
    }
}

That's it. <3