Skip to content

Commit

Permalink
Some randomness testing utilities fixes (#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
oscbyspro committed Oct 11, 2024
1 parent c1f62b8 commit b1e7d91
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 4 deletions.
32 changes: 32 additions & 0 deletions Sources/TestKit2/Expect+Random.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//=----------------------------------------------------------------------------=
// This source file is part of the Ultimathnum open source project.
//
// Copyright (c) 2023 Oscar Byström Ericsson
// Licensed under Apache License, Version 2.0
//
// See http://www.apache.org/licenses/LICENSE-2.0 for license information.
//=----------------------------------------------------------------------------=

import CoreKit

//*============================================================================*
// MARK: * Expect x Random x Utilities
//*============================================================================*

@inlinable public func Ɣexpect<T>(
entropic randomness: inout some Randomness,
through index: Shift<T.Magnitude>,
as domain: Domain,
is expectation: Set<T>,
at location: SourceLocation = #_sourceLocation
) where T: BinaryInteger {
var result = Set<T>()

while result.count < expectation.count {
for _ in 000 ..< expectation.count {
result.insert(T.entropic(through: index, as: domain, using: &randomness))
}
}

#expect(result == expectation, sourceLocation: location)
}
38 changes: 34 additions & 4 deletions Sources/TestKit2/Utilities+Integers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ extension BinaryInteger {
// MARK: Initializers
//=------------------------------------------------------------------------=

/// Picks a random value with focus on `BinaryInteger/entropy()`.
@inlinable public static func entropic(
as domain: Domain = Domain.binary,
using randomness: inout some Randomness
Expand All @@ -75,6 +76,7 @@ extension BinaryInteger {
Self.entropic(through: Shift.max, as: domain, using: &randomness)
}

/// Picks a random value with focus on `BinaryInteger/entropy()`.
@inlinable public static func entropic(
size: IX,
as domain: Domain = Domain.binary,
Expand All @@ -84,18 +86,46 @@ extension BinaryInteger {
Self.entropic(through: Shift(Count(size - 1)), as: domain, using: &randomness)
}

/// Picks a random value with focus on `BinaryInteger/entropy()`.
///
/// ### Examples: (index: one, domain: binary)
///
/// ```
/// ..signed: [-2, -1, 0, 1 ]
/// unsigned: [ 0, 1, ~1, ~0]
/// ```
///
/// ### Examples: (index: one, domain: finite)
///
/// ```
/// ..signed: [-2, -1, 0, 1 ]
/// unsigned: [ 0, 1, 2, 3]
/// ```
///
/// ### Examples: (index: one, domain: natural)
///
/// ```
/// ..signed: [ 0, 1 ]
/// unsigned: [ 0, 1, 2, 3]
/// ```
///
@inlinable public static func entropic(
through index: Shift<Magnitude>,
as domain: Domain = Domain.binary,
using randomness: inout some Randomness
) -> Self {

let index = Shift.random(through: index, using: &randomness)

switch domain {
case Domain .binary: return Self(raw: Signitude.random(through: index, using: &randomness))
case Domain .finite: return Self(raw: Magnitude.random(through: index, using: &randomness))
case Domain.natural: return Self(raw: Self.random(through: index, using: &randomness).magnitude())
case Domain.binary:
return Self(raw: Signitude.random(through: index, using: &randomness))

case Domain.finite:
return Self.random(through: index, using: &randomness)

case Domain.natural:
let random = Magnitude.random(through: index, using: &randomness)
return Self(raw: Self.isSigned ? random.down(Shift.one) : random)
}
}
}
59 changes: 59 additions & 0 deletions Tests/UltimathnumTests/Utilities/Utilities+Integers.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//=----------------------------------------------------------------------------=
// This source file is part of the Ultimathnum open source project.
//
// Copyright (c) 2023 Oscar Byström Ericsson
// Licensed under Apache License, Version 2.0
//
// See http://www.apache.org/licenses/LICENSE-2.0 for license information.
//=----------------------------------------------------------------------------=

import CoreKit
import RandomIntKit
import TestKit2

//*============================================================================*
// MARK: * Utilities x Integers
//*============================================================================*

@Suite struct UtilitiesTestsOnIntegers {

//=------------------------------------------------------------------------=
// MARK: Tests
//=------------------------------------------------------------------------=

@Test("BinaryInteger.entropic(through:as:using:) - max index for each domain", arguments: i8u8, fuzzers)
func entropicThroughMaxIndexForEachDomain(type: any SystemsInteger.Type, randomness: consuming FuzzerInt) {
whereIs(type)

func whereIs<T>(_ type: T.Type) where T: SystemsInteger {
Ɣexpect(entropic: &randomness, through: Shift.max, as: Domain.binary, is: Set(T.all))
Ɣexpect(entropic: &randomness, through: Shift.max, as: Domain.finite, is: Set(T.all))
Ɣexpect(entropic: &randomness, through: Shift.max, as: Domain.natural, is: Set(T.nonnegatives))
}
}

@Test("BinaryInteger.entropic(through:as:using:) - small indices for each domain", arguments: binaryIntegers, fuzzers)
func entropicThroughSmallIndicesForEachDomain(type: any BinaryInteger.Type, randomness: consuming FuzzerInt) {
whereIs(type)

func whereIs<T>(_ type: T.Type) where T: BinaryInteger {
if T.isSigned {
Ɣexpect(entropic: &randomness, through: Shift.min, as: Domain.binary, is: [ -1, 0 ] as Set<T>)
Ɣexpect(entropic: &randomness, through: Shift.min, as: Domain.finite, is: [ -1, 0 ] as Set<T>)
Ɣexpect(entropic: &randomness, through: Shift.min, as: Domain.natural, is: [ 0 ] as Set<T>)

Ɣexpect(entropic: &randomness, through: Shift.one, as: Domain.binary, is: [-2, -1, 0, 1] as Set<T>)
Ɣexpect(entropic: &randomness, through: Shift.one, as: Domain.finite, is: [-2, -1, 0, 1] as Set<T>)
Ɣexpect(entropic: &randomness, through: Shift.one, as: Domain.natural, is: [ 0, 1] as Set<T>)
} else {
Ɣexpect(entropic: &randomness, through: Shift.min, as: Domain.binary, is: [ 0, ~0] as Set<T>)
Ɣexpect(entropic: &randomness, through: Shift.min, as: Domain.finite, is: [ 0, 1 ] as Set<T>)
Ɣexpect(entropic: &randomness, through: Shift.min, as: Domain.natural, is: [ 0, 1 ] as Set<T>)

Ɣexpect(entropic: &randomness, through: Shift.one, as: Domain.binary, is: [ 0, 1, ~1, ~0] as Set<T>)
Ɣexpect(entropic: &randomness, through: Shift.one, as: Domain.finite, is: [ 0, 1, 2, 3] as Set<T>)
Ɣexpect(entropic: &randomness, through: Shift.one, as: Domain.natural, is: [ 0, 1, 2, 3] as Set<T>)
}
}
}
}

0 comments on commit b1e7d91

Please sign in to comment.