Skip to content

Libraries

Arttu Jantunen edited this page Nov 2, 2026 · 1 revision

A library has no pages: its scenarios call it. A step is a function, a static method, a new object or a method on one, always under the original's names:

steps:
  - fn: Shop\slug
    args: ["Hello World"]            # a list, or named arguments: {text: "Hello World"}
  - fn: Shop\Cart::fromJson          # a static method
    args: ['{"lines": {}}']
  - new: Shop\Cart                   # an object, kept for the steps after it
    args: [EUR]
    as: cart
  - fn: cart.add                     # a method on it
    args: [apple, 2]
    id: added                        # later steps use {{added.value}}

What is recorded

Each call is recorded as result:

  • {"value": ...}: an object as {"$object": class, its public properties}, an enum case as {"$enum": "Class::CASE"}, nothing as null;
  • {"error": {"class": ..., "message": ...}} when it throws;
  • with "output" when it printed.

Files, databases and outside calls are recorded as for an app.

How it is called

Every implementation of a library is a small HTTP server, a shim, that turns each step into a call: POST /call with {"fn" | "new", "args", "as"}, answering as above, and GET /health. parityrun ships them in {shims} (an impls.json placeholder):

  • {shims}/library.php serves a PHP library: PARITYRUN_LIB names the files to load, comma-separated and relative to the working folder, wildcards allowed (default vendor/autoload.php). With coverage=True it writes the lines run after every call.
  • library.js, library.ts and library.rs (with json.rs, JSON without crates) are the templates a port fills in: tables of the original's functions and classes (JavaScript, TypeScript) or a call function (Rust). The rest of each is the protocol and stays as it is.
{"php":  {"cwd": "php", "cmd": ["php", "{shims}/library.php"], "env": {"PORT": "{port}", "PARITYRUN_LIB": "src/*.php"}},
 "node": {"cwd": "../shop-js", "cmd": ["node", "shim.js"], "env": {"PORT": "{port}"}}}

Setting it up

parityrun init (or just parityrun) tells a PHP library by its composer.json ("type": "library") or by having no index.php and no framework. It writes:

  • the shim's settings (PARITYRUN_LIB: the autoloader and the files that declare functions, or every file of the API),
  • library=True and ready="/health" in the project,
  • the API read from the code into golden/endpoints.json (functions, public static and instance methods, the classes new can make),
  • scenarios/calls.yaml, with that API listed at its top and the calls that need no argument.

Write the calls people make there, with real arguments, then parityrun record. parityrun routes lists the API again with what the scenarios call; coverage shows the parts no scenario calls and, for PHP, the lines no call ran.

Porting it

parityrun port --to ... starts the port as an empty library beside the shim template, and PORTING.md tells the AI tool how the scenarios call it and what to fill in. examples/cart is a PHP library with JavaScript, TypeScript and Rust ports, each with its shim filled in.

Clone this wiki locally