This file is indexed.

/usr/share/perl5/Test2/Workflow.pm is in libtest2-suite-perl 0.000102-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
package Test2::Workflow;
use strict;
use warnings;

our $VERSION = '0.000102';

our @EXPORT_OK = qw/parse_args current_build build root_build init_root build_stack/;
use base 'Exporter';

use Test2::Workflow::Build;
use Test2::Workflow::Task::Group;
use Test2::API qw/intercept/;
use Scalar::Util qw/blessed/;

sub parse_args {
    my %input = @_;
    my $args = delete $input{args};
    my %out;
    my %props;

    my $caller = $out{frame} = $input{caller} || caller(defined $input{level} ? $input{level} : 1);
    delete @input{qw/caller level/};

    for my $arg (@$args) {
        if (my $r = ref($arg)) {
            if ($r eq 'HASH') {
                %props = (%props, %$arg);
            }
            elsif ($r eq 'CODE') {
                die "Code is already set, did you provide multiple code blocks at $caller->[1] line $caller->[2].\n"
                    if $out{code};

                $out{code} = $arg
            }
            else {
                die "Not sure what to do with $arg at $caller->[1] line $caller->[2].\n";
            }
            next;
        }

        if ($arg =~ m/^\d+$/) {
            push @{$out{lines}} => $arg;
            next;
        }

        die "Name is already set to '$out{name}', cannot set to '$arg', did you specify multiple names at $caller->[1] line $caller->[2].\n"
            if $out{name};

        $out{name} = $arg;
    }

    die "a name must be provided, and must be truthy at $caller->[1] line $caller->[2].\n"
        unless $out{name};

    die "a codeblock must be provided at $caller->[1] line $caller->[2].\n"
        unless $out{code};

    return { %props, %out, %input };
}

{
    my %ROOT_BUILDS;
    my @BUILD_STACK;

    sub root_build    { $ROOT_BUILDS{$_[0]} }
    sub current_build { @BUILD_STACK ? $BUILD_STACK[-1] : undef }
    sub build_stack   { @BUILD_STACK }

    sub init_root {
        my ($pkg, %args) = @_;
        $ROOT_BUILDS{$pkg} ||= Test2::Workflow::Build->new(
            name    => $pkg,
            flat    => 1,
            iso     => 0,
            async   => 0,
            is_root => 1,
            %args,
        );

        return $ROOT_BUILDS{$pkg};
    }

    sub build {
        my %params = @_;
        my $args = parse_args(%params);

        my $build = Test2::Workflow::Build->new(%$args);

        return $build if $args->{skip};

        push @BUILD_STACK => $build;

        my ($ok, $err);
        my $events = intercept {
            my $todo = $args->{todo} ? Test2::Todo->new(reason => $args->{todo}) : undef;
            $ok = eval { $args->{code}->(); 1 };
            $err = $@;
            $todo->end if $todo;
        };

        # Clear the stash
        $build->{stash} = [];
        $build->set_events($events);

        pop @BUILD_STACK;

        unless($ok) {
            my $hub = Test2::API::test2_stack->top;
            my $count = @$events;
            my $list = $count
                ? "Overview of unseen events:\n" . join "" => map "    " . blessed($_) . " " . $_->trace->debug . "\n", @$events
                : "";
            die <<"            EOT";
Exception in build '$args->{name}' with $count unseen event(s).
$err
$list
            EOT
        }

        return $build;
    }
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Test2::Workflow - A test workflow is a way of structuring tests using
composable units.

=head1 DESCRIPTION

A test workflow is a way of structuring tests using composable units. A well
known example of a test workflow is L<RSPEC|http://rspec.info/>. RSPEC is
implemented using Test2::Workflow in L<Test2::Tools::Spec> along with several
extensions.

=head1 IMPORTANT CONCEPTS

=head2 BUILD

L<Test2::Workflow::Build>

A Build is used to compose tasks. Usually a build object is pushed to the stack
before running code that adds tasks to the build. Once the build sub is
complete the build is popped and returned. Usually a build is converted into a
root task or task group.

=head2 RUNNER

L<Test2::Workflow::Runner>

A runner takes the composed tasks and executes them in the proper order.

=head2 TASK

L<Test2::Workflow::Task>

A task is a unit of work to accomplish. There are 2 main types of task.

=head3 ACTION

An action is the most simple unit used in composition. An action is essentially
a name and a codeblock to run.

=head3 GROUP

A group is a task that is composed of other tasks.

=head1 EXPORTS

All exports are optional, you must request the ones you want.

=over 4

=item $parsed = parse_args(args => \@args)

=item $parsed = parse_args(args => \@args, level => $L)

=item $parsed = parse_args(args => \@args, caller => [caller($L)])

This will parse a "typical" task builders arguments. The C<@args> array MUST
contain a name (plain scalar containing text) and also a single CODE reference.
The C<@args> array MAY also contain any quantity of line numbers or hashrefs.
The resulting data structure will be a single hashref with all the provided
hashrefs squashed together, and the 'name', 'code', 'lines' and 'frame' keys
set from other arguments.

    {
        # All hashrefs from @args get squashed together:
        %squashed_input_hashref_data,

        # @args must have exactly 1 plaintext scalar that is not a number, it
        # is considered the name:
        name => 'name from input args'

        # Integer values are treated as line numbers
        lines => [ 35, 44 ],

        # Exactly 1 coderef must be provided in @args:
        code => \&some_code,

        # 'frame' contains the 'caller' data. This may be passed in directly,
        # obtained from the 'level' parameter, or automatically deduced.
        frame => ['A::Package', 'a_file.pm', 42, ...],
    }

=item $build = init_root($pkg, %args)

This will initialize (or return the existing) a build for the specified
package. C<%args> get passed into the L<Test2::Workflow::Build> constructor.
This uses the following defaults (which can be overridden using C<%args>):

    name    => $pkg,
    flat    => 1,
    iso     => 0,
    async   => 0,
    is_root => 1,

Note that C<%args> is completely ignored if the package build has already been
initialized.

=item $build = root_build($pkg)

This will return the root build for the specified package.

=item $build = current_build()

This will return the build currently at the top of the build stack (or undef).

=item $build = build($name, \%params, sub { ... })

This will push a new build object onto the build stash then run the provided
codeblock. Once the codeblock has finished running the build will be popped off
the stack and returned.

See C<parse_args()> for details about argument processing.

=back

=head1 SEE ALSO

=over 4

=item Test2::Tools::Spec

L<Test2::Tools::Spec> is an implementation of RSPEC using this library.

=back

=head1 SOURCE

The source code repository for Test2-Workflow can be found at
F<https://github.com/Test-More/Test2-Suite/>.

=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 2016 Chad Granum E<lt>exodist7@gmail.comE<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