Documentation
¶
Overview ¶
Package testing provides test utilities, mocks, and helpers for testing Fisher-Yates implementations.
Index ¶
- func AssertBufferCapacityPreserved(t TestReporter, buf []int, expectedCap int)
- func AssertNoAllocations(t TestReporter, runs int, fn func(), maxAllocs float64)
- func AssertPermutationsDifferent(t TestReporter, perm1, perm2 []int)
- func AssertPermutationsEqual(t TestReporter, perm1, perm2 []int)
- func AssertValidPermutation(t TestReporter, perm []int)
- func CountInversions(perm []int) int
- func IsIdentityPermutation(perm []int) bool
- type MockRandomSource
- type TestReporter
- type TestVector
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AssertBufferCapacityPreserved ¶
func AssertBufferCapacityPreserved(t TestReporter, buf []int, expectedCap int)
AssertBufferCapacityPreserved verifies that a buffer's capacity hasn't changed. This is useful for testing the zero-allocation pattern with GenerateInto().
Parameters:
- t: The test reporter (typically *testing.T)
- buf: The buffer to check
- expectedCap: The expected capacity
Example:
buf := make([]int, 100) initialCap := cap(buf) buf = fy.GenerateInto(buf, 50, random) AssertBufferCapacityPreserved(t, buf, initialCap)
func AssertNoAllocations ¶
func AssertNoAllocations(t TestReporter, runs int, fn func(), maxAllocs float64)
AssertNoAllocations verifies that a function performs no heap allocations. This uses testing.AllocsPerRun to measure allocations.
Parameters:
- t: The test reporter (typically *testing.T)
- runs: Number of runs to average over
- fn: The function to test
- maxAllocs: Maximum allowed allocations per run
Example:
buf := make([]int, 100)
AssertNoAllocations(t, 100, func() {
buf = fy.GenerateInto(buf, 100, random)
}, 0) // Expect zero allocations
func AssertPermutationsDifferent ¶
func AssertPermutationsDifferent(t TestReporter, perm1, perm2 []int)
AssertPermutationsDifferent verifies that two permutations are different. This is useful for testing that different seeds produce different results.
Parameters:
- t: The test reporter (typically *testing.T)
- perm1: First permutation
- perm2: Second permutation
Example:
perm1 := fy.Generate(10, random1) perm2 := fy.Generate(10, random2) // Different seed AssertPermutationsDifferent(t, perm1, perm2)
func AssertPermutationsEqual ¶
func AssertPermutationsEqual(t TestReporter, perm1, perm2 []int)
AssertPermutationsEqual verifies that two permutations are identical.
Parameters:
- t: The test reporter (typically *testing.T)
- perm1: First permutation
- perm2: Second permutation
Example:
perm1 := fy.Generate(10, random) random.Seed(sameSeed) // Reset to same state perm2 := fy.Generate(10, random) AssertPermutationsEqual(t, perm1, perm2) // Verify determinism
func AssertValidPermutation ¶
func AssertValidPermutation(t TestReporter, perm []int)
AssertValidPermutation verifies that a slice is a valid permutation of [0, n-1]. A valid permutation must contain all integers from 0 to n-1 exactly once.
This helper checks:
- All values are in the range [0, n-1]
- No duplicate values exist
- All expected values are present
Parameters:
- t: The test reporter (typically *testing.T)
- perm: The permutation slice to validate
Example:
perm := fy.Generate(10, random) AssertValidPermutation(t, perm) // Fails test if invalid
func CountInversions ¶
CountInversions counts the number of inversions in a permutation. An inversion is a pair of indices (i, j) where i < j but perm[i] > perm[j]. This can be useful for analyzing the "randomness" of a permutation.
Parameters:
- perm: The permutation to analyze
Returns:
- The number of inversions
Example:
inversions := CountInversions(perm)
t.Logf("Permutation has %d inversions", inversions)
func IsIdentityPermutation ¶
IsIdentityPermutation checks if a permutation is the identity permutation [0, 1, 2, ..., n-1].
Parameters:
- perm: The permutation to check
Returns:
- true if perm is the identity permutation, false otherwise
Example:
if IsIdentityPermutation(perm) {
t.Error("Expected shuffled permutation, got identity")
}
Types ¶
type MockRandomSource ¶
type MockRandomSource struct {
// contains filtered or unexported fields
}
MockRandomSource provides a deterministic random source for testing. It cycles through a predefined set of int32 values, making tests reproducible.
This mock implements the f5prng.RandomSource interface and is useful for:
- Testing specific permutation sequences
- Verifying negative int32 handling
- Creating deterministic test scenarios
Example usage:
mock := NewMockRandomSource(5, -10, 3, -1, 0) fy := fisheryates.NewFisherYates() perm := fy.Generate(5, mock) // perm will be generated using values [5, -10, 3, -1, 0] in sequence
func NewMockRandomSource ¶
func NewMockRandomSource(values ...int32) *MockRandomSource
NewMockRandomSource creates a new MockRandomSource with the specified values. The mock will cycle through these values repeatedly when NextInt() is called.
Parameters:
- values: The int32 values to return in sequence (cycles if exhausted)
Returns:
- A MockRandomSource ready for use in tests
Example:
// Create mock that returns specific values mock := NewMockRandomSource(-2147483648, 0, 2147483647) // Use in permutation generation perm := fy.Generate(10, mock)
func (*MockRandomSource) Clear ¶
func (m *MockRandomSource) Clear()
Clear is a no-op for MockRandomSource since it holds no sensitive state. This method exists to satisfy the f5prng.RandomSource interface.
func (*MockRandomSource) NextBytes ¶
func (m *MockRandomSource) NextBytes(n int) []byte
NextBytes returns a byte slice of the specified length. All bytes are zero for simplicity in this mock implementation.
Parameters:
- n: Number of bytes to generate
Returns:
- A byte slice of length n filled with zeros
func (*MockRandomSource) NextInt ¶
func (m *MockRandomSource) NextInt() int32
NextInt returns the next int32 value from the predefined sequence. The sequence cycles back to the beginning when exhausted.
Returns:
- The next int32 value in the sequence
func (*MockRandomSource) Reset ¶
func (m *MockRandomSource) Reset()
Reset resets the mock's internal index to the beginning of the value sequence. This is useful when you want to repeat the same sequence in multiple tests.
Example:
mock := NewMockRandomSource(1, 2, 3) perm1 := fy.Generate(5, mock) // Uses 1, 2, 3, 1, 2 mock.Reset() perm2 := fy.Generate(5, mock) // Uses 1, 2, 3, 1, 2 (same sequence)
func (*MockRandomSource) Seed ¶
func (m *MockRandomSource) Seed(_ []byte) error
Seed is a no-op for MockRandomSource since it provides deterministic values. This method exists to satisfy the RandomSource interface.
Parameters:
- seed: Ignored (not used in deterministic mock)
Returns:
- Always nil (mock cannot fail to seed)
func (*MockRandomSource) SetValues ¶
func (m *MockRandomSource) SetValues(values ...int32)
SetValues replaces the current value sequence with a new one and resets the index. This allows reusing the same mock instance with different test data.
Parameters:
- values: New int32 values to use in the sequence
Example:
mock := NewMockRandomSource(1, 2, 3) perm1 := fy.Generate(3, mock) mock.SetValues(10, 20, 30) // Change values for next test perm2 := fy.Generate(3, mock)
type TestReporter ¶
type TestReporter interface {
Helper()
Errorf(format string, args ...interface{})
Fatalf(format string, args ...interface{})
Error(args ...interface{})
}
TestReporter is a minimal interface for test reporting used by assertion helpers. This interface is automatically satisfied by *testing.T and *testing.B.
type TestVector ¶
type TestVector struct {
Seed []byte // The seed bytes used for the PRNG
Output []int // The expected permutation output
Size int // The permutation size
}
TestVector represents a cross-platform test vector. Test vectors are used to verify that implementations in different programming languages (Go, Java, TypeScript, Rust) produce identical results.
func GenerateTestVector ¶
func GenerateTestVector(seed []byte, size int, perm []int) TestVector
GenerateTestVector creates a test vector for cross-platform verification. A test vector includes the input parameters and expected output for verifying implementations across different languages.
Parameters:
- seed: The seed bytes
- size: The permutation size
- perm: The expected permutation output
Returns:
- A TestVector struct
Example:
vec := GenerateTestVector([]byte("test"), 10, expectedPerm)
t.Logf("Test Vector: seed=%q, size=%d, output=%v", vec.Seed, vec.Size, vec.Output)