check_rname(rname)
check_pos(pos)
check_mapq(mapq)
- check_cigar(cigar)
+ check_cigar(cigar, seq)
check_rnext(rnext)
check_pnext(pnext)
check_tlen(tlen)
# Method to check mapq.
def check_mapq(mapq)
- raise SamError, "Bad mapq: #{mapq}" unless (0 .. 2**8 - 1).include? mapq
+ raise SamError, "Bad mapq: #{mapq}" unless (0 .. 2**8 - 1).include? mapq
end
# Method to check cigar.
- def check_cigar(cigar)
+ def check_cigar(cigar, seq)
raise SamError, "Bad cigar: #{cigar}" unless cigar =~ /^(\*|([0-9]+[MIDNSHPX=])+)$/
+
+ # Check cigar length matches sequence length.
+ unless cigar == '*' or seq == '*'
+ cigar_len = 0
+
+ cigar.scan(/([0-9]+)([MIDNSHPX=])/).each do |len, op|
+ cigar_len += len.to_i if op =~ /[MISX=]/
+ end
+
+ if cigar_len != seq.length
+ raise SamError, "cigar and sequence length mismatch: #{cigar_len} != #{seq.length}"
+ end
+ end
end
# Method to check if rnext, when not '*' or '='
sam = Sam.new(StringIO.new("@SQ\tSN:ref\tLN:45\n*\t*\t*\t*\t*\t*\tref\t*\t\*\t*\t*\n"))
assert_nothing_raised { sam.each }
end
+
+ def test_Sam_each_with_bad_cigar_length_raise
+ sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t6M\t*\t*\t\*\tAAAAA\t*\n"))
+ assert_raise(SamError) { sam.each }
+
+ sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t6M\t*\t*\t\*\tAAAAAAA\t*\n"))
+ assert_raise(SamError) { sam.each }
+ end
+
+ def test_Sam_each_with_ok_cigar_length_dont_raise
+ sam = Sam.new(StringIO.new("*\t*\t*\t*\t*\t6M\t*\t*\t\*\tAAAAAA\t*\n"))
+ assert_nothing_raised { sam.each }
+ end
end