Commit 79a18474 authored by Marc Duez's avatar Marc Duez
Browse files
parents bc4aa111 b5820f2a
CC=g++
OPTIM=-O2 -DNDEBUG $(COVERAGE)
CXXFLAGS=-W -Wall $(OPTIM) $(DEBUG) $(CONFIG)
## inspired from http://stackoverflow.com/questions/399850/best-compiler-warning-level-for-c-c-compilers/401276
PARANOID= -Wall -Weffc++ -pedantic \
-Wextra -Waggregate-return -Wcast-align \
-Wcast-qual -Wchar-subscripts -Wcomment -Wconversion \
-Wdisabled-optimization \
-Wfloat-equal -Wformat -Wformat=2 \
-Wformat-nonliteral -Wformat-security \
-Wformat-y2k \
-Wimplicit -Wimport -Winit-self -Winline \
-Winvalid-pch -Wlong-long -Wmissing-braces \
-Wmissing-field-initializers -Wmissing-format-attribute \
-Wmissing-include-dirs -Wmissing-noreturn \
-Wpacked -Wpadded -Wparentheses -Wpointer-arith \
-Wredundant-decls -Wreturn-type \
-Wsequence-point -Wshadow -Wsign-compare -Wstack-protector \
-Wstrict-aliasing -Wstrict-aliasing=2 -Wswitch -Wswitch-default \
-Wswitch-enum -Wtrigraphs -Wuninitialized \
-Wunknown-pragmas -Wunreachable-code -Wunused \
-Wunused-function -Wunused-label -Wunused-parameter \
-Wunused-value -Wunused-variable -Wvariadic-macros \
-Wvolatile-register-var -Wwrite-strings
LDFLAGS=-lm
EXEC=vidjil
MAINCORE=$(wildcard *.cpp)
......@@ -17,6 +39,11 @@ v: vidjil align.cgi
###
paranoid: clean
make vidjil OPTIM="$(PARANOID)"
###
kmers: cleankmers
make CONFIG="-DDEBUG_KMERS"
......
......@@ -53,8 +53,6 @@ int main(int argc, char* argv[])
const char* fdata;
ostringstream ost;
ostream * p;
p=&ost;
char filename[] = "VidjilAlignXXXXXX";
JsonList result;
bool error = false;
......@@ -78,11 +76,10 @@ int main(int argc, char* argv[])
}else{
cgi_mode=false;
fdata = argv[1];
p=&cout;
}
if (!cgi_mode) cout <<ost<<endl;
Fasta fa(fdata, 1, " ", *p);
Fasta fa(fdata, 1, " ");
string seq0 = fa.sequence(0);
......
......@@ -39,12 +39,11 @@ Fasta::Fasta(int extract_field, string extract_separator)
}
Fasta::Fasta(const string &input,
int extract_field, string extract_separator,
ostream &out)
int extract_field, string extract_separator)
{
init(extract_field, extract_separator);
if (!input.size()) // Do not open empty files (D germline if not segmentD)
if (!input.size()) // Do not open empty filenames (D germline if not segmentD)
return ;
add(input);
......@@ -60,8 +59,7 @@ void Fasta::add(const string &filename) {
ifstream is(filename.c_str());
if (is.fail())
{
cerr << " !! Error in opening file: " << filename << endl ;
exit(1);
throw invalid_argument(" !! Error in opening file: "+ filename);
}
cout << " <== " << filename ;
......@@ -96,7 +94,8 @@ OnlineFasta::OnlineFasta(const string &input,
extract_separator(extract_separator)
{
if (this->input->fail()) {
throw ios_base::failure("!! Error in opening file "+input);
delete this->input;
throw invalid_argument("!! Error in opening file "+input);
}
cout << " <== " << input << endl ;
......@@ -106,24 +105,13 @@ OnlineFasta::OnlineFasta(const string &input,
OnlineFasta::OnlineFasta(istream &input,
int extract_field, string extract_separator)
:extract_field(extract_field),
:input(&input), extract_field(extract_field),
extract_separator(extract_separator)
{
this->input = &input;
input_allocated = false;
init();
}
OnlineFasta::OnlineFasta(const OnlineFasta &of) {
current = of.current;
input = of.input;
extract_field = of.extract_field;
extract_separator = of.extract_separator;
line = of.line;
input_allocated = false;
line_nb = of.line_nb;
}
OnlineFasta::~OnlineFasta() {
if (input_allocated)
delete input;
......@@ -165,7 +153,7 @@ void OnlineFasta::next() {
case '>': state=FASTX_FASTA; break;
case '@': state=FASTX_FASTQ_ID; break;
default:
throw runtime_error("The file seems to be malformed!");
throw invalid_argument("The file seems to be malformed!");
}
// Identifier line
......@@ -184,14 +172,17 @@ void OnlineFasta::next() {
break;
case FASTX_FASTQ_SEQ:
// FASTQ separator between sequence and quality
assert(line[0] == '+');
if (line[0] != '+')
throw invalid_argument("Expected line starting with + in FASTQ file");
break;
case FASTX_FASTQ_SEP:
// Reading quality
current.quality = line;
if (current.quality.length() != current.sequence.length())
throw invalid_argument("Quality and sequence don't have the same length ");
break;
default:
throw runtime_error("Unexpected state after reading identifiers line");
throw invalid_argument("Unexpected state after reading identifiers line");
}
if (state >= FASTX_FASTQ_ID && state <= FASTX_FASTQ_SEP)
state = (fasta_state)(((int)state) + 1);
......@@ -218,15 +209,6 @@ void OnlineFasta::next() {
unexpectedEOF();
}
OnlineFasta& OnlineFasta::operator=(const OnlineFasta&of) {
current = of.current;
line = of.line;
input = of.input;
extract_field = of.extract_field;
extract_separator = of.extract_separator;
return *this;
}
string OnlineFasta::getInterestingLine() {
string line;
while (line.length() == 0 && hasNext() && getline(*input, line)) {
......@@ -237,7 +219,7 @@ string OnlineFasta::getInterestingLine() {
}
void OnlineFasta::unexpectedEOF() {
throw runtime_error("Unexpected EOF while reading FASTA/FASTQ file");
throw invalid_argument("Unexpected EOF while reading FASTA/FASTQ file");
}
// Operators
......@@ -257,14 +239,22 @@ istream& operator>>(istream& in, Fasta& fasta){
ostream& operator<<(ostream& out, Fasta& fasta){
for(int i = 0 ; i < fasta.size() ; i++){
out << fasta.read(i) << endl;
out << fasta.read(i);
}
return out;
}
ostream &operator<<(ostream &out, const Sequence &seq) {
out << ">" << seq.label << endl;
bool is_fastq=false;
if (seq.quality.length() > 0) {
is_fastq = true;
out << "@";
} else
out << ">";
out << seq.label << endl;
out << seq.sequence << endl;
if (is_fastq) {
out << "+" << endl << seq.quality << endl;
}
return out;
}
......@@ -43,10 +43,11 @@ public:
/**
* Read all the sequences in the input filename and record them in the object.
*
*/
* @throws invalid_argument if filename or file content is not
* valid
*/
Fasta(const string &input,
int extract_field=0, string extract_separator="|",
ostream &out=cout);
int extract_field=0, string extract_separator="|");
int size() const;
/**
......@@ -59,7 +60,15 @@ public:
const Sequence &read(int index) const;
const string& sequence(int index) const;
/**
* Add the content of the stream to the current object
*/
void add(istream &in);
/**
* Add the content of the file to the current object
* @throws invalid_argument if the file cannot be opened or
* if the content is not valid
*/
void add(const string &filename);
friend istream& operator>>(istream&, Fasta&);
......@@ -91,6 +100,8 @@ class OnlineFasta {
* Open the file and read the first sequence.
* @post getSequence() does not return the first sequence yet.
* next() must be called first.
* @throws invalid_argument if file cannot be opened or is not
* well-formed
*/
OnlineFasta(const string &input,
int extract_field=0, string extract_separator="|");
......@@ -98,11 +109,6 @@ class OnlineFasta {
OnlineFasta(istream &input,
int extract_field=0, string extract_separator="|");
/**
* Copy constructor
*/
OnlineFasta(const OnlineFasta &of);
~OnlineFasta();
/**
......@@ -124,11 +130,10 @@ class OnlineFasta {
/**
* Go to the next sequence in the file.
* @post hasNext() ==> getSequence() returns the following sequence in the file.
* @throws invalid_argument if the file is not well formated
*/
void next();
OnlineFasta& operator=(const OnlineFasta&);
private:
/**
......
......@@ -28,9 +28,9 @@ Germline::Germline(string _code, char _shortcut,
f_reps_4.push_back(f_rep_4);
f_reps_3.push_back(f_rep_3);
rep_5 = Fasta(f_rep_5, 2, "|", cout);
rep_4 = Fasta(f_rep_4, 2, "|", cout);
rep_3 = Fasta(f_rep_3, 2, "|", cout);
rep_5 = Fasta(f_rep_5, 2, "|");
rep_4 = Fasta(f_rep_4, 2, "|");
rep_3 = Fasta(f_rep_3, 2, "|");
}
......
......@@ -50,9 +50,9 @@ bool operator!=(const affect_t &a1, const affect_t &a2) {
string toString(const affect_t &a) {
string result;
if(a ==AFFECT_UNKNOWN)
result = " _";
result = " "AFFECT_UNKNOWN_SYMBOL;
else if (a == AFFECT_AMBIGUOUS)
result = " ?";
result = " "AFFECT_AMBIGUOUS_SYMBOL;
else
result = (affect_strand(a)==1 ? "+" : "-") + string(1,affect_char(a));
return result;
......
......@@ -26,9 +26,12 @@
Kmer::Kmer():count(0) {}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
Kmer::Kmer(const string &label, int strand) {
count = 1;
}
#pragma GCC diagnostic pop
Kmer &Kmer::operator+=(const Kmer &kmer) {
count += kmer.count;
......
......@@ -104,7 +104,7 @@ void KmerRepresentativeComputer::compute() {
size_t length_run = 0;
size_t i = pos_required;
if (pos_required)
while (i > 0 && isSufficienlyExpressed(counts[i-1].count, max)) {
i--;
length_run++;
......@@ -126,7 +126,7 @@ void KmerRepresentativeComputer::compute() {
sequence_longest_run = sequence;
seq_index_longest_run = seq;
}
// We have a requirement. We reached it, exit.
// We have a requirement (ie. a non empty string). We reached it, exit.
if (pos_required != pos_end_required)
break;
length_run = 0;
......
......@@ -77,6 +77,7 @@ public:
/**
* Sequence that the representative must contain absolutely.
* This sequence should appear only once in a read.
* Setting the sequence is not required and it can be empty.
*/
void setRequiredSequence(string sequence);
......
!LAUNCH: ../../vidjil -r 1 -k 4 -w 20 -c clones -V ../../data/toy_V.fa -J ../../data/toy_J.fa ../../data/no_representative.fa
$ Short reads properly segmented
1:SEG_+.* 4
$ Window found
1:^CACCCCCCCCCTTTTTTTCT$
$ Representative computation
1:>clone-001--custom--0000004--100%--seq.-\\[11,30\\]
#include "tests.h"
#include <core/kmeraffect.h>
void testAffect() {
affect_t Vminus = {'V'}, Vplus = {'V'};
Vplus.c |= 1 << 7;
affect_t Jplus = {'J'};
Jplus.c |= 1 << 7;
TAP_TEST(affect_strand(Vminus) == -1, TEST_AFFECT_STRAND, "");
TAP_TEST(affect_strand(Vplus) == 1, TEST_AFFECT_STRAND, "");
TAP_TEST(affect_char(Vminus) == 'V', TEST_AFFECT_CHAR, "");
TAP_TEST(affect_char(Vplus) == 'V', TEST_AFFECT_CHAR, "");
TAP_TEST(affect_char(Jplus) == 'J', TEST_AFFECT_CHAR, "");
TAP_TEST(! (Vminus == Vplus), TEST_AFFECT_COMPARISON, "");
TAP_TEST(Vminus != Vplus, TEST_AFFECT_COMPARISON, "");
TAP_TEST(! (Vminus < Vplus), TEST_AFFECT_COMPARISON, "");
TAP_TEST(Vminus > Vplus, TEST_AFFECT_COMPARISON, "");
TAP_TEST(! (Vminus <= Vplus), TEST_AFFECT_COMPARISON, "");
TAP_TEST(Vminus >= Vplus, TEST_AFFECT_COMPARISON, "");
TAP_TEST(! (Vminus == Jplus), TEST_AFFECT_COMPARISON, "");
TAP_TEST(Vminus != Jplus, TEST_AFFECT_COMPARISON, "");
TAP_TEST(! (Vminus <= Jplus), TEST_AFFECT_COMPARISON, "");
TAP_TEST(Vminus >= Jplus, TEST_AFFECT_COMPARISON, "");
TAP_TEST(! (Vminus < Jplus), TEST_AFFECT_COMPARISON, "");
TAP_TEST(Vminus > Jplus, TEST_AFFECT_COMPARISON, "");
TAP_TEST(Vminus == Vminus, TEST_AFFECT_COMPARISON, "");
TAP_TEST(! (Vminus != Vminus), TEST_AFFECT_COMPARISON, "");
TAP_TEST(! (Vminus < Vminus), TEST_AFFECT_COMPARISON, "");
TAP_TEST(! (Vminus > Vminus), TEST_AFFECT_COMPARISON, "");
TAP_TEST(Vminus <= Vminus, TEST_AFFECT_COMPARISON, "");
TAP_TEST(Vminus >= Vminus, TEST_AFFECT_COMPARISON, "");
TAP_TEST(toString(Vminus) == "-V", TEST_AFFECT_TO_STRING, toString(Vminus));
TAP_TEST(toString(Vplus) == "+V", TEST_AFFECT_TO_STRING, toString(Vplus));
TAP_TEST(toString(Jplus) == "+J", TEST_AFFECT_TO_STRING, toString(Jplus));
TAP_TEST(toString(AFFECT_UNKNOWN.affect) == " _", TEST_AFFECT_TO_STRING, "");
TAP_TEST(toString(AFFECT_AMBIGUOUS.affect) == " ?", TEST_AFFECT_TO_STRING, "");
ostringstream oss;
oss << Vminus;
TAP_TEST(toString(Vminus) == oss.str(), TEST_AFFECT_OUT, "");
ostringstream oss2;
oss2 << Vplus;
TAP_TEST(toString(Vplus) == oss2.str(), TEST_AFFECT_OUT, "");
ostringstream oss3;
oss3 << Jplus;
TAP_TEST(toString(Jplus) == oss3.str(), TEST_AFFECT_OUT, "");
}
void testKmerAffectClass() {
affect_t Vminus = {'V'}, Vplus = {'V'};
Vplus.c |= 1 << 7;
affect_t Jplus = {'J'};
Jplus.c |= 1 << 7;
KmerAffect KAVp("V", 1);
KmerAffect KAVm("V", -1);
KmerAffect KAJp("J", 1);
TAP_TEST(KAVp.affect == Vplus, TEST_KMERAFFECT_CONSTRUCTOR, "");
TAP_TEST(KAVm.affect == Vminus, TEST_KMERAFFECT_CONSTRUCTOR, "");
TAP_TEST(KAJp.affect == Jplus, TEST_KMERAFFECT_CONSTRUCTOR, "");
KmerAffect test = KAVp;
TAP_TEST(test.affect == KAVp.affect, TEST_KMERAFFECT_AFFECTATION, "");
test += KAVp;
TAP_TEST(test.affect == KAVp.affect, TEST_KMERAFFECT_ADD, "");
test += KAVm;
TAP_TEST(test == AFFECT_AMBIGUOUS, TEST_KMERAFFECT_ADD, "");
KmerAffect unknown;
TAP_TEST(unknown == AFFECT_UNKNOWN, TEST_KMERAFFECT_CONSTRUCTOR, "");
TAP_TEST(unknown.isUnknown(), TEST_KMERAFFECT_UNKNOWN, "");
TAP_TEST(unknown.getStrand() == 0, TEST_KMERAFFECT_STRAND, "");
TAP_TEST(unknown.getLabel() == AFFECT_UNKNOWN_SYMBOL, TEST_KMERAFFECT_LABEL, "");
unknown += KAVm;
TAP_TEST(unknown.affect == KAVm, TEST_KMERAFFECT_ADD, "");
unknown += KAJp;
TAP_TEST(unknown == AFFECT_AMBIGUOUS, TEST_KMERAFFECT_ADD, "");
TAP_TEST(unknown.isAmbiguous(), TEST_KMERAFFECT_AMBIGUOUS, "");
TAP_TEST(unknown.getLabel() == AFFECT_AMBIGUOUS_SYMBOL, TEST_KMERAFFECT_LABEL, "");
TAP_TEST(unknown.getStrand() == 0, TEST_KMERAFFECT_STRAND, "");
TAP_TEST(KAVp.getStrand() == 1, TEST_KMERAFFECT_STRAND, "");
TAP_TEST(KAVm.getStrand() == -1, TEST_KMERAFFECT_STRAND, "");
TAP_TEST(KAJp.getStrand() == 1, TEST_KMERAFFECT_STRAND, "");
TAP_TEST(KAVp.getLabel() == "V", TEST_KMERAFFECT_LABEL, "");
TAP_TEST(KAVm.getLabel() == "V", TEST_KMERAFFECT_LABEL, "");
TAP_TEST(KAJp.getLabel() == "J", TEST_KMERAFFECT_LABEL, "");
ostringstream ossKA, ossA;
ossKA << KAVp;
ossA << Vplus;
TAP_TEST(ossA.str() == ossKA.str(), TEST_KMERAFFECT_OUT, "");
ossKA << KAVm;
ossA << Vminus;
TAP_TEST(ossA.str() == ossKA.str(), TEST_KMERAFFECT_OUT, "");
ossKA << KAJp;
ossA << Jplus;
TAP_TEST(ossA.str() == ossKA.str(), TEST_KMERAFFECT_OUT, "");
}
void testKmerAffectComparison() {
KmerAffect Vminus("V", -1);
KmerAffect Vplus("V", 1);
KmerAffect Jplus("J", 1);
TAP_TEST(! (Vminus == Vplus), TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(Vminus != Vplus, TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(! (Vminus < Vplus), TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(Vminus > Vplus, TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(! (Vminus <= Vplus), TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(Vminus >= Vplus, TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(! (Vminus == Jplus), TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(Vminus != Jplus, TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(! (Vminus <= Jplus), TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(Vminus >= Jplus, TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(! (Vminus < Jplus), TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(Vminus > Jplus, TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(Vminus == Vminus, TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(! (Vminus != Vminus), TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(! (Vminus < Vminus), TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(! (Vminus > Vminus), TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(Vminus <= Vminus, TEST_KMERAFFECT_COMPARISON, "");
TAP_TEST(Vminus >= Vminus, TEST_KMERAFFECT_COMPARISON, "");
}
void testKmerAffect() {
testAffect();
testKmerAffectClass();
testKmerAffectComparison();
}
#include <core/fasta.h>
#include <core/kmerstore.h>
#include "tests.h"
template<template<class> class Index>
void testInsertOneSeq() {
Index<Kmer> index(4, true);
string seq = "ACAA";
string label = "s";
index.insert(seq, label);
string other1 = "TTGT", other2 = "AACA", other3 = "AAAA",
other4 = "CAAA";
TAP_TEST(index.get(seq).count == 1, TEST_KMERSTORE_INSERT_ONE_SEQ, "");
TAP_TEST(index.get(other1).count == 0, TEST_KMERSTORE_INSERT_ONE_SEQ, "");
TAP_TEST(index.get(other2).count == 0, TEST_KMERSTORE_INSERT_ONE_SEQ, "");
TAP_TEST(index.get(other3).count == 0, TEST_KMERSTORE_INSERT_ONE_SEQ, "");
TAP_TEST(index.get(other4).count == 0, TEST_KMERSTORE_INSERT_ONE_SEQ, "");
}
template<template <class> class T>
void testKmerStoreWithKmerSimple(int k, bool revcomp, int test_id ) {
......@@ -82,6 +100,8 @@ void testKmerStoreSeed() {
}
void testStorage() {
testInsertOneSeq<ArrayKmerStore>();
testInsertOneSeq<MapKmerStore>();
testKmerStoreWithKmerSimple<ArrayKmerStore>(5, false, TEST_ARRAY_KMERSTORE);
testKmerStoreWithKmerSimple<ArrayKmerStore>(5, true, TEST_ARRAY_KMERSTORE_RC);
......
#include <core/tools.h>
#include <core/fasta.h>
#include "tests.h"
#include <stdexcept>
void testOnlineFasta1() {
OnlineFasta fa("../../data/test1.fa");
OnlineFasta fq("../../data/test1.fq");
int nb_seq = 0;
TAP_TEST(fa.getLineNb() == 1, TEST_O_FASTA_LINE_NB, "");
TAP_TEST(fq.getLineNb() == 1, TEST_O_FASTA_LINE_NB, "");
while (fa.hasNext()) {
TAP_TEST(fq.hasNext(), TEST_O_FASTA_HAS_NEXT, "");
fa.next();
fq.next();
Sequence s1 = fa.getSequence();
Sequence s2 = fq.getSequence();
TAP_TEST(s1.label == s2.label && s1.label_full == s2.label_full
&& s1.sequence == s2.sequence, TEST_O_FASTA_GET_SEQUENCE, "fa: " << fa.getSequence() << endl << "fq: " << fq.getSequence());
nb_seq++;
}
TAP_TEST(fq.getLineNb() == 20, TEST_O_FASTA_LINE_NB, "");
TAP_TEST(! fq.hasNext(), TEST_O_FASTA_HAS_NEXT, "");
TAP_TEST(nb_seq == 5, TEST_O_FASTA_HAS_NEXT, "");
}
void testFasta1() {
Fasta fa("../../data/test1.fa");
......@@ -12,6 +36,10 @@ void testFasta1() {
TAP_TEST(fa.label_full(i) == fq.label_full(i), TEST_FASTA_LABEL_FULL, "");
TAP_TEST(fa.sequence(i) == fq.sequence(i), TEST_FASTA_SEQUENCE, "");
}
TAP_TEST(fa.label(2) == "seq3", TEST_FASTA_LABEL, "");
TAP_TEST(fa.sequence(2) == "A", TEST_FASTA_SEQUENCE, "");
TAP_TEST(fa.label(4) == "", TEST_FASTA_LABEL, "");
TAP_TEST(fa.sequence(4) == "AATN", TEST_FASTA_SEQUENCE, "");
}
void testFastaAdd() {
......@@ -32,6 +60,120 @@ void testFastaAdd() {
}
}
void testFastaAddThrows() {
bool caught = false;
try {
Fasta fa1("mlkdkklflskjfskldfj.fa");
} catch (invalid_argument e) {
TAP_TEST(string(e.what()).find("Error in opening file") != string::npos, TEST_FASTA_INVALID_FILE, "");
caught = true;
}
TAP_TEST(caught == true, TEST_FASTA_INVALID_FILE, "");
Fasta fa1("../../data/test1.fa");
caught = false;
try {
fa1.add("ljk:lkjsdfsdlfjsdlfkjs.fa");
} catch (invalid_argument e) {
TAP_TEST(string(e.what()).find("Error in opening file") != string::npos, TEST_FASTA_INVALID_FILE, "");
caught = true;
}
TAP_TEST(caught == true, TEST_FASTA_INVALID_FILE, "");
caught = false;
try {
fa1.add("testTools.cpp");
} catch (invalid_argument e) {
TAP_TEST(string(e.what()).find("The file seems to be malformed") != string::npos, TEST_FASTA_INVALID_FILE, "");
caught = true;
}
TAP_TEST(caught == true, TEST_FASTA_INVALID_FILE, "");
caught = false;
try {
OnlineFasta fa("lkjdflkdfjglkdfjg.fa");
} catch (invalid_argument e) {
TAP_TEST(string(e.what()).find("Error in opening file") != string::npos, TEST_FASTA_INVALID_FILE, "");
caught = true;
}
TAP_TEST(caught == true, TEST_FASTA_INVALID_FILE, "");
caught = false;
try {