muParser API -  1.35
muParserTest.h
Go to the documentation of this file.
1 /*
2 
3  _____ __ _____________ _______ ______ ___________
4  / \| | \____ \__ \\_ __ \/ ___// __ \_ __ \
5  | Y Y \ | / |_> > __ \| | \/\___ \\ ___/| | \/
6  |__|_| /____/| __(____ /__| /____ >\___ >__|
7  \/ |__| \/ \/ \/
8  Copyright (C) 2004 - 2022 Ingo Berg
9 
10  Redistribution and use in source and binary forms, with or without modification, are permitted
11  provided that the following conditions are met:
12 
13  * Redistributions of source code must retain the above copyright notice, this list of
14  conditions and the following disclaimer.
15  * Redistributions in binary form must reproduce the above copyright notice, this list of
16  conditions and the following disclaimer in the documentation and/or other materials provided
17  with the distribution.
18 
19  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28 
29 #ifndef MU_PARSER_TEST_H
30 #define MU_PARSER_TEST_H
31 
32 #include <string>
33 #include <cstdlib>
34 #include <cstdint>
35 #include <numeric> // for accumulate
36 #include "muParser.h"
37 #include "muParserInt.h"
38 
39 #if defined(_MSC_VER)
40  #pragma warning(push)
41  #pragma warning(disable : 4251) // ...needs to have dll-interface to be used by clients of class ...
42 #endif
43 
44 /** \file
45  \brief This file contains the parser test class.
46 */
47 
48 namespace mu
49 {
50  /** \brief Namespace for test cases. */
51  namespace Test
52  {
53  /** \brief Test cases for unit testing. */
54  class API_EXPORT_CXX ParserTester final
55  {
56  private:
57  static int c_iCount;
58 
59  static value_type f0() { return 42; };
60 
61  // Multiarg callbacks
62  static value_type f1of1(value_type v) { return v; };
63 
64  static value_type f1of2(value_type v, value_type) { return v; };
65  static value_type f2of2(value_type, value_type v) { return v; };
66 
67  static value_type f1of3(value_type v, value_type, value_type) { return v; };
68  static value_type f2of3(value_type, value_type v, value_type) { return v; };
69  static value_type f3of3(value_type, value_type, value_type v) { return v; };
70 
71  static value_type f1of4(value_type v, value_type, value_type, value_type) { return v; }
72  static value_type f2of4(value_type, value_type v, value_type, value_type) { return v; }
73  static value_type f3of4(value_type, value_type, value_type v, value_type) { return v; }
74  static value_type f4of4(value_type, value_type, value_type, value_type v) { return v; }
75 
76  static value_type f1of5(value_type v, value_type, value_type, value_type, value_type) { return v; }
77  static value_type f2of5(value_type, value_type v, value_type, value_type, value_type) { return v; }
78  static value_type f3of5(value_type, value_type, value_type v, value_type, value_type) { return v; }
79  static value_type f4of5(value_type, value_type, value_type, value_type v, value_type) { return v; }
80  static value_type f5of5(value_type, value_type, value_type, value_type, value_type v) { return v; }
81 
82  static value_type Min(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1 < a_fVal2) ? a_fVal1 : a_fVal2; }
83  static value_type Max(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1 > a_fVal2) ? a_fVal1 : a_fVal2; }
84 
85  static value_type plus2(value_type v1) { return v1 + 2; }
86  static value_type times3(value_type v1) { return v1 * 3; }
87  static value_type sqr(value_type v1) { return v1 * v1; }
88  static value_type sign(value_type v) { return -v; }
89  static value_type add(value_type v1, value_type v2) { return v1 + v2; }
90  static value_type land(value_type v1, value_type v2) { return (int)v1 & (int)v2; }
91 
92 
93  static value_type FirstArg(const value_type* a_afArg, int a_iArgc)
94  {
95  if (!a_iArgc)
96  throw mu::Parser::exception_type(_T("too few arguments for function FirstArg."));
97 
98  return a_afArg[0];
99  }
100 
101  static value_type LastArg(const value_type* a_afArg, int a_iArgc)
102  {
103  if (!a_iArgc)
104  throw mu::Parser::exception_type(_T("too few arguments for function LastArg."));
105 
106  return a_afArg[a_iArgc - 1];
107  }
108 
109  static value_type Sum(const value_type* a_afArg, int a_iArgc)
110  {
111  if (!a_iArgc)
112  throw mu::Parser::exception_type(_T("too few arguments for function sum."));
113 
114  value_type fRes = 0;
115  for (int i = 0; i < a_iArgc; ++i) fRes += a_afArg[i];
116  return fRes;
117  }
118 
119  static value_type Rnd(value_type v)
120  {
121  return (value_type)(1 + (v * std::rand() / (RAND_MAX + 1.0)));
122  }
123 
124  static value_type RndWithString(const char_type*)
125  {
126  return (value_type)(1.0 + (1000.0 * std::rand() / (RAND_MAX + 1.0)));
127  }
128 
129  static value_type Ping()
130  {
131  return 10;
132  }
133 
134  static value_type ValueOf(const char_type*)
135  {
136  return 123;
137  }
138 
139  static value_type StrFun1(const char_type* v1)
140  {
141  int val(0);
142  stringstream_type(v1) >> val;
143  return (value_type)val;
144  }
145 
146  static value_type StrFun2(const char_type* v1, value_type v2)
147  {
148  int val(0);
149  stringstream_type(v1) >> val;
150  return (value_type)(val + v2);
151  }
152 
153  static value_type StrFun3(const char_type* v1, value_type v2, value_type v3)
154  {
155  int val(0);
156  stringstream_type(v1) >> val;
157  return val + v2 + v3;
158  }
159 
160  static value_type StrFun4(const char_type* v1, value_type v2, value_type v3, value_type v4)
161  {
162  int val(0);
163  stringstream_type(v1) >> val;
164  return val + v2 + v3 + v4;
165  }
166 
167  static value_type StrFun5(const char_type* v1, value_type v2, value_type v3, value_type v4, value_type v5)
168  {
169  int val(0);
170  stringstream_type(v1) >> val;
171  return val + v2 + v3 + v4 + v5;
172  }
173 
174  static value_type StrFun6(const char_type* v1, value_type v2, value_type v3, value_type v4, value_type v5, value_type v6)
175  {
176  int val(0);
177  stringstream_type(v1) >> val;
178  return val + v2 + v3 + v4 + v5 + v6;
179  }
180 
181  static value_type StrToFloat(const char_type* a_szMsg)
182  {
183  value_type val(0);
184  stringstream_type(a_szMsg) >> val;
185  return val;
186  }
187 
188  // postfix operator callback
189  static value_type Mega(value_type a_fVal)
190  {
191  return a_fVal * (value_type)1e6;
192  }
193 
194  static value_type Micro(value_type a_fVal)
195  {
196  return a_fVal * (value_type)1e-6;
197  }
198 
199  static value_type Milli(value_type a_fVal)
200  {
201  return a_fVal / (value_type)1e3;
202  }
203 
204  // Custom value recognition
205  static int IsHexVal(const char_type* a_szExpr, int* a_iPos, value_type* a_fVal);
206 
207  // With user data
208  static value_type FunUd0(void* data)
209  {
210  return reinterpret_cast<std::intptr_t>(data);
211  }
212 
213  static value_type FunUd1(void* data, value_type v)
214  {
215  return reinterpret_cast<std::intptr_t>(data) + v;
216  }
217 
218  static value_type FunUd2(void* data, value_type v1, value_type v2)
219  {
220  return reinterpret_cast<std::intptr_t>(data) + v1 + v2;
221  }
222 
223  static value_type FunUd10(void* data, value_type v1, value_type v2, value_type v3, value_type v4, value_type v5, value_type v6, value_type v7, value_type v8, value_type v9, value_type v10)
224  {
225  return reinterpret_cast<std::intptr_t>(data) + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10;
226  }
227 
228  static value_type StrFunUd3(void* data, const char_type* v1, value_type v2, value_type v3)
229  {
230  int val(0);
231  stringstream_type(v1) >> val;
232  return reinterpret_cast<std::intptr_t>(data) + val + v2 + v3;
233  }
234 
235  static value_type SumUd(void* data, const value_type* a_afArg, int a_iArgc)
236  {
237  if (!a_iArgc)
238  throw mu::Parser::exception_type(_T("too few arguments for function sum."));
239 
240  value_type fRes = 0;
241  for (int i = 0; i < a_iArgc; ++i)
242  fRes += a_afArg[i];
243 
244  return reinterpret_cast<std::intptr_t>(data) + fRes;
245  }
246 
247  int TestNames();
248  int TestSyntax();
249  int TestMultiArg();
250  int TestPostFix();
251  int TestExpression();
252  int TestInfixOprt();
253  int TestBinOprt();
254  int TestVarConst();
255  int TestInterface();
256  int TestException();
257  int TestStrArg();
258  int TestIfThenElse();
259  int TestBulkMode();
260  int TestOssFuzzTestCases();
261  int TestOptimizer();
262 
263  void Abort() const;
264 
265  public:
266  typedef int (ParserTester::* testfun_type)();
267 
268  ParserTester();
269  int Run();
270 
271  private:
272  std::vector<testfun_type> m_vTestFun;
273  void AddTest(testfun_type a_pFun);
274 
275  // Test Double Parser
276  int EqnTest(const string_type& a_str, double a_fRes, bool a_fPass);
277  int EqnTestWithVarChange(const string_type& a_str, double a_fRes1, double a_fVar1, double a_fRes2, double a_fVar2);
278  int ThrowTest(const string_type& a_str, int a_iErrc, bool a_bFail = true);
279 
280  // Test Int Parser
281  int EqnTestInt(const string_type& a_str, double a_fRes, bool a_fPass);
282 
283  // Test Bulkmode
284  int EqnTestBulk(const string_type& a_str, double a_fRes[4], bool a_fPass);
285 
286  };
287  } // namespace Test
288 } // namespace mu
289 
290 
291 #if defined(_MSC_VER)
292  #pragma warning(pop)
293 #endif
294 
295 #endif
296 
#define _T(x)
Activate this option in order to compile with OpenMP support.
Definition: muParserDef.h:69
Definition of a parser using integer value.
Definition of the standard floating point parser.
std::basic_stringstream< char_type, std::char_traits< char_type >, std::allocator< char_type > > stringstream_type
Typedef for easily using stringstream that respect the parser stringtype.
Definition: muParserDef.h:309
MUP_BASETYPE value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:294
Test cases for unit testing.
Definition: muParserTest.h:54
Namespace for mathematical applications.
Definition: muParser.cpp:46
string_type::value_type char_type
The character type used by the parser.
Definition: muParserDef.h:306
MUP_STRING_TYPE string_type
The stringtype used by the parser.
Definition: muParserDef.h:300
ParserError exception_type
Type of the error class.
Definition: muParserBase.h:103