Update mussa to build on ubuntu 10.04 with qt 4.6.2 +boost 1.40.0.1
[mussa.git] / alg / test / test_glsequence.cpp
index 220b455487934d09fe62358eb9003c1ac473f654..29bbf34839a171bfeeb5bd9312d0681ec210297a 100644 (file)
-#include <boost/test/auto_unit_test.hpp>
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE test_glsequence
+#include <boost/test/unit_test.hpp>
+#include <boost/test/floating_point_comparison.hpp>
+#include <boost/shared_ptr.hpp>
 
 #include <string>
 
+#include "alg/annotation_colors.hpp"
 #include "alg/glsequence.hpp"
 #include "alg/sequence.hpp"
 
 using namespace std;
 
-BOOST_AUTO_TEST_CASE ( glsequence_operator_equal )
+BOOST_AUTO_TEST_CASE ( glsequence_operator_assignment )
 {
-  // I don't trust my operator = hack so lets make sure it works.
+  boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
   string s0("AAGGCCTT");
   string s1("TTGGCCAA");
   Sequence seq0(s0);
   Sequence seq1(s1);
 
-  GlSequence glseq0(seq0);
-  BOOST_CHECK (glseq0.sequence().get_seq() == s0);
-  GlSequence glseq1(seq1);
+  GlSequence glseq0(seq0, cm);
+  BOOST_CHECK (glseq0.get_sequence() == s0);
+  GlSequence glseq1(seq1, cm);
   GlSequence glseq_copy0(glseq0);
 
-  BOOST_CHECK(glseq_copy0.sequence().get_seq() == glseq0.sequence().get_seq());
-  BOOST_CHECK( &(glseq_copy0.sequence()) == &(glseq0.sequence()));
+  BOOST_CHECK(glseq_copy0.get_sequence() == glseq0.get_sequence());
+  BOOST_CHECK( glseq_copy0.get_sequence() == glseq0.get_sequence());
 
   glseq0 = glseq1;
+  BOOST_CHECK( glseq0.get_sequence() == s1 );
+}
+
+BOOST_AUTO_TEST_CASE( glsequence_copy_constructor )
+{
+  boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
+  string s0("AAAAAAGGGGGG");
 
-  BOOST_CHECK( glseq0.sequence().get_seq() == s1 );
+  GlSequenceRef glsp0(new GlSequence(s0, cm));
+  glsp0->setY(100.0);
+  BOOST_CHECK_EQUAL(glsp0->get_sequence(), s0);
+  BOOST_CHECK_EQUAL(glsp0->y(), 100.0);
+  
+  GlSequenceRef glsp0ref(glsp0);
+  GlSequenceRef glsp0copy(new GlSequence(glsp0));
+  BOOST_CHECK_EQUAL(glsp0->get_sequence(), s0);
+  BOOST_CHECK_EQUAL(glsp0->y(), 100.0);
+  BOOST_CHECK_EQUAL(glsp0ref->get_sequence(), s0);
+  BOOST_CHECK_EQUAL(glsp0ref->y(), 100.0);  
+  BOOST_CHECK_EQUAL(glsp0copy->get_sequence(), s0);
+  BOOST_CHECK_EQUAL(glsp0copy->y(), 100.0);
+  
+  glsp0ref->setY(50.0);
+  BOOST_CHECK_EQUAL(glsp0->y(), 50.0);
+  BOOST_CHECK_EQUAL(glsp0ref->y(), 50.0);  
+  BOOST_CHECK_EQUAL(glsp0copy->y(), 100.0);
+  
+  glsp0copy->setY(75.0);
+  BOOST_CHECK_EQUAL(glsp0->y(), 50.0);
+  BOOST_CHECK_EQUAL(glsp0ref->y(), 50.0);  
+  BOOST_CHECK_EQUAL(glsp0copy->y(), 75.0);
 }
 
 BOOST_AUTO_TEST_CASE( glsequence_color )
 {
-  Color black(0.0, 0.0, 0.0, 0.0);
-  Color c(0.1, 0.2, 0.3, 0.4);
+  boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
+  boost::shared_ptr<Color> black(new Color(0.0, 0.0, 0.0, 1.0));
+  boost::shared_ptr<Color> c(new Color(0.1, 0.2, 0.3, 0.4));
   Sequence seq("AAGGCCTT");
-  GlSequence s(seq);
+  GlSequence s(seq, cm);
   
-  BOOST_CHECK_EQUAL(s.color(), black );
+  BOOST_CHECK_EQUAL(*s.color(), *black );
   s.setColor( c );
-  BOOST_CHECK_EQUAL( s.color(), c );
+  BOOST_CHECK_EQUAL( *(s.color()), *c );
+}
+
+BOOST_AUTO_TEST_CASE( glsequence_find_real_sequence )
+{
+  boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
+  GlSequence s("AAAAAAAAAANNNNNANNA", cm);
+  //            0123456789012345678
+  s.add_annotations_for_defined_sequence();
+  
+  BOOST_CHECK_EQUAL(s.annotations().size(), 3);
+  std::vector<SeqSpanRef> annot(s.annotations().begin(), s.annotations().end());
+  BOOST_CHECK_EQUAL(annot[0]->start(), 0);
+  BOOST_CHECK_EQUAL(annot[0]->stop(), 10);
+  BOOST_CHECK_EQUAL(annot[1]->start(), 15);
+  BOOST_CHECK_EQUAL(annot[1]->size(), 1);
+  BOOST_CHECK_EQUAL(annot[2]->start(), 18);
+  BOOST_CHECK_EQUAL(annot[2]->size(), 1);
+}
+
+void dummy_draw_func(SeqSpanRef ref, float l, float r)
+{
+}
+  
+BOOST_AUTO_TEST_CASE( glsequence_set_annotation_drawfunc_by_type )
+{
+  ColorRef default_color(new Color(1.0, 0.0, 0.0));
+  boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
+  GlSequence s("AAAAGGGGNNNNTTTTCCC", cm);
+  //            0123456789012345678
+  s.add_annotation("Aname", "value", 0, 4);
+  s.add_annotation("Gname", "value", 4, 4);
+  s.add_annotation("Tname", "gene", 12, 4);
+  s.update_annotation_draw_function("gene", dummy_draw_func, default_color);
+
+  BOOST_CHECK_EQUAL(s.annotations().size(), 3);
+  std::vector<SeqSpanRef> annot(s.annotations().begin(), s.annotations().end());
+  // the two not updated annotations shouldn't have a drawable attached to them yet 
+  BOOST_CHECK( not annot[0]->drawable());
+  BOOST_CHECK( not annot[1]->drawable());
+  // the annotation updated must be drawable
+  BOOST_REQUIRE(annot[2]->drawable());
+  // and it must have the right draw function
+  BOOST_CHECK_EQUAL(annot[2]->drawable()->drawFunction(), dummy_draw_func);
+  BOOST_CHECK_EQUAL(annot[2]->drawable()->color(), default_color);
 }
 
 BOOST_AUTO_TEST_CASE( glsequence_renderable )
 {
+  boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
   Sequence seq("AAGGCCTT");
-  GlSequence s(seq);
+  GlSequence s(seq, cm);
 
   // way more base pairs than viewport pixel width 
   BOOST_CHECK_EQUAL(s.is_sequence_renderable( 0, 1000, 500), false );
   // way fewer basepairs than viewport pixel width
   BOOST_CHECK_EQUAL(s.is_sequence_renderable( 0, 10, 500), true);
+
+  BOOST_CHECK_CLOSE((double)s.pixelWidth(0, 100, 100), 1.0, 1e-6);
+  BOOST_CHECK_CLOSE((double)s.pixelWidth(0, 1000, 100), 10.0, 1e-6);
 }
 
 BOOST_AUTO_TEST_CASE( glsequence_sequence )
 {
+  boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
   string seq_string("AAGGCCTTNNAAGGCCTTNNAAGGCCTTNN");
   string::size_type seqlen = seq_string.size();
   Sequence seq(seq_string);
-  GlSequence glseq(seq);
+  GlSequence glseq(seq, cm);
 
-  BOOST_CHECK( glseq.sequence_begin(0, 50) == seq.begin() );
+  BOOST_CHECK( glseq.region_begin(0, 50) == seq.begin() );
   // always make sure we return seq.end() regardless of how much extra
   // is asked for
-  BOOST_CHECK( glseq.sequence_end(0, seqlen+10) == seq.end() );
+  BOOST_CHECK( glseq.region_end(0, seqlen+10) == seq.end() );
   // do we get the right end pointer?
-  BOOST_CHECK( glseq.sequence_end(0, 5) == seq.begin()+5 );
+  BOOST_CHECK( glseq.region_end(0, 5) == seq.begin()+5 );
 
   // when we request far too much sequence what do we get?
-  BOOST_CHECK( glseq.sequence_begin(seqlen+10, seqlen+20) == seq.end() );
-  BOOST_CHECK( glseq.sequence_end(seqlen+10, seqlen+20) == seq.end() );
+  BOOST_CHECK( glseq.region_begin(seqlen+10, seqlen+20) == seq.end() );
+  BOOST_CHECK( glseq.region_end(seqlen+10, seqlen+20) == seq.end() );
 
-  // we cant ask for reversed sequences with sequence_begin/end
-  BOOST_CHECK( glseq.sequence_begin(10, 5) == seq.end() );
-  BOOST_CHECK( glseq.sequence_end(10, 5) == seq.end() );
+  // we cant ask for reversed sequences with region_begin/end
+  BOOST_CHECK( glseq.region_begin(10, 5) == seq.end() );
+  BOOST_CHECK( glseq.region_end(10, 5) == seq.end() );
 
   Sequence::const_iterator seq_itor;
 
   // if we as for an empty segment? start and end should equal
-  seq_itor = glseq.sequence_begin(10, 10);
-  BOOST_CHECK( seq_itor == glseq.sequence_end(10, 10) );
+  seq_itor = glseq.region_begin(10, 10);
+  BOOST_CHECK( seq_itor == glseq.region_end(10, 10) );
 
   // reuse seq_itor downhere 
   string::const_iterator str_itor;
   for(str_itor = seq.begin(),
-      seq_itor = glseq.sequence_begin();
+      seq_itor = glseq.begin();
       str_itor != seq.end() and 
-      seq_itor != glseq.sequence_end();
+      seq_itor != glseq.end();
       ++str_itor, ++seq_itor)
   {
     BOOST_CHECK_EQUAL( *str_itor, *seq_itor );
@@ -94,13 +178,101 @@ BOOST_AUTO_TEST_CASE( glsequence_sequence )
 // make sure the computation of the leftmost and rightmost base is correct
 BOOST_AUTO_TEST_CASE( glsequence_leftright_base )
 {
+  boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
   std::string seq_string = "AAGGCCTT";
   Sequence seq(seq_string);
-  GlSequence glseq(seq);
+  GlSequence glseq(seq, cm);
 
   BOOST_CHECK_EQUAL( glseq.leftbase( -50.0 ), 0 );
   BOOST_CHECK_EQUAL( glseq.leftbase(   0.5 ), 1 );
+  BOOST_CHECK_EQUAL( glseq.leftbase(   5.0 ), 5 );
+  BOOST_CHECK_EQUAL( glseq.leftbase( 500.0 ), seq_string.size() );
+  BOOST_CHECK_EQUAL( glseq.rightbase(    0.0 ), 0 );
   BOOST_CHECK_EQUAL( glseq.rightbase( 1000.0 ), seq_string.size() );
   BOOST_CHECK_EQUAL( glseq.rightbase( seq_string.size()-0.5),
                      seq_string.size()-1);
 }
+
+// do our left and right most base computations still work if
+// we move the sequence around?
+BOOST_AUTO_TEST_CASE( glsequence_movex )
+{
+  boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
+  std::string seq_string = "AAGGCCTTAAGGCCTT";
+  Sequence seq(seq_string);
+  GlSequence glseq(seq, cm);
+
+  glseq.setX(-5);
+  BOOST_CHECK_EQUAL( glseq.leftbase(-100.0), 0 );
+  BOOST_CHECK_EQUAL( glseq.leftbase(   0.0), 5 );
+  BOOST_CHECK_EQUAL( glseq.leftbase(  -2.0), 3 );
+  BOOST_CHECK_EQUAL( glseq.leftbase( 100.0), seq_string.size() );
+  BOOST_CHECK_EQUAL( glseq.rightbase( 1000.0 ), seq_string.size() );
+  BOOST_CHECK_EQUAL( glseq.rightbase(    8.0 ), 8+5 );
+  BOOST_CHECK_EQUAL( glseq.rightbase(   -7.0 ), 0 );
+}
+
+// Check iterators
+BOOST_AUTO_TEST_CASE( glsequence_check_iterators )
+{
+  boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
+  std::string seq_string = "AAGGCCTTAAGGCCTT";
+  Sequence seq(seq_string);
+  GlSequence glseq(seq, cm);
+
+  Sequence::const_iterator seq_begin_i;
+  Sequence::const_iterator seq_end_i;
+
+  BOOST_CHECK(glseq.region_begin(5, -5) == seq.end());
+  BOOST_CHECK(glseq.region_begin(0, 20) == seq.begin());
+  BOOST_CHECK(glseq.region_begin(10,20) == seq.begin()+10);
+
+  BOOST_CHECK(glseq.region_end(5, -5) == seq.end());
+  BOOST_CHECK(glseq.region_end(0, 20) == seq.end());
+  BOOST_CHECK(glseq.region_end(0, 10) == seq.begin()+10);
+
+  glseq.setX(-5);
+  BOOST_CHECK(glseq.region_begin(0, 10) == seq.begin()+5);
+  BOOST_CHECK(glseq.region_end(0, 15) == seq.end());
+}
+
+BOOST_AUTO_TEST_CASE( glsequence_subseq ) 
+{
+  boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
+  boost::shared_ptr<Color> c(new Color(1.0, 0.5, 0.5));
+  
+  GlSequence seq("AAGGCCTT", cm);
+  seq.setColor(c);
+  
+  GlSequence subseq = seq.subseq(4,2);
+  BOOST_CHECK_EQUAL(subseq.get_sequence(), "CC");
+  BOOST_CHECK_EQUAL(subseq.color(), c);
+}
+
+/*
+BOOST_AUTO_TEST_CASE ( shared_ptr_test )
+{
+  boost::shared_ptr<AnnotationColors> cm(new AnnotationColors);
+  // I don't trust my operator= hack so lets make sure it works.
+  string s0("AAGGCCTT");
+  string s1("TTGGCCAA");
+  Sequence seq0(s0);
+  BOOST_CHECK_EQUAL( seq0.use_count(), 1 );
+  Sequence seq1(s1);
+  BOOST_CHECK_EQUAL( seq0.use_count(), 1 );
+
+  // make a block to test deallocation
+  {
+    GlSequence glseq0(seq0, cm);
+    BOOST_CHECK_EQUAL(seq0.use_count(), 2);
+    GlSequence glseq1(seq1, cm);
+    BOOST_CHECK_EQUAL(seq1.use_count(), 2);
+
+    glseq0 = glseq1;
+    BOOST_CHECK_EQUAL( seq0.use_count(), 1 );
+    BOOST_CHECK_EQUAL( seq1.use_count(), 3 );
+  }
+  BOOST_CHECK_EQUAL(seq0.use_count(), 1);
+  BOOST_CHECK_EQUAL(seq1.use_count(), 1);
+}
+*/