63 bool s_InVerboseMode(
void) {
67 typedef pair<CAgpConverter::EError,string> TErrInfo;
68 typedef vector<TErrInfo> TErrInfoVec;
73 virtual ~CErrorCollector() { }
75 m_errInfoVec.push_back(make_pair(
eError, sMessage));
78 typedef pair<CAgpConverter::EError,string> TErrInfo;
79 typedef vector<TErrInfo> TErrInfoVec;
81 const TErrInfoVec & GetErrInfoVec(
void)
const {
return m_errInfoVec; }
84 mutable TErrInfoVec m_errInfoVec;
87 string s_NormalizeErrorString(
const string & sErrMsg )
91 ITERATE(
string, ch_iter, sAnswer) {
92 const char ch = *ch_iter;
107 template<
class TClass>
112 string sAsn1Text(pchAsn1Text);
119 template<
class TClass>
129 string s_ErrInfoToStr(
const TErrInfo *pErrInfo)
139 sAnswer += pErrInfo->second;
149 void s_UpdateCreateAndUpdateDate(
CBioseq_set & bioseq_set)
153 if( ! s_pTodaysDate ) {
173 const vector<string> & vecAgpFileNames,
174 const TErrInfoVec & expectedErrInfoVec
186 agpConvert.OutputBioseqs(
191 if( s_InVerboseMode() ) {
192 cerr <<
"OutputBioseqs output: " << ostrm.str() << endl;
196 const TErrInfoVec & resultingErrInfoVec = pErrorCollector->GetErrInfoVec();
197 const size_t highest_err_idx =
198 max(expectedErrInfoVec.size(),
199 resultingErrInfoVec.size());
200 for(
size_t err_idx = 0; err_idx < highest_err_idx; ++err_idx ) {
201 const TErrInfo * pExpectedErrInfo =
202 ( (err_idx < expectedErrInfoVec.size()) ?
203 &expectedErrInfoVec[err_idx] :
205 const TErrInfo * pResultingErrInfo =
206 ( (err_idx < resultingErrInfoVec.size()) ?
207 &resultingErrInfoVec[err_idx] :
210 if( pExpectedErrInfo && pResultingErrInfo &&
211 pExpectedErrInfo->first == pResultingErrInfo->first &&
212 s_NormalizeErrorString(pResultingErrInfo->second) ==
213 s_NormalizeErrorString(pExpectedErrInfo->second) )
219 BOOST_ERROR(
"At index " << err_idx <<
", expected error was: "
220 << s_ErrInfoToStr(pExpectedErrInfo) <<
", but got: "
221 << s_ErrInfoToStr(pResultingErrInfo) );
232 BOOST_ERROR(
"Could not parse this answer: " << ostrm.str() );
242 const string & vecAgpFileName,
243 const TErrInfoVec & expectedErrInfoVec = TErrInfoVec()
246 vector<string> vecAgpFileNames;
247 vecAgpFileNames.push_back(vecAgpFileName);
253 expectedErrInfoVec );
259 struct SSerialObjectPtrToAsnText {
260 SSerialObjectPtrToAsnText(
262 : m_pObject(pObject) { }
267 const SSerialObjectPtrToAsnText & stream_op )
269 if( stream_op.m_pObject ) {
270 BOOST_CHECK_NO_THROW( ostrm <<
MSerial_AsnText << *stream_op.m_pObject );
273 return ostrm <<
"(NULL)";
280 descrs->AddDefaultKey(
283 "Use this to change the directory where test cases are sought.",
285 "agp_converter_test_cases");
288 "Set this to print a lot of extra data to help with debugging.");
295 class CAgpConverterTestRunner :
public unit_test_util::ITestRunner
298 virtual void RunTest(
299 const string & sTestName,
300 const TMapSuffixToFile & mapSuffixToFile )
302 BOOST_TEST_MESSAGE(
"Starting test: " << sTestName);
305 s_Asn1TextFileToClass<CBioseq>(mapSuffixToFile.find(
"template.asn")->second);
307 TMapSuffixToFile::const_iterator submit_block_find_iter =
308 mapSuffixToFile.find(
"submit_block.asn");
310 if( submit_block_find_iter != mapSuffixToFile.end() ) {
311 pSubmitBlock = s_Asn1TextFileToClass<CSubmit_block>(submit_block_find_iter->second);
314 TMapSuffixToFile::const_iterator flags_find_iter =
315 mapSuffixToFile.find(
"flags.txt");
317 if( flags_find_iter != mapSuffixToFile.end() ) {
318 CNcbiIfstream flags_istrm( flags_find_iter->second.GetPath().c_str() );
319 while( flags_istrm ) {
323 if( sFlagName.empty() ) {
332 const CFile agpFile = mapSuffixToFile.find(
"agp")->second;
334 TMapSuffixToFile::const_iterator expected_errors_find_iter =
335 mapSuffixToFile.find(
"expected_errors.txt");
336 TErrInfoVec errInfoVec;
337 if( expected_errors_find_iter != mapSuffixToFile.end() ) {
339 expected_errors_find_iter->second.GetPath().c_str() );
344 if( sLine.empty() ) {
355 errInfoVec.push_back( TErrInfo(eErrEnum, sErrMsg) );
360 BOOST_CHECK_NO_THROW(
361 pExpectedBioseqSetAnswer =
362 s_Asn1TextFileToClass<CBioseq_set>(
363 mapSuffixToFile.find(
"expected_bioseq_set.asn")->second ) );
364 if( pExpectedBioseqSetAnswer ) {
365 s_UpdateCreateAndUpdateDate(*pExpectedBioseqSetAnswer);
367 BOOST_ERROR(
"could not parse this file: "
368 << mapSuffixToFile.find(
"expected_bioseq_set.asn")->second.GetPath() );
383 pBioseqSetAnswer.
Reset(
385 }
else if( pAnswer->
GetThisTypeInfo() == CSeq_submit::GetTypeInfo() ) {
389 BOOST_CHECK_NO_THROW(
390 pBioseqSetAnswer.
Reset(
392 &pSeqSubmit->
SetData().SetEntrys().front()->SetSet() ) ) );
395 BOOST_ERROR(
"Cannot figure out type of s_RunTests response" );
401 if( pBioseqSetAnswer ) {
402 s_UpdateCreateAndUpdateDate(*pBioseqSetAnswer);
405 if( ! pBioseqSetAnswer ||
406 ! pExpectedBioseqSetAnswer ||
407 ! pBioseqSetAnswer->
Equals(*pExpectedBioseqSetAnswer) )
409 BOOST_ERROR(
"Result does not match expected. Expected: " <<
Endl()
410 << SSerialObjectPtrToAsnText(pExpectedBioseqSetAnswer) <<
Endl()
411 <<
"But got: " <<
Endl()
412 << SSerialObjectPtrToAsnText(pBioseqSetAnswer) );
416 virtual void OnError(
const string & sErrorText) {
417 BOOST_ERROR(sErrorText);
420 CAgpConverterTestRunner testRunner;
423 requiredSuffixes.
insert(
"template.asn");
424 requiredSuffixes.
insert(
"expected_bioseq_set.asn");
425 requiredSuffixes.
insert(
"agp");
428 optionalSuffixes.
insert(
"submit_block.asn");
429 optionalSuffixes.
insert(
"flags.txt");
430 optionalSuffixes.
insert(
"expected_errors.txt");
434 args[
"test-cases-dir"].AsDirectory(),
451 string sSubmitBlockFileName =
453 args[
"test-cases-dir"].AsString(),
"basic_test_with_submit_block_ignored.submit_block.asn");
454 CNcbiIfstream submit_block_strm( sSubmitBlockFileName.c_str() );
459 vector<string> arrSingleBioseqAGPFileBases;
460 arrSingleBioseqAGPFileBases.push_back(
"basic_test.agp");
461 arrSingleBioseqAGPFileBases.push_back(
"basic_test_with_submit_block_ignored.agp");
463 vector<string> arrMultiBioseqAGPFileBases;
464 arrMultiBioseqAGPFileBases.push_back(
"multi_obj.agp");
465 arrMultiBioseqAGPFileBases.push_back(
"multi_obj_2.agp");
468 typedef vector<const CTypeInfo*> TTypeInfoVec;
469 TTypeInfoVec vecTypeInfos;
470 vecTypeInfos.push_back( CSeq_submit::GetTypeInfo() );
471 vecTypeInfos.push_back( CSeq_entry::GetTypeInfo() );
472 vecTypeInfos.push_back( CBioseq_set::GetTypeInfo() );
473 vecTypeInfos.push_back( CBioseq::GetTypeInfo() );
475 vecTypeInfos.push_back(
nullptr);
482 ++fOutputBioseqsFlags )
488 ( bUseSubmitBlock ? pSubmitBlock.
GetPointer() :
nullptr ) );
492 const vector<string> & refPossibleAGPFileBases = (
493 bMultipleBioseqsPerAGPFile ?
494 arrMultiBioseqAGPFileBases :
495 arrSingleBioseqAGPFileBases );
497 vector<string> refPossibleAGPFiles;
498 ITERATE(vector<string>, file_base_it, refPossibleAGPFileBases ) {
499 refPossibleAGPFiles.push_back(
501 args[
"test-cases-dir"].AsString(), *file_base_it ) );
506 vector<string> vecAgpFileNames;
507 vecAgpFileNames.push_back( refPossibleAGPFiles[0] );
508 if( bMultipleAGPFiles ) {
509 vecAgpFileNames.push_back( refPossibleAGPFiles[1] );
512 cout <<
"Testing with these settings:" << endl;
513 cout <<
"\tflags: " << fOutputBioseqsFlags << endl;
515 cout <<
"\tbMultipleBioseqsPerAGPFile: "
517 cout <<
"\tbMultipleAGPFiles: " <<
521 stringstream obj_strm;
525 fOutputBioseqsFlags );
527 if( s_InVerboseMode() ) {
528 cerr <<
"agpConverter.OutputBioseqs output: "
529 << obj_strm.str() << endl;
537 BOOST_CHECK_NO_THROW( sFileHeader = obj_reader.
ReadFileHeader() );
540 ITERATE( TTypeInfoVec, type_info_it, vecTypeInfos ) {
541 const CTypeInfo *pTypeInfo = *type_info_it;
545 BOOST_ERROR(
"Unknown object type or corrupted file: " << ( sFileHeader.empty() ?
kEmptyStr : sFileHeader ) );
546 }
else if( sFileHeader == pTypeInfo->
GetName() ) {
551 stringstream dummy_ostrm;
Subclass this to override how errors are handled (example: to stop early on some kinds of errors)
virtual void HandleError(EError, const string &sMessage) const
Default is to print to cerr, but feel free to override in a subclass.
void OutputBioseqs(CNcbiOstream &ostrm, const std::vector< std::string > &vecAgpFileNames, TOutputBioseqsFlags fFlags=0, size_t uMaxBioseqsToWrite=std::numeric_limits< size_t >::max()) const
Outputs the result from the AGP file names as ASN.1.
@ fOutputBioseqsFlags_LAST_PLUS_ONE
@ fOutputBioseqsFlags_DoNOTUnwrapSingularBioseqSets
Specify this if Bioseq-sets with just one Bioseq in them should _NOT_ be unwrapped into a Bioseq.
EError
The different kinds of errors that could occur while processing.
static TOutputFlags OutputFlagStringToEnum(const string &sEnumAsString)
Convert string to flag.
int TOutputFlags
Bitwise-OR of EOutputFlags.
static EError ErrorStringToEnum(const string &sEnumAsString)
Convert string to EError enum.
static CNcbiApplication * Instance(void)
Singleton method.
Note about the "buf_size" parameter for streams in this API.
bool IsEntrys(void) const
Base class for all serializable objects.
CTypeInfo class contains all information about C++ types (both basic and classes): members and layout...
Template class for iteration on objects of class C.
iterator_bool insert(const value_type &val)
CNcbiOstream & operator<<(CNcbiOstream &out, const CEquivRange &range)
virtual const CArgs & GetArgs(void) const
Get parsed command line arguments.
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
#define ITERATE_BOTH_BOOL_VALUES(BoolVar)
The body of the loop will be run with Var equal to false and then true.
@ eDirectory
Name of file directory.
static string ConcatPath(const string &first, const string &second)
Concatenate two parts of the path for the current OS.
const string & GetPath(void) const
Get entry path.
virtual const CTypeInfo * GetThisTypeInfo(void) const =0
C * SerialClone(const C &src)
Create on heap a clone of the source object.
#define MSerial_AsnText
I/O stream manipulators –.
virtual bool Equals(const CSerialObject &object, ESerialRecursionMode how=eRecursive) const
Check if both objects contain the same values.
CBeginInfo Begin(C &obj)
Get starting point of object hierarchy.
virtual bool EndOfData(void) override
Check if there is still some meaningful data that can be read; this function will skip white spaces a...
void ReadObject(const CObjectInfo &object)
Read child object.
virtual string ReadFileHeader(void) override
Read file header.
TObjectType * GetPointer(void) THROWS_NONE
Get pointer,.
void Reset(void)
Reset reference object.
TObjectType * GetPointerOrNull(void) const THROWS_NONE
Get pointer value.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
CNcbiIstream & NcbiGetlineEOL(CNcbiIstream &is, string &str, string::size_type *count=NULL)
Read from "is" to "str" the next line (taking into account platform specifics of End-of-Line)
const char * Endl(void)
Platform-specific EndOfLine.
IO_PREFIX::ifstream CNcbiIfstream
Portable alias for ifstream.
static const string BoolToString(bool value)
Convert bool to string.
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate spaces in a string (in-place)
static bool SplitInTwo(const CTempString str, const CTempString delim, string &str1, string &str2, TSplitFlags flags=0)
Split a string into two pieces using the specified delimiters.
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
@ eCurrent
Use current time. See also CCurrentTime.
const string & GetName(void) const
Get name of this type.
TObjectPtr Create(CObjectMemoryPool *memoryPool=0) const
Create object of this type on heap (can be deleted by operator delete)
bool IsUpdate_date(void) const
Check if variant Update_date is selected.
bool IsCreate_date(void) const
Check if variant Create_date is selected.
TCreate_date & SetCreate_date(void)
Select the variant.
TUpdate_date & SetUpdate_date(void)
Select the variant.
void SetData(TData &value)
Assign a value to Data data member.
Defines the CNcbiApplication and CAppException classes for creating NCBI applications.
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
@ eError
An error was encountered while trying to send request or to read and to process the reply.
Reader-writer based streams.
Utility stuff for more convenient using of Boost.Test library.
#define NCBITEST_CHECK_MESSAGE(P, M)
BOOST_AUTO_TEST_CASE(MasterTest)
NCBITEST_INIT_CMDLINE(descrs)
void TraverseAndRunTestCases(ITestRunner *pTestRunner, CDir dirWithTestCases, const set< string > &setOfRequiredSuffixes, const set< string > &setOfOptionalSuffixes=set< string >(), const set< string > &setOfIgnoredSuffixes=set< string >(), TTraverseAndRunTestCasesFlags fFlags=0)
This is for running data-driven test cases below the given top-level test directory.
CRef< objects::CSeq_entry > BuildGoodSeq(void)