iutest  1.17.1.0
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 #include "iutest_genparams.hpp"
22 
23 #if IUTEST_HAS_PARAM_TEST
24 #include "iutest_pool.hpp"
25 
26 namespace iutest {
27 namespace detail
28 {
29 
30 //======================================================================
31 // class
32 
36 class IParamTestInfoData
37 {
38 public:
39  class EachTestBase : public iuIObject {};
40  template<typename T>
41  class ParamEachTestBase : public EachTestBase
42  {
43  public:
44  virtual void SetParam(const T& param) = 0;
45  };
46 public:
47  explicit IParamTestInfoData(const char* name) : m_name(name) {}
48  virtual ~IParamTestInfoData() IUTEST_CXX_DEFAULT_FUNCTION
49  virtual TestCase* MakeTestCase(const ::std::string& , TestTypeId , SetUpMethod , TearDownMethod ) const = 0;
50  virtual EachTestBase* RegisterTest(TestCase* , const ::std::string& ) const = 0;
51  const char* GetName() const { return m_name.c_str(); }
52 protected:
53  ::std::string m_name;
54 };
55 
59 class IParamTestCaseInfo
60 {
61 public:
62  virtual ~IParamTestCaseInfo() {}
63 protected:
64  IParamTestCaseInfo(const ::std::string& base_name, const ::std::string& package_name)
65  : m_testcase_base_name(base_name), m_package_name(package_name) {}
66  IParamTestCaseInfo(const char* base_name, const char* package_name)
67  : m_testcase_base_name(base_name), m_package_name(package_name) {}
68 
69 public:
73  void AddTestPattern(IParamTestInfoData* testinfo)
74  {
75  m_testinfos.push_back(testinfo);
76  }
77 
78 public:
79  void RegisterTests() const
80  {
81  for( TestInfoContainer::const_iterator it=m_testinfos.begin(), end=m_testinfos.end(); it != end; ++it )
82  {
83  OnRegisterTests(*it);
84  }
85  }
86 
87  ::std::string GetTestCaseBaseName() const { return m_testcase_base_name; }
88  ::std::string GetPackageName() const { return m_package_name; }
89 
90 public:
91  bool is_same(const ::std::string& base_name, const ::std::string& package_name)
92  {
93  return m_testcase_base_name == base_name && m_package_name == package_name;
94  }
95  bool is_same(const char* base_name, const char* package_name)
96  {
97  return m_testcase_base_name == base_name && m_package_name == package_name;
98  }
99 
100 private:
101  virtual void OnRegisterTests(IParamTestInfoData*) const = 0;
102 private:
103  typedef ::std::vector<IParamTestInfoData*> TestInfoContainer;
104  TestInfoContainer m_testinfos;
105 protected:
106  ::std::string m_testcase_base_name;
107  ::std::string m_package_name;
108 };
109 
114 template<class T>
115 class ParamTestCaseInfo : public IParamTestCaseInfo
116 {
117  typedef T Tester;
118  typedef typename Tester::ParamType ParamType;
119  typedef detail::iuIParamGenerator<ParamType> ParamGenerator;
120  typedef typename ParamGenerator::Generator Generator;
121  typedef IParamTestInfoData::ParamEachTestBase<ParamType> EachTest;
122 
123  typedef ::std::vector<IParamTestInfoData*> TestInfoContainer;
124 
125  typedef ParamGenerator* (*pfnCreateGeneratorFunc)();
126  typedef ::std::string (*pfnParamNameGeneratorFunc)(const TestParamInfo<ParamType>&);
127 
128  class Functor
129  {
130  public:
131  Functor()
132  : CreateGen(NULL), ParamNameGen(NULL) {}
133  Functor(pfnCreateGeneratorFunc c, pfnParamNameGeneratorFunc p)
134  : CreateGen(c), ParamNameGen(p) {}
135  pfnCreateGeneratorFunc CreateGen;
136  pfnParamNameGeneratorFunc ParamNameGen;
137  };
138 
139 public:
141  ParamTestCaseInfo(const ::std::string& testcase_name, const ::std::string& package_name)
142  : IParamTestCaseInfo(testcase_name, package_name)
143  {
144  }
145  ParamTestCaseInfo(const char* testcase_name, const char* package_name)
146  : IParamTestCaseInfo(testcase_name, package_name)
147  {
148  }
149  virtual ~ParamTestCaseInfo() {}
150 
154  int AddTestCaseInstantiation(::std::string name
155  , pfnCreateGeneratorFunc create_func, pfnParamNameGeneratorFunc paramname_func)
156  {
157 #if IUTEST_HAS_STD_EMPLACE
158  m_instantiation.emplace_back(name, Functor(create_func, paramname_func));
159 #else
160  m_instantiation.push_back(InstantiationPair(name, Functor(create_func, paramname_func)));
161 #endif
162  return 0;
163  }
164 
168  virtual void OnRegisterTests(IParamTestInfoData* infodata) const IUTEST_CXX_OVERRIDE
169  {
170  for( typename InstantiationContainer::const_iterator gen_it=m_instantiation.begin()
171  , gen_end=m_instantiation.end(); gen_it != gen_end; ++gen_it )
172  {
173  // パラメータ生成器の作成
174  detail::scoped_ptr<ParamGenerator> p((gen_it->second.CreateGen)());
175 
176  const ::std::string testcase_name = CreateTestCaseName(gen_it->first);
177  TestCase* testcase = infodata->MakeTestCase(testcase_name
178  , internal::GetTypeId<Tester>()
179  , Tester::SetUpTestCase
180  , Tester::TearDownTestCase);
181 
182  if( p.get() != NULL )
183  {
184  size_t i=0;
185  for( p->Begin(); !p->IsEnd(); p->Next() )
186  {
187  const ::std::string name = MakeParamTestName(infodata->GetName()
188  , gen_it->second.ParamNameGen(TestParamInfo<ParamType>(p->GetCurrent(), i)) );
189 #if IUTEST_CHECK_STRICT
190  if( !CheckTestName(testcase, name) )
191  {
192  IUTEST_LOG_(WARNING) << testcase_name << "." << name << " is already exist.";
193  }
194 #endif
195  EachTest* test = static_cast<EachTest*>(infodata->RegisterTest(testcase, name));
196  test->SetParam(p->GetCurrent());
197  ++i;
198  }
199  }
200  }
201  }
202 
203  static ::std::string DefaultParamNameFunc(const TestParamInfo<ParamType>& info)
204  {
205  return Tester::MakeTestParamName(info);
206  }
207 
208  template<typename ParamNameFunctor>
209  static ParamNameFunctor GetParamNameGen(ParamNameFunctor func)
210  {
211  return func;
212  }
213 
214  static pfnParamNameGeneratorFunc GetParamNameGen()
215  {
216  return DefaultParamNameFunc;
217  }
218 
219 private:
220  ::std::string CreateTestCaseName(const ::std::string& generator_name) const
221  {
222  ::std::string testcase_name = m_package_name;
223  if( !generator_name.empty() )
224  {
225  testcase_name += generator_name;
226  testcase_name += "/";
227  }
228  testcase_name += m_testcase_base_name;
229  return testcase_name;
230  }
231 private:
232  static bool CheckTestName(const TestCase* testcase, const::std::string& name)
233  {
234  const int count = testcase->total_test_count();
235  for(int i = 0; i < count; ++i )
236  {
237  if( detail::IsStringEqual(name.c_str(), testcase->GetTestInfo(i)->name()) )
238  {
239  return false;
240  }
241  }
242  return true;
243  }
244 private:
245  typedef ::std::pair< ::std::string, Functor > InstantiationPair;
246  typedef ::std::vector<InstantiationPair> InstantiationContainer;
247  InstantiationContainer m_instantiation;
248 };
249 
253 class ParamTestCaseHolder
254 {
255 private:
256  ~ParamTestCaseHolder()
257  {
258  // 解放
259  for( TestCaseInfoContainer::const_iterator it=m_testcase_infos.begin(), end=m_testcase_infos.end(); it != end; ++it )
260  {
261  delete *it;
262  }
263  }
264 
265 public:
266  template<typename T>
267  ParamTestCaseInfo<T>* GetTestCasePatternHolder(const ::std::string& testcase
268  , const ::std::string& package IUTEST_APPEND_EXPLICIT_TEMPLATE_TYPE_(T) )
269  {
270  ParamTestCaseInfo<T>* p = static_cast<ParamTestCaseInfo<T>*>(FindTestCasePatternHolder(testcase, package));
271  if( p == NULL )
272  {
273  p = new ParamTestCaseInfo<T>(testcase, package);
274  m_testcase_infos.push_back(p);
275  }
276  return p;
277  }
278 
279 private:
280  template<typename T>
281  IParamTestCaseInfo* FindTestCasePatternHolder(const T& testcase, const T& package)
282  {
283  for( TestCaseInfoContainer::iterator it=m_testcase_infos.begin(), end=m_testcase_infos.end(); it != end; ++it )
284  {
285  if( (*it)->is_same(testcase, package) )
286  {
287  return (*it);
288  }
289  }
290  return NULL;
291  }
292 
293 public:
294  size_t count() const { return m_testcase_infos.size(); }
295 
296 private:
297  struct RegisterTestsFunctor
298  {
299  inline void operator ()(const IParamTestCaseInfo* p) const
300  {
301  p->RegisterTests();
302  }
303  };
304 
305  // テストを登録
306  void RegisterTests()
307  {
308  ::std::for_each(m_testcase_infos.begin(), m_testcase_infos.end(), RegisterTestsFunctor());
309  }
310 private:
311  friend class ::iutest::UnitTest;
312  typedef ::std::vector<IParamTestCaseInfo*> TestCaseInfoContainer;
313  TestCaseInfoContainer m_testcase_infos;
314 };
315 
316 } // end of namespace detail
317 } // end of namespace iutest
318 
319 #endif
320 
321 #endif // INCG_IRIS_IUTEST_PARAMS_UTIL_HPP_19F0C0BB_EEAE_4E8B_B269_A09A4A45E890_
IUTEST_CXX_DEFAULT_FUNCTION
#define IUTEST_CXX_DEFAULT_FUNCTION
default function
Definition: iutest_compiler.hpp:420
iutest_config.hpp
iris unit test config
iutest_genparams_from_file.hpp
iris unit test parameter generator from file
iutest
iutest root namespace
Definition: iutest_charcode.hpp:31
IUTEST_LOG_
#define IUTEST_LOG_(level)
ログメッセージストリーム
Definition: iutest_port.hpp:53
iutest::TestTypeId
internal::TypeId TestTypeId
テスト識別型
Definition: iutest_defs.hpp:440
IUTEST_CXX_OVERRIDE
#define IUTEST_CXX_OVERRIDE
override definition
Definition: iutest_compiler.hpp:670
iutest::TearDownMethod
void(* TearDownMethod)()
TearDown 関数型
Definition: iutest_defs.hpp:443
iutest::SetUpMethod
void(* SetUpMethod)()
SetUp 関数型
Definition: iutest_defs.hpp:442
iutest_pool.hpp
iris unit test memory pool
iutest_genparams.hpp
iris unit test parameter generator