Skip to content

Testing architecture for the standard library #18

Description

@LesterEvSe

Problem

simf/lib/ is the product; everything else is scaffolding. Today that scaffolding uses one shape for every feature — a per-feature program with witness dispatch plus per-feature Rust plumbing — but the wishlist features differ in what context they need to run:

Feature Needs Category
and/or/not, EC point_to_gej, decimals, identities, deep_eq, is_some/is_none known input → known output Vector
checked/safe arithmetic randomized inputs + failure injection Property
u256 store/load, Merkle tools program storage state Stateful
asset/amount utils, script-hash utils, OP_RETURN, covenants, relative timelocks a crafted transaction Scenario

The bulk of the wishlist is Scenario, which has no shared support today.

Proposal

Standardize the universal piece (spend plumbing), then pick the lightest category per feature. Build order:

  1. Shared helpers — extract the duplicated fund / spend / broadcast / assert block. Everything below builds on it.
  2. Vector tests (default) — self-asserting main(), no witness; Rust side is one call to the helpers. A generic runner enumerates a registry of should-succeed programs. Prove out by converting logical and ct/point.
  3. Scenario tests (main future investment) — reusable transaction-scenario builder (inputs/outputs, assets, sequence/version, OP_RETURN, storage) plus a thin contract entrypoint per function. Unblocks covenants, assets, script hashes, timelocks.
    Property tests already exist and stay as-is.

Layout

simf/
  lib/
  logical.simf  ct_point.simf  uint.simf  ...   # test entrypoints, mirroring lib/
tests/
  common/                                        # shared helpers + scenario builder
  logical.rs  ct_point.rs  uint.rs  ...

Rename *_mock.simf*_test.simf; these are entrypoints, not mocks.

Entrypoints can't live in simf/tests/. A contract resolves modules (crate::lib::...) relative to its main file's directory, so a main under simf/tests/ can't see simf/lib/. Decoupling source root from entrypoint location needs separate Simplex/SimplicityHL work — out of scope here.

Future: enum dispatch

Witness-driven contracts currently select a function via numeric witness::FUNCTION_INDEX with one match if_test_this_function(N, ...) block per case. Once PR #336 lands, indices become named variants and dispatch collapses to a single match with one arm per case. Readability only.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions