]> git.donarmstrong.com Git - biopieces.git/blob - code_ruby/test/maasha/test_seq.rb
added test for length of seq/qual mismatch
[biopieces.git] / code_ruby / test / maasha / test_seq.rb
1 #!/usr/bin/env ruby
2 $:.unshift File.join(File.dirname(__FILE__), '..', '..')
3
4 # Copyright (C) 2011 Martin A. Hansen.
5
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
10
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
20 # http://www.gnu.org/copyleft/gpl.html
21
22 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
23
24 # This software is part of the Biopieces framework (www.biopieces.org).
25
26 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
27
28 require 'maasha/seq'
29 require 'test/unit'
30 require 'test/helper'
31
32 class TestSeq < Test::Unit::TestCase 
33   def setup
34     @entry = Seq.new
35   end
36
37   test "Seq.new with differnet length SEQ and SCORES raises" do
38     assert_raise(SeqError) { Seq.new("test", "ATCG", "dna", "hhh") }
39   end
40
41   test "Seq.new_bp returns correctly" do
42     record = {:SEQ_NAME => "test", :SEQ => "ATCG", :SEQ_TYPE => :dna, :SCORES => "hhhh"}
43     seq    = Seq.new_bp(record)
44     assert_equal("test", seq.seq_name)
45     assert_equal("ATCG", seq.seq)
46     assert_equal(:dna,  seq.type)
47     assert_equal("hhhh", seq.qual)
48   end
49
50   test "#is_dna? with no sequence type returns false" do
51     assert(@entry.is_dna? == false)
52   end
53
54   test "#is_dna? with dna sequence type returns true" do
55     @entry.type = :dna
56     assert(@entry.is_dna? == true)
57   end
58
59   test "#is_rna? with no sequence type returns false" do
60     assert(@entry.is_rna? == false)
61   end
62
63   test "#is_rna? with rna sequence type returns true" do
64     @entry.type = :rna
65     assert(@entry.is_rna? == true)
66   end
67
68   test "#is_protein? with no sequence type returns false" do
69     assert(@entry.is_protein? == false)
70   end
71
72   test "#is_protein? with protein sequence type returns true" do
73     @entry.type = :protein
74     assert_equal(true, @entry.is_protein?)
75   end
76
77   test "#type_guess without sequence raises" do
78     assert_raise(SeqError) { @entry.type_guess }
79   end
80
81   test "#type_guess with protein returns protein" do
82     @entry.seq = 'atcatcrFgatcg'
83     assert_equal(:protein, @entry.type_guess)
84   end
85
86   test "#type_guess with rna returns rna" do
87     @entry.seq = 'atcatcrUgatcg'
88     assert_equal(:rna, @entry.type_guess)
89   end
90
91   test "#type_guess with dna returns dna" do
92     @entry.seq = 'atcatcgatcg'
93     assert_equal(:dna, @entry.type_guess)
94   end
95
96   test "#type_guess! without sequence raises" do
97     assert_raise(SeqError) { @entry.type_guess! }
98   end
99
100   test "#type_guess! with protein returns protein" do
101     @entry.seq = 'atcatcrFgatcg'
102     @entry.type_guess!
103     assert_equal(:protein, @entry.type)
104   end
105
106   test "#type_guess! with rna returns rna" do
107     @entry.seq = 'atcatcrUgatcg'
108     @entry.type_guess!
109     assert_equal(:rna, @entry.type)
110   end
111
112   test "#type_guess! with dna returns dna" do
113     @entry.seq = 'atcatcgatcg'
114     @entry.type_guess!
115     assert_equal(:dna, @entry.type)
116   end
117
118   test "#length returns corretly" do
119     @entry.seq = 'ATCG'
120     assert_equal(4, @entry.length)
121   end
122
123   test "#indels returns correctly" do
124     @entry.seq = 'ATCG.-~_'
125     assert_equal(4, @entry.indels)
126   end
127
128   test "#to_rna with no sequence raises" do
129     @entry.type = :dna
130     assert_raise(SeqError) { @entry.to_rna }
131   end
132
133   test "#to_rna with bad type raises" do
134     @entry.seq  = 'ATCG'
135     @entry.type = :rna
136     assert_raise(SeqError) { @entry.to_rna }
137   end
138
139   test "#to_rna transcribes correctly" do
140     @entry.seq  = 'ATCGatcg'
141     @entry.type = :dna
142     assert_equal("AUCGaucg", @entry.to_rna)
143   end
144
145   test "#to_rna changes entry type to rna" do
146     @entry.seq  = 'ATCGatcg'
147     @entry.type = :dna
148     @entry.to_rna
149     assert_equal(:rna, @entry.type)
150   end
151
152   test "#to_dna with no sequence raises" do
153     @entry.type = :rna
154     assert_raise(SeqError) { @entry.to_dna }
155   end
156
157   test "#to_dna with bad type raises" do
158     @entry.seq  = 'AUCG'
159     @entry.type = :dna
160     assert_raise(SeqError) { @entry.to_dna }
161   end
162
163   test "#to_dna transcribes correctly" do
164     @entry.seq  = 'AUCGaucg'
165     @entry.type = :rna
166     assert_equal("ATCGatcg", @entry.to_dna)
167   end
168
169   test "#to_dna changes entry type to dna" do
170     @entry.seq  = 'AUCGaucg'
171     @entry.type = :rna
172     @entry.to_dna
173     assert_equal(:dna, @entry.type)
174   end
175
176   test "#to_bp returns correct record" do
177     @entry.seq_name = 'test'
178     @entry.seq      = 'ATCG'
179     assert_equal({:SEQ_NAME=>"test", :SEQ=>"ATCG", :SEQ_LEN=>4}, @entry.to_bp)
180   end
181
182   test "#to_bp with missing seq_name raises" do
183     @entry.seq = 'ATCG'
184     assert_raise(SeqError) { @entry.to_bp }
185   end
186
187   test "#to_bp with missing sequence raises" do
188     @entry.seq_name = 'test'
189     assert_raise(SeqError) { @entry.to_bp }
190   end
191
192   test "#to_fasta with missing seq_name raises" do
193     @entry.seq = 'ATCG'
194     assert_raise(SeqError) { @entry.to_fasta }
195   end
196
197   test "#to_fasta with empty seq_name raises" do
198     @entry.seq_name = ''
199     @entry.seq      = 'ATCG'
200     assert_raise(SeqError) { @entry.to_fasta }
201   end
202
203   test "#to_fasta with missing seq raises" do
204     @entry.seq_name = 'test'
205     assert_raise(SeqError) { @entry.to_fasta }
206   end
207
208   test "#to_fasta with empty seq raises" do
209     @entry.seq_name = 'test'
210     @entry.seq      = ''
211     assert_raise(SeqError) { @entry.to_fasta }
212   end
213
214   test "#to_fasta returns correct entry" do
215     @entry.seq_name = 'test'
216     @entry.seq      = 'ATCG'
217     assert_equal(">test\nATCG\n", @entry.to_fasta)
218   end
219
220   test "#to_fasta wraps correctly" do
221     entry = Seq.new("test", "ATCG")
222     assert_equal(">test\nAT\nCG\n", entry.to_fasta(2))
223   end
224
225   test "#to_fastq returns correct entry" do
226     @entry.seq_name = 'test'
227     @entry.seq      = 'ATCG'
228     @entry.qual     = 'hhhh'
229     assert_equal("@test\nATCG\n+\nhhhh\n", @entry.to_fastq)
230   end
231
232   test "#to_key with bad residue raises" do
233     entry = Seq.new("test", "AUCG")
234     assert_raise(SeqError) { entry.to_key }
235   end
236
237   test "#to_key returns correctly" do
238     entry = Seq.new("test", "ATCG")
239     assert_equal(54, entry.to_key)
240   end
241
242   test "#reverse returns correctly" do
243     @entry.seq = "ATCG"
244     new_entry  = @entry.reverse
245     assert_equal("GCTA", new_entry.seq)
246     assert_equal("ATCG", @entry.seq)
247   end
248
249   test "#reverse! returns correctly" do
250     @entry.seq = "ATCG"
251     @entry.reverse!
252     assert_equal("GCTA", @entry.seq)
253   end
254
255   test "#complement with no sequence raises" do
256     @entry.type = :dna
257     assert_raise(SeqError) { @entry.complement }
258   end
259
260   test "#complement with bad type raises" do
261     @entry.seq  = 'ATCG'
262     @entry.type = :protein
263     assert_raise(SeqError) { @entry.complement }
264   end
265
266   test "#complement for DNA is correct" do
267     @entry.seq  = 'ATCGatcg'
268     @entry.type = :dna
269     comp        = @entry.complement
270     assert_equal("TAGCtagc", comp.seq)
271     assert_equal("ATCGatcg", @entry.seq)
272   end
273
274   test "#complement for RNA is correct" do
275     @entry.seq  = 'AUCGaucg'
276     @entry.type = :rna
277     comp        = @entry.complement
278     assert_equal("UAGCuagc", comp.seq)
279     assert_equal("AUCGaucg", @entry.seq)
280   end
281
282   test "#complement! with no sequence raises" do
283     @entry.type = :dna
284     assert_raise(SeqError) { @entry.complement! }
285   end
286
287   test "#complement! with bad type raises" do
288     @entry.seq  = 'ATCG'
289     @entry.type = :protein
290     assert_raise(SeqError) { @entry.complement! }
291   end
292
293   test "#complement! for DNA is correct" do
294     @entry.seq  = 'ATCGatcg'
295     @entry.type = :dna
296     assert_equal("TAGCtagc", @entry.complement!.seq)
297   end
298
299   test "#complement! for RNA is correct" do
300     @entry.seq  = 'AUCGaucg'
301     @entry.type = :rna
302     assert_equal("UAGCuagc", @entry.complement!.seq)
303   end
304
305   test "#hamming_distance returns correctly" do
306     seq1 = Seq.new("test1", "ATCG")
307     seq2 = Seq.new("test2", "atgg")
308     assert_equal(1, seq1.hamming_distance(seq2))
309   end
310
311   test "#hamming_distance with ambiguity codes return correctly" do
312     seq1 = Seq.new("test1", "ATCG")
313     seq2 = Seq.new("test2", "atng")
314
315     assert_equal(1, seq1.hamming_distance(seq2))
316     assert_equal(0, seq1.hamming_distance(seq2, ambiguity: true))
317   end
318
319   test "#edit_distance returns correctly" do
320     seq1 = Seq.new("test1", "ATCG")
321     seq2 = Seq.new("test2", "tgncg")
322     assert_equal(2, seq1.edit_distance(seq2))
323   end
324
325   test "#generate with length < 1 raises" do
326     assert_raise(SeqError) { @entry.generate(-10, :dna) }
327     assert_raise(SeqError) { @entry.generate(0, :dna) }
328   end
329
330   test "#generate with bad type raises" do
331     assert_raise(SeqError) { @entry.generate(10, "foo") }
332   end
333
334   test "#generate with ok type dont raise" do
335     %w[dna rna protein].each do |type|
336       assert_nothing_raised { @entry.generate(10, type.to_sym) }
337     end
338   end
339
340   test "#shuffle returns correctly" do
341     orig       = "actgactgactgatcgatcgatcgatcgtactg" 
342     @entry.seq = "actgactgactgatcgatcgatcgatcgtactg"
343     entry_shuf = @entry.shuffle
344     assert_equal(orig, @entry.seq)
345     assert_not_equal(@entry.seq, entry_shuf.seq)
346   end
347
348   test "#shuffle! returns correctly" do
349     @entry.seq = "actgactgactgatcgatcgatcgatcgtactg"
350     assert_not_equal(@entry.seq, @entry.shuffle!.seq)
351   end
352
353   test "#+ without qual returns correctly" do
354     entry = Seq.new("test1", "at") + Seq.new("test2", "cg")
355     assert_nil(entry.seq_name)
356     assert_equal("atcg", entry.seq)
357     assert_nil(entry.type)
358     assert_nil(entry.qual)
359   end
360
361   test "#+ with qual returns correctly" do
362     entry = Seq.new("test1", "at", :dna, "II") + Seq.new("test2", "cg", :dna, "JJ")
363     assert_nil(entry.seq_name)
364     assert_equal("atcg", entry.seq)
365     assert_equal(:dna,   entry.type)
366     assert_equal("IIJJ", entry.qual)
367   end
368
369   test "#<< with different types raises" do
370     @entry.seq = "atcg"
371     assert_raise(SeqError) { @entry << Seq.new("test", "atcg", :dna) }
372   end
373
374   test "#<< with missing qual in one entry raises" do
375     @entry.seq  = "atcg"
376     @entry.type = :dna
377     assert_raise(SeqError) { @entry << Seq.new("test", "atcg", :dna, "IIII") }
378     @entry.qual = "IIII"
379     assert_raise(SeqError) { @entry << Seq.new("test", "atcg", :dna) }
380   end
381
382   test "#<< with nil qual in both entries dont raise" do
383     @entry.seq = "atcg"
384     assert_nothing_raised { @entry << Seq.new("test", "atcg") }
385   end
386
387   test "#<< with qual in both entries dont raise" do
388     @entry.seq  = "atcg"
389     @entry.type = :dna
390     @entry.qual = "IIII"
391     assert_nothing_raised { @entry << Seq.new("test", "atcg", :dna, "IIII") }
392   end
393
394   test "#<< without qual returns correctly" do
395     @entry.seq  = "atcg"
396     @entry <<  Seq.new("test", "ATCG")
397     assert_equal("atcgATCG", @entry.seq)
398   end
399
400   test "#<< with qual returns correctly" do
401     @entry.seq  = "atcg"
402     @entry.type = :dna
403     @entry.qual = "HHHH"
404     @entry <<  Seq.new("test", "ATCG", :dna, "IIII")
405     assert_equal("atcgATCG", @entry.seq)
406     assert_equal("HHHHIIII", @entry.qual)
407   end
408
409   test "#[] with qual returns correctly" do
410     entry = Seq.new("test", "atcg", :dna, "FGHI")
411
412     e = entry[2]
413
414     assert_equal("test", e.seq_name)
415     assert_equal("c",    e.seq)
416     assert_equal(:dna,   e.type)
417     assert_equal("H",    e.qual)
418     assert_equal("atcg", entry.seq)
419     assert_equal("FGHI", entry.qual)
420   end
421
422   test "#[] without qual returns correctly" do
423     entry = Seq.new("test", "atcg")
424
425     e = entry[2]
426
427     assert_equal("test", e.seq_name)
428     assert_equal("c",    e.seq)
429     assert_nil(e.qual)
430     assert_equal("atcg", entry.seq)
431   end
432
433   test "[]= with qual returns correctly" do
434     entry = Seq.new("test", "atcg", :dna, "FGHI")
435
436     entry[0] = Seq.new("foo", "T", :dna, "I")
437
438     assert_equal("test", entry.seq_name)
439     assert_equal("Ttcg", entry.seq)
440     assert_equal(:dna,   entry.type)
441     assert_equal("IGHI", entry.qual)
442   end
443
444   test "[]= without qual returns correctly" do
445     entry = Seq.new("test", "atcg")
446
447     entry[0] = Seq.new("foo", "T")
448
449     assert_equal("test", entry.seq_name)
450     assert_equal("Ttcg", entry.seq)
451   end
452
453   test "#subseq with start < 0 raises" do
454     @entry.seq = "ATCG"
455     assert_raise(SeqError) { @entry.subseq(-1, 1) }
456   end
457
458   test "#subseq with start plus length gt seq raises" do
459     @entry.seq = "ATCG"
460     assert_raise(SeqError) { @entry.subseq(0, 5) }
461   end
462
463   test "#subseq returns correct sequence" do
464     @entry.seq  = "ATCG"
465     assert_equal("AT", @entry.subseq(0, 2).seq)
466     assert_equal("CG", @entry.subseq(2, 2).seq)
467   end
468
469   test "#subseq without length returns correct sequence" do
470     @entry.seq  = "ATCG"
471     assert_equal("ATCG", @entry.subseq(0).seq)
472     assert_equal("CG",   @entry.subseq(2).seq)
473   end
474
475   test "#subseq returns correct qual" do
476     @entry.seq  = "ATCG"
477     @entry.qual = "abcd"
478     assert_equal("ab", @entry.subseq(0, 2).qual)
479     assert_equal("cd", @entry.subseq(2, 2).qual)
480   end
481
482   test "#subseq without length returns correct qual" do
483     @entry.seq  = "ATCG"
484     @entry.qual = "abcd"
485     assert_equal("abcd", @entry.subseq(0).qual)
486     assert_equal("cd",   @entry.subseq(2).qual)
487   end
488
489   test "#subseq! with start < 0 raises" do
490     @entry.seq = "ATCG"
491     assert_raise(SeqError) { @entry.subseq!(-1, 1) }
492   end
493
494   test "#subseq! with start plus length > seq.length raises" do
495     @entry.seq = "ATCG"
496     assert_raise(SeqError) { @entry.subseq!(0, 5) }
497   end
498
499   test "#subseq! returns correct sequence" do
500     @entry.seq  = "ATCG"
501     @entry.subseq!(0, 2)
502     assert_equal("AT", @entry.seq)
503     @entry.seq  = "ATCG"
504     @entry.subseq!(2, 2)
505     assert_equal("CG", @entry.seq)
506   end
507
508   test "#subseq! without length returns correct sequence" do
509     @entry.seq  = "ATCG"
510     @entry.subseq!(0)
511     assert_equal("ATCG", @entry.seq)
512     @entry.seq  = "ATCG"
513     @entry.subseq!(2)
514     assert_equal("CG", @entry.seq)
515   end
516
517   test "#subseq! with pos and length returns correct qual" do
518     @entry.seq  = "ATCG"
519     @entry.qual = "abcd"
520     @entry.subseq!(0, 2)
521     assert_equal("ab", @entry.qual)
522     @entry.seq  = "ATCG"
523     @entry.qual = "abcd"
524     @entry.subseq!(2, 2)
525     assert_equal("cd", @entry.qual)
526   end
527
528   test "#subseq! with pos returns correct qual" do
529     @entry.seq  = "ATCG"
530     @entry.qual = "abcd"
531     @entry.subseq!(0)
532     assert_equal("abcd", @entry.qual)
533     @entry.seq  = "ATCG"
534     @entry.qual = "abcd"
535     @entry.subseq!(2)
536     assert_equal("cd", @entry.qual)
537   end
538
539   test "#subseq_rand returns correct sequence" do
540     @entry.seq  = "ATCG"
541     assert_equal("ATCG", @entry.subseq_rand(4).seq)
542   end
543
544   test "#indels_remove without qual returns correctly" do
545     @entry.seq  = "A-T.CG~CG"
546     @entry.qual = nil
547     assert_equal("ATCGCG", @entry.indels_remove.seq)
548   end
549
550   test "#indels_remove with qual returns correctly" do
551     @entry.seq  = "A-T.CG~CG"
552     @entry.qual = "a@b@cd@fg"
553     assert_equal("ATCGCG", @entry.indels_remove.seq)
554     assert_equal("abcdfg", @entry.indels_remove.qual)
555   end
556
557   test "#composition returns correctly" do
558     @entry.seq = "AAAATTTCCG"
559     assert_equal(4, @entry.composition["A"])
560     assert_equal(3, @entry.composition["T"])
561     assert_equal(2, @entry.composition["C"])
562     assert_equal(1, @entry.composition["G"])
563     assert_equal(0, @entry.composition["X"])
564   end
565
566   test "#hard_mask returns correctly" do
567     @entry.seq = "--AAAANn"
568     assert_equal(33.33, @entry.hard_mask)
569   end
570
571   test "#soft_mask returns correctly" do
572     @entry.seq = "--AAAa"
573     assert_equal(25.00, @entry.soft_mask)
574   end
575
576   test "#mask_seq_hard! with nil seq raises" do
577     @entry.seq  = nil
578     @entry.qual = ""
579
580     assert_raise(SeqError) { @entry.mask_seq_hard!(20) }
581   end
582
583   test "#mask_seq_hard! with nil qual raises" do
584     @entry.seq  = ""
585     @entry.qual = nil
586
587     assert_raise(SeqError) { @entry.mask_seq_hard!(20) }
588   end
589
590   test "#mask_seq_hard! with bad cutoff raises" do
591     assert_raise(SeqError) { @entry.mask_seq_hard!(-1) }
592     assert_raise(SeqError) { @entry.mask_seq_hard!(41) }
593   end
594
595   test "#mask_seq_hard! with OK cutoff dont raise" do
596     @entry.seq  = "ATCG"
597     @entry.qual = "RSTU"
598
599     assert_nothing_raised { @entry.mask_seq_hard!(0) }
600     assert_nothing_raised { @entry.mask_seq_hard!(40) }
601   end
602
603   test "#mask_seq_hard! returns correctly" do
604     @entry.seq  = "-ATCG"
605     @entry.qual = "33456"
606
607     assert_equal("-NNCG", @entry.mask_seq_hard!(20).seq)
608   end
609
610   test "#mask_seq_soft! with nil seq raises" do
611     @entry.seq  = nil
612     @entry.qual = ""
613
614     assert_raise(SeqError) { @entry.mask_seq_soft!(20) }
615   end
616
617   test "#mask_seq_soft! with nil qual raises" do
618     @entry.seq  = ""
619     @entry.qual = nil
620
621     assert_raise(SeqError) { @entry.mask_seq_soft!(20) }
622   end
623
624   test "#mask_seq_soft! with bad cutoff raises" do
625     assert_raise(SeqError) { @entry.mask_seq_soft!(-1) }
626     assert_raise(SeqError) { @entry.mask_seq_soft!(41) }
627   end
628
629   test "#mask_seq_soft! with OK cutoff dont raise" do
630     @entry.seq  = "ATCG"
631     @entry.qual = "RSTU"
632
633     assert_nothing_raised { @entry.mask_seq_soft!(0) }
634     assert_nothing_raised { @entry.mask_seq_soft!(40) }
635   end
636
637   test "#mask_seq_soft! returns correctly" do
638     @entry.seq  = "-ATCG"
639     @entry.qual = "33456"
640
641     assert_equal("-atCG", @entry.mask_seq_soft!(20).seq)
642   end
643
644   # qual score detection
645
646   test "#qual_base33? returns correctly" do
647     # self.qual.match(/[!-:]/)
648     @entry.qual = '!"#$%&\'()*+,-./0123456789:'
649     assert_equal(true,  @entry.qual_base33? )
650     @entry.qual = 32.chr
651     assert_equal(false, @entry.qual_base33? )
652     @entry.qual = 59.chr
653     assert_equal(false, @entry.qual_base33? )
654   end
655
656   test "#qual_base64? returns correctly" do
657     # self.qual.match(/[K-h]/)
658     @entry.qual = 'KLMNOPQRSTUVWXYZ[\]^_`abcdefgh'
659     assert_equal(true,  @entry.qual_base64? )
660     @entry.qual = 74.chr
661     assert_equal(false, @entry.qual_base64? )
662     @entry.qual = 105.chr
663     assert_equal(false, @entry.qual_base64? )
664   end
665
666   test "#qual_valid? with nil qual raises" do
667     assert_raise(SeqError) { @entry.qual_valid?(:base_33) }
668     assert_raise(SeqError) { @entry.qual_valid?(:base_64) }
669   end
670
671   test "#qual_valid? with bad encoding raises" do
672     @entry.qual = "abc"
673     assert_raise(SeqError) { @entry.qual_valid?("foobar") }
674   end
675
676   test "#qual_valid? with OK range returns correctly" do
677     @entry.qual = ((Seq::SCORE_MIN + 33).chr .. (Seq::SCORE_MAX + 33).chr).to_a.join
678     assert_equal(true,  @entry.qual_valid?(:base_33))
679     @entry.qual = ((Seq::SCORE_MIN + 64).chr .. (Seq::SCORE_MAX + 64).chr).to_a.join
680     assert_equal(true,  @entry.qual_valid?(:base_64))
681   end
682
683   test "#qual_valid? with bad range returns correctly" do
684     @entry.qual = ((Seq::SCORE_MIN + 33 - 1).chr .. (Seq::SCORE_MAX + 33).chr).to_a.join
685     assert_equal(false,  @entry.qual_valid?(:base_33))
686     @entry.qual = ((Seq::SCORE_MIN + 33).chr .. (Seq::SCORE_MAX + 33 + 1).chr).to_a.join
687     assert_equal(false,  @entry.qual_valid?(:base_33))
688
689     @entry.qual = ((Seq::SCORE_MIN + 64 - 1).chr .. (Seq::SCORE_MAX + 64).chr).to_a.join
690     assert_equal(false,  @entry.qual_valid?(:base_64))
691     @entry.qual = ((Seq::SCORE_MIN + 64).chr .. (Seq::SCORE_MAX + 64 + 1).chr).to_a.join
692     assert_equal(false,  @entry.qual_valid?(:base_64))
693   end
694
695   # convert sanger to ...
696
697   test "#qual_convert! from base33 to base33 returns OK" do
698     @entry.qual = 'BCDEFGHI'
699     assert_equal('BCDEFGHI', @entry.qual_convert!(:base_33, :base_33).qual)
700   end
701
702   test "#qual_convert! from base33 to base64 returns OK" do
703     @entry.qual = 'BCDEFGHI'
704     assert_equal('abcdefgh', @entry.qual_convert!(:base_33, :base_64).qual)
705   end
706
707   test "#qual_convert! from base64 to base64 returns OK" do
708     @entry.qual = 'BCDEFGHI'
709     assert_equal('BCDEFGHI', @entry.qual_convert!(:base_64, :base_64).qual)
710   end
711
712   test "#qual_convert! from base64 to base33 returns OK" do
713     @entry.qual = 'abcdefgh'
714     assert_equal('BCDEFGHI', @entry.qual_convert!(:base_64, :base_33).qual)
715   end
716
717   test "#qual_coerce! returns correctly" do
718     @entry.qual = ('!' .. '~').to_a.join
719     assert_equal("!\"\#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII", @entry.qual_coerce!(:base_33).qual)
720     @entry.qual = ('!' .. '~').to_a.join
721     assert_equal("!\"\#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZh\\h^_`abcdefghhhhhhhhhhhhhhhhhhhhhhh", @entry.qual_coerce!(:base_64).qual)
722   end
723
724   test "#scores_mean without qual raises" do
725     @entry.qual = nil
726     assert_raise(SeqError) { @entry.scores_mean }
727   end
728
729   test "#scores_mean returns correctly" do
730     @entry.qual = '!!II'
731     assert_equal(20.0, @entry.scores_mean)
732   end
733 end