blob: 12691f503bc3607aea824e738f9660f306f33460 [file] [log] [blame]
Jeff Thompsonef2d5a42013-08-22 19:09:24 -07001// (C) Copyright Gennadiy Rozental 2001-2008.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// http://www.boost.org/LICENSE_1_0.txt)
5
6// See http://www.boost.org/libs/test for the library home page.
7//
8// File : $RCSfile$
9//
10// Version : $Revision: 54633 $
11//
12// Description : main function implementation for Unit Test Framework
13// ***************************************************************************
14
Jeff Thompson3d613fd2013-10-15 15:39:04 -070015#ifndef NDNBOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER
16#define NDNBOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER
Jeff Thompsonef2d5a42013-08-22 19:09:24 -070017
18// Boost.Test
19#include <ndnboost/test/framework.hpp>
20#include <ndnboost/test/results_collector.hpp>
21#include <ndnboost/test/unit_test_suite_impl.hpp>
22#include <ndnboost/test/results_reporter.hpp>
23
24#include <ndnboost/test/detail/unit_test_parameters.hpp>
25
Jeff Thompson3d613fd2013-10-15 15:39:04 -070026#if !defined(__BORLANDC__) && !NDNBOOST_WORKAROUND( NDNBOOST_MSVC, < 1300 ) && !NDNBOOST_WORKAROUND( __SUNPRO_CC, < 0x5100 )
27#define NDNBOOST_TEST_SUPPORT_RUN_BY_NAME
Jeff Thompsonef2d5a42013-08-22 19:09:24 -070028#include <ndnboost/test/utils/iterator/token_iterator.hpp>
29#endif
30
31// Boost
32#include <ndnboost/cstdlib.hpp>
33#include <ndnboost/bind.hpp>
34
35// STL
36#include <stdexcept>
37#include <iostream>
38
39#include <ndnboost/test/detail/suppress_warnings.hpp>
40
41//____________________________________________________________________________//
42
43namespace ndnboost {
44
45namespace unit_test {
46
47// ************************************************************************** //
48// ************** test_case_filter ************** //
49// ************************************************************************** //
50
51class test_case_filter : public test_tree_visitor {
52public:
53 struct single_filter {
54 single_filter( const_string in )
55 {
56 if( in == "*" )
57 m_kind = SFK_ALL;
58 else if( first_char( in ) == '*' && last_char( in ) == '*' ) {
59 m_kind = SFK_SUBSTR;
60 m_value = in.substr( 1, in.size()-1 );
61 }
62 else if( first_char( in ) == '*' ) {
63 m_kind = SFK_TRAILING;
64 m_value = in.substr( 1 );
65 }
66 else if( last_char( in ) == '*' ) {
67 m_kind = SFK_LEADING;
68 m_value = in.substr( 0, in.size()-1 );
69 }
70 else {
71 m_kind = SFK_MATCH;
72 m_value = in;
73 }
74 };
75
76 bool pass( test_unit const& tu ) const
77 {
78 const_string name( tu.p_name );
79
80 switch( m_kind ) {
81 default:
82 case SFK_ALL:
83 return true;
84
85 case SFK_LEADING:
86 return name.substr( 0, m_value.size() ) == m_value;
87
88 case SFK_TRAILING:
89 return name.size() >= m_value.size() && name.substr( name.size() - m_value.size() ) == m_value;
90
91 case SFK_SUBSTR:
92 return name.find( m_value ) != const_string::npos;
93
94 case SFK_MATCH:
95 return m_value == tu.p_name.get();
96 }
97 }
98 enum kind { SFK_ALL, SFK_LEADING, SFK_TRAILING, SFK_SUBSTR, SFK_MATCH };
99
100 kind m_kind;
101 const_string m_value;
102 };
103 // Constructor
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700104#ifndef NDNBOOST_TEST_SUPPORT_RUN_BY_NAME
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700105 explicit test_case_filter( const_string ) : m_depth( 0 ) {}
106#else
107 explicit test_case_filter( const_string tc_to_run )
108 : m_depth( 0 )
109 {
110 string_token_iterator tit( tc_to_run, (dropped_delimeters = "/", kept_delimeters = dt_none) );
111
112 while( tit != string_token_iterator() ) {
113 m_filters.push_back(
114 std::vector<single_filter>( string_token_iterator( *tit, (dropped_delimeters = ",", kept_delimeters = dt_none) ),
115 string_token_iterator() ) );
116
117 ++tit;
118 }
119 }
120#endif
121
122 void filter_unit( test_unit const& tu )
123 {
124 if( (++m_depth - 1) > m_filters.size() ) {
125 tu.p_enabled.value = true;
126 return;
127 }
128
129 if( m_depth == 1 )
130 return;
131
132 std::vector<single_filter> const& filters = m_filters[m_depth-2];
133
134 tu.p_enabled.value =
135 std::find_if( filters.begin(), filters.end(), bind( &single_filter::pass, _1, ndnboost::ref(tu) ) ) != filters.end();
136 }
137
138 // test tree visitor interface
139 virtual void visit( test_case const& tc )
140 {
141 if( m_depth < m_filters.size() ) {
142 tc.p_enabled.value = false;
143 return;
144 }
145
146 filter_unit( tc );
147
148 --m_depth;
149 }
150
151 virtual bool test_suite_start( test_suite const& ts )
152 {
153 filter_unit( ts );
154
155 if( !ts.p_enabled )
156 --m_depth;
157
158 return ts.p_enabled;
159 }
160
161 virtual void test_suite_finish( test_suite const& ) { --m_depth; }
162
163private:
164 // Data members
165 std::vector<std::vector<single_filter> > m_filters;
166 unsigned m_depth;
167};
168
169// ************************************************************************** //
170// ************** unit_test_main ************** //
171// ************************************************************************** //
172
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700173int NDNBOOST_TEST_DECL
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700174unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
175{
176 try {
177 framework::init( init_func, argc, argv );
178
179 if( !runtime_config::test_to_run().is_empty() ) {
180 test_case_filter filter( runtime_config::test_to_run() );
181
182 traverse_test_tree( framework::master_test_suite().p_id, filter );
183 }
184
185 framework::run();
186
187 results_reporter::make_report();
188
189 return runtime_config::no_result_code()
190 ? ndnboost::exit_success
191 : results_collector.results( framework::master_test_suite().p_id ).result_code();
192 }
193 catch( framework::nothing_to_test const& ) {
194 return ndnboost::exit_success;
195 }
196 catch( framework::internal_error const& ex ) {
197 results_reporter::get_stream() << "Boost.Test framework internal error: " << ex.what() << std::endl;
198
199 return ndnboost::exit_exception_failure;
200 }
201 catch( framework::setup_error const& ex ) {
202 results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl;
203
204 return ndnboost::exit_exception_failure;
205 }
206 catch( ... ) {
207 results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl;
208
209 return ndnboost::exit_exception_failure;
210 }
211}
212
213} // namespace unit_test
214
215} // namespace ndnboost
216
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700217#if !defined(NDNBOOST_TEST_DYN_LINK) && !defined(NDNBOOST_TEST_NO_MAIN)
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700218
219// ************************************************************************** //
220// ************** main function for tests using lib ************** //
221// ************************************************************************** //
222
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700223int NDNBOOST_TEST_CALL_DECL
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700224main( int argc, char* argv[] )
225{
226 // prototype for user's unit test init function
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700227#ifdef NDNBOOST_TEST_ALTERNATIVE_INIT_API
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700228 extern bool init_unit_test();
229
230 ndnboost::unit_test::init_unit_test_func init_func = &init_unit_test;
231#else
232 extern ::ndnboost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] );
233
234 ndnboost::unit_test::init_unit_test_func init_func = &init_unit_test_suite;
235#endif
236
237 return ::ndnboost::unit_test::unit_test_main( init_func, argc, argv );
238}
239
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700240#endif // !NDNBOOST_TEST_DYN_LINK && !NDNBOOST_TEST_NO_MAIN
Jeff Thompsonef2d5a42013-08-22 19:09:24 -0700241
242//____________________________________________________________________________//
243
244#include <ndnboost/test/detail/enable_warnings.hpp>
245
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700246#endif // NDNBOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER