]> git.donarmstrong.com Git - biopieces.git/blob - code_ruby/test/maasha/test_sam.rb
3671a8dca2b72423016e6c8bb55d38b47eb4d5ce
[biopieces.git] / code_ruby / test / maasha / test_sam.rb
1 #!/usr/bin/env ruby
2
3 # Copyright (C) 2011 Martin A. Hansen.
4
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
19 # http://www.gnu.org/copyleft/gpl.html
20
21 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
22
23 # This software is part of the Biopieces framework (www.biopieces.org).
24
25 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
26
27 require 'test/unit'
28 require 'maasha/sam'
29 require 'pp'
30 require 'stringio'
31
32 SAM_DATA =
33 %{@HD\tVN:1.3\tSO:coordinate
34 @SQ\tSN:ref\tLN:45
35 @CO\tMyComment
36 r001\t163\tref\t7\t30\t8M2I4M1D3M\t=\t37\t39\tTTAGATAAAGGATACTG\t*
37 r002\t0\tref\t9\t30\t3S6M1P1I4M\t*\t0\t0\tAAAAGATAAGGATA\t*
38 r003\t0\tref\t9\t30\t5H6M\t*\t0\t0\tAGCTAA\t*\tNM:i:1
39 r004\t0\tref\t16\t30\t6M14N5M\t*\t0\t0\tATAGCTTCAGC\t*
40 r003\t16\tref\t29\t30\t6H5M\t*\t0\t0\tTAGGC\t*\tNM:i:0
41 r001\t83\tref\t37\t30\t9M\t=\t7\t-39\tCAGCGCCAT\t*
42 }
43
44 class SamTest < Test::Unit::TestCase
45   def setup
46     @sam = Sam.new(StringIO.new(SAM_DATA))
47   end
48
49   def test_Sam_new_with_missing_version_number_raises
50     assert_raise(SamError) { Sam.new(StringIO.new("@HD")) }
51   end
52
53   def test_Sam_new_with_bad_version_number_raises
54     assert_raise(SamError) { Sam.new(StringIO.new("@HD\tXN:1.3")) }
55   end
56
57   def test_Sam_new_with_ok_version_number_returns_correctly
58     sam = Sam.new(StringIO.new("@HD\tVN:1.3"))
59     assert_equal(1.3, sam.header[:HD][:VN])
60   end
61
62   def test_Sam_new_with_bad_sort_order_raises
63     assert_raise(SamError) { Sam.new(StringIO.new("@HD\tVN:1.3\tSO:fish")) }
64   end
65
66   def test_Sam_new_with_ok_sort_order_returns_correctly
67     %w{unknown unsorted queryname coordinate}.each do |order|
68       sam = Sam.new(StringIO.new("@HD\tVN:1.3\tSO:#{order}"))
69       assert_equal(order, sam.header[:HD][:SO])
70     end
71   end
72
73   def test_Sam_new_with_missing_sequence_name_raises
74     assert_raise(SamError) { Sam.new(StringIO.new("@SQ")) }
75   end
76
77   def test_Sam_new_with_bad_sequence_name_raises
78     assert_raise(SamError) { Sam.new(StringIO.new("@SQ\tSN:")) }
79   end
80
81   def test_Sam_new_with_ok_sequence_name_returns_correctly
82     sam = Sam.new(StringIO.new("@SQ\tSN:ref\tLN:45"))
83     assert_equal({:LN=>45}, sam.header[:SQ][:SN][:ref])
84   end
85
86   def test_Sam_new_with_duplicate_sequence_name_raises
87     assert_raise(SamError) { Sam.new(StringIO.new("@SQ\tSN:ref\n@SQ\tSN:ref")) }
88   end
89
90   def test_Sam_new_with_missing_sequence_length_raises
91     assert_raise(SamError) { Sam.new(StringIO.new("@SQ\tSN:ref")) }
92   end
93
94   def test_Sam_new_with_bad_sequence_length_raises
95     assert_raise(SamError) { Sam.new(StringIO.new("@SQ\tSN:scaffold17_1_MH0083\tLN:x")) }
96   end
97
98   def test_Sam_new_with_ok_sequence_length_returns_correctly
99     sam = Sam.new(StringIO.new("@SQ\tSN:scaffold17_1_MH0083\tLN:995"))
100     assert_equal(995, sam.header[:SQ][:SN][:scaffold17_1_MH0083][:LN])
101   end
102
103   def test_Sam_new_with_full_SQ_dont_raise
104     sam = Sam.new(StringIO.new("@SQ\tSN:ref\tLN:45\tAS:ident\tM5:87e6b2aedf51b1f9c89becfab9267f41\tSP:E.coli\tUR:http://www.biopieces.org"))
105     assert_nothing_raised { sam.header }
106   end
107
108   def test_Sam_new_with_bad_read_group_identifier_raises
109     assert_raise(SamError) { Sam.new(StringIO.new("@RG\tID:")) }
110   end
111
112   def test_Sam_new_with_missing_read_group_identifier_raises
113     assert_raise(SamError) { Sam.new(StringIO.new("@RG")) }
114   end
115
116   def test_Sam_new_with_duplicate_read_group_identifier_raises
117     assert_raise(SamError) { Sam.new(StringIO.new("@RG\tID:123\n@RG\tID:123")) }
118   end
119
120   def test_Sam_new_with_ok_read_group_identifier_dont_raise
121     sam = Sam.new(StringIO.new("@RG\tID:123\n@RG\tID:124"))
122     assert_nothing_raised { sam.header }
123   end
124
125   def test_Sam_new_with_bad_flow_order_raises
126     assert_raise(SamError) { Sam.new(StringIO.new("@RG\tID:123\tFO:3")) }
127   end
128
129   def test_Sam_new_with_ok_flow_order_dont_raise
130     sam = Sam.new(StringIO.new("@RG\tID:123\tFO:*"))
131     assert_nothing_raised { sam.header }
132     sam = Sam.new(StringIO.new("@RG\tID:123\tFO:ACMGRSVTWYHKDBN"))
133     assert_nothing_raised { sam.header }
134   end
135
136   def test_Sam_new_with_bad_platform_raises
137     assert_raise(SamError) { Sam.new(StringIO.new("@RG\tID:123\tPL:maersk")) }
138   end
139
140   def test_Sam_new_with_ok_platform_dont_raise
141     sam = Sam.new(StringIO.new("@RG\tID:123\tPL:ILLUMINA"))
142     assert_nothing_raised { sam.header }
143   end
144
145   def test_Sam_new_with_bad_program_identifier_raises
146     assert_raise(SamError) { Sam.new(StringIO.new("@PG\tID:")) }
147   end
148
149   def test_Sam_new_with_missing_program_identifier_raises
150     assert_raise(SamError) { Sam.new(StringIO.new("@PG")) }
151   end
152
153   def test_Sam_new_with_duplicate_program_identifier_raises
154     assert_raise(SamError) { Sam.new(StringIO.new("@PG\tID:123\n@PG\tID:123")) }
155   end
156
157   def test_Sam_new_with_bad_comment_raises
158     assert_raise(SamError) { Sam.new(StringIO.new("@CO\t")) }
159   end 
160
161   def test_Sam_new_with_ok_comment_dont_raise
162     sam = Sam.new(StringIO.new("@CO\tfubar"))
163     assert_nothing_raised { sam.header }
164   end
165
166   def test_Sam_each_with_bad_field_count_raises
167     fields = []
168
169     (0 ... 11).each do |i|
170       sam = Sam.new(StringIO.new(fields.join("\t") + $/))
171       assert_raise(SamError) { sam.each }
172       fields << "*"
173     end
174   end
175
176   def test_Sam_each_with_ok_field_count_dont_raise
177     sam = Sam.new(StringIO.new(SAM_DATA))
178     assert_nothing_raised { sam.each }
179   end
180
181   def test_Sam_each_with_bad_qname_raises
182     sam = Sam.new(StringIO.new(" \t*\t*\t*\t*\t*\t*\t*\t*\t*\t*\n"))
183     assert_raise(SamError) { sam.each }
184   end
185
186   def test_Sam_each_with_ok_qname_dont_raise
187     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t*\t*\t*\n"))
188     assert_nothing_raised(SamError) { sam.each }
189   end
190
191   def test_Sam_each_with_bad_flag_raises
192     sam = Sam.new(StringIO.new("*\t-1\t*\t*\t*\t*\t*\t*\t*\t*\t*\n"))
193     assert_raise(SamError) { sam.each }
194
195     sam = Sam.new(StringIO.new("*\t65536\t*\t*\t*\t*\t*\t*\t*\t*\t*\n"))
196     assert_raise(SamError) { sam.each }
197   end
198
199   def test_Sam_each_with_ok_flag_dont_raise
200     sam = Sam.new(StringIO.new("*\t0\t*\t*\t*\t*\t*\t*\t*\t*\t*\n"))
201     assert_nothing_raised { sam.each }
202
203     sam = Sam.new(StringIO.new("*\t65535\t*\t*\t*\t*\t*\t*\t*\t*\t*\n"))
204     assert_nothing_raised { sam.each }
205   end
206
207   def test_Sam_each_with_bad_rname_raises
208     sam = Sam.new(StringIO.new("*\t*\t \t*\t*\t*\t*\t*\t*\t*\t*\n"))
209     assert_raise(SamError) { sam.each }
210   end
211
212   def test_Sam_each_with_ok_rname_dont_raise
213     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t*\t*\t*\n"))
214     assert_nothing_raised { sam.each }
215   end
216
217   def test_Sam_each_with_bad_pos_raises
218     sam = Sam.new(StringIO.new("*\t*\t*\t-1\t*\t*\t*\t*\t*\t*\t*\n"))
219     assert_raise(SamError) { sam.each }
220
221     sam = Sam.new(StringIO.new("*\t*\t*\t536870912\t*\t*\t*\t*\t*\t*\t*\n"))
222     assert_raise(SamError) { sam.each }
223   end
224
225   def test_Sam_each_with_ok_pos_dont_raise
226     sam = Sam.new(StringIO.new("*\t*\t*\t0\t*\t*\t*\t*\t*\t*\t*\n"))
227     assert_nothing_raised { sam.each }
228
229     sam = Sam.new(StringIO.new("*\t*\t*\t536870911\t*\t*\t*\t*\t*\t*\t*\n"))
230     assert_nothing_raised { sam.each }
231   end
232
233   def test_Sam_each_with_bad_mapq_raises
234     sam = Sam.new(StringIO.new("*\t*\t*\t*\t-1\t*\t*\t*\t*\t*\t*\n"))
235     assert_raise(SamError) { sam.each }
236
237     sam = Sam.new(StringIO.new("*\t*\t*\t*\t256\t*\t*\t*\t*\t*\t*\n"))
238     assert_raise(SamError) { sam.each }
239   end
240
241   def test_Sam_each_with_ok_mapq_dont_raise
242     sam = Sam.new(StringIO.new("*\t*\t*\t*\t0\t*\t*\t*\t*\t*\t*\n"))
243     assert_nothing_raised { sam.each }
244
245     sam = Sam.new(StringIO.new("*\t*\t*\t*\t255\t*\t*\t*\t*\t*\t*\n"))
246     assert_nothing_raised { sam.each }
247   end
248
249   def test_Sam_each_with_bad_cigar_raises
250     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t24\t*\t*\t*\t*\t*\n"))
251     assert_raise(SamError) { sam.each }
252   end
253
254   def test_Sam_each_with_ok_cigar_dont_raise
255     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t24M2I3D\t*\t*\t*\t*\t*\n"))
256     assert_nothing_raised { sam.each }
257
258     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t*\t*\t*\n"))
259     assert_nothing_raised { sam.each }
260   end
261
262   def test_Sam_each_with_bad_rnext_raises
263     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t \t*\t*\t*\t*\n"))
264     assert_raise(SamError) { sam.each }
265   end
266
267   def test_Sam_each_with_ok_rnext_dont_raise
268     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t*\t*\t*\n"))
269     assert_nothing_raised { sam.each }
270
271     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t=\t*\t*\t*\t*\n"))
272     assert_nothing_raised { sam.each }
273
274     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t!\t*\t*\t*\t*\n"))
275     assert_nothing_raised { sam.each }
276   end
277
278   def test_Sam_each_with_bad_pnext_raises
279     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t-1\t*\t*\t*\n"))
280     assert_raise(SamError) { sam.each }
281
282     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t536870912\t*\t*\t*\n"))
283     assert_raise(SamError) { sam.each }
284   end
285
286   def test_Sam_each_with_ok_pnext_dont_raise
287     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t0\t*\t*\t*\n"))
288     assert_nothing_raised { sam.each }
289
290     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t536870911\t*\t*\t*\t*\n"))
291     assert_nothing_raised { sam.each }
292   end
293
294   def test_Sam_each_with_bad_tlen_raises
295     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t-536870912\t*\t*\n"))
296     assert_raise(SamError) { sam.each }
297
298     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t536870912\t*\t*\n"))
299     assert_raise(SamError) { sam.each }
300   end
301
302   def test_Sam_each_with_ok_tlen_dont_raise
303     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t-536870911\t*\t*\n"))
304     assert_nothing_raised { sam.each }
305
306     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t536870911\t*\t*\n"))
307     assert_nothing_raised { sam.each }
308   end
309
310   def test_Sam_each_with_bad_seq_raises
311     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t\*\t \t*\n"))
312     assert_raise(SamError) { sam.each }
313   end
314
315   def test_Sam_each_with_ok_seq_dont_raise
316     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t\*\t*\t*\n"))
317     assert_nothing_raised { sam.each }
318
319     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t\*\tATCGatcg=.\t*\n"))
320     assert_nothing_raised { sam.each }
321   end
322
323   def test_Sam_each_with_bad_qual_raises
324     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t\*\t*\t \n"))
325     assert_raise(SamError) { sam.each }
326   end
327
328   def test_Sam_each_with_ok_qual_dont_raise
329     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t\*\t*\t@\n"))
330     assert_nothing_raised { sam.each }
331   end
332
333   def test_Sam_each_with_rname_missing_from_header_raises
334     sam = Sam.new(StringIO.new("@SQ\tSN:ref\tLN:45\n*\t*\tMIS\t*\t*\t*\t*\t*\t\*\t*\t*\n"))
335     assert_raise(SamError) { sam.each }
336   end
337
338   def test_Sam_each_with_rname_present_in_header_dont_raise
339     sam = Sam.new(StringIO.new("@SQ\tSN:ref\tLN:45\n*\t*\tref\t*\t*\t*\t*\t*\t\*\t*\t*\n"))
340     assert_nothing_raised { sam.each }
341
342     sam = Sam.new(StringIO.new("@SQ\tSN:ref\tLN:45\n*\t*\t*\t*\t*\t*\t*\t*\t\*\t*\t*\n"))
343     assert_nothing_raised { sam.each }
344   end
345
346   def test_Sam_each_with_rnext_missing_from_header_raises
347     sam = Sam.new(StringIO.new("@SQ\tSN:ref\tLN:45\n*\t*\t*\t*\t*\t*\tMIS\t*\t\*\t*\t*\n"))
348     assert_raise(SamError) { sam.each }
349   end
350
351   def test_Sam_each_with_rnext_present_in_header_dont_raise
352     sam = Sam.new(StringIO.new("@SQ\tSN:ref\tLN:45\n*\t*\t*\t*\t*\t*\t*\t*\t\*\t*\t*\n"))
353     assert_nothing_raised { sam.each }
354
355     sam = Sam.new(StringIO.new("@SQ\tSN:ref\tLN:45\n*\t*\t*\t*\t*\t*\t=\t*\t\*\t*\t*\n"))
356     assert_nothing_raised { sam.each }
357
358     sam = Sam.new(StringIO.new("@SQ\tSN:ref\tLN:45\n*\t*\t*\t*\t*\t*\tref\t*\t\*\t*\t*\n"))
359     assert_nothing_raised { sam.each }
360   end
361
362   def test_Sam_each_with_bad_cigar_hard_clip_raises
363     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t1M1H1M\t*\t*\t\*\tAAA\t*\n"))
364     assert_raise(SamError) { sam.each }
365
366     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t1H1M1H1M\t*\t*\t\*\tAAA\t*\n"))
367     assert_raise(SamError) { sam.each }
368
369     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t1M1H1M1H\t*\t*\t\*\tAAA\t*\n"))
370     assert_raise(SamError) { sam.each }
371   end
372
373   def test_Sam_each_with_ok_cigar_hard_clip_dont_raise
374     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t1H1M\t*\t*\t\*\tA\t*\n"))
375     assert_nothing_raised { sam.each }
376
377     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t1M1H\t*\t*\t\*\tA\t*\n"))
378     assert_nothing_raised { sam.each }
379
380     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t1H1M1H\t*\t*\t\*\tA\t*\n"))
381     assert_nothing_raised { sam.each }
382   end
383
384   def test_Sam_each_with_bad_cigar_length_raise
385     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t6M\t*\t*\t\*\tAAAAA\t*\n"))
386     assert_raise(SamError) { sam.each }
387   end
388
389   def test_Sam_each_with_ok_cigar_length_dont_raise
390     sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t6M\t*\t*\t\*\tAAAAAA\t*\n"))
391     assert_nothing_raised { sam.each }
392   end
393 end
394