Skip to content

test: one contract per file (satisfy rainix single-contract gate) - #537

Open
thedavidmeister wants to merge 5 commits into
mainfrom
2026-06-15-one-contract-per-file
Open

test: one contract per file (satisfy rainix single-contract gate)#537
thedavidmeister wants to merge 5 commits into
mainfrom
2026-06-15-one-contract-per-file

Conversation

@thedavidmeister

@thedavidmeister thedavidmeister commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

The rainix rainix-sol-single-contract gate (rainix #214) enforces the Rain convention of one contract / abstract contract per .sol file. 14 pre-existing test files declared more than one contract, which fails the gate and reds main.

This PR splits each offending file so every .sol declares exactly one contract. The primary test contract stays in the original file named after it; each helper / mock / secondary contract moves into its own file named after the contract, carrying the SPDX header, pragma, and the imports it needs. Each original file imports the contracts it still references. This is a pure file reorganization: no test logic or contract behavior changed.

Files split (original -> moved contracts in their own new files)

  • test/src/abstract/BaseRainlangExtern.construction.t.sol (5) -> TestableExtern.sol, EmptyPointersExtern.sol, MismatchedExternMoreOpcodes.sol, MismatchedExternMoreIntegrity.sol
  • test/src/abstract/BaseRainlangExtern.ierc165.t.sol (2) -> ChildRainlangExtern.sol
  • test/src/abstract/BaseRainlangExtern.integrityOpcodeRange.t.sol (2) -> TwoOpExtern.sol
  • test/src/abstract/BaseRainlangSubParser.ierc165.t.sol (2) -> ChildRainlangSubParser.sol
  • test/src/abstract/BaseRainlangSubParser.subParseLiteral2.t.sol (4) -> HappyPathLiteralSubParser.sol, NoMatchLiteralSubParser.sol, MismatchedLiteralSubParser.sol
  • test/src/abstract/BaseRainlangSubParser.subParseWord2.t.sol (3) -> MismatchedWordSubParser.sol, EmptyWordParsersSubParser.sol
  • test/src/concrete/RainlangInterpreter.zeroFunctionPointers.t.sol (2) -> ZeroFPRainlangInterpreter.sol
  • test/src/concrete/RainlangParser.parseMemoryOverflow.t.sol (2) -> ModifierTestParser.sol
  • test/src/concrete/RainlangReferenceExtern.subParserIndexOutOfBounds.t.sol (2) -> MockExternBadLiteralIndex.sol
  • test/src/lib/integrity/LibIntegrityCheck.t.sol (3) -> IntegritySingleOp.sol, IntegrityHighwater.sol
  • test/src/lib/parse/LibSubParse.badSubParserResult.t.sol (2) -> BadLengthSubParser.sol
  • test/src/lib/parse/LibSubParse.constantAccumulation.t.sol (3) -> ConstantReturningSubParser.sol, MultiConstantSubParser.sol
  • test/src/lib/parse/LibSubParse.subParseWords.t.sol (2) -> ContextReturningSubParser.sol
  • test/src/lib/state/LibInterpreterStateDataContract.t.sol (2) -> LibInterpreterStateDataContractExtern.sol

14 files split into 22 new single-contract files; contract count is conserved (36 contracts before and after).

Verification

  • rainix-sol-single-contract exits 0 (no violations remain).
  • forge build clean; forge fmt --check clean.
  • forge test: 1524 passed. The only 16 failures are pre-existing fork tests that need RPC env vars (ARBITRUM_RPC_URL, BASE_RPC_URL, etc.) not set in the local sandbox; they fail identically on clean main and are in files this PR does not touch.

Greens main and unblocks coverage PRs #534 and #536.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added explanatory documentation for the zero-function-pointer Rainlang interpreter override.

Split each test .sol that declared more than one contract so every file
declares exactly one. The primary test contract stays in the original
file; each helper/mock/secondary contract moves to its own file named
after the contract, with the SPDX header, pragma, and imports it needs.
Each original file imports the contracts it still references.

Pure file reorganization: no test logic or contract behavior changes.
Satisfies the rainix rainix-sol-single-contract gate (rainix #214),
greening main and unblocking coverage PRs #534 and #536.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@thedavidmeister thedavidmeister self-assigned this Jun 15, 2026
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 57854a20-6ddc-4066-86c3-1f4c830d53e5

📥 Commits

Reviewing files that changed from the base of the PR and between a6b7ad7 and 3ab9897.

📒 Files selected for processing (1)
  • test/src/concrete/ZeroFPRainlangInterpreter.sol

Included review availability: Your plan includes up to 1 review per rolling hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The change adds a developer comment to ZeroFPRainlangInterpreter. The comment documents that the interpreter override uses empty opcode function pointers.

Changes

Interpreter documentation

Layer / File(s) Summary
Document interpreter override
test/src/concrete/ZeroFPRainlangInterpreter.sol
Adds a comment describing the override’s empty opcode function pointers.

Estimated code review effort: 1 (Trivial) | ~2 minutes

Merge Risk: ⚪ Minimal · up to 3ab98

This PR reorganizes test contracts into one contract per file without changing test logic or contract behavior, and the relevant build, formatting, gate, and test checks pass. No actionable merge-blocking risk remains beyond normal review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change: splitting test contracts into one contract per file to satisfy the single-contract gate.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 2026-06-15-one-contract-per-file

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@thedavidmeister

Copy link
Copy Markdown
Contributor Author

🤖 ai:producer
Producer note: MAIN-STATE red, not PR-caused — the only failures on rainix-sol / test (run 28749242292) are the 5 testProdDeploy* 'Interpreter not deployed' prod-pins; main fails identically (run 28658876491, 2026-07-03). This PR is a pure test-file reorganization (no bytecode change); it greens when main's pending interpreter deploy lands. No empty-commit retrigger pushed — a re-run reproduces the same pins.

@thedavidmeister thedavidmeister added the ai:ready AI vetter: passes review, ready for human decision label Jul 6, 2026
@thedavidmeister

thedavidmeister commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

🤖 ai:vetter
Reviewed 23d6050: ready — re-vet after merge-main-only commit, full-diff line-multiset check confirms pure reorganization with
cost 185 — mechanical file split, gate-verified

@thedavidmeister thedavidmeister added ai:blocked-deploy and removed ai:ready AI vetter: passes review, ready for human decision labels Jul 12, 2026
@thedavidmeister

Copy link
Copy Markdown
Contributor Author

🤖 ai:producer
Blocked-deploy: Blocked on the same failed interpreter deploy as #534 (see its ai:blocked-deploy note): rainix-sol test red is main-state prod pins ('Interpreter not deployed' ×5 networks), no branch fix possible from this test-only PR. Deployer EOA 0x6698…9a88 unfunded on flare (0 FLR) / underfunded on polygon; greens when the funded re-dispatch of suite=interpreter lands.

@thedavidmeister

Copy link
Copy Markdown
Contributor Author

👤 human
Ruled 23d6050: reject — executing the 2026-08-06 ruling in rainlanguage/issue-pr-cron#221 — the retired ai:blocked-deploy residue (#162) migrates to ai:reject for rework to the split release lifecycle

@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Rework note @23d605015892d5bbc29de677ba6fb2634199a29a: rework the PR to fit the split release lifecycle — deploys never gate merges (the deploy-before-merge choreography is superseded); remove or restructure anything in the PR that waits on a deploy; where deploy constants/pins are involved, follow the *.deploy repo convention (audited code only; version ↔ snapshot ↔ pins internally consistent; tag-release lifecycle). Whatever states follow the rework (including a typed blocked-on the repo's migration if one is genuinely needed) are the producer's ordinary transitions. Executes the 2026-08-06 ruling: rainlanguage/issue-pr-cron#221

@thedavidmeister thedavidmeister added ai:needs-work Needs rework — the producer's inbox (vetter verdict or human ruling) and removed ai:blocked-deploy labels Aug 6, 2026
…ct-per-file

# Conflicts:
#	test/src/abstract/BaseRainlangSubParser.subParseLiteral2.t.sol
#	test/src/abstract/MismatchedLiteralSubParser.sol
#	test/src/abstract/NoMatchLiteralSubParser.sol
#	test/src/concrete/ZeroFPRainlangInterpreter.sol
@thedavidmeister thedavidmeister added ai:design AI vetter: raises a design question and removed ai:needs-work Needs rework — the producer's inbox (vetter verdict or human ruling) labels Aug 18, 2026
@thedavidmeister

Copy link
Copy Markdown
Contributor Author

🤖 ai:producer
Design-question: Superseded by merged #549 — the rework leaves a one-line PR. Executing the needs-work order (split release lifecycle, #221): this PR waits on no deploy in its content — the ai:blocked-deploy state was pure residue, so there was nothing deploy-shaped to restructure. Resolved the DIRTY conflicts by merging main (4 add/add conflicts, unioned both sides: kept main's echoLiteralParser free functions in BaseRainlangSubParser.subParseLiteral2.t.sol / MismatchedLiteralSubParser.sol / NoMatchLiteralSubParser.sol, kept this branch's NatSpec on ZeroFPRainlangInterpreter.sol). Pushed 23d6050 -> 3ab9897 so the state below is visible on GitHub rather than resting on this note. What that merge revealed: main already carries this PR's ENTIRE split, landed via merged PR #549 (fix/one-contract-per-file). Evidence: test/src file lists are identical (255 == 255, empty symmetric difference); test/invariant function signatures are identical (1552 == 1552, empty both ways) so closing loses no test; zero test .sol files on main declare more than one contract, i.e. the rainix-sol-single-contract gate this PR exists to satisfy is ALREADY satisfied on main. The full remaining diff of this branch against main is one NatSpec line: '/// @dev RainlangInterpreter override with empty opcode function pointers.' on ZeroFPRainlangInterpreter.sol. Merging also had to DROP one thing this branch carried that main deliberately pruned: an unused 'import {BadOpInputsLength, BadOpOutputsLength}' in LibIntegrityCheck.t.sol (referenced nowhere in that file) — main's prune is correct and the merge took it. DESIGN QUESTION: this PR's stated purpose is done and its title no longer describes its content. Close it as superseded by #549, or keep it open to land the single NatSpec comment (better as a one-line docs PR)? Producer's read: close as superseded. Note the two red checks are not PR-caused — rs-static runs over crates/ and this diff touches zero Rust, so it is main-state red; rainix-sol/static (slither + forge fmt) cannot be moved by a comment line either. Flagging design rather than closing because no producer transition closes a PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai:design AI vetter: raises a design question

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant