<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package Test2::API::Stack;
use strict;
use warnings;

our $VERSION = '1.302199';


use Test2::Hub();

use Carp qw/confess/;

sub new {
    my $class = shift;
    return bless [], $class;
}

sub new_hub {
    my $self = shift;
    my %params = @_;

    my $class = delete $params{class} || 'Test2::Hub';

    my $hub = $class-&gt;new(%params);

    if (@$self) {
        $hub-&gt;inherit($self-&gt;[-1], %params);
    }
    else {
        require Test2::API;
        $hub-&gt;format(Test2::API::test2_formatter()-&gt;new_root)
            unless $hub-&gt;format || exists($params{formatter});

        my $ipc = Test2::API::test2_ipc();
        if ($ipc &amp;&amp; !$hub-&gt;ipc &amp;&amp; !exists($params{ipc})) {
            $hub-&gt;set_ipc($ipc);
            $ipc-&gt;add_hub($hub-&gt;hid);
        }
    }

    push @$self =&gt; $hub;

    $hub;
}

sub top {
    my $self = shift;
    return $self-&gt;new_hub unless @$self;
    return $self-&gt;[-1];
}

sub peek {
    my $self = shift;
    return @$self ? $self-&gt;[-1] : undef;
}

sub cull {
    my $self = shift;
    $_-&gt;cull for reverse @$self;
}

sub all {
    my $self = shift;
    return @$self;
}

sub root {
    my $self = shift;
    return unless @$self;
    return $self-&gt;[0];
}

sub clear {
    my $self = shift;
    @$self = ();
}

# Do these last without keywords in order to prevent them from getting used
# when we want the real push/pop.

{
    no warnings 'once';

    *push = sub {
        my $self = shift;
        my ($hub) = @_;
        $hub-&gt;inherit($self-&gt;[-1]) if @$self;
        push @$self =&gt; $hub;
    };

    *pop = sub {
        my $self = shift;
        my ($hub) = @_;
        confess "No hubs on the stack"
            unless @$self;
        confess "You cannot pop the root hub"
            if 1 == @$self;
        confess "Hub stack mismatch, attempted to pop incorrect hub"
            unless $self-&gt;[-1] == $hub;
        pop @$self;
    };
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Test2::API::Stack - Object to manage a stack of L&lt;Test2::Hub&gt;
instances.

=head1 ***INTERNALS NOTE***

B&lt;The internals of this package are subject to change at any time!&gt; The public
methods provided will not change in backwards incompatible ways, but the
underlying implementation details might. B&lt;Do not break encapsulation here!&gt;

=head1 DESCRIPTION

This module is used to represent and manage a stack of L&lt;Test2::Hub&gt;
objects. Hubs are usually in a stack so that you can push a new hub into place
that can intercept and handle events differently than the primary hub.

=head1 SYNOPSIS

    my $stack = Test2::API::Stack-&gt;new;
    my $hub = $stack-&gt;top;

=head1 METHODS

=over 4

=item $stack = Test2::API::Stack-&gt;new()

This will create a new empty stack instance. All arguments are ignored.

=item $hub = $stack-&gt;new_hub()

=item $hub = $stack-&gt;new_hub(%params)

=item $hub = $stack-&gt;new_hub(%params, class =&gt; $class)

This will generate a new hub and push it to the top of the stack. Optionally
you can provide arguments that will be passed into the constructor for the
L&lt;Test2::Hub&gt; object.

If you specify the C&lt;&lt; 'class' =&gt; $class &gt;&gt; argument, the new hub will be an
instance of the specified class.

Unless your parameters specify C&lt;'formatter'&gt; or C&lt;'ipc'&gt; arguments, the
formatter and IPC instance will be inherited from the current top hub. You can
set the parameters to C&lt;undef&gt; to avoid having a formatter or IPC instance.

If there is no top hub, and you do not ask to leave IPC and formatter undef,
then a new formatter will be created, and the IPC instance from
L&lt;Test2::API&gt; will be used.

=item $hub = $stack-&gt;top()

This will return the top hub from the stack. If there is no top hub yet this
will create it.

=item $hub = $stack-&gt;peek()

This will return the top hub from the stack. If there is no top hub yet this
will return undef.

=item $stack-&gt;cull

This will call C&lt;&lt; $hub-&gt;cull &gt;&gt; on all hubs in the stack.

=item @hubs = $stack-&gt;all

This will return all the hubs in the stack as a list.

=item $stack-&gt;clear

This will completely remove all hubs from the stack. Normally you do not want
to do this, but there are a few valid reasons for it.

=item $stack-&gt;push($hub)

This will push the new hub onto the stack.

=item $stack-&gt;pop($hub)

This will pop a hub from the stack, if the hub at the top of the stack does not
match the hub you expect (passed in as an argument) it will throw an exception.

=back

=head1 SOURCE

The source code repository for Test2 can be found at
L&lt;https://github.com/Test-More/test-more/&gt;.

=head1 MAINTAINERS

=over 4

=item Chad Granum E&lt;lt&gt;exodist@cpan.orgE&lt;gt&gt;

=back

=head1 AUTHORS

=over 4

=item Chad Granum E&lt;lt&gt;exodist@cpan.orgE&lt;gt&gt;

=back

=head1 COPYRIGHT

Copyright 2020 Chad Granum E&lt;lt&gt;exodist@cpan.orgE&lt;gt&gt;.

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

See L&lt;https://dev.perl.org/licenses/&gt;

=cut
</pre></body></html>