shape-runtime 0.2.0

Bytecode compiler, builtins, and runtime infrastructure for Shape
Documentation
/// @module std::core::utils::property_testing
/// Property-Based Testing
///
/// Generates random inputs to test invariants (properties) that should
/// hold for all inputs. Inspired by QuickCheck/Hypothesis.

/// Run a property test with random inputs.
///
/// @param name - Test name for reporting
/// @param n_trials - Number of random inputs to try
/// @param gen_fn - Generator function () => input value
/// @param prop_fn - Property function (input) => bool
/// @returns { passed, name, trials, counterexample }
pub fn property(name, n_trials, gen_fn, prop_fn) {
    var counterexample = None;
    var passed = true;

    for i in range(0, n_trials) {
        let input = gen_fn();
        let result = prop_fn(input);
        if !result {
            counterexample = input;
            passed = false;
            break;
        }
    }

    {
        passed: passed,
        name: name,
        trials: n_trials,
        counterexample: counterexample
    }
}

/// Run multiple property tests and return a summary.
///
/// @param tests - Array of { name, trials, gen, prop } objects
/// @returns { passed, failed, results }
pub fn run_properties(tests) {
    let mut results = [];
    var passed_count = 0;
    var failed_count = 0;

    for test in tests {
        let result = property(test.name, test.trials, test.gen, test.prop);
        results.push(result);
        if result.passed {
            passed_count = passed_count + 1;
        } else {
            failed_count = failed_count + 1;
        }
    }

    {
        passed: passed_count,
        failed: failed_count,
        total: tests.len(),
        results: results
    }
}

// ===== Built-in Generators =====

/// Generate random integer in [lo, hi]
pub fn gen_int(lo, hi) {
    || __intrinsic_random_int(lo, hi)
}

/// Generate random float in [lo, hi)
pub fn gen_float(lo, hi) {
    || lo + __intrinsic_random() * (hi - lo)
}

/// Generate random boolean
pub fn gen_bool() {
    || __intrinsic_random() < 0.5
}

/// Generate random string of given length from ascii letters
pub fn gen_string(max_len) {
    || {
        let chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        let n = __intrinsic_random_int(0, max_len);
        var s = "";
        for i in range(0, n) {
            let idx = __intrinsic_random_int(0, 61);
            s = s + chars[idx];
        }
        s
    }
}

/// Generate random array of given max length using element generator
pub fn gen_array(max_len, elem_gen) {
    || {
        let n = __intrinsic_random_int(0, max_len);
        let mut arr = [];
        for i in range(0, n) {
            arr.push(elem_gen());
        }
        arr
    }
}

/// Generate a value picked uniformly from a list of choices
pub fn gen_one_of(choices) {
    || {
        let idx = __intrinsic_random_int(0, choices.len() - 1);
        choices[idx]
    }
}