+#define BOOST_AUTO_TEST_MAIN
+#include <boost/test/auto_unit_test.hpp>
+
+#include "seq_span.hpp"
+#include "mussa_exceptions.hpp"
+
+#include <stdlib.h>
+
+BOOST_AUTO_TEST_CASE( seqspan_from_string )
+{
+ std::string str1("AAGGCCTT");
+ SeqSpanRef span1(new SeqSpan(str1));
+ BOOST_CHECK_EQUAL(span1->length(), str1.length());
+ BOOST_CHECK_EQUAL(span1->sequence(), str1);
+}
+
+BOOST_AUTO_TEST_CASE( seqspan_from_seqspan )
+{
+ std::string str1("AAGGCCTT");
+ SeqSpanRef span1(new SeqSpan(str1));
+ SeqSpanRef span2(new SeqSpan(span1));
+ SeqSpanRef span3(new SeqSpan(span1));
+
+ BOOST_CHECK_EQUAL(span1->length(), str1.length());
+ BOOST_CHECK_EQUAL(span1->sequence(), str1);
+ BOOST_CHECK_EQUAL(span1->length(), span2->length());
+ BOOST_CHECK_EQUAL(span2->sequence(), str1);
+
+ BOOST_CHECK_EQUAL(span1->length(), span3->length());
+ BOOST_CHECK_EQUAL(span3->sequence(), str1);
+}
+
+BOOST_AUTO_TEST_CASE( seqspan_equality )
+{
+ std::string str1("AAGGCCTT");
+ std::string str2("AACCGGTT");
+ std::string str3("AACCGGTT");
+ SeqSpanRef span1(new SeqSpan(str1));
+ SeqSpanRef span1copy(new SeqSpan(span1));
+ SeqSpanRef span2(new SeqSpan(str2));
+ SeqSpanRef span3(new SeqSpan(str3));
+
+ BOOST_CHECK_EQUAL(*span1, *span1copy);
+ BOOST_CHECK(*span1 != *span3);
+ // if its different source strings, compare the underlying string
+ BOOST_CHECK(*span2 != *span3);
+ BOOST_CHECK_EQUAL(SeqSpan::isFamily(*span2, *span3), false);
+}
+
+BOOST_AUTO_TEST_CASE( seqspan_find_first_not_of )
+{
+ std::string str1("AAAAT");
+ SeqSpan seq1(str1);
+ BOOST_CHECK_EQUAL(seq1.find_first_not_of("A"), str1.find_first_not_of("A"));
+
+ std::string str2("AATTGGCC");
+ SeqSpan seq2(str2);
+ BOOST_CHECK_EQUAL(seq2.find_first_not_of("qwer"), str2.find_first_not_of("qwer"));
+}
+
+BOOST_AUTO_TEST_CASE( seqspan_at )
+{
+ std::string str1("AAGGCCTT");
+ SeqSpanRef seq1(new SeqSpan(str1));
+ SeqSpanRef seq2(new SeqSpan(seq1, 2, 2));
+
+ BOOST_CHECK_EQUAL( seq1->at(0), str1.at(0) );
+ BOOST_CHECK_EQUAL( seq1->at(2), seq2->at(0) );
+ BOOST_CHECK_EQUAL( str1[2], seq2->at(0) );
+ BOOST_CHECK_EQUAL( (*seq1)[0], seq1->at(0) );
+ BOOST_CHECK_EQUAL( (*seq1)[2], (*seq2)[0] );
+}
+
+BOOST_AUTO_TEST_CASE( seqspan_data )
+{
+ std::string str1("AAGGCCTT");
+ SeqSpanRef seq1(new SeqSpan(str1));
+ SeqSpanRef seq2(new SeqSpan(seq1, 3, 2));
+
+ BOOST_REQUIRE_EQUAL( str1.length(), seq1->length());
+ BOOST_CHECK_EQUAL( str1.data(), seq1->data() );
+ std::string str1sub = str1.substr(3,2);
+ BOOST_REQUIRE_EQUAL( seq2->size(), str1sub.size() );
+ BOOST_REQUIRE_EQUAL( seq2->length(), str1sub.length() );
+ for (int i = 0; i != seq2->size(); ++i) {
+ BOOST_CHECK_EQUAL( seq2->data()[i], str1sub.data()[i] );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( seqspan_begin_end )
+{
+ std::string str1("AAGGCCTT");
+ SeqSpanRef seq1(new SeqSpan(str1));
+ SeqSpanRef seq2(new SeqSpan(seq1, 2, 2));
+
+ BOOST_CHECK(seq1->begin() + 2 == seq2->begin());
+
+ std::string::const_iterator str1_i = str1.begin();
+ SeqSpan::const_iterator seq1_i = seq1->begin();
+ for(; not ((str1_i == str1.end()) or (seq1_i == seq1->end())); ++str1_i, ++seq1_i) {
+ BOOST_CHECK_EQUAL( *str1_i, *seq1_i );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( seqspan_rbegin_rend )
+{
+ std::string str1("AAGGCCTT");
+ SeqSpanRef seq1(new SeqSpan(str1));
+
+ std::string::const_reverse_iterator str1_i = str1.rbegin();
+ SeqSpan::const_reverse_iterator seq1_i = seq1->rbegin();
+ for(; seq1_i != seq1->rend(); ++str1_i, ++seq1_i) {
+ BOOST_CHECK_EQUAL( *str1_i, *seq1_i );
+ }
+}
+
+BOOST_AUTO_TEST_CASE( seqspan_empty_start_stop )
+{
+ SeqSpanRef s1(new SeqSpan(""));
+ BOOST_CHECK_EQUAL( s1->start(), 0 );
+ BOOST_CHECK_EQUAL( s1->stop(), 0 );
+
+ BOOST_CHECK_EQUAL( s1->parentStart(), 0 );
+ BOOST_CHECK_EQUAL( s1->parentStop(), 0 );
+
+ BOOST_CHECK_EQUAL( s1->size(), 0 );
+}
+
+BOOST_AUTO_TEST_CASE( seqspan_global_start_stop )
+{
+ std::string seq_string("AAGGCCTT");
+ SeqSpanRef s1(new SeqSpan(seq_string));
+ BOOST_CHECK_EQUAL( s1->start(), 0 );
+ BOOST_CHECK_EQUAL( s1->stop(), seq_string.size() );
+
+ std::string s2seq_string = seq_string.substr(2,3);
+ SeqSpanRef s2 = s1->subseq(2,3);
+ BOOST_CHECK_EQUAL( s2->start(), 2);
+ BOOST_CHECK_EQUAL( s2->stop(), 2+3);
+ BOOST_CHECK_EQUAL( s2->size(), 3);
+ BOOST_CHECK_EQUAL( s2->sequence(), s2seq_string);
+
+ std::string s3seq_string = s2seq_string.substr(1,1);
+ SeqSpanRef s3 = s2->subseq(1,1);
+ BOOST_CHECK_EQUAL( s3->start(), 2+1 );
+ BOOST_CHECK_EQUAL( s3->stop(), 2+1+1);
+ BOOST_CHECK_EQUAL( s3->size(), 1);
+ BOOST_CHECK_EQUAL( s3->sequence(), s3seq_string);
+}
+
+BOOST_AUTO_TEST_CASE( seqspan_global_to_large )
+{
+ std::string seq_string("AAGGCCTT");
+ SeqSpanRef s1(new SeqSpan(seq_string));
+ BOOST_CHECK_EQUAL( s1->start(), 0 );
+ BOOST_CHECK_EQUAL( s1->stop(), seq_string.size() );
+
+ std::string s2seq_string = seq_string.substr(2,3);
+ SeqSpanRef s2 = s1->subseq(4,8);
+ BOOST_CHECK_EQUAL( s2->start(), 4);
+ BOOST_CHECK_EQUAL( s2->size(), 4);
+ BOOST_CHECK_EQUAL( s2->stop(), 8);
+}
+
+BOOST_AUTO_TEST_CASE( seqspan_parent_start_stop )
+{
+ std::string seq_string("AAGGCCTT");
+ SeqSpanRef s1(new SeqSpan(seq_string));
+ BOOST_CHECK_EQUAL( s1->parentStart(), 0 );
+ BOOST_CHECK_EQUAL( s1->parentStop(), seq_string.size() );
+
+ std::string s2seq_string = seq_string.substr(2,3);
+ SeqSpanRef s2 = s1->subseq(2,3);
+ BOOST_CHECK_EQUAL( s2->parentStart(), 2);
+ BOOST_CHECK_EQUAL( s2->parentStop(), 2+3);
+ BOOST_CHECK_EQUAL( s2->size(), 3);
+ BOOST_CHECK_EQUAL( s2->sequence(), s2seq_string);
+
+ std::string s3seq_string = s2seq_string.substr(1,1);
+ SeqSpanRef s3 = s2->subseq(1,1);
+ BOOST_CHECK_EQUAL( s3->parentStart(), 1 );
+ BOOST_CHECK_EQUAL( s3->parentStop(), 1+1);
+ BOOST_CHECK_EQUAL( s3->size(), 1);
+ BOOST_CHECK_EQUAL( s3->sequence(), s3seq_string);
+}
+
+BOOST_AUTO_TEST_CASE( seqspan_global_mutable_start_stop )
+{
+ std::string seq_string("AAGGCCTT");
+ SeqSpanRef s1(new SeqSpan(seq_string));
+
+ std::string s2seq_string = seq_string.substr(2,3);
+ SeqSpanRef s2 = s1->subseq(2,3);
+ BOOST_CHECK_EQUAL( s2->start(), 2);
+ BOOST_CHECK_EQUAL( s2->stop(), 2+3);
+ BOOST_CHECK_EQUAL( s2->size(), 3);
+ BOOST_CHECK_EQUAL( s2->sequence(), s2seq_string);
+
+ std::string s3seq_string = s2seq_string.substr(1,1);
+ SeqSpanRef s3 = s2->subseq(1,1);
+ // Check root location
+ BOOST_CHECK_EQUAL( s3->start(), 2+1 );
+ BOOST_CHECK_EQUAL( s3->stop(), 2+1+1);
+ BOOST_CHECK_EQUAL( s3->size(), 1);
+ // Check parent location
+ BOOST_CHECK_EQUAL( s3->parentStart(), 1 );
+ BOOST_CHECK_EQUAL( s3->parentStop(), 1+1);
+ BOOST_CHECK_EQUAL( s3->sequence(), s3seq_string);
+
+ // Extend s2 to the left
+ s2->setStart(1);
+ BOOST_CHECK_EQUAL( s2->start(), 1);
+ BOOST_CHECK_EQUAL( s2->stop(), 1+1+3);
+ BOOST_CHECK_EQUAL( s2->size(), 4);
+
+ // Child sequence should have the same global location
+ BOOST_CHECK_EQUAL( s3->start(), 2+1 );
+ BOOST_CHECK_EQUAL( s3->stop(), 2+1+1);
+ BOOST_CHECK_EQUAL( s3->size(), 1);
+ // Child sequence should now have different parent location
+ BOOST_CHECK_EQUAL( s3->parentStart(), 2 );
+ BOOST_CHECK_EQUAL( s3->parentStop(), 2+1);
+ BOOST_CHECK_EQUAL( s3->size(), 1);
+}
+
+BOOST_AUTO_TEST_CASE( seqspan_parent_mutable_start_stop )
+{
+ std::string seq_string("AAGGCCTT");
+ SeqSpanRef s1(new SeqSpan(seq_string));
+
+ std::string s2seq_string = seq_string.substr(3,3);
+ SeqSpanRef s2 = s1->subseq(3,3);
+ BOOST_CHECK_EQUAL( s2->start(), 3);
+ BOOST_CHECK_EQUAL( s2->stop(), 3+3);
+ BOOST_CHECK_EQUAL( s2->size(), 3);
+ BOOST_CHECK_EQUAL( s2->sequence(), s2seq_string);
+
+ std::string s3seq_string = s2seq_string.substr(1,1);
+ SeqSpanRef s3 = s2->subseq(1,1);
+ // Check root location
+ BOOST_CHECK_EQUAL( s3->start(), 3+1 );
+ BOOST_CHECK_EQUAL( s3->stop(), 3+1+1);
+ BOOST_CHECK_EQUAL( s3->size(), 1);
+ // Check parent location
+ BOOST_CHECK_EQUAL( s3->parentStart(), 1 );
+ BOOST_CHECK_EQUAL( s3->parentStop(), 1+1);
+ BOOST_CHECK_EQUAL( s3->sequence(), s3seq_string);
+
+ // s2 should now be equivalent to s1->subseq(1,5)
+ s2->setParentStart(1);
+ BOOST_CHECK_EQUAL( s2->start(), 1);
+ BOOST_CHECK_EQUAL( s2->stop(), 3+3);
+ BOOST_CHECK_EQUAL( s2->size(), 5);
+
+ // Child sequence should have the same global location
+ BOOST_CHECK_EQUAL( s3->start(), 3+1 );
+ BOOST_CHECK_EQUAL( s3->stop(), 3+1+1);
+ BOOST_CHECK_EQUAL( s3->size(), 1);
+ // Child sequence should now have different parent location
+ BOOST_CHECK_EQUAL( s3->parentStart(), 1+2);
+ BOOST_CHECK_EQUAL( s3->parentStop(), 1+2+1);
+}
+
+// what happens if we set a stop past our actual end
+BOOST_AUTO_TEST_CASE( seqspan_stop_past_end )
+{
+ std::string seq_string("AAGGCCTT");
+ SeqSpanRef s1(new SeqSpan(seq_string));
+ std::string s2seq_string = seq_string.substr(3,3);
+ SeqSpanRef s2 = s1->subseq(3,3);
+ std::string s3seq_string = s2seq_string.substr(1,1);
+ SeqSpanRef s3 = s2->subseq(1,1);
+
+ // should be limited by our parent sequence
+ s3->setStop(8);
+ BOOST_CHECK_EQUAL( s3->size(), 2);
+
+ s2->setStop(8);
+ BOOST_CHECK_EQUAL( s2->size(), 5);
+
+ s3->setStop(8);
+ BOOST_CHECK_EQUAL( s3->size(), 4);
+}
\ No newline at end of file