text:
import six
import platform
from six.moves import builtins
from copy import deepcopy
from json import dumps
from unittest import TestCase, skip
import sqlite3

try:
    from unittest.mock import patch, mock_open
except ImportError:
    from mock import patch

from Bio import SeqIO

from .sample_data import PARAMS, RECORD0, RECORD1, RECORD2, RECORD3, RECORD4

from dark.reads import Read, Reads, DNARead
from dark.hsp import HSP, LSP
from dark.score import LowerIsBetterScore
from dark.blast.alignments import (
    BlastReadsAlignments, ZERO_EVALUE_UPPER_RANDOM_INCREMENT)
from dark.titles import TitlesAlignments
from dark import ncbidb
from dark.utils import StringIO

class TestBlastReadsAlignments(TestCase):
    """
    Test the BlastReadsAlignments class.
    """

    def testEmptyJSONInput(self):
        """
        When a JSON input file is empty, a C{ValueError} must be raised
        on trying to read it.
        """
        with patch.object(builtins, 'open', mock_open()):
            reads = Reads()
            error = "JSON file 'file.json' was empty\\."
            six.assertRaisesRegex(self, ValueError, error,
                                  BlastReadsAlignments, reads, 'file.json')

    def testNonJSONInput(self):
        """
        When given a file whose contents are not JSON, attempting to
        read the BLAST hits from it must raise a C{ValueError}.
        """
        pypy = platform.python_implementation() == 'PyPy'
        with patch.object(builtins, 'open', mock_open(read_data='not JSON\n')):
            reads = Reads()
            if six.PY3:
                error = (
                    "^Could not convert first line of 'file\\.json' to JSON "
                    "\\(Expecting value: line 1 column 1 \\(char 0\\)\\)\\. "
                    "Line is 'not JSON'\\.$")
            else:
                if pypy:
                    error = (
                        "^Could not convert first line of 'file\\.json' to "
                        "JSON \\(Error when decoding null at char 1\\)\\. "
                        "Line is 'not JSON'\\.$")
                else:
                    error = (
                        "^Could not convert first line of 'file\\.json' to "
                        "JSON \\(No JSON object could be decoded\\)\\. Line "
                        "is 'not JSON'\\.$")
            six.assertRaisesRegex(self, ValueError, error,
                                  BlastReadsAlignments, reads, 'file.json')

    def testScoreTitle_Bits(self):
        """
        The score title must be correct when we are using bit scores.
        """
        data = dumps(PARAMS) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            self.assertEqual('Bit score', readsAlignments.params.scoreTitle)

    def testScoreTitle_EValue(self):
        """
        The score title must be correct when we are using e values.
        """
        data = dumps(PARAMS) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            readsAlignments = BlastReadsAlignments(
                reads, 'file.json', scoreClass=LowerIsBetterScore)
            self.assertEqual('$- log_{10}(e)$',
                             readsAlignments.params.scoreTitle)

    def testNucleotidesBlastn(self):
        """
        The nucleotide type of the subject must be correct when we are using
        blastn.
        """
        data = dumps(PARAMS) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            self.assertEqual('blastn', readsAlignments.params.application)
            self.assertTrue(readsAlignments.params.subjectIsNucleotides)

    def testNucleotidesTblastx(self):
        """
        The nucleotide type of the subject must be correct when we are using
        tblastx.
        """
        params = deepcopy(PARAMS)
        params['application'] = 'tblastx'
        data = dumps(params) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            self.assertEqual('tblastx', readsAlignments.params.application)
            self.assertTrue(readsAlignments.params.subjectIsNucleotides)

    def testNucleotidesBlastx(self):
        """
        The nucleotide type of the subject must be correct when we are using
        blastx.
        """
        params = deepcopy(PARAMS)
        params['application'] = 'blastx'
        data = dumps(params) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            self.assertEqual('blastx', readsAlignments.params.application)
            self.assertFalse(readsAlignments.params.subjectIsNucleotides)

    def testApplicationParams(self):
        """
        BLAST parameters must be extracted from the input JSON file and stored
        correctly.
        """
        data = dumps(PARAMS) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            self.assertEqual(PARAMS, readsAlignments.params.applicationParams)

    def testJSONParamsButNoHits(self):
        """
        When BLAST parameters are present in the input but there are no
        records, the __iter__ method of a L{BlastReadsAlignments} instance must
        not yield anything.
        """
        data = dumps(PARAMS) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            self.assertEqual([], list(readsAlignments))

    def testNotEnoughReads(self):
        """
        If a JSON file contains a parameters section and one hit, but there
        is no read to go with the hit, a C{ValueError} must be raised.
        """
        data = dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            error = ("Read generator failed to yield read number 1 during "
                     "parsing of BLAST file 'file\\.json'\\.")
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            six.assertRaisesRegex(self, ValueError, error, list,
                                  readsAlignments)

    def testTooManyReads(self):
        """
        If a JSON file contains a parameters section and one hit, but there
        is more than one read, a C{ValueError} must be raised.
        """
        data = dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'G' * 70))
            error = ("Reads iterator contained more reads than the number of "
                     "BLAST records found \\(1\\)\\. First unknown read id is "
                     "'id1'\\.")
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            six.assertRaisesRegex(self, ValueError, error, list,
                                  readsAlignments)

    def testIncorrectReadId(self):
        """
        If the query id of a hit does not match the id of the corresponding
        input read, a C{ValueError} must be raised.
        """
        data = dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('not id0', 'A' * 70))
            error = ("The reads you have provided do not match the BLAST "
                     "output: BLAST record query id \\(id0\\) does "
                     "not match the id of the supposedly corresponding read "
                     "\\(not id0\\)\\.")
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            six.assertRaisesRegex(self, ValueError, error, list,
                                  readsAlignments)

    def testOneJSONInput(self):
        """
        If a JSON file contains a parameters section and one record, it must
        be read correctly.
        """
        result = StringIO(dumps(PARAMS) + '\n' +
                          dumps(RECORD0) + '\n')

        with patch.object(builtins, 'open') as mockMethod:
            mockMethod.return_value = result
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            self.assertEqual(1, len(list(readsAlignments)))

    def testTwoJSONInputs(self):
        """
        If two JSON files are passed to L{BlastReadsAlignments} each with a
        parameters section and one record, both records must be read correctly
        and the result should have 2 records.
        """

        class SideEffect(object):
            def __init__(self):
                self.first = True

            def sideEffect(self, _ignoredFilename, **kwargs):
                if self.first:
                    self.first = False
                    return StringIO(dumps(PARAMS) + '\n' +
                                    dumps(RECORD0) + '\n')
                else:
                    return StringIO(dumps(PARAMS) + '\n' +
                                    dumps(RECORD1) + '\n')

        sideEffect = SideEffect()
        with patch.object(builtins, 'open') as mockMethod:
            mockMethod.side_effect = sideEffect.sideEffect
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            readsAlignments = BlastReadsAlignments(
                reads, ['file1.json', 'file2.json'])
            result = list(readsAlignments)
            self.assertEqual(2, len(result))
            self.assertEqual('id0', result[0].read.id)
            self.assertEqual('id1', result[1].read.id)

    def testTwoJSONInputsWithSubjectInCommon(self):
        """
        If two JSON files are passed to L{BlastReadsAlignments} with a matched
        subject in common, the title should be in the alignments for both
        reads.
        """

        class SideEffect(object):
            def __init__(self):
                self.first = True

            def sideEffect(self, _ignoredFilename, **kwargs):
                if self.first:
                    self.first = False
                    return StringIO(dumps(PARAMS) + '\n' +
                                    dumps(RECORD2) + '\n')
                else:
                    return StringIO(dumps(PARAMS) + '\n' +
                                    dumps(RECORD3) + '\n')

        sideEffect = SideEffect()
        with patch.object(builtins, 'open') as mockMethod:
            mockMethod.side_effect = sideEffect.sideEffect
            reads = Reads()
            reads.add(Read('id2', 'A' * 70))
            reads.add(Read('id3', 'A' * 70))
            readsAlignments = BlastReadsAlignments(
                reads, ['file1.json', 'file2.json'])
            result = list(readsAlignments)
            self.assertEqual(2, len(result))
            self.assertEqual('id2', result[0].read.id)
            self.assertEqual('gi|887699|gb|DQ37780 Cowpox virus 15',
                             result[0][0].subjectTitle)
            self.assertEqual('id3', result[1].read.id)
            self.assertEqual('gi|887699|gb|DQ37780 Cowpox virus 15',
                             result[1][0].subjectTitle)

    def testThreeJSONInputs(self):
        """
        If three JSON files are passed to L{BlastReadsAlignments} with names
        that have a numeric prefix and each with a parameters section and one
        record, all records must be read correctly and the result should have
        3 records in the correct order.
        """
        class SideEffect(object):
            def __init__(self, test):
                self.test = test
                self.count = 0

            def sideEffect(self, filename, **kwargs):
                if self.count == 0:
                    self.test.assertEqual('1.json', filename)
                    self.count += 1
                    return StringIO(dumps(PARAMS) + '\n' +
                                    dumps(RECORD0) + '\n')
                elif self.count == 1:
                    self.test.assertEqual('2.json', filename)
                    self.count += 1
                    return StringIO(dumps(PARAMS) + '\n' +
                                    dumps(RECORD1) + '\n')
                else:
                    self.test.assertEqual('3.json', filename)
                    return StringIO(dumps(PARAMS) + '\n' +
                                    dumps(RECORD2) + '\n')

        sideEffect = SideEffect(self)
        with patch.object(builtins, 'open') as mockMethod:
            mockMethod.side_effect = sideEffect.sideEffect
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))

            # Note the files are given out of order. Their names will be
            # sorted before they are opened. The sorting of the names is
            # verified in the SideEffect class, above.
            readsAlignments = BlastReadsAlignments(
                reads, ['3.json', '1.json', '2.json'])
            result = list(readsAlignments)
            self.assertEqual(3, len(result))
            self.assertEqual('id0', result[0].read.id)
            self.assertEqual('id1', result[1].read.id)
            self.assertEqual('id2', result[2].read.id)

    def testIncompatibleParameters(self):
        """
        If two compressed (bz2) JSON files with incompatible parameters
        are given to L{BlastReadsAlignments}, a C{ValueError} must be
        raised when the files are read.
        """

        class SideEffect(object):
            def __init__(self):
                self.first = True

            def sideEffect(self, _ignoredFilename):
                if self.first:
                    self.first = False
                    return StringIO(dumps(PARAMS) + '\n' +
                                    dumps(RECORD0) + '\n')
                else:
                    params = deepcopy(PARAMS)
                    params['application'] = 'Skype'
                    return StringIO(dumps(params) + '\n' +
                                    dumps(RECORD1) + '\n')

        sideEffect = SideEffect()
        with patch.object(builtins, 'open') as mockMethod:
            mockMethod.side_effect = sideEffect.sideEffect
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            if six.PY3:
                error = (
                    "^Incompatible BLAST parameters found\\. The parameters "
                    "in file2\\.json differ from those originally found "
                    "in file1\\.json. Summary of differences:\n\tParam "
                    "'application' initial value 'BLASTN' differs from "
                    "later value 'Skype'$")
            else:
                # Python 2 prints a 'u' before the repr of strings in the error
                # message. In Python 3 all strings are unicode.
                error = (
                    "^Incompatible BLAST parameters found\\. The parameters "
                    "in file2\\.json differ from those originally found "
                    "in file1\\.json. Summary of differences:\n\tParam "
                    "u'application' initial value u'BLASTN' differs from "
                    "later value u'Skype'$")
            readsAlignments = BlastReadsAlignments(
                reads, ['file1.json', 'file2.json'])
            six.assertRaisesRegex(self, ValueError, error, list,
                                  readsAlignments)

    def testGetSubjectSequenceBlastdbcmd(self):
        """
        The getSubjectSequence function must return a correct C{DNARead}
        instance with a 'sequence' attribute that is a string when the
        sequence is fetched using ncbidb.getSequence.
        """
        handle = SeqIO.read(StringIO('>id1 Description\nAA\n'), 'fasta')
        data = dumps(PARAMS) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            with patch.object(ncbidb, 'getSequence') as mockMethod:
                mockMethod.return_value = handle
                sequence = readsAlignments.getSubjectSequence('title')
                self.assertIsInstance(sequence, DNARead)
                self.assertIsInstance(sequence.sequence, str)
                self.assertEqual('id1 Description', sequence.id)
                self.assertEqual('AA', sequence.sequence)

    @skip('Some tests are broken and skipped under latest BioPython')
    def testGetSubjectSequenceFASTADatabase(self):
        """
        The getSubjectSequence function must return the correct C{DNARead}
        instance when a FASTA database filename is given to the
        BlastReadsAlignments constructor.
        """
        class SideEffect(object):
            def __init__(self, test):
                self.test = test
                self.count = 0

            def sideEffect(self, filename, mode='r'):
                if self.count == 0:
                    self.test.assertEqual('file.json', filename)
                    self.count += 1
                    return StringIO(dumps(PARAMS) + '\n' +
                                    dumps(RECORD0) + '\n')
                elif self.count == 1:
                    self.count += 1
                    return StringIO('>id1 Description\nAA\n')
                else:
                    self.test.fail(
                        'Unexpected third call to open, filename %r.' %
                        filename)

        sideEffect = SideEffect(self)

        with patch.object(builtins, 'open') as mockMethod:
            mockMethod.side_effect = sideEffect.sideEffect
            reads = Reads()
            readsAlignments = BlastReadsAlignments(
                reads, 'file.json', databaseFilename='database.fasta')
            subject = readsAlignments.getSubjectSequence('id1 Description')
            self.assertIsInstance(subject, DNARead)
            self.assertIsInstance(subject.sequence, str)
            self.assertEqual('id1 Description', subject.id)
            self.assertEqual('AA', subject.sequence)

    @patch('os.path.exists')
    def testGetSubjectSequenceSqliteDatabase(self, existsMock):
        """
        The getSubjectSequence function must return the correct C{DNARead}
        instance when a FASTA sqlite database filename is given to the
        BlastReadsAlignments constructor.
        """

        class ConnectSideEffect(object):
            def __init__(self):
                connection = sqlite3.connect(':memory:')
                cur = connection.cursor()
                cur.executescript('''
                    CREATE TABLE files (
                            id INTEGER PRIMARY KEY AUTOINCREMENT,
                        name VARCHAR UNIQUE
                    );

                    CREATE TABLE sequences (
                        id VARCHAR UNIQUE PRIMARY KEY,
                        fileNumber INTEGER,
                        offset INTEGER
                    );
                ''')
                cur.execute('INSERT INTO files(name) VALUES (?)',
                            ('xxx.fasta',))
                fileNumber = cur.lastrowid
                cur.execute(
                    'INSERT INTO sequences(id, '
                    'fileNumber, offset) VALUES (?, ?, ?)',
                    ('seqid', fileNumber, 7))
                connection.commit()
                self.connection = connection

            def sideEffect(self, filename):
                return self.connection

        class OpenSideEffect(object):
            def __init__(self, test):
                self.test = test
                self.count = 0

            def sideEffect(self, filename, mode='r'):
                if self.count == 0:
                    self.test.assertEqual('file.json', filename)
                    self.count += 1
                    return StringIO(dumps(PARAMS) + '\n' +
                                    dumps(RECORD0) + '\n')
                elif self.count == 1:
                    self.test.assertEqual('xxx.fasta', filename)
                    self.count += 1
                    return StringIO('>seqid\nAA\n')
                else:
                    self.test.fail('Unexpected third call to open.')

        connectSideEffect = ConnectSideEffect()
        with patch.object(sqlite3, 'connect') as mockMethod:
            mockMethod.side_effect = connectSideEffect.sideEffect

            openSideEffect = OpenSideEffect(self)
            with patch.object(builtins, 'open') as mockMethod:
                mockMethod.side_effect = openSideEffect.sideEffect

                reads = Reads()
                readsAlignments = BlastReadsAlignments(
                    reads, 'file.json', sqliteDatabaseFilename='dummy')
                subject = readsAlignments.getSubjectSequence('seqid')
                self.assertIsInstance(subject, DNARead)
                self.assertIsInstance(subject.sequence, str)
                self.assertEqual('seqid', subject.id)
                self.assertEqual('AA', subject.sequence)

    def testGetSubjectSequenceThenReverseComplement(self):
        """
        It must be possible to call reverseComplement on the return
        result of getSubjectSequence and obtain a correct C{DNARead} result.
        """
        data = dumps(PARAMS) + '\n'
        handle = SeqIO.read(StringIO('>id1 Description\nACGAT\n'), 'fasta')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            with patch.object(ncbidb, 'getSequence') as mockMethod:
                mockMethod.return_value = handle
                sequence = readsAlignments.getSubjectSequence('title')
                rc = sequence.reverseComplement()
                self.assertIsInstance(rc, DNARead)
                self.assertIsInstance(rc.sequence, str)
                self.assertEqual('id1 Description', rc.id)
                self.assertEqual('ATCGT', rc.sequence)

    def testHsps(self):
        """
        The hsps function must yield the HSPs.
        """
        # adjustHspsForPlotting changes HSPs in place, so we pass copied
        # records so we don't mess up other tests.
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n' +
                dumps(RECORD3) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            reads.add(Read('id3', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            self.assertEqual(
                sorted([HSP(20), HSP(25), HSP(20), HSP(20), HSP(20), HSP(20)]),
                sorted(readsAlignments.hsps()))

    def testAdjustHspsForPlotting_EValueNoZero(self):
        """
        The adjustHspsForPlotting function must alter HSPs so that non-zero
        evalues are converted to the positive value of their negative exponent.
        """
        def result(a, **kwargs):
            return StringIO(
                dumps(PARAMS) + '\n' +
                dumps(deepcopy(RECORD0)) + '\n' +
                dumps(deepcopy(RECORD1)) + '\n' +
                dumps(deepcopy(RECORD2)) + '\n' +
                dumps(deepcopy(RECORD3)) + '\n')

        with patch.object(builtins, 'open') as mockMethod:
            mockMethod.side_effect = result
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            reads.add(Read('id3', 'A' * 70))
            readsAlignments = BlastReadsAlignments(
                reads, 'file.json', scoreClass=LowerIsBetterScore)
            titlesAlignments = TitlesAlignments(readsAlignments)
            title = 'gi|887699|gb|DQ37780 Cowpox virus 15'
            titleAlignments = titlesAlignments[title]
            readsAlignments.adjustHspsForPlotting(titleAlignments)
            hsps = sorted(titleAlignments.hsps())
            self.assertEqual([6.0, 5.0], [hsp.score.score for hsp in hsps])

    def testAdjustHspsForPlotting_EValueWithZero(self):
        """
        The adjustHspsForPlotting function must alter HSPs so that zero
        evalues are set randomly high.
        """
        def result(a, **kwargs):
            return StringIO(
                dumps(PARAMS) + '\n' +
                dumps(deepcopy(RECORD0)) + '\n' +
                dumps(deepcopy(RECORD1)) + '\n' +
                dumps(deepcopy(RECORD2)) + '\n' +
                dumps(deepcopy(RECORD3)) + '\n' +
                dumps(deepcopy(RECORD4)) + '\n')

        with patch.object(builtins, 'open') as mockMethod:
            mockMethod.side_effect = result
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            reads.add(Read('id3', 'A' * 70))
            reads.add(Read('id4', 'A' * 70))
            readsAlignments = BlastReadsAlignments(
                reads, 'file.json', scoreClass=LowerIsBetterScore)
            titlesAlignments = TitlesAlignments(readsAlignments)
            title = 'gi|887699|gb|DQ37780 Cowpox virus 15'
            titleAlignments = titlesAlignments[title]
            readsAlignments.adjustHspsForPlotting(titleAlignments)
            hsps = sorted(titleAlignments.hsps())
            # All we really know is that the first HSP will have a randomly
            # high value whose bounds we can check. The other values are
            # predictable.
            self.assertTrue(LSP(6.0 + 2) > hsps[0] >
                            LSP(6.0 + 2 + ZERO_EVALUE_UPPER_RANDOM_INCREMENT))
            self.assertEqual([6.0, 5.0, 3.0, 2.0],
                             [hsp.score.score for hsp in hsps[1:]])

class TestBlastReadsAlignmentsFiltering(TestCase):
    """
    Test the BlastReadsAlignments class filter function.
    """

    def testNoResultNoFilteringArgs(self):
        """
        If the L{BlastReadsAlignments} filter function is called with no
        arguments, and there are no hits, it should produce a generator
        that yields no result.
        """
        data = dumps(PARAMS) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter())
            self.assertEqual(0, len(result))

    def testOneHitNoFilteringArgs(self):
        """
        If the L{BlastReadsAlignments} filter function is called with no
        arguments, and there is one hit, it should produce a generator that
        yields that hit.
        """
        data = dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter())
            self.assertEqual(1, len(result))
            self.assertEqual('id0', result[0].read.id)

    def testLimitZero(self):
        """
        If L{BlastReadsAlignments} is limited to zero result, that limit must
        be respected.
        """
        data = dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(limit=0))
            self.assertEqual(0, len(result))

    def testLimitOne(self):
        """
        If L{BlastReadsAlignments} is limited to one hit, that limit must
        be respected.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(limit=1))
            self.assertEqual(1, len(result))
            self.assertEqual('id0', result[0].read.id)

    def testOneAlignmentPerRead(self):
        """
        If L{BlastReadsAlignments} is asked to deliver only the best alignment
        for each read, that must be respected.
        """
        record = {
            "query": "H6E8I1T01BFUH9",
            "alignments": [
                {
                    "length": 2885,
                    "hsps": [
                        {
                            "sbjct_end": 2506,
                            "expect": 1.25854e-43,
                            "sbjct": "AATCCAGGGAATGAATAAAATAATCATTAGCAGTAACAA",
                            "sbjct_start": 2607,
                            "query": "AATCCAGGGAATAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 182.092,
                            "query_start": 362
                        }
                    ],
                    "title": "Merkel1"
                },
                {
                    "length": 2220,
                    "hsps": [
                        {
                            "sbjct_end": 1841,
                            "expect": 1.25854e-43,
                            "sbjct": "AATCCAGGGAATCTAATAAAATAATCAA",
                            "sbjct_start": 1942,
                            "query": "AATCCAGGGAATCTTAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 180,
                            "query_start": 362
                        }
                    ],
                    "title":"Merkel2"
                }
            ]
        }

        data = dumps(PARAMS) + '\n' + dumps(record) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('H6E8I1T01BFUH9', 'A' * 500))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(oneAlignmentPerRead=True))
            self.assertEqual(1, len(result))
            self.assertEqual(1, len(result[0]))
            self.assertEqual('Merkel1', result[0][0].subjectTitle)

    def testMaxZeroAlignmentsPerRead(self):
        """
        If L{BlastReadsAlignments} is asked to deliver only reads that have at
        most zero alignments, a read with no alignments must be allowed
        through but a read with one alignment must be filtered out.
        """
        record1 = {
            "query": "read1",
            "alignments": [],
        }

        record2 = {
            "query": "read2",
            "alignments": [
                {
                    "length": 2885,
                    "hsps": [
                        {
                            "sbjct_end": 2506,
                            "expect": 1.25854e-43,
                            "sbjct": "AATCCAGGGAATGAATAAAATAATCATTAGCAGTAACAA",
                            "sbjct_start": 2607,
                            "query": "AATCCAGGGAATAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 182.092,
                            "query_start": 362
                        }
                    ],
                    "title": "Merkel1"
                },
            ],
        }

        data = (dumps(PARAMS) + '\n' + dumps(record1) + '\n' +
                dumps(record2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('read1', 'A' * 500))
            reads.add(Read('read2', 'G' * 500))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(maxAlignmentsPerRead=0))
            self.assertEqual(1, len(result))
            self.assertEqual('read1', result[0].read.id)

    def testMaxOneAlignmentPerRead(self):
        """
        If L{BlastReadsAlignments} is asked to deliver only reads that have at
        most one alignment, a read with two alignments must be filtered out.
        """
        record = {
            "query": "H6E8I1T01BFUH9",
            "alignments": [
                {
                    "length": 2885,
                    "hsps": [
                        {
                            "sbjct_end": 2506,
                            "expect": 1.25854e-43,
                            "sbjct": "AATCCAGGGAATGAATAAAATAATCATTAGCAGTAACAA",
                            "sbjct_start": 2607,
                            "query": "AATCCAGGGAATAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 182.092,
                            "query_start": 362
                        }
                    ],
                    "title": "Merkel1"
                },
                {
                    "length": 2220,
                    "hsps": [
                        {
                            "sbjct_end": 1841,
                            "expect": 1.25854e-43,
                            "sbjct": "AATCCAGGGAATCTAATAAAATAATCAA",
                            "sbjct_start": 1942,
                            "query": "AATCCAGGGAATCTTAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 180,
                            "query_start": 362
                        }
                    ],
                    "title":"Merkel2"
                }
            ]
        }

        data = dumps(PARAMS) + '\n' + dumps(record) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('H6E8I1T01BFUH9', 'A' * 500))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(maxAlignmentsPerRead=1))
            self.assertEqual(0, len(result))

    def testScoreCutoffRemovesEntireAlignment_Bits(self):
        """
        If the L{BlastReadsAlignments} filter function is supposed to filter on
        a scoreCutoff (bit score) and the cut-off value results in an
        alignment with no HSPs, then the alignment must be removed entirely.
        """
        record = {
            "query": "H6E8I1T01BFUH9",
            "alignments": [
                {
                    "length": 2885,
                    "hsps": [
                        {
                            "sbjct_end": 2506,
                            "expect": 1.25854e-10,
                            "sbjct": "AATCCAGGGAATGAATAAAATAATCATTAGCAGTAACAA",
                            "sbjct_start": 2607,
                            "query": "AATCCAGGGAATAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 150,
                            "query_start": 362
                        }
                    ],
                    "title": "Merkel1"
                },
                {
                    "length": 2220,
                    "hsps": [
                        {
                            "sbjct_end": 1841,
                            "expect": 1.25854e-43,
                            "sbjct": "AATCCAGGGAATCTAATAAAATAATCAA",
                            "sbjct_start": 1942,
                            "query": "AATCCAGGGAATCTTAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 180,
                            "query_start": 362
                        }
                    ],
                    "title": "Merkel2"
                }
            ]
        }

        data = dumps(PARAMS) + '\n' + dumps(record) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('H6E8I1T01BFUH9', 'A' * 500))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(scoreCutoff=160))
            self.assertEqual(1, len(result))
            self.assertEqual(1, len(result[0]))
            self.assertEqual('Merkel2', result[0][0].subjectTitle)

    def testScoreCutoffRemovesEntireAlignment_EValue(self):
        """
        If the L{BlastReadsAlignments} filter function is supposed to filter on
        a scoreCutoff (bit score) and the cut-off value results in an
        alignment with no HSPs, then the alignment must be removed entirely.
        """
        record = {
            "query": "H6E8I1T01BFUH9",
            "alignments": [
                {
                    "length": 2885,
                    "hsps": [
                        {
                            "sbjct_end": 2506,
                            "expect": 1.25e-10,
                            "sbjct": "AATCCAGGGAATGAATAAAATAATCATTAGCAGTAACAA",
                            "sbjct_start": 2607,
                            "query": "AATCCAGGGAATAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 150,
                            "query_start": 362
                        }
                    ],
                    "title": "Merkel1"
                },
                {
                    "length": 2220,
                    "hsps": [
                        {
                            "sbjct_end": 1841,
                            "expect": 1.25e-30,
                            "sbjct": "AATCCAGGGAATCTAATAAAATAATCAA",
                            "sbjct_start": 1942,
                            "query": "AATCCAGGGAATCTTAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 180,
                            "query_start": 362
                        }
                    ],
                    "title": "Merkel2"
                }
            ]
        }

        data = dumps(PARAMS) + '\n' + dumps(record) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('H6E8I1T01BFUH9', 'A' * 500))
            readsAlignments = BlastReadsAlignments(
                reads, 'file.json', scoreClass=LowerIsBetterScore)
            result = list(readsAlignments.filter(scoreCutoff=1e-20))
            self.assertEqual(1, len(result))
            self.assertEqual(1, len(result[0]))
            self.assertEqual('Merkel2', result[0][0].subjectTitle)

    def testScoreCutoffRemovesHsps_Bits(self):
        """
        If the L{BlastRecords} records function is supposed to filter on
        scoreCutoff (bit score) and the cut-off value results in some HSPs
        being invalid, then those HSPs must be removed entirely.
        """
        record = {
            "query": "H6E8I1T01BFUH9",
            "alignments": [
                {
                    "length": 2885,
                    "hsps": [
                        {
                            "sbjct_end": 2506,
                            "expect": 1.25854e-10,
                            "sbjct": "AATCCAGGGAATGAATAAAATAATCATTAGCAGTAACAA",
                            "sbjct_start": 2607,
                            "query": "AATCCAGGGAATAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 150,
                            "query_start": 362
                        },
                        {
                            "sbjct_end": 2506,
                            "expect": 1.25e-20,
                            "sbjct": "AATCCAGGGAATGAATAAAATAATCATTAGCAGTAACAA",
                            "sbjct_start": 2607,
                            "query": "AATCCAGGGAATAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 170,
                            "query_start": 362
                        }
                    ],
                    "title": "Merkel1"
                },
                {
                    "length": 2220,
                    "hsps": [
                        {
                            "sbjct_end": 1841,
                            "expect": 1.25e-43,
                            "sbjct": "AATCCAGGGAATCTAATAAAATAATCAA",
                            "sbjct_start": 1942,
                            "query": "AATCCAGGGAATCTTAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 180,
                            "query_start": 362
                        }
                    ],
                    "title": "Merkel2"
                }
            ]
        }

        data = dumps(PARAMS) + '\n' + dumps(record) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('H6E8I1T01BFUH9', 'A' * 500))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(scoreCutoff=160))

            # There should only be one HSP left in the alignments for the
            # first read, and it should have the right score (bit score).
            self.assertEqual(1, len(result[0][0].hsps))
            self.assertEqual(HSP(170), result[0][0].hsps[0])

            # The second alignment should also be present.
            self.assertEqual(1, len(result[0][1].hsps))
            self.assertEqual(HSP(180), result[0][1].hsps[0])

    def testScoreCutoffRemovesHsps_EValue(self):
        """
        If the L{BlastRecords} records function is supposed to filter on
        scoreCutoff (bit score) and the cut-off value results in some HSPs
        being invalid, then those HSPs must be removed entirely.
        """
        record = {
            "query": "H6E8I1T01BFUH9",
            "alignments": [
                {
                    "length": 2885,
                    "hsps": [
                        {
                            "sbjct_end": 2506,
                            "expect": 1.25e-10,
                            "sbjct": "AATCCAGGGAATGAATAAAATAATCATTAGCAGTAACAA",
                            "sbjct_start": 2607,
                            "query": "AATCCAGGGAATAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 150,
                            "query_start": 362
                        },
                        {
                            "sbjct_end": 2506,
                            "expect": 1.25e-20,
                            "sbjct": "AATCCAGGGAATGAATAAAATAATCATTAGCAGTAACAA",
                            "sbjct_start": 2607,
                            "query": "AATCCAGGGAATAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 170,
                            "query_start": 362
                        }
                    ],
                    "title": "Merkel1"
                },
                {
                    "length": 2220,
                    "hsps": [
                        {
                            "sbjct_end": 1841,
                            "expect": 1.25e-30,
                            "sbjct": "AATCCAGGGAATCTAATAAAATAATCAA",
                            "sbjct_start": 1942,
                            "query": "AATCCAGGGAATCTTAAA-TAATCATTAGCAGTAACAA",
                            "frame": [1, -1],
                            "query_end": 462,
                            "bits": 180,
                            "query_start": 362
                        }
                    ],
                    "title": "Merkel2"
                }
            ]
        }

        data = dumps(PARAMS) + '\n' + dumps(record) + '\n'
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('H6E8I1T01BFUH9', 'A' * 500))
            readsAlignments = BlastReadsAlignments(
                reads, 'file.json', scoreClass=LowerIsBetterScore)
            result = list(readsAlignments.filter(scoreCutoff=1e-15))

            # There should only be one HSP left in the alignments for the
            # first read, and it should have the right score (e-value).
            self.assertEqual(1, len(result[0][0].hsps))
            self.assertEqual(LSP(1.25e-20), result[0][0].hsps[0])

            # The second alignment should also be present.
            self.assertEqual(1, len(result[0][1].hsps))
            self.assertEqual(LSP(1.25e-30), result[0][1].hsps[0])

    def testTitleByRegexCaseInvariant(self):
        """
        Filtering with a title regex must work independent of case.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(titleRegex='sqUIRRel'))
            self.assertEqual(1, len(result))
            self.assertEqual('id0', result[0].read.id)
            self.assertEqual('gi|887699|gb|DQ37780 Squirrelpox virus 1296/99',
                             result[0][0].subjectTitle)

    def testTitleByRegexAllAlignments(self):
        """
        Filtering with a title regex must work in the case that all alignments
        for a hit match the regex.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(titleRegex='squirrel'))
            self.assertEqual(1, len(result))
            self.assertEqual('id0', result[0].read.id)
            self.assertEqual('gi|887699|gb|DQ37780 Squirrelpox virus 1296/99',
                             result[0][0].subjectTitle)

    def testTitleByRegexOneAlignments(self):
        """
        Filtering with a title regex must work in the case that only some
        alignments for a hit match the regex.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(titleRegex='Mummy'))
            self.assertEqual(1, len(result))
            self.assertEqual('id1', result[0].read.id)
            self.assertEqual('gi|887699|gb|DQ37780 Mummypox virus 3000 B.C.',
                             result[0][0].subjectTitle)

    def testTitleByNegativeRegexOneAlignment(self):
        """
        Filtering with a negative title regex must work in the case that only
        some alignments for a hit are ruled out (in which case only those
        alignments must be removed but the hit is still valid).
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(negativeTitleRegex='Mummy'))
            self.assertEqual(3, len(result))
            self.assertEqual('id1', result[1].read.id)
            self.assertEqual(1, len(result[1]))
            self.assertEqual('gi|887699|gb|DQ37780 Monkeypox virus 456',
                             result[1][0].subjectTitle)

    def testTitleByNegativeRegexMatchesAll(self):
        """
        Filtering with a negative title regex that matches all alignments
        must remove everything and return an empty result.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(negativeTitleRegex='pox'))
            self.assertEqual(0, len(result))

    def testTitleByNegativeRegexMatchingAllWithWhitelist(self):
        """
        Filtering with a negative title regex that matches all alignments
        must remove everything and result in no hits, except for any
        whitelisted titles.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            title = 'gi|887699|gb|DQ37780 Squirrelpox virus 1296/99'
            result = list(readsAlignments.filter(negativeTitleRegex='pox',
                                                 whitelist=[title]))
            self.assertEqual(1, len(result))
            self.assertEqual('id0', result[0].read.id)
            self.assertEqual(1, len(result[0]))
            self.assertEqual(title, result[0][0].subjectTitle)

    def testTitleByRegexMatchingAllWithBlacklist(self):
        """
        Filtering with a title regex that matches all alignments
        must keep everything, except for any blacklisted titles.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            blacklist = ['gi|887699|gb|DQ37780 Squirrelpox virus 1296/99',
                         'gi|887699|gb|DQ37780 Squirrelpox virus 55']
            result = list(readsAlignments.filter(titleRegex='pox',
                                                 blacklist=blacklist))
            self.assertEqual(2, len(result))
            self.assertEqual('id1', result[0].read.id)
            self.assertEqual('id2', result[1].read.id)

    def testTitleTruncation(self):
        """
        When truncating titles, if a set of matched sequences has titles that
        are identical up to the truncation word, only the first found is
        returned.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = readsAlignments.filter(truncateTitlesAfter='virus')
            result = list(result)
            self.assertEqual(3, len(result))
            self.assertEqual('id0', result[0].read.id)
            self.assertEqual(1, len(result[0]))
            # The Squirrelpox virus 55 hit in RECORD0 is not returned.
            self.assertEqual('gi|887699|gb|DQ37780 Squirrelpox virus 1296/99',
                             result[0][0].subjectTitle)

    def testMinTitleSequenceLength(self):
        """
        It must be possible to filter alignments based on minimum hit sequence
        length.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(minSequenceLen=37500))
            self.assertEqual(1, len(result))
            self.assertEqual('id0', result[0].read.id)
            self.assertEqual(1, len(result[0]))
            self.assertEqual('gi|887699|gb|DQ37780 Squirrelpox virus 55',
                             result[0][0].subjectTitle)

    def testMinTitleSequenceLengthNoHits(self):
        """
        It must be possible to filter alignments based on minimum hit sequence
        length and if nothing sufficiently long matches, an empty list of
        alignments must be returned.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(minSequenceLen=1000000))
            self.assertEqual(0, len(result))

    def testMaxTitleSequenceLength(self):
        """
        It must be possible to filter alignments based on maximum hit sequence
        length.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(maxSequenceLen=31000))
            self.assertEqual(1, len(result))
            self.assertEqual('id2', result[0].read.id)
            self.assertEqual(1, len(result[0]))
            self.assertEqual('gi|887699|gb|DQ37780 Cowpox virus 15',
                             result[0][0].subjectTitle)

    def testMaxTitleSequenceLengthNoHits(self):
        """
        It must be possible to filter alignments based on maximum hit sequence
        length and if no sufficiently short sequences match, an empty
        list of alignments must be returned.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(maxSequenceLen=10000))
            self.assertEqual(0, len(result))

    def testMinAndMaxTitleSequenceLength(self):
        """
        It must be possible to filter alignments simultaneously on minimum and
        maximum hit sequence length.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(minSequenceLen=37000,
                                                 maxSequenceLen=38000))
            self.assertEqual(1, len(result))
            self.assertEqual('id0', result[0].read.id)
            self.assertEqual(2, len(result[0]))
            self.assertEqual('gi|887699|gb|DQ37780 Squirrelpox virus 1296/99',
                             result[0][0].subjectTitle)
            self.assertEqual('gi|887699|gb|DQ37780 Squirrelpox virus 55',
                             result[0][1].subjectTitle)

    def testMinStart(self):
        """
        It must be possible to filter alignments based on minimum offset in
        the hit sequence.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(minStart=15300))
            self.assertEqual(1, len(result))
            self.assertEqual('id0', result[0].read.id)
            self.assertEqual(1, len(result[0]))
            self.assertEqual('gi|887699|gb|DQ37780 Squirrelpox virus 1296/99',
                             result[0][0].subjectTitle)

    def testMinStartNoHits(self):
        """
        It must be possible to filter alignments based on minimum offset in
        the hit sequence, and if no hsps match then an empty result set
        must be returned.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(minStart=100000))
            self.assertEqual(0, len(result))

    def testMaxStop(self):
        """
        It must be possible to filter alignments based on maximum offset in
        the hit sequence.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(maxStop=1500))
            self.assertEqual(1, len(result))
            self.assertEqual('id2', result[0].read.id)
            self.assertEqual(1, len(result[0]))
            self.assertEqual('gi|887699|gb|DQ37780 Cowpox virus 15',
                             result[0][0].subjectTitle)

    def testMaxStopNoHits(self):
        """
        It must be possible to filter alignments based on maximum offset in
        the hit sequence, and if no hsps match then an empty result set must
        be returned.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(maxStop=100))
            self.assertEqual(0, len(result))

    def testMinStartAndMaxstop(self):
        """
        It must be possible to filter alignments based simultaneously on
        mininum and maximum offset in the hit sequence.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(minStart=9000, maxStop=12000))
            self.assertEqual(1, len(result))
            self.assertEqual('id1', result[0].read.id)
            self.assertEqual(2, len(result[0]))

    def testRepeatedFilter_MinStartThenMinStart(self):
        """
        It must be possible to filter alignments multiple times using the same
        filter parameters.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json').filter(
                minStart=9000).filter(minStart=9000)
            result = list(readsAlignments)
            self.assertEqual(2, len(result))
            self.assertEqual('id0', result[0].read.id)
            self.assertEqual('id1', result[1].read.id)

    def testRepeatedFilter_MinStartThenMaxstop(self):
        """
        It must be possible to filter alignments multiple times using different
        filter parameters.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json').filter(
                minStart=9000).filter(maxStop=12000)
            result = list(readsAlignments)
            self.assertEqual(1, len(result))
            self.assertEqual('id1', result[0].read.id)
            self.assertEqual(2, len(result[0]))

    def testReadIdNoMatches(self):
        """
        When filtering on alignments based on a regex for
        read ids that matches no ids, an empty generator must be returned.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(readIdRegex='blah'))
            self.assertEqual(0, len(result))

    def testReadId(self):
        """
        It must be possible to filter alignments based on a regex for
        read ids.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(readIdRegex='id[12]'))
            self.assertEqual(2, len(result))
            self.assertEqual('id1', result[0].read.id)
            self.assertEqual('id2', result[1].read.id)

    def testReadIdAnchored(self):
        """
        It must be possible to filter alignments based on a regex for
        read ids that is anchored at start and end.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(readIdRegex='^id0$'))
            self.assertEqual(1, len(result))
            self.assertEqual('id0', result[0].read.id)

    def testReadIdCaseSensitive(self):
        """
        Filtering alignments based on a regex for read ids must be case
        sensitive.
        """
        data = (dumps(PARAMS) + '\n' + dumps(RECORD0) + '\n' +
                dumps(RECORD1) + '\n' + dumps(RECORD2) + '\n')
        with patch.object(builtins, 'open', mock_open(read_data=data)):
            reads = Reads()
            reads.add(Read('id0', 'A' * 70))
            reads.add(Read('id1', 'A' * 70))
            reads.add(Read('id2', 'A' * 70))
            readsAlignments = BlastReadsAlignments(reads, 'file.json')
            result = list(readsAlignments.filter(readIdRegex='^ID0$'))
            self.assertEqual(0, len(result))


text:
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_TEST_SCRIPTNUM10_H
#define BITCOIN_TEST_SCRIPTNUM10_H

#include <algorithm>
#include <limits>
#include <stdexcept>
#include <stdint.h>
#include <string>
#include <vector>
#include <assert.h>

class scriptnum10_error : public std::runtime_error
{
public:
    explicit scriptnum10_error(const std::string& str) : std::runtime_error(str) {}
};

class CScriptNum10
{
/**
 * The ScriptNum implementation from Bitcoin Core 0.10.0, for cross-comparison.
 */
public:

    explicit CScriptNum10(const int64_t& n)
    {
        m_value = n;
    }

    static const size_t nDefaultMaxNumSize = 4;

    explicit CScriptNum10(const std::vector<unsigned char>& vch, bool fRequireMinimal,
                        const size_t nMaxNumSize = nDefaultMaxNumSize)
    {
        if (vch.size() > nMaxNumSize) {
            throw scriptnum10_error("script number overflow");
        }
        if (fRequireMinimal && vch.size() > 0) {
            // Check that the number is encoded with the minimum possible
            // number of bytes.
            //
            // If the most-significant-byte - excluding the sign bit - is zero
            // then we're not minimal. Note how this test also rejects the
            // negative-zero encoding, 0x80.
            if ((vch.back() & 0x7f) == 0) {
                // One exception: if there's more than one byte and the most
                // significant bit of the second-most-significant-byte is set
                // it would conflict with the sign bit. An example of this case
                // is +-255, which encode to 0xff00 and 0xff80 respectively.
                // (big-endian).
                if (vch.size() <= 1 || (vch[vch.size() - 2] & 0x80) == 0) {
                    throw scriptnum10_error("non-minimally encoded script number");
                }
            }
        }
        m_value = set_vch(vch);
    }

    inline bool operator==(const int64_t& rhs) const    { return m_value == rhs; }
    inline bool operator!=(const int64_t& rhs) const    { return m_value != rhs; }
    inline bool operator<=(const int64_t& rhs) const    { return m_value <= rhs; }
    inline bool operator< (const int64_t& rhs) const    { return m_value <  rhs; }
    inline bool operator>=(const int64_t& rhs) const    { return m_value >= rhs; }
    inline bool operator> (const int64_t& rhs) const    { return m_value >  rhs; }

    inline bool operator==(const CScriptNum10& rhs) const { return operator==(rhs.m_value); }
    inline bool operator!=(const CScriptNum10& rhs) const { return operator!=(rhs.m_value); }
    inline bool operator<=(const CScriptNum10& rhs) const { return operator<=(rhs.m_value); }
    inline bool operator< (const CScriptNum10& rhs) const { return operator< (rhs.m_value); }
    inline bool operator>=(const CScriptNum10& rhs) const { return operator>=(rhs.m_value); }
    inline bool operator> (const CScriptNum10& rhs) const { return operator> (rhs.m_value); }

    inline CScriptNum10 operator+(   const int64_t& rhs)    const { return CScriptNum10(m_value + rhs);}
    inline CScriptNum10 operator-(   const int64_t& rhs)    const { return CScriptNum10(m_value - rhs);}
    inline CScriptNum10 operator+(   const CScriptNum10& rhs) const { return operator+(rhs.m_value);   }
    inline CScriptNum10 operator-(   const CScriptNum10& rhs) const { return operator-(rhs.m_value);   }

    inline CScriptNum10& operator+=( const CScriptNum10& rhs)       { return operator+=(rhs.m_value);  }
    inline CScriptNum10& operator-=( const CScriptNum10& rhs)       { return operator-=(rhs.m_value);  }

    inline CScriptNum10 operator-()                         const
    {
        assert(m_value != std::numeric_limits<int64_t>::min());
        return CScriptNum10(-m_value);
    }

    inline CScriptNum10& operator=( const int64_t& rhs)
    {
        m_value = rhs;
        return *this;
    }

    inline CScriptNum10& operator+=( const int64_t& rhs)
    {
        assert(rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits<int64_t>::max() - rhs) ||
                           (rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs));
        m_value += rhs;
        return *this;
    }

    inline CScriptNum10& operator-=( const int64_t& rhs)
    {
        assert(rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits<int64_t>::min() + rhs) ||
                           (rhs < 0 && m_value <= std::numeric_limits<int64_t>::max() + rhs));
        m_value -= rhs;
        return *this;
    }

    int getint() const
    {
        if (m_value > std::numeric_limits<int>::max())
            return std::numeric_limits<int>::max();
        else if (m_value < std::numeric_limits<int>::min())
            return std::numeric_limits<int>::min();
        return m_value;
    }

    std::vector<unsigned char> getvch() const
    {
        return serialize(m_value);
    }

    static std::vector<unsigned char> serialize(const int64_t& value)
    {
        if(value == 0)
            return std::vector<unsigned char>();

        std::vector<unsigned char> result;
        const bool neg = value < 0;
        uint64_t absvalue = neg ? -value : value;

        while(absvalue)
        {
            result.push_back(absvalue & 0xff);
            absvalue >>= 8;
        }

//    - If the most significant byte is >= 0x80 and the value is positive, push a
//    new zero-byte to make the significant byte < 0x80 again.

//    - If the most significant byte is >= 0x80 and the value is negative, push a
//    new 0x80 byte that will be popped off when converting to an integral.

//    - If the most significant byte is < 0x80 and the value is negative, add
//    0x80 to it, since it will be subtracted and interpreted as a negative when
//    converting to an integral.

        if (result.back() & 0x80)
            result.push_back(neg ? 0x80 : 0);
        else if (neg)
            result.back() |= 0x80;

        return result;
    }

private:
    static int64_t set_vch(const std::vector<unsigned char>& vch)
    {
      if (vch.empty())
          return 0;

      int64_t result = 0;
      for (size_t i = 0; i != vch.size(); ++i)
          result |= static_cast<int64_t>(vch[i]) << 8*i;

      // If the input vector's most significant byte is 0x80, remove it from
      // the result's msb and return a negative.
      if (vch.back() & 0x80)
          return -((int64_t)(result & ~(0x80ULL << (8 * (vch.size() - 1)))));

      return result;
    }

    int64_t m_value;
};

#endif // BITCOIN_TEST_BIGNUM_H

redpajama_set_name: RedPajamaGithub


text:
<?php

namespace P\Iris;

use InvalidArgumentException;

/**
 * Abstract class implementing EventDispatching and Options Settings
 */
abstract class CurlAbstract
{

    /**
    * cUrl handler
    *
    * @var resource
    */
    protected $handle;

    /**
     * Options for the cURL handler
     *
     * @var array
     */
    protected $options = array();

    /**
     * callable container
     *
     * @var Array
     */
    protected $listeners = array();

    /**
     * The destructor
     */
    public function __destruct()
    {
        $this->close();
        $this->handle = null;
    }

    /**
     * {@inheritdoc}
     */
    abstract public function close();

    /**
     * {@inheritdoc}
     */
    public function addListener($event, $listener)
    {
        if (! is_callable($listener)) {
            throw new InvalidArgumentException('a callable function should be attached');
        }
        if (! array_key_exists($event, $this->listeners)) {
            $this->listeners[$event] = array();
        }
        $this->listeners[$event][] = $listener;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function removeListener($event, $listener)
    {
        if (! is_callable($listener)) {
            throw new InvalidArgumentException('a callable function should be attached');
        }
        if (! array_key_exists($event, $this->listeners)) {
            return $this;
        }
        $index = array_search($listener, $this->listeners[$event], true);
        if (false !== $index) {
            unset($this->listeners[$event][$index]);
        }

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function getListeners($event)
    {
        if (! array_key_exists($event, $this->listeners)) {
            return [];
        }

        return $this->listeners[$event];
    }

    /**
     * {@inheritdoc}
     */
    public function dispatch($event, array $args = array())
    {
        foreach ($this->getListeners($event) as $listener) {
            call_user_func_array($listener, $args);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function setOption($name, $value = null)
    {
        if (is_array($name)) {
            foreach ($name as $option_name => $option_value) {
                $this->setOption($option_name, $option_value);
            }

            return $this;
        }

        if (false === filter_var($name, FILTER_VALIDATE_INT, array('options' => array('min_range' => 0)))) {
            throw new InvalidArgumentException('options $name should be a valid integer');
        }

        $this->options[$name] = $value;

        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function getOption($name = null)
    {
        if (array_key_exists($name, $this->options)) {
            return $this->options[$name];
        } elseif (is_null($name)) {
            return $this->options;
        }

        return null;
    }

    /**
     * {@inheritdoc}
     */
    public function getHandler()
    {
        return $this->handle;
    }

    /**
     * {@inheritdoc}
     */
    public function isAvailable()
    {
        return is_resource($this->handle);
    }
}


text:
<?php

namespace Cupon\TiendaBundle\Entity;

use Doctrine\ORM\EntityRepository;

/**
 * TiendaRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class TiendaRepository extends EntityRepository
{
	public function findUltimasOfertasPublicadas($tienda_id, $limite = 10)
	{
		$em = $this->getEntityManager();
		$consulta = $em->createQuery('
			SELECT o, t
			FROM OfertaBundle:Oferta o
			JOIN o.tienda t
			WHERE o.revisada = true
			AND o.fecha_publicacion < :fecha
			AND o.tienda = :id
			ORDER BY o.fecha_expiracion DESC');
		$consulta->setMaxResults($limite);
		$consulta->setParameter('id', $tienda_id);
		$consulta->setParameter('fecha', new \DateTime('now'));
		return $consulta->getResult();
	}

	public function findCercanas($tienda, $ciudad)
	{
		$em = $this->getEntityManager();
		$consulta = $em->createQuery('
			SELECT t, c
			FROM TiendaBundle:Tienda t
			JOIN t.ciudad c
			WHERE c.slug = :ciudad
			AND t.slug != :tienda');
		$consulta->setMaxResults(5);
		$consulta->setParameter('ciudad', $ciudad);
		$consulta->setParameter('tienda', $tienda);
		return $consulta->getResult();
	}

	public function findOfertasRecientes($tienda_id, $limite = null)
	{
		$em = $this->getEntityManager();
		$consulta = $em->createQuery('
			SELECT o, t FROM OfertaBundle:Oferta o JOIN o.tienda t
			WHERE o.tienda = :id
			ORDER BY o.fechaExpiracion DESC
			');
		$consulta->setParameter('id', $tienda_id);
		if (null != $limite) {
			$consulta->setMaxResults($limite);
		}
		return $consulta->getResult();
	}

}


text:
require 'puppet/error'

# Puppet::Forge specific exceptions
module Puppet::Forge::Errors

  # This exception is the parent for all Forge API errors
  class ForgeError < Puppet::Error
    # This is normally set by the child class, but if it is not this will
    # fall back to displaying the message as a multiline.
    #
    # @return [String] the multiline version of the error message
    def multiline
      self.message
    end
  end

  # This exception is raised when there is an SSL verification error when
  # communicating with the forge.
  class SSLVerifyError < ForgeError
    # @option options [String] :uri The URI that failed
    # @option options [String] :original the original exception
    def initialize(options)
      @uri     = options[:uri]
      original = options[:original]

      super("Unable to verify the SSL certificate at #{@uri}", original)
    end

    # Return a multiline version of the error message
    #
    # @return [String] the multiline version of the error message
    def multiline
      message = <<-EOS.chomp
Could not connect via HTTPS to #{@uri}
  Unable to verify the SSL certificate
    The certificate may not be signed by a valid CA
    The CA bundle included with OpenSSL may not be valid or up to date
      EOS
    end
  end

  # This exception is raised when there is a communication error when connecting
  # to the forge
  class CommunicationError < ForgeError
    # @option options [String] :uri The URI that failed
    # @option options [String] :original the original exception
    def initialize(options)
      @uri     = options[:uri]
      original = options[:original]
      @detail  = original.message

      message = "Unable to connect to the server at #{@uri}. Detail: #{@detail}."
      super(message, original)
    end

    # Return a multiline version of the error message
    #
    # @return [String] the multiline version of the error message
    def multiline
      message = <<-EOS.chomp
Could not connect to #{@uri}
  There was a network communications problem
    The error we caught said '#{@detail}'
    Check your network connection and try again
      EOS
    end
  end

end


text:
package com.example.prjagannath.castus;

import java.util.GregorianCalendar;

/**
 * Created by prjagannath on 9/2/2016.
 */
public class Session {
    private boolean isActive = false;
    private long lastActiveTime = 0;
    private long timeoutInMillis = 0;

    /**
     * Initiate a session with desire timeout length
     * @param timeoutInSec define in seconds
     */
    public Session(long timeoutInSec){
        timeoutInMillis = timeoutInSec * 1000;
    }

    public void startSession(){
        lastActiveTime = new GregorianCalendar().getTimeInMillis();
        isActive = true;
    }

    public void closeSession(){
        lastActiveTime = 0;
        isActive = false;
    }

    public boolean isSessionActive(){
        return (isActive && (new GregorianCalendar().getTimeInMillis() - lastActiveTime < timeoutInMillis));
    }
}


text:
package com.dremio.dac.explore.model.extract;

import java.util.List;

import javax.validation.constraints.NotNull;

import com.dremio.dac.util.JSONUtil;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * The selection in a given cell
 */
public class MapSelection {
  @NotNull
  private final String colName;
  @NotNull
  private final List<String> mapPathList;

  @JsonCreator
  public MapSelection(
      @JsonProperty("colName") String colName,
      @JsonProperty("mapPathList") List<String> mapPathList) {
    super();
    this.colName = colName;
    this.mapPathList = mapPathList;
  }

  public String getColName() {
    return colName;
  }
  public List<String> getMapPathList() {
    return mapPathList;
  }

  @Override
  public String toString() {
    return JSONUtil.toString(this);
  }
}


text:
import groupIn = require( './index' );

const indicator = ( v: string ): string => v[ 0 ];

/**
* A class for instantiating objects with `a` and `b` dummy properties.
*/
class Foo {
	/**
	* String property.
	*/
	a: string;

	/**
	* String property.
	*/
	b: string;

	constructor() {
		this.a = 'beep';
		this.b = 'boop';
	}
}

// TESTS //

// The function returns an object...
{
	const obj = new Foo();
	groupIn( obj, indicator ); // $ExpectType any
	groupIn( {}, indicator ); // $ExpectType any
	const opts = {
		'returns': 'indices' as 'indices'
	};
	groupIn( obj, opts, indicator ); // $ExpectType any
}

// The compiler throws an error if the function is provided a last argument which is not a function...
{
	const obj = new Foo();
	groupIn( obj, false ); // $ExpectError
	groupIn( obj, true ); // $ExpectError
	groupIn( obj, 32 ); // $ExpectError
	groupIn( obj, 'abc' ); // $ExpectError
	groupIn( obj, [] ); // $ExpectError
	groupIn( obj, {} ); // $ExpectError

	groupIn( obj, {}, false ); // $ExpectError
	groupIn( obj, {}, true ); // $ExpectError
	groupIn( obj, {}, 32 ); // $ExpectError
	groupIn( obj, {}, 'abc' ); // $ExpectError
	groupIn( obj, {}, [] ); // $ExpectError
	groupIn( obj, {}, {} ); // $ExpectError
}

// The compiler throws an error if the function is provided an options argument which is not an object...
{
	const obj = new Foo();
	groupIn( obj, null, indicator ); // $ExpectError
}

// The compiler throws an error if the function is provided a `returns` option which is not one of 'indices', 'values', or '*'...
{
	const obj = new Foo();
	groupIn( obj, { 'returns': '5' }, indicator ); // $ExpectError
	groupIn( obj, { 'returns': 123 }, indicator ); // $ExpectError
	groupIn( obj, { 'returns': [] }, indicator ); // $ExpectError
	groupIn( obj, { 'returns': {} }, indicator ); // $ExpectError
	groupIn( obj, { 'returns': ( x: number ): number => x }, indicator ); // $ExpectError
}

// The compiler throws an error if the function is provided an invalid number of arguments...
{
	const obj = new Foo();
	groupIn(); // $ExpectError
	groupIn( obj ); // $ExpectError
	groupIn( obj, {}, indicator, 16 ); // $ExpectError
}


text:
//
//  ComboFont.c
//
//  www.catch22.net
//
//  Copyright (C) 2012 James Brown
//  Please refer to the file LICENCE.TXT for copying permission
//

#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_NON_CONFORMING_SWPRINTFS
#define _WIN32_WINNT 0x501
#define STRICT

#include <windows.h>
#include <uxtheme.h>
#include <vssym32.h>
#include <tchar.h>
#include "resource.h"
#include "ComboUtil.h"

HFONT g_hBoldFont;
HFONT g_hNormalFont;
HICON g_hIcon2;
HICON g_hIcon3;

BOOL WINAPI FontCombo_DrawItem(HTHEME hTheme, DRAWITEMSTRUCT *dis, BOOL fDrawBackground);
#define MSG_UPDATE_PREVIEW (WM_USER+1)

//
//	Font-enumeration callback
//
int CALLBACK EnumFontNames(ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, DWORD FontType, LPARAM lParam)
{
	HWND hwndCombo = (HWND)lParam;
	TCHAR *pszName  = lpelfe->elfLogFont.lfFaceName;

		if(pszName[0] == '@')
			return 1;

	// make sure font doesn't already exist in our list
	if(SendMessage(hwndCombo, CB_FINDSTRING, 0, (LPARAM)pszName) == CB_ERR)
	{
		int		idx;
		BOOL	fFixed;
		int		fTrueType;		// 0 = normal, 1 = TrueType, 2 = OpenType

		// add the font
		idx = (int)SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)pszName);

		// record the font's attributes (Fixedwidth and Truetype)
		fFixed		= (lpelfe->elfLogFont.lfPitchAndFamily & FIXED_PITCH) ? TRUE : FALSE;
		fTrueType	= (lpelfe->elfLogFont.lfOutPrecision == OUT_STROKE_PRECIS) ? TRUE : FALSE;
		fTrueType	= (lpntme->ntmTm.ntmFlags & NTM_TT_OPENTYPE) ? 2 : fTrueType;

		// store this information in the list-item's userdata area
		SendMessage(hwndCombo, CB_SETITEMDATA, idx, MAKELPARAM(fFixed, fTrueType));

		/*{
			COMBOBOXEXITEM cbxi = { CBEIF_TEXT, 0, pszName };
			SendMessage(GetDlgItem(GetParent(hwndCombo), IDC_COMBOBOXEX1), CBEM_INSERTITEM, 0, &cbxi);
		}*/
	}

	return 1;
}

//
//	Initialize the font-list by enumeration all system fonts
//
void FillFontComboList(HWND hwndCombo, TCHAR *szInitialFont)
{
	HDC		hdc = GetDC(hwndCombo);
	LOGFONT lf;
	int		idx = 0;

	SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);
//	SendMessage(hwndCombo, WM_SETFONT, (WPARAM)g_hNormalFont, 0);

	lf.lfCharSet			= ANSI_CHARSET;	// DEFAULT_CHARSET;
	lf.lfFaceName[0]		= '\0';			// all fonts
	lf.lfPitchAndFamily		= 0;

	// store the list of fonts in the combo
	EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)EnumFontNames, (LPARAM)hwndCombo, 0);

	ReleaseDC(hwndCombo, hdc);

	// select current font in list
	if(szInitialFont != 0)
		idx = (int)SendMessage(hwndCombo, CB_FINDSTRING, 0, (LPARAM)szInitialFont);

	SendMessage(hwndCombo, CB_SETCURSEL, idx, 0);
}

//
//	Fontlist owner-draw
//
BOOL WINAPI FontCombo_DrawItem(CTRLITEM *cip, DRAWITEMSTRUCT *dis, BOOL fDrawBackground)
{
	TCHAR		szText[100];

	BOOL		fFixed		= LOWORD(dis->itemData);
	BOOL		fTrueType	= HIWORD(dis->itemData);

	TEXTMETRIC	tm;
	int			xpos, ypos;
	HANDLE		hOldFont;

	if(dis->itemAction & ODA_FOCUS && !(dis->itemState & ODS_NOFOCUSRECT))
	{
		DrawFocusRect(dis->hDC, &dis->rcItem);
		return TRUE;
	}

	/*{
		HTHEME hTheme = 	OpenThemeShim(hwnd, L"combobox");
		RECT rc;
		HDC hdc=GetDC(GetParent(hwnd));
		CopyRect(&rc, &dis->rcItem);
		InflateRect(&rc, 3, 3);
		//GetClientRect(hwnd, &rc);
		//rc.bottom = rc.top + 22;

		//DrawThemeBackground(
		//	hTheme,
		//	dis->hDC,
		//	4,//CP_DROPDOWNBUTTON,
		//	CBXS_HOT,//CBXS_NORMAL,
		//	&rc,
		//	&rc);

		CloseThemeData(hTheme);
		ReleaseDC(GetParent(hwnd),hdc);
		return TRUE;
	}*/

	//
	//	Set text colour and background based on current state
	//
	DrawItem_DefaultColours(dis);

	if(dis->itemState & ODS_COMBOBOXEDIT)
	{
		RECT rect;
		GetClientRect(dis->hwndItem, &rect);
		fDrawBackground = FALSE;
		SelectClipRgn(dis->hDC, NULL);
		DrawThemedComboBackground(cip, dis->hwndItem, dis->hDC, &rect);

		SetTextColor(dis->hDC, GetSysColor(COLOR_WINDOWTEXT));
		//InvalidateRect(dis->hwndItem, 0, 0);
		//return 0;
	}

	//
	//	Get the item text
	//
	if(dis->itemID == -1)
		SendMessage(dis->hwndItem, WM_GETTEXT, 0, (LPARAM)szText);
	else
		SendMessage(dis->hwndItem, CB_GETLBTEXT, dis->itemID, (LPARAM)szText);

	// set the font: BOLD for fixed-width, NORMAL for 'normal'
	hOldFont = SelectObject(dis->hDC, fFixed ? g_hBoldFont : g_hNormalFont);
	GetTextMetrics(dis->hDC, &tm);

	ypos = dis->rcItem.top  + (dis->rcItem.bottom-dis->rcItem.top-tm.tmHeight)/2;
	xpos = dis->rcItem.left + 20;

	// draw the text
	SetBkMode(dis->hDC, TRANSPARENT);
	ExtTextOut(dis->hDC, xpos, ypos,
		ETO_CLIPPED|(fDrawBackground?ETO_OPAQUE:0), &dis->rcItem, szText, (UINT)_tcslen(szText), 0);

	// draw a 'TT' icon if the font is TRUETYPE
	if(fTrueType)
	{
		DrawIconEx(dis->hDC, dis->rcItem.left+2, dis->rcItem.top +
		(dis->rcItem.bottom-dis->rcItem.top-16)/2,
		g_hIcon2, 16, 16, 0, 0, DI_NORMAL);
	}
	//else if(fTrueType == 2)
	//	DrawIconEx(dis->hDC, dis->rcItem.left+2, dis->rcItem.top, g_hIcon3,16, 16, 0, 0, DI_NORMAL);

	SelectObject(dis->hDC, hOldFont);

	// draw the focus rectangle
	if((dis->itemState & ODS_FOCUS) && !(dis->itemState & ODS_NOFOCUSRECT))
	{
		DrawFocusRect(dis->hDC, &dis->rcItem);
	}

	return TRUE;
}

void MakeFontCombo(HWND hwndDlg, HWND hwndCombo)
{
	CTRLITEM *cip;
	HFONT hDlgFont;
	LOGFONT lf;

	//
	//	Load the TrueType icon for the font-list
	//
	g_hIcon2 = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON4), IMAGE_ICON, 16, 16, 0);
	g_hIcon3 = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON4), IMAGE_ICON, 16, 16, 0);

	//
	//	Create two fonts (normal+bold) based on current dialog's font settings
	//
	hDlgFont = (HFONT)SendMessage(hwndDlg, WM_GETFONT, 0, 0);
	GetObject(hDlgFont, sizeof(lf), &lf);

	g_hNormalFont = CreateFontIndirect(&lf);
	lf.lfWeight   = FW_BOLD;
	g_hBoldFont   = CreateFontIndirect(&lf);

	SetComboItemHeight(hwndCombo, 16);

	cip = SubclassCombo(hwndCombo, FontCombo_DrawItem);

	// fill the combo with the list of all fonts
	FillFontComboList(hwndCombo, TEXT("Arial"));//g_szFontName);

	AutoOwnerDraw(cip->hTheme, hwndCombo, FontCombo_DrawItem, 0);
}


text:
function T = read_adcirc_nws20(filename, startRow, endRow)
%IMPORTFILE1 Import numeric data from a text file as a matrix.
%   T = read_adcirc_nws20(FILENAME) Reads data from text file
%   FILENAME for the default selection.
%
%   T = read_adcirc_nws20(FILENAME, STARTROW, ENDROW) Reads data
%   from rows STARTROW through ENDROW of text file FILENAME.
%
% Example:
%   mandyNWS20fort = importfile1('mandy_NWS_20_fort.22', 1, 66);
%
%    See also TEXTSCAN.

% Auto-generated by MATLAB on 2017/07/06 13:17:02

%% Initialize variables.
delimiter = ',';
if nargin == 0
    filename='fort.22';
end

if nargin<=2
    startRow = 1;
    endRow = inf;
end

%% Read columns of data as text:
% For more information, see the TEXTSCAN documentation.
formatSpec = '%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%[^\n\r]';

%% Open the text file.
fileID = fopen(filename,'r');

%% Read columns of data according to the format.
% This call is based on the structure of the file used to generate this
% code. If an error occurs for a different file, try regenerating the code
% from the Import Tool.
dataArray = textscan(fileID, formatSpec, endRow(1)-startRow(1)+1, 'Delimiter', delimiter, 'HeaderLines', startRow(1)-1, 'ReturnOnError', false, 'EndOfLine', '\r\n');
for block=2:length(startRow)
    frewind(fileID);
    dataArrayBlock = textscan(fileID, formatSpec, endRow(block)-startRow(block)+1, 'Delimiter', delimiter, 'HeaderLines', startRow(block)-1, 'ReturnOnError', false, 'EndOfLine', '\r\n');
    for col=1:length(dataArray)
        dataArray{col} = [dataArray{col};dataArrayBlock{col}];
    end
end

%% Close the text file.
fclose(fileID);

%% Convert the contents of columns containing numeric text to numbers.
% Replace non-numeric text with NaN.
raw = repmat({''},length(dataArray{1}),length(dataArray)-1);
for col=1:length(dataArray)-1
    raw(1:length(dataArray{col}),col) = dataArray{col};
end
numericData = NaN(size(dataArray{1},1),size(dataArray,2));

for col=[2,6,7,8,9,10,12,14,15,16,17,18,20,26,27,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47]
    % Converts text in the input cell array to numbers. Replaced non-numeric
    % text with NaN.
    rawData = dataArray{col};
    for row=1:size(rawData, 1);
        % Create a regular expression to detect and remove non-numeric prefixes and
        % suffixes.
        regexstr = '(?<prefix>.*?)(?<numbers>([-]*(\d+[\,]*)+[\.]{0,1}\d*[eEdD]{0,1}[-+]*\d*[i]{0,1})|([-]*(\d+[\,]*)*[\.]{1,1}\d+[eEdD]{0,1}[-+]*\d*[i]{0,1}))(?<suffix>.*)';
        try
            result = regexp(rawData{row}, regexstr, 'names');
            numbers = result.numbers;

            % Detected commas in non-thousand locations.
            invalidThousandsSeparator = false;
            if any(numbers==',');
                thousandsRegExp = '^\d+?(\,\d{3})*\.{0,1}\d*$';
                if isempty(regexp(numbers, thousandsRegExp, 'once'));
                    numbers = NaN;
                    invalidThousandsSeparator = true;
                end
            end
            % Convert numeric text to numbers.
            if ~invalidThousandsSeparator;
                numbers = textscan(strrep(numbers, ',', ''), '%f');
                numericData(row, col) = numbers{1};
                raw{row, col} = numbers{1};
            end
        catch me
        end
    end
end

% Convert the contents of columns with dates to MATLAB datetimes using the
% specified date format.
try
    dates{3} = datetime(dataArray{3}, 'Format', 'yyyyMMddHH', 'InputFormat', 'yyyyMMddHH');
catch
    try
        % Handle dates surrounded by quotes
        dataArray{3} = cellfun(@(x) x(2:end-1), dataArray{3}, 'UniformOutput', false);
        dates{3} = datetime(dataArray{3}, 'Format', 'yyyyMMddHH', 'InputFormat', 'yyyyMMddHH');
    catch
        dates{3} = repmat(datetime([NaN NaN NaN]), size(dataArray{3}));
    end
end

anyBlankDates = cellfun(@isempty, dataArray{3});
anyInvalidDates = isnan(dates{3}.Hour) - anyBlankDates;
dates = dates(:,3);

%% Split data into numeric and cell columns.
rawNumericColumns = raw(:, [2,6,7,8,9,10,12,14,15,16,17,18,20,26,27,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47]);
rawCellColumns = raw(:, [1,4,5,11,13,19,21,22,23,24,25,28]);

%% Create output variable
T = table;
T.BASIN = rawCellColumns(:, 1);
T.CY = cell2mat(rawNumericColumns(:, 1));
T.YYYYMMDDHH = dates{:, 1};
T.TECHNUM = rawCellColumns(:, 2);
T.TECH = rawCellColumns(:, 3);
T.TAU = cell2mat(rawNumericColumns(:, 2));
T.LatNS = cell2mat(rawNumericColumns(:, 3));
T.LonEW = cell2mat(rawNumericColumns(:, 4));
T.VMAX = cell2mat(rawNumericColumns(:, 5));
T.MSLP = cell2mat(rawNumericColumns(:, 6));
T.TY = rawCellColumns(:, 4);
T.VarName12 = cell2mat(rawNumericColumns(:, 7));
T.WINDCODE  = rawCellColumns(:, 5);
T.RAD1 = cell2mat(rawNumericColumns(:, 8));
T.RAD2 = cell2mat(rawNumericColumns(:, 9));
T.RAD3 = cell2mat(rawNumericColumns(:, 10));
T.RAD4 = cell2mat(rawNumericColumns(:, 11));
T.POUTER = cell2mat(rawNumericColumns(:, 12));
T.ROUTER = rawCellColumns(:, 6);
T.RMW = cell2mat(rawNumericColumns(:, 13));
T.GUSTS = rawCellColumns(:, 7);
T.EYE = rawCellColumns(:, 8);
T.SUBREGION = rawCellColumns(:, 9);
T.MAXSEAS = rawCellColumns(:, 10);
T.INITIALS = rawCellColumns(:, 11);
T.DIR = cell2mat(rawNumericColumns(:, 14));
T.SPEED = cell2mat(rawNumericColumns(:, 15));
T.STORMNAME = rawCellColumns(:, 12);
T.DEPTH = cell2mat(rawNumericColumns(:, 16));
T.SEAS = cell2mat(rawNumericColumns(:, 17));
T.SEASCODE = cell2mat(rawNumericColumns(:, 18));
T.SEAS1 = cell2mat(rawNumericColumns(:, 19));
T.SEAS2 = cell2mat(rawNumericColumns(:, 20));
T.SEAS3 = cell2mat(rawNumericColumns(:, 21));
T.SEAS4 = cell2mat(rawNumericColumns(:, 22));
T.VarName36 = cell2mat(rawNumericColumns(:, 23));
T.VarName37 = cell2mat(rawNumericColumns(:, 24));
T.VarName38 = cell2mat(rawNumericColumns(:, 25));
T.VarName39 = cell2mat(rawNumericColumns(:, 26));
T.VarName40 = cell2mat(rawNumericColumns(:, 27));
T.VarName41 = cell2mat(rawNumericColumns(:, 28));
T.VarName42 = cell2mat(rawNumericColumns(:, 29));
T.VarName43 = cell2mat(rawNumericColumns(:, 30));
T.VarName44 = cell2mat(rawNumericColumns(:, 31));
T.VarName45 = cell2mat(rawNumericColumns(:, 32));
T.VarName46 = cell2mat(rawNumericColumns(:, 33));
T.VarName47 = cell2mat(rawNumericColumns(:, 34));

% convert to degrees
T.LatNS=T.LatNS/10;
T.LonEW=-T.LonEW/10;

% For code requiring serial dates (datenum) instead of datetime, uncomment
% the following line(s) below to return the imported dates as datenum(s).

% T.DateTime=datenum(T.DateTime);


text:
import Mixin from '@ember/object/mixin';
import { computed, setProperties } from '@ember/object';
import { isEmpty } from '@ember/utils';

const NONE = 'none';
const TLS = 'tls';
const STARTTLS = 'starttls';

export default Mixin.create({
  encryption: computed('authConfig.{tls,starttls}', {
    get() {
      const { authConfig } = this;

      if (isEmpty(authConfig)) {
        return NONE;
      } else {
        if (authConfig.tls && !authConfig.starttls) {
          return TLS;
        } else if (!authConfig.tls && authConfig.starttls) {
          return STARTTLS;
        } else {
          return NONE;
        }
      }
    },
    set(key, value) {
      switch (value) {
      case TLS:
        setProperties(this.authConfig, {
          tls:      true,
          starttls: false,
        });
        break;
      case STARTTLS:
        setProperties(this.authConfig, {
          tls:      false,
          starttls: true,
        });
        break;
      default:
        setProperties(this.authConfig, {
          tls:      false,
          starttls: false,
        });
        break;
      }

      return value;
    },
  }),

});