[BUG] bug 2598
[bioperl-live.git] / t / LocationFactory.t
blob5e65c2c23abf146e14730c51289c4f18472bfca3
1 # -*-Perl-*- Test Harness script for Bioperl
2 # $Id$
4 use strict;
6 BEGIN {
7     use lib 't/lib';
8     use BioperlTest;
9     
10     test_begin(-tests => 271);
11         
12     use_ok('Bio::Factory::FTLocationFactory');
15 my $simple_impl = "Bio::Location::Simple";
16 my $fuzzy_impl = "Bio::Location::Fuzzy";
17 my $split_impl = "Bio::Location::Split";
19 # Holds strings and results. The latter is an array of expected class name,
20 # min/max start position and position type, min/max end position and position
21 # type, location type, the number of locations, and the strand.
23 my %testcases = (
24    # note: the following are directly taken from 
25    # http://www.ncbi.nlm.nih.gov/collab/FT/#location
26    "467" => [$simple_impl,
27             467, 467, "EXACT", 467, 467, "EXACT", "EXACT", 1, 1],
28         "340..565" => [$simple_impl,
29                  340, 340, "EXACT", 565, 565, "EXACT", "EXACT", 1, 1],
30         "<345..500" => [$fuzzy_impl,
31                  undef, 345, "BEFORE", 500, 500, "EXACT", "EXACT", 1, 1],
32         "<1..888" => [$fuzzy_impl,
33                  undef, 1, "BEFORE", 888, 888, "EXACT", "EXACT", 1, 1],
34         "(102.110)" => [$fuzzy_impl,
35                  102, 102, "EXACT", 110, 110, "EXACT", "WITHIN", 1, 1],
36         "(23.45)..600" => [$fuzzy_impl,
37                  23, 45, "WITHIN", 600, 600, "EXACT", "EXACT", 1, 1],
38         "(122.133)..(204.221)" => [$fuzzy_impl,
39                  122, 133, "WITHIN", 204, 221, "WITHIN", "EXACT", 1, 1],
40         "123^124" => [$simple_impl,
41                  123, 123, "EXACT", 124, 124, "EXACT", "IN-BETWEEN", 1, 1],
42         "145^177" => [$fuzzy_impl,
43                  145, 145, "EXACT", 177, 177, "EXACT", "IN-BETWEEN", 1, 1],
44         "join(12..78,134..202)" => [$split_impl,
45                  12, 12, "EXACT", 202, 202, "EXACT", "EXACT", 2, 1],
46         "complement(join(4918..5163,2691..4571))" => [$split_impl,
47                  2691, 2691, "EXACT", 5163, 5163, "EXACT", "EXACT", 2, -1],
48         "complement(34..(122.126))" => [$fuzzy_impl,
49                  34, 34, "EXACT", 122, 126, "WITHIN", "EXACT", 1, -1],
50         "J00194:100..202" => [$simple_impl,
51                  100, 100, "EXACT", 202, 202, "EXACT", "EXACT", 1, 1],
52         # this variant is not really allowed by the FT definition
53         # document but we want to be able to cope with it
54         "J00194:(100..202)" => [$simple_impl,
55                  100, 100, "EXACT", 202, 202, "EXACT", "EXACT", 1, 1],
56         "((122.133)..(204.221))" => [$fuzzy_impl,
57                  122, 133, "WITHIN", 204, 221, "WITHIN", "EXACT", 1, 1],
58         "join(AY016290.1:108..185,AY016291.1:1546..1599)"=> [$split_impl,
59                  108, 108, "EXACT", 185, 185, "EXACT", "EXACT", 2, undef],
61         # UNCERTAIN locations and positions (Swissprot)
62    "?2465..2774" => [$fuzzy_impl,
63        2465, 2465, "UNCERTAIN", 2774, 2774, "EXACT", "EXACT", 1, 1],
64    "22..?64" => [$fuzzy_impl,
65        22, 22, "EXACT", 64, 64, "UNCERTAIN", "EXACT", 1, 1],
66    "?22..?64" => [$fuzzy_impl,
67        22, 22, "UNCERTAIN", 64, 64, "UNCERTAIN", "EXACT", 1, 1],
68    "?..>393" => [$fuzzy_impl,
69        undef, undef, "UNCERTAIN", 393, undef, "AFTER", "UNCERTAIN", 1, 1],
70    "<1..?" => [$fuzzy_impl,
71        undef, 1, "BEFORE", undef, undef, "UNCERTAIN", "UNCERTAIN", 1, 1],
72    "?..536" => [$fuzzy_impl,
73        undef, undef, "UNCERTAIN", 536, 536, "EXACT", "UNCERTAIN", 1, 1],
74    "1..?" => [$fuzzy_impl,
75        1, 1, "EXACT", undef, undef, "UNCERTAIN", "UNCERTAIN", 1, 1],
76    "?..?" => [$fuzzy_impl,
77        undef, undef, "UNCERTAIN", undef, undef, "UNCERTAIN", "UNCERTAIN", 1, 1],
78    # Not working yet:
79    #"12..?1" => [$fuzzy_impl,
80    #    1, 1, "UNCERTAIN", 12, 12, "EXACT", "EXACT", 1, 1]
81                  );
83 my $locfac = Bio::Factory::FTLocationFactory->new();
84 isa_ok($locfac,'Bio::Factory::LocationFactoryI');
86 # sorting is to keep the order constant from one run to the next
87 foreach my $locstr (keys %testcases) { 
88         my $loc = $locfac->from_string($locstr);
89         if($locstr eq "join(AY016290.1:108..185,AY016291.1:1546..1599)") {
90                 $loc->seq_id("AY016295.1");
91         }
92         my @res = @{$testcases{$locstr}};
93         is(ref($loc), $res[0], $res[0]);
94         is($loc->min_start(), $res[1]);
95         is($loc->max_start(), $res[2]);
96         is($loc->start_pos_type(), $res[3]);
97         is($loc->min_end(), $res[4]);
98         is($loc->max_end(), $res[5]);
99         is($loc->end_pos_type(), $res[6]);
100         is($loc->location_type(), $res[7]);
101         my @locs = $loc->each_Location();
102         is(@locs, $res[8]);
103         my $ftstr = $loc->to_FTstring();
104         # this is a somewhat ugly hack, but we want clean output from to_FTstring()
105         # Umm, then these should really fail, correct?
106         # Should we be engineering workarounds for tests?
107         $locstr = "J00194:100..202" if $locstr eq "J00194:(100..202)";
108         $locstr = "(122.133)..(204.221)" if $locstr eq "((122.133)..(204.221))";
109         # now test
110         is($ftstr, $locstr, "Location String: $locstr");
111         # test strand production
112         is($loc->strand(), $res[9]);
115 SKIP: {
116     skip('nested matches in regex only supported in v5.6.1 and higher', 5) unless $^V gt v5.6.0;
117     
118         # bug #1674, #1765, 2101
119         # EMBL-like 
120         # join(20464..20694,21548..22763,join(complement(314652..314672),complement(232596..232990),complement(231520..231669)))
121         # GenBank-like
122         # join(20464..20694,21548..22763,complement(join(231520..231669,232596..232990,314652..314672)))
123         # Note that
124         # join(1000..2000,join(3000..4000,join(5000..6000,7000..8000)),9000..10000)
125         # is the same as
126         # join(1000..2000,3000..4000,5000..6000,7000..8000,9000..10000)
127         # But I don't want to bother with it at this point
128         my @expected = (# intentionally testing same expected string twice
129                                         # as I am providing two different encodings
130                                         # that should mean the same thing
131         'join(11025..11049,complement(join(315036..315294,251354..251412,241499..241580,239890..240081)))',
132         'join(11025..11049,complement(join(315036..315294,251354..251412,241499..241580,239890..240081)))',
133         # ditto
134         'join(20464..20694,21548..22763,complement(join(314652..314672,232596..232990,231520..231669)))',
135         'join(20464..20694,21548..22763,complement(join(314652..314672,232596..232990,231520..231669)))',
136         # this is just seen once
137         'join(1000..2000,join(3000..4000,join(5000..6000,7000..8000)),9000..10000)'
138    );
140         for my $locstr (
141                 'join(11025..11049,join(complement(239890..240081),complement(241499..241580),complement(251354..251412),complement(315036..315294)))',
142                 'join(11025..11049,complement(join(315036..315294,251354..251412,241499..241580,239890..240081)))',
143                 'join(20464..20694,21548..22763,complement(join(314652..314672,232596..232990,231520..231669)))',
144                 'join(20464..20694,21548..22763,join(complement(231520..231669),complement(232596..232990),complement(314652..314672)))',
145                 'join(1000..2000,join(3000..4000,join(5000..6000,7000..8000)),9000..10000)' 
146            ) {
147                 my $loc = $locfac->from_string($locstr);
148                 my $ftstr = $loc->to_FTstring();
149                 is($ftstr, shift @expected, $locstr);
150         }