NCBI C++ ToolKit
unit_test_rna_edit.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: unit_test_rna_edit.cpp 93572 2021-04-30 13:48:31Z stakhovv $
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: Igor Filippov, based on vcf reader unit test by Frank Ludwig, NCBI.
27 *
28 * File Description:
29 * Find ITS parser unit test.
30 *
31 * ===========================================================================
32 */
33 
34 #include <ncbi_pch.hpp>
35 
36 #include <corelib/ncbi_system.hpp>
37 #include <corelib/ncbiapp.hpp>
38 #include <corelib/ncbifile.hpp>
40 #include <objmgr/scope.hpp>
41 
43 
44 #include <cstdio>
45 
46 // This header must be included before all Boost.Test headers if there are any
47 #include <corelib/test_boost.hpp>
48 
49 #include <common/test_assert.h> /* This header must go last */
50 
51 
54 
55 // ============================================================================
56 // Customization data:
57 const string extOrigInput("input.asn");
58 const string extInput("find_its_output.tab");
59 const string extOutput("output.asn");
60 const string dirTestFiles("rna_edit_test_cases");
61 const string extKeep("new");
62 // ============================================================================
63 
64 struct STestInfo {
68 };
69 typedef string TTestName;
71 
73 public:
75  TTestNameToInfoMap * pTestNameToInfoMap)
76  : m_pTestNameToInfoMap(pTestNameToInfoMap)
77  { }
78 
79  void operator()( const CDirEntry & dirEntry ) {
80  if( ! dirEntry.IsFile() ) {
81  return;
82  }
83 
84  CFile file(dirEntry);
85  string name = file.GetName();
86  if (NStr::EndsWith(name, ".txt") || NStr::StartsWith(name, ".")) {
87  return;
88  }
89 
90  // extract info from the file name
91  const string sFileName = file.GetName();
92  vector<string> vecFileNamePieces;
93  NStr::Split(sFileName, ".", vecFileNamePieces);
94  BOOST_REQUIRE(vecFileNamePieces.size() == 3);
95 
96  string tsTestName = vecFileNamePieces[0];
97  BOOST_REQUIRE(!tsTestName.empty());
98  string tsFileType = vecFileNamePieces[1] + "." + vecFileNamePieces[2];
99  BOOST_REQUIRE(!tsFileType.empty());
100 
101  STestInfo & test_info_to_load =
102  (*m_pTestNameToInfoMap)[vecFileNamePieces[0]];
103 
104  // figure out what type of file we have and set appropriately
105  if (tsFileType == extInput) {
106  BOOST_REQUIRE( test_info_to_load.mInFile.GetPath().empty() );
107  test_info_to_load.mInFile = file;
108  }
109  else if (tsFileType == extOrigInput) {
110  BOOST_REQUIRE( test_info_to_load.mOrigInFile.GetPath().empty() );
111  test_info_to_load.mOrigInFile = file;
112  }
113  else if (tsFileType == extOutput) {
114  BOOST_REQUIRE( test_info_to_load.mOutFile.GetPath().empty() );
115  test_info_to_load.mOutFile = file;
116  }
117  else {
118  BOOST_FAIL("Unknown file type " << sFileName << ".");
119  }
120  }
121 
122 private:
123  // raw pointer because we do NOT own this
125 };
126 
127 void sUpdateCase(CDir& test_cases_dir, const string& test_name)
128 {
129  string input = CDir::ConcatPath( test_cases_dir.GetPath(), test_name + "." + extInput);
130  string orig_input = CDir::ConcatPath( test_cases_dir.GetPath(), test_name + "." + extOrigInput);
131  string output = CDir::ConcatPath( test_cases_dir.GetPath(), test_name + "." + extOutput);
132  if (!CFile(input).Exists()) {
133  BOOST_FAIL("input file " << input << " does not exist.");
134  }
135  cerr << "Creating new test case from " << input << " ..." << endl;
136 
137  CNcbiIfstream ifstr(orig_input.c_str());
138  CRef <CSeq_entry> entry(new CSeq_entry());
139  ifstr >> MSerial_AsnText >> *entry;
140  ifstr.close();
142  CSeq_entry_Handle tse = scope->AddTopLevelSeqEntry(*entry);
143 
144  CNcbiOfstream ofstr(output.c_str());
145  try
146  {
147  edit::CFindITSParser parser(input.c_str(), tse);
148  do
149  {
150  CRef <CSeq_feat> new_mrna = parser.ParseLine();
151  if (new_mrna)
152  ofstr << MSerial_AsnText << *new_mrna;
153  } while ( !parser.AtEOF() );
154  }
155  catch (...)
156  {
157  BOOST_FAIL("Error: " << input << " failed during conversion.");
158  }
159 
160  ofstr.close();
161  cerr << " Produced new ASN1 file " << output << "." << endl;
162 
163  cerr << " ... Done." << endl;
164 }
165 
166 void sUpdateAll(CDir& test_cases_dir) {
167 
168  const vector<string> kEmptyStringVec;
169  TTestNameToInfoMap testNameToInfoMap;
170  CTestNameToInfoMapLoader testInfoLoader(&testNameToInfoMap);
172  test_cases_dir,
173  kEmptyStringVec,
174  kEmptyStringVec,
175  testInfoLoader,
177 
178  ITERATE(TTestNameToInfoMap, name_to_info_it, testNameToInfoMap) {
179  const string & sName = name_to_info_it->first;
180  sUpdateCase(test_cases_dir, sName);
181  }
182 }
183 
184 void sRunTest(const string &sTestName, const STestInfo & testInfo, bool keep)
185 {
186  cerr << "Testing " << testInfo.mInFile.GetName() << " against " <<
187  testInfo.mOutFile.GetName() << endl;
188 
189  CNcbiIfstream ifstr(testInfo.mOrigInFile.GetPath().c_str());
190  CRef <CSeq_entry> entry(new CSeq_entry());
191  ifstr >> MSerial_AsnText >> *entry;
192  ifstr.close();
194  CSeq_entry_Handle tse = scope->AddTopLevelSeqEntry(*entry);
195 
196 
197  string resultName = CDirEntry::GetTmpName();
198  CNcbiOfstream ofstr(resultName.c_str());
199  try
200  {
201  edit::CFindITSParser parser(testInfo.mInFile.GetPath().c_str(), tse);
202  do
203  {
204  CRef <CSeq_feat> new_mrna = parser.ParseLine();
205  if (new_mrna)
206  ofstr << MSerial_AsnText << *new_mrna;
207  } while ( !parser.AtEOF() );
208  }
209  catch (...)
210  {
211  BOOST_FAIL("Error: " << sTestName << " failed during conversion.");
212  return;
213  }
214  ofstr.close();
215 
216  bool success = testInfo.mOutFile.CompareTextContents(resultName, CFile::eIgnoreWs);
217  if (!success) {
218  CDirEntry deResult = CDirEntry(resultName);
219  if (keep) {
220  deResult.Copy(testInfo.mOutFile.GetPath() + "." + extKeep);
221  }
222  deResult.Remove();
223  BOOST_ERROR("Error: " << sTestName << " failed due to post processing diffs.");
224  }
225  CDirEntry(resultName).Remove();
226 };
227 
229 {
230 }
231 
232 
234 {
235  arg_descrs->AddDefaultKey("test-dir", "TEST_FILE_DIRECTORY",
236  "Set the root directory under which all test files can be found.",
238  dirTestFiles );
239  arg_descrs->AddDefaultKey("update-case", "UPDATE_CASE",
240  "Produce .asn and .error files from given name for new or updated test case.",
242  "" );
243  arg_descrs->AddFlag("update-all",
244  "Update all test cases to current reader code (dangerous).",
245  true );
246  arg_descrs->AddFlag("keep-diffs",
247  "Keep output files that are different from the expected.",
248  true );
249 }
250 
252 {
253 }
254 
256 {
257  const CArgs& args = CNcbiApplication::Instance()->GetArgs();
258 
259  CDir test_cases_dir( args["test-dir"].AsDirectory() );
260  BOOST_REQUIRE_MESSAGE( test_cases_dir.IsDir(),
261  "Cannot find dir: " << test_cases_dir.GetPath() );
262 
263  bool update_all = args["update-all"].AsBoolean();
264  if (update_all) {
265  sUpdateAll(test_cases_dir);
266  return;
267  }
268 
269  string update_case = args["update-case"].AsString();
270  if (!update_case.empty()) {
271  sUpdateCase(test_cases_dir, update_case);
272  return;
273  }
274 
275  const vector<string> kEmptyStringVec;
276  TTestNameToInfoMap testNameToInfoMap;
277  CTestNameToInfoMapLoader testInfoLoader(&testNameToInfoMap);
278  FindFilesInDir(test_cases_dir, kEmptyStringVec,kEmptyStringVec,testInfoLoader, fFF_Default | fFF_Recursive );
279 
280  ITERATE(TTestNameToInfoMap, name_to_info_it, testNameToInfoMap) {
281  const string & sName = name_to_info_it->first;
282  const STestInfo & testInfo = name_to_info_it->second;
283  cout << "Verifying: " << sName << endl;
284  BOOST_REQUIRE_MESSAGE( testInfo.mOrigInFile.Exists(), extOrigInput + " file does not exist: " << testInfo.mOrigInFile.GetPath() );
285  BOOST_REQUIRE_MESSAGE( testInfo.mInFile.Exists(), extInput + " file does not exist: " << testInfo.mInFile.GetPath() );
286  BOOST_REQUIRE_MESSAGE( testInfo.mOutFile.Exists(), extOutput + " file does not exist: " << testInfo.mOutFile.GetPath() );
287  }
288  ITERATE(TTestNameToInfoMap, name_to_info_it, testNameToInfoMap) {
289  const string & sName = name_to_info_it->first;
290  const STestInfo & testInfo = name_to_info_it->second;
291 
292  cout << "Running test: " << sName << endl;
293 
294  BOOST_CHECK_NO_THROW(sRunTest(sName, testInfo, args["keep-diffs"]));
295  }
296 }
CArgs –.
Definition: ncbiargs.hpp:379
CDirEntry –.
Definition: ncbifile.hpp:262
CDir –.
Definition: ncbifile.hpp:1695
CFile –.
Definition: ncbifile.hpp:1604
static CNcbiApplication * Instance(void)
Singleton method.
Definition: ncbiapp.cpp:264
CScope –.
Definition: scope.hpp:92
CSeq_entry_Handle –.
Definition: Seq_entry.hpp:56
CTestNameToInfoMapLoader(TTestNameToInfoMap *pTestNameToInfoMap)
TTestNameToInfoMap * m_pTestNameToInfoMap
void operator()(const CDirEntry &dirEntry)
Definition: map.hpp:338
static SQLCHAR output[256]
Definition: print.c:5
static int RunTests(void)
Code to iterate through all tests to run.
Definition: testodbc.c:397
static char test_name[128]
Definition: utf8_2.c:34
virtual const CArgs & GetArgs(void) const
Get parsed command line arguments.
Definition: ncbiapp.cpp:305
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
@ eString
An arbitrary string.
Definition: ncbiargs.hpp:589
@ eDirectory
Name of file directory.
Definition: ncbiargs.hpp:598
void FindFilesInDir(const CDir &dir, const vector< string > &masks, const vector< string > &masks_subdir, TFindFunc &find_func, TFindFiles flags=fFF_Default)
Find files in the specified directory.
Definition: ncbifile.hpp:3022
virtual bool Remove(TRemoveFlags flags=eRecursive) const
Remove a directory entry.
Definition: ncbifile.cpp:2595
bool IsDir(EFollowLinks follow=eFollowLinks) const
Check whether a directory entry is a directory.
Definition: ncbifile.hpp:3946
bool CompareTextContents(const string &file, ECompareText mode, size_t buf_size=0) const
Compare files contents in text form.
Definition: ncbifile.cpp:3565
bool IsFile(EFollowLinks follow=eFollowLinks) const
Check whether a directory entry is a file.
Definition: ncbifile.hpp:3940
static string GetTmpName(ETmpFileCreationMode mode=eTmpFileGetName)
Get temporary file name.
Definition: ncbifile.cpp:2903
static string ConcatPath(const string &first, const string &second)
Concatenate two parts of the path for the current OS.
Definition: ncbifile.cpp:776
string GetName(void) const
Get the base entry name with extension (if any).
Definition: ncbifile.hpp:3916
const string & GetPath(void) const
Get entry path.
Definition: ncbifile.hpp:3910
virtual bool Copy(const string &new_path, TCopyFlags flags=fCF_Default, size_t buf_size=0) const
Copy the entry to a location specified by "new_path".
Definition: ncbifile.cpp:2428
virtual bool Exists(void) const
Check existence of file.
Definition: ncbifile.hpp:4038
@ fFF_Recursive
descend into sub-dirs
Definition: ncbifile.hpp:3012
@ fFF_Default
default behavior
Definition: ncbifile.hpp:3014
@ eIgnoreWs
Definition: ncbifile.hpp:1668
#define MSerial_AsnText
I/O stream manipulators –.
Definition: serialbase.hpp:696
static CRef< CObjectManager > GetInstance(void)
Return the existing object manager or create one.
CSeq_entry_Handle AddTopLevelSeqEntry(CSeq_entry &top_entry, TPriority pri=kPriority_Default, EExist action=eExist_Default)
Add seq_entry, default priority is higher than for defaults or loaders Add object to the score with p...
Definition: scope.cpp:522
IO_PREFIX::ofstream CNcbiOfstream
Portable alias for ofstream.
Definition: ncbistre.hpp:500
IO_PREFIX::ifstream CNcbiIfstream
Portable alias for ifstream.
Definition: ncbistre.hpp:439
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3461
static bool EndsWith(const CTempString str, const CTempString end, ECase use_case=eCase)
Check if a string ends with a specified suffix value.
Definition: ncbistr.hpp:5430
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5412
FILE * file
static int input()
Defines the CNcbiApplication and CAppException classes for creating NCBI applications.
Defines classes: CDirEntry, CFile, CDir, CSymLink, CMemoryFile, CFileUtil, CFileLock,...
The Object manager core.
Utility stuff for more convenient using of Boost.Test library.
BOOST_AUTO_TEST_CASE(RunTests)
USING_SCOPE(objects)
const string dirTestFiles("rna_edit_test_cases")
void sUpdateAll(CDir &test_cases_dir)
map< TTestName, STestInfo > TTestNameToInfoMap
const string extOrigInput("input.asn")
const string extOutput("output.asn")
void sUpdateCase(CDir &test_cases_dir, const string &test_name)
NCBITEST_AUTO_INIT()
USING_NCBI_SCOPE
const string extInput("find_its_output.tab")
const string extKeep("new")
void sRunTest(const string &sTestName, const STestInfo &testInfo, bool keep)
NCBITEST_AUTO_FINI()
NCBITEST_INIT_CMDLINE(arg_descrs)
string TTestName
Modified on Wed Apr 17 13:08:37 2024 by modify_doxy.py rev. 669887