Store Sequence sequence location in a shared_ptr class
[mussa.git] / alg / test / test_seq_span.cpp
diff --git a/alg/test/test_seq_span.cpp b/alg/test/test_seq_span.cpp
new file mode 100644 (file)
index 0000000..9b98f21
--- /dev/null
@@ -0,0 +1,283 @@
+#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