github.com/biogo/biogo@v1.0.4/io/featio/gff/gff_test.go (about) 1 // Copyright ©2011-2012 The bíogo Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package gff 6 7 import ( 8 "github.com/biogo/biogo/alphabet" 9 "github.com/biogo/biogo/feat" 10 "github.com/biogo/biogo/seq" 11 "github.com/biogo/biogo/seq/linear" 12 13 "bytes" 14 "io" 15 "strings" 16 "testing" 17 "time" 18 19 "gopkg.in/check.v1" 20 ) 21 22 // Helpers 23 func floatPtr(f float64) *float64 { return &f } 24 25 func mustTime(t time.Time, err error) time.Time { 26 if err != nil { 27 panic(err) 28 } 29 return t 30 } 31 32 // Tests 33 func Test(t *testing.T) { check.TestingT(t) } 34 35 type S struct{} 36 37 var _ = check.Suite(&S{}) 38 39 var ( 40 gffTests = []struct { 41 gff string 42 feat []*Feature 43 }{ 44 { 45 gff: `SEQ1 EMBL atg 103 105 . + 0 46 SEQ1 EMBL exon 103 172 . + 0 47 SEQ1 EMBL splice5 172 173 . + . 48 SEQ1 netgene splice5 172 173 0.94 + . 49 SEQ1 genie sp5-20 163 182 2.3 + . 50 SEQ1 genie sp5-10 168 177 2.1 + . 51 SEQ2 grail ATG 17 19 2.1 - 0 52 `, 53 feat: []*Feature{ 54 {SeqName: "SEQ1", Source: "EMBL", Feature: "atg", FeatStart: 102, FeatEnd: 105, FeatScore: nil, FeatFrame: Frame0, FeatStrand: seq.Plus}, 55 {SeqName: "SEQ1", Source: "EMBL", Feature: "exon", FeatStart: 102, FeatEnd: 172, FeatScore: nil, FeatFrame: Frame0, FeatStrand: seq.Plus}, 56 {SeqName: "SEQ1", Source: "EMBL", Feature: "splice5", FeatStart: 171, FeatEnd: 173, FeatScore: nil, FeatFrame: NoFrame, FeatStrand: seq.Plus}, 57 {SeqName: "SEQ1", Source: "netgene", Feature: "splice5", FeatStart: 171, FeatEnd: 173, FeatScore: floatPtr(0.94), FeatFrame: NoFrame, FeatStrand: seq.Plus}, 58 {SeqName: "SEQ1", Source: "genie", Feature: "sp5-20", FeatStart: 162, FeatEnd: 182, FeatScore: floatPtr(2.3), FeatFrame: NoFrame, FeatStrand: seq.Plus}, 59 {SeqName: "SEQ1", Source: "genie", Feature: "sp5-10", FeatStart: 167, FeatEnd: 177, FeatScore: floatPtr(2.1), FeatFrame: NoFrame, FeatStrand: seq.Plus}, 60 {SeqName: "SEQ2", Source: "grail", Feature: "ATG", FeatStart: 16, FeatEnd: 19, FeatScore: floatPtr(2.1), FeatFrame: Frame0, FeatStrand: seq.Minus}, 61 }, 62 }, 63 } 64 65 metaTests = []struct { 66 date string 67 format string 68 sourceVersion string 69 version int 70 name string 71 molType feat.Moltype 72 gff string 73 feat []feat.Feature 74 write []interface{} 75 }{ 76 { 77 date: "1997-11-08", 78 format: Astronomical, 79 sourceVersion: "<source> <version-text>", 80 version: 2, 81 name: "<seqname>", 82 molType: feat.DNA, 83 84 gff: `##gff-version 2 85 ##source-version <source> <version-text> 86 ##date 1997-11-08 87 ##Type DNA <seqname> 88 ##DNA <seqname> 89 ##acggctcggattggcgctggatgatagatcagacgac 90 ##... 91 ##end-DNA 92 ##RNA <seqname> 93 ##acggcucggauuggcgcuggaugauagaucagacgac 94 ##... 95 ##end-RNA 96 ##Protein <seqname> 97 ##MVLSPADKTNVKAAWGKVGAHAGEYGAEALERMFLSF 98 ##... 99 ##end-Protein 100 ##sequence-region <seqname> 1 5 101 `, 102 feat: []feat.Feature{ 103 linear.NewSeq("<seqname>", alphabet.BytesToLetters([]byte("acggctcggattggcgctggatgatagatcagacgac...")), alphabet.DNA), 104 linear.NewSeq("<seqname>", alphabet.BytesToLetters([]byte("acggcucggauuggcgcuggaugauagaucagacgac...")), alphabet.RNA), 105 linear.NewSeq("<seqname>", alphabet.BytesToLetters([]byte("MVLSPADKTNVKAAWGKVGAHAGEYGAEALERMFLSF...")), alphabet.Protein), 106 &Region{Sequence: Sequence{SeqName: "<seqname>", Type: feat.DNA}, RegionStart: 0, RegionEnd: 5}, 107 }, 108 write: []interface{}{ 109 2, 110 "source-version <source> <version-text>", 111 mustTime(time.Parse(Astronomical, "1997-11-08")), 112 Sequence{SeqName: "<seqname>", Type: feat.DNA}, 113 linear.NewSeq("<seqname>", alphabet.BytesToLetters([]byte("acggctcggattggcgctggatgatagatcagacgac...")), alphabet.DNA), 114 linear.NewSeq("<seqname>", alphabet.BytesToLetters([]byte("acggcucggauuggcgcuggaugauagaucagacgac...")), alphabet.RNA), 115 linear.NewSeq("<seqname>", alphabet.BytesToLetters([]byte("MVLSPADKTNVKAAWGKVGAHAGEYGAEALERMFLSF...")), alphabet.Protein), 116 &Region{Sequence: Sequence{SeqName: "<seqname>"}, RegionStart: 0, RegionEnd: 5}, 117 }, 118 }, 119 } 120 ) 121 122 func (s *S) TestUnsafeString(c *check.C) { 123 for _, t := range []string{ 124 "I", 125 "Lorem", 126 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", 127 } { 128 b := []byte(t) 129 c.Check(unsafeString(b), check.Equals, t) 130 } 131 } 132 133 func (s *S) TestReadGFF(c *check.C) { 134 for i, g := range gffTests { 135 buf := strings.NewReader(g.gff) 136 r := NewReader(buf) 137 for j := 0; ; j++ { 138 f, err := r.Read() 139 if err == io.EOF { 140 c.Check(j, check.Equals, len(g.feat)) 141 break 142 } 143 c.Check(f, check.DeepEquals, g.feat[j], check.Commentf("Test: %d Line: %d", i, j+1)) 144 c.Check(err, check.Equals, nil) 145 } 146 } 147 } 148 149 func (s *S) TestReadMetaline(c *check.C) { 150 for i, g := range metaTests { 151 buf := strings.NewReader(g.gff) 152 r := NewReader(buf) 153 for j := 0; ; j++ { 154 f, err := r.Read() 155 if err == io.EOF { 156 c.Check(j, check.Equals, len(g.feat)) 157 break 158 } 159 c.Check(f, check.DeepEquals, g.feat[j], check.Commentf("Test: %d Line: %d", i, j+1)) 160 c.Check(err, check.Equals, nil) 161 } 162 c.Check(r.Version, check.Equals, g.version) 163 date, err := time.Parse(g.format, g.date) 164 c.Assert(err, check.Equals, nil) 165 c.Check(r.Name, check.Equals, g.name) 166 c.Check(r.Type, check.Equals, g.molType) 167 c.Check(r.Date, check.Equals, date) 168 c.Check(r.SourceVersion, check.Equals, g.sourceVersion) 169 } 170 } 171 172 const width = 37 // Not the normal fasta width - this matches the examples from the GFF spec page. 173 174 func (s *S) TestWriteGff(c *check.C) { 175 for i, g := range gffTests { 176 buf := &bytes.Buffer{} 177 w := NewWriter(buf, width, false) 178 var n int 179 for _, f := range g.feat { 180 _n, err := w.Write(f) 181 c.Check(err, check.Equals, nil) 182 n += _n 183 } 184 c.Check(buf.Len(), check.Equals, n) 185 c.Check(buf.String(), check.Equals, g.gff, check.Commentf("Test: %d", i)) 186 } 187 } 188 189 func (s *S) TestWriteMetadata(c *check.C) { 190 for i, g := range metaTests { 191 buf := &bytes.Buffer{} 192 w := NewWriter(buf, width, false) 193 var n int 194 for _, d := range g.write { 195 _n, err := w.WriteMetaData(d) 196 c.Check(err, check.Equals, nil) 197 n += _n 198 } 199 c.Check(buf.Len(), check.Equals, n) 200 c.Check(buf.String(), check.Equals, g.gff, check.Commentf("Test: %d", i)) 201 } 202 }