1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4  * http://ugene.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  */
21 
22 #include "MsaObjectUnitTests.h"
23 
24 #include <U2Core/AppContext.h>
25 #include <U2Core/DNAAlphabet.h>
26 #include <U2Core/MultipleSequenceAlignmentExporter.h>
27 #include <U2Core/MultipleSequenceAlignmentImporter.h>
28 #include <U2Core/MultipleSequenceAlignmentObject.h>
29 #include <U2Core/U2MsaDbi.h>
30 #include <U2Core/U2ObjectDbi.h>
31 #include <U2Core/U2OpStatusUtils.h>
32 
33 namespace U2 {
34 
35 TestDbiProvider MsaObjectTestData::dbiProvider = TestDbiProvider();
36 const QString &MsaObjectTestData::MAL_OBJ_DB_URL("malignment-object-dbi.ugenedb");
37 U2DbiRef MsaObjectTestData::dbiRef = U2DbiRef();
38 
init()39 void MsaObjectTestData::init() {
40     bool ok = dbiProvider.init(MAL_OBJ_DB_URL, false);
41     SAFE_POINT(ok, "Dbi provider failed to initialize in MsaObjectTestData::init()!", );
42 
43     U2Dbi *dbi = dbiProvider.getDbi();
44     dbiRef = dbi->getDbiRef();
45     dbiProvider.close();
46 }
47 
shutdown()48 void MsaObjectTestData::shutdown() {
49     if (dbiRef != U2DbiRef()) {
50         U2OpStatusImpl opStatus;
51         dbiRef = U2DbiRef();
52         dbiProvider.close();
53         SAFE_POINT_OP(opStatus, );
54     }
55 }
56 
getDbiRef()57 U2DbiRef MsaObjectTestData::getDbiRef() {
58     if (dbiRef == U2DbiRef()) {
59         init();
60     }
61     return dbiRef;
62 }
63 
getTestAlignmentObject(const U2DbiRef & dbiRef,const QString & name,U2OpStatus & os)64 MultipleSequenceAlignmentObject *MsaObjectTestData::getTestAlignmentObject(const U2DbiRef &dbiRef, const QString &name, U2OpStatus &os) {
65     const U2EntityRef entityRef = getTestAlignmentRef(dbiRef, name, os);
66     CHECK_OP(os, nullptr);
67 
68     return new MultipleSequenceAlignmentObject(name, entityRef);
69 }
70 
getTestAlignmentRef(const U2DbiRef & dbiRef,const QString & name,U2OpStatus & os)71 U2EntityRef MsaObjectTestData::getTestAlignmentRef(const U2DbiRef &dbiRef, const QString &name, U2OpStatus &os) {
72     DbiConnection con(dbiRef, os);
73     CHECK_OP(os, U2EntityRef());
74 
75     QScopedPointer<U2DbiIterator<U2DataId>> it(con.dbi->getObjectDbi()->getObjectsByVisualName(name, U2Type::Msa, os));
76     CHECK_OP(os, U2EntityRef());
77 
78     CHECK_EXT(it->hasNext(), os.setError(QString("Malignment object '%1' wasn't found in the database").arg(name)), U2EntityRef());
79     const U2DataId msaId = it->next();
80     CHECK_EXT(!msaId.isEmpty(), os.setError(QString("Malignment object '%1' wasn't found in the database").arg(name)), U2EntityRef());
81 
82     return U2EntityRef(dbiRef, msaId);
83 }
84 
getTestAlignment(const U2DbiRef & dbiRef,const QString & name,U2OpStatus & os)85 MultipleSequenceAlignment MsaObjectTestData::getTestAlignment(const U2DbiRef &dbiRef, const QString &name, U2OpStatus &os) {
86     U2EntityRef malignmentRef = getTestAlignmentRef(dbiRef, name, os);
87     CHECK_OP(os, MultipleSequenceAlignment());
88 
89     MultipleSequenceAlignmentExporter exporter;
90     return exporter.getAlignment(dbiRef, malignmentRef.entityId, os);
91 }
92 
IMPLEMENT_TEST(MsaObjectUnitTests,getMAlignment)93 IMPLEMENT_TEST(MsaObjectUnitTests, getMAlignment) {
94     //  Test data:
95     //  ---AG-T
96     //  AG-CT-TAA
97 
98     const QString alName = "Test alignment";
99     const U2DbiRef dbiRef = MsaObjectTestData::getDbiRef();
100     U2OpStatusImpl os;
101 
102     QScopedPointer<MultipleSequenceAlignmentObject> alObj(MsaObjectTestData::getTestAlignmentObject(dbiRef, alName, os));
103     CHECK_NO_ERROR(os);
104 
105     const MultipleSequenceAlignment alActual = alObj->getMultipleAlignment();
106 
107     const bool alsEqual = (*alActual == *MsaObjectTestData::getTestAlignment(dbiRef, alName, os));
108     CHECK_TRUE(alsEqual, "Actual alignment doesn't equal to the original!");
109     CHECK_EQUAL(alName, alActual->getName(), "alignment name");
110 }
111 
IMPLEMENT_TEST(MsaObjectUnitTests,setMAlignment)112 IMPLEMENT_TEST(MsaObjectUnitTests, setMAlignment) {
113     //  Test data, alignment 1:
114     //  ---AG-T
115     //  AG-CT-TAA
116 
117     //  alignment 2:
118     //  AC-GT--AAA
119     //  -ACACA-GT
120 
121     const QString firstAlignmentName = "Test alignment";
122     const QString secondAlignmentName = "Test alignment 2";
123     const U2DbiRef dbiRef = MsaObjectTestData::getDbiRef();
124     U2OpStatusImpl os;
125 
126     QScopedPointer<MultipleSequenceAlignmentObject> alObj(MsaObjectTestData::getTestAlignmentObject(dbiRef, firstAlignmentName, os));
127     CHECK_NO_ERROR(os);
128 
129     const MultipleSequenceAlignment secondAlignment = MsaObjectTestData::getTestAlignment(dbiRef, secondAlignmentName, os);
130     alObj->setMultipleAlignment(secondAlignment);
131     const MultipleSequenceAlignment actualAlignment = alObj->getMultipleAlignment();
132 
133     bool alsEqual = (*secondAlignment == *actualAlignment);
134     CHECK_TRUE(alsEqual, "Actual alignment doesn't equal to the original!");
135     CHECK_EQUAL(secondAlignmentName, actualAlignment->getName(), "alignment name");
136 }
137 
IMPLEMENT_TEST(MsaObjectUnitTests,deleteGap_trailingGaps)138 IMPLEMENT_TEST(MsaObjectUnitTests, deleteGap_trailingGaps) {
139     //  Test data:
140     //  AC-GT--AAA----
141     //  -ACA---GTT----
142     //  -ACACA-G------
143 
144     //  Expected result: the same
145 
146     const QString malignment = "Alignment with trailing gaps";
147     const U2DbiRef dbiRef = MsaObjectTestData::getDbiRef();
148     U2OpStatusImpl os;
149 
150     QScopedPointer<MultipleSequenceAlignmentObject> alnObj(MsaObjectTestData::getTestAlignmentObject(dbiRef, malignment, os));
151     CHECK_NO_ERROR(os);
152 
153     alnObj->deleteGap(os, U2Region(0, alnObj->getNumRows()), 10, 3);
154 
155     const MultipleSequenceAlignment resultAlignment = alnObj->getMultipleAlignment();
156     CHECK_TRUE(resultAlignment->getMsaRow(0)->getData() == "AC-GT--AAA-", "First row content is unexpected!");
157     CHECK_TRUE(resultAlignment->getMsaRow(1)->getData() == "-ACA---GTT-", "Second row content is unexpected!");
158     CHECK_TRUE(resultAlignment->getMsaRow(2)->getData() == "-ACACA-G---", "Third row content is unexpected!");
159 }
160 
IMPLEMENT_TEST(MsaObjectUnitTests,deleteGap_regionWithNonGapSymbols)161 IMPLEMENT_TEST(MsaObjectUnitTests, deleteGap_regionWithNonGapSymbols) {
162     //  Test data:
163     //  AC-GT--AAA----
164     //  -ACA---GTT----
165     //  -ACACA-G------
166 
167     //  Expected result: the same
168 
169     const QString alignmentName = "Alignment with trailing gaps";
170     const U2DbiRef dbiRef = MsaObjectTestData::getDbiRef();
171     U2OpStatusImpl os;
172 
173     QScopedPointer<MultipleSequenceAlignmentObject> alnObj(MsaObjectTestData::getTestAlignmentObject(dbiRef, alignmentName, os));
174     CHECK_NO_ERROR(os);
175 
176     const int countOfDeleted = alnObj->deleteGap(os, U2Region(1, alnObj->getNumRows() - 1), 6, 2);
177     SAFE_POINT_OP(os, );
178 
179     CHECK_TRUE(0 == countOfDeleted, "Unexpected count of removed symbols!");
180     const MultipleSequenceAlignment resultAlignment = alnObj->getMultipleAlignment();
181     CHECK_TRUE(resultAlignment->getMsaRow(0)->getData() == "AC-GT--AAA----", "First row content is unexpected!");
182     CHECK_TRUE(resultAlignment->getMsaRow(1)->getData() == "-ACA---GTT----", "Second row content is unexpected!");
183     CHECK_TRUE(resultAlignment->getMsaRow(2)->getData() == "-ACACA-G------", "Third row content is unexpected!");
184 }
185 
IMPLEMENT_TEST(MsaObjectUnitTests,deleteGap_gapRegion)186 IMPLEMENT_TEST(MsaObjectUnitTests, deleteGap_gapRegion) {
187     //  Test data:
188     //  AC-GT--AAA----
189     //  -ACA---GTT----
190     //  -ACACA-G------
191 
192     //  Expected result:
193     //  AC-GTAAA----
194     //  -ACA-GTT----
195     //  -ACACA-G------
196 
197     const QString alignmentName = "Alignment with trailing gaps";
198     const U2DbiRef dbiRef = MsaObjectTestData::getDbiRef();
199     U2OpStatusImpl os;
200 
201     QScopedPointer<MultipleSequenceAlignmentObject> alnObj(MsaObjectTestData::getTestAlignmentObject(dbiRef, alignmentName, os));
202     CHECK_NO_ERROR(os);
203 
204     const int countOfDeleted = alnObj->deleteGap(os, U2Region(0, alnObj->getNumRows() - 1), 5, 2);
205     SAFE_POINT_OP(os, );
206 
207     CHECK_TRUE(2 == countOfDeleted, "Unexpected count of removed symbols!");
208     const MultipleSequenceAlignment resultAlignment = alnObj->getMultipleAlignment();
209     CHECK_TRUE(resultAlignment->getMsaRow(0)->getData() == "AC-GTAAA---", "First row content is unexpected!");
210     CHECK_TRUE(resultAlignment->getMsaRow(1)->getData() == "-ACA-GTT---", "Second row content is unexpected!");
211     CHECK_TRUE(resultAlignment->getMsaRow(2)->getData() == "-ACACA-G---", "Third row content is unexpected!");
212 }
213 
214 }  // namespace U2
215