⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prove.pm

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 PM
字号:
package App::Prove;use strict;use TAP::Harness;use File::Spec;use Getopt::Long;use App::Prove::State;use Carp;use vars qw($VERSION);=head1 NAMEApp::Prove - Implements the C<prove> command.=head1 VERSIONVersion 3.07=cut$VERSION = '3.07';=head1 DESCRIPTIONL<Test::Harness> provides a command, C<prove>, which runs a TAP basedtest suite and prints a report. The C<prove> command is a minimalwrapper around an instance of this module.=head1 SYNOPSIS    use App::Prove;    my $app = App::Prove->new;    $app->process_args(@ARGV);    $app->run;=cutuse constant IS_WIN32 => ( $^O =~ /^(MS)?Win32$/ );use constant IS_VMS => $^O eq 'VMS';use constant IS_UNIXY => !( IS_VMS || IS_WIN32 );use constant STATE_FILE => IS_UNIXY ? '.prove'   : '_prove';use constant RC_FILE    => IS_UNIXY ? '.proverc' : '_proverc';use constant PLUGINS => 'App::Prove::Plugin';my @ATTR;BEGIN {    @ATTR = qw(      archive argv blib color directives exec failures fork formatter      harness includes modules plugins jobs lib merge parse quiet      really_quiet recurse backwards shuffle taint_fail taint_warn timer      verbose warnings_fail warnings_warn show_help show_man      show_version test_args state    );    for my $attr (@ATTR) {        no strict 'refs';        *$attr = sub {            my $self = shift;            croak "$attr is read-only" if @_;            $self->{$attr};        };    }}=head1 METHODS=head2 Class Methods=head3 C<new>Create a new C<App::Prove>. Optionally a hash ref of attributeinitializers may be passed.=cutsub new {    my $class = shift;    my $args = shift || {};    my $self = bless {        argv          => [],        rc_opts       => [],        includes      => [],        modules       => [],        state         => [],        plugins       => [],        harness_class => 'TAP::Harness',        _state        => App::Prove::State->new( { store => STATE_FILE } ),    }, $class;    for my $attr (@ATTR) {        if ( exists $args->{$attr} ) {            # TODO: Some validation here            $self->{$attr} = $args->{$attr};        }    }    return $self;}=head3 C<add_rc_file>    $prove->add_rc_file('myproj/.proverc');Called before C<process_args> to prepend the contents of an rc file tothe options.=cutsub add_rc_file {    my ( $self, $rc_file ) = @_;    local *RC;    open RC, "<$rc_file" or croak "Can't read $rc_file ($!)";    while ( defined( my $line = <RC> ) ) {        push @{ $self->{rc_opts} }, grep $_ && $_ !~ /^#/,          $line =~ m{ ' ([^']*) ' | " ([^"]*) " | (\#.*) | (\S*) }xg;    }    close RC;}=head3 C<process_args>    $prove->process_args(@args);Processes the command-line arguments. Attributes will be setappropriately. Any filenames may be found in the C<argv> attribute.Dies on invalid arguments.=cutsub process_args {    my $self = shift;    my @rc = RC_FILE;    unshift @rc, glob '~/' . RC_FILE if IS_UNIXY;    # Preprocess meta-args.    my @args;    while ( defined( my $arg = shift ) ) {        if ( $arg eq '--norc' ) {            @rc = ();        }        elsif ( $arg eq '--rc' ) {            defined( my $rc = shift )              or croak "Missing argument to --rc";            push @rc, $rc;        }        elsif ( $arg =~ m{^--rc=(.+)$} ) {            push @rc, $1;        }        else {            push @args, $arg;        }    }    # Everything after the arisdottle '::' gets passed as args to    # test programs.    if ( defined( my $stop_at = _first_pos( '::', @args ) ) ) {        my @test_args = splice @args, $stop_at;        shift @test_args;        $self->{test_args} = \@test_args;    }    # Grab options from RC files    $self->add_rc_file($_) for grep -f, @rc;    unshift @args, @{ $self->{rc_opts} };    if ( my @bad = map {"-$_"} grep {/^-(man|help)$/} @args ) {        die "Long options should be written with two dashes: ",          join( ', ', @bad ), "\n";    }    # And finally...    {        local @ARGV = @args;        Getopt::Long::Configure( 'no_ignore_case', 'bundling' );        # Don't add coderefs to GetOptions        GetOptions(            'v|verbose'   => \$self->{verbose},            'f|failures'  => \$self->{failures},            'l|lib'       => \$self->{lib},            'b|blib'      => \$self->{blib},            's|shuffle'   => \$self->{shuffle},            'color!'      => \$self->{color},            'colour!'     => \$self->{color},            'c'           => \$self->{color},            'harness=s'   => \$self->{harness},            'formatter=s' => \$self->{formatter},            'r|recurse'   => \$self->{recurse},            'reverse'     => \$self->{backwards},            'fork'        => \$self->{fork},            'p|parse'     => \$self->{parse},            'q|quiet'     => \$self->{quiet},            'Q|QUIET'     => \$self->{really_quiet},            'e|exec=s'    => \$self->{exec},            'm|merge'     => \$self->{merge},            'I=s@'        => $self->{includes},            'M=s@'        => $self->{modules},            'P=s@'        => $self->{plugins},            'state=s@'    => $self->{state},            'directives'  => \$self->{directives},            'h|help|?'    => \$self->{show_help},            'H|man'       => \$self->{show_man},            'V|version'   => \$self->{show_version},            'a|archive=s' => \$self->{archive},            'j|jobs=i'    => \$self->{jobs},            'timer'       => \$self->{timer},            'T'           => \$self->{taint_fail},            't'           => \$self->{taint_warn},            'W'           => \$self->{warnings_fail},            'w'           => \$self->{warnings_warn},        ) or croak('Unable to continue');        # Stash the remainder of argv for later        $self->{argv} = [@ARGV];    }    return;}sub _first_pos {    my $want = shift;    for ( 0 .. $#_ ) {        return $_ if $_[$_] eq $want;    }    return;}sub _exit { exit( $_[1] || 0 ) }sub _help {    my ( $self, $verbosity ) = @_;    eval('use Pod::Usage 1.12 ()');    if ( my $err = $@ ) {        die 'Please install Pod::Usage for the --help option '          . '(or try `perldoc prove`.)'          . "\n ($@)";    }    Pod::Usage::pod2usage( { -verbose => $verbosity } );    return;}sub _color_default {    my $self = shift;    return -t STDOUT && !IS_WIN32;}sub _get_args {    my $self = shift;    my %args;    if ( defined $self->color ? $self->color : $self->_color_default ) {        $args{color} = 1;    }    if ( $self->archive ) {        $self->require_harness( archive => 'TAP::Harness::Archive' );        $args{archive} = $self->archive;    }    if ( my $jobs = $self->jobs ) {        $args{jobs} = $jobs;    }    if ( my $fork = $self->fork ) {        $args{fork} = $fork;    }    if ( my $harness_opt = $self->harness ) {        $self->require_harness( harness => $harness_opt );    }    if ( my $formatter = $self->formatter ) {        $args{formatter_class} = $formatter;    }    if ( $self->taint_fail && $self->taint_warn ) {        die '-t and -T are mutually exclusive';    }    if ( $self->warnings_fail && $self->warnings_warn ) {        die '-w and -W are mutually exclusive';    }    for my $a (qw( lib switches )) {        my $method = "_get_$a";        my $val    = $self->$method();        $args{$a} = $val if defined $val;    }    # Handle verbose, quiet, really_quiet flags    my %verb_map = ( verbose => 1, quiet => -1, really_quiet => -2, );    my @verb_adj = grep {$_} map { $self->$_() ? $verb_map{$_} : 0 }      keys %verb_map;    die "Only one of verbose, quiet or really_quiet should be specified\n"      if @verb_adj > 1;    $args{verbosity} = shift @verb_adj || 0;    for my $a (qw( merge failures timer directives )) {        $args{$a} = 1 if $self->$a();    }    $args{errors} = 1 if $self->parse;    # defined but zero-length exec runs test files as binaries    $args{exec} = [ split( /\s+/, $self->exec ) ]      if ( defined( $self->exec ) );    if ( defined( my $test_args = $self->test_args ) ) {        $args{test_args} = $test_args;    }    return ( \%args, $self->{harness_class} );}sub _find_module {    my ( $self, $class, @search ) = @_;    croak "Bad module name $class"      unless $class =~ /^ \w+ (?: :: \w+ ) *$/x;    for my $pfx (@search) {        my $name = join( '::', $pfx, $class );        print "$name\n";        eval "require $name";        return $name unless $@;    }    eval "require $class";    return $class unless $@;    return;}sub _load_extension {    my ( $self, $class, @search ) = @_;    my @args = ();    if ( $class =~ /^(.*?)=(.*)/ ) {        $class = $1;        @args = split( /,/, $2 );    }    if ( my $name = $self->_find_module( $class, @search ) ) {        $name->import(@args);    }    else {        croak "Can't load module $class";    }}sub _load_extensions {    my ( $self, $ext, @search ) = @_;    $self->_load_extension( $_, @search ) for @$ext;}=head3 C<run>Perform whatever actions the command line args specified. The C<prove>command line tool consists of the following code:    use App::Prove;    my $app = App::Prove->new;    $app->process_args(@ARGV);    $app->run;=cutsub run {    my $self = shift;    if ( $self->show_help ) {        $self->_help(1);    }    elsif ( $self->show_man ) {        $self->_help(2);    }    elsif ( $self->show_version ) {        $self->print_version;    }    else {        $self->_load_extensions( $self->modules );        $self->_load_extensions( $self->plugins, PLUGINS );        my $state = $self->{_state};        if ( defined( my $state_switch = $self->state ) ) {            $state->apply_switch(@$state_switch);        }        my @tests = $state->get_tests( $self->recurse, @{ $self->argv } );        $self->_shuffle(@tests) if $self->shuffle;        @tests = reverse @tests if $self->backwards;        local $ENV{TEST_VERBOSE} = 1 if $self->verbose;        $self->_runtests( $self->_get_args, @tests );    }    return;}sub _runtests {    my ( $self, $args, $harness_class, @tests ) = @_;    my $harness = $harness_class->new($args);    $harness->callback(        after_test => sub {            $self->{_state}->observe_test(@_);        }    );    my $aggregator = $harness->runtests(@tests);    $self->_exit( $aggregator->has_problems ? 1 : 0 );    return;}sub _get_switches {    my $self = shift;    my @switches;    # notes that -T or -t must be at the front of the switches!    if ( $self->taint_fail ) {        push @switches, '-T';    }    elsif ( $self->taint_warn ) {        push @switches, '-t';    }    if ( $self->warnings_fail ) {        push @switches, '-W';    }    elsif ( $self->warnings_warn ) {        push @switches, '-w';    }    if ( defined( my $hps = $ENV{HARNESS_PERL_SWITCHES} ) ) {        push @switches, $hps;    }    return @switches ? \@switches : ();}sub _get_lib {    my $self = shift;    my @libs;    if ( $self->lib ) {        push @libs, 'lib';    }    if ( $self->blib ) {        push @libs, 'blib/lib', 'blib/arch';    }    if ( @{ $self->includes } ) {        push @libs, @{ $self->includes };    }    #24926    @libs = map { File::Spec->rel2abs($_) } @libs;    # Huh?    return @libs ? \@libs : ();}sub _shuffle {    my $self = shift;    # Fisher-Yates shuffle    my $i = @_;    while ($i) {        my $j = rand $i--;        @_[ $i, $j ] = @_[ $j, $i ];    }    return;}=head3 C<require_harness>Load a harness replacement class.  $prove->require_harness($for => $class_name);=cutsub require_harness {    my ( $self, $for, $class ) = @_;    eval("require $class");    die "$class is required to use the --$for feature: $@" if $@;    $self->{harness_class} = $class;    return;}=head3 C<print_version>Display the version numbers of the loaded L<TAP::Harness> and thecurrent Perl.=cutsub print_version {    my $self = shift;    printf(        "TAP::Harness v%s and Perl v%vd\n",        $TAP::Harness::VERSION, $^V    );    return;}1;# vim:ts=4:sw=4:et:sta__END__=head2 AttributesAfter command line parsing the following attributes reflect the valuesof the corresponding command line switches. They may be altered beforecalling C<run>.=over=item C<archive>=item C<argv>=item C<backwards>=item C<blib>=item C<color>=item C<directives>=item C<exec>=item C<failures>=item C<fork>=item C<formatter>=item C<harness>=item C<includes>=item C<jobs>=item C<lib>=item C<merge>=item C<modules>=item C<parse>=item C<plugins>=item C<quiet>=item C<really_quiet>=item C<recurse>=item C<show_help>=item C<show_man>=item C<show_version>=item C<shuffle>=item C<state>=item C<taint_fail>=item C<taint_warn>=item C<test_args>=item C<timer>=item C<verbose>=item C<warnings_fail>=item C<warnings_warn>=back

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -