test(numtower): property tests run at the 256-case budget (improvise-59nw.1)
Answers Copilot on PR #337 (context/design-principles.md section 7). Every fault in the review's table still fails by name at 256 cases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
committed by
Edward Langley
parent
34ab0fc3d3
commit
f11d27377d
@@ -105,11 +105,18 @@ to discriminate.
|
||||
|
||||
### rust_decimal_to_f64_agrees_on_fifteen_digit_mantissas_so_a_narrow_generator_is_vacuous
|
||||
|
||||
This test **passes the rival** on purpose. With mantissas of at most 15 digits, 4,096
|
||||
cases, `rust_decimal`'s `to_f64` agrees with the text every time, as ADR 005 says (200,000
|
||||
of 200,000). So a test whose generator stays in that range proves nothing about the
|
||||
conversion. This test is why the generator above spans 96 bits, and it is what fails, and
|
||||
should be re-read, if `rust_decimal` ever fixes its conversion.
|
||||
This test **passes the rival** on purpose. With mantissas of at most 15 digits,
|
||||
`rust_decimal`'s `to_f64` agrees with the text every time, at this test's 256 cases as
|
||||
in ADR 005's 200,000 of 200,000. So a test whose generator stays in that range proves
|
||||
nothing about the conversion, and this test is why the generator above spans 96 bits. It
|
||||
ran at 4,096 cases until Copilot pointed out, on PR #337, that the repository's budget is
|
||||
256 (`context/design-principles.md` §7). The 200,000 is the ADR's measurement, and this
|
||||
test only pins its direction.
|
||||
|
||||
If `rust_decimal` ever fixes its conversion, this test still passes. What fails then is
|
||||
`the_f64_conversion_agrees_with_parsing_the_decimal_text_catches_rust_decimal_to_f64`,
|
||||
whose rival would agree. That is the signal to re-read both. An earlier version of this
|
||||
entry named this test instead, which was wrong.
|
||||
|
||||
### a_fractions_conversion_lies_inside_the_round_to_nearest_even_interval
|
||||
|
||||
@@ -205,7 +212,9 @@ faults passed the whole suite:
|
||||
- F14: the past-K read dropped the decimal partition;
|
||||
- F15: the past-K read dropped every inexact term.
|
||||
|
||||
The test now has the reviewer's oracle and 512 cases. Half the lists come from the
|
||||
The test now has the reviewer's oracle, at the repository's 256-case budget. 34ab0fc3 ran
|
||||
it at 512, and Copilot pointed out the budget. At 256, every fault in the table below
|
||||
still failed by name, and F7, F8, F12, F14 and F15 failed in four of four passes. Half the lists come from the
|
||||
fourteen-denominator pool, up to 40 terms long, so groups receive several terms and K is
|
||||
passed often. **It also counts how many cases reach each branch and fails if any branch
|
||||
is reached fewer than 20 times**, so a generator change cannot silently starve one.
|
||||
|
||||
@@ -93,7 +93,7 @@ fn an_exact_result_is_never_a_rounded_one_catches_a_silently_rounding_add() {
|
||||
fn check_contagion(add: BinOp, deterministic: bool) -> Result<(), String> {
|
||||
let seed = Just((dec("2"), Num::inexact(3.0)));
|
||||
let cases = prop_oneof![1 => seed, 8 => (any_num(), any_num())];
|
||||
run(cases, 512, deterministic, |(a, b)| {
|
||||
run(cases, 256, deterministic, |(a, b)| {
|
||||
let results = [
|
||||
("+", add(&a, &b)),
|
||||
("-", Some(&a - &b)),
|
||||
@@ -310,7 +310,7 @@ fn the_f64_conversion_agrees_with_parsing_the_decimal_text_catches_rust_decimal_
|
||||
#[test]
|
||||
fn rust_decimal_to_f64_agrees_on_fifteen_digit_mantissas_so_a_narrow_generator_is_vacuous() {
|
||||
let narrow = 10i128.pow(15) - 1;
|
||||
let result = run((-narrow..=narrow, 0u32..=15), 4096, true, |(m, s)| {
|
||||
let result = run((-narrow..=narrow, 0u32..=15), 256, true, |(m, s)| {
|
||||
let d = Decimal::from_i128_with_scale(m, s);
|
||||
prop_assert_eq!(
|
||||
crate_to_f64(&d).to_bits(),
|
||||
@@ -772,7 +772,7 @@ fn the_accumulator_reads_the_exact_sum_or_its_stated_roundings() {
|
||||
prop::collection::vec(weighted(term()), 0..24),
|
||||
prop::collection::vec(weighted(pooled_term()), 0..40),
|
||||
];
|
||||
run(lists, 512, false, |xs| {
|
||||
run(lists, 256, false, |xs| {
|
||||
let got = sum_weighted(&xs);
|
||||
let e = Expected::of(&xs);
|
||||
let present = e.inexact.values().any(|w| *w != 0);
|
||||
@@ -1004,7 +1004,7 @@ fn check_language(
|
||||
parse: &dyn Fn(&str, Typing) -> Option<Num>,
|
||||
deterministic: bool,
|
||||
) -> Result<(), String> {
|
||||
run(lexeme(), 512, deterministic, |s| {
|
||||
run(lexeme(), 256, deterministic, |s| {
|
||||
let gate = s.parse::<f64>().is_ok_and(f64::is_finite);
|
||||
let parsed = parse(&s, Typing::Inferred);
|
||||
prop_assert_eq!(
|
||||
@@ -1205,7 +1205,7 @@ fn an_intermediate_beyond_i128_comes_back_exact() {
|
||||
|
||||
#[test]
|
||||
fn the_canonical_text_reads_back_as_the_same_number() {
|
||||
run(any_num(), 512, false, |n| {
|
||||
run(any_num(), 256, false, |n| {
|
||||
let text = n.to_string();
|
||||
let back = Num::from_canonical(&text);
|
||||
prop_assert!(
|
||||
|
||||
Reference in New Issue
Block a user