File Coverage

blib/lib/Scientist.pm
Criterion Covered Total %
statement 63 63 100.0
branch 20 20 100.0
condition n/a
subroutine 15 15 100.0
pod 3 4 75.0
total 101 102 99.0


line stmt bran cond sub pod time code
1             package Scientist;
2              
3 8     8   1489512 use strict;
  8         14  
  8         280  
4 8     8   43 use warnings;
  8         16  
  8         369  
5             our $VERSION = '0.009'; # VERSION
6              
7 8     8   4513 use Moo;
  8         86223  
  8         41  
8 8     8   10284 use Test2::API qw/intercept/;
  8         15  
  8         506  
9 8     8   43 use Test2::Compare::Delta 0.000025 qw//;
  8         241  
  8         185  
10 8     8   35 use Test2::Tools::Compare qw/is/;
  8         14  
  8         410  
11 8     8   4474 use Time::HiRes qw/time/;
  8         10354  
  8         31  
12 8     8   5786 use Types::Standard qw/Bool Str CodeRef HashRef/;
  8         760847  
  8         132  
13              
14             # ABSTRACT: Perl module inspired by https://github.com/github/scientist
15             # https://github.com/lancew/Scientist
16              
17             has 'context' => (
18             is => 'rw',
19             isa => HashRef,
20             );
21              
22             has 'enabled' => (
23             is => 'rw',
24             isa => Bool,
25             default => 1,
26             );
27              
28             has 'experiment' => (
29             is => 'ro',
30             isa => Str,
31             builder => 'name',
32             );
33              
34             has 'use' => (
35             is => 'rw',
36             isa => CodeRef,
37             );
38              
39             has 'result' => (
40             is => 'rw',
41             isa => HashRef,
42             );
43              
44             has 'try' => (
45             is => 'rw',
46             isa => CodeRef,
47             );
48              
49             sub name {
50 13     13 1 60529 return 'experiment';
51             }
52              
53             sub publish {
54 1009     1009 1 1158 my $self = shift;
55             # Stub publish sub, extend this to enable your own own
56             # unique publishing requirements
57 1009         978 return;
58             }
59              
60             sub run {
61 1014     1014 1 4410 my $self = shift;
62              
63             # If experiment not enabled just return the control code results.
64 1014 100       18406 return $self->use->() unless $self->enabled;
65              
66 1011         18978 my %result = (
67             context => $self->context,
68             experiment => $self->experiment,
69             );
70              
71 1011         6045 my $wantarray = wantarray;
72              
73 1011         877 my ( @control, @candidate );
74             my $run_control = sub {
75 1011     1011   1745 my $start = time;
76 1011 100       17503 @control = $wantarray ? $self->use->() : scalar $self->use->();
77 1010         7778 $result{control}{duration} = time - $start;
78 1011         3590 };
79              
80             my $run_candidate = sub {
81 1010     1010   1524 my $start = time;
82             @candidate = $wantarray
83 1         25 ? eval { $self->try->() }
84 1010 100       1500 : eval { scalar $self->try->() };
  1009         16799  
85 1010         8029 $result{candidate}{duration} = time - $start;
86 1011         2190 };
87              
88 1011 100       2157 if ( rand > 0.5 ) {
89 543         683 $run_control->();
90 542         779 $run_candidate->();
91             }
92             else {
93 468         570 $run_candidate->();
94 468         668 $run_control->();
95             }
96              
97             # Capture the events generated by is().
98             my $events = intercept {
99 1010     1010   126907 is(\@candidate, \@control);
100 1010         3871 };
101              
102 1010         436338 my ($ok_ev, undef, $why_ev) = @$events;
103              
104 1010         2219 my $ok = $ok_ev->pass;
105 1010 100       3315 $result{matched} = $ok ? 1 : 0;
106 1010 100       1780 $result{mismatched} = $ok ? 0 : 1;
107              
108 1010 100       2379 $result{observation}{candidate} = $wantarray ? @candidate : $candidate[0];
109 1010 100       1586 $result{observation}{control} = $wantarray ? @control : $control[0];
110              
111 1010 100       2019 if ($result{mismatched}){
112             # $why_ev has a table displaying why the test failed.
113 7         36 $result{observation}{diagnostic} = $why_ev->message;
114             }
115              
116 1010         23037 $self->result( \%result );
117 1010         17692 $self->publish;
118              
119 1009 100       8827 return $wantarray ? @control : $control[0];
120             }
121              
122             # Use better column header names in the observation diagnostic table.
123             sub BUILD {
124 15     15 0 11190 Test2::Compare::Delta->set_column_alias(GOT => 'CONTROL');
125 15         174 Test2::Compare::Delta->set_column_alias(CHECK => 'CANDIDATE');
126 15         138 return;
127             }
128              
129             1;
130              
131             =head1 LICENSE
132              
133             This software is Copyright (c) 2016 by Lance Wicks.
134              
135             This is free software, licensed under:
136              
137             The MIT (X11) License
138              
139             The MIT License
140              
141             Permission is hereby granted, free of charge, to any person
142             obtaining a copy of this software and associated
143             documentation files (the "Software"), to deal in the Software
144             without restriction, including without limitation the rights to
145             use, copy, modify, merge, publish, distribute, sublicense,
146             and/or sell copies of the Software, and to permit persons to
147             whom the Software is furnished to do so, subject to the
148             following conditions:
149              
150             The above copyright notice and this permission notice shall
151             be included in all copies or substantial portions of the
152             Software.
153              
154             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT
155             WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
156             INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
157             MERCHANTABILITY, FITNESS FOR A PARTICULAR
158             PURPOSE AND NONINFRINGEMENT. IN NO EVENT
159             SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
160             LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
161             LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
162             TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
163             CONNECTION WITH THE SOFTWARE OR THE USE OR
164             OTHER DEALINGS IN THE SOFTWARE.