VOOZH about

URL: https://deepwiki.com/hypervel/process/6.5-fake-invoked-processes

⇱ Fake Invoked Processes | hypervel/process | DeepWiki


Loading...
Menu

Fake Invoked Processes

Purpose and Scope

This document explains the FakeInvokedProcess class, which simulates asynchronous process execution for testing purposes. When a process is started via start() instead of run(), it returns an invoked process handle that allows checking if the process is running, reading incremental output, sending signals, and waiting for completion. FakeInvokedProcess provides a fake implementation of this behavior without spawning actual system processes.

For information about synchronous fake results, see Fake Process Results. For configuring complex fake behavior, see Fake Process Descriptions. For real asynchronous execution, see Asynchronous Execution.

Sources: src/FakeInvokedProcess.php1-252


Class Overview

FakeInvokedProcess implements the InvokedProcessContract interface, providing the same API as the real InvokedProcess class. The key difference is that it simulates process behavior based on configuration from a FakeProcessDescription rather than interacting with actual system processes.


Sources: src/FakeInvokedProcess.php11-252 src/Contracts/InvokedProcess.php1-49 src/FakeProcessDescription.php1-189


Construction and Lifecycle

FakeInvokedProcess is constructed with a command string and a FakeProcessDescription that defines the process behavior. The FakeProcessDescription contains all configuration: process ID, output lines, exit code, and number of iterations the process should appear "running".

PropertyTypePurpose
commandstringThe command that was executed
processFakeProcessDescriptionConfiguration defining process behavior
receivedSignalsarray<int, int>Signals sent to the process
remainingRunIterations?intHow many more times running() returns true
outputHandler?ClosureCallback for incremental output
nextOutputIndexintPosition in standard output stream
nextErrorOutputIndexintPosition in error output stream

Sources: src/FakeInvokedProcess.php13-47


Iteration-Based Running State

The running() method simulates a process that gradually completes over multiple checks. The FakeProcessDescription.runIterations property specifies how many times running() should return true before the process is considered finished.


The implementation tracks remaining iterations internally:

  • On the first running() call, remainingRunIterations is initialized from process.runIterations
  • Each subsequent running() call decrements the counter
  • When the counter reaches 0, running() returns false and flushes remaining output
  • All other methods (id(), signal()) also trigger output handler invocation

Sources: src/FakeInvokedProcess.php82-99


Process ID and Signal Handling

The id() method returns the simulated process ID from the FakeProcessDescription. The signal() method records signals sent to the process without actually sending them to the OS.


The hasReceivedSignal() method allows tests to verify that specific signals were sent to the fake process. This is particularly useful for testing graceful shutdown logic.

Sources: src/FakeInvokedProcess.php52-77


Incremental Output Streaming

FakeInvokedProcess simulates streaming output by progressively revealing output lines configured in the FakeProcessDescription. The output array in FakeProcessDescription contains entries with type ('out' or 'err') and buffer (the line content).

Output Structure

The FakeProcessDescription.output array stores output in the order it should be emitted:

[
 ['type' => 'out', 'buffer' => "Starting process\n"],
 ['type' => 'err', 'buffer' => "Warning: deprecated\n"],
 ['type' => 'out', 'buffer' => "Processing item 1\n"],
 ['type' => 'out', 'buffer' => "Processing item 2\n"],
 ['type' => 'err', 'buffer' => "Error on item 3\n"],
 ['type' => 'out', 'buffer' => "Complete\n"]
]

Output Method Behavior

MethodReturnsBehavior
output()All standard output so farFilters for type === 'out', up to nextOutputIndex
errorOutput()All error output so farFilters for type === 'err', up to nextErrorOutputIndex
latestOutput()Next standard output lineAdvances nextOutputIndex, returns single line
latestErrorOutput()Next error output lineAdvances nextErrorOutputIndex, returns single line

Sources: src/FakeInvokedProcess.php138-213


Output Handler Integration

When an output handler callback is provided, FakeInvokedProcess invokes it progressively as output becomes available. This simulates how real processes stream output incrementally rather than returning it all at once.


The output handler is invoked automatically by:

  • running() on each call
  • id() when checking process ID
  • signal() when sending signals
  • wait() when blocking for completion

This ensures that tests checking process state also trigger output streaming, mimicking real process behavior where checking status might also read buffered output.

Sources: src/FakeInvokedProcess.php106-135


Waiting for Completion

The wait() method blocks until the process completes and returns a ProcessResult. For fake processes, this means:

  1. Setting the output handler if one is provided
  2. Exhausting all output through the handler
  3. Setting remainingRunIterations to 0
  4. Returning the final FakeProcessResult

The predictProcessResult() method allows tests to inspect what the final result will be without actually waiting for the process to complete.

Sources: src/FakeInvokedProcess.php218-241


Usage Example Flow


Sources: src/FakeInvokedProcess.php1-252


Key Implementation Details

Output Index Tracking

The class maintains two separate indices to track progress through standard output and error output independently. This allows interleaved output to be consumed correctly:

  • nextOutputIndex: Next position in output array for standard output
  • nextErrorOutputIndex: Next position in output array for error output

When retrieving output, the class iterates through the process.output array and filters by type, respecting the appropriate index boundary.

Sources: src/FakeInvokedProcess.php33-38 src/FakeInvokedProcess.php140-171

Automatic Output Handler Invocation

Nearly every method triggers invokeOutputHandlerWithNextLineOfOutput() before performing its main operation. This ensures that output is progressively streamed regardless of which method the test code calls, mimicking how real processes emit output asynchronously.

Sources: src/FakeInvokedProcess.php54 src/FakeInvokedProcess.php64 src/FakeInvokedProcess.php84

Completion Behavior

When running() returns false (because remainingRunIterations reached 0), the method exhausts all remaining output by calling invokeOutputHandlerWithNextLineOfOutput() in a loop until it returns false. This ensures tests receive all output even if they don't explicitly read it.

Sources: src/FakeInvokedProcess.php90-93


Relationship to FakeProcessDescription

FakeInvokedProcess is a thin wrapper around FakeProcessDescription that adds stateful tracking for asynchronous simulation:

AspectFakeProcessDescriptionFakeInvokedProcess
RoleConfiguration objectExecution simulator
StateImmutable after creationMutable (tracks progress)
OutputComplete output arrayProgressive output streaming
CompletionDefines final resultSimulates gradual completion
UsageBuilder pattern setupRuntime process handle

The FakeProcessDescription is created during test setup (typically by a handler registered with Factory::fake()), while the FakeInvokedProcess is created by PendingProcess::start() when faking is enabled and wraps that description.

Sources: src/FakeInvokedProcess.php44-46 src/FakeProcessDescription.php1-189


Testing Signal Handling Example

The hasReceivedSignal() method provides a way to assert that specific signals were sent during test execution:


This allows testing graceful shutdown logic without actually sending signals to real processes.

Sources: src/FakeInvokedProcess.php74-77


Summary

FakeInvokedProcess provides comprehensive simulation of asynchronous process execution by:

  • Implementing the InvokedProcessContract interface identically to InvokedProcess
  • Using iteration-based simulation for the running() state
  • Recording signals sent via signal() for test assertions
  • Progressively streaming output through indices and handlers
  • Wrapping FakeProcessDescription configuration to define behavior
  • Providing wait() that exhausts output and returns FakeProcessResult

This enables robust testing of asynchronous process handling without spawning actual system processes, while maintaining the same API as real process execution.

Sources: src/FakeInvokedProcess.php1-252 src/Contracts/InvokedProcess.php1-49 src/FakeProcessDescription.php1-189