File Coverage

blib/lib/TAP/Formatter/EARL.pm
Criterion Covered Total %
statement 63 64 98.4
branch 2 4 50.0
condition n/a
subroutine 21 21 100.0
pod 2 2 100.0
total 88 91 96.7


line stmt bran cond sub pod time code
1             package TAP::Formatter::EARL;
2              
3 2     2   1293 use 5.010001;
  2         7  
4 2     2   10 use strict;
  2         14  
  2         38  
5 2     2   9 use warnings;
  2         3  
  2         104  
6              
7              
8             our $AUTHORITY = 'cpan:KJETILK';
9             our $VERSION = '0.001';
10              
11 2     2   910 use Moo;
  2         16679  
  2         9  
12 2     2   3918 use Data::Dumper;
  2         11212  
  2         134  
13              
14 2     2   808 use TAP::Formatter::EARL::Session;
  2         6  
  2         72  
15 2     2   13 use Types::Standard qw(ConsumerOf);
  2         3  
  2         13  
16 2     2   1188 use Types::Namespace qw( Namespace NamespaceMap );
  2         4  
  2         10  
17 2     2   722 use Attean;
  2         4  
  2         12  
18 2     2   40 use Attean::RDF;
  2         3  
  2         11  
19 2     2   1398 use Types::Attean qw(AtteanIRI to_AtteanIRI);
  2         4  
  2         11  
20 2     2   1465 use MooX::Attribute::ENV;
  2         1354  
  2         11  
21 2     2   1130 use Types::DateTime -all;
  2         35696  
  2         24  
22 2     2   8863 use Carp qw(croak);
  2         5  
  2         1190  
23              
24             extends qw(
25             TAP::Formatter::Console
26             );
27              
28             has model => (is => 'rw',
29             isa => ConsumerOf['Attean::API::MutableModel'],
30             builder => '_build_model');
31              
32             sub _build_model {
33 1     1   5168 my $self = shift;
34 1         9 return Attean->temporary_model;
35             }
36              
37             has ns => (
38             is => "ro",
39             isa => NamespaceMap,
40             builder => '_build_ns'
41             );
42              
43             sub _build_ns {
44 1     1   40487 my $self = shift;
45 1         13 return URI::NamespaceMap->new( [ 'rdf', 'dc', 'earl', 'doap' ] );
46             }
47              
48             has graph_name => (
49             is => "rw",
50             isa => AtteanIRI,
51             coerce => 1,
52             env_prefix => 'earl',
53             default => sub {'http://example.test/graph'});
54              
55             has base => (
56             is => "rw",
57             isa => AtteanIRI,
58             coerce => 1,
59             predicate => 'has_base',
60             env_prefix => 'earl'
61             );
62              
63              
64             has _test_time => (
65             is => 'ro',
66             isa => DateTime,
67             coerce => 1,
68             default => sub { return "now" }
69             );
70              
71             has [qw(software_prefix result_prefix assertion_prefix)] => (
72             is => "lazy",
73             isa => Namespace,
74             coerce => 1,
75             required => 1,
76             env_prefix => 'earl'
77             );
78              
79             sub _build_software_prefix {
80 1     1   23 return 'script#';
81             }
82              
83             sub _build_result_prefix {
84 1     1   35 my $self = shift;
85 1         10 return 'result/' . $self->_test_time . '#';
86             }
87              
88             sub _build_assertion_prefix {
89 1     1   500 my $self = shift;
90 1         7 return 'assertion/' . $self->_test_time . '#';
91             }
92              
93              
94              
95              
96             sub open_test {
97 1     1 1 46783 my ($self, $script, $parser) = @_;
98 1         32 my $giri = $self->graph_name;
99 1         10 my $ns = $self->ns;
100 1         16 my $siri = to_AtteanIRI($self->software_prefix->iri('script-' . $script));
101 1         1159 $self->model->add_quad(quad($siri, to_AtteanIRI($ns->rdf->type), to_AtteanIRI($ns->earl->Software), $giri));
102 1         8265 $self->model->add_quad(quad($siri, to_AtteanIRI($ns->doap->name), literal($script), $giri));
103             # TODO: Add richer metadata, pointer to software, with seeAlso
104             # $self->model->add_quad(quad($siri, to_AtteanIRI($ns->doap->release), blank('rev'), $giri));
105             # $self->model->add_quad(quad(blank('rev'), to_AtteanIRI($ns->doap->revision), literal($VERSION), $giri));
106              
107 1         7017 return TAP::Formatter::EARL::Session->new(model => $self->model,
108             software_uri => $siri,
109             result_prefix => $self->result_prefix,
110             assertion_prefix => $self->assertion_prefix,
111             ns => $self->ns,
112             graph_name => $giri
113             )
114             }
115              
116             sub summary {
117 1     1 1 6030 my $self = shift;
118 1         7 my $s = Attean->get_serializer('Turtle')->new(namespaces => $self->ns);
119 1 50       60855 open(my $fh, ">-:encoding(UTF-8)") || croak "Could not open STDOUT";
120 1 50       8 if ($self->has_base) {
121 0         0 print $fh '@base <' . $self->base->as_string . "> .\n"; # TODO, the URLs are probably not interpreted as relative
122             }
123 1         21 $s->serialize_iter_to_io( $fh, $self->model->get_quads);
124 1         16987 close $fh;
125             }
126              
127             1;
128              
129             __END__
130              
131             =pod
132              
133             =encoding utf-8
134              
135             =head1 NAME
136              
137             TAP::Formatter::EARL - Formatting TAP output using the Evaluation and Report Language
138              
139             =head1 SYNOPSIS
140              
141             Use on the command line:
142              
143             prove --formatter TAP::Formatter::EARL -l
144              
145             =head1 DESCRIPTION
146              
147             This is a formatter for TAP-based test results to output them using
148             the L<Evaluation and Report
149             Language|https://www.w3.org/TR/EARL10-Guide/>, which is a vocabulary
150             based on the Resource Description Framework (RDF) to describe test
151             results, so that they can be shared, for example as part of an audit.
152              
153             This module has a number of attributes, but they are all optional, as
154             they have reasonable defaults. Many of them can be set using
155             environment variables. It further extends L<TAP::Formatter::Console>.
156              
157             =head2 Attributes
158              
159             =over
160              
161             =item * C<< model >>
162              
163             An L<Attean> mutable model that will contain the generated RDF
164             triples. A temporary model is used by default.
165              
166             =item * C<< ns >>
167              
168             A L<URI::NamespaceMap> object. This can be used internally in
169             programming with prefixes, and to abbreviate using the given prefixes
170             in serializations. It is initialized by default with the prefixes used
171             internally.
172              
173             =item * C<< graph_name >>
174              
175             An L<Attean::IRI> to use as graph name for all triples. In normal
176             operations, the formatter will not use the graph name, and so the
177             default is set to C<http://example.test/graph>. Normal coercions
178             apply.
179              
180             It can be set using the environment variable C<EARL_GRAPH_NAME>.
181              
182             =item * C<< base >>
183              
184             An L<Attean::IRI> to use as the base URI for relative URIs in the
185             serialized output. The default is no base. Normal coercions apply.
186              
187             It can be set using the environment variable C<EARL_BASE>.
188              
189             =item * C<< software_prefix >>, C<< assertion_prefix >>, C<< result_prefix >>
190              
191             Prefixes for URIs of the script running the test, the assertion that a
192             certain result has been found, and the result itself, respectively.
193              
194             They accept a L<URI::Namespace> object. They have relative URIs as
195             defaults. These will not be set as a prefix in the serializer. Normal
196             coercions apply.
197              
198             They can be set using environment variables, C<EARL_SOFTWARE_PREFIX>,
199             C<EARL_ASSERTION_PREFIX> and C<EARL_RESULT_PREFIX>, respectively.
200              
201             =back
202              
203             =head2 Methods
204              
205             These methods are specialised implementations of methods in the
206             superclass L<TAP::Formatter::Base>.
207              
208             =over
209              
210             =item * C<< open_test >>
211              
212             This is called to create a new test session. It first describes the
213             software used in RDF before calling L<TAP::Formatter::EARL::Session>.
214              
215             =item * C<< summary >>
216              
217             Serializes the model to Turtle and prints it to STDOUT.
218              
219             =back
220              
221              
222             =head1 TODO
223              
224             This is a rudimentary first release, it will only make use of data
225             parsed from each individual test result.
226              
227             EARL reports can be extended to become a part of an extensive Linked
228             Data cloud. It can also link to tests as formulated by
229             e.g. L<Test::FITesque::RDF>.
230              
231             =head1 BUGS
232              
233             Please report any bugs to
234             L<https://github.com/kjetilk/p5-tap-formatter-earl/issues>.
235              
236             =head1 SEE ALSO
237              
238             =head1 AUTHOR
239              
240             Kjetil Kjernsmo E<lt>kjetilk@cpan.orgE<gt>.
241              
242             =head1 COPYRIGHT AND LICENCE
243              
244             This software is copyright (c) 2019 by Inrupt Inc
245              
246             This is free software, licensed under:
247              
248             The MIT (X11) License
249              
250              
251             =head1 DISCLAIMER OF WARRANTIES
252              
253             THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
254             WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
255             MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
256