test_StringManipulator.cxx
Go to the documentation of this file.
1 // test_StringManipulator.cxx
2 
3 // David Adams
4 // April 2018
5 //
6 // This is a test and demonstration for StringManipulator.
7 
8 #undef NDEBUG
9 
10 #include "../StringManipulator.h"
11 #include <string>
12 #include <iostream>
13 #include <iomanip>
14 #include <vector>
15 #include <cassert>
16 
17 using std::string;
18 using std::cout;
19 using std::endl;
20 using std::setw;
21 using std::vector;
22 
23 using Index = unsigned int;
25 using StringVV = std::vector<StringVector>;
26 
27 //**********************************************************************
28 
29 bool checkEqual(string s1, string s2) {
30  string prefix = "Stringmanipulator: ";
31  cout << prefix << s1;
32  cout << (s1 == s2 ? " == " : " != ");
33  cout << s2 << endl;
34  return s1 == s2;
35 }
36 
37 bool areEqual(const StringVector& lhs, const StringVector& rhs) {
38  string myname = "areEqual: ";
39  if ( lhs == rhs ) return true;
40  Index nlhs = lhs.size();
41  Index nrhs = rhs.size();
42  Index nstr = nlhs > nrhs ? nlhs : nrhs;
43  cout << myname << "Unequal string vectors: " << endl;
44  cout << myname << " Vector lengths: " << nlhs << ", " << nrhs << endl;
45  for ( Index istr=0; istr<nstr; ++istr ) {
46  string slhs = istr < nlhs ? lhs[istr] : "";
47  string srhs = istr < nrhs ? rhs[istr] : "";
48  cout << myname << " " << istr << ": " << slhs << ", " << srhs << endl;
49  }
50  return false;
51 }
52 
53 //**********************************************************************
54 
55 int test_StringManipulator(bool copy, Index logLevel) {
56  const string myname = "test_StringManipulator: ";
57  cout << myname << "Starting test with copy = " << (copy ? "true" : "false") << endl;
58 #ifdef NDEBUG
59  cout << myname << "NDEBUG must be off." << endl;
60  abort();
61 #endif
62  string line = "-----------------------------";
63  string scfg;
64 
65  cout << myname << "Checking float to string." << endl;
66  assert( checkEqual(StringManipulator::floatToString(123, 6, true, "p"), "123") );
67  assert( checkEqual(StringManipulator::floatToString(1.23, 6, true, "p"), "1p23") );
68  assert( checkEqual(StringManipulator::floatToString(-1.23, 6, true, "p"), "-1p23") );
69  assert( checkEqual(StringManipulator::floatToString(-1.23, 6, true, "p", "Minus"), "Minus1p23") );
70  assert( checkEqual(StringManipulator::floatToString(1., 6, true, "p"), "1") );
71  assert( checkEqual(StringManipulator::floatToString(0.009, 6, true, "p"), "0p009") );
72 
73  char cfill = 'x';
74  cout << myname << "Checking fill char." << endl;
75  int vint = 123;
76  cfill = StringManipulator::getFill<int>(vint);
77  cout << myname << " int " << vint << ": " << cfill << endl;
78  assert( cfill == '0' );
79  vint = -123;
80  cfill = StringManipulator::getFill<int>(vint);
81  cout << myname << " int " << vint << ": " << cfill << endl;
82  assert( cfill == '-' );
83  float vflo = 1.23;
84  cfill = StringManipulator::getFill<float>(vflo);
85  cout << myname << " float " << vflo << ": " << cfill << endl;
86  assert( cfill == '_' );
87 
88  // Build raw and expected strings.
89  vector<string> raws = {
90  "abc*SUB*ghi",
91  "abc*POS*ghi",
92  "abc*NEG*ghi",
93  "abc*SUB*ghi_*NEG*_*POS*.txt"
94  };
95  vector<string> exps = {
96  "abcdefghi",
97  "abc123ghi",
98  "abc-123ghi",
99  "abcdefghi_-123_123.txt"
100  };
101  vector<string> expws = {
102  "abc__defghi",
103  "abc00123ghi",
104  "abc--123ghi",
105  "abc__defghi_--123_00123.txt"
106  };
107 
108  cout << myname << "Testing no width with " << raws.size() << " strings." << endl;
109  Index w = 12;
110  for ( Index istr=0; istr<raws.size(); ++istr ) {
111  string raw = raws[istr];
112  string exp = exps[istr];
113  string val = raw;
114  StringManipulator sman(val, copy);
115  assert( sman.logLevel() == 0 );
116  sman.setLogLevel(logLevel);
117  assert( sman.logLevel() == logLevel );
118  sman.replace("*SUB*", "def");
119  sman.replace("*POS*", 123);
120  sman.replace("*NEG*", -123);
121  cout << myname << " "
122  << setw(w) << raw << ": "
123  << setw(w) << val << " ?= "
124  << setw(w) << exp << endl;
125  assert( raw != exp );
126  assert( sman.str() == exp );
127  if ( ! copy ) assert( val == exp );
128  }
129 
130  cout << myname << "Testing width 5 with " << raws.size() << " strings." << endl;
131  for ( Index istr=0; istr<raws.size(); ++istr ) {
132  string raw = raws[istr];
133  string exp = expws[istr];
134  string val = raw;
135  StringManipulator sman(val, copy);
136  sman.setLogLevel(logLevel);
137  sman.replaceFixedWidth("*SUB*", "def", 5);
138  sman.replaceFixedWidth("*POS*", 123, 5);
139  sman.replaceFixedWidth("*NEG*", -123, 5);
140  cout << myname << " "
141  << setw(w) << raw << ": "
142  << setw(w) << val << " ?= "
143  << setw(w) << exp << endl;
144  assert( raw != exp );
145  assert( sman.str() == exp );
146  if ( ! copy ) assert( val == exp );
147  }
148 
149  cout << myname << "Test split." << endl;
150  StringVector strs;
151  StringVector sepss(100, ",");
152  StringVV splits1;
153  StringVV splits2;
154  strs.push_back("a,bb,ccc");
155  splits1.push_back({"a", "bb", "ccc"});
156  splits2.push_back({"a", "bb", "ccc"});
157  strs.push_back(",a,bb,ccc,");
158  splits1.push_back({"a", "bb", "ccc"});
159  splits2.push_back({"", "a", "bb", "ccc", ""});
160  strs.push_back("a,,bb,ccc");
161  splits1.push_back({"a", "bb", "ccc"});
162  splits2.push_back({"a", "", "bb", "ccc"});
163  for ( Index itst=0; itst<strs.size(); ++itst ) {
164  string str = strs[itst];
165  string seps = sepss[itst];
166  StringManipulator sman(str, copy);
167  sman.setLogLevel(logLevel);
168  cout << myname << " " << str << endl;
169  assert( areEqual(sman.split(seps), splits1[itst]) );
170  assert( areEqual(sman.split(seps, true), splits2[itst]) );
171  }
172 
173  cout << myname << "Test pattern split." << endl;
174  strs.clear();
175  StringVector spats(100, "{,}");
176  splits1.clear();
177  strs.push_back("where did {bob,sally,kim} go?");
178  splits1.push_back({"where did bob go?", "where did sally go?", "where did kim go?"});
179  strs.push_back("where did {bob,sal,kim} {go,stay}?");
180  splits1.push_back({"where did bob go?", "where did bob stay?",
181  "where did sal go?", "where did sal stay?",
182  "where did kim go?", "where did kim stay?"});
183  for ( Index itst=0; itst<strs.size(); ++itst ) {
184  string str = strs[itst];
185  string spat = spats[itst];
186  StringManipulator sman(str, copy);
187  cout << myname << " " << str << ", " << spat << endl;
188  assert( areEqual(sman.patternSplit(spat), splits1[itst]) );
189  }
190 
191  cout << myname << "Check int conversion." << endl;
192  vector<std::pair<string, int>> ichks;
193  int badInt = -9999;
194  ichks.push_back({"123", 123});
195  ichks.push_back({"+123", 123});
196  ichks.push_back({"-123", -123});
197  ichks.push_back({"xx", badInt});
198  ichks.push_back({"", badInt});
199  ichks.push_back({"--123", badInt});
200  ichks.push_back({"", badInt});
201  for ( auto vv : ichks ) {
202  int iman = StringManipulator(vv.first).toInt(badInt);
203  cout << myname << setw(10) << vv.first << ": " << vv.second << " ?= " << iman << endl;
204  assert( iman == vv.second );
205  }
206 
207  cout << myname << "Check unsigned int conversion." << endl;
208  vector<std::pair<string, unsigned int>> uchks;
209  unsigned int badUInt = 9999;
210  uchks.push_back({"123", 123});
211  uchks.push_back({"+123", 123});
212  uchks.push_back({"-123", badUInt});
213  uchks.push_back({"xx", badUInt});
214  uchks.push_back({"", badUInt});
215  uchks.push_back({"--123", badUInt});
216  uchks.push_back({"", badUInt});
217  for ( auto vv : uchks ) {
218  unsigned int iman = StringManipulator(vv.first).toUnsignedInt(badUInt);
219  cout << myname << setw(10) << vv.first << ": " << vv.second << " ?= " << iman << endl;
220  assert( iman == vv.second );
221  }
222 
223  cout << myname << "Check float conversion." << endl;
224  vector<std::pair<string, float>> fchks;
225  float badFloat = -999.9;
226  fchks.push_back({"1.23", 1.23});
227  fchks.push_back({"+1.23", 1.23});
228  fchks.push_back({"-1.23", -1.23});
229  fchks.push_back({"xx", badFloat});
230  fchks.push_back({"", badFloat});
231  fchks.push_back({"--1.23", badFloat});
232  fchks.push_back({"1.23e1", 12.3});
233  fchks.push_back({"1.23x", badFloat});
234  fchks.push_back({"", badFloat});
235  for ( auto vv : fchks ) {
236  StringManipulator sman(vv.first);
237  float xman = sman.toFloat(badFloat);
238  cout << myname << setw(10) << vv.first << ": " << vv.second << " ?= " << xman << endl;
239  assert( int(1000*xman) == int(1000*(vv.second)) );
240  bool foundBad = int(1000*xman) == int(1000*badFloat);
241  assert( sman.isFloat() != foundBad );
242  }
243 
244  cout << myname << "Done." << endl;
245  return 0;
246 }
247 
248 //**********************************************************************
249 
250 int main() {
251  return test_StringManipulator(false, 0) +
252  test_StringManipulator(true, 0);
253 }
254 
255 //**********************************************************************
const StringVector & patternSplit(std::string spat)
int test_StringManipulator(bool copy, Index logLevel)
static std::string floatToString(float val, int prec, bool trunc, std::string sdot="", std::string smin="")
const std::vector< std::string > & split(std::string seps, bool fullSplit=false)
std::string string
Definition: nybbler.cc:12
struct vector vector
Index logLevel() const
int replace(std::string substr, const T &xsub)
Raw data description.
unsigned int Index
const std::string & str() const
bool checkEqual(string s1, string s2)
unsigned int toUnsignedInt(unsigned int valbad=0) const
void setLogLevel(Index logLevel)
bool areEqual(const StringVector &lhs, const StringVector &rhs)
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
int toInt(int valbad=0) const
int replaceFixedWidth(std::string substr, const T &xsub, Index width)
std::vector< string > StringVector
Definition: fcldump.cxx:29
void line(double t, double *p, double &x, double &y, double &z)
T copy(T const &v)
std::vector< StringVector > StringVV
std::vector< std::string > StringVector
static QCString str
QTextStream & endl(QTextStream &s)
float toFloat(float valbad=0) const