[dali_2.3.20] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / test-trace-call-stack.h
1 #ifndef TEST_TRACE_CALL_STACK_H
2 #define TEST_TRACE_CALL_STACK_H
3
4 /*
5  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 #include <map>
22 #include <sstream>
23 #include <string>
24 #include <vector>
25
26 namespace Dali
27 {
28 template<typename T>
29 std::string ToString(const T& x)
30 {
31   return "undefined";
32 }
33
34 std::string ToString(int x);
35 std::string ToString(unsigned int x);
36 std::string ToString(float x);
37
38 /**
39  * Helper class to track method calls in the abstraction and search for them in test cases
40  */
41 class TraceCallStack
42 {
43 public:
44   /// Typedef for passing and storing named parameters
45   class NamedParams
46   {
47   public:
48     struct NameValue
49     {
50       std::string        parameterName;
51       std::ostringstream value;
52       NameValue(std::string pname, std::string aValue)
53       : parameterName(pname),
54         value(aValue)
55       {
56       }
57       NameValue(const NameValue& rhs)
58       : parameterName(rhs.parameterName),
59         value(rhs.value.str())
60       {
61       }
62       NameValue& operator=(const NameValue& rhs)
63       {
64         if(this != &rhs)
65         {
66           this->parameterName = rhs.parameterName;
67           this->value.str(rhs.value.str());
68         }
69         return *this;
70       }
71
72       bool operator==(const NameValue& rhs)
73       {
74         return !parameterName.compare(rhs.parameterName) && !value.str().compare(rhs.value.str());
75       }
76
77       bool operator==(int match) const;
78     };
79
80     auto find(const std::string& param) const
81     {
82       auto iter = mParams.begin();
83       for(; iter != mParams.end(); ++iter)
84       {
85         if(!iter->parameterName.compare(param))
86         {
87           break;
88         }
89       }
90       return iter;
91     }
92
93     auto begin() const
94     {
95       return mParams.begin();
96     }
97     auto end() const
98     {
99       return mParams.end();
100     }
101
102     std::ostringstream& operator[](std::string name)
103     {
104       auto iter = mParams.begin();
105       for(; iter != mParams.end(); ++iter)
106       {
107         if(!iter->parameterName.compare(name))
108         {
109           break;
110         }
111       }
112
113       if(iter != mParams.end())
114       {
115         return iter->value;
116       }
117       else
118       {
119         mParams.push_back(NameValue(name, ""));
120         return mParams.back().value;
121       }
122     }
123
124     const std::ostringstream& operator[](std::string name) const
125     {
126       static std::ostringstream empty;
127       auto                      iter = mParams.begin();
128       for(; iter != mParams.end(); ++iter)
129       {
130         if(!iter->parameterName.compare(name))
131         {
132           break;
133         }
134       }
135
136       if(iter != mParams.end())
137       {
138         return iter->value;
139       }
140       return empty;
141     }
142
143     std::string str() const
144     {
145       std::ostringstream out;
146       bool               first = true;
147       for(auto& elem : mParams)
148       {
149         out << (first ? "" : " ") << elem.parameterName << ": " << elem.value.str();
150         first = false;
151       }
152       return out.str();
153     }
154     std::vector<NameValue> mParams{};
155   };
156
157   /**
158    * Constructor
159    */
160   TraceCallStack(bool logging, std::string prefix);
161
162   TraceCallStack(const TraceCallStack&) = delete;
163   TraceCallStack(TraceCallStack&&)      = delete;
164
165   /**
166    * Destructor
167    */
168   ~TraceCallStack();
169
170   /**
171    * Turn on / off tracing
172    */
173   void Enable(bool enable);
174
175   bool IsEnabled();
176
177   void EnableLogging(bool enable);
178
179   /**
180    * Push a call onto the stack if the trace is active
181    * @param[in] method The name of the method
182    * @param[in] params A comma separated list of parameter values
183    */
184   void PushCall(std::string method, std::string params);
185
186   /**
187    * Push a call onto the stack if the trace is active
188    * @param[in] method The name of the method
189    * @param[in] params A comma separated list of parameter values
190    * @param[in] altParams A map of named parameter values
191    */
192   void PushCall(std::string method, std::string params, const NamedParams& altParams);
193
194   /**
195    * Search for a method in the stack
196    * @param[in] method The name of the method
197    * @return true if the method was in the stack
198    */
199   bool FindMethod(std::string method) const;
200
201   /**
202    * Search for a method in the stack and return its parameters if found
203    * @param[in] method The name of the method
204    * @param[out] params of the method
205    * @return true if the method was in the stack
206    */
207   bool FindMethodAndGetParameters(std::string method, std::string& params) const;
208
209   /**
210    * Search for a method in the stack and return its parameters if found
211    * @param[in] method The name of the method
212    * @param[out] params of the method
213    * @return true if the method was in the stack
214    */
215   bool FindMethodAndGetParameters(std::string method, NamedParams& params) const;
216
217   /**
218    * Count how many times a method was called
219    * @param[in] method The name of the method
220    * @return The number of times it was called
221    */
222   int CountMethod(std::string method) const;
223
224   /**
225    * Search for a method in the stack with the given parameter list
226    * @param[in] method The name of the method
227    * @param[in] params A comma separated list of parameter values
228    * @return true if the method was in the stack
229    */
230   bool FindMethodAndParams(std::string method, std::string params) const;
231
232   /**
233    * Search for a method in the stack with the given parameter list
234    * @param[in] method The name of the method
235    * @param[in] params A map of named parameters to test for
236    * @return true if the method was in the stack
237    */
238   bool FindMethodAndParams(std::string method, const NamedParams& params) const;
239
240   /**
241    * Search for a method in the stack with the given parameter list.
242    * The search is done from a given index.
243    * This allows the order of methods and parameters to be checked.
244    * @param[in] method The name of the method
245    * @param[in] params A comma separated list of parameter values
246    * @param[in/out] startIndex The method index to start looking from.
247    *                This is updated if a method is found so subsequent
248    *                calls can search for methods occuring after this one.
249    * @return True if the method was in the stack
250    */
251   bool FindMethodAndParamsFromStartIndex(std::string method, std::string params, size_t& startIndex) const;
252
253   /**
254    * Search for a method in the stack with the given parameter list
255    * @param[in] method The name of the method
256    * @param[in] params A comma separated list of parameter values
257    * @return index in the stack where the method was found or -1 otherwise
258    */
259   int FindIndexFromMethodAndParams(std::string method, std::string params) const;
260
261   /**
262    * Search for a method in the stack with the given parameter list
263    * @param[in] method The name of the method
264    * @param[in] params A map of named parameter values to match
265    * @return index in the stack where the method was found or -1 otherwise
266    */
267   int FindIndexFromMethodAndParams(std::string method, const NamedParams& params) const;
268
269   /**
270    * Search for the most recent occurrence of the method with the given (partial) parameters.
271    * @param[in] method The name of the method
272    * @param[in] params A map of named parameter values to match
273    * @return The full named parameters of the matching call.
274    */
275   const NamedParams* FindLastMatch(std::string method, const TraceCallStack::NamedParams& params) const;
276
277   /**
278    * Test if the given method and parameters are at a given index in the stack
279    * @param[in] index Index in the call stack
280    * @param[in] method Name of method to test
281    * @param[in] params A comma separated list of parameter values to test
282    */
283   bool TestMethodAndParams(int index, std::string method, std::string params) const;
284
285   /**
286    * Reset the call stack
287    */
288   void Reset();
289
290   /**
291    * Method to display contents of the TraceCallStack.
292    * @return A string containing a list of function calls and parameters (may contain newline characters)
293    */
294   std::string GetTraceString()
295   {
296     std::stringstream traceStream;
297     std::size_t       functionCount = mCallStack.size();
298     for(std::size_t i = 0; i < functionCount; ++i)
299     {
300       Dali::TraceCallStack::FunctionCall functionCall = mCallStack[i];
301       traceStream << "StackTrace: Index:" << i << ",  Function:" << functionCall.method << ",  ParamList:" << functionCall.paramList << std::endl;
302     }
303
304     return traceStream.str();
305   }
306
307 public:
308   bool        mTraceActive{false}; ///< True if the trace is active
309   bool        mLogging{false};     ///< True if the trace is logged to stdout
310   std::string mPrefix;
311
312   struct FunctionCall
313   {
314     std::string method;
315     std::string paramList;
316     NamedParams namedParams;
317     FunctionCall(const std::string& aMethod, const std::string& aParamList)
318     : method(aMethod),
319       paramList(aParamList)
320     {
321     }
322     FunctionCall(const std::string& aMethod, const std::string& aParamList, const NamedParams& altParams)
323     : method(aMethod),
324       paramList(aParamList),
325       namedParams(altParams)
326     {
327     }
328   };
329
330   std::vector<FunctionCall> mCallStack; ///< The call stack
331 };
332
333 } // namespace Dali
334
335 #endif // TEST_TRACE_CALL_STACK_H