iutest  1.17.99.14
iutest_params_util.hpp
[詳解]
1 //======================================================================
2 //-----------------------------------------------------------------------
13 //-----------------------------------------------------------------------
14 //======================================================================
15 #ifndef INCG_IRIS_IUTEST_PARAMS_UTIL_HPP_19F0C0BB_EEAE_4E8B_B269_A09A4A45E890_
16 #define INCG_IRIS_IUTEST_PARAMS_UTIL_HPP_19F0C0BB_EEAE_4E8B_B269_A09A4A45E890_
17 
18 //======================================================================
19 // include
20 // IWYU pragma: begin_exports
21 #include "iutest_genparams.hpp"
23 // IWYU pragma: end_exports
24 
25 #if IUTEST_HAS_PARAM_TEST
26 // IWYU pragma: begin_exports
27 #include "iutest_pool.hpp"
28 // IWYU pragma: end_exports
29 
30 namespace iutest {
31 namespace detail
32 {
33 
34 //======================================================================
35 // class
36 
40 class IParamTestInfoData
41 {
42 public:
43  class EachTestBase : public iuIObject {};
44  template<typename T>
45  class ParamEachTestBase : public EachTestBase
46  {
47  public:
48  virtual void SetParam(const T& param) = 0;
49  };
50 public:
51  explicit IParamTestInfoData(const char* name) : m_name(name) {}
52  virtual ~IParamTestInfoData() IUTEST_CXX_DEFAULT_FUNCTION
53  virtual TestSuite* MakeTestSuite(const ::std::string& , TestTypeId , SetUpMethod , TearDownMethod ) const = 0;
54  virtual EachTestBase* RegisterTest(TestSuite* , const ::std::string& ) const = 0;
55  const char* GetName() const { return m_name.c_str(); }
56 protected:
57  ::std::string m_name;
58 };
59 
63 class IParamTestSuiteInfo
64 {
65 public:
66  virtual ~IParamTestSuiteInfo() {}
67 protected:
68  IParamTestSuiteInfo(const ::std::string& base_name, const ::std::string& package_name)
69  : m_testsuite_base_name(base_name), m_package_name(package_name) {}
70  IParamTestSuiteInfo(const char* base_name, const char* package_name)
71  : m_testsuite_base_name(base_name), m_package_name(package_name) {}
72 
73 public:
77  void AddTestPattern(IParamTestInfoData* testinfo)
78  {
79  m_testinfos.push_back(testinfo);
80  }
81 
82 public:
83  void RegisterTests() const
84  {
85  for( TestInfoContainer::const_iterator it=m_testinfos.begin(), end=m_testinfos.end(); it != end; ++it )
86  {
87  OnRegisterTests(*it);
88  }
89  }
90 
91  ::std::string GetTestSuiteBaseName() const { return m_testsuite_base_name; }
92  ::std::string GetPackageName() const { return m_package_name; }
93 
94 public:
95  bool is_same(const ::std::string& base_name, const ::std::string& package_name)
96  {
97  return m_testsuite_base_name == base_name && m_package_name == package_name;
98  }
99  bool is_same(const char* base_name, const char* package_name)
100  {
101  return m_testsuite_base_name == base_name && m_package_name == package_name;
102  }
103 
104 private:
105  virtual void OnRegisterTests(IParamTestInfoData*) const = 0;
106 private:
107  typedef ::std::vector<IParamTestInfoData*> TestInfoContainer;
108  TestInfoContainer m_testinfos;
109 protected:
110  ::std::string m_testsuite_base_name;
111  ::std::string m_package_name;
112  const char* m_file;
113  int m_line;
114 };
115 
120 template<class T>
121 class ParamTestSuiteInfo IUTEST_CXX_FINAL : public IParamTestSuiteInfo
122 {
123  typedef T Tester;
124  typedef typename Tester::ParamType ParamType;
125  typedef detail::iuIParamGenerator<ParamType> ParamGenerator;
126  typedef typename ParamGenerator::Generator Generator;
127  typedef IParamTestInfoData::ParamEachTestBase<ParamType> EachTest;
128 
129  typedef ::std::vector<IParamTestInfoData*> TestInfoContainer;
130 
131  typedef ParamGenerator* (*pfnCreateGeneratorFunc)();
132  typedef ::std::string (*pfnParamNameGeneratorFunc)(const TestParamInfo<ParamType>&);
133 
134  class Functor
135  {
136  public:
137  Functor()
138  : CreateGen(NULL), ParamNameGen(NULL), m_file(NULL), m_line(0) {}
139  Functor(pfnCreateGeneratorFunc c, pfnParamNameGeneratorFunc p, const char* file, int line)
140  : CreateGen(c), ParamNameGen(p), m_file(file), m_line(line) {}
141  pfnCreateGeneratorFunc CreateGen;
142  pfnParamNameGeneratorFunc ParamNameGen;
143  const char* m_file;
144  int m_line;
145  };
146 
147 public:
149  ParamTestSuiteInfo(const ::std::string& testsuite_name, const ::std::string& package_name)
150  : IParamTestSuiteInfo(testsuite_name, package_name)
151  {
152  }
153  ParamTestSuiteInfo(const char* testsuite_name, const char* package_name)
154  : IParamTestSuiteInfo(testsuite_name, package_name)
155  {
156  }
157  virtual ~ParamTestSuiteInfo() {}
158 
162  int AddTestSuiteInstantiation(::std::string name
163  , pfnCreateGeneratorFunc create_func, pfnParamNameGeneratorFunc paramname_func
164  , const char* file, int line)
165  {
166 #if IUTEST_HAS_STD_EMPLACE
167  m_instantiation.emplace_back(name, Functor(create_func, paramname_func, file, line));
168 #else
169  m_instantiation.push_back(InstantiationPair(name, Functor(create_func, paramname_func, file, line)));
170 #endif
171  return 0;
172  }
173 
177  virtual void OnRegisterTests(IParamTestInfoData* infodata) const IUTEST_CXX_OVERRIDE
178  {
179  for( typename InstantiationContainer::const_iterator gen_it=m_instantiation.begin()
180  , gen_end=m_instantiation.end(); gen_it != gen_end; ++gen_it )
181  {
182  // パラメータ生成器の作成
183  detail::scoped_ptr<ParamGenerator> p((gen_it->second.CreateGen)());
184 
185  const ::std::string testsuite_name = CreateTestSuiteName(gen_it->first);
186  const char* file = gen_it->second.m_file;
187  const int line = gen_it->second.m_line;
188  TestSuite* testsuite = infodata->MakeTestSuite(testsuite_name
189  , internal::GetTypeId<Tester>()
190  , IUTEST_GET_SETUP_TESTSUITE(Tester, file, line)
191  , IUTEST_GET_TEARDOWN_TESTSUITE(Tester, file, line));
192 
193  if( p.get() != NULL )
194  {
195  size_t i=0;
196  for( p->Begin(); !p->IsEnd(); p->Next() )
197  {
198  const ::std::string name = MakeParamTestName(infodata->GetName()
199  , gen_it->second.ParamNameGen(TestParamInfo<ParamType>(p->GetCurrent(), i)) );
200 #if IUTEST_CHECK_STRICT
201  if( !CheckTestName(testsuite, name) )
202  {
203  IUTEST_LOG_(WARNING) << testsuite_name << "." << name << " is already exist.";
204  }
205 #endif
206  EachTest* test = static_cast<EachTest*>(infodata->RegisterTest(testsuite, name));
207  test->SetParam(p->GetCurrent());
208  ++i;
209  }
210  }
211  }
212  }
213 
214  static ::std::string DefaultParamNameFunc(const TestParamInfo<ParamType>& info)
215  {
216  return Tester::MakeTestParamName(info);
217  }
218 
219  template<typename ParamNameFunctor>
220  static ParamNameFunctor GetParamNameGen(ParamNameFunctor func)
221  {
222  return func;
223  }
224 
225  static pfnParamNameGeneratorFunc GetParamNameGen()
226  {
227  return DefaultParamNameFunc;
228  }
229 
230 private:
231  ::std::string CreateTestSuiteName(const ::std::string& generator_name) const
232  {
233  ::std::string testsuite_name = m_package_name;
234  if( !generator_name.empty() )
235  {
236  testsuite_name += generator_name;
237  testsuite_name += "/";
238  }
239  testsuite_name += m_testsuite_base_name;
240  return testsuite_name;
241  }
242 private:
243  static bool CheckTestName(const TestSuite* testsuite, const::std::string& name)
244  {
245  const int count = testsuite->total_test_count();
246  for(int i = 0; i < count; ++i )
247  {
248  if( detail::IsStringEqual(name.c_str(), testsuite->GetTestInfo(i)->name()) )
249  {
250  return false;
251  }
252  }
253  return true;
254  }
255 private:
256  typedef ::std::pair< ::std::string, Functor > InstantiationPair;
257  typedef ::std::vector<InstantiationPair> InstantiationContainer;
258  InstantiationContainer m_instantiation;
259 };
260 
264 class ParamTestSuiteHolder
265 {
266 private:
267  ~ParamTestSuiteHolder()
268  {
269  // 解放
270  for( TestSuiteInfoContainer::const_iterator it=m_testsuite_infos.begin(), end=m_testsuite_infos.end(); it != end; ++it )
271  {
272  delete *it;
273  }
274  }
275 
276 public:
277  template<typename T>
278  ParamTestSuiteInfo<T>* GetTestSuitePatternHolder(const ::std::string& testsuite
279  , const ::std::string& package IUTEST_APPEND_EXPLICIT_TEMPLATE_TYPE_(T) )
280  {
281  ParamTestSuiteInfo<T>* p = static_cast<ParamTestSuiteInfo<T>*>(FindTestSuitePatternHolder(testsuite, package));
282  if( p == NULL )
283  {
284  p = new ParamTestSuiteInfo<T>(testsuite, package);
285  m_testsuite_infos.push_back(p);
286  }
287  return p;
288  }
289 
290 private:
291  template<typename T>
292  IParamTestSuiteInfo* FindTestSuitePatternHolder(const T& testsuite, const T& package)
293  {
294  for( TestSuiteInfoContainer::iterator it=m_testsuite_infos.begin(), end=m_testsuite_infos.end(); it != end; ++it )
295  {
296  if( (*it)->is_same(testsuite, package) )
297  {
298  return (*it);
299  }
300  }
301  return NULL;
302  }
303 
304 public:
305  size_t count() const { return m_testsuite_infos.size(); }
306 
307 private:
308  // テストを登録
309  void RegisterTests() const
310  {
311  for( TestSuiteInfoContainer::const_iterator it = m_testsuite_infos.begin(); it != m_testsuite_infos.end(); ++it)
312  {
313  (*it)->RegisterTests();
314  }
315  }
316 private:
317  friend class ::iutest::UnitTest;
318  typedef ::std::vector<IParamTestSuiteInfo*> TestSuiteInfoContainer;
319  TestSuiteInfoContainer m_testsuite_infos;
320 };
321 
322 } // end of namespace detail
323 } // end of namespace iutest
324 
325 #endif
326 
327 #endif // INCG_IRIS_IUTEST_PARAMS_UTIL_HPP_19F0C0BB_EEAE_4E8B_B269_A09A4A45E890_
#define IUTEST_CXX_FINAL
final definition
Definition: iutest_compiler.hpp:756
#define IUTEST_CXX_OVERRIDE
override definition
Definition: iutest_compiler.hpp:747
#define IUTEST_CXX_DEFAULT_FUNCTION
default function
Definition: iutest_compiler.hpp:494
iris unit test parameter generator
iris unit test parameter generator from file
iris unit test memory pool
#define IUTEST_LOG_(level)
ログメッセージストリーム
Definition: iutest_port.hpp:56
iutest root namespace
Definition: iutest_charcode.hpp:33
void(* SetUpMethod)()
SetUp 関数型
Definition: iutest_defs.hpp:523
void(* TearDownMethod)()
TearDown 関数型
Definition: iutest_defs.hpp:524
internal::TypeId TestTypeId
テスト識別型
Definition: iutest_defs.hpp:521