1 /*  $Id: seq_loc_unit_test.cpp 625330 2021-02-11 13:30:35Z ivanov $
2  * ===========================================================================
3  *
4  *                            PUBLIC DOMAIN NOTICE
5  *               National Center for Biotechnology Information
6  *
7  *  This software/database is a "United States Government Work" under the
8  *  terms of the United States Copyright Act.  It was written as part of
9  *  the author's official duties as a United States Government employee and
10  *  thus cannot be copyrighted.  This software/database is freely available
11  *  to the public for use. The National Library of Medicine and the U.S.
12  *  Government have not placed any restriction on its use or reproduction.
13  *
14  *  Although all reasonable efforts have been taken to ensure the accuracy
15  *  and reliability of the software and data, the NLM and the U.S.
16  *  Government do not and cannot warrant the performance or results that
17  *  may be obtained by using this software or data. The NLM and the U.S.
18  *  Government disclaim all warranties, express or implied, including
19  *  warranties of performance, merchantability or fitness for any particular
20  *  purpose.
21  *
22  *  Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author:  Eugene Vasilchenko, NCBI
27  *
28  * File Description:
29  *   Unit test for CSeq_loc and some closely related code
30  *
31  * ===========================================================================
32  */
33 #define NCBI_TEST_APPLICATION
34 #include <ncbi_pch.hpp>
35 
36 #include <objects/seqloc/seqloc__.hpp>
37 
38 #include <corelib/ncbiapp.hpp>
39 #include <corelib/ncbithr.hpp>
40 #include <util/random_gen.hpp>
41 #include <corelib/test_boost.hpp>
42 
43 #include <boost/test/parameterized_test.hpp>
44 
45 #include <common/test_assert.h>  /* This header must go last */
46 
47 USING_NCBI_SCOPE;
48 USING_SCOPE(objects);
49 
50 
MakeLoc(const char * text)51 CRef<CSeq_loc> MakeLoc(const char* text)
52 {
53     string input = text;
54     if ( input.find("::=") == NPOS ) {
55         input = "Seq-loc::="+input;
56     }
57     CNcbiIstrstream str(input);
58     CRef<CSeq_loc> loc(new CSeq_loc);
59     str >> MSerial_AsnText >> *loc;
60     return loc;
61 }
62 
63 
64 template<class Obj>
MakeASN(const Obj & loc)65 string MakeASN(const Obj& loc)
66 {
67     CNcbiOstrstream str;
68     str << MSerial_AsnText << loc;
69     return CNcbiOstrstreamToString(str);
70 }
71 
72 
BOOST_AUTO_TEST_CASE(TestSingle)73 BOOST_AUTO_TEST_CASE(TestSingle)
74 {
75     CRef<CSeq_loc> loc =
76         MakeLoc("int { from 10, to 20, id gi 2 }");
77 
78     CSeq_loc_CI it(*loc);
79     BOOST_CHECK(!it.HasEquivSets());
80 
81     BOOST_REQUIRE(it);
82     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(2));
83     BOOST_CHECK(it.GetSeq_id().IsGi());
84     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(10, 20));
85     BOOST_CHECK(!it.IsSetStrand());
86     BOOST_CHECK(!it.IsWhole());
87     BOOST_CHECK(!it.IsEmpty());
88     BOOST_CHECK(!it.IsPoint());
89     BOOST_CHECK(!it.IsInEquivSet());
90     BOOST_CHECK(!it.IsInBond());
91     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
92                       "Seq-loc ::= int {\n"
93                       "  from 10,\n"
94                       "  to 20,\n"
95                       "  id gi 2\n"
96                       "}\n");
97     ++it;
98 
99     BOOST_CHECK(!it);
100 }
101 
102 
BOOST_AUTO_TEST_CASE(TestDouble)103 BOOST_AUTO_TEST_CASE(TestDouble)
104 {
105     CRef<CSeq_loc> loc =
106         MakeLoc("mix {"
107                 " int { from 10, to 20, strand plus, id gi 2 },"
108                 " pnt { point 30, strand minus, id gi 3}"
109                 "}");
110 
111     CSeq_loc_CI it(*loc);
112     BOOST_CHECK(!it.HasEquivSets());
113 
114     BOOST_REQUIRE(it);
115     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(2));
116     BOOST_CHECK(it.GetSeq_id().IsGi());
117     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(10, 20));
118     BOOST_CHECK(it.IsSetStrand());
119     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
120     BOOST_CHECK(!it.IsWhole());
121     BOOST_CHECK(!it.IsEmpty());
122     BOOST_CHECK(!it.IsPoint());
123     BOOST_CHECK(!it.IsInEquivSet());
124     BOOST_CHECK(!it.IsInBond());
125     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
126                       "Seq-loc ::= int {\n"
127                       "  from 10,\n"
128                       "  to 20,\n"
129                       "  strand plus,\n"
130                       "  id gi 2\n"
131                       "}\n");
132     ++it;
133 
134     BOOST_REQUIRE(it);
135     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(3));
136     BOOST_CHECK(it.GetSeq_id().IsGi());
137     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(30, 30));
138     BOOST_CHECK(it.IsSetStrand());
139     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_minus));
140     BOOST_CHECK(!it.IsWhole());
141     BOOST_CHECK(!it.IsEmpty());
142     BOOST_CHECK(it.IsPoint());
143     BOOST_CHECK(!it.IsInEquivSet());
144     BOOST_CHECK(!it.IsInBond());
145     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
146                       "Seq-loc ::= pnt {\n"
147                       "  point 30,\n"
148                       "  strand minus,\n"
149                       "  id gi 3\n"
150                       "}\n");
151     ++it;
152 
153     BOOST_CHECK(!it);
154 }
155 
156 
BOOST_AUTO_TEST_CASE(TestEquiv)157 BOOST_AUTO_TEST_CASE(TestEquiv)
158 {
159     CRef<CSeq_loc> loc =
160         MakeLoc("mix {"
161                 " int { from 10, to 20, strand plus, id gi 2 },"
162                 " equiv {"
163                 "  int { from 25, to 27, strand plus, id gi 2 },"
164                 "  mix {"
165                 "   int { from 25, to 26, strand plus, id gi 2 },"
166                 "   int { from 27, to 27, strand minus, id gi 2 }"
167                 "  }"
168                 " },"
169                 " pnt { point 30, strand minus, id gi 3}"
170                 "}");
171 
172     CSeq_loc_CI it(*loc);
173     BOOST_CHECK(it.HasEquivSets());
174 
175     BOOST_REQUIRE(it);
176     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(2));
177     BOOST_CHECK(it.GetSeq_id().IsGi());
178     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(10, 20));
179     BOOST_CHECK(it.IsSetStrand());
180     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
181     BOOST_CHECK(!it.IsWhole());
182     BOOST_CHECK(!it.IsEmpty());
183     BOOST_CHECK(!it.IsPoint());
184     BOOST_CHECK(!it.IsInEquivSet());
185     BOOST_CHECK(!it.IsInBond());
186     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
187                       "Seq-loc ::= int {\n"
188                       "  from 10,\n"
189                       "  to 20,\n"
190                       "  strand plus,\n"
191                       "  id gi 2\n"
192                       "}\n");
193     ++it;
194 
195     BOOST_REQUIRE(it);
196     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(2));
197     BOOST_CHECK(it.GetSeq_id().IsGi());
198     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(25, 27));
199     BOOST_CHECK(it.IsSetStrand());
200     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
201     BOOST_CHECK(!it.IsWhole());
202     BOOST_CHECK(!it.IsEmpty());
203     BOOST_CHECK(!it.IsPoint());
204     BOOST_CHECK(it.IsInEquivSet());
205     BOOST_CHECK(!it.IsInBond());
206     BOOST_CHECK_EQUAL(it.GetEquivSetsCount(), 1u);
207     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).first.GetPos(), 1u);
208     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).second.GetPos(), 4u);
209     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).first.GetPos(), 1u);
210     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).second.GetPos(), 2u);
211     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
212                       "Seq-loc ::= int {\n"
213                       "  from 25,\n"
214                       "  to 27,\n"
215                       "  strand plus,\n"
216                       "  id gi 2\n"
217                       "}\n");
218     ++it;
219 
220     BOOST_REQUIRE(it);
221     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(2));
222     BOOST_CHECK(it.GetSeq_id().IsGi());
223     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(25, 26));
224     BOOST_CHECK(it.IsSetStrand());
225     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
226     BOOST_CHECK(!it.IsWhole());
227     BOOST_CHECK(!it.IsEmpty());
228     BOOST_CHECK(!it.IsPoint());
229     BOOST_CHECK(it.IsInEquivSet());
230     BOOST_CHECK(!it.IsInBond());
231     BOOST_CHECK_EQUAL(it.GetEquivSetsCount(), 1u);
232     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).first.GetPos(), 1u);
233     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).second.GetPos(), 4u);
234     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).first.GetPos(), 2u);
235     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).second.GetPos(), 4u);
236     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
237                       "Seq-loc ::= int {\n"
238                       "  from 25,\n"
239                       "  to 26,\n"
240                       "  strand plus,\n"
241                       "  id gi 2\n"
242                       "}\n");
243     ++it;
244 
245     BOOST_REQUIRE(it);
246     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(2));
247     BOOST_CHECK(it.GetSeq_id().IsGi());
248     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(27, 27));
249     BOOST_CHECK(it.IsSetStrand());
250     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_minus));
251     BOOST_CHECK(!it.IsWhole());
252     BOOST_CHECK(!it.IsEmpty());
253     BOOST_CHECK(it.IsPoint());
254     BOOST_CHECK(it.IsInEquivSet());
255     BOOST_CHECK(!it.IsInBond());
256     BOOST_CHECK_EQUAL(it.GetEquivSetsCount(), 1u);
257     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).first.GetPos(), 1u);
258     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).second.GetPos(), 4u);
259     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).first.GetPos(), 2u);
260     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).second.GetPos(), 4u);
261     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
262                       "Seq-loc ::= int {\n"
263                       "  from 27,\n"
264                       "  to 27,\n"
265                       "  strand minus,\n"
266                       "  id gi 2\n"
267                       "}\n");
268     ++it;
269 
270     BOOST_REQUIRE(it);
271     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(3));
272     BOOST_CHECK(it.GetSeq_id().IsGi());
273     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(30, 30));
274     BOOST_CHECK(it.IsSetStrand());
275     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_minus));
276     BOOST_CHECK(!it.IsWhole());
277     BOOST_CHECK(!it.IsEmpty());
278     BOOST_CHECK(it.IsPoint());
279     BOOST_CHECK(!it.IsInEquivSet());
280     BOOST_CHECK(!it.IsInBond());
281     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
282                       "Seq-loc ::= pnt {\n"
283                       "  point 30,\n"
284                       "  strand minus,\n"
285                       "  id gi 3\n"
286                       "}\n");
287     ++it;
288 
289     BOOST_CHECK(!it);
290 }
291 
292 
BOOST_AUTO_TEST_CASE(TestEdit1)293 BOOST_AUTO_TEST_CASE(TestEdit1)
294 {
295     CRef<CSeq_loc> loc =
296         MakeLoc("mix {"
297                 " int { from 10, to 20, strand plus, id gi 2 },"
298                 " pnt { point 30, strand minus, id gi 3}"
299                 "}");
300 
301     CSeq_loc_I it(*loc);
302     BOOST_CHECK(!it.HasEquivSets());
303 
304     BOOST_REQUIRE(it);
305     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(2));
306     BOOST_CHECK(it.GetSeq_id().IsGi());
307     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(10, 20));
308     BOOST_CHECK(it.IsSetStrand());
309     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
310     BOOST_CHECK(!it.IsWhole());
311     BOOST_CHECK(!it.IsEmpty());
312     BOOST_CHECK(!it.IsPoint());
313     BOOST_CHECK(!it.IsInEquivSet());
314     BOOST_CHECK(!it.IsInBond());
315     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
316                       "Seq-loc ::= int {\n"
317                       "  from 10,\n"
318                       "  to 20,\n"
319                       "  strand plus,\n"
320                       "  id gi 2\n"
321                       "}\n");
322     it.SetTo(10);
323     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
324                       "Seq-loc ::= int {\n"
325                       "  from 10,\n"
326                       "  to 10,\n"
327                       "  strand plus,\n"
328                       "  id gi 2\n"
329                       "}\n");
330     ++it;
331 
332     BOOST_REQUIRE(it);
333     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(3));
334     BOOST_CHECK(it.GetSeq_id().IsGi());
335     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(30, 30));
336     BOOST_CHECK(it.IsSetStrand());
337     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_minus));
338     BOOST_CHECK(!it.IsWhole());
339     BOOST_CHECK(!it.IsEmpty());
340     BOOST_CHECK(it.IsPoint());
341     BOOST_CHECK(!it.IsInEquivSet());
342     BOOST_CHECK(!it.IsInBond());
343     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
344                       "Seq-loc ::= pnt {\n"
345                       "  point 30,\n"
346                       "  strand minus,\n"
347                       "  id gi 3\n"
348                       "}\n");
349     it.SetSeq_id_Handle(CSeq_id_Handle::GetGiHandle(TIntId(2)));
350     it.SetStrand(eNa_strand_plus);
351     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
352                       "Seq-loc ::= pnt {\n"
353                       "  point 30,\n"
354                       "  strand plus,\n"
355                       "  id gi 2\n"
356                       "}\n");
357     ++it;
358 
359     BOOST_CHECK(!it);
360 
361     string loc2 = MakeASN(*it.MakeSeq_loc());
362     BOOST_CHECK_EQUAL(loc2,
363                       "Seq-loc ::= packed-pnt {\n"
364                       "  strand plus,\n"
365                       "  id gi 2,\n"
366                       "  points {\n"
367                       "    10,\n"
368                       "    30\n"
369                       "  }\n"
370                       "}\n");
371 }
372 
373 
BOOST_AUTO_TEST_CASE(TestEdit2)374 BOOST_AUTO_TEST_CASE(TestEdit2)
375 {
376     CRef<CSeq_loc> loc =
377         MakeLoc("mix {"
378                 " int { from 10, to 20, strand plus, id gi 2 },"
379                 " pnt { point 30, strand minus, id gi 3}"
380                 "}");
381 
382     CSeq_loc_I it(*loc);
383     BOOST_CHECK(!it.HasEquivSets());
384 
385     BOOST_REQUIRE(it);
386     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(2)));
387     BOOST_CHECK(it.GetSeq_id().IsGi());
388     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(10, 20));
389     BOOST_CHECK(it.IsSetStrand());
390     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
391     BOOST_CHECK(!it.IsWhole());
392     BOOST_CHECK(!it.IsEmpty());
393     BOOST_CHECK(!it.IsPoint());
394     BOOST_CHECK(!it.IsInEquivSet());
395     BOOST_CHECK(!it.IsInBond());
396     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
397                       "Seq-loc ::= int {\n"
398                       "  from 10,\n"
399                       "  to 20,\n"
400                       "  strand plus,\n"
401                       "  id gi 2\n"
402                       "}\n");
403     it.SetPoint(10);
404     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
405                       "Seq-loc ::= pnt {\n"
406                       "  point 10,\n"
407                       "  strand plus,\n"
408                       "  id gi 2\n"
409                       "}\n");
410     ++it;
411 
412     BOOST_REQUIRE(it);
413     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(3)));
414     BOOST_CHECK(it.GetSeq_id().IsGi());
415     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(30, 30));
416     BOOST_CHECK(it.IsSetStrand());
417     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_minus));
418     BOOST_CHECK(!it.IsWhole());
419     BOOST_CHECK(!it.IsEmpty());
420     BOOST_CHECK(it.IsPoint());
421     BOOST_CHECK(!it.IsInEquivSet());
422     BOOST_CHECK(!it.IsInBond());
423     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
424                       "Seq-loc ::= pnt {\n"
425                       "  point 30,\n"
426                       "  strand minus,\n"
427                       "  id gi 3\n"
428                       "}\n");
429     it.SetSeq_id_Handle(CSeq_id_Handle::GetGiHandle(TIntId(2)));
430     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
431                       "Seq-loc ::= pnt {\n"
432                       "  point 30,\n"
433                       "  strand minus,\n"
434                       "  id gi 2\n"
435                       "}\n");
436     ++it;
437 
438     BOOST_CHECK(!it);
439 
440     string loc2 = MakeASN(*it.MakeSeq_loc());
441     BOOST_CHECK_EQUAL(loc2,
442                       "Seq-loc ::= packed-int {\n"
443                       "  {\n"
444                       "    from 10,\n"
445                       "    to 10,\n"
446                       "    strand plus,\n"
447                       "    id gi 2\n"
448                       "  },\n"
449                       "  {\n"
450                       "    from 30,\n"
451                       "    to 30,\n"
452                       "    strand minus,\n"
453                       "    id gi 2\n"
454                       "  }\n"
455                       "}\n");
456 }
457 
458 
BOOST_AUTO_TEST_CASE(TestEdit3)459 BOOST_AUTO_TEST_CASE(TestEdit3)
460 {
461     CRef<CSeq_loc> loc =
462         MakeLoc("mix {"
463                 " int { from 10, to 20, strand plus, id gi 2 },"
464                 " pnt { point 30, strand minus, id gi 3}"
465                 "}");
466 
467     CSeq_loc_I it(*loc);
468     BOOST_CHECK(!it.HasEquivSets());
469 
470     BOOST_REQUIRE(it);
471     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(2)));
472     BOOST_CHECK(it.GetSeq_id().IsGi());
473     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(10, 20));
474     BOOST_CHECK(it.IsSetStrand());
475     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
476     BOOST_CHECK(!it.IsWhole());
477     BOOST_CHECK(!it.IsEmpty());
478     BOOST_CHECK(!it.IsPoint());
479     BOOST_CHECK(!it.IsInEquivSet());
480     BOOST_CHECK(!it.IsInBond());
481     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
482                       "Seq-loc ::= int {\n"
483                       "  from 10,\n"
484                       "  to 20,\n"
485                       "  strand plus,\n"
486                       "  id gi 2\n"
487                       "}\n");
488     it.SetTo(10);
489     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
490                       "Seq-loc ::= int {\n"
491                       "  from 10,\n"
492                       "  to 10,\n"
493                       "  strand plus,\n"
494                       "  id gi 2\n"
495                       "}\n");
496     ++it;
497 
498     BOOST_REQUIRE(it);
499     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(3)));
500     BOOST_CHECK(it.GetSeq_id().IsGi());
501     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(30, 30));
502     BOOST_CHECK(it.IsSetStrand());
503     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_minus));
504     BOOST_CHECK(!it.IsWhole());
505     BOOST_CHECK(!it.IsEmpty());
506     BOOST_CHECK(it.IsPoint());
507     BOOST_CHECK(!it.IsInEquivSet());
508     BOOST_CHECK(!it.IsInBond());
509     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
510                       "Seq-loc ::= pnt {\n"
511                       "  point 30,\n"
512                       "  strand minus,\n"
513                       "  id gi 3\n"
514                       "}\n");
515     it.SetSeq_id_Handle(CSeq_id_Handle::GetGiHandle(TIntId(2)));
516     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
517                       "Seq-loc ::= pnt {\n"
518                       "  point 30,\n"
519                       "  strand minus,\n"
520                       "  id gi 2\n"
521                       "}\n");
522     ++it;
523 
524     BOOST_CHECK(!it);
525 
526     string loc2 = MakeASN(*it.MakeSeq_loc(it.eMake_PreserveType));
527     BOOST_CHECK_EQUAL(loc2,
528                       "Seq-loc ::= mix {\n"
529                       "  int {\n"
530                       "    from 10,\n"
531                       "    to 10,\n"
532                       "    strand plus,\n"
533                       "    id gi 2\n"
534                       "  },\n"
535                       "  pnt {\n"
536                       "    point 30,\n"
537                       "    strand minus,\n"
538                       "    id gi 2\n"
539                       "  }\n"
540                       "}\n");
541 }
542 
543 
BOOST_AUTO_TEST_CASE(TestBond)544 BOOST_AUTO_TEST_CASE(TestBond)
545 {
546     CRef<CSeq_loc> loc =
547         MakeLoc("bond {"
548                 " a { point 10, strand plus, id gi 2 },"
549                 " b { point 30, strand minus, id gi 3}"
550                 "}");
551 
552     CSeq_loc_I it(*loc);
553     BOOST_CHECK(!it.HasEquivSets());
554 
555     BOOST_REQUIRE(it);
556     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(2)));
557     BOOST_CHECK(it.GetSeq_id().IsGi());
558     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(10, 10));
559     BOOST_CHECK(it.IsSetStrand());
560     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
561     BOOST_CHECK(!it.IsWhole());
562     BOOST_CHECK(!it.IsEmpty());
563     BOOST_CHECK(it.IsPoint());
564     BOOST_CHECK(!it.IsInEquivSet());
565     BOOST_CHECK(it.IsInBond());
566     BOOST_CHECK(it.IsBondA());
567     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
568                       "Seq-loc ::= pnt {\n"
569                       "  point 10,\n"
570                       "  strand plus,\n"
571                       "  id gi 2\n"
572                       "}\n");
573     ++it;
574 
575     BOOST_REQUIRE(it);
576     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(3)));
577     BOOST_CHECK(it.GetSeq_id().IsGi());
578     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(30, 30));
579     BOOST_CHECK(it.IsSetStrand());
580     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_minus));
581     BOOST_CHECK(!it.IsWhole());
582     BOOST_CHECK(!it.IsEmpty());
583     BOOST_CHECK(it.IsPoint());
584     BOOST_CHECK(!it.IsInEquivSet());
585     BOOST_CHECK(it.IsInBond());
586     BOOST_CHECK(it.IsBondB());
587     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
588                       "Seq-loc ::= pnt {\n"
589                       "  point 30,\n"
590                       "  strand minus,\n"
591                       "  id gi 3\n"
592                       "}\n");
593     ++it;
594 
595     BOOST_CHECK(!it);
596 
597     string loc2 = MakeASN(*it.MakeSeq_loc(it.eMake_PreserveType));
598     BOOST_CHECK_EQUAL(loc2,
599                       "Seq-loc ::= bond {\n"
600                       "  a {\n"
601                       "    point 10,\n"
602                       "    strand plus,\n"
603                       "    id gi 2\n"
604                       "  },\n"
605                       "  b {\n"
606                       "    point 30,\n"
607                       "    strand minus,\n"
608                       "    id gi 3\n"
609                       "  }\n"
610                       "}\n");
611 }
612 
613 
BOOST_AUTO_TEST_CASE(TestMakeBond)614 BOOST_AUTO_TEST_CASE(TestMakeBond)
615 {
616     CRef<CSeq_loc> loc =
617         MakeLoc("mix {"
618                 " pnt { point 10, strand plus, id gi 2 },"
619                 " pnt { point 30, strand minus, id gi 3},"
620                 " pnt { point 40, id gi 4}"
621                 "}");
622 
623     CSeq_loc_I it(*loc);
624     BOOST_CHECK(!it.HasEquivSets());
625 
626     BOOST_REQUIRE(it);
627     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(2)));
628     BOOST_CHECK(it.GetSeq_id().IsGi());
629     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(10, 10));
630     BOOST_CHECK(it.IsSetStrand());
631     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
632     BOOST_CHECK(!it.IsWhole());
633     BOOST_CHECK(!it.IsEmpty());
634     BOOST_CHECK(it.IsPoint());
635     BOOST_CHECK(!it.IsInEquivSet());
636     BOOST_CHECK(!it.IsInBond());
637     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
638                       "Seq-loc ::= pnt {\n"
639                       "  point 10,\n"
640                       "  strand plus,\n"
641                       "  id gi 2\n"
642                       "}\n");
643     ++it;
644 
645     BOOST_REQUIRE(it);
646     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(3)));
647     BOOST_CHECK(it.GetSeq_id().IsGi());
648     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(30, 30));
649     BOOST_CHECK(it.IsSetStrand());
650     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_minus));
651     BOOST_CHECK(!it.IsWhole());
652     BOOST_CHECK(!it.IsEmpty());
653     BOOST_CHECK(it.IsPoint());
654     BOOST_CHECK(!it.IsInEquivSet());
655     BOOST_CHECK(!it.IsInBond());
656     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
657                       "Seq-loc ::= pnt {\n"
658                       "  point 30,\n"
659                       "  strand minus,\n"
660                       "  id gi 3\n"
661                       "}\n");
662     ++it;
663 
664     BOOST_REQUIRE(it);
665     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(4)));
666     BOOST_CHECK(it.GetSeq_id().IsGi());
667     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(40, 40));
668     BOOST_CHECK(!it.IsSetStrand());
669     BOOST_CHECK(!it.IsWhole());
670     BOOST_CHECK(!it.IsEmpty());
671     BOOST_CHECK(it.IsPoint());
672     BOOST_CHECK(!it.IsInEquivSet());
673     BOOST_CHECK(!it.IsInBond());
674     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
675                       "Seq-loc ::= pnt {\n"
676                       "  point 40,\n"
677                       "  id gi 4\n"
678                       "}\n");
679     ++it;
680 
681     BOOST_CHECK(!it);
682 
683     it.SetPos(0);
684     it.MakeBondAB();
685     BOOST_REQUIRE(it);
686     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(2)));
687     BOOST_CHECK(it.GetSeq_id().IsGi());
688     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(10, 10));
689     BOOST_CHECK(it.IsSetStrand());
690     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
691     BOOST_CHECK(!it.IsWhole());
692     BOOST_CHECK(!it.IsEmpty());
693     BOOST_CHECK(it.IsPoint());
694     BOOST_CHECK(!it.IsInEquivSet());
695     BOOST_CHECK(it.IsInBond());
696     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
697                       "Seq-loc ::= pnt {\n"
698                       "  point 10,\n"
699                       "  strand plus,\n"
700                       "  id gi 2\n"
701                       "}\n");
702     ++it;
703 
704     BOOST_REQUIRE(it);
705     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(3)));
706     BOOST_CHECK(it.GetSeq_id().IsGi());
707     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(30, 30));
708     BOOST_CHECK(it.IsSetStrand());
709     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_minus));
710     BOOST_CHECK(!it.IsWhole());
711     BOOST_CHECK(!it.IsEmpty());
712     BOOST_CHECK(it.IsPoint());
713     BOOST_CHECK(!it.IsInEquivSet());
714     BOOST_CHECK(it.IsInBond());
715     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
716                       "Seq-loc ::= pnt {\n"
717                       "  point 30,\n"
718                       "  strand minus,\n"
719                       "  id gi 3\n"
720                       "}\n");
721     ++it;
722 
723     BOOST_REQUIRE(it);
724     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(4)));
725     BOOST_CHECK(it.GetSeq_id().IsGi());
726     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(40, 40));
727     BOOST_CHECK(!it.IsSetStrand());
728     BOOST_CHECK(!it.IsWhole());
729     BOOST_CHECK(!it.IsEmpty());
730     BOOST_CHECK(it.IsPoint());
731     BOOST_CHECK(!it.IsInEquivSet());
732     BOOST_CHECK(!it.IsInBond());
733     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
734                       "Seq-loc ::= pnt {\n"
735                       "  point 40,\n"
736                       "  id gi 4\n"
737                       "}\n");
738     ++it;
739 
740     BOOST_CHECK(!it);
741 
742     string loc2 = MakeASN(*it.MakeSeq_loc(it.eMake_PreserveType));
743     BOOST_CHECK_EQUAL(loc2,
744                       "Seq-loc ::= mix {\n"
745                       "  bond {\n"
746                       "    a {\n"
747                       "      point 10,\n"
748                       "      strand plus,\n"
749                       "      id gi 2\n"
750                       "    },\n"
751                       "    b {\n"
752                       "      point 30,\n"
753                       "      strand minus,\n"
754                       "      id gi 3\n"
755                       "    }\n"
756                       "  },\n"
757                       "  pnt {\n"
758                       "    point 40,\n"
759                       "    id gi 4\n"
760                       "  }\n"
761                       "}\n");
762 
763     it.SetPos(0);
764     it.RemoveBond();
765     BOOST_REQUIRE(it);
766     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(2)));
767     BOOST_CHECK(it.GetSeq_id().IsGi());
768     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(10, 10));
769     BOOST_CHECK(it.IsSetStrand());
770     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
771     BOOST_CHECK(!it.IsWhole());
772     BOOST_CHECK(!it.IsEmpty());
773     BOOST_CHECK(it.IsPoint());
774     BOOST_CHECK(!it.IsInEquivSet());
775     BOOST_CHECK(!it.IsInBond());
776     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
777                       "Seq-loc ::= pnt {\n"
778                       "  point 10,\n"
779                       "  strand plus,\n"
780                       "  id gi 2\n"
781                       "}\n");
782     ++it;
783 
784     BOOST_REQUIRE(it);
785     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(3)));
786     BOOST_CHECK(it.GetSeq_id().IsGi());
787     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(30, 30));
788     BOOST_CHECK(it.IsSetStrand());
789     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_minus));
790     BOOST_CHECK(!it.IsWhole());
791     BOOST_CHECK(!it.IsEmpty());
792     BOOST_CHECK(it.IsPoint());
793     BOOST_CHECK(!it.IsInEquivSet());
794     BOOST_CHECK(!it.IsInBond());
795     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
796                       "Seq-loc ::= pnt {\n"
797                       "  point 30,\n"
798                       "  strand minus,\n"
799                       "  id gi 3\n"
800                       "}\n");
801     ++it;
802 
803     BOOST_REQUIRE(it);
804     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(4)));
805     BOOST_CHECK(it.GetSeq_id().IsGi());
806     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(40, 40));
807     BOOST_CHECK(!it.IsSetStrand());
808     BOOST_CHECK(!it.IsWhole());
809     BOOST_CHECK(!it.IsEmpty());
810     BOOST_CHECK(it.IsPoint());
811     BOOST_CHECK(!it.IsInEquivSet());
812     BOOST_CHECK(!it.IsInBond());
813     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
814                       "Seq-loc ::= pnt {\n"
815                       "  point 40,\n"
816                       "  id gi 4\n"
817                       "}\n");
818     ++it;
819 
820     BOOST_CHECK(!it);
821 
822     loc2 = MakeASN(*it.MakeSeq_loc(it.eMake_PreserveType));
823     BOOST_CHECK_EQUAL(loc2,
824                       "Seq-loc ::= mix {\n"
825                       "  pnt {\n"
826                       "    point 10,\n"
827                       "    strand plus,\n"
828                       "    id gi 2\n"
829                       "  },\n"
830                       "  pnt {\n"
831                       "    point 30,\n"
832                       "    strand minus,\n"
833                       "    id gi 3\n"
834                       "  },\n"
835                       "  pnt {\n"
836                       "    point 40,\n"
837                       "    id gi 4\n"
838                       "  }\n"
839                       "}\n");
840 }
841 
842 
BOOST_AUTO_TEST_CASE(TestMakeEquiv1)843 BOOST_AUTO_TEST_CASE(TestMakeEquiv1)
844 {
845     CRef<CSeq_loc> loc =
846         MakeLoc("mix {"
847                 " int { from 10, to 20, strand plus, id gi 2 },"
848                 " equiv {"
849                 "  int { from 25, to 27, strand plus, id gi 2 },"
850                 "  mix {"
851                 "   int { from 25, to 26, strand plus, id gi 2 },"
852                 "   int { from 27, to 27, strand minus, id gi 2 }"
853                 "  }"
854                 " },"
855                 " pnt { point 30, strand minus, id gi 3}"
856                 "}");
857 
858     CSeq_loc_I it(*loc);
859     BOOST_CHECK(it.HasEquivSets());
860 
861     BOOST_REQUIRE(it);
862     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(2)));
863     BOOST_CHECK(it.GetSeq_id().IsGi());
864     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(10, 20));
865     BOOST_CHECK(it.IsSetStrand());
866     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
867     BOOST_CHECK(!it.IsWhole());
868     BOOST_CHECK(!it.IsEmpty());
869     BOOST_CHECK(!it.IsPoint());
870     BOOST_CHECK(!it.IsInEquivSet());
871     BOOST_CHECK(!it.IsInBond());
872     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
873                       "Seq-loc ::= int {\n"
874                       "  from 10,\n"
875                       "  to 20,\n"
876                       "  strand plus,\n"
877                       "  id gi 2\n"
878                       "}\n");
879     ++it;
880 
881     BOOST_REQUIRE(it);
882     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(2)));
883     BOOST_CHECK(it.GetSeq_id().IsGi());
884     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(25, 27));
885     BOOST_CHECK(it.IsSetStrand());
886     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
887     BOOST_CHECK(!it.IsWhole());
888     BOOST_CHECK(!it.IsEmpty());
889     BOOST_CHECK(!it.IsPoint());
890     BOOST_CHECK(it.IsInEquivSet());
891     BOOST_CHECK(!it.IsInBond());
892     BOOST_CHECK_EQUAL(it.GetEquivSetsCount(), 1u);
893     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).first.GetPos(), 1u);
894     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).second.GetPos(), 4u);
895     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).first.GetPos(), 1u);
896     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).second.GetPos(), 2u);
897     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
898                       "Seq-loc ::= int {\n"
899                       "  from 25,\n"
900                       "  to 27,\n"
901                       "  strand plus,\n"
902                       "  id gi 2\n"
903                       "}\n");
904     ++it;
905 
906     BOOST_REQUIRE(it);
907     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(2)));
908     BOOST_CHECK(it.GetSeq_id().IsGi());
909     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(25, 26));
910     BOOST_CHECK(it.IsSetStrand());
911     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
912     BOOST_CHECK(!it.IsWhole());
913     BOOST_CHECK(!it.IsEmpty());
914     BOOST_CHECK(!it.IsPoint());
915     BOOST_CHECK(it.IsInEquivSet());
916     BOOST_CHECK(!it.IsInBond());
917     BOOST_CHECK_EQUAL(it.GetEquivSetsCount(), 1u);
918     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).first.GetPos(), 1u);
919     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).second.GetPos(), 4u);
920     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).first.GetPos(), 2u);
921     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).second.GetPos(), 4u);
922     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
923                       "Seq-loc ::= int {\n"
924                       "  from 25,\n"
925                       "  to 26,\n"
926                       "  strand plus,\n"
927                       "  id gi 2\n"
928                       "}\n");
929     ++it;
930 
931     BOOST_REQUIRE(it);
932     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(2)));
933     BOOST_CHECK(it.GetSeq_id().IsGi());
934     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(27, 27));
935     BOOST_CHECK(it.IsSetStrand());
936     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_minus));
937     BOOST_CHECK(!it.IsWhole());
938     BOOST_CHECK(!it.IsEmpty());
939     BOOST_CHECK(it.IsPoint());
940     BOOST_CHECK(it.IsInEquivSet());
941     BOOST_CHECK(!it.IsInBond());
942     BOOST_CHECK_EQUAL(it.GetEquivSetsCount(), 1u);
943     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).first.GetPos(), 1u);
944     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).second.GetPos(), 4u);
945     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).first.GetPos(), 2u);
946     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).second.GetPos(), 4u);
947     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
948                       "Seq-loc ::= int {\n"
949                       "  from 27,\n"
950                       "  to 27,\n"
951                       "  strand minus,\n"
952                       "  id gi 2\n"
953                       "}\n");
954     ++it;
955 
956     BOOST_REQUIRE(it);
957     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(3)));
958     BOOST_CHECK(it.GetSeq_id().IsGi());
959     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(30, 30));
960     BOOST_CHECK(it.IsSetStrand());
961     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_minus));
962     BOOST_CHECK(!it.IsWhole());
963     BOOST_CHECK(!it.IsEmpty());
964     BOOST_CHECK(it.IsPoint());
965     BOOST_CHECK(!it.IsInEquivSet());
966     BOOST_CHECK(!it.IsInBond());
967     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
968                       "Seq-loc ::= pnt {\n"
969                       "  point 30,\n"
970                       "  strand minus,\n"
971                       "  id gi 3\n"
972                       "}\n");
973     ++it;
974 
975     BOOST_CHECK(!it);
976 
977     string loc2 = MakeASN(*it.MakeSeq_loc(CSeq_loc_I::eMake_PreserveType));
978     BOOST_CHECK_EQUAL(loc2,
979                       "Seq-loc ::= mix {\n"
980                       "  int {\n"
981                       "    from 10,\n"
982                       "    to 20,\n"
983                       "    strand plus,\n"
984                       "    id gi 2\n"
985                       "  },\n"
986                       "  equiv {\n"
987                       "    int {\n"
988                       "      from 25,\n"
989                       "      to 27,\n"
990                       "      strand plus,\n"
991                       "      id gi 2\n"
992                       "    },\n"
993                       "    mix {\n"
994                       "      int {\n"
995                       "        from 25,\n"
996                       "        to 26,\n"
997                       "        strand plus,\n"
998                       "        id gi 2\n"
999                       "      },\n"
1000                       "      int {\n"
1001                       "        from 27,\n"
1002                       "        to 27,\n"
1003                       "        strand minus,\n"
1004                       "        id gi 2\n"
1005                       "      }\n"
1006                       "    }\n"
1007                       "  },\n"
1008                       "  pnt {\n"
1009                       "    point 30,\n"
1010                       "    strand minus,\n"
1011                       "    id gi 3\n"
1012                       "  }\n"
1013                       "}\n");
1014     loc2 = MakeASN(*it.MakeSeq_loc(CSeq_loc_I::eMake_CompactType));
1015     BOOST_CHECK_EQUAL(loc2,
1016                       "Seq-loc ::= mix {\n"
1017                       "  int {\n"
1018                       "    from 10,\n"
1019                       "    to 20,\n"
1020                       "    strand plus,\n"
1021                       "    id gi 2\n"
1022                       "  },\n"
1023                       "  equiv {\n"
1024                       "    int {\n"
1025                       "      from 25,\n"
1026                       "      to 27,\n"
1027                       "      strand plus,\n"
1028                       "      id gi 2\n"
1029                       "    },\n"
1030                       "    packed-int {\n"
1031                       "      {\n"
1032                       "        from 25,\n"
1033                       "        to 26,\n"
1034                       "        strand plus,\n"
1035                       "        id gi 2\n"
1036                       "      },\n"
1037                       "      {\n"
1038                       "        from 27,\n"
1039                       "        to 27,\n"
1040                       "        strand minus,\n"
1041                       "        id gi 2\n"
1042                       "      }\n"
1043                       "    }\n"
1044                       "  },\n"
1045                       "  pnt {\n"
1046                       "    point 30,\n"
1047                       "    strand minus,\n"
1048                       "    id gi 3\n"
1049                       "  }\n"
1050                       "}\n");
1051 }
1052 
1053 
BOOST_AUTO_TEST_CASE(TestMakeEquiv2)1054 BOOST_AUTO_TEST_CASE(TestMakeEquiv2)
1055 {
1056     CRef<CSeq_loc> loc =
1057         MakeLoc("equiv {"
1058                 " equiv {"
1059                 "  int { from 25, to 27, strand plus, id gi 2 },"
1060                 "  mix {"
1061                 "   int { from 25, to 26, strand plus, id gi 2 },"
1062                 "   int { from 27, to 27, strand minus, id gi 2 }"
1063                 "  }"
1064                 " }"
1065                 "}");
1066 
1067     CSeq_loc_I it(*loc);
1068     BOOST_CHECK(it.HasEquivSets());
1069 
1070     BOOST_REQUIRE(it);
1071     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(2)));
1072     BOOST_CHECK(it.GetSeq_id().IsGi());
1073     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(25, 27));
1074     BOOST_CHECK(it.IsSetStrand());
1075     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
1076     BOOST_CHECK(!it.IsWhole());
1077     BOOST_CHECK(!it.IsEmpty());
1078     BOOST_CHECK(!it.IsPoint());
1079     BOOST_CHECK(it.IsInEquivSet());
1080     BOOST_CHECK(!it.IsInBond());
1081     BOOST_CHECK_EQUAL(it.GetEquivSetsCount(), 2u);
1082     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).first.GetPos(), 0u);
1083     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).second.GetPos(), 3u);
1084     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).first.GetPos(), 0u);
1085     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).second.GetPos(), 1u);
1086     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
1087                       "Seq-loc ::= int {\n"
1088                       "  from 25,\n"
1089                       "  to 27,\n"
1090                       "  strand plus,\n"
1091                       "  id gi 2\n"
1092                       "}\n");
1093     ++it;
1094 
1095     BOOST_REQUIRE(it);
1096     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(2)));
1097     BOOST_CHECK(it.GetSeq_id().IsGi());
1098     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(25, 26));
1099     BOOST_CHECK(it.IsSetStrand());
1100     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_plus));
1101     BOOST_CHECK(!it.IsWhole());
1102     BOOST_CHECK(!it.IsEmpty());
1103     BOOST_CHECK(!it.IsPoint());
1104     BOOST_CHECK(it.IsInEquivSet());
1105     BOOST_CHECK(!it.IsInBond());
1106     BOOST_CHECK_EQUAL(it.GetEquivSetsCount(), 2u);
1107     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).first.GetPos(), 0u);
1108     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).second.GetPos(), 3u);
1109     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).first.GetPos(), 1u);
1110     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).second.GetPos(), 3u);
1111     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
1112                       "Seq-loc ::= int {\n"
1113                       "  from 25,\n"
1114                       "  to 26,\n"
1115                       "  strand plus,\n"
1116                       "  id gi 2\n"
1117                       "}\n");
1118     ++it;
1119 
1120     BOOST_REQUIRE(it);
1121     BOOST_CHECK_EQUAL(it.GetSeq_id_Handle(), CSeq_id_Handle::GetGiHandle(TIntId(2)));
1122     BOOST_CHECK(it.GetSeq_id().IsGi());
1123     BOOST_CHECK_EQUAL(it.GetRange(), CRange<TSeqPos>(27, 27));
1124     BOOST_CHECK(it.IsSetStrand());
1125     BOOST_CHECK_EQUAL(int(it.GetStrand()), int(eNa_strand_minus));
1126     BOOST_CHECK(!it.IsWhole());
1127     BOOST_CHECK(!it.IsEmpty());
1128     BOOST_CHECK(it.IsPoint());
1129     BOOST_CHECK(it.IsInEquivSet());
1130     BOOST_CHECK(!it.IsInBond());
1131     BOOST_CHECK_EQUAL(it.GetEquivSetsCount(), 2u);
1132     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).first.GetPos(), 0u);
1133     BOOST_CHECK_EQUAL(it.GetEquivSetRange(0).second.GetPos(), 3u);
1134     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).first.GetPos(), 1u);
1135     BOOST_CHECK_EQUAL(it.GetEquivPartRange(0).second.GetPos(), 3u);
1136     BOOST_CHECK_EQUAL(MakeASN(*it.GetRangeAsSeq_loc()),
1137                       "Seq-loc ::= int {\n"
1138                       "  from 27,\n"
1139                       "  to 27,\n"
1140                       "  strand minus,\n"
1141                       "  id gi 2\n"
1142                       "}\n");
1143     ++it;
1144 
1145     BOOST_CHECK(!it);
1146 
1147     string loc2 = MakeASN(*it.MakeSeq_loc(CSeq_loc_I::eMake_PreserveType));
1148     BOOST_CHECK_EQUAL(loc2,
1149                       "Seq-loc ::= equiv {\n"
1150                       "  equiv {\n"
1151                       "    int {\n"
1152                       "      from 25,\n"
1153                       "      to 27,\n"
1154                       "      strand plus,\n"
1155                       "      id gi 2\n"
1156                       "    },\n"
1157                       "    mix {\n"
1158                       "      int {\n"
1159                       "        from 25,\n"
1160                       "        to 26,\n"
1161                       "        strand plus,\n"
1162                       "        id gi 2\n"
1163                       "      },\n"
1164                       "      int {\n"
1165                       "        from 27,\n"
1166                       "        to 27,\n"
1167                       "        strand minus,\n"
1168                       "        id gi 2\n"
1169                       "      }\n"
1170                       "    }\n"
1171                       "  }\n"
1172                       "}\n");
1173 }
1174 
1175 
BOOST_AUTO_TEST_CASE(TestMakeEquiv3)1176 BOOST_AUTO_TEST_CASE(TestMakeEquiv3)
1177 {
1178     CRef<CSeq_loc> loc =
1179         MakeLoc("equiv {"
1180                 " equiv {"
1181                 " }"
1182                 "}");
1183     // empty equiv is omitted
1184 
1185     CSeq_loc_I it(*loc);
1186     BOOST_CHECK(!it.HasEquivSets());
1187 
1188     BOOST_CHECK(!it);
1189 
1190     string loc2 = MakeASN(*it.MakeSeq_loc(CSeq_loc_I::eMake_PreserveType));
1191     BOOST_CHECK_EQUAL(loc2,
1192                       "Seq-loc ::= mix {\n"
1193                       "}\n");
1194 }
1195 
1196 
BOOST_AUTO_TEST_CASE(TestMakeEquiv4)1197 BOOST_AUTO_TEST_CASE(TestMakeEquiv4)
1198 {
1199     CRef<CSeq_loc> loc =
1200         MakeLoc("equiv {"
1201                 " equiv {"
1202                 "   mix {"
1203                 "   }"
1204                 " }"
1205                 "}");
1206     // empty equiv is omitted
1207 
1208     CSeq_loc_I it(*loc);
1209     BOOST_CHECK(!it.HasEquivSets());
1210 
1211     BOOST_CHECK(!it);
1212 
1213     string loc2 = MakeASN(*it.MakeSeq_loc(CSeq_loc_I::eMake_PreserveType));
1214     BOOST_CHECK_EQUAL(loc2,
1215                       "Seq-loc ::= mix {\n"
1216                       "}\n");
1217 }
1218 
1219 
BOOST_AUTO_TEST_CASE(TestMakeEquiv5)1220 BOOST_AUTO_TEST_CASE(TestMakeEquiv5)
1221 {
1222     CRef<CSeq_loc> loc =
1223         MakeLoc("equiv {"
1224                 " equiv {"
1225                 "   mix {"
1226                 "   },"
1227                 "   mix {"
1228                 "   }"
1229                 " }"
1230                 "}");
1231     // empty parts and empty equivs are omitted
1232 
1233     CSeq_loc_I it(*loc);
1234     BOOST_CHECK(!it.HasEquivSets());
1235 
1236     BOOST_CHECK(!it);
1237 
1238     string loc2 = MakeASN(*it.MakeSeq_loc(CSeq_loc_I::eMake_PreserveType));
1239     BOOST_CHECK_EQUAL(loc2,
1240                       "Seq-loc ::= mix {\n"
1241                       "}\n");
1242 }
1243 
1244 
BOOST_AUTO_TEST_CASE(TestMakeEquiv6)1245 BOOST_AUTO_TEST_CASE(TestMakeEquiv6)
1246 {
1247     CRef<CSeq_loc> loc =
1248         MakeLoc("equiv {"
1249                 " equiv {"
1250                 "   mix {"
1251                 "   }"
1252                 " },"
1253                 " mix {"
1254                 " }"
1255                 "}");
1256     // empty parts and empty equivs are omitted
1257 
1258     CSeq_loc_I it(*loc);
1259     BOOST_CHECK(!it.HasEquivSets());
1260 
1261     BOOST_CHECK(!it);
1262 
1263     string loc2 = MakeASN(*it.MakeSeq_loc(CSeq_loc_I::eMake_PreserveType));
1264     BOOST_CHECK_EQUAL(loc2,
1265                       "Seq-loc ::= mix {\n"
1266                       "}\n");
1267 }
1268 
1269 
BOOST_AUTO_TEST_CASE(TestMakeEquiv7)1270 BOOST_AUTO_TEST_CASE(TestMakeEquiv7)
1271 {
1272     CRef<CSeq_loc> loc =
1273         MakeLoc("equiv {"
1274                 " equiv {"
1275                 "   mix {"
1276                 "   }"
1277                 " },"
1278                 " mix {"
1279                 " }"
1280                 "}");
1281     // empty parts and empty equivs are omitted
1282 
1283     CSeq_loc_I it(*loc);
1284     BOOST_CHECK(!it.HasEquivSets());
1285 
1286     BOOST_CHECK(!it);
1287 
1288     string loc2 = MakeASN(*it.MakeSeq_loc(CSeq_loc_I::eMake_PreserveType));
1289     BOOST_CHECK_EQUAL(loc2,
1290                       "Seq-loc ::= mix {\n"
1291                       "}\n");
1292 
1293     it.SetEquivMode(it.eEquiv_new_equiv);
1294     it.InsertInterval(CSeq_id_Handle::GetGiHandle(TIntId(10)), 100, 200);
1295     it.SetEquivMode(it.eEquiv_new_part);
1296     it.InsertInterval(CSeq_id_Handle::GetGiHandle(TIntId(10)), 100, 149);
1297     it.InsertInterval(CSeq_id_Handle::GetGiHandle(TIntId(10)), 150, 200, eNa_strand_minus);
1298 
1299     loc2 = MakeASN(*it.MakeSeq_loc(CSeq_loc_I::eMake_PreserveType));
1300     BOOST_CHECK_EQUAL(loc2,
1301                       "Seq-loc ::= equiv {\n"
1302                       "  int {\n"
1303                       "    from 100,\n"
1304                       "    to 200,\n"
1305                       "    id gi 10\n"
1306                       "  },\n"
1307                       "  mix {\n"
1308                       "    int {\n"
1309                       "      from 100,\n"
1310                       "      to 149,\n"
1311                       "      id gi 10\n"
1312                       "    },\n"
1313                       "    int {\n"
1314                       "      from 150,\n"
1315                       "      to 200,\n"
1316                       "      strand minus,\n"
1317                       "      id gi 10\n"
1318                       "    }\n"
1319                       "  }\n"
1320                       "}\n");
1321 
1322     it.SetEquivMode(it.eEquiv_none);
1323     it.InsertInterval(CSeq_id_Handle::GetGiHandle(TIntId(10)), 201, 300, eNa_strand_plus);
1324 
1325     loc2 = MakeASN(*it.MakeSeq_loc(CSeq_loc_I::eMake_PreserveType));
1326     BOOST_CHECK_EQUAL(loc2,
1327                       "Seq-loc ::= mix {\n"
1328                       "  equiv {\n"
1329                       "    int {\n"
1330                       "      from 100,\n"
1331                       "      to 200,\n"
1332                       "      id gi 10\n"
1333                       "    },\n"
1334                       "    mix {\n"
1335                       "      int {\n"
1336                       "        from 100,\n"
1337                       "        to 149,\n"
1338                       "        id gi 10\n"
1339                       "      },\n"
1340                       "      int {\n"
1341                       "        from 150,\n"
1342                       "        to 200,\n"
1343                       "        strand minus,\n"
1344                       "        id gi 10\n"
1345                       "      }\n"
1346                       "    }\n"
1347                       "  },\n"
1348                       "  int {\n"
1349                       "    from 201,\n"
1350                       "    to 300,\n"
1351                       "    strand plus,\n"
1352                       "    id gi 10\n"
1353                       "  }\n"
1354                       "}\n");
1355 }
1356 
1357 
1358 #ifdef NCBI_THREADS
1359 
1360 typedef vector< CRef<CSeq_loc> > TSeqLocs;
1361 
1362 DEFINE_STATIC_MUTEX(s_BoostMutex);
1363 
1364 class CTotalRangeThread : public CThread
1365 {
1366 public:
CTotalRangeThread(const TSeqLocs & locs,CAtomicCounter & start_counter)1367     CTotalRangeThread(const TSeqLocs& locs, CAtomicCounter& start_counter)
1368         : m_Locs(locs), m_StartCounter(start_counter)
1369         {
1370         }
1371 
x_CheckPoint(CSeq_loc::TRange range,TSeqPos point)1372     static void x_CheckPoint(CSeq_loc::TRange range, TSeqPos point)
1373         {
1374             if ( range.GetFrom() != point || range.GetTo() != point ) {
1375                 CMutexGuard guard(s_BoostMutex);
1376                 BOOST_REQUIRE_EQUAL(range, CSeq_loc::TRange(point, point));
1377             }
1378         }
1379 
Main(void)1380     virtual void* Main(void)
1381         {
1382             m_StartCounter.Add(-1);
1383             // wait for all threads to start
1384             while ( m_StartCounter.Get() != 0 ) {
1385             }
1386 
1387             const size_t LCOUNT = m_Locs.size();
1388             for ( TSeqPos i = 0; i < LCOUNT; ++i ) {
1389                 x_CheckPoint(m_Locs[i]->GetTotalRange(), i);
1390             }
1391             for ( TSeqPos i = 0; i < LCOUNT; ++i ) {
1392                 x_CheckPoint(m_Locs[i]->GetTotalRange(), i);
1393             }
1394             return 0;
1395         }
1396 
1397 private:
1398     const TSeqLocs& m_Locs;
1399     CAtomicCounter& m_StartCounter;
1400 };
1401 
BOOST_AUTO_TEST_CASE(TestTotalRange)1402 BOOST_AUTO_TEST_CASE(TestTotalRange)
1403 {
1404     const int LCOUNT = 1000000;
1405     const int TCOUNT = 4;
1406 
1407     CRandom rnd(1);
1408     TSeqLocs ll;
1409     CRef<CSeq_id> id(new CSeq_id("1"));
1410     for ( int i = 0; i < LCOUNT; ++i ) {
1411         CRef<CSeq_loc> loc(new CSeq_loc);
1412         if ( rnd.GetRand(0, 2) > 0 ) {
1413             loc->SetPnt().SetPoint(i);
1414         }
1415         else {
1416             loc->SetInt().SetFrom(i);
1417             loc->SetInt().SetTo(i);
1418         }
1419         loc->SetId(*id);
1420         ll.push_back(loc);
1421     }
1422 
1423     CAtomicCounter start_counter;
1424     start_counter.Set(TCOUNT);
1425 
1426     vector< CRef<CThread> > tt(TCOUNT);
1427     for ( int i = 0; i < TCOUNT; ++i ) {
1428         tt[i] = new CTotalRangeThread(ll, start_counter);
1429         tt[i]->Run();
1430     }
1431     for ( int i = 0; i < TCOUNT; ++i ) {
1432         void* exit_data;
1433         tt[i]->Join(&exit_data);
1434     }
1435 }
1436 #endif
1437