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  }