• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

bin/H13-May-2020-15464

lib/Test/H03-May-2022-4,2141,608

t/H13-May-2020-1,7481,067

CHANGESH A D13-May-20202.1 KiB8269

INSTALLH A D13-May-20202.2 KiB7346

LICENSEH A D13-May-202011.2 KiB208172

META.jsonH A D13-May-20201.6 KiB6260

META.ymlH A D13-May-2020942 3736

Makefile.PLH A D13-May-20201.3 KiB6251

READMEH A D13-May-202016.8 KiB639405

README.mdH A D13-May-202016.2 KiB623390

cpanfileH A D13-May-2020615 2319

README

1NAME
2
3    Test::Auto - Test Automation
4
5ABSTRACT
6
7    Test Automation, Docs Generation
8
9SYNOPSIS
10
11      #!/usr/bin/env perl
12
13      use Test::Auto;
14      use Test::More;
15
16      my $test = Test::Auto->new(
17        't/Test_Auto.t'
18      );
19
20      # automation
21
22      # my $subtests = $test->subtests->standard;
23
24      # ...
25
26      # done_testing;
27
28DESCRIPTION
29
30    This package aims to provide, a standard for documenting Perl 5
31    software projects, a framework writing tests, test automation, and
32    documentation generation.
33
34REASONING
35
36    This framework lets you write documentation in test files using
37    pod-like comment blocks. By using a particular set of comment blocks
38    (the specification) this framework can run certain kinds of tests
39    automatically. For example, we can automatically ensure that the
40    package the test is associated with is loadable, that the test file
41    comment blocks meet the specification, that any super-classes or
42    libraries are loadable, and that the functions, methods, and routines
43    are properly documented.
44
45LIBRARIES
46
47    This package uses type constraints from:
48
49    Test::Auto::Types
50
51SCENARIOS
52
53    This package supports the following scenarios:
54
55 exports
56
57      use Test::Auto;
58      use Test::More;
59
60      my $subtests = testauto 't/Test_Auto.t';
61
62      # automation
63
64      # $subtests->standard;
65
66      # ...
67
68      # done_testing;
69
70    This package automatically exports the testauto function which uses the
71    "current file" as the automated testing source.
72
73ATTRIBUTES
74
75    This package has the following attributes:
76
77 data
78
79      data(Data)
80
81    This attribute is read-only, accepts (Data) values, and is optional.
82
83 file
84
85      file(Str)
86
87    This attribute is read-only, accepts (Str) values, and is required.
88
89FUNCTIONS
90
91    This package implements the following functions:
92
93 testauto
94
95      testauto(Str $file) : Subtests
96
97    This function is exported automatically and returns a
98    Test::Auto::Subtests object for the test file given.
99
100    testauto example #1
101
102        # given: synopsis
103
104        my $subtests = testauto 't/Test_Auto.t';
105
106METHODS
107
108    This package implements the following methods:
109
110 document
111
112      document() : Document
113
114    This method returns a Test::Auto::Document object.
115
116    document example #1
117
118        # given: synopsis
119
120        my $document = $test->document;
121
122 parser
123
124      parser() : Parser
125
126    This method returns a Test::Auto::Parser object.
127
128    parser example #1
129
130        # given: synopsis
131
132        my $parser = $test->parser;
133
134 subtests
135
136      subtests() : Subtests
137
138    This method returns a Test::Auto::Subtests object.
139
140    subtests example #1
141
142        # given: synopsis
143
144        my $subtests = $test->subtests;
145
146SPECIFICATION
147
148      # [required]
149
150      =name
151      =abstract
152      =tagline
153      =includes
154      =synopsis
155      =description
156
157      # [optional]
158
159      =libraries
160      =inherits
161      =integrates
162      =attributes
163
164      # [repeatable; optional]
165
166      =scenario $name
167      =example $name
168
169      # [repeatable; optional]
170
171      =method $name
172      =signature $name
173      =example-$number $name # [repeatable]
174
175      # [repeatable; optional]
176
177      =function $name
178      =signature $name
179      =example-$number $name # [repeatable]
180
181      # [repeatable; optional]
182
183      =routine $name
184      =signature $name
185      =example-$number $name # [repeatable]
186
187      # [repeatable; optional]
188
189      =type $name
190      =type-library $name
191      =type-composite $name # [optional]
192      =type-parent $name # [optional]
193      =type-coercion-$number $name # [optional]
194      =type-example-$number $name # [repeatable]
195
196    The specification is designed to accommodate typical package
197    declarations. It is used by the parser to provide the content used in
198    the test automation and document generation. Note: when code blocks are
199    evaluated "redefined" warnings are now automatically disabled.
200
201 name
202
203      =name
204
205      Path::Find
206
207      =cut
208
209    The name block should contain the package name. This is tested for
210    loadability.
211
212 tagline
213
214      =tagline
215
216      Path Finder
217
218      =cut
219
220    The tagline block should contain a tagline for the package. This is
221    optional but if present is concatenated with the name during POD
222    generation.
223
224 abstract
225
226      =abstract
227
228      Find Paths using Heuristics
229
230      =cut
231
232    The abstract block should contain a subtitle describing the package.
233    This is tested for existence.
234
235 includes
236
237      =includes
238
239      function: path
240      method: children
241      method: siblings
242      method: new
243
244      =cut
245
246    The includes block should contain a list of function, method, and/or
247    routine names in the format of $type: $name. Empty lines are ignored.
248    This is tested for existence. Each function, method, and/or routine is
249    tested to be documented properly. Also, the package must recognize that
250    each exists.
251
252 synopsis
253
254      =synopsis
255
256      use Path::Find 'path';
257
258      my $path = path; # get path using cwd
259
260      =cut
261
262    The synopsis block should contain the normative usage of the package.
263    This is tested for existence. This block should be written in a way
264    that allows it to be evaled successfully and should return a value.
265
266 description
267
268      =description
269
270      interdum posuere lorem ipsum dolor sit amet consectetur adipiscing elit duis
271      tristique sollicitudin nibh sit amet
272
273      =cut
274
275    The description block should contain a thorough explanation of the
276    purpose of the package. This is tested for existence.
277
278 libraries
279
280      =libraries
281
282      Types::Standard
283      Types::TypeTiny
284
285      =cut
286
287    The libraries block should contain a list of packages, each of which is
288    itself a Type::Library. These packages are tested for loadability, and
289    to ensure they are type library classes.
290
291 inherits
292
293      =inherits
294
295      Path::Tiny
296
297      =cut
298
299    The inherits block should contain a list of parent packages. These
300    packages are tested for loadability.
301
302 integrates
303
304      =integrates
305
306      Path::Find::Upable
307      Path::Find::Downable
308
309      =cut
310
311    The integrates block should contain a list of packages that are
312    involved in the behavior of the main package. These packages are not
313    automatically tested.
314
315 scenarios
316
317      =scenario export-path-make
318
319      quisque egestas diam in arcu cursus euismod quis viverra nibh
320
321      =example export-path-make
322
323      # given: synopsis
324
325      package main;
326
327      use Path::Find 'path_make';
328
329      path_make 'relpath/to/file';
330
331      =cut
332
333    There are situation where a package can be configured in different
334    ways, especially where it exists without functions, methods or routines
335    for the purpose of configuring the environment. The scenario directive
336    can be used to automate testing and documenting package usages and
337    configurations.Describing a scenario requires two blocks, i.e. scenario
338    $name and example $name. The scenario block should contain a
339    description of the scenario and its purpose. The example block must
340    exist when documenting a method and should contain valid Perl code and
341    return a value. The block may contain a "magic" comment in the form of
342    given: synopsis or given: example $name which if present will include
343    the given code example(s) with the evaluation of the current block.
344    Each scenario is tested and must be recognized to exist by the main
345    package.
346
347 attributes
348
349      =attributes
350
351      cwd: ro, req, Object
352
353      =cut
354
355    The attributes block should contain a list of package attributes in the
356    form of $name: $is, $presence, $type, where $is should be ro
357    (read-only) or rw (read-wire), and $presence should be req (required)
358    or opt (optional), and $type can be any valid Type::Tiny expression.
359    Each attribute declaration must be recognized to exist by the main
360    package and have a type which is recognized by one of the declared type
361    libraries.
362
363 methods
364
365      =method children
366
367      quis viverra nibh cras pulvinar mattis nunc sed blandit libero volutpat
368
369      =signature children
370
371      children() : [Object]
372
373      =example-1 children
374
375      # given: synopsis
376
377      my $children = $path->children;
378
379      =example-2 children
380
381      # given: synopsis
382
383      my $filtered = $path->children(qr/lib/);
384
385      =cut
386
387    Describing a method requires at least three blocks, i.e. method $name,
388    signature $name, and example-1 $name. The method block should contain a
389    description of the method and its purpose. The signature block should
390    contain a method signature in the form of $signature : $return_type,
391    where $signature is a valid typed signature and $return_type is any
392    valid Type::Tiny expression. The example-$number block is a repeatable
393    block, and at least one block must exist when documenting a method. The
394    example-$number block should contain valid Perl code and return a
395    value. The block may contain a "magic" comment in the form of given:
396    synopsis or given: example-$number $name which if present will include
397    the given code example(s) with the evaluation of the current block.
398    Each method is tested and must be recognized to exist by the main
399    package.
400
401 functions
402
403      =function path
404
405      lectus quam id leo in vitae turpis massa sed elementum tempus egestas
406
407      =signature children
408
409      path() : Object
410
411      =example-1 path
412
413      package Test::Path::Find;
414
415      use Path::Find;
416
417      my $path = path;
418
419      =cut
420
421    Describing a function requires at least three blocks, i.e. function
422    $name, signature $name, and example-1 $name. The function block should
423    contain a description of the function and its purpose. The signature
424    block should contain a function signature in the form of $signature :
425    $return_type, where $signature is a valid typed signature and
426    $return_type is any valid Type::Tiny expression. The example-$number
427    block is a repeatable block, and at least one block must exist when
428    documenting a function. The example-$number block should contain valid
429    Perl code and return a value. The block may contain a "magic" comment
430    in the form of given: synopsis or given: example-$number $name which if
431    present will include the given code example(s) with the evaluation of
432    the current block. Each function is tested and must be recognized to
433    exist by the main package.
434
435 routines
436
437      =routine algorithms
438
439      sed sed risus pretium quam vulputate dignissim suspendisse in est ante
440
441      =signature algorithms
442
443      algorithms() : Object
444
445      =example-1 algorithms
446
447      # given: synopsis
448
449      $path->algorithms
450
451      =example-2 algorithms
452
453      package Test::Path::Find;
454
455      use Path::Find;
456
457      Path::Find->algorithms;
458
459      =cut
460
461    Typically, a Perl subroutine is declared as a function or a method.
462    Rarely, but sometimes necessary, you will need to describe a subroutine
463    where the invocant is either a class or class instance. Describing a
464    routine requires at least three blocks, i.e. routine $name, signature
465    $name, and example-1 $name. The routine block should contain a
466    description of the routine and its purpose. The signature block should
467    contain a routine signature in the form of $signature : $return_type,
468    where $signature is a valid typed signature and $return_type is any
469    valid Type::Tiny expression. The example-$number block is a repeatable
470    block, and at least one block must exist when documenting a routine.
471    The example-$number block should contain valid Perl code and return a
472    value. The block may contain a "magic" comment in the form of given:
473    synopsis or given: example-$number $name which if present will include
474    the given code example(s) with the evaluation of the current block.
475    Each routine is tested and must be recognized to exist by the main
476    package.
477
478 types
479
480      =type Path
481
482        Path
483
484      =type-parent Path
485
486        Object
487
488      =type-library Path
489
490      Path::Types
491
492      =type-composite Path
493
494        InstanceOf["Path::Find"]
495
496      =type-coercion-1 Path
497
498        # can coerce from Str
499
500        './path/to/file'
501
502      =type-example-1 Path
503
504        require Path::Find;
505
506        Path::Find::path('./path/to/file')
507
508      =cut
509
510    When developing Perl programs, or type libraries, that use Type::Tiny
511    based type constraints, testing and documenting custom type constraints
512    is often overlooked. Describing a custom type constraint requires at
513    least two blocks, i.e. type $name and type-library $name. While it's
514    not strictly required, it's a good idea to also include at least one
515    type-example-1 $name. The optional type-parent block should contain the
516    name of the parent type. The type-composite block should contain a type
517    expression that represents the derived type. The type-coercion-$number
518    block is a repeatable block which is used to validate type coercion.
519    The type-coercion-$number block should contain valid Perl code and
520    return the value to be coerced. The type-example-$number block is a
521    repeatable block, and it's a good idea to have at least one block must
522    exist when documenting a type. The type-example-$number block should
523    contain valid Perl code and return a value. Each type is tested and
524    must be recognized to exist within the package specified by the
525    type-library block.
526
527AUTOMATION
528
529      $test->standard;
530
531    This is the equivalent of writing:
532
533      $test->package;
534      $test->document;
535      $test->libraries;
536      $test->inherits;
537      $test->attributes;
538      $test->methods;
539      $test->routines;
540      $test->functions;
541      $test->types;
542
543    This framework provides a set of automated subtests based on the
544    package specification, but not everything can be automated so it also
545    provides you with powerful hooks into the framework for manual testing.
546
547      my $subtests = $test->subtests;
548
549      $subtests->synopsis(sub {
550        my ($tryable) = @_;
551
552        ok my $result = $tryable->result, 'result ok';
553
554        $result; # for automated testing after the callback
555      });
556
557    The code examples documented can be automatically evaluated (evaled)
558    and returned using a callback you provide for further testing. Because
559    the code examples are returned as Test::Auto::Try objects (see
560    Data::Object::Try), this makes capturing and testing exceptions simple,
561    for example:
562
563      my $subtests = $test->subtests;
564
565      $subtests->synopsis(sub {
566        my ($tryable) = @_;
567
568        # catch exception thrown by the synopsis
569        $tryable->catch('Path::Find::Error', sub {
570          return $_[0];
571        });
572        # test the exception
573        ok my $result = $tryable->result, 'result ok';
574        ok $result->isa('Path::Find::Error'), 'exception caught';
575
576        $result;
577      });
578
579    Additionally, another manual testing hook (with some automation) is the
580    example method. This hook evaluates (evals) a given example and returns
581    the result as a Test::Auto::Try object (see Data::Object::Try). The
582    first argument is the example ID (or number), for example:
583
584      my $subtests = $test->subtests;
585
586      $subtests->example(-1, 'children', 'method', sub {
587        my ($tryable) = @_;
588
589        ok my $result = $tryable->result, 'result ok';
590
591        $result; # for automated testing after the callback
592      });
593
594    Finally, the lesser-used but useful manual testing hook is the scenario
595    method. This hook evaluates (evals) a documented scenario and returns
596    the result as a Test::Auto::Try object (see Data::Object::Try), for
597    example:
598
599      my $subtests = $test->subtests;
600
601      $subtests->scenario('export-path-make', sub {
602        my ($tryable) = @_;
603
604        ok my $result = $tryable->result, 'result ok';
605
606        $result; # for automated testing after the callback
607      });
608
609    The test automation and document generation enabled through this
610    framework makes it easy to maintain source/test/documentation parity.
611    This also increases reusability and reduces the need for complicated
612    state and test setup.
613
614AUTHOR
615
616    Al Newkirk, awncorp@cpan.org
617
618LICENSE
619
620    Copyright (C) 2011-2019, Al Newkirk, et al.
621
622    This is free software; you can redistribute it and/or modify it under
623    the terms of the The Apache License, Version 2.0, as elucidated in the
624    "license file"
625    <https://github.com/iamalnewkirk/test-auto/blob/master/LICENSE>.
626
627PROJECT
628
629    Wiki <https://github.com/iamalnewkirk/test-auto/wiki>
630
631    Project <https://github.com/iamalnewkirk/test-auto>
632
633    Initiatives <https://github.com/iamalnewkirk/test-auto/projects>
634
635    Milestones <https://github.com/iamalnewkirk/test-auto/milestones>
636
637    Issues <https://github.com/iamalnewkirk/test-auto/issues>
638
639

README.md

1# NAME
2
3Test::Auto - Test Automation
4
5# ABSTRACT
6
7Test Automation, Docs Generation
8
9# SYNOPSIS
10
11    #!/usr/bin/env perl
12
13    use Test::Auto;
14    use Test::More;
15
16    my $test = Test::Auto->new(
17      't/Test_Auto.t'
18    );
19
20    # automation
21
22    # my $subtests = $test->subtests->standard;
23
24    # ...
25
26    # done_testing;
27
28# DESCRIPTION
29
30This package aims to provide, a standard for documenting Perl 5 software
31projects, a framework writing tests, test automation, and documentation
32generation.
33
34# REASONING
35
36This framework lets you write documentation in test files using pod-like
37comment blocks. By using a particular set of comment blocks (the specification)
38this framework can run certain kinds of tests automatically. For example, we
39can automatically ensure that the package the test is associated with is
40loadable, that the test file comment blocks meet the specification, that any
41super-classes or libraries are loadable, and that the functions, methods, and
42routines are properly documented.
43
44# LIBRARIES
45
46This package uses type constraints from:
47
48[Test::Auto::Types](https://metacpan.org/pod/Test::Auto::Types)
49
50# SCENARIOS
51
52This package supports the following scenarios:
53
54## exports
55
56    use Test::Auto;
57    use Test::More;
58
59    my $subtests = testauto 't/Test_Auto.t';
60
61    # automation
62
63    # $subtests->standard;
64
65    # ...
66
67    # done_testing;
68
69This package automatically exports the `testauto` function which uses the
70"current file" as the automated testing source.
71
72# ATTRIBUTES
73
74This package has the following attributes:
75
76## data
77
78    data(Data)
79
80This attribute is read-only, accepts `(Data)` values, and is optional.
81
82## file
83
84    file(Str)
85
86This attribute is read-only, accepts `(Str)` values, and is required.
87
88# FUNCTIONS
89
90This package implements the following functions:
91
92## testauto
93
94    testauto(Str $file) : Subtests
95
96This function is exported automatically and returns a [Test::Auto::Subtests](https://metacpan.org/pod/Test::Auto::Subtests)
97object for the test file given.
98
99- testauto example #1
100
101        # given: synopsis
102
103        my $subtests = testauto 't/Test_Auto.t';
104
105# METHODS
106
107This package implements the following methods:
108
109## document
110
111    document() : Document
112
113This method returns a [Test::Auto::Document](https://metacpan.org/pod/Test::Auto::Document) object.
114
115- document example #1
116
117        # given: synopsis
118
119        my $document = $test->document;
120
121## parser
122
123    parser() : Parser
124
125This method returns a [Test::Auto::Parser](https://metacpan.org/pod/Test::Auto::Parser) object.
126
127- parser example #1
128
129        # given: synopsis
130
131        my $parser = $test->parser;
132
133## subtests
134
135    subtests() : Subtests
136
137This method returns a [Test::Auto::Subtests](https://metacpan.org/pod/Test::Auto::Subtests) object.
138
139- subtests example #1
140
141        # given: synopsis
142
143        my $subtests = $test->subtests;
144
145# SPECIFICATION
146
147    # [required]
148
149    =name
150    =abstract
151    =tagline
152    =includes
153    =synopsis
154    =description
155
156    # [optional]
157
158    =libraries
159    =inherits
160    =integrates
161    =attributes
162
163    # [repeatable; optional]
164
165    =scenario $name
166    =example $name
167
168    # [repeatable; optional]
169
170    =method $name
171    =signature $name
172    =example-$number $name # [repeatable]
173
174    # [repeatable; optional]
175
176    =function $name
177    =signature $name
178    =example-$number $name # [repeatable]
179
180    # [repeatable; optional]
181
182    =routine $name
183    =signature $name
184    =example-$number $name # [repeatable]
185
186    # [repeatable; optional]
187
188    =type $name
189    =type-library $name
190    =type-composite $name # [optional]
191    =type-parent $name # [optional]
192    =type-coercion-$number $name # [optional]
193    =type-example-$number $name # [repeatable]
194
195The specification is designed to accommodate typical package declarations. It
196is used by the parser to provide the content used in the test automation and
197document generation. Note: when code blocks are evaluated _"redefined"_
198warnings are now automatically disabled.
199
200## name
201
202    =name
203
204    Path::Find
205
206    =cut
207
208The `name` block should contain the package name. This is tested for
209loadability.
210
211## tagline
212
213    =tagline
214
215    Path Finder
216
217    =cut
218
219The `tagline` block should contain a tagline for the package. This is optional
220but if present is concatenated with the `name` during POD generation.
221
222## abstract
223
224    =abstract
225
226    Find Paths using Heuristics
227
228    =cut
229
230The `abstract` block should contain a subtitle describing the package. This is
231tested for existence.
232
233## includes
234
235    =includes
236
237    function: path
238    method: children
239    method: siblings
240    method: new
241
242    =cut
243
244The `includes` block should contain a list of `function`, `method`, and/or
245`routine` names in the format of `$type: $name`. Empty lines are ignored.
246This is tested for existence. Each function, method, and/or routine is tested
247to be documented properly. Also, the package must recognize that each exists.
248
249## synopsis
250
251    =synopsis
252
253    use Path::Find 'path';
254
255    my $path = path; # get path using cwd
256
257    =cut
258
259The `synopsis` block should contain the normative usage of the package. This
260is tested for existence. This block should be written in a way that allows it
261to be evaled successfully and should return a value.
262
263## description
264
265    =description
266
267    interdum posuere lorem ipsum dolor sit amet consectetur adipiscing elit duis
268    tristique sollicitudin nibh sit amet
269
270    =cut
271
272The `description` block should contain a thorough explanation of the purpose
273of the package. This is tested for existence.
274
275## libraries
276
277    =libraries
278
279    Types::Standard
280    Types::TypeTiny
281
282    =cut
283
284The `libraries` block should contain a list of packages, each of which is
285itself a [Type::Library](https://metacpan.org/pod/Type::Library). These packages are tested for loadability, and to
286ensure they are type library classes.
287
288## inherits
289
290    =inherits
291
292    Path::Tiny
293
294    =cut
295
296The `inherits` block should contain a list of parent packages. These packages
297are tested for loadability.
298
299## integrates
300
301    =integrates
302
303    Path::Find::Upable
304    Path::Find::Downable
305
306    =cut
307
308The `integrates` block should contain a list of packages that are involved in
309the behavior of the main package. These packages are not automatically tested.
310
311## scenarios
312
313    =scenario export-path-make
314
315    quisque egestas diam in arcu cursus euismod quis viverra nibh
316
317    =example export-path-make
318
319    # given: synopsis
320
321    package main;
322
323    use Path::Find 'path_make';
324
325    path_make 'relpath/to/file';
326
327    =cut
328
329There are situation where a package can be configured in different ways,
330especially where it exists without functions, methods or routines for the
331purpose of configuring the environment. The scenario directive can be used to
332automate testing and documenting package usages and configurations.Describing a
333scenario requires two blocks, i.e. `scenario $name` and `example $name`. The
334`scenario` block should contain a description of the scenario and its purpose.
335The `example` block must exist when documenting a method and should contain
336valid Perl code and return a value. The block may contain a "magic" comment in
337the form of `given: synopsis` or `given: example $name` which if present will
338include the given code example(s) with the evaluation of the current block.
339Each scenario is tested and must be recognized to exist by the main package.
340
341## attributes
342
343    =attributes
344
345    cwd: ro, req, Object
346
347    =cut
348
349The `attributes` block should contain a list of package attributes in the form
350of `$name: $is, $presence, $type`, where `$is` should be `ro` (read-only) or
351`rw` (read-wire), and `$presence` should be `req` (required) or `opt`
352(optional), and `$type` can be any valid [Type::Tiny](https://metacpan.org/pod/Type::Tiny) expression. Each
353attribute declaration must be recognized to exist by the main package and have
354a type which is recognized by one of the declared type libraries.
355
356## methods
357
358    =method children
359
360    quis viverra nibh cras pulvinar mattis nunc sed blandit libero volutpat
361
362    =signature children
363
364    children() : [Object]
365
366    =example-1 children
367
368    # given: synopsis
369
370    my $children = $path->children;
371
372    =example-2 children
373
374    # given: synopsis
375
376    my $filtered = $path->children(qr/lib/);
377
378    =cut
379
380Describing a method requires at least three blocks, i.e. `method $name`,
381`signature $name`, and `example-1 $name`. The `method` block should contain
382a description of the method and its purpose. The `signature` block should
383contain a method signature in the form of `$signature : $return_type`, where
384`$signature` is a valid typed signature and `$return_type` is any valid
385[Type::Tiny](https://metacpan.org/pod/Type::Tiny) expression. The `example-$number` block is a repeatable block,
386and at least one block must exist when documenting a method. The
387`example-$number` block should contain valid Perl code and return a value. The
388block may contain a "magic" comment in the form of `given: synopsis` or
389`given: example-$number $name` which if present will include the given code
390example(s) with the evaluation of the current block. Each method is tested and
391must be recognized to exist by the main package.
392
393## functions
394
395    =function path
396
397    lectus quam id leo in vitae turpis massa sed elementum tempus egestas
398
399    =signature children
400
401    path() : Object
402
403    =example-1 path
404
405    package Test::Path::Find;
406
407    use Path::Find;
408
409    my $path = path;
410
411    =cut
412
413Describing a function requires at least three blocks, i.e. `function $name`,
414`signature $name`, and `example-1 $name`. The `function` block should
415contain a description of the function and its purpose. The `signature` block
416should contain a function signature in the form of `$signature :
417$return_type`, where `$signature` is a valid typed signature and
418`$return_type` is any valid [Type::Tiny](https://metacpan.org/pod/Type::Tiny) expression. The `example-$number`
419block is a repeatable block, and at least one block must exist when documenting
420a function. The `example-$number` block should contain valid Perl code and
421return a value. The block may contain a "magic" comment in the form of `given:
422synopsis` or `given: example-$number $name` which if present will include the
423given code example(s) with the evaluation of the current block. Each function
424is tested and must be recognized to exist by the main package.
425
426## routines
427
428    =routine algorithms
429
430    sed sed risus pretium quam vulputate dignissim suspendisse in est ante
431
432    =signature algorithms
433
434    algorithms() : Object
435
436    =example-1 algorithms
437
438    # given: synopsis
439
440    $path->algorithms
441
442    =example-2 algorithms
443
444    package Test::Path::Find;
445
446    use Path::Find;
447
448    Path::Find->algorithms;
449
450    =cut
451
452Typically, a Perl subroutine is declared as a function or a method. Rarely, but
453sometimes necessary, you will need to describe a subroutine where the invocant
454is either a class or class instance. Describing a routine requires at least
455three blocks, i.e. `routine $name`, `signature $name`, and `example-1
456$name`. The `routine` block should contain a description of the routine and
457its purpose. The `signature` block should contain a routine signature in the
458form of `$signature : $return_type`, where `$signature` is a valid typed
459signature and `$return_type` is any valid [Type::Tiny](https://metacpan.org/pod/Type::Tiny) expression. The
460`example-$number` block is a repeatable block, and at least one block must
461exist when documenting a routine. The `example-$number` block should contain
462valid Perl code and return a value. The block may contain a "magic" comment in
463the form of `given: synopsis` or `given: example-$number $name` which if
464present will include the given code example(s) with the evaluation of the
465current block. Each routine is tested and must be recognized to exist by the
466main package.
467
468## types
469
470    =type Path
471
472      Path
473
474    =type-parent Path
475
476      Object
477
478    =type-library Path
479
480    Path::Types
481
482    =type-composite Path
483
484      InstanceOf["Path::Find"]
485
486    =type-coercion-1 Path
487
488      # can coerce from Str
489
490      './path/to/file'
491
492    =type-example-1 Path
493
494      require Path::Find;
495
496      Path::Find::path('./path/to/file')
497
498    =cut
499
500When developing Perl programs, or type libraries, that use [Type::Tiny](https://metacpan.org/pod/Type::Tiny) based
501type constraints, testing and documenting custom type constraints is often
502overlooked. Describing a custom type constraint requires at least two blocks,
503i.e. `type $name` and `type-library $name`. While it's not strictly required,
504it's a good idea to also include at least one `type-example-1 $name`. The
505optional `type-parent` block should contain the name of the parent type. The
506`type-composite` block should contain a type expression that represents the
507derived type. The `type-coercion-$number` block is a repeatable block which
508is used to validate type coercion. The `type-coercion-$number` block should
509contain valid Perl code and return the value to be coerced. The
510`type-example-$number` block is a repeatable block, and it's a good idea to
511have at least one block must exist when documenting a type. The
512`type-example-$number` block should contain valid Perl code and return a
513value. Each type is tested and must be recognized to exist within the package
514specified by the `type-library` block.
515
516# AUTOMATION
517
518    $test->standard;
519
520This is the equivalent of writing:
521
522    $test->package;
523    $test->document;
524    $test->libraries;
525    $test->inherits;
526    $test->attributes;
527    $test->methods;
528    $test->routines;
529    $test->functions;
530    $test->types;
531
532This framework provides a set of automated subtests based on the package
533specification, but not everything can be automated so it also provides you with
534powerful hooks into the framework for manual testing.
535
536    my $subtests = $test->subtests;
537
538    $subtests->synopsis(sub {
539      my ($tryable) = @_;
540
541      ok my $result = $tryable->result, 'result ok';
542
543      $result; # for automated testing after the callback
544    });
545
546The code examples documented can be automatically evaluated (evaled) and
547returned using a callback you provide for further testing. Because the code
548examples are returned as `Test::Auto::Try` objects (see [Data::Object::Try](https://metacpan.org/pod/Data::Object::Try)),
549this makes capturing and testing exceptions simple, for example:
550
551    my $subtests = $test->subtests;
552
553    $subtests->synopsis(sub {
554      my ($tryable) = @_;
555
556      # catch exception thrown by the synopsis
557      $tryable->catch('Path::Find::Error', sub {
558        return $_[0];
559      });
560      # test the exception
561      ok my $result = $tryable->result, 'result ok';
562      ok $result->isa('Path::Find::Error'), 'exception caught';
563
564      $result;
565    });
566
567Additionally, another manual testing hook (with some automation) is the
568`example` method. This hook evaluates (evals) a given example and returns the
569result as a `Test::Auto::Try` object (see [Data::Object::Try](https://metacpan.org/pod/Data::Object::Try)). The first
570argument is the example ID (or number), for example:
571
572    my $subtests = $test->subtests;
573
574    $subtests->example(-1, 'children', 'method', sub {
575      my ($tryable) = @_;
576
577      ok my $result = $tryable->result, 'result ok';
578
579      $result; # for automated testing after the callback
580    });
581
582Finally, the lesser-used but useful manual testing hook is the `scenario`
583method. This hook evaluates (evals) a documented scenario and returns the
584result as a `Test::Auto::Try` object (see [Data::Object::Try](https://metacpan.org/pod/Data::Object::Try)), for example:
585
586    my $subtests = $test->subtests;
587
588    $subtests->scenario('export-path-make', sub {
589      my ($tryable) = @_;
590
591      ok my $result = $tryable->result, 'result ok';
592
593      $result; # for automated testing after the callback
594    });
595
596The test automation and document generation enabled through this framework
597makes it easy to maintain source/test/documentation parity. This also
598increases reusability and reduces the need for complicated state and test setup.
599
600# AUTHOR
601
602Al Newkirk, `awncorp@cpan.org`
603
604# LICENSE
605
606Copyright (C) 2011-2019, Al Newkirk, et al.
607
608This is free software; you can redistribute it and/or modify it under the terms
609of the The Apache License, Version 2.0, as elucidated in the
610["license file"](https://github.com/iamalnewkirk/test-auto/blob/master/LICENSE).
611
612# PROJECT
613
614[Wiki](https://github.com/iamalnewkirk/test-auto/wiki)
615
616[Project](https://github.com/iamalnewkirk/test-auto)
617
618[Initiatives](https://github.com/iamalnewkirk/test-auto/projects)
619
620[Milestones](https://github.com/iamalnewkirk/test-auto/milestones)
621
622[Issues](https://github.com/iamalnewkirk/test-auto/issues)
623