From 95a1e8905e9054ee914687409cf80575cad19304 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 16 Aug 2026 18:18:09 +0000 Subject: [PATCH 1/2] test: drop two assertions a sibling in the same file already implies `testFilePrefixNamesNoScript` asserted the prefix holds no `.sol`. `testFilePrefixExact` pins the whole prefix, so exactly one string passes it and every string naming a `.sol` file fails it. `testBytesToHexHasNoPrefix` asserted no output byte is `x`. `testBytesToHexCharset` asserts every output byte is in `[0-9a-f]`, an alphabet that excludes `x`, and both fuzz the same `bytes` domain for 2048 runs. Each survivor carries the removed intent in its docstring. Co-Authored-By: Claude Opus 5 (1M context) --- test/lib/LibCodeGen.filePrefix.t.sol | 15 ++++++--------- test/lib/LibHexString.bytesToHex.t.sol | 13 ++++--------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/test/lib/LibCodeGen.filePrefix.t.sol b/test/lib/LibCodeGen.filePrefix.t.sol index 7fc5594..3be611d 100644 --- a/test/lib/LibCodeGen.filePrefix.t.sol +++ b/test/lib/LibCodeGen.filePrefix.t.sol @@ -7,19 +7,16 @@ import {LibCodeGen} from "src/lib/LibCodeGen.sol"; /// @title LibCodeGenFilePrefixTest contract LibCodeGenFilePrefixTest is Test { - /// The prefix must not name the script that generates the file. Each - /// consumer names its own build script, so any script path here is a claim - /// this library cannot keep. Asserted as "names no Solidity file at all" - /// because the constraint is that no script is named, not that some - /// particular name is absent. - function testFilePrefixNamesNoScript() external pure { - assertFalse(vm.contains(LibCodeGen.filePrefix(), ".sol"), "prefix names a script"); - } - /// The prefix heads every generated file in every consumer repo, so a /// change here rewrites committed files org wide. Pinned exactly so that /// lands as a deliberate, reviewable diff rather than a surprise on the /// next regeneration. + /// + /// The pinned text names no script. Each consumer names its own build + /// script, so a script path in the prefix would be a claim this library + /// cannot keep. Exactly one string passes here, so every string that + /// names a `.sol` file fails, and pinning the whole prefix is what + /// refuses them. function testFilePrefixExact() external pure { //REUSE-IgnoreStart assertEq( diff --git a/test/lib/LibHexString.bytesToHex.t.sol b/test/lib/LibHexString.bytesToHex.t.sol index a4163b9..0e05757 100644 --- a/test/lib/LibHexString.bytesToHex.t.sol +++ b/test/lib/LibHexString.bytesToHex.t.sol @@ -69,15 +69,6 @@ contract LibHexStringBytesToHexTest is Test { ); } - /// The prefix is removed, not merely expected to be absent. `0x` cannot - /// appear in hex output, so any `x` in the result is a prefix that survived. - function testBytesToHexHasNoPrefix(bytes memory data) external pure { - bytes memory hexBytes = bytes(LibHexString.bytesToHex(vm, data)); - for (uint256 i = 0; i < hexBytes.length; i++) { - assertTrue(hexBytes[i] != bytes1("x"), "prefix survived"); - } - } - /// Two characters per byte, exactly. An off by one here emits an odd number /// of hex nibbles and the generated source does not compile. function testBytesToHexLength(bytes memory data) external pure { @@ -86,6 +77,10 @@ contract LibHexStringBytesToHexTest is Test { /// Every character is a lower case hex nibble. Anything else in the string /// terminates or corrupts the `hex"..."` literal it is spliced into. + /// + /// `x` is outside that alphabet, and hex output can only hold an `x` as a + /// prefix character the strip left behind, so this also pins that the + /// prefix is removed rather than merely expected to be absent. function testBytesToHexCharset(bytes memory data) external pure { bytes memory hexBytes = bytes(LibHexString.bytesToHex(vm, data)); for (uint256 i = 0; i < hexBytes.length; i++) { From 36a640b4790c318ccea2d60e3abbde20d26d82d9 Mon Sep 17 00:00:00 2001 From: David Meister Date: Sun, 16 Aug 2026 19:26:34 +0000 Subject: [PATCH 2/2] test: restore testBytesToHexHasNoPrefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two fuzz tests over one domain are not one test. `x` is outside `[0-9a-f]`, so on any single output `testBytesToHexCharset` implies `testBytesToHexHasNoPrefix` — but `[fuzz] runs = 2048` with no pinned seed means each of them draws its own 2048 inputs, and the survivor's coverage of `bytes memory` is its own draws. Deleting the weaker sibling cost 2048 draws of the property, which is coverage rather than redundancy. The `testFilePrefixNamesNoScript` deletion stands. `filePrefix()` takes no arguments and is `pure`, so `testFilePrefixExact` pins the only input there is and subsumption is total. Drops the docstring paragraph added to `testBytesToHexCharset` to stand in for the deleted test, since the test is back. Co-Authored-By: Claude Opus 5 (1M context) --- test/lib/LibHexString.bytesToHex.t.sol | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/test/lib/LibHexString.bytesToHex.t.sol b/test/lib/LibHexString.bytesToHex.t.sol index 0e05757..a4163b9 100644 --- a/test/lib/LibHexString.bytesToHex.t.sol +++ b/test/lib/LibHexString.bytesToHex.t.sol @@ -69,6 +69,15 @@ contract LibHexStringBytesToHexTest is Test { ); } + /// The prefix is removed, not merely expected to be absent. `0x` cannot + /// appear in hex output, so any `x` in the result is a prefix that survived. + function testBytesToHexHasNoPrefix(bytes memory data) external pure { + bytes memory hexBytes = bytes(LibHexString.bytesToHex(vm, data)); + for (uint256 i = 0; i < hexBytes.length; i++) { + assertTrue(hexBytes[i] != bytes1("x"), "prefix survived"); + } + } + /// Two characters per byte, exactly. An off by one here emits an odd number /// of hex nibbles and the generated source does not compile. function testBytesToHexLength(bytes memory data) external pure { @@ -77,10 +86,6 @@ contract LibHexStringBytesToHexTest is Test { /// Every character is a lower case hex nibble. Anything else in the string /// terminates or corrupts the `hex"..."` literal it is spliced into. - /// - /// `x` is outside that alphabet, and hex output can only hold an `x` as a - /// prefix character the strip left behind, so this also pins that the - /// prefix is removed rather than merely expected to be absent. function testBytesToHexCharset(bytes memory data) external pure { bytes memory hexBytes = bytes(LibHexString.bytesToHex(vm, data)); for (uint256 i = 0; i < hexBytes.length; i++) {