.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" ======================================================================== .\" .IX Title "Test2::Manual::Tooling::Formatter 3pm" .TH Test2::Manual::Tooling::Formatter 3pm "2019-05-06" "perl v5.24.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Test2::Manual::Tooling::Formatter \- How to write a custom formatter, in our case a JSONL formatter. .SH "DESCRIPTION" .IX Header "DESCRIPTION" This tutorial explains a minimal formatter that outputs each event as a json string on its own line. A true formatter will probably be significantly more complicated, but this will give you the basics needed to get started. .SH "COMPLETE CODE UP FRONT" .IX Header "COMPLETE CODE UP FRONT" .Vb 3 \& package Test2::Formatter::MyFormatter; \& use strict; \& use warnings; \& \& use JSON::MaybeXS qw/encode_json/; \& \& use base qw/Test2::Formatter/; \& \& sub new { bless {}, shift } \& \& sub encoding {}; \& \& sub write { \& my ($self, $e, $num, $f) = @_; \& $f ||= $e\->facet_data; \& \& print encode_json($f), "\en"; \& } \& \& 1; .Ve .SH "LINE BY LINE" .IX Header "LINE BY LINE" .IP "use base qw/Test2::Formatter/;" 4 .IX Item "use base qw/Test2::Formatter/;" All formatters should inherit from Test2::Formatter. .IP "sub new { bless {}, shift }" 4 .IX Item "sub new { bless {}, shift }" Formatters need to be instantiable objects, this is a minimal \f(CW\*(C`new()\*(C'\fR method. .IP "sub encoding {};" 4 .IX Item "sub encoding {};" For this example we leave this sub empty. In general you should implement this sub to make sure you honor situations where the encoding is set. Test2::V0 itself will try to set the encoding to \s-1UTF8.\s0 .IP "sub write { ... }" 4 .IX Item "sub write { ... }" The \f(CW\*(C`write()\*(C'\fR method is the most important, each event is sent here. .ie n .IP "my ($self, $e, $num, $f) = @_;" 4 .el .IP "my ($self, \f(CW$e\fR, \f(CW$num\fR, \f(CW$f\fR) = \f(CW@_\fR;" 4 .IX Item "my ($self, $e, $num, $f) = @_;" The \f(CW\*(C`write()\*(C'\fR method receives 3 or 4 arguments, the fourth is optional. .RS 4 .ie n .IP "$self" 4 .el .IP "\f(CW$self\fR" 4 .IX Item "$self" The formatter itself. .ie n .IP "$e" 4 .el .IP "\f(CW$e\fR" 4 .IX Item "$e" The event being written .ie n .IP "$num" 4 .el .IP "\f(CW$num\fR" 4 .IX Item "$num" The most recent assertion number. If the event being processed is an assertion then this will have been bumped by 1 since the last call to write. For non assertions this number is set to the most recent assertion. .ie n .IP "$f" 4 .el .IP "\f(CW$f\fR" 4 .IX Item "$f" This \s-1MAY\s0 be a hashref containing all the facet data from the event. More often then not this will be undefined. This is only set if the facet data was needed by the hub, and it usually is not. .RE .RS 4 .RE .ie n .IP "$f ||= $e\->facet_data;" 4 .el .IP "\f(CW$f\fR ||= \f(CW$e\fR\->facet_data;" 4 .IX Item "$f ||= $e->facet_data;" We want to dump the event facet data. This will set \f(CW$f\fR to the facet data unless we already have the facet data. .ie n .IP "print encode_json($f), ""\en"";" 4 .el .IP "print encode_json($f), ``\en'';" 4 .IX Item "print encode_json($f), n;" This line prints the \s-1JSON\s0 encoded facet data, and a newline. .SH "SEE ALSO" .IX Header "SEE ALSO" Test2::Manual \- Primary index of the manual. .SH "SOURCE" .IX Header "SOURCE" The source code repository for Test2\-Manual can be found at \&\fIhttps://github.com/Test\-More/Test2\-Suite/\fR. .SH "MAINTAINERS" .IX Header "MAINTAINERS" .IP "Chad Granum " 4 .IX Item "Chad Granum " .SH "AUTHORS" .IX Header "AUTHORS" .PD 0 .IP "Chad Granum " 4 .IX Item "Chad Granum " .PD .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright 2018 Chad Granum . .PP This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. .PP See \fIhttp://dev.perl.org/licenses/\fR