Documentation
¶
Overview ¶
Package arbitrary contains helpers to create contexts of arbitrary values, i.e. automatically combine generators as needed using reflection.
A simple example might look like this:
func TestIntParse(t *testing.T) {
properties := gopter.NewProperties(nil)
arbitraries := arbitrary.DefaultArbitraries()
properties.Property("printed integers can be parsed", arbitraries.ForAll(
func(a int64) bool {
str := fmt.Sprintf("%d", a)
parsed, err := strconv.ParseInt(str, 10, 64)
return err == nil && parsed == a
}))
properties.TestingRun(t)
}
Be aware that by default always the most generic generators are used. I.e. in the example above the gen.Int64 generator will be used and the condition will be tested for the full range of int64 numbers.
To adapt this one might register a generator for a specific type in an arbitraries context. I.e. by adding
arbitraries.RegisterGen(gen.Int64Range(-1000, 1000))
any generated int64 number will be between -1000 and 1000.
Example (Parseint) ¶
package main
import (
"fmt"
"strconv"
"github.com/leanovate/gopter"
"github.com/leanovate/gopter/arbitrary"
)
func main() {
parameters := gopter.DefaultTestParameters()
parameters.Rng.Seed(1234) // Just for this example to generate reproducable results
arbitraries := arbitrary.DefaultArbitraries()
properties := gopter.NewProperties(parameters)
properties.Property("printed integers can be parsed", arbitraries.ForAll(
func(a int64) bool {
str := fmt.Sprintf("%d", a)
parsed, err := strconv.ParseInt(str, 10, 64)
return err == nil && parsed == a
}))
// When using testing.T you might just use: properties.TestingRun(t)
properties.Run(gopter.ConsoleReporter(false))
}
Output: + printed integers can be parsed: OK, passed 100 tests.
Example (Quadratic) ¶
package main
import (
"errors"
"math/cmplx"
"github.com/leanovate/gopter"
"github.com/leanovate/gopter/arbitrary"
"github.com/leanovate/gopter/gen"
)
type QudraticEquation struct {
A, B, C complex128
}
func (q *QudraticEquation) Eval(x complex128) complex128 {
return q.A*x*x + q.B*x + q.C
}
func (q *QudraticEquation) Solve() (complex128, complex128, error) {
if q.A == 0 {
return 0, 0, errors.New("No solution")
}
v := q.B*q.B - 4*q.A*q.C
v = cmplx.Sqrt(v)
return (-q.B + v) / 2 / q.A, (-q.B - v) / 2 / q.A, nil
}
func main() {
parameters := gopter.DefaultTestParameters()
parameters.Rng.Seed(1234) // Just for this example to generate reproducable results
arbitraries := arbitrary.DefaultArbitraries()
arbitraries.RegisterGen(gen.Complex128Box(-1e8-1e8i, 1e8+1e8i)) // Only use complex values within a range
properties := gopter.NewProperties(parameters)
properties.Property("Quadratic equations can be solved", arbitraries.ForAll(
func(quadratic *QudraticEquation) bool {
x1, x2, err := quadratic.Solve()
if err != nil {
return true
}
return cmplx.Abs(quadratic.Eval(x1)) < 1e-5 && cmplx.Abs(quadratic.Eval(x2)) < 1e-5
}))
properties.Property("Quadratic equations can be solved alternative", arbitraries.ForAll(
func(a, b, c complex128) bool {
quadratic := &QudraticEquation{
A: a,
B: b,
C: c,
}
x1, x2, err := quadratic.Solve()
if err != nil {
return true
}
return cmplx.Abs(quadratic.Eval(x1)) < 1e-5 && cmplx.Abs(quadratic.Eval(x2)) < 1e-5
}))
// When using testing.T you might just use: properties.TestingRun(t)
properties.Run(gopter.ConsoleReporter(false))
}
Output: + Quadratic equations can be solved: OK, passed 100 tests. + Quadratic equations can be solved alternative: OK, passed 100 tests.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Arbitraries ¶
type Arbitraries struct {
// contains filtered or unexported fields
}
Arbitraries defines a context to generate arbitrary values of any kind. Values are generated by either providing a generator for a specific type or by creating a generator on the fly using golang reflection.
func DefaultArbitraries ¶
func DefaultArbitraries() *Arbitraries
DefaultArbitraries creates a default arbitrary context with the widest possible ranges for all types.
func (*Arbitraries) ForAll ¶
func (a *Arbitraries) ForAll(condition interface{}) gopter.Prop
ForAll creates a property that requires the check condition to be true for all values, if the condition falsiies the generated values will be shrinked.
"condition" has to be a function with the any number of parameters that can generated in context of the Arbitraries. The function may return a simple bool, a *PropResult, a boolean with error or a *PropResult with error.
func (*Arbitraries) GenForType ¶
func (a *Arbitraries) GenForType(rt reflect.Type) gopter.Gen
GenForType gets a generator for a generator for a type
func (*Arbitraries) RegisterGen ¶
func (a *Arbitraries) RegisterGen(gen gopter.Gen)
RegisterGen registers a generator