prop

package
v0.2.11 Latest Latest
Warning

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

Go to latest
Published: Apr 3, 2024 License: MIT Imports: 5 Imported by: 20

Documentation

Overview

Package prop contains the most common implementations of a gopter.Prop.

Example (Invalidconcat)

Example_invalidconcat demonstrates shrinking of string Kudos to @exarkun and @itamarst for finding this issue

package main

import (
	"strings"
	"unicode"

	"github.com/leanovate/gopter"
	"github.com/leanovate/gopter/gen"
	"github.com/leanovate/gopter/prop"
)

func MisimplementedConcat(a, b string) string {
	if strings.IndexFunc(a, unicode.IsDigit) > 5 {
		return b
	}
	return a + b
}

// Example_invalidconcat demonstrates shrinking of string
// Kudos to @exarkun and @itamarst for finding this issue
func main() {
	parameters := gopter.DefaultTestParametersWithSeed(1234) // Example should generate reproducible results, otherwise DefaultTestParameters() will suffice

	properties := gopter.NewProperties(parameters)

	properties.Property("length is sum of lengths", prop.ForAll(
		func(a, b string) bool {
			return MisimplementedConcat(a, b) == a+b
		},
		gen.Identifier(),
		gen.Identifier(),
	))

	// When using testing.T you might just use: properties.TestingRun(t)
	properties.Run(gopter.ConsoleReporter(false))
}
Output:

! length is sum of lengths: Falsified after 17 passed tests.
ARG_0: bahbxh6
ARG_0_ORIGINAL (2 shrinks): pkpbahbxh6
ARG_1: l
ARG_1_ORIGINAL (1 shrinks): dl
Example (Quadratic)
package main

import (
	"errors"
	"math"

	"github.com/leanovate/gopter"
	"github.com/leanovate/gopter/gen"
	"github.com/leanovate/gopter/prop"
)

func solveQuadratic(a, b, c float64) (float64, float64, error) {
	if a == 0 {
		return 0, 0, errors.New("No solution")
	}
	v := b*b - 4*a*c
	if v < 0 {
		return 0, 0, errors.New("No solution")
	}
	v = math.Sqrt(v)
	return (-b + v) / 2 / a, (-b - v) / 2 / a, nil
}

func main() {
	parameters := gopter.DefaultTestParametersWithSeed(1234) // Example should generate reproducible results, otherwise DefaultTestParameters() will suffice

	properties := gopter.NewProperties(parameters)

	properties.Property("solve quadratic", prop.ForAll(
		func(a, b, c float64) bool {
			x1, x2, err := solveQuadratic(a, b, c)
			if err != nil {
				return true
			}
			return math.Abs(a*x1*x1+b*x1+c) < 1e-5 && math.Abs(a*x2*x2+b*x2+c) < 1e-5
		},
		gen.Float64(),
		gen.Float64(),
		gen.Float64(),
	))

	properties.Property("solve quadratic with resonable ranges", prop.ForAll(
		func(a, b, c float64) bool {
			x1, x2, err := solveQuadratic(a, b, c)
			if err != nil {
				return true
			}
			return math.Abs(a*x1*x1+b*x1+c) < 1e-5 && math.Abs(a*x2*x2+b*x2+c) < 1e-5
		},
		gen.Float64Range(-1e8, 1e8),
		gen.Float64Range(-1e8, 1e8),
		gen.Float64Range(-1e8, 1e8),
	))

	// When using testing.T you might just use: properties.TestingRun(t)
	properties.Run(gopter.ConsoleReporter(false))
}
Output:

! solve quadratic: Falsified after 0 passed tests.
ARG_0: -1.4667384313385178e-05
ARG_0_ORIGINAL (187 shrinks): -1.0960555181801604e+51
ARG_1: 0
ARG_1_ORIGINAL (1 shrinks): -1.1203884793568249e+96
ARG_2: 6.481285637227244e+10
ARG_2_ORIGINAL (905 shrinks): 1.512647219322138e+281
+ solve quadratic with resonable ranges: OK, passed 100 tests.
Example (Shrink)
package main

import (
	"github.com/leanovate/gopter"
	"github.com/leanovate/gopter/gen"
	"github.com/leanovate/gopter/prop"
)

func main() {
	parameters := gopter.DefaultTestParametersWithSeed(1234) // Example should generate reproducible results, otherwise DefaultTestParameters() will suffice

	properties := gopter.NewProperties(parameters)

	properties.Property("fail above 100", prop.ForAll(
		func(arg int64) bool {
			return arg <= 100
		},
		gen.Int64(),
	))

	properties.Property("fail above 100 no shrink", prop.ForAllNoShrink(
		func(arg int64) bool {
			return arg <= 100
		},
		gen.Int64(),
	))

	// When using testing.T you might just use: properties.TestingRun(t)
	properties.Run(gopter.ConsoleReporter(false))
}
Output:

! fail above 100: Falsified after 0 passed tests.
ARG_0: 101
ARG_0_ORIGINAL (56 shrinks): 2041104533947223744
! fail above 100 no shrink: Falsified after 0 passed tests.
ARG_0: 6006156956070140861
Example (TimeGen)
package main

import (
	"time"

	"github.com/leanovate/gopter"
	"github.com/leanovate/gopter/gen"
	"github.com/leanovate/gopter/prop"
)

func main() {
	parameters := gopter.DefaultTestParametersWithSeed(1234) // Example should generate reproducible results, otherwise DefaultTestParameters() will suffice
	time.Local = time.UTC                                    // Just for this example to generate reproducible results

	properties := gopter.NewProperties(parameters)

	properties.Property("time in range format parsable", prop.ForAll(
		func(actual time.Time) (bool, error) {
			str := actual.Format(time.RFC3339Nano)
			parsed, err := time.Parse(time.RFC3339Nano, str)
			return actual.Equal(parsed), err
		},
		gen.TimeRange(time.Now(), time.Duration(100*24*365)*time.Hour),
	))

	properties.Property("regular time format parsable", prop.ForAll(
		func(actual time.Time) (bool, error) {
			str := actual.Format(time.RFC3339Nano)
			parsed, err := time.Parse(time.RFC3339Nano, str)
			return actual.Equal(parsed), err
		},
		gen.Time(),
	))

	properties.Property("any time format parsable", prop.ForAll(
		func(actual time.Time) (bool, error) {
			str := actual.Format(time.RFC3339Nano)
			parsed, err := time.Parse(time.RFC3339Nano, str)
			return actual.Equal(parsed), err
		},
		gen.AnyTime(),
	))

	properties.Run(gopter.ConsoleReporter(false))
}
Output:

+ time in range format parsable: OK, passed 100 tests.
+ regular time format parsable: OK, passed 100 tests.
! any time format parsable: Error on property evaluation after 0 passed
   tests: parsing time "10000-01-01T00:00:00Z" as
   "2006-01-02T15:04:05.999999999Z07:00": cannot parse "0-01-01T00:00:00Z"
   as "-"
ARG_0: 10000-01-01 00:00:00 +0000 UTC
ARG_0_ORIGINAL (45 shrinks): 237903042092-02-10 19:15:18.148265469 +0000
   UTC

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ErrorProp

func ErrorProp(err error) gopter.Prop

ErrorProp creates a property that will always fail with an error. Mostly used as a fallback when setup/initialization fails

func ForAll

func ForAll(condition interface{}, gens ...gopter.Gen) 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 shrunk.

"condition" has to be a function with the same number of parameters as the provided generators "gens". The function may return a simple bool (true means that the condition has passed), a string (empty string means that condition has passed), a *PropResult, or one of former combined with an error.

func ForAll1

func ForAll1(gen gopter.Gen, check func(v interface{}) (interface{}, error)) gopter.Prop

ForAll1 legacy interface to be removed in the future

func ForAllNoShrink

func ForAllNoShrink(condition interface{}, gens ...gopter.Gen) gopter.Prop

ForAllNoShrink creates a property that requires the check condition to be true for all values. As the name suggests the generated values will not be shrunk if the condition falsiies.

"condition" has to be a function with the same number of parameters as the provided generators "gens". The function may return a simple bool (true means that the condition has passed), a string (empty string means that condition has passed), a *PropResult, or one of former combined with an error.

func ForAllNoShrink1

func ForAllNoShrink1(gen gopter.Gen, check func(interface{}) (interface{}, error)) gopter.Prop

ForAllNoShrink1 creates a property that requires the check condition to be true for all values As the name suggests the generated values will not be shrunk if the condition falsiies

Types

This section is empty.

Jump to

Keyboard shortcuts

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