Pārlūkot izejas kodu

Fix #66 - MegaReFactorZone

George S. Baugh 10 gadi atpakaļ
vecāks
revīzija
33ba99c8b9

+ 8 - 44
bin/testrail-bulk-mark-results

@@ -48,6 +48,8 @@ All mandatory options not passed with the above switches, or in your ~/.testrail
 
 
 -c --config     : configuration name to filter plans in run.  Can be passed multiple times.
 -c --config     : configuration name to filter plans in run.  Can be passed multiple times.
 
 
+-s --status     : only mark tests already marked as [status] in testrail.  Can be passed multiple times.
+
 -a --assignedto : only mark tests assigned to user. Can be passed multiple times.
 -a --assignedto : only mark tests assigned to user. Can be passed multiple times.
 
 
 =back
 =back
@@ -62,8 +64,6 @@ All options specified thereby are overridden by passing the command-line switche
 
 
 =over 4
 =over 4
 
 
---mock : don't do any real HTTP requests.
-
 --help : show this output
 --help : show this output
 
 
 =back
 =back
@@ -95,12 +95,13 @@ GetOptions(
     'apiurl=s'        => \$opts->{'apiurl'},
     'apiurl=s'        => \$opts->{'apiurl'},
     'password=s'      => \$opts->{'password'},
     'password=s'      => \$opts->{'password'},
     'user=s'          => \$opts->{'user'},
     'user=s'          => \$opts->{'user'},
+    'assignedto=s@'   => \$opts->{'users'},
+    'status=s@'       => \$opts->{'statuses'},
     'j|project=s'     => \$opts->{'project'},
     'j|project=s'     => \$opts->{'project'},
     'p|plan=s'        => \$opts->{'plan'},
     'p|plan=s'        => \$opts->{'plan'},
     'r|run=s'         => \$opts->{'run'},
     'r|run=s'         => \$opts->{'run'},
     'c|config=s@'     => \$opts->{'configs'},
     'c|config=s@'     => \$opts->{'configs'},
     'a|assignedto=s@' => \$opts->{'users'},
     'a|assignedto=s@' => \$opts->{'users'},
-    'mock'            => \$opts->{'mock'},
     'e|encoding=s'    => \$opts->{'encoding'},
     'e|encoding=s'    => \$opts->{'encoding'},
     'h|help'          => \$opts->{'help'}
     'h|help'          => \$opts->{'help'}
 );
 );
@@ -113,49 +114,12 @@ my $reason = $ARGV[1];
 die("No status to set provided.") unless $status;
 die("No status to set provided.") unless $status;
 TestRail::Utils::interrogateUser($opts,qw{apiurl user password project run});
 TestRail::Utils::interrogateUser($opts,qw{apiurl user password project run});
 
 
-if ($opts->{mock}) {
-    use Test::LWP::UserAgent::TestRailMock;
-    $opts->{browser} = $Test::LWP::UserAgent::TestRailMock::mockObject;
-    $opts->{debug} = 1;
-}
-
 my $tr = TestRail::API->new($opts->{apiurl},$opts->{user},$opts->{password},$opts->{'encoding'},$opts->{'debug'});
 my $tr = TestRail::API->new($opts->{apiurl},$opts->{user},$opts->{password},$opts->{'encoding'},$opts->{'debug'});
-$tr->{'browser'} = $opts->{'browser'} if $opts->{'browser'};
-$tr->{'debug'} = 0;
-
-my ($project,$plan,$run) = TestRail::Utils::getRunInformation($tr,$opts);
-
-my $user_ids;
-#Process assignedto ids
-if ($opts->{'users'}) {
-    eval { @$user_ids = $tr->userNamesToIds(@{$opts->{'users'}}); };
-    if ($@) {
-        print "$@\n";
-        exit 5;
-    }
-}
-
-my $cases = $tr->getTests($run->{'id'},undef,$user_ids);
-
-if (!$cases) {
-    print "No cases in TestRail to mark!\n";
-    exit 3;
-}
-
-my ($status_id) = $tr->statusNamesToIds($status);
-
-@$cases = map {
-    {
-        'test_id' => $_->{'id'},
-        'status_id' => $status_id,
-        'comment'   => $reason,
-        'version'   => $opts->{'version'}
-    }
-} @$cases;
-
-my $results = $tr->bulkAddResults($run->{'id'},$cases);
+$opts->{'set_status_to'} = $status;
+$opts->{'reason'} = $reason;
+my $results = TestRail::Utils::Results::bulkMarkResults($opts,$tr);
 
 
-print "Successfully set the status of ".scalar(@$results)." cases to $status.\n";
+print "Successfully set the status of ".scalar(@$results)." cases to $status.\n" if $results;
 
 
 exit 0;
 exit 0;
 
 

+ 2 - 4
bin/testrail-lock

@@ -77,8 +77,6 @@ All options specified thereby are overridden by passing the command-line switche
 
 
 =over 4
 =over 4
 
 
---mock : don't do any real HTTP requests.  Used only by tests.
-
 --help : show this output
 --help : show this output
 
 
 =back
 =back
@@ -116,7 +114,6 @@ GetOptions(
     'no-match=s'      => \$opts->{'no-match'},
     'no-match=s'      => \$opts->{'no-match'},
     'n|no-recurse'    => \$opts->{'no-recurse'},
     'n|no-recurse'    => \$opts->{'no-recurse'},
     't|case-type=s@'  => \$opts->{'case-types'},
     't|case-type=s@'  => \$opts->{'case-types'},
-    'mock'            => \$opts->{'mock'},
     'e|encoding=s'    => \$opts->{'encoding'},
     'e|encoding=s'    => \$opts->{'encoding'},
     'h|help'          => \$opts->{'help'}
     'h|help'          => \$opts->{'help'}
 );
 );
@@ -126,7 +123,8 @@ $opts->{'hostname'} = hostname;
 
 
 TestRail::Utils::interrogateUser($opts,qw{apiurl user password project run lockname});
 TestRail::Utils::interrogateUser($opts,qw{apiurl user password project run lockname});
 
 
-my $ret = TestRail::Utils::pickAndLockTest($opts);
+my $tr = TestRail::API->new($opts->{apiurl},$opts->{user},$opts->{password},$opts->{'encoding'});
+my $ret = TestRail::Utils::pickAndLockTest($opts,$tr);
 
 
 exit 255 if !$ret;
 exit 255 if !$ret;
 
 

+ 4 - 50
bin/testrail-report

@@ -100,10 +100,6 @@ states which TAP can have.
 Also, be sure your tests don't output non-TAP (unknown) lines ending in dots (.)
 Also, be sure your tests don't output non-TAP (unknown) lines ending in dots (.)
 This will cause the preceding characters to be interpreted as a test name, which may lead to unexpected results.
 This will cause the preceding characters to be interpreted as a test name, which may lead to unexpected results.
 
 
-=head2 TESTING OPTIONS:
-
-    --mock don't do any real HTTP requests.
-
 =cut
 =cut
 
 
 use strict;
 use strict;
@@ -111,9 +107,7 @@ use warnings;
 
 
 use TestRail::Utils;
 use TestRail::Utils;
 use Getopt::Long;
 use Getopt::Long;
-use Term::ANSIColor 2.01 qw(colorstrip);
 use Test::Rail::Parser;
 use Test::Rail::Parser;
-use IO::Interactive::Tiny ();
 use File::HomeDir qw{my_home};
 use File::HomeDir qw{my_home};
 
 
 print "testrail-report\n----------------------\n";
 print "testrail-report\n----------------------\n";
@@ -130,7 +124,6 @@ GetOptions(
     'project=s'      => \$opts{project},
     'project=s'      => \$opts{project},
     'case-ok'        => \$opts{case_per_ok},
     'case-ok'        => \$opts{case_per_ok},
     'step-results=s' => \$opts{step_results},
     'step-results=s' => \$opts{step_results},
-    'mock'           => \$opts{mock},
     'config=s@'      => \$opts{configs},
     'config=s@'      => \$opts{configs},
     'plan=s'         => \$opts{plan},
     'plan=s'         => \$opts{plan},
     'version=s'      => \$opts{version},
     'version=s'      => \$opts{version},
@@ -152,51 +145,12 @@ if (-e $homedir . '/.testrailrc' && (!$opts{apiurl} || !$opts{password} || !$opt
 #If argument is passed use it instead of stdin
 #If argument is passed use it instead of stdin
 my $file = $ARGV[0];
 my $file = $ARGV[0];
 die "No Such File $file" if ($file && !-e $file);
 die "No Such File $file" if ($file && !-e $file);
-my ($fh,$fcontents,@files);
-
-if ($file) {
-    open($fh,'<',$file);
-    while (<$fh>) {
-        $_ = colorstrip($_); #strip prove brain damage
-
-        if (TestRail::Utils::getFilenameFromTapLine($_)) {
-            push(@files,$fcontents) if $fcontents;
-            $fcontents = '';
-        }
-        $fcontents .= $_;
-    }
-    close($fh);
-    push(@files,$fcontents) if $fcontents;
-} else {
-    #Just read STDIN, print help if no file was passed
-    if (IO::Interactive::Tiny::is_interactive()) {
-        print "ERROR: no file passed, and no data piped in! See --help for usage.\n";
-        exit(1);
-    }
-    if ( !$opts{run} || !$opts{apiurl} || !$opts{password} || !$opts{user} || !$opts{project} ) {
-        print "ERROR: Interactive mode not allowed when piping input.  See --help for options.\n";
-        exit(1);
-    }
-    while (<>) {
-        $_ = colorstrip($_); #strip prove brain damage
-        if (TestRail::Utils::getFilenameFromTapLine($_)) {
-            push(@files,$fcontents) if $fcontents;
-            $fcontents = '';
-        }
-        $fcontents .= $_;
-    }
-    help() if !$fcontents; #Nothing passed to stdin!
-    push(@files,$fcontents) if $fcontents;
-}
 
 
-TestRail::Utils::interrogateUser(\%opts,qw{apiurl user password project run});
+die "ERROR: Interactive mode not allowed when piping input.  See --help for options." if ( !$opts{run} || !$opts{apiurl} || !$opts{password} || !$opts{user} || !$opts{project} );
 
 
-$opts{debug} = 0;
-if ($opts{mock}) {
-    use Test::LWP::UserAgent::TestRailMock;
-    $opts{browser} = $Test::LWP::UserAgent::TestRailMock::mockObject;
-    $opts{debug} = 1;
-}
+my @files = TestRail::Utils::TAP2TestFiles($file);
+
+TestRail::Utils::interrogateUser(\%opts,qw{apiurl user password project run});
 
 
 $opts{result_options} = {'version' => $opts{version}} if $opts{version};
 $opts{result_options} = {'version' => $opts{version}} if $opts{version};
 
 

+ 4 - 1
bin/testrail-tests

@@ -57,6 +57,8 @@ All mandatory options not passed with the above switches, or in your ~/.testrail
 
 
 -a --assignedto : only list tests assigned to user. Can be passed multiple times.
 -a --assignedto : only list tests assigned to user. Can be passed multiple times.
 
 
+--extension     : only list files ending in the provided string (e.g. .pl, .pm, .t, .test)
+
 =back
 =back
 
 
 =head1 CONFIGURATION FILE
 =head1 CONFIGURATION FILE
@@ -108,6 +110,7 @@ GetOptions(
     'no-match=s'      => \$opts->{'no-match'},
     'no-match=s'      => \$opts->{'no-match'},
     'n|no-recurse'    => \$opts->{'no-recurse'},
     'n|no-recurse'    => \$opts->{'no-recurse'},
     'e|encoding=s'    => \$opts->{'encoding'},
     'e|encoding=s'    => \$opts->{'encoding'},
+    'extension=s'     => \$opts->{'extension'},
     'h|help'          => \$opts->{'help'}
     'h|help'          => \$opts->{'help'}
 );
 );
 
 
@@ -117,7 +120,7 @@ TestRail::Utils::interrogateUser($opts,qw{apiurl user password project run});
 
 
 my $tr = TestRail::API->new($opts->{apiurl},$opts->{user},$opts->{password},$opts->{'encoding'},$opts->{'debug'});
 my $tr = TestRail::API->new($opts->{apiurl},$opts->{user},$opts->{password},$opts->{'encoding'},$opts->{'debug'});
 
 
-my $cases = TestRail::Utils::getTests($opts,$tr);
+my ($cases) = TestRail::Utils::getTests($opts,$tr);
 die "No cases in TestRail!\n" unless $cases;
 die "No cases in TestRail!\n" unless $cases;
 
 
 $opts->{'names-only'} = 1;
 $opts->{'names-only'} = 1;

+ 1 - 0
dist.ini

@@ -120,6 +120,7 @@ stopwords = lifo
 stopwords = milesort
 stopwords = milesort
 stopwords = findRuns
 stopwords = findRuns
 stopwords = findTests
 stopwords = findTests
+stopwords = assignee
 
 
 [PkgVersion]
 [PkgVersion]
 [AutoPrereqs]
 [AutoPrereqs]

+ 1 - 1
lib/Test/Rail/Harness.pm

@@ -63,7 +63,7 @@ sub make_parser {
 
 
     #for Testability of plugin
     #for Testability of plugin
     if ($ENV{'TESTRAIL_MOCKED'}) {
     if ($ENV{'TESTRAIL_MOCKED'}) {
-        use Test::LWP::UserAgent::TestRailMock;
+        require Test::LWP::UserAgent::TestRailMock;
         $args->{'debug'} = 1;
         $args->{'debug'} = 1;
         $args->{'browser'} = $Test::LWP::UserAgent::TestRailMock::mockObject;
         $args->{'browser'} = $Test::LWP::UserAgent::TestRailMock::mockObject;
     }
     }

+ 42 - 0
lib/TestRail/Utils.pm

@@ -9,6 +9,8 @@ use warnings;
 use Carp qw{confess cluck};
 use Carp qw{confess cluck};
 use Pod::Perldoc 3.10;
 use Pod::Perldoc 3.10;
 
 
+use IO::Interactive::Tiny ();
+use Term::ANSIColor 2.01 qw(colorstrip);
 use Scalar::Util qw{blessed};
 use Scalar::Util qw{blessed};
 
 
 =head1 SCRIPT HELPER FUNCTIONS
 =head1 SCRIPT HELPER FUNCTIONS
@@ -130,6 +132,46 @@ sub getFilenameFromTapLine {
     return 0;
     return 0;
 }
 }
 
 
+=head2 TAP2TestFiles(file)
+
+Returns ARRAY of TAP output for the various test files therein.
+file is optional, will read TAP from STDIN if not passed.
+
+=cut
+
+sub TAP2TestFiles {
+    my $file = shift;
+    my ($fh,$fcontents,@files);
+
+    if ($file) {
+        open($fh,'<',$file);
+        while (<$fh>) {
+            $_ = colorstrip($_); #strip prove brain damage
+
+            if (getFilenameFromTapLine($_)) {
+                push(@files,$fcontents) if $fcontents;
+                $fcontents = '';
+            }
+            $fcontents .= $_;
+        }
+        close($fh);
+        push(@files,$fcontents) if $fcontents;
+    } else {
+        #Just read STDIN, print help if no file was passed
+        die "ERROR: no file passed, and no data piped in! See --help for usage.\n" if IO::Interactive::Tiny::is_interactive();
+        while (<>) {
+            $_ = colorstrip($_); #strip prove brain damage
+            if (getFilenameFromTapLine($_)) {
+                push(@files,$fcontents) if $fcontents;
+                $fcontents = '';
+            }
+            $fcontents .= $_;
+        }
+        push(@files,$fcontents) if $fcontents;
+    }
+    return @files;
+}
+
 =head2 getRunInformation
 =head2 getRunInformation
 
 
 Return the relevant project definition, plan, run and milestone definition HASHREFs for the provided options.
 Return the relevant project definition, plan, run and milestone definition HASHREFs for the provided options.

+ 12 - 5
lib/TestRail/Utils/Find.pm

@@ -7,6 +7,7 @@ use strict;
 use warnings;
 use warnings;
 
 
 use Carp qw{confess cluck};
 use Carp qw{confess cluck};
+use Scalar::Util qw{blessed};
 
 
 use File::Find;
 use File::Find;
 use Cwd qw{abs_path};
 use Cwd qw{abs_path};
@@ -39,6 +40,8 @@ Returns ARRAYREF of run definition HASHREFs.
 
 
 sub findRuns {
 sub findRuns {
     my ($opts,$tr) = @_;
     my ($opts,$tr) = @_;
+    confess("TestRail handle must be provided as argument 2") unless blessed($tr) eq 'TestRail::API';
+
     my ($status_ids);
     my ($status_ids);
 
 
     #Process statuses
     #Process statuses
@@ -131,14 +134,15 @@ Get the tests specified by the options passed.
 
 
 =back
 =back
 
 
-Returns ARRAYREF of tests.
+Returns ARRAYREF of tests, and the run in which they belong.
 
 
 =cut
 =cut
 
 
 sub getTests {
 sub getTests {
     my ($opts,$tr) = @_;
     my ($opts,$tr) = @_;
+    confess("TestRail handle must be provided as argument 2") unless blessed($tr) eq 'TestRail::API';
 
 
-    my ($project,$plan,$run) = TestRail::Utils::getRunInformation($tr,$opts);
+    my (undef,undef,$run) = TestRail::Utils::getRunInformation($tr,$opts);
     my ($status_ids,$user_ids);
     my ($status_ids,$user_ids);
 
 
     #Process statuses
     #Process statuses
@@ -148,7 +152,7 @@ sub getTests {
     @$user_ids = $tr->userNamesToIds(@{$opts->{'users'}}) if $opts->{'users'};
     @$user_ids = $tr->userNamesToIds(@{$opts->{'users'}}) if $opts->{'users'};
 
 
     my $cases = $tr->getTests($run->{'id'},$status_ids,$user_ids);
     my $cases = $tr->getTests($run->{'id'},$status_ids,$user_ids);
-    return $cases;
+    return ($cases,$run);
 }
 }
 
 
 =head2 findTests(opts,case1,...,caseN)
 =head2 findTests(opts,case1,...,caseN)
@@ -169,6 +173,8 @@ Given an ARRAY of tests, find tests meeting your criteria (or not) in the specif
 
 
 =item BOOL C<NAMES-ONLY> - Only return the names of the tests rather than the entire test objects.
 =item BOOL C<NAMES-ONLY> - Only return the names of the tests rather than the entire test objects.
 
 
+=item STRING C<EXTENSION> (optional) - Only return files ending with the provided text (e.g. .t, .test, .pl, .pm)
+
 =back
 =back
 
 
 =item ARRAY C<CASES> - Array of cases to translate to pathnames based on above options.
 =item ARRAY C<CASES> - Array of cases to translate to pathnames based on above options.
@@ -187,15 +193,16 @@ sub findTests {
     confess "Error! match and no-match options are mutually exclusive.\n" if ($opts->{'match'} && $opts->{'no-match'});
     confess "Error! match and no-match options are mutually exclusive.\n" if ($opts->{'match'} && $opts->{'no-match'});
     my @tests = @cases;
     my @tests = @cases;
     my (@realtests);
     my (@realtests);
+    my $ext = $opts->{'extension'} // '';
 
 
     if ($opts->{'match'} || $opts->{'no-match'}) {
     if ($opts->{'match'} || $opts->{'no-match'}) {
         my $dir = $opts->{'match'} ? $opts->{'match'} : $opts->{'no-match'};
         my $dir = $opts->{'match'} ? $opts->{'match'} : $opts->{'no-match'};
         if (!$opts->{'no-recurse'}) {
         if (!$opts->{'no-recurse'}) {
-            File::Find::find( sub { push(@realtests,$File::Find::name) if -f }, $dir );
+            File::Find::find( sub { push(@realtests,$File::Find::name) if -f && m/\Q$ext\E$/ }, $dir );
             @tests = grep {my $real = $_->{'title'}; grep { $real eq basename($_) } @realtests} @cases; #XXX if you have dups in your tree, be-ware
             @tests = grep {my $real = $_->{'title'}; grep { $real eq basename($_) } @realtests} @cases; #XXX if you have dups in your tree, be-ware
         } else {
         } else {
             #Handle special windows case -- glob doesn't prepend abspath
             #Handle special windows case -- glob doesn't prepend abspath
-            @realtests = glob("$dir/*");
+            @realtests = glob("$dir/*$ext");
             @tests = map {
             @tests = map {
                 $_->{'title'} = "$dir/".$_->{'title'} if( $^O eq 'MSWin32' );
                 $_->{'title'} = "$dir/".$_->{'title'} if( $^O eq 'MSWin32' );
                 $_
                 $_

+ 2 - 9
lib/TestRail/Utils/Lock.pm

@@ -9,6 +9,7 @@ use strict;
 use warnings;
 use warnings;
 
 
 use Carp qw{confess cluck};
 use Carp qw{confess cluck};
+use Scalar::Util qw{blessed};
 
 
 use Types::Standard qw( slurpy ClassName Object Str Int Bool HashRef ArrayRef Maybe Optional);
 use Types::Standard qw( slurpy ClassName Object Str Int Bool HashRef ArrayRef Maybe Optional);
 use Type::Params qw( compile );
 use Type::Params qw( compile );
@@ -54,16 +55,8 @@ If the test could not be locked, 0 is returned.
 sub pickAndLockTest {
 sub pickAndLockTest {
     state $check = compile(HashRef, Optional[Maybe[Object]]);
     state $check = compile(HashRef, Optional[Maybe[Object]]);
     my ($opts, $tr) = $check->(@_);
     my ($opts, $tr) = $check->(@_);
+    confess("TestRail handle must be provided as argument 2") unless blessed($tr) eq 'TestRail::API';
 
 
-    if ($opts->{mock} && !$tr) {
-        require Test::LWP::UserAgent::TestRailMock; #LazyLoad
-        $opts->{browser} = $Test::LWP::UserAgent::TestRailMock::mockObject;
-        $opts->{debug} = 1;
-    }
-
-    $tr //= TestRail::API->new($opts->{apiurl},$opts->{user},$opts->{password},$opts->{'encoding'},$opts->{'debug'});
-    $tr->{'browser'} = $opts->{'browser'} if $opts->{'browser'};
-    $tr->{'debug'} = 0;
 
 
     my ($project,$plan,$run) = TestRail::Utils::getRunInformation($tr,$opts);
     my ($project,$plan,$run) = TestRail::Utils::getRunInformation($tr,$opts);
 
 

+ 56 - 0
lib/TestRail/Utils/Results.pm

@@ -0,0 +1,56 @@
+# PODNAME: TestRail::Utils::Results
+# ABSTRACT: Perform batch operations on test results, and analyze the same.
+
+package TestRail::Utils::Results;
+
+use strict;
+use warnings;
+
+use Carp qw{confess cluck};
+use Scalar::Util qw{blessed};
+
+use TestRail::Utils::Find;
+
+=head1 FUNCTIONS
+
+=head2 bulkMarkResults(options,TestRail::API)
+
+Primary routine of testrail-bulk-mark-results.
+Takes same options as the aforementioned binary as a HASHREF, with the following exceptions:
+
+=over 4
+
+=item C<users> ARRAYREF (optional) - corresponds to --assignedto options passed
+
+=item C<statuses> ARRAYREF (optional) - corresponds to --status options passed
+
+=item C<set_status_to> STRING - Status to bulk-set cases to (ARGV[0])
+
+=item C<reason> STRING (optional) - Reason to do said bulk-set, recorded as result comment (ARGV[1])
+
+=back
+
+=cut;
+
+sub bulkMarkResults {
+    my ($opts,$tr) = @_;
+    confess("TestRail handle must be provided as argument 2") unless blessed($tr) eq 'TestRail::API';
+
+    my ($cases,$run) = TestRail::Utils::Find::getTests($opts,$tr);
+    die "No cases in TestRail to mark!\n" unless $cases;
+
+    my ($status_id) = $tr->statusNamesToIds($opts->{'set_status_to'});
+
+    @$cases = map {
+        {
+            'test_id'   => $_->{'id'},
+            'status_id' => $status_id,
+            'comment'   => $opts->{'reason'},
+            'version'   => $opts->{'version'}
+        }
+    } @$cases;
+
+    return $tr->bulkAddResults($run->{'id'},$cases);
+}
+
+1;

+ 14 - 14
t/TestRail-Utils-Find.t

@@ -26,8 +26,7 @@ my $tr = new TestRail::API($apiurl,$login,$pw,undef,1);
 
 
 #Mock if necesary
 #Mock if necesary
 $tr->{'debug'} = 0;
 $tr->{'debug'} = 0;
-
-$tr->{'browser'} = Test::LWP::UserAgent::TestRailMock::lockMockStep0();
+$tr->{'browser'} = $Test::LWP::UserAgent::TestRailMock::mockObject;
 
 
 my $runs = TestRail::Utils::Find::findRuns($opts,$tr);
 my $runs = TestRail::Utils::Find::findRuns($opts,$tr);
 is(ref $runs, 'ARRAY', "FindRuns returns ARRAYREF");
 is(ref $runs, 'ARRAY', "FindRuns returns ARRAYREF");
@@ -87,7 +86,7 @@ $opts = {
     'names-only' => 1
     'names-only' => 1
 };
 };
 
 
-my $cases = TestRail::Utils::Find::getTests($opts,$tr);
+my ($cases) = TestRail::Utils::Find::getTests($opts,$tr);
 my @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 my @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 @expected = ("$FindBin::Bin/skipall.test");
 @expected = ("$FindBin::Bin/skipall.test");
 cmp_deeply(\@tests,\@expected,"findTests: match, no-recurse, plan mode, names-only");
 cmp_deeply(\@tests,\@expected,"findTests: match, no-recurse, plan mode, names-only");
@@ -100,12 +99,13 @@ cmp_deeply(\@tests,\@expected,"findTests: match, no-recurse, plan mode");
 delete $opts->{'match'};
 delete $opts->{'match'};
 $opts->{'no-match'} = $FindBin::Bin;
 $opts->{'no-match'} = $FindBin::Bin;
 $opts->{'names-only'} = 1;
 $opts->{'names-only'} = 1;
-$cases = TestRail::Utils::Find::getTests($opts,$tr);
+$opts->{'extension'} = '.test';
+($cases) = TestRail::Utils::Find::getTests($opts,$tr);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 is(scalar(grep {$_ eq 'skipall.test'} @tests),0,"Tests in tree are not returned in no-match mode");
 is(scalar(grep {$_ eq 'skipall.test'} @tests),0,"Tests in tree are not returned in no-match mode");
 is(scalar(grep {$_ eq 'NOT SO SEARED AFTER ALL'} @tests),0,"Tests not in tree that do exist are not returned in no-match mode");
 is(scalar(grep {$_ eq 'NOT SO SEARED AFTER ALL'} @tests),0,"Tests not in tree that do exist are not returned in no-match mode");
 is(scalar(grep {$_ eq $FindBin::Bin.'/faker.test'} @tests),1,"Orphan Tests in tree ARE returned in no-match mode");
 is(scalar(grep {$_ eq $FindBin::Bin.'/faker.test'} @tests),1,"Orphan Tests in tree ARE returned in no-match mode");
-is(scalar(@tests),26,"Correct number of non-existant cases shown (no-match, names-only)");
+is(scalar(@tests),6,"Correct number of non-existant cases shown (no-match, names-only)");
 
 
 $opts->{'configs'} = ['testPlatform1'];
 $opts->{'configs'} = ['testPlatform1'];
 isnt(exception { TestRail::Utils::Find::getTests($opts,$tr) } , undef,"Correct number of non-existant cases shown (no-match, names-only)");
 isnt(exception { TestRail::Utils::Find::getTests($opts,$tr) } , undef,"Correct number of non-existant cases shown (no-match, names-only)");
@@ -115,23 +115,23 @@ delete $opts->{'names-only'};
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 my @filtered_tests = grep {defined $_} map {$_->{'full_title'}} @tests;
 my @filtered_tests = grep {defined $_} map {$_->{'full_title'}} @tests;
 is(scalar(@filtered_tests),0,"Full titles not returned in no-match mode");
 is(scalar(@filtered_tests),0,"Full titles not returned in no-match mode");
-is(scalar(@tests),26,"Correct number of nonexistant cases shown in no-match mode");
+is(scalar(@tests),6,"Correct number of nonexistant cases shown in no-match mode");
 
 
 delete $opts->{'no-recurse'};
 delete $opts->{'no-recurse'};
 $opts->{'names-only'} = 1;
 $opts->{'names-only'} = 1;
-$cases = TestRail::Utils::Find::getTests($opts,$tr);
+($cases) = TestRail::Utils::Find::getTests($opts,$tr);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
-is(scalar(@tests),30,"Correct number of non-existant cases shown (no-match, names-only, recurse)");
+is(scalar(@tests),10,"Correct number of non-existant cases shown (no-match, names-only, recurse)");
 
 
 #mutual excl
 #mutual excl
 $opts->{'match'} = $FindBin::Bin;
 $opts->{'match'} = $FindBin::Bin;
-$cases = TestRail::Utils::Find::getTests($opts,$tr);
+($cases) = TestRail::Utils::Find::getTests($opts,$tr);
 isnt(exception {TestRail::Utils::Find::findTests($opts,@$cases)},undef,"match and no-match are mutually exclusive");
 isnt(exception {TestRail::Utils::Find::findTests($opts,@$cases)},undef,"match and no-match are mutually exclusive");
 delete $opts->{'no-match'};
 delete $opts->{'no-match'};
 
 
 delete $opts->{'plan'};
 delete $opts->{'plan'};
 $opts->{'run'} = 'TestingSuite';
 $opts->{'run'} = 'TestingSuite';
-$cases = TestRail::Utils::Find::getTests($opts,$tr);
+($cases) = TestRail::Utils::Find::getTests($opts,$tr);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 is(scalar(@tests),1,"Correct number of non-existant cases shown (match, plain run)");
 is(scalar(@tests),1,"Correct number of non-existant cases shown (match, plain run)");
 is(scalar(grep {$_ eq "$FindBin::Bin/skipall.test"} @tests),1,"Tests in tree are returned in match, plain run mode");
 is(scalar(grep {$_ eq "$FindBin::Bin/skipall.test"} @tests),1,"Tests in tree are returned in match, plain run mode");
@@ -140,24 +140,24 @@ is(scalar(grep {$_ eq "$FindBin::Bin/skipall.test"} @tests),1,"Tests in tree are
 $opts->{'plan'} = 'GosPlan';
 $opts->{'plan'} = 'GosPlan';
 $opts->{'run'} = 'Executing the great plan';
 $opts->{'run'} = 'Executing the great plan';
 $opts->{'users'} = ['teodesian'];
 $opts->{'users'} = ['teodesian'];
-$cases = TestRail::Utils::Find::getTests($opts,$tr);
+($cases) = TestRail::Utils::Find::getTests($opts,$tr);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 is(scalar(@tests),1,"Correct number of cases shown (match, plan run, assignedto pos)");
 is(scalar(@tests),1,"Correct number of cases shown (match, plan run, assignedto pos)");
 is(scalar(grep {$_ eq "$FindBin::Bin/skipall.test"} @tests),1,"Tests in tree are returned filtered by assignee");
 is(scalar(grep {$_ eq "$FindBin::Bin/skipall.test"} @tests),1,"Tests in tree are returned filtered by assignee");
 
 
 $opts->{'users'} = ['billy'];
 $opts->{'users'} = ['billy'];
-$cases = TestRail::Utils::Find::getTests($opts,$tr);
+($cases) = TestRail::Utils::Find::getTests($opts,$tr);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 is(scalar(@tests),0,"Correct number of cases shown (match, plan run, assignedto neg)");
 is(scalar(@tests),0,"Correct number of cases shown (match, plan run, assignedto neg)");
 
 
 delete $opts->{'users'};
 delete $opts->{'users'};
 $opts->{'statuses'} = ['passed'];
 $opts->{'statuses'} = ['passed'];
-$cases = TestRail::Utils::Find::getTests($opts,$tr);
+($cases) = TestRail::Utils::Find::getTests($opts,$tr);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 is(scalar(@tests),1,"Correct number of cases shown (match, plan run, passed)");
 is(scalar(@tests),1,"Correct number of cases shown (match, plan run, passed)");
 
 
 $opts->{'statuses'} = ['failed'];
 $opts->{'statuses'} = ['failed'];
 delete $opts->{'match'};
 delete $opts->{'match'};
-$cases = TestRail::Utils::Find::getTests($opts,$tr);
+($cases) = TestRail::Utils::Find::getTests($opts,$tr);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 @tests = TestRail::Utils::Find::findTests($opts,@$cases);
 is(scalar(@tests),0,"Correct number of cases shown (match, plan run, failed)");
 is(scalar(@tests),0,"Correct number of cases shown (match, plan run, failed)");

+ 0 - 3
t/TestRail-Utils-Lock.t

@@ -28,10 +28,7 @@ my $opts = {
 my ($apiurl,$login,$pw) = ('http://hokum.bogus','bogus','bogus');
 my ($apiurl,$login,$pw) = ('http://hokum.bogus','bogus','bogus');
 
 
 my $tr = new TestRail::API($apiurl,$login,$pw,undef,1);
 my $tr = new TestRail::API($apiurl,$login,$pw,undef,1);
-
-#Mock if necesary
 $tr->{'debug'} = 0;
 $tr->{'debug'} = 0;
-
 $tr->{'browser'} = Test::LWP::UserAgent::TestRailMock::lockMockStep0();
 $tr->{'browser'} = Test::LWP::UserAgent::TestRailMock::lockMockStep0();
 
 
 my $ret = TestRail::Utils::Lock::pickAndLockTest($opts,$tr);
 my $ret = TestRail::Utils::Lock::pickAndLockTest($opts,$tr);

+ 28 - 0
t/TestRail-Utils-Results.t

@@ -0,0 +1,28 @@
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+
+use Test::More 'tests' => 1;
+use Test::Fatal;
+
+use TestRail::API;
+use TestRail::Utils::Results;
+use Test::LWP::UserAgent::TestRailMock;
+
+my $opts = {
+    'project'       => 'CRUSH ALL HUMANS',
+    'run'           => 'SEND T-1000 INFILTRATION UNITS BACK IN TIME',
+    'set_status_to' => 'blocked',
+    'reason'        => 'Build was bad.'
+};
+
+my ($apiurl,$login,$pw) = ('http://testrail.local','bogus','bogus');
+
+my $tr = new TestRail::API($apiurl,$login,$pw,undef,1);
+$tr->{'debug'} = 0;
+$tr->{'browser'} = $Test::LWP::UserAgent::TestRailMock::mockObject;
+
+my $results = TestRail::Utils::Results::bulkMarkResults($opts,$tr);
+is(scalar(@$results),1,"Correctly marks outstanding tests in run");

+ 8 - 1
t/TestRail-Utils.t

@@ -4,7 +4,7 @@ use warnings;
 use FindBin;
 use FindBin;
 use lib "$FindBin::Bin/lib";
 use lib "$FindBin::Bin/lib";
 
 
-use Test::More 'tests' => 23;
+use Test::More 'tests' => 25;
 use Test::Fatal;
 use Test::Fatal;
 
 
 use TestRail::API;
 use TestRail::API;
@@ -57,6 +57,13 @@ close($fh);
 push(@files,$fcontents);
 push(@files,$fcontents);
 is(scalar(@files),7,"Detects # of filenames correctly in TAP");
 is(scalar(@files),7,"Detects # of filenames correctly in TAP");
 
 
+#Test the actual TAP parsing
+@files = TestRail::Utils::TAP2TestFiles('t/test_multiple_files.tap');
+is(scalar(@files),2,"TAP correctly parsed into right number of bins");
+
+@files = TestRail::Utils::TAP2TestFiles('t/seq_multiple_files.tap');
+is(scalar(@files),7,"TAP correctly parsed into right number of bins");
+
 #Test getRunInformation
 #Test getRunInformation
 my ($apiurl,$login,$pw) = ('http://testrail.local','teodesian@cpan.org','fake');
 my ($apiurl,$login,$pw) = ('http://testrail.local','teodesian@cpan.org','fake');
 my $debug = 1;
 my $debug = 1;

+ 1 - 10
t/testrail-bulk-mark-results.t

@@ -1,18 +1,9 @@
 use strict;
 use strict;
 use warnings;
 use warnings;
 
 
-use Test::More "tests" => 4;
+use Test::More "tests" => 2;
 
 
 my @args = ($^X,qw{bin/testrail-bulk-mark-results --help});
 my @args = ($^X,qw{bin/testrail-bulk-mark-results --help});
 my $out = `@args`;
 my $out = `@args`;
 is($? >> 8, 0, "Exit code OK asking for help");
 is($? >> 8, 0, "Exit code OK asking for help");
 like($out,qr/encoding of arguments/i,"Help output OK");
 like($out,qr/encoding of arguments/i,"Help output OK");
-
-#check plan mode
-@args = ($^X,qw{bin/testrail-bulk-mark-results --apiurl http://testrail.local --user "test@fake.fake" --password "fake" -j "CRUSH ALL HUMANS" -r "SEND T-1000 INFILTRATION UNITS BACK IN TIME" --mock blocked "Build was bad."});
-$out = `@args`;
-is($? >> 8, 0, "Exit code OK running against normal run");
-chomp $out;
-like($out,qr/set the status of 1 cases to blocked/,"Sets test correctly in single run mode");
-
-#TODO more thorough testing

+ 4 - 52
t/testrail-report.t

@@ -1,59 +1,11 @@
 use strict;
 use strict;
 use warnings;
 use warnings;
 
 
-use Test::More 'tests' => 16;
-
-my @args = ($^X,qw{bin/testrail-report --apiurl http://testrail.local --user "test@fake.fake" --password "fake" --project "CRUSH ALL HUMANS" --run "SEND T-1000 INFILTRATION UNITS BACK IN TIME" --mock t/test_multiple_files.tap});
-my $out = `@args`;
-is($? >> 8, 0, "Exit code OK reported with multiple files");
-my $matches = () = $out =~ m/Reporting result of case/ig;
-is($matches,2,"Attempts to upload multiple times");
-
-@args = ($^X,qw{bin/testrail-report --apiurl http://testrail.local --user "test@fake.fake" --password "fake" --project "CRUSH ALL HUMANS" --run "SEND T-1000 INFILTRATION UNITS BACK IN TIME" --case-ok --mock t/test_multiple_files.tap});
-$out = `@args`;
-is($? >> 8, 0, "Exit code OK reported with multiple files (case-ok mode)");
-$matches = () = $out =~ m/Reporting result of case/ig;
-is($matches,4,"Attempts to upload multiple times (case-ok mode)");
-
-#Test version, case-ok
-@args = ($^X,qw{bin/testrail-report --apiurl http://testrail.local --user "test@fake.fake" --password "fake" --project "TestProject" --run "TestingSuite" --case-ok --version '1.0.14' --mock t/test_subtest.tap});
-$out = `@args`;
-is($? >> 8, 0, "Exit code OK reported with subtests (case-ok mode)");
-$matches = () = $out =~ m/Reporting result of case/ig;
-is($matches,2,"Attempts to upload do not do subtests (case-ok mode)");
-
-#Test plans/configs
-@args = ($^X,qw{bin/testrail-report --apiurl http://testrail.local --user "test@fake.fake" --password "fake" --project "TestProject" --run "Executing the great plan" --plan "GosPlan" --config "testConfig"  --case-ok --mock t/test_subtest.tap});
-$out = `@args`;
-is($? >> 8, 0, "Exit code OK reported with plans");
-$matches = () = $out =~ m/Reporting result of case.*OK/ig;
-is($matches,2,"Attempts to to plans work");
-
-#Test that spawn works
-@args = ($^X,qw{bin/testrail-report --apiurl http://testrail.local --user "test@fake.fake" --password "fake" --project "TestProject" --run "TestingSuite2" --spawn 9 --case-ok --mock t/test_subtest.tap});
-$out = `@args`;
-is($? >> 8, 0, "Exit code OK reported with spawn");
-$matches = () = $out =~ m/Reporting result of case.*OK/ig;
-is($matches,2,"Attempts to spawn work");
-
-#Test that spawn works w/sections
-@args = ($^X,qw{bin/testrail-report --apiurl http://testrail.local --user "test@fake.fake" --password "fake" --project "TestProject" --run "TestingSuite2" --spawn 9 --case-ok --section "CARBON LIQUEFACTION" --mock t/test_subtest.tap});
-$out = `@args`;
-is($? >> 8, 0, "Exit code OK reported with spawn");
-$matches = () = $out =~ m/with specified sections/ig;
-is($matches,1,"Attempts to spawn work");
-
-#Test that the autoclose option works
-@args = ($^X,qw{bin/testrail-report --apiurl http://testrail.local --user "test@fake.fake" --password "fake" --project "TestProject" --run "FinalRun" --plan "FinalPlan" --config "testConfig" --case-ok --autoclose --mock t/fake.tap});
-$out = `@args`;
-is($? >> 8, 0, "Exit code OK when doing autoclose");
-like($out,qr/closing plan/i,"Run closure reported to user");
+use Test::More 'tests' => 2;
 
 
 #Test that help works
 #Test that help works
-@args = ($^X,qw{bin/testrail-report --help});
-$out = `@args`;
+my @args = ($^X,qw{bin/testrail-report --help});
+my $out = `@args`;
 is($? >> 8, 0, "Exit code OK reported with help");
 is($? >> 8, 0, "Exit code OK reported with help");
-$matches = () = $out =~ m/encoding of arguments/ig;
+my $matches = () = $out =~ m/encoding of arguments/ig;
 is($matches,1,"Help output OK");
 is($matches,1,"Help output OK");
-
-

+ 3 - 3
t/testrail-tests.t

@@ -1,9 +1,9 @@
 use strict;
 use strict;
 use warnings;
 use warnings;
 
 
-use Test::More "tests" => 30;
+use Test::More "tests" => 2;
 
 
-@args = ($^X,qw{bin/testrail-tests --help});
-$out = `@args`;
+my @args = ($^X,qw{bin/testrail-tests --help});
+my $out = `@args`;
 is($? >> 8, 0, "Exit code OK asking for help");
 is($? >> 8, 0, "Exit code OK asking for help");
 like($out,qr/encoding of arguments/i,"Help output OK");
 like($out,qr/encoding of arguments/i,"Help output OK");