VOOZH about

URL: https://deepwiki.com/hypervel/process/3.3-contracts

⇱ Contracts | hypervel/process | DeepWiki


Loading...
Menu

Contracts

Purpose and Scope

This document describes the two core contracts in the hypervel/process package: ProcessResult and InvokedProcess. These interfaces define stable APIs that enable the dual execution model, allowing both real system processes and fake test implementations to be used interchangeably. For information about the concrete implementations of these contracts, see Process Results. For information about how these contracts are used in asynchronous execution, see Asynchronous Execution. For information about the fake implementations, see Faking Overview.

Contract Architecture

The package defines two primary contracts that abstract process execution and results:

ContractPurposePrimary Usage
ProcessResultRepresents the outcome of a completed processReturned by synchronous run() and asynchronous wait()
InvokedProcessRepresents a running process that can be monitoredReturned by asynchronous start() for non-blocking execution

These contracts serve as the foundation for the package's dual execution model, where application code interacts with interfaces rather than concrete implementations.

Sources:

Contract Relationship Diagram


Sources:

ProcessResult Contract

The ProcessResult interface defines methods for inspecting the outcome of a completed process. All methods on this contract are read-only operations that examine the process state after execution has finished.

Method Categories


Sources:

Status Inspection Methods

MethodReturn TypeDescription
command()stringReturns the original command string that was executed
successful()boolReturns true if exit code is 0, false otherwise
failed()boolReturns true if exit code is non-zero, false otherwise
exitCode()?intReturns the process exit code, or null if process hasn't completed

The successful() and failed() methods are inverse operations - exactly one will always return true for a completed process. These provide a fluent interface for imperative status checking without requiring exception handling.

Sources:

Output Inspection Methods

MethodReturn TypeDescription
output()stringReturns the complete standard output (STDOUT) as a string
errorOutput()stringReturns the complete error output (STDERR) as a string
seeInOutput(string $output)boolChecks if the given string exists anywhere in STDOUT
seeInErrorOutput(string $output)boolChecks if the given string exists anywhere in STDERR

The seeInOutput() and seeInErrorOutput() methods provide convenient assertion-style checks for testing output content without requiring string manipulation or regular expressions for simple substring matching.

Sources:

Exception Methods

MethodSignatureDescription
throw(?callable $callback = null)staticThrows ProcessFailedException if process failed
throwIf(bool $condition, ?callable $callback = null)staticThrows ProcessFailedException if process failed AND condition is true

Both methods accept an optional callback that receives the ProcessResult instance and returns a string to be used as the exception message. If no callback is provided, a default message is generated. These methods return static to enable fluent chaining when the process succeeds.

Sources:

InvokedProcess Contract

The InvokedProcess interface defines methods for interacting with a running process. Unlike ProcessResult, which represents a completed process, InvokedProcess provides real-time monitoring and control of an active process.

Method Categories


Sources:

Process Control Methods

MethodReturn TypeDescription
id()?intReturns the OS process ID if running, null if process has terminated
signal(int $signal)staticSends a Unix signal to the process (e.g., SIGTERM, SIGKILL)
running()boolReturns true if process is still executing, false if completed

The signal() method returns static to enable fluent chaining. Signal constants are typically from the standard PHP SIGTERM, SIGKILL, etc. constants.

Sources:

Output Streaming Methods

MethodReturn TypeDescription
output()stringReturns all STDOUT data captured since process started
errorOutput()stringReturns all STDERR data captured since process started
latestOutput()stringReturns STDOUT data captured since last call to this method
latestErrorOutput()stringReturns STDERR data captured since last call to this method

The distinction between output() and latestOutput() enables incremental output processing. The "latest" methods maintain internal state tracking what has been retrieved, allowing polling loops to process only new output since the last check.

Sources:

Lifecycle Management


The wait(?callable $output = null) method blocks until the process completes and returns a ProcessResult instance. The optional $output callback is invoked periodically with output data as it becomes available, enabling real-time output streaming without requiring manual polling.

Sources:

Dual Execution Model

The contract architecture enables the package's dual execution model where application code remains unchanged whether executing real processes or using fakes in tests.

Implementation Matrix

ContractReal ImplementationFake ImplementationCreation Source
ProcessResultHypervel\Process\ProcessResultHypervel\Process\FakeProcessResultPendingProcess::run() or InvokedProcess::wait()
InvokedProcessHypervel\Process\InvokedProcessHypervel\Process\FakeInvokedProcessPendingProcess::start()

Sources:

Execution Flow with Contracts


The Factory class determines which implementation to return based on its recording state. When Factory::fake() has been called, all contract implementations are swapped to their fake counterparts. Application code depends only on the contracts, never on concrete classes.

Sources:

Contract Usage Patterns

Pattern 1: Imperative Status Checking


This pattern uses the boolean methods on ProcessResult to check status without exception handling.

Sources:

Pattern 2: Exception-Based Error Handling


This pattern uses the throw() method to raise exceptions on failure, leveraging PHP's exception propagation.

Sources:

Pattern 3: Asynchronous Monitoring


This pattern uses InvokedProcess to monitor a running process and retrieve incremental output.

Sources:

Pattern 4: Signal Management


This pattern uses signal() to send Unix signals for process control.

Sources:

Contract Stability Guarantees

The contracts provide the following stability guarantees:

  1. Method Signatures: All method signatures in both contracts are considered stable API. Breaking changes will follow semantic versioning.

  2. Return Types: Return types are strictly typed and will not change within major versions.

  3. Implementation Substitution: Any code written against the contracts will work identically whether using real or fake implementations.

  4. Exception Consistency: Both real and fake implementations throw the same exception types from the same methods.

These guarantees enable confident usage in both application and test code, knowing that the interface will remain stable across the dual execution model.

Sources: