lib/test: Go external-test packages (<mod>_test); retire decimaltest (#16 PREP-a)

30 lib test files: package <mod> -> <mod>_test, the sanctioned Go-over-Hare
departure (CLAUDE.md rule-9 carve-out; white-box testing deferred, not
forbidden). decimaltest retired per .ai/rob-16-decimaltest-ruling.md: Hare
ships no decimal_test.ha (engine covered transitively); coverage migrated
losslessly into stoftest rows (all-9s carry, nd>19 pure-decimal) + ftostest
f64_roundtrip mirroring ref/hare strconv ftos_test.ha tcsf64; k=0 micro-gap
documented at site. regex_test keeps its white-box internal probes under a
documented rule-7 divergence (rehome = task #9). 922_decimal_run + its 989
byte-id row removed with the fixture.
This commit is contained in:
2026-06-10 12:11:11 +09:00
parent b795c320c9
commit 99e3393048
35 changed files with 77 additions and 306 deletions

View File

@@ -20,7 +20,7 @@
// DIRECTORY (full package), not the strconv.ww FILE — same rationale as
// stoftest/decimaltest.
package strconv;
package strconv_test;
import strconv;
import os;
@@ -43,6 +43,17 @@ fn chk(n: f64, want: str) bool = {
return streq(f64tos(n), want);
};
// rt64 — bit-exact round-trip: render then parse back must reproduce the
// exact bits. The parse-back re-runs strconv's decimal slow path.
fn rt64(x: f64) bool = {
match (stof64(f64tos(x), base.DEC)) {
case let v: f64 => { return math.f64bits(v) == math.f64bits(x); };
case let e: invalid => { return false; };
case let e: overflow => { return false; };
};
return false;
};
// ftos_test.ha:57-64 (G/void/NONE-equivalent) — fixed-point renders.
@test fn f64tos_fixed() void = {
if (!chk(13.37, "13.37")) { fail(); };
@@ -151,6 +162,21 @@ fn chkf32(n: f32, want: str) bool = {
if (!chkf32(nan, "nan")) { fail(); };
};
// ftos_test.ha:196-204 (tcsf64) — Hare's f64-exclusive extremes, here as a
// bit-exact ROUND-TRIP (f64bits(stof64(f64tos(x)))==f64bits(x)): the parse-
// back re-runs strconv's decimal engine end-to-end, preserving the coverage
// the retired white-box decimaltest.ww gave directly (#16). Extremes built
// via f64frombits (ww math has no F64_MIN_*/MAX_NORMAL const); exact and
// 17-digit-halfway values as literals.
@test fn f64_roundtrip() void = {
if (!rt64(9007199254740991.0)) { fail(); }; // 2^53-1
if (!rt64(90071992547409915.0)) { fail(); }; // 17-digit halfway pair
if (!rt64(90071992547409925.0)) { fail(); };
if (!rt64(math.f64frombits(0x0000000000000001u64))) { fail(); }; // F64_MIN_SUBNORMAL (5e-324)
if (!rt64(math.f64frombits(0x0010000000000000u64))) { fail(); }; // F64_MIN_NORMAL
if (!rt64(math.f64frombits(0x7FEFFFFFFFFFFFFFu64))) { fail(); }; // F64_MAX_NORMAL
};
export fn main() i32 = {
signalled = 1; f64tos_fixed();
signalled = 2; f64tos_scientific();
@@ -159,6 +185,7 @@ export fn main() i32 = {
signalled = 5; f32tos_scientific();
signalled = 6; f32tos_extremes();
signalled = 7; f32tos_special();
signalled = 8; f64_roundtrip();
os.exit(0);
return 0;
};