3 # Copyright (C) 2011 Martin A. Hansen.
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.
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.
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.
19 # http://www.gnu.org/copyleft/gpl.html
21 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
23 # This software is part of the Biopieces framework (www.biopieces.org).
25 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
33 %{@HD\tVN:1.3\tSO:coordinate
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*
44 class SamTest < Test::Unit::TestCase
46 @sam = Sam.new(StringIO.new(SAM_DATA))
49 def test_Sam_new_with_missing_version_number_raises
50 assert_raise(SamError) { Sam.new(StringIO.new("@HD")) }
53 def test_Sam_new_with_bad_version_number_raises
54 assert_raise(SamError) { Sam.new(StringIO.new("@HD\tXN:1.3")) }
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])
62 def test_Sam_new_with_bad_sort_order_raises
63 assert_raise(SamError) { Sam.new(StringIO.new("@HD\tVN:1.3\tSO:fish")) }
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])
73 def test_Sam_new_with_missing_sequence_name_raises
74 assert_raise(SamError) { Sam.new(StringIO.new("@SQ")) }
77 def test_Sam_new_with_bad_sequence_name_raises
78 assert_raise(SamError) { Sam.new(StringIO.new("@SQ\tSN:")) }
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])
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")) }
90 def test_Sam_new_with_missing_sequence_length_raises
91 assert_raise(SamError) { Sam.new(StringIO.new("@SQ\tSN:ref")) }
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")) }
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])
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 }
108 def test_Sam_new_with_bad_read_group_identifier_raises
109 assert_raise(SamError) { Sam.new(StringIO.new("@RG\tID:")) }
112 def test_Sam_new_with_missing_read_group_identifier_raises
113 assert_raise(SamError) { Sam.new(StringIO.new("@RG")) }
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")) }
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 }
125 def test_Sam_new_with_bad_flow_order_raises
126 assert_raise(SamError) { Sam.new(StringIO.new("@RG\tID:123\tFO:3")) }
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 }
136 def test_Sam_new_with_bad_platform_raises
137 assert_raise(SamError) { Sam.new(StringIO.new("@RG\tID:123\tPL:maersk")) }
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 }
145 def test_Sam_new_with_bad_program_identifier_raises
146 assert_raise(SamError) { Sam.new(StringIO.new("@PG\tID:")) }
149 def test_Sam_new_with_missing_program_identifier_raises
150 assert_raise(SamError) { Sam.new(StringIO.new("@PG")) }
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")) }
157 def test_Sam_new_with_bad_comment_raises
158 assert_raise(SamError) { Sam.new(StringIO.new("@CO\t")) }
161 def test_Sam_new_with_ok_comment_dont_raise
162 sam = Sam.new(StringIO.new("@CO\tfubar"))
163 assert_nothing_raised { sam.header }
166 def test_Sam_each_with_bad_field_count_raises
169 (0 ... 11).each do |i|
170 sam = Sam.new(StringIO.new(fields.join("\t") + $/))
171 assert_raise(SamError) { sam.each }
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 }
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 }
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 }
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 }
195 sam = Sam.new(StringIO.new("*\t65536\t*\t*\t*\t*\t*\t*\t*\t*\t*\n"))
196 assert_raise(SamError) { sam.each }
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 }
203 sam = Sam.new(StringIO.new("*\t65535\t*\t*\t*\t*\t*\t*\t*\t*\t*\n"))
204 assert_nothing_raised { sam.each }
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 }
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 }
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 }
221 sam = Sam.new(StringIO.new("*\t*\t*\t536870912\t*\t*\t*\t*\t*\t*\t*\n"))
222 assert_raise(SamError) { sam.each }
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 }
229 sam = Sam.new(StringIO.new("*\t*\t*\t536870911\t*\t*\t*\t*\t*\t*\t*\n"))
230 assert_nothing_raised { sam.each }
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 }
237 sam = Sam.new(StringIO.new("*\t*\t*\t*\t256\t*\t*\t*\t*\t*\t*\n"))
238 assert_raise(SamError) { sam.each }
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 }
245 sam = Sam.new(StringIO.new("*\t*\t*\t*\t255\t*\t*\t*\t*\t*\t*\n"))
246 assert_nothing_raised { sam.each }
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 }
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 }
258 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t*\t*\t*\n"))
259 assert_nothing_raised { sam.each }
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 }
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 }
271 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t=\t*\t*\t*\t*\n"))
272 assert_nothing_raised { sam.each }
274 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t!\t*\t*\t*\t*\n"))
275 assert_nothing_raised { sam.each }
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 }
282 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t536870912\t*\t*\t*\n"))
283 assert_raise(SamError) { sam.each }
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 }
290 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t536870911\t*\t*\t*\t*\n"))
291 assert_nothing_raised { sam.each }
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 }
298 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t536870912\t*\t*\n"))
299 assert_raise(SamError) { sam.each }
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 }
306 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t536870911\t*\t*\n"))
307 assert_nothing_raised { sam.each }
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 }
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 }
319 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t*\t*\t*\t\*\tATCGatcg=.\t*\n"))
320 assert_nothing_raised { sam.each }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
366 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t1H1M1H1M\t*\t*\t\*\tAAA\t*\n"))
367 assert_raise(SamError) { sam.each }
369 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t1M1H1M1H\t*\t*\t\*\tAAA\t*\n"))
370 assert_raise(SamError) { sam.each }
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 }
377 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t1M1H\t*\t*\t\*\tA\t*\n"))
378 assert_nothing_raised { sam.each }
380 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t1H1M1H\t*\t*\t\*\tA\t*\n"))
381 assert_nothing_raised { sam.each }
384 def test_Sam_each_with_bad_cigar_soft_clip_raises
385 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t1M1S1M\t*\t*\t\*\tA\t*\n"))
386 assert_raise(SamError) { sam.each }
389 def test_Sam_each_with_ok_cigar_soft_clip_dont_raise
390 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t1S1M\t*\t*\t\*\tAA\t*\n"))
391 assert_nothing_raised { sam.each }
393 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t1H1S1M\t*\t*\t\*\tAA\t*\n"))
394 assert_nothing_raised { sam.each }
397 def test_Sam_each_with_bad_cigar_length_raise
398 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t6M\t*\t*\t\*\tAAAAA\t*\n"))
399 assert_raise(SamError) { sam.each }
402 def test_Sam_each_with_ok_cigar_length_dont_raise
403 sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t6M\t*\t*\t\*\tAAAAAA\t*\n"))
404 assert_nothing_raised { sam.each }