File Coverage

blib/lib/Test/Auto.pm
Criterion Covered Total %
statement 46 46 100.0
branch 1 2 50.0
condition n/a
subroutine 15 15 100.0
pod 4 5 80.0
total 66 68 97.0


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