summaryrefslogtreecommitdiff
path: root/systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util
diff options
context:
space:
mode:
Diffstat (limited to 'systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util')
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/ExternalMeta.pm182
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/Facets2Legacy.pm299
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/HashBase.pm435
-rw-r--r--systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/Trace.pm54
4 files changed, 970 insertions, 0 deletions
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/ExternalMeta.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/ExternalMeta.pm
new file mode 100644
index 0000000000..f03422c61a
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/ExternalMeta.pm
@@ -0,0 +1,182 @@
+package Test2::Util::ExternalMeta;
+use strict;
+use warnings;
+
+our $VERSION = '1.302133';
+
+
+use Carp qw/croak/;
+
+sub META_KEY() { '_meta' }
+
+our @EXPORT = qw/meta set_meta get_meta delete_meta/;
+BEGIN { require Exporter; our @ISA = qw(Exporter) }
+
+sub set_meta {
+ my $self = shift;
+ my ($key, $value) = @_;
+
+ validate_key($key);
+
+ $self->{+META_KEY} ||= {};
+ $self->{+META_KEY}->{$key} = $value;
+}
+
+sub get_meta {
+ my $self = shift;
+ my ($key) = @_;
+
+ validate_key($key);
+
+ my $meta = $self->{+META_KEY} or return undef;
+ return $meta->{$key};
+}
+
+sub delete_meta {
+ my $self = shift;
+ my ($key) = @_;
+
+ validate_key($key);
+
+ my $meta = $self->{+META_KEY} or return undef;
+ delete $meta->{$key};
+}
+
+sub meta {
+ my $self = shift;
+ my ($key, $default) = @_;
+
+ validate_key($key);
+
+ my $meta = $self->{+META_KEY};
+ return undef unless $meta || defined($default);
+
+ unless($meta) {
+ $meta = {};
+ $self->{+META_KEY} = $meta;
+ }
+
+ $meta->{$key} = $default
+ if defined($default) && !defined($meta->{$key});
+
+ return $meta->{$key};
+}
+
+sub validate_key {
+ my $key = shift;
+
+ return if $key && !ref($key);
+
+ my $render_key = defined($key) ? "'$key'" : 'undef';
+ croak "Invalid META key: $render_key, keys must be true, and may not be references";
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Util::ExternalMeta - Allow third party tools to safely attach meta-data
+to your instances.
+
+=head1 DESCRIPTION
+
+This package lets you define a clear, and consistent way to allow third party
+tools to attach meta-data to your instances. If your object consumes this
+package, and imports its methods, then third party meta-data has a safe place
+to live.
+
+=head1 SYNOPSIS
+
+ package My::Object;
+ use strict;
+ use warnings;
+
+ use Test2::Util::ExternalMeta qw/meta get_meta set_meta delete_meta/;
+
+ ...
+
+Now to use it:
+
+ my $inst = My::Object->new;
+
+ $inst->set_meta(foo => 'bar');
+ my $val = $inst->get_meta('foo');
+
+=head1 WHERE IS THE DATA STORED?
+
+This package assumes your instances are blessed hashrefs, it will not work if
+that is not true. It will store all meta-data in the C<_meta> key on your
+objects hash. If your object makes use of the C<_meta> key in its underlying
+hash, then there is a conflict and you cannot use this package.
+
+=head1 EXPORTS
+
+=over 4
+
+=item $val = $obj->meta($key)
+
+=item $val = $obj->meta($key, $default)
+
+This will get the value for a specified meta C<$key>. Normally this will return
+C<undef> when there is no value for the C<$key>, however you can specify a
+C<$default> value to set when no value is already set.
+
+=item $val = $obj->get_meta($key)
+
+This will get the value for a specified meta C<$key>. This does not have the
+C<$default> overhead that C<meta()> does.
+
+=item $val = $obj->delete_meta($key)
+
+This will remove the value of a specified meta C<$key>. The old C<$val> will be
+returned.
+
+=item $obj->set_meta($key, $val)
+
+Set the value of a specified meta C<$key>.
+
+=back
+
+=head1 META-KEY RESTRICTIONS
+
+Meta keys must be defined, and must be true when used as a boolean. Keys may
+not be references. You are free to stringify a reference C<"$ref"> for use as a
+key, but this package will not stringify it for you.
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2018 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/Facets2Legacy.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/Facets2Legacy.pm
new file mode 100644
index 0000000000..db74510a4d
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/Facets2Legacy.pm
@@ -0,0 +1,299 @@
+package Test2::Util::Facets2Legacy;
+use strict;
+use warnings;
+
+our $VERSION = '1.302133';
+
+use Carp qw/croak confess/;
+use Scalar::Util qw/blessed/;
+
+use base 'Exporter';
+our @EXPORT_OK = qw{
+ causes_fail
+ diagnostics
+ global
+ increments_count
+ no_display
+ sets_plan
+ subtest_id
+ summary
+ terminate
+ uuid
+};
+our %EXPORT_TAGS = ( ALL => \@EXPORT_OK );
+
+our $CYCLE_DETECT = 0;
+sub _get_facet_data {
+ my $in = shift;
+
+ if (blessed($in) && $in->isa('Test2::Event')) {
+ confess "Cycle between Facets2Legacy and $in\->facet_data() (Did you forget to override the facet_data() method?)"
+ if $CYCLE_DETECT;
+
+ local $CYCLE_DETECT = 1;
+ return $in->facet_data;
+ }
+
+ return $in if ref($in) eq 'HASH';
+
+ croak "'$in' Does not appear to be either a Test::Event or an EventFacet hashref";
+}
+
+sub causes_fail {
+ my $facet_data = _get_facet_data(shift @_);
+
+ return 1 if $facet_data->{errors} && grep { $_->{fail} } @{$facet_data->{errors}};
+
+ if (my $control = $facet_data->{control}) {
+ return 1 if $control->{halt};
+ return 1 if $control->{terminate};
+ }
+
+ return 0 if $facet_data->{amnesty} && @{$facet_data->{amnesty}};
+ return 1 if $facet_data->{assert} && !$facet_data->{assert}->{pass};
+ return 0;
+}
+
+sub diagnostics {
+ my $facet_data = _get_facet_data(shift @_);
+ return 1 if $facet_data->{errors} && @{$facet_data->{errors}};
+ return 0 unless $facet_data->{info} && @{$facet_data->{info}};
+ return (grep { $_->{debug} } @{$facet_data->{info}}) ? 1 : 0;
+}
+
+sub global {
+ my $facet_data = _get_facet_data(shift @_);
+ return 0 unless $facet_data->{control};
+ return $facet_data->{control}->{global};
+}
+
+sub increments_count {
+ my $facet_data = _get_facet_data(shift @_);
+ return $facet_data->{assert} ? 1 : 0;
+}
+
+sub no_display {
+ my $facet_data = _get_facet_data(shift @_);
+ return 0 unless $facet_data->{about};
+ return $facet_data->{about}->{no_display};
+}
+
+sub sets_plan {
+ my $facet_data = _get_facet_data(shift @_);
+ my $plan = $facet_data->{plan} or return;
+ my @out = ($plan->{count} || 0);
+
+ if ($plan->{skip}) {
+ push @out => 'SKIP';
+ push @out => $plan->{details} if defined $plan->{details};
+ }
+ elsif ($plan->{none}) {
+ push @out => 'NO PLAN'
+ }
+
+ return @out;
+}
+
+sub subtest_id {
+ my $facet_data = _get_facet_data(shift @_);
+ return undef unless $facet_data->{parent};
+ return $facet_data->{parent}->{hid};
+}
+
+sub summary {
+ my $facet_data = _get_facet_data(shift @_);
+ return '' unless $facet_data->{about} && $facet_data->{about}->{details};
+ return $facet_data->{about}->{details};
+}
+
+sub terminate {
+ my $facet_data = _get_facet_data(shift @_);
+ return undef unless $facet_data->{control};
+ return $facet_data->{control}->{terminate};
+}
+
+sub uuid {
+ my $in = shift;
+
+ if ($CYCLE_DETECT) {
+ if (blessed($in) && $in->isa('Test2::Event')) {
+ my $meth = $in->can('uuid');
+ $meth = $in->can('SUPER::uuid') if $meth == \&uuid;
+ my $uuid = $in->$meth if $meth && $meth != \&uuid;
+ return $uuid if $uuid;
+ }
+
+ return undef;
+ }
+
+ my $facet_data = _get_facet_data($in);
+ return $facet_data->{about}->{uuid} if $facet_data->{about} && $facet_data->{about}->{uuid};
+
+ return undef;
+}
+
+1;
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Util::Facets2Legacy - Convert facet data to the legacy event API.
+
+=head1 DESCRIPTION
+
+This module exports several subroutines from the older event API (see
+L<Test2::Event>). These subroutines can be used as methods on any object that
+provides a custom C<facet_data()> method. These subroutines can also be used as
+functions that take a facet data hashref as arguments.
+
+=head1 SYNOPSIS
+
+=head2 AS METHODS
+
+ package My::Event;
+
+ use Test2::Util::Facets2Legacy ':ALL';
+
+ sub facet_data { return { ... } }
+
+Then to use it:
+
+ my $e = My::Event->new(...);
+
+ my $causes_fail = $e->causes_fail;
+ my $summary = $e->summary;
+ ....
+
+=head2 AS FUNCTIONS
+
+ use Test2::Util::Facets2Legacy ':ALL';
+
+ my $f = {
+ assert => { ... },
+ info => [{...}, ...],
+ control => {...},
+ ...
+ };
+
+ my $causes_fail = causes_fail($f);
+ my $summary = summary($f);
+
+=head1 NOTE ON CYCLES
+
+When used as methods, all these subroutines call C<< $e->facet_data() >>. The
+default C<facet_data()> method in L<Test2::Event> relies on the legacy methods
+this module emulates in order to work. As a result of this it is very easy to
+create infinite recursion bugs.
+
+These methods have cycle detection and will throw an exception early if a cycle
+is detected. C<uuid()> is currently the only subroutine in this library that
+has a fallback behavior when cycles are detected.
+
+=head1 EXPORTS
+
+Nothing is exported by default. You must specify which methods to import, or
+use the ':ALL' tag.
+
+=over 4
+
+=item $bool = $e->causes_fail()
+
+=item $bool = causes_fail($f)
+
+Check if the event or facets result in a failing state.
+
+=item $bool = $e->diagnostics()
+
+=item $bool = diagnostics($f)
+
+Check if the event or facets contain any diagnostics information.
+
+=item $bool = $e->global()
+
+=item $bool = global($f)
+
+Check if the event or facets need to be globally processed.
+
+=item $bool = $e->increments_count()
+
+=item $bool = increments_count($f)
+
+Check if the event or facets make an assertion.
+
+=item $bool = $e->no_display()
+
+=item $bool = no_display($f)
+
+Check if the event or facets should be rendered or hidden.
+
+=item ($max, $directive, $reason) = $e->sets_plan()
+
+=item ($max, $directive, $reason) = sets_plan($f)
+
+Check if the event or facets set a plan, and return the plan details.
+
+=item $id = $e->subtest_id()
+
+=item $id = subtest_id($f)
+
+Get the subtest id, if any.
+
+=item $string = $e->summary()
+
+=item $string = summary($f)
+
+Get the summary of the event or facets hash, if any.
+
+=item $undef_or_int = $e->terminate()
+
+=item $undef_or_int = terminate($f)
+
+Check if the event or facets should result in process termination, if so the
+exit code is returned (which could be 0). undef is returned if no termination
+is requested.
+
+=item $uuid = $e->uuid()
+
+=item $uuid = uuid($f)
+
+Get the UUID of the facets or event.
+
+B<Note:> This will fall back to C<< $e->SUPER::uuid() >> if a cycle is
+detected and an event is used as the argument.
+
+=back
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2018 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/HashBase.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/HashBase.pm
new file mode 100644
index 0000000000..8e73af425e
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/HashBase.pm
@@ -0,0 +1,435 @@
+package Test2::Util::HashBase;
+use strict;
+use warnings;
+
+our $VERSION = '1.302133';
+
+#################################################################
+# #
+# This is a generated file! Do not modify this file directly! #
+# Use hashbase_inc.pl script to regenerate this file. #
+# The script is part of the Object::HashBase distribution. #
+# Note: You can modify the version number above this comment #
+# if needed, that is fine. #
+# #
+#################################################################
+
+{
+ no warnings 'once';
+ $Test2::Util::HashBase::HB_VERSION = '0.006';
+ *Test2::Util::HashBase::ATTR_SUBS = \%Object::HashBase::ATTR_SUBS;
+ *Test2::Util::HashBase::ATTR_LIST = \%Object::HashBase::ATTR_LIST;
+ *Test2::Util::HashBase::VERSION = \%Object::HashBase::VERSION;
+ *Test2::Util::HashBase::CAN_CACHE = \%Object::HashBase::CAN_CACHE;
+}
+
+
+require Carp;
+{
+ no warnings 'once';
+ $Carp::Internal{+__PACKAGE__} = 1;
+}
+
+BEGIN {
+ # these are not strictly equivalent, but for out use we don't care
+ # about order
+ *_isa = ($] >= 5.010 && require mro) ? \&mro::get_linear_isa : sub {
+ no strict 'refs';
+ my @packages = ($_[0]);
+ my %seen;
+ for my $package (@packages) {
+ push @packages, grep !$seen{$_}++, @{"$package\::ISA"};
+ }
+ return \@packages;
+ }
+}
+
+my %STRIP = (
+ '^' => 1,
+ '-' => 1,
+);
+
+sub import {
+ my $class = shift;
+ my $into = caller;
+
+ # Make sure we list the OLDEST version used to create this class.
+ my $ver = $Test2::Util::HashBase::HB_VERSION || $Test2::Util::HashBase::VERSION;
+ $Test2::Util::HashBase::VERSION{$into} = $ver if !$Test2::Util::HashBase::VERSION{$into} || $Test2::Util::HashBase::VERSION{$into} > $ver;
+
+ my $isa = _isa($into);
+ my $attr_list = $Test2::Util::HashBase::ATTR_LIST{$into} ||= [];
+ my $attr_subs = $Test2::Util::HashBase::ATTR_SUBS{$into} ||= {};
+
+ my %subs = (
+ ($into->can('new') ? () : (new => \&_new)),
+ (map %{$Test2::Util::HashBase::ATTR_SUBS{$_} || {}}, @{$isa}[1 .. $#$isa]),
+ (
+ map {
+ my $p = substr($_, 0, 1);
+ my $x = $_;
+ substr($x, 0, 1) = '' if $STRIP{$p};
+ push @$attr_list => $x;
+ my ($sub, $attr) = (uc $x, $x);
+ $sub => ($attr_subs->{$sub} = sub() { $attr }),
+ $attr => sub { $_[0]->{$attr} },
+ $p eq '-' ? ("set_$attr" => sub { Carp::croak("'$attr' is read-only") })
+ : $p eq '^' ? ("set_$attr" => sub { Carp::carp("set_$attr() is deprecated"); $_[0]->{$attr} = $_[1] })
+ : ("set_$attr" => sub { $_[0]->{$attr} = $_[1] }),
+ } @_
+ ),
+ );
+
+ no strict 'refs';
+ *{"$into\::$_"} = $subs{$_} for keys %subs;
+}
+
+sub attr_list {
+ my $class = shift;
+
+ my $isa = _isa($class);
+
+ my %seen;
+ my @list = grep { !$seen{$_}++ } map {
+ my @out;
+
+ if (0.004 > ($Test2::Util::HashBase::VERSION{$_} || 0)) {
+ Carp::carp("$_ uses an inlined version of Test2::Util::HashBase too old to support attr_list()");
+ }
+ else {
+ my $list = $Test2::Util::HashBase::ATTR_LIST{$_};
+ @out = $list ? @$list : ()
+ }
+
+ @out;
+ } reverse @$isa;
+
+ return @list;
+}
+
+sub _new {
+ my $class = shift;
+
+ my $self;
+
+ if (@_ == 1) {
+ my $arg = shift;
+ my $type = ref($arg);
+
+ if ($type eq 'HASH') {
+ $self = bless({%$arg}, $class)
+ }
+ else {
+ Carp::croak("Not sure what to do with '$type' in $class constructor")
+ unless $type eq 'ARRAY';
+
+ my %proto;
+ my @attributes = attr_list($class);
+ while (@$arg) {
+ my $val = shift @$arg;
+ my $key = shift @attributes or Carp::croak("Too many arguments for $class constructor");
+ $proto{$key} = $val;
+ }
+
+ $self = bless(\%proto, $class);
+ }
+ }
+ else {
+ $self = bless({@_}, $class);
+ }
+
+ $Test2::Util::HashBase::CAN_CACHE{$class} = $self->can('init')
+ unless exists $Test2::Util::HashBase::CAN_CACHE{$class};
+
+ $self->init if $Test2::Util::HashBase::CAN_CACHE{$class};
+
+ $self;
+}
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Util::HashBase - Build hash based classes.
+
+=head1 SYNOPSIS
+
+A class:
+
+ package My::Class;
+ use strict;
+ use warnings;
+
+ # Generate 3 accessors
+ use Test2::Util::HashBase qw/foo -bar ^baz/;
+
+ # Chance to initialize defaults
+ sub init {
+ my $self = shift; # No other args
+ $self->{+FOO} ||= "foo";
+ $self->{+BAR} ||= "bar";
+ $self->{+BAZ} ||= "baz";
+ }
+
+ sub print {
+ print join ", " => map { $self->{$_} } FOO, BAR, BAZ;
+ }
+
+Subclass it
+
+ package My::Subclass;
+ use strict;
+ use warnings;
+
+ # Note, you should subclass before loading HashBase.
+ use base 'My::Class';
+ use Test2::Util::HashBase qw/bat/;
+
+ sub init {
+ my $self = shift;
+
+ # We get the constants from the base class for free.
+ $self->{+FOO} ||= 'SubFoo';
+ $self->{+BAT} ||= 'bat';
+
+ $self->SUPER::init();
+ }
+
+use it:
+
+ package main;
+ use strict;
+ use warnings;
+ use My::Class;
+
+ # These are all functionally identical
+ my $one = My::Class->new(foo => 'MyFoo', bar => 'MyBar');
+ my $two = My::Class->new({foo => 'MyFoo', bar => 'MyBar'});
+ my $three = My::Class->new(['MyFoo', 'MyBar']);
+
+ # Accessors!
+ my $foo = $one->foo; # 'MyFoo'
+ my $bar = $one->bar; # 'MyBar'
+ my $baz = $one->baz; # Defaulted to: 'baz'
+
+ # Setters!
+ $one->set_foo('A Foo');
+
+ #'-bar' means read-only, so the setter will throw an exception (but is defined).
+ $one->set_bar('A bar');
+
+ # '^baz' means deprecated setter, this will warn about the setter being
+ # deprecated.
+ $one->set_baz('A Baz');
+
+ $one->{+FOO} = 'xxx';
+
+=head1 DESCRIPTION
+
+This package is used to generate classes based on hashrefs. Using this class
+will give you a C<new()> method, as well as generating accessors you request.
+Generated accessors will be getters, C<set_ACCESSOR> setters will also be
+generated for you. You also get constants for each accessor (all caps) which
+return the key into the hash for that accessor. Single inheritance is also
+supported.
+
+=head1 THIS IS A BUNDLED COPY OF HASHBASE
+
+This is a bundled copy of L<Object::HashBase>. This file was generated using
+the
+C</home/exodist/perl5/perlbrew/perls/main/bin/hashbase_inc.pl>
+script.
+
+=head1 METHODS
+
+=head2 PROVIDED BY HASH BASE
+
+=over 4
+
+=item $it = $class->new(%PAIRS)
+
+=item $it = $class->new(\%PAIRS)
+
+=item $it = $class->new(\@ORDERED_VALUES)
+
+Create a new instance.
+
+HashBase will not export C<new()> if there is already a C<new()> method in your
+packages inheritance chain.
+
+B<If you do not want this method you can define your own> you just have to
+declare it before loading L<Test2::Util::HashBase>.
+
+ package My::Package;
+
+ # predeclare new() so that HashBase does not give us one.
+ sub new;
+
+ use Test2::Util::HashBase qw/foo bar baz/;
+
+ # Now we define our own new method.
+ sub new { ... }
+
+This makes it so that HashBase sees that you have your own C<new()> method.
+Alternatively you can define the method before loading HashBase instead of just
+declaring it, but that scatters your use statements.
+
+The most common way to create an object is to pass in key/value pairs where
+each key is an attribute and each value is what you want assigned to that
+attribute. No checking is done to verify the attributes or values are valid,
+you may do that in C<init()> if desired.
+
+If you would like, you can pass in a hashref instead of pairs. When you do so
+the hashref will be copied, and the copy will be returned blessed as an object.
+There is no way to ask HashBase to bless a specific hashref.
+
+In some cases an object may only have 1 or 2 attributes, in which case a
+hashref may be too verbose for your liking. In these cases you can pass in an
+arrayref with only values. The values will be assigned to attributes in the
+order the attributes were listed. When there is inheritance involved the
+attributes from parent classes will come before subclasses.
+
+=back
+
+=head2 HOOKS
+
+=over 4
+
+=item $self->init()
+
+This gives you the chance to set some default values to your fields. The only
+argument is C<$self> with its indexes already set from the constructor.
+
+B<Note:> Test2::Util::HashBase checks for an init using C<< $class->can('init') >>
+during construction. It DOES NOT call C<can()> on the created object. Also note
+that the result of the check is cached, it is only ever checked once, the first
+time an instance of your class is created. This means that adding an C<init()>
+method AFTER the first construction will result in it being ignored.
+
+=back
+
+=head1 ACCESSORS
+
+=head2 READ/WRITE
+
+To generate accessors you list them when using the module:
+
+ use Test2::Util::HashBase qw/foo/;
+
+This will generate the following subs in your namespace:
+
+=over 4
+
+=item foo()
+
+Getter, used to get the value of the C<foo> field.
+
+=item set_foo()
+
+Setter, used to set the value of the C<foo> field.
+
+=item FOO()
+
+Constant, returns the field C<foo>'s key into the class hashref. Subclasses will
+also get this function as a constant, not simply a method, that means it is
+copied into the subclass namespace.
+
+The main reason for using these constants is to help avoid spelling mistakes
+and similar typos. It will not help you if you forget to prefix the '+' though.
+
+=back
+
+=head2 READ ONLY
+
+ use Test2::Util::HashBase qw/-foo/;
+
+=over 4
+
+=item set_foo()
+
+Throws an exception telling you the attribute is read-only. This is exported to
+override any active setters for the attribute in a parent class.
+
+=back
+
+=head2 DEPRECATED SETTER
+
+ use Test2::Util::HashBase qw/^foo/;
+
+=over 4
+
+=item set_foo()
+
+This will set the value, but it will also warn you that the method is
+deprecated.
+
+=back
+
+=head1 SUBCLASSING
+
+You can subclass an existing HashBase class.
+
+ use base 'Another::HashBase::Class';
+ use Test2::Util::HashBase qw/foo bar baz/;
+
+The base class is added to C<@ISA> for you, and all constants from base classes
+are added to subclasses automatically.
+
+=head1 GETTING A LIST OF ATTRIBUTES FOR A CLASS
+
+Test2::Util::HashBase provides a function for retrieving a list of attributes for an
+Test2::Util::HashBase class.
+
+=over 4
+
+=item @list = Test2::Util::HashBase::attr_list($class)
+
+=item @list = $class->Test2::Util::HashBase::attr_list()
+
+Either form above will work. This will return a list of attributes defined on
+the object. This list is returned in the attribute definition order, parent
+class attributes are listed before subclass attributes. Duplicate attributes
+will be removed before the list is returned.
+
+B<Note:> This list is used in the C<< $class->new(\@ARRAY) >> constructor to
+determine the attribute to which each value will be paired.
+
+=back
+
+=head1 SOURCE
+
+The source code repository for HashBase can be found at
+F<http://github.com/Test-More/HashBase/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2018 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut
diff --git a/systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/Trace.pm b/systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/Trace.pm
new file mode 100644
index 0000000000..1e5351f6db
--- /dev/null
+++ b/systems/texlive/tlnet/tlpkg/tlperl/lib/Test2/Util/Trace.pm
@@ -0,0 +1,54 @@
+package Test2::Util::Trace;
+require Test2::EventFacet::Trace;
+@ISA = ('Test2::EventFacet::Trace');
+
+our $VERSION = '1.302133';
+
+1;
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Test2::Util::Trace - Legacy wrapper fro L<Test2::EventFacet::Trace>.
+
+=head1 DESCRIPTION
+
+All the functionality for this class has been moved to
+L<Test2::EventFacet::Trace>.
+
+=head1 SOURCE
+
+The source code repository for Test2 can be found at
+F<http://github.com/Test-More/test-more/>.
+
+=head1 MAINTAINERS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 AUTHORS
+
+=over 4
+
+=item Chad Granum E<lt>exodist@cpan.orgE<gt>
+
+=back
+
+=head1 COPYRIGHT
+
+Copyright 2018 Chad Granum E<lt>exodist@cpan.orgE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://dev.perl.org/licenses/>
+
+=cut