Migrate the slice/str-header core of drew's Family 1 from bespoke build+run C twins to test/lang @test, retiring each now-redundant twin in the same commit. Runtime coverage MOVES from $(TESTS) to test-lang (T1 runs+asserts via `ww test`) + test-lang-byteid (T2 keeps cs==ww .s byte-id); coverage is preserved, the $(TESTS) headline drops 6 (440->434). All asserts are primitive int/u8/bool comparisons (no fmt/strconv in the assert path); the slice-store families poison the slot (cap!=len) and read it back so a dropped data word FAILS. 928_str_abi_run.c -> str_abi_test.ww (str 24B ABI: .len/.cap across literal/arg/return/field/tuple/deref/index/tagged) 941_slice_store_cap_run.c -> slice_store_cap_test.ww (slice value store through indexed/field/chained lhs writes full 24B header; cap==8) 942_subslice_cap_run.c -> subslice_cap_test.ww (sub-slice cap = base_cap-lo; array/slice/str/append-no-realloc/hi-default) 943_subslice_ptresz_run.c -> subslice_ptresz_test.ww (sub-slice ptr advances lo*esz bytes; esz 2/4/8, let + call-arg) 944_deref_slice_store_run.c-> deref_slice_store_test.ww(*p=sliceval whole-deref store writes 24B header; cap==8) 949_f6_header_run.c -> f6_header_test.ww (str/slice header partial load/store; .cap/.len after clobber) Bump LANGBYTEID_EXPECTED_MIN 16->22 to ratchet the new corpus floor.
77 lines
2.7 KiB
Plaintext
77 lines
2.7 KiB
Plaintext
// subslice_cap_test — a sub-slice `base[lo:hi]` must set its capacity word to
|
|
// base_cap - lo (storage remaining to the underlying end; Go/Hare-identical),
|
|
// NOT hi - lo (the new length), migrated from test/wcc/942_subslice_cap_run.c
|
|
// (task #20). base_cap is the array length N for [N]T, or the carried .capacity
|
|
// for a slice/str base. Cite (drew): harec ref/harec/src/eval.c:1017 (slice cap
|
|
// -= start), eval.c:1024 (array cap = length - start), check.c:596 (cap>=len),
|
|
// ref/hare/rt/ensure.ha:4-8 (capacity is a distinct field).
|
|
//
|
|
// Before the fix BOTH stages emitted cap = hi - lo (== len). Every row picks a
|
|
// shape where base_cap - lo != hi - lo, so a stale `cap = len` stage is
|
|
// observably wrong (cap reads hi-lo, or the append row reallocs instead of
|
|
// filling the base's spare). cap != len in every row.
|
|
|
|
package subslice_cap_test;
|
|
|
|
@test fn subslice_array_hilt_n() void = {
|
|
// A — array base, hi < N. cap = N(8) - lo(1) = 7 != len(2).
|
|
let a: [8]u8;
|
|
let i: i32 = 0;
|
|
for (i < 8) { a[i] = (20 + i): u8; i += 1; };
|
|
let s: []u8 = a[1:3];
|
|
assert(s.cap: i32 == 7);
|
|
assert(s.len: i32 == 2);
|
|
assert(s[0] == 21u8);
|
|
};
|
|
|
|
@test fn subslice_slice_spare_cap() void = {
|
|
// B — slice base with spare cap. cap = base.cap(8) - lo(1) = 7 != len(3);
|
|
// base.cap is read from the header +16, not re-derived.
|
|
let a: [8]u8;
|
|
let i: i32 = 0;
|
|
for (i < 8) { a[i] = (40 + i): u8; i += 1; };
|
|
let p: []u8; p.ptr = &a[0]; p.len = 6; p.cap = 8;
|
|
let s: []u8 = p[1:4];
|
|
assert(s.cap: i32 == 7);
|
|
assert(s.len: i32 == 3);
|
|
assert(s[0] == 41u8);
|
|
};
|
|
|
|
@test fn subslice_str_base() void = {
|
|
// C — str base (str[lo:hi] yields str, real .capacity, no downgrade).
|
|
// cap = sb.cap(5) - lo(1) = 4 != len(2).
|
|
let sb: str = "hello";
|
|
let s: str = sb[1:3];
|
|
assert(s.cap: i32 == 4);
|
|
assert(s.len: i32 == 2);
|
|
assert(s[0] == 101u8);
|
|
};
|
|
|
|
@test fn subslice_append_no_realloc() void = {
|
|
// D — append-no-realloc (strongest). s = buf[1:3] has cap 7 > len 2, so
|
|
// append(s,99) fills buf's spare at lo+len = 3. A cap=len stage sees
|
|
// len==cap (full) and reallocs, leaving buf[3] == 0.
|
|
let buf: [8]u8;
|
|
let i: i32 = 0;
|
|
for (i < 8) { buf[i] = 0u8; i += 1; };
|
|
let s: []u8 = buf[1:3];
|
|
append(s, 99u8);
|
|
assert(s.cap: i32 == 7);
|
|
assert(s.len: i32 == 3);
|
|
assert(s[2] == 99u8);
|
|
assert(buf[3] == 99u8);
|
|
};
|
|
|
|
@test fn subslice_hidefault_spare_cap() void = {
|
|
// E — hi-default with spare cap. p{len=6,cap=8}; `p[2:]` defaults hi to
|
|
// base.len=6, so len = 4, but cap = base.cap(8) - lo(2) = 6 != len.
|
|
let a: [8]u8;
|
|
let i: i32 = 0;
|
|
for (i < 8) { a[i] = (60 + i): u8; i += 1; };
|
|
let p: []u8; p.ptr = &a[0]; p.len = 6; p.cap = 8;
|
|
let s: []u8 = p[2:];
|
|
assert(s.cap: i32 == 6);
|
|
assert(s.len: i32 == 4);
|
|
assert(s[0] == 62u8);
|
|
};
|