# Copyright 2012 by Wibowo Arindrarto.  All rights reserved.
# This code is part of the Biopython distribution and governed by its
# license.  Please see the LICENSE file that should have been included
# as part of this package.

"""Tests for SearchIO BlastIO plain text parsers."""

import os
import unittest
import warnings

from Bio.SearchIO import parse
from Bio import BiopythonWarning

# test case files are in the Blast directory
TEST_DIR = "Blast"
FMT = "blast-text"

# This prevents the NCBIStandalone usage warning from
# printing to screen when running the test suite
warnings.filterwarnings("ignore", r"Parsing BLAST plain text output "
                        "file is not a well supported.*", BiopythonWarning)


def get_file(filename):
    """Return the path of a test file."""
    return os.path.join(TEST_DIR, filename)


class BaseBlastCases(unittest.TestCase):

    def check_common_attrs(self, qresults):
        # check common attributes
        for qresult in qresults:
            for hit in qresult:
                self.assertEqual(qresult.id, hit.query_id)
                for hsp in hit:
                    self.assertEqual(hit.id, hsp.hit_id)
                    self.assertEqual(qresult.id, hsp.query_id)


class BlastnCases(BaseBlastCases):

    def test_text_2226_blastn_001(self):
        """Test parsing blastn output (text_2226_blastn_001.txt)."""
        blast_file = get_file("text_2226_blastn_001.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("random_s00", qresult.id)
        self.assertEqual("", qresult.description)
        self.assertEqual(128, qresult.seq_len)
        self.assertEqual("NCBI Transcript Reference Sequences", qresult.target)
        self.assertEqual("blastn", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(0, len(qresult))

    def test_text_2226_blastn_002(self):
        """Test parsing blastn output (text_2226_blastn_002.txt)."""
        blast_file = get_file("text_2226_blastn_002.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("gi|356995852:1-490", qresult.id)
        self.assertEqual("Mus musculus POU domain, class 5, transcriptionfactor 1 (Pou5f1), transcript variant 1, mRNA", qresult.description)
        self.assertEqual(490, qresult.seq_len)
        self.assertEqual("NCBI Transcript Reference Sequences", qresult.target)
        self.assertEqual("blastn", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(8, len(qresult))
        # first qresult, first hit
        hit = qresult[0]
        self.assertEqual("ref|NM_013633.3|", hit.id)
        self.assertEqual("Mus musculus POU domain, class 5, transcription factor 1 (Pou5f1), transcript variant 1, mRNA", hit.description)
        self.assertEqual(1353, hit.seq_len)
        self.assertEqual(1, len(hit))
        # first qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(490, hsp.aln_span)
        self.assertEqual(0.0, hsp.evalue)
        self.assertEqual(905.0, hsp.bitscore)
        self.assertEqual(490.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(490, hsp.ident_num)
        self.assertEqual(490, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(0, hsp.hit_start)
        self.assertEqual(490, hsp.query_end)
        self.assertEqual(490, hsp.hit_end)
        self.assertEqual("GAGGTGAAACCGTCCCTAGGTGAGCCGTCTTTCCACCAGG", str(hsp.query.seq)[:40])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("GAGGTGAAACCGTCCCTAGGTGAGCCGTCTTTCCACCAGG", str(hsp.hit.seq)[:40])
        self.assertEqual("AGTCCCAGGACATGAAAGCCCTGCAGAAGGAGCTAGAACA", str(hsp.query.seq)[-40:])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("AGTCCCAGGACATGAAAGCCCTGCAGAAGGAGCTAGAACA", str(hsp.hit.seq)[-40:])
        # first qresult, second hit
        hit = qresult[1]
        self.assertEqual("ref|XR_141831.1|", hit.id)
        self.assertEqual("PREDICTED: Mus musculus predicted gene, 19553 (Gm19553), miscRNA ref|XR_105837.2| PREDICTED: Mus musculus predicted gene, 19553 (Gm19553), miscRNA ref|XR_141464.1| PREDICTED: Mus musculus predicted gene, 19553 (Gm19553), miscRNA ref|XR_141446.1| PREDICTED: Mus musculus predicted gene, 19553 (Gm19553), miscRNA", hit.description)
        self.assertEqual(570, hit.seq_len)
        self.assertEqual(1, len(hit))
        # first qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(490, hsp.aln_span)
        self.assertEqual(0.0, hsp.evalue)
        self.assertEqual(900.0, hsp.bitscore)
        self.assertEqual(487.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(489, hsp.ident_num)
        self.assertEqual(490, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(80, hsp.hit_start)
        self.assertEqual(490, hsp.query_end)
        self.assertEqual(570, hsp.hit_end)
        self.assertEqual("GAGGTGAAACCGTCCCTAGGTGAGCCGTCTTTCCACCAGG", str(hsp.query.seq)[:40])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("GAGGTGAAACCGTCCCTAGGTGAGCCGTCTTTCCACCAGG", str(hsp.hit.seq)[:40])
        self.assertEqual("AGTCCCAGGACATGAAAGCCCTGCAGAAGGAGCTAGAACA", str(hsp.query.seq)[-40:])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("AGTCCCAGGACATGAAAGCCCTGCAGAAGGAGCTAGAACA", str(hsp.hit.seq)[-40:])

    def test_text_2226_blastn_003(self):
        """Test parsing blastn output (text_2226_blastn_003.txt)."""
        blast_file = get_file("text_2226_blastn_003.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("hg19_dna", qresult.id)
        self.assertEqual("range=chr1:1207307-1207372 5'pad=0 3'pad=0 strand=+repeatMasking=none", qresult.description)
        self.assertEqual(66, qresult.seq_len)
        self.assertEqual("NCBI Transcript Reference Sequences", qresult.target)
        self.assertEqual("blastn", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(10, len(qresult))
        # first qresult, first hit
        hit = qresult[0]
        self.assertEqual("ref|XM_003267724.1|", hit.id)
        self.assertEqual("PREDICTED: Nomascus leucogenys ATG14 autophagy related 14 homolog (S. cerevisiae) (ATG14), mRNA", hit.description)
        self.assertEqual(4771, hit.seq_len)
        self.assertEqual(1, len(hit))
        # first qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(62, hsp.aln_span)
        self.assertEqual(3e-24, hsp.evalue)
        self.assertEqual(115.0, hsp.bitscore)
        self.assertEqual(62.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(62, hsp.ident_num)
        self.assertEqual(62, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(4, hsp.query_start)
        self.assertEqual(2864, hsp.hit_start)
        self.assertEqual(66, hsp.query_end)
        self.assertEqual(2926, hsp.hit_end)
        self.assertEqual("GCCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCCG", str(hsp.query.seq)[:40])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("GCCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCCG", str(hsp.hit.seq)[:40])
        self.assertEqual("AACAAGAGCGAAACTCCGTCTCaaaaaaaaaaaaaaaaaa", str(hsp.query.seq)[-40:])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("AACAAGAGCGAAACTCCGTCTCAAAAAAAAAAAAAAAAAA", str(hsp.hit.seq)[-40:])
        # first qresult, second hit
        hit = qresult[1]
        self.assertEqual("ref|NM_001040441.1|", hit.id)
        self.assertEqual("Homo sapiens zinc finger and BTB domain containing 8A (ZBTB8A), mRNA", hit.description)
        self.assertEqual(7333, hit.seq_len)
        self.assertEqual(2, len(hit))
        # first qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(62, hsp.aln_span)
        self.assertEqual(3e-24, hsp.evalue)
        self.assertEqual(115.0, hsp.bitscore)
        self.assertEqual(62.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(62, hsp.ident_num)
        self.assertEqual(62, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(4, hsp.query_start)
        self.assertEqual(3676, hsp.hit_start)
        self.assertEqual(66, hsp.query_end)
        self.assertEqual(3738, hsp.hit_end)
        self.assertEqual("GCCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCCG", str(hsp.query.seq)[:40])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("GCCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCCG", str(hsp.hit.seq)[:40])
        self.assertEqual("AACAAGAGCGAAACTCCGTCTCaaaaaaaaaaaaaaaaaa", str(hsp.query.seq)[-40:])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("AACAAGAGCGAAACTCCGTCTCAAAAAAAAAAAAAAAAAA", str(hsp.hit.seq)[-40:])
        # first qresult, second hit, second hsp
        hsp = qresult[1].hsps[1]
        self.assertEqual(53, hsp.aln_span)
        self.assertEqual(3e-19, hsp.evalue)
        self.assertEqual(99.0, hsp.bitscore)
        self.assertEqual(53.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(53, hsp.ident_num)
        self.assertEqual(53, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(5, hsp.query_start)
        self.assertEqual(2823, hsp.hit_start)
        self.assertEqual(58, hsp.query_end)
        self.assertEqual(2876, hsp.hit_end)
        self.assertEqual("CCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCCGT", str(hsp.query.seq)[:40])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("CCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCCGT", str(hsp.hit.seq)[:40])
        self.assertEqual("GCCTGGGCAACAAGAGCGAAACTCCGTCTCaaaaaaaaaa", str(hsp.query.seq)[-40:])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("GCCTGGGCAACAAGAGCGAAACTCCGTCTCAAAAAAAAAA", str(hsp.hit.seq)[-40:])

    def test_text_2226_blastn_004(self):
        """Test parsing blastn output (text_2226_blastn_004.txt)."""
        blast_file = get_file("text_2226_blastn_004.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(3, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("random_s00", qresult.id)
        self.assertEqual("", qresult.description)
        self.assertEqual(128, qresult.seq_len)
        self.assertEqual("minirefseq_mrna", qresult.target)
        self.assertEqual("blastn", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(0, len(qresult))

        # test second qresult
        qresult = qresults[1]
        self.assertEqual("gi|356995852:1-490", qresult.id)
        self.assertEqual("Mus musculus POU domain, class 5, transcriptionfactor 1 (Pou5f1), transcript variant 1, mRNA", qresult.description)
        self.assertEqual(490, qresult.seq_len)
        self.assertEqual("minirefseq_mrna", qresult.target)
        self.assertEqual("blastn", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(5, len(qresult))
        # second qresult, first hit
        hit = qresult[0]
        self.assertEqual("gi|356995852|ref|NM_013633.3|", hit.id)
        self.assertEqual("Mus musculus POU domain, class 5, transcription factor 1 (Pou5f1), transcript variant 1, mRNA", hit.description)
        self.assertEqual(1353, hit.seq_len)
        self.assertEqual(1, len(hit))
        # second qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(490, hsp.aln_span)
        self.assertEqual(0.0, hsp.evalue)
        self.assertEqual(905.0, hsp.bitscore)
        self.assertEqual(490.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(490, hsp.ident_num)
        self.assertEqual(490, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(0, hsp.hit_start)
        self.assertEqual(490, hsp.query_end)
        self.assertEqual(490, hsp.hit_end)
        self.assertEqual("GAGGTGAAACCGTCCCTAGGTGAGCCGTCTTTCCACCAGG", str(hsp.query.seq)[:40])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("GAGGTGAAACCGTCCCTAGGTGAGCCGTCTTTCCACCAGG", str(hsp.hit.seq)[:40])
        self.assertEqual("AGTCCCAGGACATGAAAGCCCTGCAGAAGGAGCTAGAACA", str(hsp.query.seq)[-40:])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("AGTCCCAGGACATGAAAGCCCTGCAGAAGGAGCTAGAACA", str(hsp.hit.seq)[-40:])
        # second qresult, second hit
        hit = qresult[1]
        self.assertEqual("gi|377833530|ref|XR_141831.1|", hit.id)
        self.assertEqual("PREDICTED: Mus musculus predicted gene, 19553 (Gm19553), miscRNA", hit.description)
        self.assertEqual(570, hit.seq_len)
        self.assertEqual(1, len(hit))
        # second qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(490, hsp.aln_span)
        self.assertEqual(0.0, hsp.evalue)
        self.assertEqual(900.0, hsp.bitscore)
        self.assertEqual(487.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(489, hsp.ident_num)
        self.assertEqual(490, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(80, hsp.hit_start)
        self.assertEqual(490, hsp.query_end)
        self.assertEqual(570, hsp.hit_end)
        self.assertEqual("GAGGTGAAACCGTCCCTAGGTGAGCCGTCTTTCCACCAGG", str(hsp.query.seq)[:40])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("GAGGTGAAACCGTCCCTAGGTGAGCCGTCTTTCCACCAGG", str(hsp.hit.seq)[:40])
        self.assertEqual("AGTCCCAGGACATGAAAGCCCTGCAGAAGGAGCTAGAACA", str(hsp.query.seq)[-40:])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("AGTCCCAGGACATGAAAGCCCTGCAGAAGGAGCTAGAACA", str(hsp.hit.seq)[-40:])

        # test third qresult
        qresult = qresults[2]
        self.assertEqual("hg19_dna", qresult.id)
        self.assertEqual("range=chr1:1207307-1207372 5'pad=0 3'pad=0 strand=+repeatMasking=none", qresult.description)
        self.assertEqual(66, qresult.seq_len)
        self.assertEqual("minirefseq_mrna", qresult.target)
        self.assertEqual("blastn", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(5, len(qresult))
        # third qresult, first hit
        hit = qresult[0]
        self.assertEqual("gi|94721341|ref|NM_001040441.1|", hit.id)
        self.assertEqual("Homo sapiens zinc finger and BTB domain containing 8A (ZBTB8A), mRNA", hit.description)
        self.assertEqual(7333, hit.seq_len)
        self.assertEqual(2, len(hit))
        # third qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(62, hsp.aln_span)
        self.assertEqual(6e-29, hsp.evalue)
        self.assertEqual(115.0, hsp.bitscore)
        self.assertEqual(62.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(62, hsp.ident_num)
        self.assertEqual(62, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(4, hsp.query_start)
        self.assertEqual(3676, hsp.hit_start)
        self.assertEqual(66, hsp.query_end)
        self.assertEqual(3738, hsp.hit_end)
        self.assertEqual("GCCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCCG", str(hsp.query.seq)[:40])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("GCCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCCG", str(hsp.hit.seq)[:40])
        self.assertEqual("AACAAGAGCGAAACTCCGTCTCaaaaaaaaaaaaaaaaaa", str(hsp.query.seq)[-40:])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("AACAAGAGCGAAACTCCGTCTCAAAAAAAAAAAAAAAAAA", str(hsp.hit.seq)[-40:])
        # third qresult, first hit, second hsp
        hsp = qresult[0].hsps[1]
        self.assertEqual(53, hsp.aln_span)
        self.assertEqual(6e-24, hsp.evalue)
        self.assertEqual(99.0, hsp.bitscore)
        self.assertEqual(53.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(53, hsp.ident_num)
        self.assertEqual(53, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(5, hsp.query_start)
        self.assertEqual(2823, hsp.hit_start)
        self.assertEqual(58, hsp.query_end)
        self.assertEqual(2876, hsp.hit_end)
        self.assertEqual("CCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCCGT", str(hsp.query.seq)[:40])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("CCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCCGT", str(hsp.hit.seq)[:40])
        self.assertEqual("GCCTGGGCAACAAGAGCGAAACTCCGTCTCaaaaaaaaaa", str(hsp.query.seq)[-40:])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("GCCTGGGCAACAAGAGCGAAACTCCGTCTCAAAAAAAAAA", str(hsp.hit.seq)[-40:])
        # third qresult, second hit
        hit = qresult[1]
        self.assertEqual("gi|332237160|ref|XM_003267724.1|", hit.id)
        self.assertEqual("PREDICTED: Nomascus leucogenys ATG14 autophagy related 14 homolog (S. cerevisiae) (ATG14), mRNA", hit.description)
        self.assertEqual(4771, hit.seq_len)
        self.assertEqual(1, len(hit))
        # third qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(62, hsp.aln_span)
        self.assertEqual(6e-29, hsp.evalue)
        self.assertEqual(115.0, hsp.bitscore)
        self.assertEqual(62.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(62, hsp.ident_num)
        self.assertEqual(62, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(4, hsp.query_start)
        self.assertEqual(2864, hsp.hit_start)
        self.assertEqual(66, hsp.query_end)
        self.assertEqual(2926, hsp.hit_end)
        self.assertEqual("GCCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCCG", str(hsp.query.seq)[:40])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("GCCATTGCACTCCAGCCTGGGCAACAAGAGCGAAACTCCG", str(hsp.hit.seq)[:40])
        self.assertEqual("AACAAGAGCGAAACTCCGTCTCaaaaaaaaaaaaaaaaaa", str(hsp.query.seq)[-40:])
        self.assertEqual("||||||||||||||||||||||||||||||||||||||||", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("AACAAGAGCGAAACTCCGTCTCAAAAAAAAAAAAAAAAAA", str(hsp.hit.seq)[-40:])


class BlastpCases(BaseBlastCases):

    def test_text_2226_blastp_001(self):
        """Test parsing blastp output (text_2226_blastp_001.txt)."""
        blast_file = get_file("text_2226_blastp_001.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("random_s00", qresult.id)
        self.assertEqual("", qresult.description)
        self.assertEqual(32, qresult.seq_len)
        self.assertEqual("NCBI Protein Reference Sequences", qresult.target)
        self.assertEqual("blastp", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(0, len(qresult))

    def test_text_2226_blastp_002(self):
        """Test parsing blastp output (text_2226_blastp_002.txt)."""
        blast_file = get_file("text_2226_blastp_002.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("gi|16080617|ref|NP_391444.1|", qresult.id)
        self.assertEqual("membrane bound lipoprotein [Bacillussubtilis subsp. subtilis str. 168]", qresult.description)
        self.assertEqual(102, qresult.seq_len)
        self.assertEqual("NCBI Protein Reference Sequences", qresult.target)
        self.assertEqual("blastp", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(10, len(qresult))
        # first qresult, first hit
        hit = qresult[0]
        self.assertEqual("ref|NP_391444.1|", hit.id)
        self.assertEqual("membrane bound lipoprotein [Bacillus subtilis subsp. subtilis str. 168] ref|ZP_03593363.1| membrane bound lipoprotein [Bacillus subtilis subsp. subtilis str. 168] ref|ZP_03597648.1| membrane bound lipoprotein [Bacillus subtilis subsp. subtilis str. NCIB 3610] ref|ZP_03602051.1| membrane bound lipoprotein [Bacillus subtilis subsp. subtilis str. JH642] ref|ZP_03606337.1| membrane bound lipoprotein [Bacillus subtilis subsp. subtilis str. SMY] ref|YP_004205398.1| unnamed protein product [Bacillus subtilis BSn5]", hit.description)
        self.assertEqual(102, hit.seq_len)
        self.assertEqual(1, len(hit))
        # first qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(102, hsp.aln_span)
        self.assertEqual(1e-66, hsp.evalue)
        self.assertEqual(205.0, hsp.bitscore)
        self.assertEqual(521.0, hsp.bitscore_raw)
        self.assertEqual(0, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(102, hsp.ident_num)
        self.assertEqual(102, hsp.pos_num)
        self.assertEqual(0, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(0, hsp.hit_start)
        self.assertEqual(102, hsp.query_end)
        self.assertEqual(102, hsp.hit_end)
        self.assertEqual("MKKFIALLFFILLLSGCGVNSQKSQGEDVSPDSNIETKEG", str(hsp.query.seq)[:40])
        self.assertEqual("MKKFIALLFFILLLSGCGVNSQKSQGEDVSPDSNIETKEG", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("MKKFIALLFFILLLSGCGVNSQKSQGEDVSPDSNIETKEG", str(hsp.hit.seq)[:40])
        self.assertEqual("DITEESTSDLDKFNSGDKVTITYEKNDEGQLLLKDIERAN", str(hsp.query.seq)[-40:])
        self.assertEqual("DITEESTSDLDKFNSGDKVTITYEKNDEGQLLLKDIERAN", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("DITEESTSDLDKFNSGDKVTITYEKNDEGQLLLKDIERAN", str(hsp.hit.seq)[-40:])
        # first qresult, second hit
        hit = qresult[1]
        self.assertEqual("ref|YP_003922001.1|", hit.id)
        self.assertEqual("membrane bound lipoprotein [Bacillus amyloliquefaciens DSM 7]", hit.description)
        self.assertEqual(100, hit.seq_len)
        self.assertEqual(1, len(hit))
        # first qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(102, hsp.aln_span)
        self.assertEqual(1e-40, hsp.evalue)
        self.assertEqual(139.0, hsp.bitscore)
        self.assertEqual(350.0, hsp.bitscore_raw)
        self.assertEqual(0, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(2, hsp.gap_num)
        self.assertEqual(69, hsp.ident_num)
        self.assertEqual(81, hsp.pos_num)
        self.assertEqual(0, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(0, hsp.hit_start)
        self.assertEqual(102, hsp.query_end)
        self.assertEqual(100, hsp.hit_end)
        self.assertEqual("MKKFIALLFFILLLSGCGVNSQKSQGEDVSPDSNIETKEG", str(hsp.query.seq)[:40])
        self.assertEqual("MKK    LFFILLL+GCGV ++KSQGED      + TKEG", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("MKKIFGCLFFILLLAGCGVTNEKSQGEDAG--EKLVTKEG", str(hsp.hit.seq)[:40])
        self.assertEqual("DITEESTSDLDKFNSGDKVTITYEKNDEGQLLLKDIERAN", str(hsp.query.seq)[-40:])
        self.assertEqual("DITEES  D+   N+G+KVT+ Y+KN +GQL+LKDIE AN", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("DITEESADDVKNLNNGEKVTVKYQKNSKGQLVLKDIEPAN", str(hsp.hit.seq)[-40:])

    def test_text_2226_blastp_003(self):
        """Test parsing blastp output (text_2226_blastp_003.txt)."""
        blast_file = get_file("text_2226_blastp_003.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("gi|11464971:4-101", qresult.id)
        self.assertEqual("pleckstrin [Mus musculus]", qresult.description)
        self.assertEqual(98, qresult.seq_len)
        self.assertEqual("NCBI Protein Reference Sequences", qresult.target)
        self.assertEqual("blastp", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(10, len(qresult))
        # first qresult, first hit
        hit = qresult[0]
        self.assertEqual("ref|NP_062422.1|", hit.id)
        self.assertEqual("pleckstrin [Mus musculus]", hit.description)
        self.assertEqual(350, hit.seq_len)
        self.assertEqual(2, len(hit))
        # first qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(98, hsp.aln_span)
        self.assertEqual(1e-63, hsp.evalue)
        self.assertEqual(205.0, hsp.bitscore)
        self.assertEqual(522.0, hsp.bitscore_raw)
        self.assertEqual(0, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(98, hsp.ident_num)
        self.assertEqual(98, hsp.pos_num)
        self.assertEqual(0, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(3, hsp.hit_start)
        self.assertEqual(98, hsp.query_end)
        self.assertEqual(101, hsp.hit_end)
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.hit.seq)[:40])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.query.seq)[-40:])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.hit.seq)[-40:])
        # first qresult, first hit, second hsp
        hsp = qresult[0].hsps[1]
        self.assertEqual(100, hsp.aln_span)
        self.assertEqual(0.002, hsp.evalue)
        self.assertEqual(43.5, hsp.bitscore)
        self.assertEqual(101.0, hsp.bitscore_raw)
        self.assertEqual(0, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(6, hsp.gap_num)
        self.assertEqual(29, hsp.ident_num)
        self.assertEqual(48, hsp.pos_num)
        self.assertEqual(0, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(2, hsp.query_start)
        self.assertEqual(245, hsp.hit_start)
        self.assertEqual(96, hsp.query_end)
        self.assertEqual(345, hsp.hit_end)
        self.assertEqual("IREGYLVKKGSVFNTWKPMWVVLLEDG--IEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("I++G L+K+G     WK    +L ED   + +Y       ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("IKQGCLLKQGHRRKNWKVRKFILREDPAYLHYYDPAGGED", str(hsp.hit.seq)[:40])
        self.assertEqual("FGK--RMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKA", str(hsp.query.seq)[-40:])
        self.assertEqual("  K     + +I T  +  ++ QAA  +ER  W++ I+ A", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("VKKSDEENLFEIITADEVHYYLQAATSKERTEWIKAIQVA", str(hsp.hit.seq)[-40:])
        # first qresult, second hit
        hit = qresult[1]
        self.assertEqual("ref|XP_003502426.1|", hit.id)
        self.assertEqual("PREDICTED: pleckstrin-like [Cricetulus griseus]", hit.description)
        self.assertEqual(350, hit.seq_len)
        self.assertEqual(2, len(hit))
        # first qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(98, hsp.aln_span)
        self.assertEqual(2e-63, hsp.evalue)
        self.assertEqual(205.0, hsp.bitscore)
        self.assertEqual(521.0, hsp.bitscore_raw)
        self.assertEqual(0, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(98, hsp.ident_num)
        self.assertEqual(98, hsp.pos_num)
        self.assertEqual(0, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(3, hsp.hit_start)
        self.assertEqual(98, hsp.query_end)
        self.assertEqual(101, hsp.hit_end)
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.hit.seq)[:40])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.query.seq)[-40:])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.hit.seq)[-40:])
        # first qresult, second hit, second hsp
        hsp = qresult[1].hsps[1]
        self.assertEqual(100, hsp.aln_span)
        self.assertEqual(0.001, hsp.evalue)
        self.assertEqual(43.9, hsp.bitscore)
        self.assertEqual(102.0, hsp.bitscore_raw)
        self.assertEqual(0, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(6, hsp.gap_num)
        self.assertEqual(30, hsp.ident_num)
        self.assertEqual(50, hsp.pos_num)
        self.assertEqual(0, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(2, hsp.query_start)
        self.assertEqual(245, hsp.hit_start)
        self.assertEqual(96, hsp.query_end)
        self.assertEqual(345, hsp.hit_end)
        self.assertEqual("IREGYLVKKGSVFNTWKPMWVVLLEDG--IEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("I++G L+K+G     WK    +L ED   + +Y       ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("IKQGCLLKQGHRRKNWKVRKFILREDPAYLHYYDPAGGED", str(hsp.hit.seq)[:40])
        self.assertEqual("GKRM---FVLKITTTKQQDHFFQAAFLEERDAWVRDIKKA", str(hsp.query.seq)[-40:])
        self.assertEqual("GK+     + +I T  +  ++ QAA  +ER  W++ I+ A", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("GKKSDDENLFEIITADEVHYYLQAAAPKERTEWIKAIQVA", str(hsp.hit.seq)[-40:])

    def test_text_2226_blastp_004(self):
        """Test parsing blastp output (text_2226_blastp_004.txt)."""
        blast_file = get_file("text_2226_blastp_004.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(3, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("random_s00", qresult.id)
        self.assertEqual("", qresult.description)
        self.assertEqual(32, qresult.seq_len)
        self.assertEqual("minirefseq_prot", qresult.target)
        self.assertEqual("blastp", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(0, len(qresult))

        # test second qresult
        qresult = qresults[1]
        self.assertEqual("gi|16080617|ref|NP_391444.1|", qresult.id)
        self.assertEqual("membrane bound lipoprotein [Bacillussubtilis subsp. subtilis str. 168]", qresult.description)
        self.assertEqual(102, qresult.seq_len)
        self.assertEqual("minirefseq_prot", qresult.target)
        self.assertEqual("blastp", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(5, len(qresult))
        # second qresult, first hit
        hit = qresult[0]
        self.assertEqual("gi|308175296|ref|YP_003922001.1|", hit.id)
        self.assertEqual("membrane bound lipoprotein [Bacillus amyloliquefaciens DSM 7]", hit.description)
        self.assertEqual(100, hit.seq_len)
        self.assertEqual(1, len(hit))
        # second qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(102, hsp.aln_span)
        self.assertEqual(2e-46, hsp.evalue)
        self.assertEqual(139.0, hsp.bitscore)
        self.assertEqual(350.0, hsp.bitscore_raw)
        self.assertEqual(0, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(2, hsp.gap_num)
        self.assertEqual(69, hsp.ident_num)
        self.assertEqual(81, hsp.pos_num)
        self.assertEqual(0, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(0, hsp.hit_start)
        self.assertEqual(102, hsp.query_end)
        self.assertEqual(100, hsp.hit_end)
        self.assertEqual("MKKFIALLFFILLLSGCGVNSQKSQGEDVSPDSNIETKEG", str(hsp.query.seq)[:40])
        self.assertEqual("MKK    LFFILLL+GCGV ++KSQGED      + TKEG", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("MKKIFGCLFFILLLAGCGVTNEKSQGEDAG--EKLVTKEG", str(hsp.hit.seq)[:40])
        self.assertEqual("DITEESTSDLDKFNSGDKVTITYEKNDEGQLLLKDIERAN", str(hsp.query.seq)[-40:])
        self.assertEqual("DITEES  D+   N+G+KVT+ Y+KN +GQL+LKDIE AN", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("DITEESADDVKNLNNGEKVTVKYQKNSKGQLVLKDIEPAN", str(hsp.hit.seq)[-40:])
        # second qresult, second hit
        hit = qresult[1]
        self.assertEqual("gi|375363999|ref|YP_005132038.1|", hit.id)
        self.assertEqual("lytA gene product [Bacillus amyloliquefaciens subsp. plantarum CAU B946]", hit.description)
        self.assertEqual(105, hit.seq_len)
        self.assertEqual(1, len(hit))
        # second qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(105, hsp.aln_span)
        self.assertEqual(7e-27, hsp.evalue)
        self.assertEqual(89.0, hsp.bitscore)
        self.assertEqual(219.0, hsp.bitscore_raw)
        self.assertEqual(0, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(5, hsp.gap_num)
        self.assertEqual(48, hsp.ident_num)
        self.assertEqual(69, hsp.pos_num)
        self.assertEqual(0, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(0, hsp.hit_start)
        self.assertEqual(101, hsp.query_end)
        self.assertEqual(104, hsp.hit_end)
        self.assertEqual("MKKFIALLFFILL----LSGCGVNSQKSQGEDVSPDSNIE", str(hsp.query.seq)[:40])
        self.assertEqual("MKK IA  F ILL    L+ CG   Q  +G   S ++  +", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("MKKTIAASFLILLFSVVLAACGTAEQSKKGSG-SSENQAQ", str(hsp.hit.seq)[:40])
        self.assertEqual("LDITEESTSDLDKFNSGDKVTITYEKNDEGQLLLKDIERA", str(hsp.query.seq)[-40:])
        self.assertEqual(" + +++ +  L+KF+  DKV+ITY  ND+GQ  +K+IE+A", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("FEFSDDFSDVLNKFSENDKVSITYFTNDKGQKEIKEIEKA", str(hsp.hit.seq)[-40:])

        # test third qresult
        qresult = qresults[2]
        self.assertEqual("gi|11464971:4-101", qresult.id)
        self.assertEqual("pleckstrin [Mus musculus]", qresult.description)
        self.assertEqual(98, qresult.seq_len)
        self.assertEqual("minirefseq_prot", qresult.target)
        self.assertEqual("blastp", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(5, len(qresult))
        # third qresult, first hit
        hit = qresult[0]
        self.assertEqual("gi|11464971|ref|NP_062422.1|", hit.id)
        self.assertEqual("pleckstrin [Mus musculus]", hit.description)
        self.assertEqual(350, hit.seq_len)
        self.assertEqual(2, len(hit))
        # third qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(98, hsp.aln_span)
        self.assertEqual(2e-69, hsp.evalue)
        self.assertEqual(205.0, hsp.bitscore)
        self.assertEqual(522.0, hsp.bitscore_raw)
        self.assertEqual(0, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(98, hsp.ident_num)
        self.assertEqual(98, hsp.pos_num)
        self.assertEqual(0, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(3, hsp.hit_start)
        self.assertEqual(98, hsp.query_end)
        self.assertEqual(101, hsp.hit_end)
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.hit.seq)[:40])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.query.seq)[-40:])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.hit.seq)[-40:])
        # third qresult, first hit, second hsp
        hsp = qresult[0].hsps[1]
        self.assertEqual(100, hsp.aln_span)
        self.assertEqual(3e-09, hsp.evalue)
        self.assertEqual(43.5, hsp.bitscore)
        self.assertEqual(101.0, hsp.bitscore_raw)
        self.assertEqual(0, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(6, hsp.gap_num)
        self.assertEqual(29, hsp.ident_num)
        self.assertEqual(48, hsp.pos_num)
        self.assertEqual(0, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(2, hsp.query_start)
        self.assertEqual(245, hsp.hit_start)
        self.assertEqual(96, hsp.query_end)
        self.assertEqual(345, hsp.hit_end)
        self.assertEqual("IREGYLVKKGSVFNTWKPMWVVLLEDG--IEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("I++G L+K+G     WK    +L ED   + +Y       ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("IKQGCLLKQGHRRKNWKVRKFILREDPAYLHYYDPAGGED", str(hsp.hit.seq)[:40])
        self.assertEqual("FGK--RMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKA", str(hsp.query.seq)[-40:])
        self.assertEqual("  K     + +I T  +  ++ QAA  +ER  W++ I+ A", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("VKKSDEENLFEIITADEVHYYLQAATSKERTEWIKAIQVA", str(hsp.hit.seq)[-40:])
        # third qresult, second hit
        hit = qresult[1]
        self.assertEqual("gi|354480464|ref|XP_003502426.1|", hit.id)
        self.assertEqual("PREDICTED: pleckstrin-like [Cricetulus griseus]", hit.description)
        self.assertEqual(350, hit.seq_len)
        self.assertEqual(2, len(hit))
        # third qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(98, hsp.aln_span)
        self.assertEqual(3e-69, hsp.evalue)
        self.assertEqual(205.0, hsp.bitscore)
        self.assertEqual(521.0, hsp.bitscore_raw)
        self.assertEqual(0, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(98, hsp.ident_num)
        self.assertEqual(98, hsp.pos_num)
        self.assertEqual(0, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(3, hsp.hit_start)
        self.assertEqual(98, hsp.query_end)
        self.assertEqual(101, hsp.hit_end)
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.hit.seq)[:40])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.query.seq)[-40:])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.hit.seq)[-40:])
        # third qresult, second hit, second hsp
        hsp = qresult[1].hsps[1]
        self.assertEqual(100, hsp.aln_span)
        self.assertEqual(2e-09, hsp.evalue)
        self.assertEqual(43.9, hsp.bitscore)
        self.assertEqual(102.0, hsp.bitscore_raw)
        self.assertEqual(0, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(6, hsp.gap_num)
        self.assertEqual(30, hsp.ident_num)
        self.assertEqual(50, hsp.pos_num)
        self.assertEqual(0, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(2, hsp.query_start)
        self.assertEqual(245, hsp.hit_start)
        self.assertEqual(96, hsp.query_end)
        self.assertEqual(345, hsp.hit_end)
        self.assertEqual("IREGYLVKKGSVFNTWKPMWVVLLEDG--IEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("I++G L+K+G     WK    +L ED   + +Y       ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("IKQGCLLKQGHRRKNWKVRKFILREDPAYLHYYDPAGGED", str(hsp.hit.seq)[:40])
        self.assertEqual("GKRM---FVLKITTTKQQDHFFQAAFLEERDAWVRDIKKA", str(hsp.query.seq)[-40:])
        self.assertEqual("GK+     + +I T  +  ++ QAA  +ER  W++ I+ A", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("GKKSDDENLFEIITADEVHYYLQAAAPKERTEWIKAIQVA", str(hsp.hit.seq)[-40:])


class BlastxCases(BaseBlastCases):

    def test_text_2226_blastx_001(self):
        """Test parsing blastx output (text_2226_blastx_001.txt)."""
        blast_file = get_file("text_2226_blastx_001.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("random_s00", qresult.id)
        self.assertEqual("", qresult.description)
        self.assertEqual(128, qresult.seq_len)
        self.assertEqual("NCBI Protein Reference Sequences", qresult.target)
        self.assertEqual("blastx", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(0, len(qresult))

    def test_text_2226_blastx_002(self):
        """Test parsing blastx output (text_2226_blastx_002.txt)."""
        blast_file = get_file("text_2226_blastx_002.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("gi|356995852:1-490", qresult.id)
        self.assertEqual("Mus musculus POU domain, class 5, transcriptionfactor 1 (Pou5f1), transcript variant 1, mRNA", qresult.description)
        self.assertEqual(490, qresult.seq_len)
        self.assertEqual("NCBI Protein Reference Sequences", qresult.target)
        self.assertEqual("blastx", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(10, len(qresult))
        # first qresult, first hit
        hit = qresult[0]
        self.assertEqual("ref|NP_038661.2|", hit.id)
        self.assertEqual("POU domain, class 5, transcription factor 1 isoform 1 [Mus musculus]", hit.description)
        self.assertEqual(352, hit.seq_len)
        self.assertEqual(1, len(hit))
        # first qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(140, hsp.aln_span)
        self.assertEqual(4e-57, hsp.evalue)
        self.assertEqual(192.0, hsp.bitscore)
        self.assertEqual(487.0, hsp.bitscore_raw)
        self.assertEqual(3, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(140, hsp.ident_num)
        self.assertEqual(140, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(68, hsp.query_start)
        self.assertEqual(0, hsp.hit_start)
        self.assertEqual(488, hsp.query_end)
        self.assertEqual(140, hsp.hit_end)
        self.assertEqual("MAGHLAsdfafspppgggdgsagLEPGWVDPRTWLSFQgp", str(hsp.query.seq)[:40])
        self.assertEqual("MAGHLASDFAFSPPPGGGDGSAGLEPGWVDPRTWLSFQGP", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("MAGHLASDFAFSPPPGGGDGSAGLEPGWVDPRTWLSFQGP", str(hsp.hit.seq)[:40])
        self.assertEqual("NSEGTSSEPCADRPNAVKLEKVEPTPEESQDMKALQKELE", str(hsp.query.seq)[-40:])
        self.assertEqual("NSEGTSSEPCADRPNAVKLEKVEPTPEESQDMKALQKELE", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("NSEGTSSEPCADRPNAVKLEKVEPTPEESQDMKALQKELE", str(hsp.hit.seq)[-40:])
        # first qresult, second hit
        hit = qresult[1]
        self.assertEqual("ref|NP_001009178.1|", hit.id)
        self.assertEqual("POU class 5 homeobox 1 [Rattus norvegicus]", hit.description)
        self.assertEqual(352, hit.seq_len)
        self.assertEqual(1, len(hit))
        # first qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(140, hsp.aln_span)
        self.assertEqual(3e-52, hsp.evalue)
        self.assertEqual(179.0, hsp.bitscore)
        self.assertEqual(454.0, hsp.bitscore_raw)
        self.assertEqual(3, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(133, hsp.ident_num)
        self.assertEqual(135, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(68, hsp.query_start)
        self.assertEqual(0, hsp.hit_start)
        self.assertEqual(488, hsp.query_end)
        self.assertEqual(140, hsp.hit_end)
        self.assertEqual("MAGHLAsdfafspppgggdgsagLEPGWVDPRTWLSFQgp", str(hsp.query.seq)[:40])
        self.assertEqual("MAGHLASDFAFSPPPGGGDGSAGLEPGWVDPRTWLSFQGP", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("MAGHLASDFAFSPPPGGGDGSAGLEPGWVDPRTWLSFQGP", str(hsp.hit.seq)[:40])
        self.assertEqual("NSEGTSSEPCADRPNAVKLEKVEPTPEESQDMKALQKELE", str(hsp.query.seq)[-40:])
        self.assertEqual("NSEG SS PC  RP+AVKLEKVEP+PEESQDMKALQKELE", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("NSEGASSGPCTARPSAVKLEKVEPSPEESQDMKALQKELE", str(hsp.hit.seq)[-40:])

    def test_text_2226_blastx_003(self):
        """Test parsing blastx output (text_2226_blastx_003.txt)."""
        blast_file = get_file("text_2226_blastx_003.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("hg19_dna", qresult.id)
        self.assertEqual("range=chr1:1207057-1207541 5'pad=0 3'pad=0 strand=+repeatMasking=none", qresult.description)
        self.assertEqual(485, qresult.seq_len)
        self.assertEqual("NCBI Protein Reference Sequences", qresult.target)
        self.assertEqual("blastx", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(10, len(qresult))
        # first qresult, first hit
        hit = qresult[0]
        self.assertEqual("ref|XP_003278367.1|", hit.id)
        self.assertEqual("PREDICTED: UPF0764 protein C16orf89-like [Nomascus leucogenys]", hit.description)
        self.assertEqual(132, hit.seq_len)
        self.assertEqual(2, len(hit))
        # first qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(95, hsp.aln_span)
        self.assertEqual(2e-32, hsp.evalue)
        self.assertEqual(121.0, hsp.bitscore)
        self.assertEqual(304.0, hsp.bitscore_raw)
        self.assertEqual(-3, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(69, hsp.ident_num)
        self.assertEqual(74, hsp.pos_num)
        self.assertEqual(-1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(15, hsp.query_start)
        self.assertEqual(24, hsp.hit_start)
        self.assertEqual(300, hsp.query_end)
        self.assertEqual(119, hsp.hit_end)
        self.assertEqual("LRRSFALVAQAGVQWLDLGppqpppPGFK*FSCLSHPSSW", str(hsp.query.seq)[:40])
        self.assertEqual("LRRSFALVAQ  VQW +LG PQPPPPGFK FSCLS  SSW", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("LRRSFALVAQTRVQWYNLGSPQPPPPGFKRFSCLSLLSSW", str(hsp.hit.seq)[:40])
        self.assertEqual("VETGFYHVGQAGLEPPISGNLPAWASQSVGITGVSHHAQP", str(hsp.query.seq)[-40:])
        self.assertEqual("VE GF HVGQAGLE   SG+ P   SQS GI GVSH AQP", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("VEMGFLHVGQAGLELVTSGDPPTLTSQSAGIIGVSHCAQP", str(hsp.hit.seq)[-40:])
        # first qresult, first hit, second hsp
        hsp = qresult[0].hsps[1]
        self.assertEqual(72, hsp.aln_span)
        self.assertEqual(2e-06, hsp.evalue)
        self.assertEqual(51.6, hsp.bitscore)
        self.assertEqual(122.0, hsp.bitscore_raw)
        self.assertEqual(-3, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(5, hsp.gap_num)
        self.assertEqual(34, hsp.ident_num)
        self.assertEqual(41, hsp.pos_num)
        self.assertEqual(-1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(243, hsp.query_start)
        self.assertEqual(31, hsp.hit_start)
        self.assertEqual(459, hsp.query_end)
        self.assertEqual(98, hsp.hit_end)
        self.assertEqual("VGPARVQ*HDLSSLQPPAPEFK*FSHLSLQSSWDCRCPPP", str(hsp.query.seq)[:40])
        self.assertEqual("V   RVQ ++L S QPP P FK FS LSL SSW+ R  PP", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("VAQTRVQWYNLGSPQPPPPGFKRFSCLSLLSSWEYRHVPP", str(hsp.hit.seq)[:40])
        self.assertEqual("WDCRCPPPHPANffffffffFLRRSFALVAQAGVQWLDLG", str(hsp.query.seq)[-40:])
        self.assertEqual("W+ R  PPH AN     F F +   F  V QAG++ +  G", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("WEYRHVPPHLAN-----FLFLVEMGFLHVGQAGLELVTSG", str(hsp.hit.seq)[-40:])
        # first qresult, second hit
        hit = qresult[1]
        self.assertEqual("ref|NP_001243358.1|", hit.id)
        self.assertEqual("PDZ and LIM domain protein 5 isoform i [Homo sapiens]", hit.description)
        self.assertEqual(136, hit.seq_len)
        self.assertEqual(2, len(hit))
        # first qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(88, hsp.aln_span)
        self.assertEqual(1e-29, hsp.evalue)
        self.assertEqual(114.0, hsp.bitscore)
        self.assertEqual(286.0, hsp.bitscore_raw)
        self.assertEqual(-3, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(63, hsp.ident_num)
        self.assertEqual(69, hsp.pos_num)
        self.assertEqual(-1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(15, hsp.query_start)
        self.assertEqual(29, hsp.hit_start)
        self.assertEqual(279, hsp.query_end)
        self.assertEqual(117, hsp.hit_end)
        self.assertEqual("VAQAGVQWLDLGppqpppPGFK*FSCLSHPSSWDYRHMPP", str(hsp.query.seq)[:40])
        self.assertEqual("++ AGVQW +LG PQPP P FK FSCLS PSSWDYRH+PP", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("ISSAGVQWRNLGSPQPPSPEFKRFSCLSLPSSWDYRHVPP", str(hsp.hit.seq)[:40])
        self.assertEqual("VETGFYHVGQAGLEPPISGNLPAWASQSVGITGVSHHAQP", str(hsp.query.seq)[-40:])
        self.assertEqual("VET F +VGQAGLE P SG+LP  ASQS  ITGVSH A P", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("VETKFPYVGQAGLELPTSGDLPTSASQSAKITGVSHRAWP", str(hsp.hit.seq)[-40:])
        # first qresult, second hit, second hsp
        hsp = qresult[1].hsps[1]
        self.assertEqual(69, hsp.aln_span)
        self.assertEqual(1e-06, hsp.evalue)
        self.assertEqual(52.4, hsp.bitscore)
        self.assertEqual(124.0, hsp.bitscore_raw)
        self.assertEqual(-3, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(5, hsp.gap_num)
        self.assertEqual(33, hsp.ident_num)
        self.assertEqual(41, hsp.pos_num)
        self.assertEqual(-1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(258, hsp.query_start)
        self.assertEqual(27, hsp.hit_start)
        self.assertEqual(465, hsp.query_end)
        self.assertEqual(91, hsp.hit_end)
        self.assertEqual("VSVGPARVQ*HDLSSLQPPAPEFK*FSHLSLQSSWDCRCP", str(hsp.query.seq)[:40])
        self.assertEqual("+++  A VQ  +L S QPP+PEFK FS LSL SSWD R  ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("LTISSAGVQWRNLGSPQPPSPEFKRFSCLSLPSSWDYRHV", str(hsp.hit.seq)[:40])
        self.assertEqual("SLQSSWDCRCPPPHPANffffffffFLRRSFALVAQAGVQ", str(hsp.query.seq)[-40:])
        self.assertEqual("SL SSWD R  PP  AN     F F +   F  V QAG++", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("SLPSSWDYRHVPPRLAN-----FVFLVETKFPYVGQAGLE", str(hsp.hit.seq)[-40:])

    def test_text_2226_blastx_004(self):
        """Test parsing blastx output (text_2226_blastx_004.txt)."""
        blast_file = get_file("text_2226_blastx_004.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(2, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("random_s00", qresult.id)
        self.assertEqual("", qresult.description)
        self.assertEqual(128, qresult.seq_len)
        self.assertEqual("minirefseq_prot", qresult.target)
        self.assertEqual("blastx", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(0, len(qresult))

        # test second qresult
        qresult = qresults[1]
        self.assertEqual("hg19_dna", qresult.id)
        self.assertEqual("range=chr1:1207057-1207541 5'pad=0 3'pad=0 strand=+repeatMasking=none", qresult.description)
        self.assertEqual(485, qresult.seq_len)
        self.assertEqual("minirefseq_prot", qresult.target)
        self.assertEqual("blastx", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(5, len(qresult))
        # second qresult, first hit
        hit = qresult[0]
        self.assertEqual("gi|332258565|ref|XP_003278367.1|", hit.id)
        self.assertEqual("PREDICTED: UPF0764 protein C16orf89-like [Nomascus leucogenys]", hit.description)
        self.assertEqual(132, hit.seq_len)
        self.assertEqual(2, len(hit))
        # second qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(95, hsp.aln_span)
        self.assertEqual(3e-38, hsp.evalue)
        self.assertEqual(121.0, hsp.bitscore)
        self.assertEqual(304.0, hsp.bitscore_raw)
        self.assertEqual(-3, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(69, hsp.ident_num)
        self.assertEqual(74, hsp.pos_num)
        self.assertEqual(-1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(15, hsp.query_start)
        self.assertEqual(24, hsp.hit_start)
        self.assertEqual(300, hsp.query_end)
        self.assertEqual(119, hsp.hit_end)
        self.assertEqual("LRRSFALVAQAGVQWLDLGppqpppPGFK*FSCLSHPSSW", str(hsp.query.seq)[:40])
        self.assertEqual("LRRSFALVAQ  VQW +LG PQPPPPGFK FSCLS  SSW", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("LRRSFALVAQTRVQWYNLGSPQPPPPGFKRFSCLSLLSSW", str(hsp.hit.seq)[:40])
        self.assertEqual("VETGFYHVGQAGLEPPISGNLPAWASQSVGITGVSHHAQP", str(hsp.query.seq)[-40:])
        self.assertEqual("VE GF HVGQAGLE   SG+ P   SQS GI GVSH AQP", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("VEMGFLHVGQAGLELVTSGDPPTLTSQSAGIIGVSHCAQP", str(hsp.hit.seq)[-40:])
        # second qresult, first hit, second hsp
        hsp = qresult[0].hsps[1]
        self.assertEqual(72, hsp.aln_span)
        self.assertEqual(3e-12, hsp.evalue)
        self.assertEqual(51.6, hsp.bitscore)
        self.assertEqual(122.0, hsp.bitscore_raw)
        self.assertEqual(-3, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(5, hsp.gap_num)
        self.assertEqual(34, hsp.ident_num)
        self.assertEqual(41, hsp.pos_num)
        self.assertEqual(-1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(243, hsp.query_start)
        self.assertEqual(31, hsp.hit_start)
        self.assertEqual(459, hsp.query_end)
        self.assertEqual(98, hsp.hit_end)
        self.assertEqual("VGPARVQ*HDLSSLQPPAPEFK*FSHLSLQSSWDCRCPPP", str(hsp.query.seq)[:40])
        self.assertEqual("V   RVQ ++L S QPP P FK FS LSL SSW+ R  PP", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("VAQTRVQWYNLGSPQPPPPGFKRFSCLSLLSSWEYRHVPP", str(hsp.hit.seq)[:40])
        self.assertEqual("WDCRCPPPHPANffffffffFLRRSFALVAQAGVQWLDLG", str(hsp.query.seq)[-40:])
        self.assertEqual("W+ R  PPH AN     F F +   F  V QAG++ +  G", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("WEYRHVPPHLAN-----FLFLVEMGFLHVGQAGLELVTSG", str(hsp.hit.seq)[-40:])
        # second qresult, second hit
        hit = qresult[1]
        self.assertEqual("gi|374093214|ref|NP_001243358.1|", hit.id)
        self.assertEqual("PDZ and LIM domain protein 5 isoform i [Homo sapiens]", hit.description)
        self.assertEqual(136, hit.seq_len)
        self.assertEqual(2, len(hit))
        # second qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(88, hsp.aln_span)
        self.assertEqual(2e-35, hsp.evalue)
        self.assertEqual(114.0, hsp.bitscore)
        self.assertEqual(286.0, hsp.bitscore_raw)
        self.assertEqual(-3, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(63, hsp.ident_num)
        self.assertEqual(69, hsp.pos_num)
        self.assertEqual(-1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(15, hsp.query_start)
        self.assertEqual(29, hsp.hit_start)
        self.assertEqual(279, hsp.query_end)
        self.assertEqual(117, hsp.hit_end)
        self.assertEqual("VAQAGVQWLDLGppqpppPGFK*FSCLSHPSSWDYRHMPP", str(hsp.query.seq)[:40])
        self.assertEqual("++ AGVQW +LG PQPP P FK FSCLS PSSWDYRH+PP", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("ISSAGVQWRNLGSPQPPSPEFKRFSCLSLPSSWDYRHVPP", str(hsp.hit.seq)[:40])
        self.assertEqual("VETGFYHVGQAGLEPPISGNLPAWASQSVGITGVSHHAQP", str(hsp.query.seq)[-40:])
        self.assertEqual("VET F +VGQAGLE P SG+LP  ASQS  ITGVSH A P", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("VETKFPYVGQAGLELPTSGDLPTSASQSAKITGVSHRAWP", str(hsp.hit.seq)[-40:])
        # second qresult, second hit, second hsp
        hsp = qresult[1].hsps[1]
        self.assertEqual(69, hsp.aln_span)
        self.assertEqual(2e-12, hsp.evalue)
        self.assertEqual(52.4, hsp.bitscore)
        self.assertEqual(124.0, hsp.bitscore_raw)
        self.assertEqual(-3, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(5, hsp.gap_num)
        self.assertEqual(33, hsp.ident_num)
        self.assertEqual(41, hsp.pos_num)
        self.assertEqual(-1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(258, hsp.query_start)
        self.assertEqual(27, hsp.hit_start)
        self.assertEqual(465, hsp.query_end)
        self.assertEqual(91, hsp.hit_end)
        self.assertEqual("VSVGPARVQ*HDLSSLQPPAPEFK*FSHLSLQSSWDCRCP", str(hsp.query.seq)[:40])
        self.assertEqual("+++  A VQ  +L S QPP+PEFK FS LSL SSWD R  ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("LTISSAGVQWRNLGSPQPPSPEFKRFSCLSLPSSWDYRHV", str(hsp.hit.seq)[:40])
        self.assertEqual("SLQSSWDCRCPPPHPANffffffffFLRRSFALVAQAGVQ", str(hsp.query.seq)[-40:])
        self.assertEqual("SL SSWD R  PP  AN     F F +   F  V QAG++", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("SLPSSWDYRHVPPRLAN-----FVFLVETKFPYVGQAGLE", str(hsp.hit.seq)[-40:])


class TblastnCases(BaseBlastCases):

    def test_text_2226_tblastn_001(self):
        """Test parsing tblastn output (text_2226_tblastn_001.txt)."""
        blast_file = get_file("text_2226_tblastn_001.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("random_s00", qresult.id)
        self.assertEqual("", qresult.description)
        self.assertEqual(32, qresult.seq_len)
        self.assertEqual("NCBI Transcript Reference Sequences", qresult.target)
        self.assertEqual("tblastn", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(0, len(qresult))

    def test_text_2226_tblastn_002(self):
        """Test parsing tblastn output (text_2226_tblastn_002.txt)."""
        blast_file = get_file("text_2226_tblastn_002.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("gi|16080617|ref|NP_391444.1|", qresult.id)
        self.assertEqual("membrane bound lipoprotein [Bacillussubtilis subsp. subtilis str. 168]", qresult.description)
        self.assertEqual(102, qresult.seq_len)
        self.assertEqual("NCBI Transcript Reference Sequences", qresult.target)
        self.assertEqual("tblastn", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(4, len(qresult))
        # first qresult, first hit
        hit = qresult[0]
        self.assertEqual("ref|XM_001425911.1|", hit.id)
        self.assertEqual("Paramecium tetraurelia hypothetical protein (GSPATT00004923001) partial mRNA", hit.description)
        self.assertEqual(4632, hit.seq_len)
        self.assertEqual(1, len(hit))
        # first qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(43, hsp.aln_span)
        self.assertEqual(0.74, hsp.evalue)
        self.assertEqual(34.7, hsp.bitscore)
        self.assertEqual(78.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(15, hsp.ident_num)
        self.assertEqual(26, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(30, hsp.query_start)
        self.assertEqual(1743, hsp.hit_start)
        self.assertEqual(73, hsp.query_end)
        self.assertEqual(1872, hsp.hit_end)
        self.assertEqual("PDSNIETKEGTYVGLADTHTIEVTVDNEPVSLDITEESTS", str(hsp.query.seq)[:40])
        self.assertEqual("P +   TK+GT +GL   HTI   + +  +SL++ E++  ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("PKTATGTKKGTIIGLLSIHTILFILTSHALSLEVKEQT*K", str(hsp.hit.seq)[:40])
        self.assertEqual("NIETKEGTYVGLADTHTIEVTVDNEPVSLDITEESTSDLD", str(hsp.query.seq)[-40:])
        self.assertEqual("   TK+GT +GL   HTI   + +  +SL++ E++  D+D", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("ATGTKKGTIIGLLSIHTILFILTSHALSLEVKEQT*KDID", str(hsp.hit.seq)[-40:])
        # first qresult, second hit
        hit = qresult[1]
        self.assertEqual("ref|XM_003382561.1|", hit.id)
        self.assertEqual("PREDICTED: Amphimedon queenslandica CWF19-like protein 1-like (LOC100635130), mRNA", hit.description)
        self.assertEqual(1811, hit.seq_len)
        self.assertEqual(1, len(hit))
        # first qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(74, hsp.aln_span)
        self.assertEqual(6.4, hsp.evalue)
        self.assertEqual(32.0, hsp.bitscore)
        self.assertEqual(71.0, hsp.bitscore_raw)
        self.assertEqual(2, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(11, hsp.gap_num)
        self.assertEqual(19, hsp.ident_num)
        self.assertEqual(36, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(28, hsp.query_start)
        self.assertEqual(1105, hsp.hit_start)
        self.assertEqual(94, hsp.query_end)
        self.assertEqual(1318, hsp.hit_end)
        self.assertEqual("VSPDSNIETKEGTYVGLADTHTIEVTVDNEPVSLDITEES", str(hsp.query.seq)[:40])
        self.assertEqual("+  DS +   +G   GL D H + + + + P S+D  +E ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("IGNDSYLALSKG---GLVDEHVLILPIGHYPSSIDAPQEV", str(hsp.hit.seq)[:40])
        self.assertEqual("DITEESTSDLDK--------FNSGDKVTITYEKNDEGQLL", str(hsp.query.seq)[-40:])
        self.assertEqual("D  +E   ++DK        F+S ++  + +E+N   Q L", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("DAPQEVIEEIDKFKVALRKYFSSKNQTCVMFERNFRSQHL", str(hsp.hit.seq)[-40:])

    def test_text_2226_tblastn_003(self):
        """Test parsing tblastn output (text_2226_tblastn_003.txt)."""
        blast_file = get_file("text_2226_tblastn_003.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("gi|11464971:4-101", qresult.id)
        self.assertEqual("pleckstrin [Mus musculus]", qresult.description)
        self.assertEqual(98, qresult.seq_len)
        self.assertEqual("NCBI Transcript Reference Sequences", qresult.target)
        self.assertEqual("tblastn", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(10, len(qresult))
        # first qresult, first hit
        hit = qresult[0]
        self.assertEqual("ref|XM_003502378.1|", hit.id)
        self.assertEqual("PREDICTED: Cricetulus griseus pleckstrin-like (LOC100773128), mRNA", hit.description)
        self.assertEqual(1119, hit.seq_len)
        self.assertEqual(2, len(hit))
        # first qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(98, hsp.aln_span)
        self.assertEqual(1e-63, hsp.evalue)
        self.assertEqual(205.0, hsp.bitscore)
        self.assertEqual(521.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(98, hsp.ident_num)
        self.assertEqual(98, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(75, hsp.hit_start)
        self.assertEqual(98, hsp.query_end)
        self.assertEqual(369, hsp.hit_end)
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.hit.seq)[:40])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.query.seq)[-40:])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.hit.seq)[-40:])
        # first qresult, first hit, second hsp
        hsp = qresult[0].hsps[1]
        self.assertEqual(100, hsp.aln_span)
        self.assertEqual(0.0005, hsp.evalue)
        self.assertEqual(43.9, hsp.bitscore)
        self.assertEqual(102.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(6, hsp.gap_num)
        self.assertEqual(30, hsp.ident_num)
        self.assertEqual(50, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(2, hsp.query_start)
        self.assertEqual(801, hsp.hit_start)
        self.assertEqual(96, hsp.query_end)
        self.assertEqual(1101, hsp.hit_end)
        self.assertEqual("IREGYLVKKGSVFNTWKPMWVVLLEDG--IEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("I++G L+K+G     WK    +L ED   + +Y       ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("IKQGCLLKQGHRRKNWKVRKFILREDPAYLHYYDPAGGED", str(hsp.hit.seq)[:40])
        self.assertEqual("GKRM---FVLKITTTKQQDHFFQAAFLEERDAWVRDIKKA", str(hsp.query.seq)[-40:])
        self.assertEqual("GK+     + +I T  +  ++ QAA  +ER  W++ I+ A", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("GKKSDDENLFEIITADEVHYYLQAAAPKERTEWIKAIQVA", str(hsp.hit.seq)[-40:])
        # first qresult, second hit
        hit = qresult[1]
        self.assertEqual("ref|XM_003360601.2|", hit.id)
        self.assertEqual("PREDICTED: Sus scrofa pleckstrin-like (LOC100626968), mRNA", hit.description)
        self.assertEqual(772, hit.seq_len)
        self.assertEqual(2, len(hit))
        # first qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(98, hsp.aln_span)
        self.assertEqual(1e-62, hsp.evalue)
        self.assertEqual(199.0, hsp.bitscore)
        self.assertEqual(506.0, hsp.bitscore_raw)
        self.assertEqual(2, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(94, hsp.ident_num)
        self.assertEqual(96, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(94, hsp.hit_start)
        self.assertEqual(98, hsp.query_end)
        self.assertEqual(388, hsp.hit_end)
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("KRIREGYLVKKGS+FNTWKPMWV+LLEDGIEFYKKKSDNS", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("KRIREGYLVKKGSMFNTWKPMWVILLEDGIEFYKKKSDNS", str(hsp.hit.seq)[:40])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.query.seq)[-40:])
        self.assertEqual("FGKRMFV KITTTKQQDHFFQAAFLEERD WVRDIKKAIK", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("FGKRMFVFKITTTKQQDHFFQAAFLEERDGWVRDIKKAIK", str(hsp.hit.seq)[-40:])
        # first qresult, second hit, second hsp
        hsp = qresult[1].hsps[1]
        self.assertEqual(71, hsp.aln_span)
        self.assertEqual(2.8, hsp.evalue)
        self.assertEqual(32.7, hsp.bitscore)
        self.assertEqual(73.0, hsp.bitscore_raw)
        self.assertEqual(2, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(4, hsp.gap_num)
        self.assertEqual(21, hsp.ident_num)
        self.assertEqual(33, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(29, hsp.query_start)
        self.assertEqual(541, hsp.hit_start)
        self.assertEqual(96, hsp.query_end)
        self.assertEqual(754, hsp.hit_end)
        self.assertEqual("IEFYKKKSDNSPKGMIPLKGSTLTS-PCQDFGKRMFVLK-", str(hsp.query.seq)[:40])
        self.assertEqual("+ +Y       P G I L+G  +TS      GK  F+ + ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("LHYYDPAGGEDPLGAIHLRGCVVTSVESNTDGKNGFLWER", str(hsp.hit.seq)[:40])
        self.assertEqual("GKRMFVLK---ITTTKQQDHFFQAAFLEERDAWVRDIKKA", str(hsp.query.seq)[-40:])
        self.assertEqual("GK  F+ +     T  +  +F QAA  +ER  W++ I+ A", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("GKNGFLWERAXXITADEVHYFLQAANPKERTEWIKAIQVA", str(hsp.hit.seq)[-40:])

    def test_text_2226_tblastn_004(self):
        """Test parsing tblastn output (text_2226_tblastn_004.txt)."""
        blast_file = get_file("text_2226_tblastn_004.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(3, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("random_s00", qresult.id)
        self.assertEqual("", qresult.description)
        self.assertEqual(32, qresult.seq_len)
        self.assertEqual("minirefseq_mrna", qresult.target)
        self.assertEqual("tblastn", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(0, len(qresult))

        # test second qresult
        qresult = qresults[1]
        self.assertEqual("gi|16080617|ref|NP_391444.1|", qresult.id)
        self.assertEqual("membrane bound lipoprotein [Bacillussubtilis subsp. subtilis str. 168]", qresult.description)
        self.assertEqual(102, qresult.seq_len)
        self.assertEqual("minirefseq_mrna", qresult.target)
        self.assertEqual("tblastn", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(3, len(qresult))
        # second qresult, first hit
        hit = qresult[0]
        self.assertEqual("gi|145479850|ref|XM_001425911.1|", hit.id)
        self.assertEqual("Paramecium tetraurelia hypothetical protein (GSPATT00004923001) partial mRNA", hit.description)
        self.assertEqual(4632, hit.seq_len)
        self.assertEqual(1, len(hit))
        # second qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(43, hsp.aln_span)
        self.assertEqual(1e-05, hsp.evalue)
        self.assertEqual(34.7, hsp.bitscore)
        self.assertEqual(78.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(15, hsp.ident_num)
        self.assertEqual(26, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(30, hsp.query_start)
        self.assertEqual(1743, hsp.hit_start)
        self.assertEqual(73, hsp.query_end)
        self.assertEqual(1872, hsp.hit_end)
        self.assertEqual("PDSNIETKEGTYVGLADTHTIEVTVDNEPVSLDITEESTS", str(hsp.query.seq)[:40])
        self.assertEqual("P +   TK+GT +GL   HTI   + +  +SL++ E++  ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("PKTATGTKKGTIIGLLSIHTILFILTSHALSLEVKEQT*K", str(hsp.hit.seq)[:40])
        self.assertEqual("NIETKEGTYVGLADTHTIEVTVDNEPVSLDITEESTSDLD", str(hsp.query.seq)[-40:])
        self.assertEqual("   TK+GT +GL   HTI   + +  +SL++ E++  D+D", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("ATGTKKGTIIGLLSIHTILFILTSHALSLEVKEQT*KDID", str(hsp.hit.seq)[-40:])
        # second qresult, second hit
        hit = qresult[1]
        self.assertEqual("gi|72012412|ref|XM_777959.1|", hit.id)
        self.assertEqual("PREDICTED: Strongylocentrotus purpuratus hypothetical LOC577746 (LOC577746), mRNA", hit.description)
        self.assertEqual(1593, hit.seq_len)
        self.assertEqual(1, len(hit))
        # second qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(59, hsp.aln_span)
        self.assertEqual(0.0001, hsp.evalue)
        self.assertEqual(31.6, hsp.bitscore)
        self.assertEqual(70.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(8, hsp.gap_num)
        self.assertEqual(20, hsp.ident_num)
        self.assertEqual(29, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(43, hsp.query_start)
        self.assertEqual(1056, hsp.hit_start)
        self.assertEqual(94, hsp.query_end)
        self.assertEqual(1233, hsp.hit_end)
        self.assertEqual("GLADTHTIEVTVDNEPVSLDITEESTSDLDKFNSG-----", str(hsp.query.seq)[:40])
        self.assertEqual("GL   HT+ + V +    LD+TEE  ++LD+F S      ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("GLVPDHTLILPVGHYQSMLDLTEEVQTELDQFKSALRKYY", str(hsp.hit.seq)[:40])
        self.assertEqual("DITEESTSDLDKFNSG--------DKVTITYEKNDEGQLL", str(hsp.query.seq)[-40:])
        self.assertEqual("D+TEE  ++LD+F S          K  + YE+N   Q L", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("DLTEEVQTELDQFKSALRKYYLSKGKTCVIYERNFRTQHL", str(hsp.hit.seq)[-40:])

        # test third qresult
        qresult = qresults[2]
        self.assertEqual("gi|11464971:4-101", qresult.id)
        self.assertEqual("pleckstrin [Mus musculus]", qresult.description)
        self.assertEqual(98, qresult.seq_len)
        self.assertEqual("minirefseq_mrna", qresult.target)
        self.assertEqual("tblastn", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(5, len(qresult))
        # third qresult, first hit
        hit = qresult[0]
        self.assertEqual("gi|350596019|ref|XM_003360601.2|", hit.id)
        self.assertEqual("PREDICTED: Sus scrofa pleckstrin-like (LOC100626968), mRNA", hit.description)
        self.assertEqual(772, hit.seq_len)
        self.assertEqual(2, len(hit))
        # third qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(98, hsp.aln_span)
        self.assertEqual(2e-67, hsp.evalue)
        self.assertEqual(199.0, hsp.bitscore)
        self.assertEqual(506.0, hsp.bitscore_raw)
        self.assertEqual(2, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(94, hsp.ident_num)
        self.assertEqual(96, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(94, hsp.hit_start)
        self.assertEqual(98, hsp.query_end)
        self.assertEqual(388, hsp.hit_end)
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("KRIREGYLVKKGS+FNTWKPMWV+LLEDGIEFYKKKSDNS", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("KRIREGYLVKKGSMFNTWKPMWVILLEDGIEFYKKKSDNS", str(hsp.hit.seq)[:40])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.query.seq)[-40:])
        self.assertEqual("FGKRMFV KITTTKQQDHFFQAAFLEERD WVRDIKKAIK", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("FGKRMFVFKITTTKQQDHFFQAAFLEERDGWVRDIKKAIK", str(hsp.hit.seq)[-40:])
        # third qresult, first hit, second hsp
        hsp = qresult[0].hsps[1]
        self.assertEqual(71, hsp.aln_span)
        self.assertEqual(4e-05, hsp.evalue)
        self.assertEqual(32.7, hsp.bitscore)
        self.assertEqual(73.0, hsp.bitscore_raw)
        self.assertEqual(2, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(4, hsp.gap_num)
        self.assertEqual(21, hsp.ident_num)
        self.assertEqual(33, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(29, hsp.query_start)
        self.assertEqual(541, hsp.hit_start)
        self.assertEqual(96, hsp.query_end)
        self.assertEqual(754, hsp.hit_end)
        self.assertEqual("IEFYKKKSDNSPKGMIPLKGSTLTS-PCQDFGKRMFVLK-", str(hsp.query.seq)[:40])
        self.assertEqual("+ +Y       P G I L+G  +TS      GK  F+ + ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("LHYYDPAGGEDPLGAIHLRGCVVTSVESNTDGKNGFLWER", str(hsp.hit.seq)[:40])
        self.assertEqual("GKRMFVLK---ITTTKQQDHFFQAAFLEERDAWVRDIKKA", str(hsp.query.seq)[-40:])
        self.assertEqual("GK  F+ +     T  +  +F QAA  +ER  W++ I+ A", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("GKNGFLWERAXXITADEVHYFLQAANPKERTEWIKAIQVA", str(hsp.hit.seq)[-40:])
        # third qresult, second hit
        hit = qresult[1]
        self.assertEqual("gi|301779869|ref|XM_002925302.1|", hit.id)
        self.assertEqual("PREDICTED: Ailuropoda melanoleuca pleckstrin-like (LOC100466932), mRNA", hit.description)
        self.assertEqual(1144, hit.seq_len)
        self.assertEqual(2, len(hit))
        # third qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(98, hsp.aln_span)
        self.assertEqual(2e-67, hsp.evalue)
        self.assertEqual(202.0, hsp.bitscore)
        self.assertEqual(515.0, hsp.bitscore_raw)
        self.assertEqual(3, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(96, hsp.ident_num)
        self.assertEqual(97, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(77, hsp.hit_start)
        self.assertEqual(98, hsp.query_end)
        self.assertEqual(371, hsp.hit_end)
        self.assertEqual("KRIREGYLVKKGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("KRIREGYLVK+GSVFNTWKPMWVVLLEDGIEFYKKKSDNS", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("KRIREGYLVKRGSVFNTWKPMWVVLLEDGIEFYKKKSDNS", str(hsp.hit.seq)[:40])
        self.assertEqual("FGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.query.seq)[-40:])
        self.assertEqual("FGKRMFV KITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("FGKRMFVFKITTTKQQDHFFQAAFLEERDAWVRDIKKAIK", str(hsp.hit.seq)[-40:])
        # third qresult, second hit, second hsp
        hsp = qresult[1].hsps[1]
        self.assertEqual(100, hsp.aln_span)
        self.assertEqual(3e-09, hsp.evalue)
        self.assertEqual(45.1, hsp.bitscore)
        self.assertEqual(105.0, hsp.bitscore_raw)
        self.assertEqual(3, hsp.query_frame)
        self.assertEqual(0, hsp.hit_frame)
        self.assertEqual(6, hsp.gap_num)
        self.assertEqual(30, hsp.ident_num)
        self.assertEqual(48, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(0, hsp.hit_strand)
        self.assertEqual(2, hsp.query_start)
        self.assertEqual(803, hsp.hit_start)
        self.assertEqual(96, hsp.query_end)
        self.assertEqual(1103, hsp.hit_end)
        self.assertEqual("IREGYLVKKGSVFNTWKPMWVVLLEDG--IEFYKKKSDNS", str(hsp.query.seq)[:40])
        self.assertEqual("I++G L+K+G     WK    +L ED   + +Y       ", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("IKQGCLLKQGHRRKNWKVRKFILREDPAYLHYYDPAGGED", str(hsp.hit.seq)[:40])
        self.assertEqual("QDFGKRMFVLKITTTKQQDHFFQAAFLEERDAWVRDIKKA", str(hsp.query.seq)[-40:])
        self.assertEqual("    +   + +I T  +  +F QAA  +ER  W++ I+ A", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("VRKSEEENLFEIITADEVHYFLQAATPKERTEWIKAIQVA", str(hsp.hit.seq)[-40:])


class TblastxCases(BaseBlastCases):

    def test_text_2226_tblastx_001(self):
        """Test parsing tblastx output (text_2226_tblastx_001.txt)."""
        blast_file = get_file("text_2226_tblastx_001.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("random_s00", qresult.id)
        self.assertEqual("", qresult.description)
        self.assertEqual(128, qresult.seq_len)
        self.assertEqual("NCBI Transcript Reference Sequences", qresult.target)
        self.assertEqual("tblastx", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(0, len(qresult))

    def test_text_2226_tblastx_002(self):
        """Test parsing tblastx output (text_2226_tblastx_002.txt)."""
        blast_file = get_file("text_2226_tblastx_002.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("gi|356995852:1-490", qresult.id)
        self.assertEqual("Mus musculus POU domain, class 5, transcriptionfactor 1 (Pou5f1), transcript variant 1, mRNA", qresult.description)
        self.assertEqual(490, qresult.seq_len)
        self.assertEqual("NCBI Transcript Reference Sequences", qresult.target)
        self.assertEqual("tblastx", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(10, len(qresult))
        # first qresult, first hit
        hit = qresult[0]
        self.assertEqual("ref|NM_013633.3|", hit.id)
        self.assertEqual("Mus musculus POU domain, class 5, transcription factor 1 (Pou5f1), transcript variant 1, mRNA", hit.description)
        self.assertEqual(1353, hit.seq_len)
        self.assertEqual(1, len(hit))
        # first qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(163, hsp.aln_span)
        self.assertEqual(2e-115, hsp.evalue)
        self.assertEqual(418.0, hsp.bitscore)
        self.assertEqual(908.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(163, hsp.ident_num)
        self.assertEqual(163, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(0, hsp.hit_start)
        self.assertEqual(489, hsp.query_end)
        self.assertEqual(489, hsp.hit_end)
        self.assertEqual("EVKPSLGEPSFHQAPGSGCPPSPWLDTWLQTSPSHPHQVG", str(hsp.query.seq)[:40])
        self.assertEqual("EVKPSLGEPSFHQAPGSGCPPSPWLDTWLQTSPSHPHQVG", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("EVKPSLGEPSFHQAPGSGCPPSPWLDTWLQTSPSHPHQVG", str(hsp.hit.seq)[:40])
        self.assertEqual("TQREPPLSPVPTAPMP*SWRRWNQLPRSPRT*KPCRRS*N", str(hsp.query.seq)[-40:])
        self.assertEqual("TQREPPLSPVPTAPMP*SWRRWNQLPRSPRT*KPCRRS*N", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("TQREPPLSPVPTAPMP*SWRRWNQLPRSPRT*KPCRRS*N", str(hsp.hit.seq)[-40:])
        # first qresult, second hit
        hit = qresult[1]
        self.assertEqual("ref|XR_141831.1|", hit.id)
        self.assertEqual("PREDICTED: Mus musculus predicted gene, 19553 (Gm19553), miscRNA ref|XR_105837.2| PREDICTED: Mus musculus predicted gene, 19553 (Gm19553), miscRNA ref|XR_141464.1| PREDICTED: Mus musculus predicted gene, 19553 (Gm19553), miscRNA ref|XR_141446.1| PREDICTED: Mus musculus predicted gene, 19553 (Gm19553), miscRNA", hit.description)
        self.assertEqual(570, hit.seq_len)
        self.assertEqual(1, len(hit))
        # first qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(163, hsp.aln_span)
        self.assertEqual(3e-114, hsp.evalue)
        self.assertEqual(415.0, hsp.bitscore)
        self.assertEqual(900.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(-1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(162, hsp.ident_num)
        self.assertEqual(162, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(-1, hsp.hit_strand)
        self.assertEqual(0, hsp.query_start)
        self.assertEqual(81, hsp.hit_start)
        self.assertEqual(489, hsp.query_end)
        self.assertEqual(570, hsp.hit_end)
        self.assertEqual("EVKPSLGEPSFHQAPGSGCPPSPWLDTWLQTSPSHPHQVG", str(hsp.query.seq)[:40])
        self.assertEqual("EVKPSLGEPSFHQAPGSGCPPSPWLDTWLQTSPSHPHQVG", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("EVKPSLGEPSFHQAPGSGCPPSPWLDTWLQTSPSHPHQVG", str(hsp.hit.seq)[:40])
        self.assertEqual("TQREPPLSPVPTAPMP*SWRRWNQLPRSPRT*KPCRRS*N", str(hsp.query.seq)[-40:])
        self.assertEqual("TQREPPLSPVPTAPMP*SWRRWNQL RSPRT*KPCRRS*N", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("TQREPPLSPVPTAPMP*SWRRWNQLQRSPRT*KPCRRS*N", str(hsp.hit.seq)[-40:])

    def test_text_2226_tblastx_003(self):
        """Test parsing tblastx output (text_2226_tblastx_003.txt)."""
        blast_file = get_file("text_2226_tblastx_003.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("hg19_dna", qresult.id)
        self.assertEqual("range=chr1:1207057-1207541 5'pad=0 3'pad=0 strand=+repeatMasking=none", qresult.description)
        self.assertEqual(485, qresult.seq_len)
        self.assertEqual("NCBI Transcript Reference Sequences", qresult.target)
        self.assertEqual("tblastx", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(10, len(qresult))
        # first qresult, first hit
        hit = qresult[0]
        self.assertEqual("ref|NM_002985.2|", hit.id)
        self.assertEqual("Homo sapiens chemokine (C-C motif) ligand 5 (CCL5), mRNA", hit.description)
        self.assertEqual(1237, hit.seq_len)
        self.assertEqual(3, len(hit))
        # first qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(107, hsp.aln_span)
        self.assertEqual(4e-49, hsp.evalue)
        self.assertEqual(118.0, hsp.bitscore)
        self.assertEqual(252.0, hsp.bitscore_raw)
        self.assertEqual(-3, hsp.query_frame)
        self.assertEqual(-1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(68, hsp.ident_num)
        self.assertEqual(72, hsp.pos_num)
        self.assertEqual(-1, hsp.query_strand)
        self.assertEqual(-1, hsp.hit_strand)
        self.assertEqual(138, hsp.query_start)
        self.assertEqual(622, hsp.hit_start)
        self.assertEqual(459, hsp.query_end)
        self.assertEqual(943, hsp.hit_end)
        self.assertEqual("VGPARVQ*HDLSSLQPPAPEFK*FSHLSLQSSWDCRCPPP", str(hsp.query.seq)[:40])
        self.assertEqual("V  A V+ H+LSSLQPP P FK FS LSL SSWD R  PP", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("VTQAGVKWHNLSSLQPPPPGFKQFSCLSLPSSWDYRRGPP", str(hsp.hit.seq)[:40])
        self.assertEqual("WLDLGppqpppPGFK*FSCLSHPSSWDYRHMPPCLINFVF", str(hsp.query.seq)[-40:])
        self.assertEqual("W DLG  Q PPPGF  FSCLS PSSWDYR   P   NF++", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("WRDLGSLQAPPPGFTPFSCLSLPSSWDYRRPLPRPANFLY", str(hsp.hit.seq)[-40:])
        # first qresult, first hit, second hsp
        hsp = qresult[0].hsps[1]
        self.assertEqual(44, hsp.aln_span)
        self.assertEqual(4e-49, hsp.evalue)
        self.assertEqual(100.0, hsp.bitscore)
        self.assertEqual(214.0, hsp.bitscore_raw)
        self.assertEqual(-2, hsp.query_frame)
        self.assertEqual(-2, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(37, hsp.ident_num)
        self.assertEqual(38, hsp.pos_num)
        self.assertEqual(-1, hsp.query_strand)
        self.assertEqual(-1, hsp.hit_strand)
        self.assertEqual(16, hsp.query_start)
        self.assertEqual(498, hsp.hit_start)
        self.assertEqual(148, hsp.query_end)
        self.assertEqual(630, hsp.hit_end)
        self.assertEqual("FCIFSRDGVLPCWSGWSRTPDLR*SACLGLPKCWDYRCEP", str(hsp.query.seq)[:40])
        self.assertEqual("FCIFSRDGV  CW GWSRTPDL+*S  LGLPKCWDYR EP", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("FCIFSRDGVSSCWPGWSRTPDLK*STHLGLPKCWDYRREP", str(hsp.hit.seq)[:40])
        self.assertEqual("SRDGVLPCWSGWSRTPDLR*SACLGLPKCWDYRCEPPRPA", str(hsp.query.seq)[-40:])
        self.assertEqual("SRDGV  CW GWSRTPDL+*S  LGLPKCWDYR EPPRPA", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("SRDGVSSCWPGWSRTPDLK*STHLGLPKCWDYRREPPRPA", str(hsp.hit.seq)[-40:])
        # first qresult, second hit
        hit = qresult[1]
        self.assertEqual("ref|XM_003255417.1|", hit.id)
        self.assertEqual("PREDICTED: Nomascus leucogenys 5'-nucleotidase, cytosolic II, transcript variant 2 (NT5C2), mRNA", hit.description)
        self.assertEqual(3285, hit.seq_len)
        self.assertEqual(3, len(hit))
        # first qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(94, hsp.aln_span)
        self.assertEqual(9e-49, hsp.evalue)
        self.assertEqual(197.0, hsp.bitscore)
        self.assertEqual(425.0, hsp.bitscore_raw)
        self.assertEqual(-2, hsp.query_frame)
        self.assertEqual(-2, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(78, hsp.ident_num)
        self.assertEqual(79, hsp.pos_num)
        self.assertEqual(-1, hsp.query_strand)
        self.assertEqual(-1, hsp.hit_strand)
        self.assertEqual(16, hsp.query_start)
        self.assertEqual(2744, hsp.hit_start)
        self.assertEqual(298, hsp.query_end)
        self.assertEqual(3026, hsp.hit_end)
        self.assertEqual("ETEFRSCCPGWSAMA*SWPTTASTSWIQVILLPQSPE*LG", str(hsp.query.seq)[:40])
        self.assertEqual("E EFRSCCPGWSAMA SW    S SW+QVIL PQ PE*LG", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("EMEFRSCCPGWSAMAQSWLIATSVSWVQVILWPQPPE*LG", str(hsp.hit.seq)[:40])
        self.assertEqual("SRDGVLPCWSGWSRTPDLR*SACLGLPKCWDYRCEPPRPA", str(hsp.query.seq)[-40:])
        self.assertEqual("SRDGV PCWSGWSRTPDLR*SACLGLPKCWDYR EPP PA", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("SRDGVSPCWSGWSRTPDLR*SACLGLPKCWDYRREPPCPA", str(hsp.hit.seq)[-40:])
        # first qresult, second hit, second hsp
        hsp = qresult[1].hsps[1]
        self.assertEqual(94, hsp.aln_span)
        self.assertEqual(4e-43, hsp.evalue)
        self.assertEqual(178.0, hsp.bitscore)
        self.assertEqual(384.0, hsp.bitscore_raw)
        self.assertEqual(3, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(77, hsp.ident_num)
        self.assertEqual(83, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(17, hsp.query_start)
        self.assertEqual(2745, hsp.hit_start)
        self.assertEqual(299, hsp.query_end)
        self.assertEqual(3027, hsp.hit_end)
        self.assertEqual("AGRGGSHL*SQHFGRPRQADYLRSGVRDQPDQHGKTPSLL", str(hsp.query.seq)[:40])
        self.assertEqual("AG GGS L*SQHFGRPRQAD+LRSGVRDQPDQHG+TPSLL", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("AGHGGSRL*SQHFGRPRQADHLRSGVRDQPDQHGETPSLL", str(hsp.hit.seq)[:40])
        self.assertEqual("PSYSGD*GRRIT*IQEVEAVVGQDQAIALQPGQQERNSVS", str(hsp.query.seq)[-40:])
        self.assertEqual("PSYSG *G+RIT* QE E  + QD AIALQPGQQERNS+S", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("PSYSGG*GQRIT*TQETEVAMSQDCAIALQPGQQERNSIS", str(hsp.hit.seq)[-40:])

    def test_text_2226_tblastx_004(self):
        """Test parsing tblastx output (text_2226_tblastx_004.txt)."""
        blast_file = get_file("text_2226_tblastx_004.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(2, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("random_s00", qresult.id)
        self.assertEqual("", qresult.description)
        self.assertEqual(128, qresult.seq_len)
        self.assertEqual("minirefseq_mrna", qresult.target)
        self.assertEqual("tblastx", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(0, len(qresult))

        # test second qresult
        qresult = qresults[1]
        self.assertEqual("gi|296147483:1-350", qresult.id)
        self.assertEqual("Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA,complete cds", qresult.description)
        self.assertEqual(350, qresult.seq_len)
        self.assertEqual("minirefseq_mrna", qresult.target)
        self.assertEqual("tblastx", qresult.program)
        self.assertEqual("2.2.26+", qresult.version)
        self.assertEqual(5, len(qresult))
        # second qresult, first hit
        hit = qresult[0]
        self.assertEqual("gi|296147483|ref|NM_001183135.1|", hit.id)
        self.assertEqual("Saccharomyces cerevisiae S288c Mon2p (MON2) mRNA, complete cds", hit.description)
        self.assertEqual(4911, hit.seq_len)
        self.assertEqual(8, len(hit))
        # second qresult, first hit, first hsp
        hsp = qresult[0].hsps[0]
        self.assertEqual(116, hsp.aln_span)
        self.assertEqual(2e-81, hsp.evalue)
        self.assertEqual(289.0, hsp.bitscore)
        self.assertEqual(626.0, hsp.bitscore_raw)
        self.assertEqual(2, hsp.query_frame)
        self.assertEqual(2, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(116, hsp.ident_num)
        self.assertEqual(116, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(1, hsp.query_start)
        self.assertEqual(1, hsp.hit_start)
        self.assertEqual(349, hsp.query_end)
        self.assertEqual(349, hsp.hit_end)
        self.assertEqual("WP*TLEGLTPCKGNLKQNCVLYLPNRKEEIQPFAMLVINP", str(hsp.query.seq)[:40])
        self.assertEqual("WP*TLEGLTPCKGNLKQNCVLYLPNRKEEIQPFAMLVINP", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("WP*TLEGLTPCKGNLKQNCVLYLPNRKEEIQPFAMLVINP", str(hsp.hit.seq)[:40])
        self.assertEqual("WQCNAYRDCQPFHLFLEAGCLKFWMPSLRLLISRWRFN*K", str(hsp.query.seq)[-40:])
        self.assertEqual("WQCNAYRDCQPFHLFLEAGCLKFWMPSLRLLISRWRFN*K", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("WQCNAYRDCQPFHLFLEAGCLKFWMPSLRLLISRWRFN*K", str(hsp.hit.seq)[-40:])
        # second qresult, first hit, second hsp
        hsp = qresult[0].hsps[1]
        self.assertEqual(116, hsp.aln_span)
        self.assertEqual(5e-78, hsp.evalue)
        self.assertEqual(278.0, hsp.bitscore)
        self.assertEqual(602.0, hsp.bitscore_raw)
        self.assertEqual(-2, hsp.query_frame)
        self.assertEqual(-3, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(116, hsp.ident_num)
        self.assertEqual(116, hsp.pos_num)
        self.assertEqual(-1, hsp.query_strand)
        self.assertEqual(-1, hsp.hit_strand)
        self.assertEqual(1, hsp.query_start)
        self.assertEqual(1, hsp.hit_start)
        self.assertEqual(349, hsp.query_end)
        self.assertEqual(349, hsp.hit_end)
        self.assertEqual("LLIESPSRDE*PQ*RHPKFQTAGFEE*MERLTVPVGIALP", str(hsp.query.seq)[:40])
        self.assertEqual("LLIESPSRDE*PQ*RHPKFQTAGFEE*MERLTVPVGIALP", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("LLIESPSRDE*PQ*RHPKFQTAGFEE*MERLTVPVGIALP", str(hsp.hit.seq)[:40])
        self.assertEqual("WIYH*HGEWLNFFFSIRKIKNAILLQVAFAWSQTLQCSWP", str(hsp.query.seq)[-40:])
        self.assertEqual("WIYH*HGEWLNFFFSIRKIKNAILLQVAFAWSQTLQCSWP", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("WIYH*HGEWLNFFFSIRKIKNAILLQVAFAWSQTLQCSWP", str(hsp.hit.seq)[-40:])
        # second qresult, second hit
        hit = qresult[1]
        self.assertEqual("gi|365982352|ref|XM_003667962.1|", hit.id)
        self.assertEqual("Naumovozyma dairenensis CBS 421 hypothetical protein (NDAI0A06120), mRNA", hit.description)
        self.assertEqual(4932, hit.seq_len)
        self.assertEqual(10, len(hit))
        # second qresult, second hit, first hsp
        hsp = qresult[1].hsps[0]
        self.assertEqual(85, hsp.aln_span)
        self.assertEqual(5e-42, hsp.evalue)
        self.assertEqual(152.0, hsp.bitscore)
        self.assertEqual(327.0, hsp.bitscore_raw)
        self.assertEqual(1, hsp.query_frame)
        self.assertEqual(1, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(62, hsp.ident_num)
        self.assertEqual(73, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(93, hsp.query_start)
        self.assertEqual(87, hsp.hit_start)
        self.assertEqual(348, hsp.query_end)
        self.assertEqual(342, hsp.hit_end)
        self.assertEqual("TIRHASDKSIEILKRVHSFEELERHPDFALPFVLACQSRN", str(hsp.query.seq)[:40])
        self.assertEqual("TI+HASDKSI+ILK + + EEL RHPDF  P VLAC SRN", hsp.aln_annotation["similarity"][:40])
        self.assertEqual("TIKHASDKSIDILKTIQNIEELVRHPDFVTPLVLACSSRN", str(hsp.hit.seq)[:40])
        self.assertEqual("LAMQCLQGLSTVPSIPRSRLSEILDAFIEATHLAMEIQLK", str(hsp.query.seq)[-40:])
        self.assertEqual("+AMQCLQGL++VPSIP SR+ E+LD FIEAT LAMEIQLK", hsp.aln_annotation["similarity"][-40:])
        self.assertEqual("IAMQCLQGLASVPSIPESRIPEVLDGFIEATQLAMEIQLK", str(hsp.hit.seq)[-40:])
        # second qresult, second hit, second hsp
        hsp = qresult[1].hsps[1]
        self.assertEqual(14, hsp.aln_span)
        self.assertEqual(5e-42, hsp.evalue)
        self.assertEqual(26.3, hsp.bitscore)
        self.assertEqual(51.0, hsp.bitscore_raw)
        self.assertEqual(3, hsp.query_frame)
        self.assertEqual(3, hsp.hit_frame)
        self.assertEqual(0, hsp.gap_num)
        self.assertEqual(11, hsp.ident_num)
        self.assertEqual(11, hsp.pos_num)
        self.assertEqual(1, hsp.query_strand)
        self.assertEqual(1, hsp.hit_strand)
        self.assertEqual(68, hsp.query_start)
        self.assertEqual(62, hsp.hit_start)
        self.assertEqual(110, hsp.query_end)
        self.assertEqual(104, hsp.hit_end)
        self.assertEqual("FRIEKKKFNHSPC*", str(hsp.query.seq))
        self.assertEqual("FRI KKKFNH  C*", hsp.aln_annotation["similarity"])
        self.assertEqual("FRI*KKKFNH*TC*", str(hsp.hit.seq))

    def test_text_2230_blastp_001(self):
        """Test parsing blastp output (text_2230_blastp_001.txt)."""
        blast_file = get_file("text_2230_blastp_001.txt")
        qresults = list(parse(blast_file, FMT))
        self.assertEqual(1, len(qresults))
        self.check_common_attrs(qresults)

        # test first qresult
        qresult = qresults[0]
        self.assertEqual("TR11080zzzc0_g2_i2_0", qresult.id)
        self.assertEqual("", qresult.description)
        self.assertEqual(1691, qresult.seq_len)
        self.assertEqual("subject.fasta", qresult.target)
        self.assertEqual("blastp", qresult.program)
        self.assertEqual("2.2.30+", qresult.version)
        self.assertEqual(1, len(qresult))
        self.assertEqual(3, len(qresult.hsps))
        hsp = qresult.hsps[0]
        self.assertIn("PTSP" + ("-" * 79) + "AYSP", hsp.query)
        hsp = qresult.hsps[1]
        self.assertTrue(hsp.query.seq.startswith("AYSPTSPAYSPTSPAYSPTSPAYSPTSPAYS----------PTSPAYSPTSPAYSPTSPA"))
        hsp = qresult.hsps[2]
        self.assertTrue(hsp.query.seq.startswith("YSPTSPAYSPTSPAYSPTSPAYSPTSPAYS----------PTSPAYSPTSPAYSPTSPAY"))


if __name__ == "__main__":
    runner = unittest.TextTestRunner(verbosity=2)
    unittest.main(testRunner=runner)
