~ubuntu-branches/ubuntu/trusty/bioperl/trusty

« back to all changes in this revision

Viewing changes to Bio/Root/Test.pm

  • Committer: Package Import Robot
  • Author(s): Charles Plessy
  • Date: 2013-09-22 13:39:48 UTC
  • mfrom: (3.1.11 sid)
  • Revision ID: package-import@ubuntu.com-20130922133948-c6z62zegjyp7ztou
Tags: 1.6.922-1
* New upstream release.
* Replaces and Breaks grinder (<< 0.5.3-3~) because of overlaping contents.
  Closes: #722910
* Stop Replacing and Breaking bioperl ( << 1.6.9 ): not needed anymore. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#
2
2
# BioPerl module for Bio::Root::Test
3
3
#
4
 
# Please direct questions and support issues to <bioperl-l@bioperl.org> 
 
4
# Please direct questions and support issues to <bioperl-l@bioperl.org>
5
5
#
6
6
# Cared for by Sendu Bala <bix@sendu.me.uk>
7
7
#
27
27
  my $do_network_tests = test_network();
28
28
  my $output_debugging = test_debug();
29
29
 
30
 
  # carry out tests with Test::More, Test::Exception and Test::Warn syntax
 
30
  # Bio::Root::Test rewraps Test::Most, so one can carry out tests with
 
31
  # Test::More, Test::Exception, Test::Warn, Test::Deep, Test::Diff syntax
31
32
 
32
33
  SKIP: {
33
34
    # these tests need version 2.6 of Optional::Module to work
59
60
=head1 DESCRIPTION
60
61
 
61
62
This provides a common base for all BioPerl test scripts. It safely handles the
62
 
loading of Test::More, Test::Exception and Test::Warn (actually, a subclass
63
 
compatible with Bioperl warnings) prior to tests being run. It also presents an
64
 
interface to common needs such as skipping all tests if required modules aren't
65
 
present or if network tests haven't been enabled. See test_begin().
 
63
loading of Test::Most, itself a simple wrapper around several highly used test
 
64
modules: Test::More, Test::Exception, Test::Warn, Test::Deep, and Test::Diff. It
 
65
also presents an interface to common needs such as skipping all tests if
 
66
required modules aren't present or if network tests haven't been enabled. See
 
67
test_begin().
66
68
 
67
69
In the same way, it allows you to skip just a subset of tests for those same
68
70
reasons, in addition to requiring certain executables and environment variables.
86
88
  bioperl-l@bioperl.org                  - General discussion
87
89
  http://bioperl.org/wiki/Mailing_lists  - About the mailing lists
88
90
 
89
 
=head2 Support 
 
91
=head2 Support
90
92
 
91
93
Please direct usage questions or support issues to the mailing list:
92
94
 
93
95
I<bioperl-l@bioperl.org>
94
96
 
95
 
rather than to the module maintainer directly. Many experienced and 
96
 
reponsive experts will be able look at the problem and quickly 
97
 
address it. Please include a thorough description of the problem 
 
97
rather than to the module maintainer directly. Many experienced and
 
98
reponsive experts will be able look at the problem and quickly
 
99
address it. Please include a thorough description of the problem
98
100
with code and data examples if at all possible.
99
101
 
100
102
=head2 Reporting Bugs
109
111
 
110
112
Email bix@sendu.me.uk
111
113
 
 
114
=head1 CONTRIBUTORS
 
115
 
 
116
Chris Fields  cjfields at bioperl dot org
 
117
 
112
118
=head1 APPENDIX
113
119
 
114
120
The rest of the documentation details each of the object methods.
121
127
use strict;
122
128
use warnings;
123
129
 
 
130
# According to Ovid, 'use base' can override signal handling, so use
 
131
# old-fashioned way. This should be a Test::Builder::Module subclass
 
132
# for consistency (as are any Test modules)
 
133
use Test::Most;
 
134
use Test::Builder;
 
135
use Test::Builder::Module;
124
136
use File::Temp qw(tempdir);
125
137
use File::Spec;
126
 
use Exporter qw(import);
127
 
 
128
 
BEGIN {
129
 
    # For prototyping reasons, we have to load Test::More's methods now, even
130
 
    # though theoretically in future the user may use a different Test framework
131
 
    
132
 
    # We want to load Test::More, Test::Exception and Test::Warn. Preferably the
133
 
    # users own versions, but if they don't have them, the ones in t/lib.
134
 
    # However, this module is in t/lib so t/lib is already in @INC so Test::* in
135
 
    # t/lib will be used first, which we don't want: get rid of t/lib in @INC
136
 
    no lib 't/lib';
137
 
    eval { require Test::More;
138
 
           require Test::Exception;
139
 
           require Test::Warn; };
140
 
    if ($@) {
141
 
        eval "use lib 't/lib';";
142
 
    }
143
 
    eval "use Test::More;
144
 
          use Test::Exception;";
145
 
    die "$@\n" if $@;
146
 
    
147
 
    # now that the users' Test::Warn has been loaded if they had it, we can
148
 
    # use Bio::Root::TestWarn
149
 
    eval "use Bio::Root::Test::Warn;";
150
 
    die "$@\n" if $@;
151
 
}
152
 
 
153
 
# re-export Test::More, Test::Exception and Test::Warn methods and export our own
154
 
our @EXPORT = qw(ok use_ok require_ok
155
 
                 is isnt like unlike is_deeply
156
 
                 cmp_ok
157
 
                 skip todo todo_skip
158
 
                 pass fail
159
 
                 eq_array eq_hash eq_set
160
 
                 $TODO
161
 
                 plan
162
 
                 can_ok isa_ok
163
 
                 diag
164
 
                 BAIL_OUT
165
 
                 
166
 
                 dies_ok
167
 
                 lives_ok
168
 
                 throws_ok
169
 
                 lives_and
170
 
                 
171
 
                 warning_is
172
 
                 warnings_are
173
 
                 warning_like
174
 
                 warnings_like
175
 
                 
176
 
                 test_begin
177
 
                 test_skip
178
 
                 test_output_file
179
 
                 test_output_dir
180
 
                 test_input_file
181
 
                 test_network
182
 
                 test_email
183
 
                 test_debug
184
 
                 float_is
185
 
                 );
186
 
 
187
 
if (Test::More->can('done_testing')) {
188
 
    push @EXPORT, 'done_testing';
189
 
}
190
 
 
191
 
our $GLOBAL_FRAMEWORK = 'Test::More';
 
138
 
 
139
our @ISA = qw(Test::Builder::Module);
 
140
 
 
141
# TODO: Evil magic ahead; can we clean this up?
 
142
 
 
143
{
 
144
    my $Tester = Test::Builder->new;
 
145
 
 
146
    no warnings 'redefine';
 
147
    sub Test::Warn::_canonical_got_warning {
 
148
        my ($called_from, $msg) = @_;
 
149
        my $warn_kind = $called_from eq 'Carp' ? 'carped' : ($called_from =~ /Bio::/ ? 'Bioperl' : 'warn');
 
150
 
 
151
        my $warning;
 
152
        if ($warn_kind eq 'Bioperl') {
 
153
            ($warning) = $msg =~ /\n--------------------- WARNING ---------------------\nMSG: (.+)\n---------------------------------------------------\n$/m;
 
154
            $warning ||= $msg; # shouldn't ever happen
 
155
        }
 
156
        else {
 
157
            my @warning_stack = split /\n/, $msg;   # some stuff of uplevel is included
 
158
            $warning = $warning_stack[0];
 
159
        }
 
160
 
 
161
        return {$warn_kind => $warning}; # return only the real message
 
162
    }
 
163
 
 
164
    sub Test::Warn::_diag_found_warning {
 
165
        foreach (@_) {
 
166
            if (ref($_) eq 'HASH') {
 
167
                ${$_}{carped} ? $Tester->diag("found carped warning: ${$_}{carped}")
 
168
                              : (${$_}{Bioperl} ? $Tester->diag("found Bioperl warning: ${$_}{Bioperl}")
 
169
                                 : $Tester->diag("found warning: ${$_}{warn}"));
 
170
            } else {
 
171
                $Tester->diag( "found warning: $_" );
 
172
            }
 
173
        }
 
174
        $Tester->diag( "didn't find a warning" ) unless @_;
 
175
    }
 
176
 
 
177
    sub Test::Warn::_cmp_got_to_exp_warning {
 
178
        my ($got_kind, $got_msg) = %{ shift() };
 
179
        my ($exp_kind, $exp_msg) = %{ shift() };
 
180
        return 0 if ($got_kind eq 'warn') && ($exp_kind eq 'carped');
 
181
 
 
182
        my $cmp;
 
183
        if ($got_kind eq 'Bioperl') {
 
184
            $cmp = $got_msg =~ /^\Q$exp_msg\E$/;
 
185
        }
 
186
        else {
 
187
            $cmp = $got_msg =~ /^\Q$exp_msg\E at \S+ line \d+\.?$/;
 
188
        }
 
189
 
 
190
        return $cmp;
 
191
    }
 
192
}
 
193
 
 
194
our @EXPORT = (@Test::Most::EXPORT,
 
195
               #@Bio::Root::Test::Warn::EXPORT,
 
196
               # Test::Warn method wrappers
 
197
 
 
198
               # BioPerl-specific
 
199
               qw(
 
200
                test_begin
 
201
                test_skip
 
202
                test_output_file
 
203
                test_output_dir
 
204
                test_input_file
 
205
                test_network
 
206
                test_email
 
207
                test_debug
 
208
                float_is
 
209
             ));
 
210
 
 
211
our $GLOBAL_FRAMEWORK = 'Test::Most';
192
212
our @TEMP_FILES;
193
213
 
194
214
=head2 test_begin
217
237
           -excludes_os         => str (default none, if OS suppied, all tests
218
238
                                        will skip if running on that OS (eg.
219
239
                                        'mswin'))
220
 
           -framework           => str (default 'Test::More', the Test module
 
240
           -framework           => str (default 'Test::Most', the Test module
221
241
                                        to load. NB: experimental, avoid using)
222
 
           
 
242
 
223
243
           Note, supplying -tests => 0 is possible, allowing you to skip all
224
244
           tests in the case that a test script is testing deprecated modules
225
245
           that have yet to be removed from the distribution
229
249
sub test_begin {
230
250
    my ($skip_all, $tests, $framework) = _skip(@_);
231
251
    $GLOBAL_FRAMEWORK = $framework;
232
 
    
233
 
    if ($framework eq 'Test::More') {
234
 
        # ideally we'd delay loading Test::More until this point, but see BEGIN
 
252
 
 
253
    if ($framework eq 'Test::Most') {
 
254
        # ideally we'd delay loading Test::Most until this point, but see BEGIN
235
255
        # block
236
 
        
 
256
 
237
257
        if ($skip_all) {
238
258
            eval "plan skip_all => '$skip_all';";
239
259
        }
243
263
        elsif ($tests) {
244
264
            eval "plan tests => $tests;";
245
265
        }
246
 
        
 
266
 
247
267
        return 1;
248
268
    }
249
269
    # go ahead and add support for other frameworks here
250
270
    else {
251
 
        die "Only Test::More is supported at the current time\n";
 
271
        die "Only Test::Most is supported at the current time\n";
252
272
    }
253
 
    
 
273
 
254
274
    return 0;
255
275
}
256
276
 
260
280
 Usage   : SKIP: {
261
281
                   test_skip(-tests => 10,
262
282
                             -requires_module => 'Optional::Module 2.01');
263
 
 
264
283
                   # 10 tests that need v2.01 of Optional::Module
265
284
           }
266
285
 Function: Skip a subset of tests for one of several common reasons: missing one
298
317
sub test_skip {
299
318
    my ($skip, $tests, $framework) = _skip(@_);
300
319
    $tests || die "-tests must be a number greater than 0";
301
 
    
302
 
    if ($framework eq 'Test::More') {
 
320
 
 
321
    if ($framework eq 'Test::Most') {
303
322
        if ($skip) {
304
323
            eval "skip('$skip', $tests);";
305
324
        }
306
325
    }
307
326
    # go ahead and add support for other frameworks here
308
327
    else {
309
 
        die "Only Test::More is supported at the current time\n";
 
328
        die "Only Test::Most is supported at the current time\n";
310
329
    }
311
330
}
312
331
 
323
342
 
324
343
sub test_output_file {
325
344
    die "test_output_file takes no args\n" if @_;
326
 
    
 
345
 
327
346
    # RT 48813
328
347
    my $tmp = File::Temp->new();
329
348
    push(@TEMP_FILES, $tmp);
346
365
 
347
366
sub test_output_dir {
348
367
    die "test_output_dir takes no args\n" if @_;
349
 
    
 
368
 
350
369
    return tempdir(CLEANUP => 1);
351
370
}
352
371
 
381
400
sub test_network {
382
401
    require Module::Build;
383
402
    my $build = Module::Build->current();
384
 
    return $build->notes('Network Tests');
 
403
    return $build->notes('network');
385
404
}
386
405
 
387
406
=head2 test_email
439
458
# decide if should skip and generate skip message
440
459
sub _skip {
441
460
    my %args = @_;
442
 
    
 
461
 
443
462
    # handle input strictly
444
463
    my $tests = $args{'-tests'};
445
464
    #(defined $tests && $tests =~ /^\d+$/) || die "-tests must be supplied and be an int\n";
446
465
    delete $args{'-tests'};
447
 
    
 
466
 
448
467
    my $req_mods = $args{'-requires_modules'};
449
468
    delete $args{'-requires_modules'};
450
469
    my @req_mods;
458
477
        ref($req_mod) && die "-requires_module takes a string\n";
459
478
        push(@req_mods, $req_mod);
460
479
    }
461
 
    
 
480
 
462
481
    my $req_net = $args{'-requires_networking'};
463
482
    delete $args{'-requires_networking'};
464
 
    
 
483
 
465
484
    my $req_email = $args{'-requires_email'};
466
485
    delete $args{'-requires_email'};
467
 
    
 
486
 
468
487
    my $req_env = $args{'-requires_env'};
469
488
    delete $args{'-requires_env'};
470
489
 
471
490
    # strip any leading $ in case someone passes $FOO instead of 'FOO'
472
 
    $req_env =~ s{^\$}{} if $req_env; 
 
491
    $req_env =~ s{^\$}{} if $req_env;
473
492
 
474
493
    my $req_exe = $args{'-requires_executable'};
475
494
    delete $args{'-requires_executable'};
476
 
    
 
495
 
477
496
    if ($req_exe && (!ref($req_exe) || !$req_exe->isa('Bio::Tools::Run::WrapperBase'))) {
478
497
        die "-requires_exe takes an argument of type Bio::Tools::Run::WrapperBase";
479
498
    }
480
 
    
 
499
 
481
500
    my $os = $args{'-excludes_os'};
482
501
    delete $args{'-excludes_os'};
483
 
    
 
502
 
484
503
    my $framework = $args{'-framework'} || $GLOBAL_FRAMEWORK;
485
504
    delete $args{'-framework'};
486
 
    
 
505
 
487
506
    # catch user mistakes
488
507
    while (my ($key, $val) = each %args) {
489
508
        die "unknown argument '$key' supplied, did you mistake 'required...' for 'requires...'?\n";
490
509
    }
491
 
    
 
510
 
492
511
    # test user requirments and return
493
512
    if ($os) {
494
513
        if ($^O =~ /$os/i) {
495
514
            return ('Not compatible with your Operating System', $tests, $framework);
496
515
        }
497
516
    }
498
 
    
 
517
 
499
518
    foreach my $mod (@req_mods) {
500
519
        my $skip = _check_module($mod);
501
520
        if ($skip) {
502
 
            return ($skip, $tests, $framework); 
 
521
            return ($skip, $tests, $framework);
503
522
        }
504
523
    }
505
 
    
 
524
 
506
525
    if ($req_net && ! test_network()) {
507
526
        return ('Network tests have not been requested', $tests, $framework);
508
527
    }
511
530
        return ('Valid email not provided; required for tests', $tests, $framework);
512
531
    }
513
532
 
514
 
    if ($req_exe && !$req_exe->executable) {
515
 
        my $msg = 'Required executable for '.ref($req_exe).' is not present';
516
 
        diag($msg);
517
 
        return ($msg, $tests, $framework);
 
533
    if ($req_exe) {
 
534
        eval {$req_exe->executable};
 
535
        if ($@) {
 
536
            my $msg = 'Required executable for '.ref($req_exe).' is not present';
 
537
            diag($msg);
 
538
            return ($msg, $tests, $framework);
 
539
        }
518
540
    }
519
 
    
 
541
 
520
542
    if ($req_env && !exists $ENV{$req_env}) {
521
543
        my $msg = 'Required environment variable $'.$req_env. ' is not set';
522
544
        diag($msg);
523
545
        return ($msg, $tests, $framework);
524
546
    }
525
 
    
 
547
 
526
548
    return ('', $tests, $framework);
527
549
}
528
550
 
529
551
sub _check_module {
530
552
    my $mod = shift;
531
 
    
 
553
 
532
554
    my $desired_version;
533
555
    if ($mod =~ /(\S+)\s+(\S+)/) {
534
556
        $mod = $1;
535
557
        $desired_version = $2;
536
558
    }
537
 
    
 
559
 
538
560
    eval "require $mod;";
539
 
    
 
561
 
540
562
    if ($@) {
541
563
        if ($@ =~ /Can't locate/) {
542
564
            return "The optional module $mod (or dependencies thereof) was not installed";
554
576
            return "The optional module $mod was out of date (wanted v$desired_version)";
555
577
        }
556
578
    }
557
 
    
 
579
 
558
580
    return;
559
581
}
560
 
 
 
582
 
561
583
1;