This is Info file pm.info, produced by Makeinfo version 1.68 from the input file bigpm.texi.  File: pm.info, Node: Term/ReadPassword, Next: Term/Size, Prev: Term/ReadLine/Gnu, Up: Module List Asking the user for a password ****************************** NAME ==== Term::ReadPassword - Asking the user for a password SYNOPSIS ======== use Term::ReadPassword; while (1) { my $password = read_password('password: '); redo unless defined $password; if ($password eq 'flubber') { print "Access granted.\n"; last; } else { print "Access denied.\n"; redo; } } DESCRIPTION =========== This module lets you ask the user for a password in the traditional way, from the keyboard, without echoing. This is not intended for use over the web; user authentication over the web is another matter entirely. Also, this module should generally be used in conjunction with Perl's crypt() function, sold separately. The read_password function prompts for input, reads a line of text from the keyboard, then returns that line to the caller. The line of text doesn't include the newline character, so there's no need to use chomp. While the user is entering the text, a few special characters are processed. The character delete (or the character backspace) will back up one character, removing the last character in the input buffer (if any). The character CR (or the character LF) will signal the end of input, causing the accumulated input buffer to be returned. And, optionally, the character Control-C may be used to terminate the input operation. (See details below.) All other characters, even ones which would normally have special purposes, will be added to the input buffer. It is not recommended, though, that you use the as-yet-unspecified control characters in your passwords, as those characters may become meaningful in a future version of this module. Applications which allow the user to set their own passwords may wish to enforce this rule, perhaps with code something like this: { # Naked block for scoping and redo my $new_pw = read_password("Enter your new password: "); if ($new_pw =~ /([^\x20-\x7E])/) { my $bad = unpack "H*", $1; print "Your password may not contain the "; print "character with hex code $bad.\n"; redo; } elsif (length($new_pw) < 5) { print "Your password must be longer than that!\n"; redo; } elsif ($new_pw ne read_password("Enter it again: ")) { print "Passwords don't match.\n"; redo; } else { &change_password($new_pw); print "Your password is now changed.\n"; } } The second parameter to read_password is the optional idle_timeout value. If it is a non-zero number and there is no keyboard input for that many seconds, the input operation will terminate. Notice that this is not an overall time limit, as the timer is restarted with each new character. The third parameter will optionally allow the input operation to be terminated by the user with Control-C. If this is not supplied, or is false, a typed Control-C will be entered into the input buffer just as any other character. In that case, there is no way from the keyboard to terminate the program while it is waiting for input. (That is to say, the normal ability to generate signals from the keyboard is suspended during the call to read_password.) If the input operation terminates early (either because the idle_timeout was exceeded, or because a Control-C was enabled and typed), the return value will be undef. In either case, there is no way provided to discover what (if anything) was typed before the early termination, or why the input operation was terminated. So as to discourage users from typing their passwords anywhere except at the prompt, any input which has been "typed ahead" before the prompt appears will be discarded. And whether the input operation terminates normally or not, a newline character will be printed, so that the cursor will not remain on the line after the prompt. SECURITY ======== You would think that a module dealing with passwords would be full of security features. You'd think that, but you'd be wrong. For example, perl provides no way to erase a piece of data from memory. (It's easy to erase it so that it can't be accessed from perl, but that's not the same thing as expunging it from the actual memory.) If you've entered a password, even if the variable that contained that password has been erased, it may be possible for someone to find that password, in plaintext, in a core dump. And that's just one potential security hole. In short, if serious security is an issue, don't use this module. AUTHOR ====== Tom Phoenix SEE ALSO ======== Term::ReadLine, `crypt', *Note Perlfunc: (perl.info)perlfunc,, and your system's manpages for the low-level I/O operations used here.  File: pm.info, Node: Term/Size, Next: Term/TUI, Prev: Term/ReadPassword, Up: Module List Perl extension for retrieving terminal size ******************************************* NAME ==== Term::Size - Perl extension for retrieving terminal size SYNOPSIS ======== use Term::Size; ($columns, $rows) = Term::Size::chars *STDOUT{IO}; ($x, $y) = Term::Size::pixels; DESCRIPTION =========== *Term::Size* is a Perl module which provides a straightforward way to retrieve the terminal size. Both functions take an optional filehandle argument, which defaults to `*STDIN{IO}'. They both return a list of two values, which are the current width and height, respectively, of the terminal associated with the specified filehandle. `Term::Size::chars' returns the size in units of characters, whereas `Term::Size::pixels' uses units of pixels. In a scalar context, both functions return the first element of the list, that is, the terminal width. The functions may be imported. If you need to pass a filehandle to either of the `Term::Size' functions, beware that the `*STDOUT{IO}' syntax is only supported in Perl 5.004 and later. If you have an earlier version of Perl, or are interested in backwards compatibility, use `*STDOUT' instead. EXAMPLES ======== 1. Refuse to run in a too narrow window. use Term::Size; die "Need 80 column screen" if Term::Size::chars *STDOUT{IO} < 80; 2. Track window size changes. use Term::Size 'chars'; my $changed = 1; while (1) { local $SIG{'WINCH'} = sub { $changed = 1 }; if ($changed) { ($cols, $rows) = chars; # Redraw, or whatever. $changed = 0; } } RETURN VALUES ============= Both functions return undef if there is an error. If the terminal size information is not available, the functions will normally return `(0, 0)', but this depends on your system. On character only terminals, `pixels' will normally return `(0, 0)'. BUGS ==== It only works on Unix systems. AUTHOR ====== Tim Goodwin, , 1997-04-23.  File: pm.info, Node: Term/TUI, Next: Test, Prev: Term/Size, Up: Module List simple tool for building text-based user interfaces *************************************************** NAME ==== Term::TUI - simple tool for building text-based user interfaces SYNOPSIS ======== If TUI_Run is the only routine being used: use Term::TUI; $flag=&TUI_Run($command,\%desc); $version=&Term::TUI::TUI_Version; If other TUI subroutines are used: use Term::TUI qw(:all); $flag=&TUI_Run($command,\%desc); &TUI_Out($message); $flag=&TUI_Script(\%desc,$script,$sep); DESCRIPTION =========== Many times, I've wanted to quickly write a nice text-based user interface around a set of perl routines only to end up writing the full (though simple) parser and interface to make it nice enough, and friendly enough, to be usable. This module creates a simple but powerful text based user interface around perl routines, adding such features as command line history, command line editing, and online help (command completion will also be implemented), while hiding all details of the interface from the programmer. The interface is described in a simple hash which is passed to the TUI_Run command. This routine exits only when the user has exited the program (returning a flag signalling any special exit conditions). ROUTINES ======== TUI_Run use Term::TUI; $flag=&TUI_Run($command,\%desc); The TUI_Run command is used to run the interface. It prompts the user for commands and executes them (based on description of passed in as %desc) until the user exits. The return flag is 0 unless the user exited with the Abort command when it is 1. TUI_Script use Term::TUI qw(:all); $flag=&TUI_Script(\%desc,$script [,$sep]); This allows you to pass in commands in a "script" instead of an interactive session. The script is a series of commands separated by a semicolon (or the string included in $sep). TUI_Version use Term::TUI qw(:all); $vers=&TUI_Version; Returns the version of the module. TUI_Out use Term::TUI qw(:all); &TUI_Out($mess); This is used in the routines given in the description hash to send a message to STDOUT. INTERFACE DESCRIPTION ===================== The interface allows you to describe multiple "modes" organized in a simple tree-like hierarchy (or modes, submodes, subsubmodes, etc.), each of which has it's own set of commands specific to that mode. I've modelled it after a unix filesystem with directories being "modes" and executables being equivalent to commands. So, you might want to model the following tree: / +--------------------+ math string | | +-----+-----+ +------+ hex add* mult* len* substr* | +-----+ add* mult* Here the "executables" are marked with asterixes(*). So in math mode, you could type "add" or "mult" to add a list of numbers together or multiply them together. It also has a submode "hex" where you can do that in hexidecimal. I find this type of interface very conveniant in many cases, but a nuisance to write. This module handles this trivially. The above interface can be written with the following 2 perl commands: %modes = (".HELP" => "This is the main help.\nNot a lot of info here.", "math" => {".HELP" => "A simple calculator. Currently it can\n" . "only add and multiply in hex or decimal.", "add" => [ "Add numbers together." , Add,0 ], "mult" => [ "Multiply numbers together.", Mult,0 ], "hex" => {".HELP" => "Math in hex.", "add" => [ "Add hex numbers together.", Add,1 ], "mult" => [ "Multiply hex numbers together.", Mult,1 ] } }, "string" => {".HELP" => "String operations", "subs" => [ "Take STRING,POS,LEN and returns substring.", Substring ], "len" => [ "Returns the length of a string.", Length ] } ); $flag=&TUI_Run("sample",\%modes); print "*** ABORT ***\n" if ($flag); You also have to write an Add, Mult, Substring, and Length subroutine of course, but once that's done, you end up with a rather nice text based user interface. The following are excerpts from a session using the sample interface defined above: Changing modes is trivial. Just type in the new mode using a syntax similar to the unix filesystem: sample> string sample:string> /math/hex sample:math/hex> .. sample:math> hex sample:math/hex> / sample> When in a given mode, you can just type commands relevant to that mode: sample:string> subs barnyard 1 3 Substring = arn sample:string> len barnyard Length = 8 You can also explicitely type in the mode for a command. In this situation, commands can be typed as MODE/CMD ARGS or MODE CMD ARGS equivalently: sample:string> /math/hex/add 4 6 1 Total = b sample:string> /math mult 4 6 2 Total = 48 There are several built-in commands including "..", "/", "help", "abort", "exit", and "quit". The last two ("exit" and "quit") are equivalent and mean to exit and return 0. "abort" exits with a value of 1. There is also online help: sample> help This is the main help. Not a lot of info here. Additional help: Modes: math string Cmds : .. / abort exit help quit sample> help /string String operations Additional help: Cmds : .. / abort exit help quit len subs sample> math sample:math> help A simple calculator. Currently it can only add and multiply in hex or decimal. Additional help: Modes: hex Cmds : .. / abort exit help quit add mult sample:math> help add Add numbers together. sample:math> help /string len Returns the length of a string. sample:math> help /string/subs Take STRING,POS,LEN and returns a substring. Currently, Term::TUI does not have much in the way of bells and whistles, and I doubt it ever will. It's not designed for a full-blown, feature-rich user interface. It's mainly intended for simple control or config tools (similar to lpc for example) used primarily by the sysadmin type people (who else is interested in a text-based interface after all :-). There is also a non-interactive form which allows the same interface to be called in scripts. &TUI_Script(\%modes,"/math add 3 5; string; subs barnyard 1 3"); returns Total = 8 Substring = arn TUI DOES use one of the Term::ReadLine modules for the interactive session, so if you have Term::ReadLine::GNU or Term::ReadLine::Perl installed, you can use things like command history and command line editing. KNOWN PROBLEMS ============== None known at this point. AUTHOR ====== Sullivan Beck (sbeck@cise.ufl.edu)  File: pm.info, Node: Test, Next: Test/Cmd, Prev: Term/TUI, Up: Module List provides a simple framework for writing test scripts **************************************************** NAME ==== Test - provides a simple framework for writing test scripts SYNOPSIS ======== use strict; use Test; # use a BEGIN block so we print our plan before MyModule is loaded BEGIN { plan tests => 14, todo => [3,4] } # load your module... use MyModule; ok(0); # failure ok(1); # success ok(0); # ok, expected failure (see todo list, above) ok(1); # surprise success! ok(0,1); # failure: '0' ne '1' ok('broke','fixed'); # failure: 'broke' ne 'fixed' ok('fixed','fixed'); # success: 'fixed' eq 'fixed' ok('fixed',qr/x/); # success: 'fixed' =~ qr/x/ ok(sub { 1+1 }, 2); # success: '2' eq '2' ok(sub { 1+1 }, 3); # failure: '2' ne '3' ok(0, int(rand(2)); # (just kidding :-) my @list = (0,0); ok @list, 3, "\@list=".join(',',@list); #extra diagnostics ok 'segmentation fault', '/(?i)success/'; #regex match skip($feature_is_missing, ...); #do platform specific test DESCRIPTION =========== *Note Test/Harness: Test/Harness, expects to see particular output when it executes tests. This module aims to make writing proper test scripts just a little bit easier (and less error prone :-). TEST TYPES ========== * NORMAL TESTS These tests are expected to succeed. If they don't something's screwed up! * SKIPPED TESTS Skip is for tests that might or might not be possible to run depending on the availability of platform specific features. The first argument should evaluate to true (think "yes, please skip") if the required feature is not available. After the first argument, skip works exactly the same way as do normal tests. * TODO TESTS TODO tests are designed for maintaining an *executable TODO list*. These tests are expected NOT to succeed. If a TODO test does succeed, the feature in question should not be on the TODO list, now should it? Packages should NOT be released with succeeding TODO tests. As soon as a TODO test starts working, it should be promoted to a normal test and the newly working feature should be documented in the release notes or change log. RETURN VALUE ============ Both ok and skip return true if their test succeeds and false otherwise in a scalar context. ONFAIL ====== BEGIN { plan test => 4, onfail => sub { warn "CALL 911!" } } While test failures should be enough, extra diagnostics can be triggered at the end of a test run. `onfail' is passed an array ref of hash refs that describe each test failure. Each hash will contain at least the following fields: package, `repetition', and result. (The file, line, and test number are not included because their correspondence to a particular test is tenuous.) If the test had an expected value or a diagnostic string, these will also be included. The optional `onfail' hook might be used simply to print out the version of your package and/or how to report problems. It might also be used to generate extremely sophisticated diagnostics for a particularly bizarre test failure. However it's not a panacea. Core dumps or other unrecoverable errors prevent the `onfail' hook from running. (It is run inside an END block.) Besides, `onfail' is probably over-kill in most cases. (Your test code should be simpler than the code it is testing, yes?) SEE ALSO ======== *Note Test/Harness: Test/Harness, and, perhaps, test coverage analysis tools. AUTHOR ====== Copyright (c) 1998-1999 Joshua Nathaniel Pritikin. All rights reserved. This package is free software and is provided "as is" without express or implied warranty. It may be used, redistributed and/or modified under the terms of the Perl Artistic License (see http://www.perl.com/perl/misc/Artistic.html)  File: pm.info, Node: Test/Cmd, Next: Test/Harness, Prev: Test, Up: Module List Perl module for portable testing of commands and scripts ******************************************************** NAME ==== Test::Cmd - Perl module for portable testing of commands and scripts SYNOPSIS ======== use Test::Cmd; $test = Test::Cmd->new(prog => 'program_or_script_to_test', interpreter => 'script_interpreter', string => 'identifier_string', workdir => '', subdir => 'dir', match_sub => $code_ref, verbose => 1); $test->verbose(1); $test->prog('program_or_script_to_test'); $test->basename(@suffixlist); $test->interpreter('script_interpreter'); $test->string('identifier string'); $test->workdir('prefix'); $test->workpath('subdir', 'file'); $test->subdir('subdir', ...); $test->subdir(['sub', 'dir'], ...); $test->write('file', <<'EOF'); contents of file EOF $test->write(['subdir', 'file'], <<'EOF'); contents of file EOF $test->read(\$contents, 'file'); $test->read(\@lines, 'file'); $test->read(\$contents, ['subdir', 'file']); $test->read(\@lines, ['subdir', 'file']); $test->writable('dir', rwflag); $test->preserve(condition, ...); $test->cleanup(condition); $test->run(prog => 'program_or_script_to_test', interpreter => 'script_interpreter', chdir => 'dir', args => 'arguments', stdin => <<'EOF'); input to program EOF $test->pass(condition); $test->pass(condition, funcref); $test->fail(condition); $test->fail(condition, funcref); $test->fail(condition, funcref, caller); $test->no_result(condition); $test->no_result(condition, funcref); $test->no_result(condition, funcref, caller); $test->stdout; $test->stdout(run_number); $test->stderr; $test->stderr(run_number); $test->diff(); $test->match($lines, $matches); $test->match_exact(\@lines, \@matches); $test->match_exact($lines, $matches); $test->match_regex(\@lines, \@regexes); $test->match_regex($lines, $regexes); sub func { my ($self, $lines, $matches) = @_; # code to match $line and $matches } $test->match_sub(\&func); $test->match_sub(sub { code to match $_[1] and $[2] }); $test->here; DESCRIPTION =========== The `Test::Cmd' module provides a framework for portable automated testing of executable commands and scripts (in any language, not just Perl), especially commands and scripts that require file system interaction. In addition to running tests and evaluating conditions, the `Test::Cmd' module manages and cleans up one or more temporary workspace directories, and provides methods for creating files and directories in those workspace directories from in-line data (that is, here-documents), allowing tests to be completely self-contained. The `Test::Cmd' module inherits File::Spec methods (`file_name_is_absolute()', `catfile()', etc.) to support writing tests portably across a variety of operating and file systems. A `Test::Cmd' environment object is created via the usual invocation: $test = Test::Cmd->new(); Arguments to the `Test::Cmd::new' method are keyword-value pairs that may be used to initialize the object, typically by invoking the same-named method as the keyword. No `Test::Cmd' methods (including the new() method) exit, die or throw any other sorts of exceptions (but they all do return useful error indications). Exceptions should be handled by the test itself or a subclass specific to the program under test. The `Test::Cmd' module may be used in conjunction with the Test module to report test results in a format suitable for the Test::Harness module. A typical use would be to call the `Test::Cmd' methods to prepare and execute the test, and call the `ok()' method exported by the Test module to test the conditions: use Test; use Test::Cmd; BEGIN { $| = 1; plan => 3 } $test = Test::Cmd->new(prog => 'test_program', workdir => ''); ok($test); $wrote_file = $test->write('input_file', <<'EOF'); This is input to test_program, which we expect to process this and exit successfully (status 0). EOF ok($wrote_file); $test->run(args => 'input_file'); ok($? == 0); Alternatively, the `Test::Cmd' module provides `pass()', `fail()', and `no_result()' methods that report test results for use with the Aegis change management system. These methods terminate the test immediately, reporting PASSED, FAILED, or NO RESULT respectively, and exiting with status 0 (success), 1 or 2 respectively. This allows for a distinction between an actual failed test and a test that could not be properly evaluated because of an external condition (such as a full file system or incorrect permissions): use Test::Cmd; $test = Test::Cmd->new(prog => 'test_program', workdir => ''); Test::Cmd->no_result(! $test); $wrote_file = $test->write('input_file', <<'EOF'); This is input to test_program, which we expect to process this and exit successfully (status 0). EOF $test->no_result(! $wrote_file); $test->run(args => 'input_file'); $test->fail($? != 0); $test->pass; It is not a good idea to intermix the two reporting models. If you use the Test module and its ok method, do not use the `Test::Cmd' pass, fail or `no_result' methods, and vice versa. METHODS ======= Methods supported by the `Test::Cmd' module include: new Create a new `Test::Cmd' environment. Arguments with which to initialize the environment are passed in as keyword-value pairs. Fails if a specified temporary working directory or subdirectory cannot be created. Does NOT die or exit on failure, but returns FALSE if the test environment object cannot be created. verbose Sets the verbose level for the environment object to the specified value. prog Specifies the executable program or script to be tested. Returns the absolute path name of the current program or script. `basename' Returns the basename of the current program or script. Any specified arguments are a list of file suffixes that may be stripped from the basename. `interpreter' Specifies the program to be used to interpret prog as a script. Returns the current value of `interpreter'. string Specifies an identifier string for the functionality being tested to be printed on failure or no result. `workdir' When an argument is specified, creates a temporary working directory with the specified name. If the argument is a NULL string ("), the directory is named `testcmd' by default, followed by the unique ID of the executing process. Returns the absolute pathname to the temporary working directory, or FALSE if the directory could not be created. `workpath' Returns the absolute path name to a subdirectory or file under the current temporary working directory by concatenating the temporary working directory name with the specified arguments. `subdir' Creates new subdirectories under the temporary working dir, one for each argument. An argument may be an array reference, in which case the array elements are concatenated together using the `File::Spec-&'catfile> method. Subdirectories multiple levels deep must be created via a separate argument for each level: $test->subdir('sub', ['sub', 'dir'], [qw(sub dir ectory)]); Returns the number of subdirectories actually created. write Writes the specified text (second argument) to the specified file name (first argument). The file name may be an array reference, in which case all the array elements except the last are subdirectory names to be concatenated together. The file is created under the temporary working directory. Any subdirectories in the path must already exist. read Reads the contents of the specified file name (second argument) into the scalar or array referred to by the first argument. The file name may be an array reference, in which case all the array elements except the last are subdirectory names to be concatenated together. The file is assumed to be under the temporary working directory unless it is an absolute path name. Returns TRUE on successfully opening and reading the file, FALSE otherwise. writable Makes the specified directory tree writable (`rwflag' == TRUE) or not writable (`rwflag' == FALSE). preserve Arranges for the temporary working directories for the specified `Test::Cmd' environment to be preserved for one or more conditions. If no conditions are specified, arranges for the temporary working directories to be preserved for all conditions. cleanup Removes any temporary working directories for the specified `Test::Cmd' environment. If the environment variable `PRESERVE' was set when the `Test::Cmd' module was loaded, temporary working directories are not removed. If any of the environment variables `PRESERVE_PASS', `PRESERVE_FAIL', or `PRESERVE_NO_RESULT' were set when the `Test::Cmd' module was loaded, then temporary working directories are not removed if the test passed, failed, or had no result, respectively. Temporary working directories are also preserved for conditions specified via the preserve method. Typically, this method is not called directly, but is used when the script exits to clean up temporary working directories as appropriate for the exit status. run Runs a test of the program or script for the test environment. Standard output and error output are saved for future retrieval via the stdout and stderr methods. Arguments are supplied as keyword-value pairs: args Specifies the command-line arguments to be supplied to the program or script under test for this run: $test->run(args => 'arg1 arg2'); chdir Changes directory to the path specified as the value argument: $test->run(chdir => 'xyzzy'); If the specified path is not an absolute path name (begins with '/' on Unix systems), then the subdirectory is relative to the temporary working directory for the environment (`$test-&'workdir>). Note that, by default, the `Test::Cmd' module does NOT chdir to the temporary working directory, so to execute the test under the temporary working directory, you must specify an explicit chdir to the current directory: $test->run(chdir => '.'); # Unix-specific $test->run(chdir => $test->curdir); # portable `interpreter' Specifies the program to be used to interpret prog as a script, for this run only. This does not change the `$test-&'interpreter> value of the test environment. prog Specifies the executable program or script to be run, for this run only. This does not change the `$test-&'prog> value of the test environment. stdin Pipes the specified value (string or array ref) to the program or script under test for this run: $test->run(stdin => <<_EOF_); input to the program under test _EOF_ Returns the exit status of the program or script. pass Exits the test successfully. Reports "PASSED" on the error output and exits with a status of 0. If a condition is supplied, only exits the test if the condition evaluates TRUE. If a function reference is supplied, executes the function before reporting and exiting. fail Exits the test unsuccessfully. Reports "FAILED test of {string} at line {line} of {file}." on the error output and exits with a status of 1. If a condition is supplied, only exits the test if the condition evaluates TRUE. If a function reference is supplied, executes the function before reporting and exiting. If a caller level is supplied, prints a simple calling trace N levels deep as part of reporting the failure. `no_result' Exits the test with an indeterminate result (the test could not be performed due to external conditions such as, for example, a full file system). Reports "NO RESULT for test of {string} at line {line} of {file}." on the error output and exits with a status of 2. If a condition is supplied, only exits the test if the condition evaluates TRUE. If a function reference is supplied, executes the function before reporting and exiting. If a caller level is supplied, prints a simple calling trace N levels deep as part of reporting the failure. stdout Returns the standard output from the specified run number. If there is no specified run number, then returns the standard output of the last run. Returns the standard output as either a scalar or an array of output lines, as appropriate for the calling context. Returns undef if there has been no test run. stderr Returns the error output from the specified run number. If there is no specified run number, then returns the error output of the last run. Returns the error output as either a scalar or an array of output lines, as apporpriate for the calling context. Returns undef if there has been no test run. diff Not Yet Implemented. match Matches one or more input lines against an equal number of expected lines using the currently-registered line-matching function. The default line-matching function is the `match_regex' method, which means that the default is to match lines against regular expressions. `match_exact' Compares two arrays of lines for exact matches. The arguments are passed in as either scalars, in which case each is split on newline boundaries, or as array references. An unequal number of lines in the two arrays fails immediately and returns FALSE before any comparisons are performed. Returns TRUE if each line matched its corresponding line in the other array, FALSE otherwise. `match_regex' Matches one or more input lines against an equal number of regular expressions. The arguments are passed in as either scalars, in which case each is split on newline boundaries, or as array references. Trailing newlines are stripped from each line and regular expression. An unequal number of lines and regular expressions fails immediately and returns FALSE before any comparisons are performed. Comparison is performed for each entire line, that is, with each regular expression anchored at both the start of line (^) and end of line ($). Returns TRUE if each line matched each regular expression, FALSE otherwise. `match_sub' Registers the specified code reference as the line-matching function to be called by the match method. This can be a user-supplied subroutine, or the `match_exact' or `match_regex' methods supplied by the `Test::Cmd' module: $test->match_sub(\&Test::Cmd::match_exact); $test->match_sub(\&Test::Cmd::match_regex); The `match_exact' and `match_regex' subroutine names are exportable from the `Test::Cmd' module, and may be specified at object initialization: use Test::Cmd qw(match_exact match_regex); $test_exact = Test::Cmd->new(match_sub => \&match_exact); $test_regex = Test::Cmd->new(match_sub => \&match_regex); `here' Returns the absolute path name of the current working directory. (This is essentially the same as the `Cwd::cwd' method, except that the `Test::Cmd::here' method preserves the directory separators exactly as returned by the underlying operating-system-dependent method. The `Cwd::cwd' method canonicalizes all directory separators to '/', which makes for consistent path name representations within Perl, but may mess up another program or script to which you try to pass the path name.) ENVIRONMENT =========== Several environment variables affect the default values in a newly created `Test::Cmd' environment object. These environment variables must be set when the module is loaded, not when the object is created. `PRESERVE' If set to a true value, all temporary working directories will be preserved on exit, regardless of success or failure of the test. The full path names of all temporary working directories will be reported on error output. `PRESERVE_FAIL' If set to a true value, all temporary working directories will be preserved on exit from a failed test. The full path names of all temporary working directories will be reported on error output. `PRESERVE_NO_RESULT' If set to a true value, all temporary working directories will be preserved on exit from a test for which there is no result. The full path names of all temporary working directories will be reported on error output. `PRESERVE_PASS' If set to a true value, all temporary working directories will be preserved on exit from a successful test. The full path names of all temporary working directories will be reported on error output. VERBOSE When set to a true value, enables verbose reporting of various internal things (path names, exact command line being executed, etc.). PORTABLE TESTS ============== Although the `Test::Cmd' module is intended to make it easier to write portable tests for portable utilities that interact with file systems, it is still very easy to write non-portable tests if you're not careful. The best and most comprehensive set of portability guidelines is the standard "Writing portable Perl" document at: http://www.perl.com/pub/doc/manual/html/pod/perlport.html To reiterate one important point from the "WpP" document: Not all Perl programs have to be portable. If the program or script you're testing is UNIX-specific, you can (and should) use the `Test::Cmd' module to write UNIX-specific tests. That having been said, here are some hints that may help keep your tests portable, if that's a requirement. Use the `Test::Cmd-&'here> method for current directory path. The normal Perl way to fetch the current working directory is to use the `Cwd::cwd' method. Unfortunately, the `Cwd::cwd' method canonicalizes the path name it returns, changing the native directory separators into the forward slashes favored by Perl and UNIX. For most Perl scripts, this makes a great deal of sense and keeps code uncluttered. Passing in a file name that has had its directory separators altered, however, may confuse the command or script under test, or make it difficult to compare output from the command or script with an expected result. The `Test::Cmd::here' method returns the absolute path name of the current working directory, like `Cwd::cwd', but does not manipulate the returned path in any way. Use File::Spec methods for manipulating path names. The File::Spec module provides a system-independent interface for manipulating path names. Because the `Test::Cmd' class is a sub-class of the File::Spec class, you can use these methods directly as follows: if (! Test::Cmd->file_name_is_absolute($prog)) { my $prog = Test::Cmd->catfile(Test::Cmd->here, $prog); } For details about the available methods and their use, see the documentation for the File::Spec module and its sub-modules, especially the File::Spec::Unix modules. Use Config for file-name suffixes, where possible. The standard Config module provides values that reflect the file-name suffixes on the system for which the Perl executable was built. This provides convenient portability for situations where a file name may have different extensions on different systems: $foo_exe = "foo$Config{_exe}"; ok(-f $foo_exe); (Unfortunately, there is no existing `$Config' value that specifies the suffix for a directly-executable Perl script.) Avoid generating executable programs or scripts. How to make a file or script executable varies widely from system to system, some systems using file name extensions to indicate executability, others using a file permission bit. The differences are complicated to accomodate in a portable test script. The easiest way to deal with this complexity is to avoid it if you can. If your test somehow requires executing a script that you generate from the test itself, the best way is to generate the script in Perl and then explicitly feed it to the Perl executable on the local system. To be maximally portable, use the $^X variable instead of hard-coding "perl" into the string you execute: $line = "This is output from the generated perl script."; $test->write('script', <write('script', <workdir); chmod(0755, 'script'); # POSIX-SPECIFIC $output = `script`; ok($output eq "$line\n"); Addtional hints on writing portable tests are welcome. SEE ALSO ======== perl(1), File::Find(3), File::Spec(3), Test(3), Test::Harness(3). A rudimentary page for the Test::Cmd module is available at: http://www.baldmt.com/Test-Cmd/ AUTHORS ======= Steven Knight, knight@baldmt.com COPYRIGHT ========= Copyright 1999-2000 Steven Knight. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. ACKNOWLEDGEMENTS ================ Thanks to Greg Spencer for the inspiration to create this package and the initial draft of its implementation as a specific testing package for the Cons software construction utility. Information about Cons is available at: http://www.dsmit.com/cons/ The general idea of managing temporary working directories in this way, as well as the test reporting of the pass, fail and `no_result' methods, come from the testing framework invented by Peter Miller for his Aegis project change supervisor. Aegis is an excellent bit of work which integrates creation and execution of regression tests into the software development process. Information about Aegis is available at: http://www.tip.net.au/~millerp/aegis.html  File: pm.info, Node: Test/Harness, Next: Test/Helper, Prev: Test/Cmd, Up: Module List run perl standard test scripts with statistics ********************************************** NAME ==== Test::Harness - run perl standard test scripts with statistics SYNOPSIS ======== use Test::Harness; runtests(@tests); DESCRIPTION =========== (By using the *Note Test: Test, module, you can write test scripts without knowing the exact output this module expects. However, if you need to know the specifics, read on!) Perl test scripts print to standard output `"ok N"' for each single test, where N is an increasing sequence of integers. The first line output by a standard test script is `"1..M"' with M being the number of tests that should be run within the test script. Test::Harness::runtests(@tests) runs all the testscripts named as arguments and checks standard output for the expected `"ok N"' strings. After all tests have been performed, runtests() prints some performance statistics that are computed by the Benchmark module. The test script output ---------------------- Any output from the testscript to standard error is ignored and bypassed, thus will be seen by the user. Lines written to standard output containing `/^(not\s+)?ok\b/' are interpreted as feedback for runtests(). All other lines are discarded. It is tolerated if the test numbers after ok are omitted. In this case Test::Harness maintains temporarily its own counter until the script supplies test numbers again. So the following test script print <> 8' and $? are printed in a message similar to the above. `Failed 1 test, %.2f%% okay. %s' `Failed %d/%d tests, %.2f%% okay. %s' If not all tests were successful, the script dies with one of the above messages. ENVIRONMENT =========== Setting `HARNESS_IGNORE_EXITCODE' makes harness ignore the exit status of child processes. Setting `HARNESS_NOTTY' to a true value forces it to behave as though STDOUT were not a console. You may need to set this if you don't want harness to output more frequent progress messages using carriage returns. Some consoles may not handle carriage returns properly (which results in a somewhat messy output). Setting `HARNESS_COMPILE_TEST' to a true value will make harness attempt to compile the test using perlcc before running it. If `HARNESS_FILELEAK_IN_DIR' is set to the name of a directory, harness will check after each test whether new files appeared in that directory, and report them as LEAKED FILES: scr.tmp 0 my.db If relative, directory name is with respect to the current directory at the moment runtests() was called. Putting absolute path into `HARNESS_FILELEAK_IN_DIR' may give more predicatable results. The value of `HARNESS_PERL_SWITCHES' will be prepended to the switches used to invoke perl on each test. For example, setting `HARNESS_PERL_SWITCHES' to "-W" will run all tests with all warnings enabled. Harness sets `HARNESS_ACTIVE' before executing the individual tests. This allows the tests to determine if they are being executed through the harness or by any other means. SEE ALSO ======== *Note Test: Test, for writing test scripts and also *Note Benchmark: Benchmark, for the underlying timing routines. AUTHORS ======= Either Tim Bunce or Andreas Koenig, we don't know. What we know for sure is, that it was inspired by Larry Wall's TEST script that came with perl distributions for ages. Numerous anonymous contributors exist. Current maintainer is Andreas Koenig. BUGS ==== Test::Harness uses $^X to determine the perl binary to run the tests with. Test scripts running via the shebang (#!) line may not be portable because $^X is not consistent for shebang scripts across platforms. This is no problem when Test::Harness is run with an absolute path to the perl binary or when $^X can be found in the path.  File: pm.info, Node: Test/Helper, Next: Test/Unit, Prev: Test/Harness, Up: Module List easy creation of test scripts ***************************** NAME ==== *Test::Helper* - easy creation of test scripts SYNOPSIS ======== use Test::Helper; test { comm 'Doing first part of test'; ok $variable==$correct_value; ok not runs {this_should_die()}; }; DESCRIPTION =========== Enclose the body of your test script within a test block. Within that block, run individual tests with the ok function, which should be passed a scalar that you desire to be true; this will print "ok number" or "not ok number" as appropriate. Similarly, the *runs* command will expect its body not to signal an error when run; use it with ok, negated or not. Note that the test block keeps track of how many tests there are and outputs the first line accordingly (it stores up the messages); if an uncaught exception is raised within the body, it simulates one last failed test and propagates the exception in order to ensure that it is counted as a failure. *comm* just writes out a comment to the standard output where it will be visible in verbose testing mode. syntax_check checks the syntax of modules and scripts listed in the MANIFEST. SEE ALSO ======== See `Test::Harness(3)' in this node, for how test scripts are run; and `ExtUtils::MakeMaker(3)' in this node, for where to put test scripts (usually as files `t/*.t') in a distribution. AUTHORS ======= Jesse Glick, *jglick@sig.bsh.com* REVISION ======== X<$Format: "`$Source$' last modified $Date$. Release $TestHelperRelease$. $Copyright$"$> `Test-Helper/lib/Test/Helper.pm' last modified Fri, 05 Sep 1997 16:08:15 -0400. Release 0.002. Copyright (c) 1997 Strategic Interactive Group. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.  File: pm.info, Node: Test/Unit, Next: Test/Unit/Assert, Prev: Test/Helper, Up: Module List Procedural style unit testing interface *************************************** NAME ==== Test::Unit - Procedural style unit testing interface SYNOPSIS ======== use Test::Unit; # your code to be tested goes here sub foo { return 23 }; sub bar { return 42 }; # define tests sub test_foo { assert(foo() == 23, "Your message here"); } sub test_bar { assert(bar() == 42, "I will be printed if this fails"); } # set_up and tear_down are used to # prepare and release resources need for testing sub set_up { print "hello world\n"; } sub tear_down { print "leaving world again\n"; } # run your test create_suite(); run_suite(); DESCRIPTION =========== Test::Unit is the procedural style interface to a sophisticated unit testing framework for Perl that is derived from the JUnit testing framework for Java by Kent Beck and Erich Gamma. While this framework is originally intended to support unit testing in an object-oriented development paradigm (with support for inheritance of tests etc.), Test::Unit is intended to provide a simpler interface to the framework that is more suitable for use in a scripting style environment. Therefore, Test::Unit does not provide much support for an object-oriented approach to unit testing - if you want that, please have a look at Test::Unit::TestCase. You test a given unit (a script, a module, whatever) by using Test::Unit, which exports the following routines into your namespace: assert() - used to assert that a boolean condition is true create_suite() - used to create a test suite consisting of all methods with a name prefix of 'test' run_suite() - runs the test suite (text output) add_suite() - used to add test suites to each other For convenience, create_suite() will automatically build a test suite for a given package. This will build a test case for each subroutine in the package given that has a name starting with "test" and pack them all together into one TestSuite object for easy testing. If you dont give a package name to create_suite(), the current package is taken as default. Test output is one status line (a "." for every successful test run, or an "F" for any failed test run, to indicate progress), one result line ("OK" or "!!!FAILURES!!!"), and possibly many lines reporting detailed error messages for any failed tests. Please remember, Test::Unit is intended to be a simple and convenient interface. If you need more functionality, take the object-oriented approach outlined in Test::Unit::TestCase. AUTHOR ====== Copyright (c) 2000, 2001 Christian Lemburg, . All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Thanks go to the other PerlUnit framework people: Brian Ewins, Cayte Lindner, J.E. Fritz, Zhon Johansen. Thanks for patches go to: Matthew Astley, David Esposito. SEE ALSO ======== - Test::Unit::TestCase - the procedural style examples in the examples directory