package Test::Expect;
use strict;
use warnings;
use Class::Accessor::Chained::Fast;
use Expect::Simple;
use Exporter;
use Test::Builder;
use base qw(Class::Accessor::Chained::Fast Exporter);
our $VERSION = "0.34";
our @EXPORT  = qw(

my $Test = Test::Builder->new;

my $expect;
my $sent;

sub import {
    my $self = shift;
    if (@_) {
        die @_;
        my $package = caller;
    $self->export_to_level( 1, $self, $_ ) foreach @EXPORT;

sub expect_run {
    my (%conf) = @_;
    local $ENV{PERL_RL} = "Stub o=0";
    $expect = Expect::Simple->new(
        {   Cmd           => $conf{command},
            Prompt        => $conf{prompt},
            DisconnectCmd => $conf{quit},
            Verbose       => 0,
            Debug         => 0,
            Timeout       => 100
    die $expect->error if $expect->error;
    $Test->ok( 1, "expect_run" );

sub expect_handle { return $expect->expect_handle(); }

sub before {
    my $before = $expect->before;
    $before =~ s/\r//g;
    $before =~ s/^\Q$sent\E// if $sent;
    $before =~ s/^\n+//;
    $before =~ s/\n+$//;
    return $before;

sub expect_like {
    my ( $like, $comment ) = @_;
    $Test->like( before(), $like, $comment );

sub expect_is {
    my ( $is, $comment ) = @_;
    $Test->is_eq( before(), $is, $comment );

sub expect_send {
    my ( $send, $comment ) = @_;
    $sent = $send;
    $Test->ok( 1, $comment );

sub expect {
    my ( $send, $is, $label ) = @_;
    expect_send( $send, $label );
    expect_is( $is, $label );

sub expect_quit {
    undef $expect;

sub END {



=head1 NAME

Test::Expect - Automated driving and testing of terminal-based programs


  # in a t/*.t file:
  use Test::Expect;
  use Test::More tests => 13;
    command => ["perl", ""],
    prompt  => 'testme: ',
    quit    => 'quit',
  expect("ping", "pong", "expect");
  expect_send("ping", "expect_send");
  expect_is("* Hi there, to testme", "expect_is");
  expect_like(qr/Hi there, to testme/, "expect_like");


L<Test::Expect> is a module for automated driving and testing of
terminal-based programs.  It is handy for testing interactive programs
which have a prompt, and is based on the same concepts as the Tcl
Expect tool.  As in L<Expect::Simple>, the L<Expect> object is made
available for tweaking.

L<Test::Expect> is intended for use in a test script.


=head2 expect_run

The expect_run subroutine sets up L<Test::Expect>. You must pass in
the interactive program to run, what the prompt of the program is, and
which command quits the program:

    command => ["perl", ""],
    prompt  => 'testme: ',
    quit    => 'quit',

The C<command> may either be a string, or an arrayref of program and
arguments; the latter for bypasses the shell.

=head2 expect

The expect subroutine is the catch all subroutine. You pass in the
command, the expected output of the subroutine and an optional

  expect("ping", "pong", "expect");

=head2 expect_send

The expect_send subroutine sends a command to the program. You pass in
the command and an optional comment.

  expect_send("ping", "expect_send");

=head2 expect_is

The expect_is subroutine tests the output of the program like
Test::More's is. It has an optional comment:

  expect_is("* Hi there, to testme", "expect_is");

=head2 expect_like

The expect_like subroutine tests the output of the program like
Test::More's like. It has an optional comment:

  expect_like(qr/Hi there, to testme/, "expect_like");

=head2 expect_handle

This returns the L<Expect> object.

=head2 expect_quit

Closes the L<Expect> handle.

=head1 SEE ALSO

L<Expect>, L<Expect::Simple>.

=head1 AUTHOR

Best Practical Solutions, LLC E<lt>modules@bestpractical.comE<gt>

Original module by Leon Brocard, E<lt>acme@astray.comE<gt>

=head1 BUGS

=for html <p>All bugs should be reported via email to <a
or via the web at <a

=for text
    All bugs should be reported via email to
    or via the web at


This extension is Copyright (C) 2015 Best Practical Solutions, LLC.

Copyright (C) 2005, Leon Brocard

This module is free software; you can redistribute it or modify it
under the same terms as Perl itself.