File Coverage

blib/lib/Scientist.pm
Criterion Covered Total %
statement 46 46 100.0
branch 16 16 100.0
condition n/a
subroutine 10 10 100.0
pod 4 4 100.0
total 76 76 100.0


line stmt bran cond sub pod time code
1             ## no critic (Miscellanea::ProhibitUnrestrictedNoCritic, ValuesAndExpressions::ProhibitVersionStrings)
2             package Scientist;
3              
4 8     8   1764717 use Moo;
  8         90641  
  8         43  
5 8     8   11560 use Test2::Compare v0.0.121 qw/compare strict_convert/;
  8         177  
  8         500  
6 8     8   4254 use Time::HiRes qw/time/;
  8         11009  
  8         40  
7 8     8   6162 use Types::Standard qw/Bool Str CodeRef HashRef/;
  8         584785  
  8         86  
8              
9             our $VERSION = '0.013'; # TRIAL VERSION
10              
11             # ABSTRACT: Perl module inspired by https://github.com/github/scientist
12             # https://github.com/lancew/Scientist
13              
14             has 'context' => (
15             is => 'rw',
16             isa => HashRef,
17             );
18              
19             has 'enabled' => (
20             is => 'rw',
21             isa => Bool,
22             default => 1,
23             );
24              
25             has 'experiment' => (
26             is => 'ro',
27             isa => Str,
28             builder => 'name',
29             );
30              
31             has 'use' => (
32             is => 'rw',
33             isa => CodeRef,
34             );
35              
36             has 'result' => (
37             is => 'rw',
38             isa => HashRef,
39             );
40              
41             has 'try' => (
42             is => 'rw',
43             isa => CodeRef,
44             );
45              
46             sub name {
47 13     13 1 71470 return 'experiment';
48             }
49              
50             sub publish {
51 1009     1009 1 1478 my $self = shift;
52             # Stub publish sub, extend this to enable your own own
53             # unique publishing requirements
54 1009         1458 return;
55             }
56              
57             sub run {
58 1014     1014 1 5633 my $self = shift;
59              
60             # If experiment not enabled just return the control code results.
61 1014 100       17638 return $self->use->() unless $self->enabled;
62              
63 1011         20232 my %result = (
64             context => $self->context,
65             experiment => $self->experiment,
66             );
67              
68 1011         7054 my $wantarray = wantarray;
69              
70 1011         1517 my ( @control, @candidate );
71             my $run_control = sub {
72 1011     1011   1997 my $start = time;
73 1011 100       17048 @control = $wantarray ? $self->use->() : scalar $self->use->();
74 1010         8828 $result{control}{duration} = time - $start;
75 1011         3916 };
76              
77             my $run_candidate = sub {
78 1011     1011   1971 my $start = time;
79             @candidate = $wantarray
80 1         19 ? eval { $self->try->() }
81 1011 100       1772 : eval { scalar $self->try->() };
  1010         16309  
82 1011         8900 $result{candidate}{duration} = time - $start;
83 1011         2841 };
84              
85 1011 100       2536 if ( rand > 0.5 ) {
86 490         1119 $run_control->();
87 490         836 $run_candidate->();
88             }
89             else {
90 521         1019 $run_candidate->();
91 521         934 $run_control->();
92             }
93              
94 1010         2944 my $delta = compare(\@candidate, \@control, \&strict_convert);
95 1010 100       308607 my $diag = $delta ? $delta->table->as_string : '';
96              
97 1010         39235 $result{matched} = $diag eq '';
98 1010         1728 $result{mismatched} = $diag ne '';
99              
100             $result{observation} = {
101 1010 100       3401 candidate => $wantarray ? @candidate : $candidate[0],
    100          
102             control => $wantarray ? @control : $control[0],
103             diagnostic => $diag,
104             };
105              
106 1010         22491 $self->result( \%result );
107 1010         25074 $self->publish;
108              
109 1009 100       6610 return $wantarray ? @control : $control[0];
110             }
111              
112             # Use better column header names in the observation diagnostic table.
113             sub BUILD {
114 15     15 1 13174 Test2::Compare::Delta->set_column_alias(GOT => 'CONTROL');
115 15         194 Test2::Compare::Delta->set_column_alias(CHECK => 'CANDIDATE');
116 15         165 return;
117             }
118              
119             1;
120              
121             =head1 LICENSE
122              
123             This software is Copyright (c) 2016 by Lance Wicks.
124              
125             This is free software, licensed under:
126              
127             The MIT (X11) License
128              
129             The MIT License
130              
131             Permission is hereby granted, free of charge, to any person
132             obtaining a copy of this software and associated
133             documentation files (the "Software"), to deal in the Software
134             without restriction, including without limitation the rights to
135             use, copy, modify, merge, publish, distribute, sublicense,
136             and/or sell copies of the Software, and to permit persons to
137             whom the Software is furnished to do so, subject to the
138             following conditions:
139              
140             The above copyright notice and this permission notice shall
141             be included in all copies or substantial portions of the
142             Software.
143              
144             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT
145             WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
146             INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
147             MERCHANTABILITY, FITNESS FOR A PARTICULAR
148             PURPOSE AND NONINFRINGEMENT. IN NO EVENT
149             SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
150             LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
151             LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
152             TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
153             CONNECTION WITH THE SOFTWARE OR THE USE OR
154             OTHER DEALINGS IN THE SOFTWARE.