File: DnaTest.cpp

package info (click to toggle)
aevol 9.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 3,176 kB
  • sloc: cpp: 26,650; ansic: 1,237; sh: 582; python: 545; makefile: 31
file content (201 lines) | stat: -rw-r--r-- 6,526 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// ****************************************************************************
//
//          Aevol - An in silico experimental evolution platform
//
// ****************************************************************************
//
// Copyright: See the AUTHORS file provided with the package or <www.aevol.fr>
// Web: http://www.aevol.fr/
// E-mail: See <http://www.aevol.fr/contact/>
// Original Authors : Guillaume Beslon, Carole Knibbe, David Parsons
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
//*****************************************************************************




// =================================================================
//                              Includes
// =================================================================
#include <gtest/gtest.h>

#include <array>
#include <memory>
#include <string>
#include <sstream>

#include "Dna.h"
#include "Individual.h"
#include "macros.h"
#include "Strand.h"

using namespace aevol;

//############################################################################
//                                                                           #
//                         Class IndividualTest                              #
//                                                                           #
//############################################################################
class DnaTest : public testing::Test
{
 protected:
  virtual void SetUp(void);
  virtual void TearDown(void);

  std::vector<std::string> genomes;
  std::vector<std::unique_ptr<Individual>> indivs;
};

// ===========================================================================
//                                 Public Methods
// ===========================================================================
void DnaTest::SetUp(void) {
  // Build ad-hoc dna
  //
  // AS = Arbitrary Sequence
  // AG = Arbitrary Gene
  // Do not modify the sequences !

  // Define arbitrary sequences
  std::array<std::string, 5> as = {
    "0011",
    "11101",
    "110011",
    "11000",
    "000101"
  };

  // Define an arbitrary gene
  std::string gene = std::string(SHINE_DAL_SEQ) + "0011000100110110010001"; // S-D SPACER START M0 H0 H0 W0 STOP

  // Define an arbitrary terminator
  std::string term = "01000001101";

  // Define a few arbitrary promoters
  std::array<std::string, 2> prom = {
    "0101010001110110010110", // dist from consensus: 2 => basal level: 0.6
    "0101011001110010010010"  // dist from consensus: 1 => basal level: 0.8
  };

  // Build genomes
  //                0-------4---------26------31-----59------65-----76------81--------103 (total size: 109)
  genomes.push_back(as[0] + prom[0] + as[1] + gene + as[2] + term + as[3] + prom[1] + as[4]);

  for (const auto& genome : genomes) {
    indivs.push_back(Individual::make_from_sequence(genome));
  }
}

void DnaTest::TearDown() {
  indivs.clear();
  genomes.clear();
}

TEST_F(DnaTest, TestDna) {
  // Check genome size
  EXPECT_EQ(genomes[0].size(), 109);
  EXPECT_EQ(genomes[0].size(), indivs[0]->dna().length());
}

TEST_F(DnaTest, TestProteins) {
  auto i = 0;
  indivs[i]->locate_promoters();
  indivs[i]->prom_compute_RNA();
  indivs[i]->start_protein();
  indivs[i]->compute_protein();
  indivs[i]->translate_protein(0.1);

  const auto& proteins = indivs[i]->proteins();
  EXPECT_EQ(proteins.size(), 2);
  auto prot_it = proteins.begin();
  auto prot = *prot_it;
  EXPECT_EQ(prot->position_first_aa(), 44);
  EXPECT_EQ(prot->is_duplicate(), false);
  EXPECT_EQ(prot->size(), 4);
  ++prot_it;
  prot = *prot_it;
  EXPECT_EQ(prot->position_first_aa(), 44);
  EXPECT_EQ(prot->is_duplicate(), true);
}


struct subseq_test_params {
  Strand strand;
  size_t first;
  size_t count;
  bool spans_oriC = false;
};
std::ostream& operator<<(std::ostream& os, const subseq_test_params& o) {
  os << "strand: " << o.strand << " ; first: " << o.first << " ; count: " << o.count << " ; spans_oriC: "
     << (o.spans_oriC ? "true" : "false");
  return os;
}

TEST_F(DnaTest, Test_subseq) {
  std::array<subseq_test_params, 4> tests_leading = {{
      {Strand::LEADING, 0, 10, false},
      {Strand::LEADING, 10, 42, false},
      {Strand::LEADING, 100, 42, true},
      {Strand::LEADING, 100, genomes[0].size(), true} // Whole genome
  }};

  for (const auto& test : tests_leading) {
    auto subseq = indivs[0]->dna().subseq(test.first, test.count, test.strand);

    // Check subseq size
    EXPECT_EQ(test.count, subseq.size());

    // Check subseq content
    if (test.spans_oriC) {
      auto expected_subseq = genomes[0].substr(test.first);
      expected_subseq += genomes[0].substr(0, test.count - expected_subseq.size());
      EXPECT_EQ(expected_subseq, subseq)
          << "\tNote: testing (" << test << ')';

    } else {
      EXPECT_EQ(genomes[0].substr(test.first, test.count), subseq)
          << "\tNote: testing (" << test << ')';
    }
  }

  std::array<subseq_test_params, 3> tests_lagging = {{
      {Strand::LAGGING, 15, 12, false},
      {Strand::LAGGING, genomes[0].size() - 1, genomes[0].size(), false}, // Whole genome
      {Strand::LAGGING, 4, 11, true}
  }};

  for (const auto& test : tests_lagging) {
    auto subseq = indivs[0]->dna().subseq(test.first, test.count, test.strand);

    // Construct expected result (naïve mode)
    std::string expected_subseq(test.count, '0');
    if (test.spans_oriC) {
      for (size_t i = 0; i < test.first + 1; ++i) {
        expected_subseq[i] = genomes[0][test.first - i] == '0' ? '1' : '0';
      }
      for (size_t i = 1; i < test.count - test.first; ++i) {
        expected_subseq[test.first + i] = genomes[0][genomes[0].size() - i] == '0' ? '1' : '0';
      }
    } else {
      for (size_t i = 0 ; i < test.count ; ++i) {
        expected_subseq[i] = genomes[0][test.first - i] == '0' ? '1' : '0';
      }
    }

    EXPECT_EQ(expected_subseq, subseq)
        << "\tNote: testing (" << test << ')';
  }
}