232 lines · 4.9 KB · Go
RawDownload
// Copyright 2019 Gregory Petrosyan <gregory.petrosyan@gmail.com>//// This Source Code Form is subject to the terms of the Mozilla Public// License, v. 2.0. If a copy of the MPL was not distributed with this// file, You can obtain one at https://mozilla.org/MPL/2.0/. package rapid import (	"fmt"	"math"	"math/bits"	"sort"	"strconv"	"testing") const shrinkTestRuns = 10 func TestShrink_IntCmp(t *testing.T) {	t.Parallel() 	ref := []struct {		gt bool		a  int		b  int		eq bool	}{		{true, 1000000, 1000001, false},		{true, -1000000, 0, false},		{true, 0, 0, true},		{false, 1000000, 0, false},		{false, -1000000, -1000001, false},		{false, 0, 0, true},	} 	for _, r := range ref {		t.Run(fmt.Sprintf("%v", r), func(t *testing.T) {			checkShrink(t, func(t *T) {				i := Int().Draw(t, "i")				if ((r.gt && i > r.a) || (!r.gt && i < r.a)) || (r.eq && i == r.a) {					t.Fail()				}			}, r.b)		})	}} func TestShrink_FloatCmp(t *testing.T) {	t.Parallel() 	type cmp struct {		gt bool		a  float64		b  float64		eq bool	} 	ref := []cmp{		{true, 1000000, 1000000.5, false},		{true, math.Pi, 3.5, false},		{true, 1, 1, true},		{true, -1000000, 1, false},		{false, -1000000, -1000000.5, false},		{false, -math.E, -2.75, false},	}	if *flaky {		ref = append(ref, cmp{false, 0, -1, true}) // sometimes we end up at exactly 0	} 	for _, r := range ref {		t.Run(fmt.Sprintf("%v", r), func(t *testing.T) {			checkShrink(t, func(t *T) {				f := Float64().Draw(t, "f")				if ((r.gt && f > r.a) || (!r.gt && f < r.a)) || (r.eq && f == r.a) {					t.Fail()				}			}, r.b)		})	}} func TestShrink_IntSliceNElemsGt(t *testing.T) {	t.Parallel() 	checkShrink(t, func(t *T) {		s := SliceOf(Int()).Draw(t, "s")		n := 0		for _, i := range s {			if i > 1000000 {				n++			}		}		if n > 1 {			t.Fail()		}	}, []int{1000001, 1000001})} func TestShrink_IntSliceElemGe(t *testing.T) {	t.Parallel() 	checkShrink(t, func(t *T) {		s := SliceOfN(Int(), 1, -1).Draw(t, "s")		ix := IntRange(0, len(s)-1).Draw(t, "ix") 		if s[ix] >= 100 {			t.Fail()		}	}, []int{100}, 0)} func TestShrink_IntSliceElemSpanGe(t *testing.T) {	t.Parallel() 	checkShrink(t, func(t *T) {		s := SliceOfN(Int(), 4, -1).Draw(t, "s")		if len(s)%3 == 1 && s[len(s)-1] >= 100 {			t.Fail()		}	}, []int{0, 0, 0, 100})} func TestShrink_IntSliceNoDuplicates(t *testing.T) {	t.Parallel() 	checkShrink(t, func(t *T) {		s := SliceOfN(IntMin(1), 5, -1).Draw(t, "s")		sort.Ints(s)		last := 0		for _, i := range s {			if i == last {				return			}			last = i		}		t.Fail()	}, []int{1, 2, 3, 4, 5})} func TestShrink_String(t *testing.T) {	t.Parallel() 	checkShrink(t, func(t *T) {		s1 := String().Draw(t, "s1")		s2 := String().Draw(t, "s2")		if len(s1) > len(s2) {			t.Fail()		}	}, "A", "")} func TestShrink_StringOf(t *testing.T) {	t.Parallel() 	checkShrink(t, func(t *T) {		s1 := StringOf(RuneFrom([]rune{'X', 'Y', 'Z'})).Draw(t, "s1")		s2 := StringOf(RuneFrom([]rune{'U', 'V', 'W'})).Draw(t, "s2")		if len(s1) > len(s2) {			t.Fail()		}	}, "X", "")} func TestMinimize_UnsetBits(t *testing.T) {	t.Parallel() 	Check(t, func(t *T) {		mask := Uint64Range(0, math.MaxUint64).Draw(t, "mask")		best := minimize(math.MaxUint64, func(x uint64, s string) bool { return x&mask == mask })		if best != mask {			t.Fatalf("unset to %v instead of %v", bin(best), bin(mask))		}	})} func TestMinimize_SortBits(t *testing.T) {	t.Parallel() 	Check(t, func(t *T) {		u := Uint64Range(0, math.MaxUint64).Draw(t, "u")		n := bits.OnesCount64(u)		v := uint64(1<<uint(n) - 1) 		best := minimize(u, func(x uint64, s string) bool { return bits.OnesCount64(x) == n })		if best != v {			t.Fatalf("minimized to %v instead of %v (%v bits set)", bin(best), bin(v), n)		}	})} func TestMinimize_LowerBound(t *testing.T) {	t.Parallel() 	Check(t, func(t *T) {		min := Uint64().Draw(t, "min")		u := Uint64Min(min).Draw(t, "u") 		best := minimize(u, func(x uint64, s string) bool { return x >= min })		if best != min {			t.Fatalf("found %v instead of %v", best, min)		}	})} func checkShrink(t *testing.T, prop func(*T), draws ...any) {	t.Helper() 	for i := 0; i < shrinkTestRuns; i++ {		t.Run(strconv.Itoa(i), func(t *testing.T) {			t.Helper() 			_, _, _, seed, _, buf, err1, err2 := doCheck(t, checkDeadline(nil), 100, baseSeed(), "", false, prop)			if seed != 0 && err1 == nil && err2 == nil {				t.Fatalf("shrink test did not fail (seed %v)", seed)			}			if traceback(err1) != traceback(err2) {				t.Fatalf("flaky shrink test (seed %v)\nTraceback (%v):\n%vOriginal traceback (%v):\n%v", seed, err2, traceback(err2), err1, traceback(err1))			} 			nt := newT(t, newBufBitStream(buf, false), false, nil, draws...)			_ = checkOnce(nt, prop)			if nt.draws != len(draws) {				t.Fatalf("different number of draws: %v vs expected %v", nt.draws, len(draws))			}		})	}} func bin(u uint64) string {	return "0b" + strconv.FormatUint(u, 2)}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t