NAME

Test::MockCommand::Recorder - emulates and records command output

SYNOPSIS

# as called by Test::MockCommand
my $recorder = Test::MockCommand::Recorder->new();
my $result_object = $recorder->handle(
    command     => 'ls -l',
    function    => 'readpipe', # or 'exec', 'system' or 'open',
    arguments   => \@_,
    caller      => [ caller() ]
);

DESCRIPTION

This class which is the default 'recorder' class for Test::MockCommand. It is automatically loaded, you don't need to add it yourself.

It carries out the brunt of the recording work, including emulating the system calls. However, it has been designed to be easy to sub-class and override, so you can make your own recorder to collect extra or different data while re-using as much of the system call emulations as you want.

CONSTRUCTOR

new()

Creates a new recorder object.

METHODS

$result = $recorder->handle(%args)

This is called by the main Test::MockCommand framework in order to handle recording and emulating a system call. It should return undef if it can't handle this particular call. It should return a result object (either Test::MockCommand::Result or something with the same methods), encapsulating the entire call. The framework passes a hashlist of arguments, these are:

command

A string with roughly the command being run. Don't use this as the command to run, rather use the function and arguments parameters to make an precise emulation.

function

A string with the function you need to emulate. This will be exec, open, readpipe or system.

arguments

An arrayref to the original arguments of the function. Be careful to use them by reference rather than copying them, for example if the first argument to open() is undef because open() should be filling it in.

caller

An arrayref containing the results of caller(), collected at the start of the emulated function. This lets you see who called open(), system(), etc.

In order to make it easy to build your own recording objects, the implementation of handle() calls out to other methods on the object to do the work of handling.

First it calls matches(%args) to see if it should record this command, or just return undef immediately.

Next, it calls pre_capture(%args) and expects to get back a result object. It puts this object in $args{result}.

It then calls record_open(), record_system(), record_readpipe() or record_exec(), based on the function being emulated. It puts the result of this call into $args{return_value}.

Finally, it calls post_capture(%args).

It returns the result object created by pre_capture().

$should_handle = $recorder->matches(%args)

This should return non-zero if the recorder can handle this command, or zero if it cannot.

$result = $recorder->pre_capture(%args)

This gets called before any matched command. It should return an object that will be used to store command results. Whatever it returns will be added to the %args hash with the key result. It's not possible to stop the capture by returning undef here, use the matches() method for that.

$return_value = $recorder->record_open(%args)

This should emulate a call to open(), but instead of letting open() create the filehandle specified by the caller, it should create a intermediary "fake" tied filehandle that passes on reads and writes to the real filehandle. If all you want to change is the code implementing this fake filehandle, override the create_tied_fh() method instead of this method.

The returned value will be added to the %args hash with the key return_value.

$new_fh = $recorder->create_tied_fh($real_fh, $result_object)

Creates a Test::MockCommand::TiedFH filehandle attached to this object.

$return_value = $recorder->record_system(%args)

This should emulate a call to system(). The returned value will be added to the %args hash with the key return_value.

$return_value = $recorder->record_readpipe(%args)

This should emulate a call to readpipe(). It should always return a scalar. If an array is wanted, the Test::MockCommand framework will split it up according to $/. The returned value will be added to the %args hash with the key return_value.

$recorder->record_exec(%args)

This should emulate a call to exec(), except it shouldn't exit Perl after running the command, as exec() would. Just return as normal - the return value is stored, but is unimportant - and the Test::MockCommand framework will exit Perl with the appropriate exit code after saving the database.

$recorder->post_capture(%args)

This gets called after emulating the command. It can add any extra data only known after running the command, for example the command's exit code or the contents of any files that the command is known to have created.