arbitrary

package
v0.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 8, 2023 License: MIT Imports: 10 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrorInvalidTarget         = fmt.Errorf("Invalid generator target")
	ErrorInvalidConstraints    = fmt.Errorf("Invalid generator constraints")
	ErrorInvalidCollectionSize = fmt.Errorf("Invalid number of generators for collection")
	ErrorInvalidConfig         = fmt.Errorf("Invalid generator configuration")
	ErrorMapper                = fmt.Errorf("Generator mapper is invalid")
	ErrorFilter                = fmt.Errorf("Generator filter's predicate is invalid")
	ErrorBinder                = fmt.Errorf("Geneartor binder is invalid")
	ErrorStream                = fmt.Errorf("Failed to stream data")
)

Functions

func EncodeToString

func EncodeToString(val reflect.Value) string

EncodeToString encodes val to it's string representation.

func FilterPredicate

func FilterPredicate(in reflect.Type, predicate func(reflect.Value) bool) interface{}

FilterPredicate returns predicate function that can be used in Filter methods for generators and shrinkers. First parameter in is used to define predicate function signature as input value. Output value is always bool. Second parameter predicateFn is a arbitrary function that defines the behaviour of predicate.

func HashToInt64

func HashToInt64(vals ...reflect.Value) int64

func Mapper

func Mapper(in, out reflect.Type, mapFn func(reflect.Value) reflect.Value) interface{}

Mapper returns mapper function that can be used with Map combinator for generators and shrinkers. Parameter "in' defines mapper's input type, parameter "out" defines mapper's output type while parameter "mapFn" implements mapping.

func NewArray added in v0.2.0

func NewArray(t reflect.Type) func(Arbitrary) Arbitrary

func NewErrorInvalidCollectionSize added in v0.3.0

func NewErrorInvalidCollectionSize(collectionSize int, numberOfGenerators int) error

func NewErrorInvalidTarget added in v0.3.0

func NewErrorInvalidTarget(target reflect.Type, generatorType string) error

func NewMap added in v0.2.0

func NewMap(t reflect.Type) func(Arbitrary) Arbitrary

func NewPtr added in v0.4.0

func NewPtr(t reflect.Type) func(Arbitrary) Arbitrary

func NewSlice added in v0.2.0

func NewSlice(t reflect.Type) func(Arbitrary) Arbitrary

func NewStruct added in v0.2.0

func NewStruct(t reflect.Type) func(Arbitrary) Arbitrary

Types

type Arbitraries

type Arbitraries []Arbitrary

func (Arbitraries) Values

func (arbs Arbitraries) Values() []reflect.Value

type Arbitrary

type Arbitrary struct {
	Value      reflect.Value // Final value
	Elements   Arbitraries   // Arbitrary for each element in collection
	Precursors Arbitraries   // Precursor arbitraries from which this one is generated
	Shrinker   Shrinker
}

Arbitrary represents arbitrary type returned by shrinkers and generators.

func (Arbitrary) CompareType added in v0.2.0

func (arb Arbitrary) CompareType(target Arbitrary) error

func (Arbitrary) Copy added in v0.3.0

func (arb Arbitrary) Copy() Arbitrary

type Generator added in v0.3.0

type Generator func(target reflect.Type, bias constraints.Bias, r Random) (Arbitrary, error)

Generator returns Generate for a type specified by "target" parameter, that can be used to generate target's value using "bias" and "r".

func (Generator) Bind added in v0.3.0

func (generator Generator) Bind(binder interface{}) Generator

Bind (combinator) returns bounded generator using "binder" parameter. Binder is a function that has one input and one output. Input's type must match generated value's type. Output type must be generator.Generator. Binder allows using generated value of one generator as an input to another generator. Error is returned if binder is invalid, generator returns an error or bound generator returns an error.

Example (StringWithRepeatingCharacter)

This example demonstrates how to use Rune() generator and Bind() generator along with String() generator to build generator that generates string with single repeating character. Characters generated by Rune() generator will be used by Bind() combinator to setup rune constraints in String() generator returned by binder.

package main

import (
	"fmt"

	"github.com/steffnova/go-check/arbitrary"
	"github.com/steffnova/go-check/constraints"
	"github.com/steffnova/go-check/generator"
)

func main() {
	streamer := generator.Streamer(
		func(s string) {
			fmt.Printf("%s\n", s)
		},
		generator.Rune(constraints.Rune{
			MinCodePoint: 'a',
			MaxCodePoint: 'z',
		}).Bind(func(c rune) arbitrary.Generator {
			return generator.String(constraints.String{
				Rune: constraints.Rune{
					MinCodePoint: c,
					MaxCodePoint: c,
				},
				Length: constraints.Length{
					Min: 5,
					Max: 10,
				},
			})
		}),
	)

	if err := generator.Stream(0, 10, streamer); err != nil {
		panic(err)
	}
}
Output:

vvvvvvv
dddddddddd
jjjjjj
ooooo
bbbbbbbbbb
xxxxxxxxxx
aaaaaaaa
oooooo
wwwwwwwwww
ggggg

func (Generator) Filter added in v0.3.0

func (generator Generator) Filter(predicate interface{}) Generator

Filter (combinator) returns a generator that generates value only if predicate is satisfied. Predicate is a function that has one input and one output. Predicate's input parameter must match generator's target type, and output parameter must be bool. Error is returned predicate is invalid, or generator for predicate's input returns an error.

NOTE: Returned generator will retry generation until predicate is satisfied, which can impact the generator's speed.

Example (EvenInt)

This example demonstrates how to use Int() generator and Filter combinator to build a generator for generation of even integer numbers. Int values generated by Int() generator that are divisable by 2 will be filtered by Filter combinator.

package main

import (
	"fmt"

	"github.com/steffnova/go-check/constraints"
	"github.com/steffnova/go-check/generator"
)

func main() {
	streamer := generator.Streamer(
		func(n int) {
			fmt.Printf("%d\n", n)
		},
		generator.Int(constraints.Int{
			Min: 0,
			Max: 100,
		},
		).Filter(func(n int) bool {
			return n%2 == 0
		}),
	)

	if err := generator.Stream(0, 10, streamer); err != nil {
		panic(err)
	}
}
Output:

16
80
86
22
84
64
30
40
62
92

func (Generator) Map added in v0.3.0

func (generator Generator) Map(mapper interface{}) Generator

Map (combinator) returns generator that maps generated value to a new one using mapper. Mapper must be a function that has one input and one output. Mapper's input type must match generated value's type and Mapper's output type must match generator's target type. Error is returned if mapper is invalid or if generator of mapper's input type returns an error.

Example (EvenInt)

This example demonstrates how to use Int() generator and Map combinator to build a generator for generation of even integer numbers. Each generated int value by Int() generator will be multiplied by 2 by mapper.

package main

import (
	"fmt"

	"github.com/steffnova/go-check/constraints"
	"github.com/steffnova/go-check/generator"
)

func main() {
	streamer := generator.Streamer(
		func(n int) {
			fmt.Printf("%d\n", n)
		},
		generator.Int(constraints.Int{
			Min: 0,
			Max: 100,
		}).Map(func(n int) int {
			return n * 2
		}),
	)

	if err := generator.Stream(0, 10, streamer); err != nil {
		panic(err)
	}
}
Output:

62
32
160
172
138
44
168
6
128
60
Example (OrderedIntSlice)

This example demonstrates how to use Slice(Int()) generator and Map combinator to build a generator for generation slice of ordered intger numbers. Each generated []int value by Slice(Int()) generator will be sorted by mapper.

package main

import (
	"fmt"
	"sort"

	"github.com/steffnova/go-check/constraints"
	"github.com/steffnova/go-check/generator"
)

func main() {
	streamer := generator.Streamer(
		func(n []int) {
			fmt.Printf("%d\n", n)
		},

		generator.Slice(
			generator.Int(constraints.Int{
				Min: 0,
				Max: 10000,
			}),
			constraints.Length{
				Min: 0,
				Max: 10,
			}).Map(func(ns []int) []int {
			sort.SliceStable(ns, func(i, j int) bool {
				return ns[i] < ns[j]
			})
			return ns
		}),
	)

	if err := generator.Stream(0, 10, streamer); err != nil {
		panic(err)
	}

}
Output:

[259 1069 1984 5150 5910]
[3323]
[2140 3257 3378 5063 5836 8213 8701 9832]
[1247 3422 4175 4605 4904 5523 5629 5705 9029 9609]
[1943 3465 4132 8913]
[30 2361 3384 6926]
[]
[271 1007 2281 8190 8477 9452]
[3746 5588 8797 9599]
[19 697 3795 5496 6269 6795 7065 7552]

type Random added in v0.3.0

type Random interface {
	// Uint64 generates random uint64 in specified range [min, max] (inclusive)
	Uint64(constraints.Uint64) uint64

	// Split returns new Random that can be used idenpendently of original. Random
	// returned by Split can have it's seed changed without affecting the original
	Split() Random

	// Seed seeds Random with seed value
	Seed(seed int64)
}

Random is an interface for random number generation

type RandomNumber added in v0.3.0

type RandomNumber struct {
	Rand *rand.Rand
}

RandomNumber is implementation of Random interface

func (RandomNumber) Seed added in v0.3.0

func (r RandomNumber) Seed(seed int64)

Seed is implementation of Random.Seed

func (RandomNumber) Split added in v0.3.0

func (r RandomNumber) Split() Random

Split is implementation of Random.Split

func (RandomNumber) Uint64 added in v0.3.0

func (r RandomNumber) Uint64(limit constraints.Uint64) uint64

Uint64 is implementation of Random.Uint64

type Shrinker added in v0.3.0

type Shrinker func(arb Arbitrary, propertyFailed bool) (Arbitrary, error)

func (Shrinker) Bind added in v0.3.0

func (shrinker Shrinker) Bind(binder binder, last Arbitrary) Shrinker

Bind returns a shrinker that uses the shrunk value to generate shrink returned by binder. Binder is not guaranteed to be deterministic, as it returns new result value based on root shrinker's shrink and it should be considered non-deterministic. Two shrinkers needs to be passed alongside binder, next and lastFailing. Next shrinker is the shrinker from the previous iteration of shrinking is shrinkering where lastFail that caused last property falsification. Because of "non-deterministic" property of binder, Bind is best paired with Retry combinator that can improve shrinking efficiency.

func (Shrinker) Fail added in v0.3.0

func (shrinker Shrinker) Fail(err error) Shrinker

func (Shrinker) Filter added in v0.3.0

func (shrinker Shrinker) Filter(predicate interface{}) Shrinker

func (Shrinker) Map added in v0.3.0

func (shrinker Shrinker) Map(mapper interface{}) Shrinker

func (Shrinker) Or added in v0.3.0

func (shrinker Shrinker) Or(next Shrinker) Shrinker

func (Shrinker) Retry added in v0.3.0

func (shrinker Shrinker) Retry(maxRetries, remainingRetries uint, retryValue Arbitrary) Shrinker

Retry returns a shrinker that returns retryValue, and shrinker receiver until either reminingRetries equals 0 or propertyFailed is true. Retry is useful for shrinkers that do not shrink deterministically like shrinkers returned by Bind. On deterministic shrinkers this has no effect and will only increase total time of shrinking process.

func (Shrinker) TransformAfter added in v0.3.0

func (shrinker Shrinker) TransformAfter(transformer transform) Shrinker

func (Shrinker) TransformBefore added in v0.3.0

func (shrinker Shrinker) TransformBefore(transformer transform) Shrinker

func (Shrinker) TransformOnceBefore added in v0.3.0

func (shrinker Shrinker) TransformOnceBefore(transformer transform) Shrinker

func (Shrinker) Validate added in v0.3.0

func (shrinker Shrinker) Validate(validation func(Arbitrary) error) Shrinker

type Validate added in v0.2.0

type Validate func(Arbitrary) error

func ValidateArray added in v0.2.0

func ValidateArray() Validate

func ValidateMap added in v0.2.0

func ValidateMap() Validate

func ValidateSlice added in v0.2.0

func ValidateSlice() Validate

func ValidateStruct added in v0.2.0

func ValidateStruct() Validate

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL