File Coverage

blib/lib/TestRail/Utils.pm
Criterion Covered Total %
statement 96 119 80.6
branch 35 60 58.3
condition 5 9 55.5
subroutine 16 18 88.8
pod 8 8 100.0
total 160 214 74.7


line stmt bran cond sub pod time code
1             # ABSTRACT: Utilities for the testrail command line functions, and their main loops.
2             # PODNAME: TestRail::Utils
3              
4             package TestRail::Utils;
5             $TestRail::Utils::VERSION = '0.052';
6 14     14   196759 use strict;
  14         49  
  14         398  
7 14     14   68 use warnings;
  14         29  
  14         403  
8              
9 14     14   68 use Carp qw{confess cluck};
  14         25  
  14         780  
10 14     14   6760 use Pod::Usage ();
  14         530889  
  14         430  
11 14     14   4061 use TestRail::API;
  14         41  
  14         566  
12              
13 14     14   8078 use IO::Interactive::Tiny ();
  14         184  
  14         440  
14 14     14   7362 use Term::ANSIColor 2.01 qw(colorstrip);
  14         103122  
  14         12224  
15 14     14   6814 use Term::ReadKey ();
  14         26152  
  14         419  
16 14     14   107 use Scalar::Util qw{blessed};
  14         30  
  14         15943  
17              
18             sub help {
19 9     9 1 1593 Pod::Usage::pod2usage(
20             '-verbose' => 2,
21             '-noperldoc' => 1,
22             '-exitval' => 'NOEXIT'
23             );
24 9         203409 return 0;
25             }
26              
27             sub userInput {
28 0     0 1 0 my ($echo_ok) = @_;
29 0         0 my $input = "";
30              
31             # I'm going to be super paranoid here and consider everything to be sensitive info by default.
32 0 0       0 Term::ReadKey::ReadMode('noecho') unless $echo_ok;
33             {
34 0     0   0 local $SIG{'INT'} = sub { Term::ReadKey::ReadMode(0); exit 130; };
  0         0  
  0         0  
  0         0  
35 0         0 $input = ;
36 0 0       0 chomp($input) if $input;
37             }
38 0 0       0 Term::ReadKey::ReadMode(0) unless $echo_ok;
39 0         0 print "\n";
40 0         0 return $input;
41             }
42              
43             sub interrogateUser {
44 43     43 1 381 my ( $options, @keys ) = @_;
45 43         179 foreach my $key (@keys) {
46 188 50       450 if ( !$options->{$key} ) {
47 0         0 print "Type the $key for your TestRail install below:\n";
48 0         0 $options->{$key} = TestRail::Utils::userInput( $key ne 'password' );
49 0 0       0 die "$key cannot be blank!" unless $options->{$key};
50             }
51             }
52 43         111 return $options;
53             }
54              
55             sub parseConfig {
56 2     2 1 7683 my ( $homedir, $login_only ) = @_;
57 2         6 my $results = {};
58 2         4 my $arr = [];
59              
60 2 50       67 open( my $fh, '<', $homedir . '/.testrailrc' )
61             or return ( undef, undef, undef ); #couldn't open!
62 2         39 while (<$fh>) {
63 34         43 chomp;
64 34         83 @$arr = split( /=/, $_ );
65 34 100       60 if ( scalar(@$arr) != 2 ) {
66 4         87 warn("Could not parse $_ in '$homedir/.testrailrc'!\n");
67 4         21 next;
68             }
69 30         91 $results->{ lc( $arr->[0] ) } = $arr->[1];
70             }
71 2         20 close($fh);
72 2 100       19 return ( $results->{'apiurl'}, $results->{'password'}, $results->{'user'} )
73             if $login_only;
74 1         8 return $results;
75             }
76              
77             sub getFilenameFromTapLine {
78 392     392 1 4737 my $orig = shift;
79              
80 392         2400 $orig =~ s/ *$//g; # Strip all trailing whitespace
81              
82             #Special case
83 392         707 my ($is_skipall) = $orig =~ /(.*)\.+ skipped:/;
84 392 100       615 return $is_skipall if $is_skipall;
85              
86 390         920 my @process_split = split( / /, $orig );
87 390 100       697 return 0 unless scalar(@process_split);
88 363         464 my $dotty =
89             pop @process_split; #remove the ........ (may repeat a number of times)
90 363 100       804 return 0
91             if $dotty =~
92             /\d/; #Apparently looking for literal dots returns numbers too. who knew?
93 244         287 chomp $dotty;
94 244         460 my $line = join( ' ', @process_split );
95              
96             #IF it ends in a bunch of dots
97             #AND it isn't an ok/not ok
98             #AND it isn't a comment
99             #AND it isn't blank
100             #THEN it's a test name
101              
102 244 50 66     835 return $line
      66        
      33        
103             if ( $dotty =~ /^\.+$/
104             && !( $line =~ /^ok|not ok/ )
105             && !( $line =~ /^# / )
106             && $line );
107 204         401 return 0;
108             }
109              
110             sub TAP2TestFiles {
111 9     9 1 1524 my $file = shift;
112 9         20 my ( $fh, $fcontents, @files );
113              
114 9 50       22 if ($file) {
115 9         331 open( $fh, '<', $file );
116 9         190 while (<$fh>) {
117 197         363 $_ = colorstrip($_); #strip prove brain damage
118              
119 197 100       1433 if ( getFilenameFromTapLine($_) ) {
120 17 100       57 push( @files, $fcontents ) if $fcontents;
121 17         29 $fcontents = '';
122             }
123 197         618 $fcontents .= $_;
124             }
125 9         101 close($fh);
126 9 50       51 push( @files, $fcontents ) if $fcontents;
127             }
128             else {
129             #Just read STDIN, print help if no file was passed
130 0 0       0 die
131             "ERROR: no file passed, and no data piped in! See --help for usage.\n"
132             if IO::Interactive::Tiny::is_interactive();
133 0         0 while (<>) {
134 0         0 $_ = colorstrip($_); #strip prove brain damage
135 0 0       0 if ( getFilenameFromTapLine($_) ) {
136 0 0       0 push( @files, $fcontents ) if $fcontents;
137 0         0 $fcontents = '';
138             }
139 0         0 $fcontents .= $_;
140             }
141 0 0       0 push( @files, $fcontents ) if $fcontents;
142             }
143 9         55 return @files;
144             }
145              
146             sub getRunInformation {
147 46     46 1 7670 my ( $tr, $opts ) = @_;
148 46 50       150 confess("First argument must be instance of TestRail::API")
149             unless blessed($tr) eq 'TestRail::API';
150              
151 46         154 my $project = $tr->getProjectByName( $opts->{'project'} );
152 46 100       261 confess "No such project '$opts->{project}'.\n" if !$project;
153              
154 45         67 my ( $run, $plan );
155              
156 45 100       95 if ( $opts->{'plan'} ) {
157 24         74 $plan = $tr->getPlanByName( $project->{'id'}, $opts->{'plan'} );
158 24 100       1624 confess "No such plan '$opts->{plan}'!\n" if !$plan;
159             $run =
160 23         105 $tr->getChildRunByName( $plan, $opts->{'run'}, $opts->{'configs'} );
161             }
162             else {
163 21         103 $run = $tr->getRunByName( $project->{'id'}, $opts->{'run'} );
164             }
165              
166 44 100       959 confess
167             "No such run '$opts->{run}' matching the provided configs (if any).\n"
168             if !$run;
169              
170             #If the run/plan has a milestone set, then return it too
171 41         59 my $milestone;
172 41 100       92 my $mid = $plan ? $plan->{'milestone_id'} : $run->{'milestone_id'};
173 41 100       107 if ($mid) {
174 20         55 $milestone = $tr->getMilestoneByID($mid);
175 20 50       690 confess "Could not fetch run milestone!"
176             unless $milestone; #hope this doesn't happen
177             }
178              
179 41         150 return ( $project, $plan, $run, $milestone );
180             }
181              
182             sub getHandle {
183 37     37 1 732 my $opts = shift;
184              
185 37 50       331 $opts->{'debug'} = 1 if ( $opts->{'browser'} );
186              
187             my $tr = TestRail::API->new(
188             $opts->{apiurl}, $opts->{user}, $opts->{password},
189 37         576 $opts->{'encoding'}, $opts->{'debug'}
190             );
191 37 50       151 if ( $opts->{'browser'} ) {
192 37         907 $tr->{'browser'} = $opts->{'browser'};
193 37         97 $tr->{'debug'} = 0;
194             }
195 37         138 return $tr;
196             }
197              
198             1;
199              
200             __END__