Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/boost/beast/_experimental/unit_test/runner.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
0008 //
0009 
0010 #ifndef BOOST_BEAST_UNIT_TEST_RUNNER_H_INCLUDED
0011 #define BOOST_BEAST_UNIT_TEST_RUNNER_H_INCLUDED
0012 
0013 #include <boost/beast/_experimental/unit_test/suite_info.hpp>
0014 #include <boost/assert.hpp>
0015 #include <mutex>
0016 #include <ostream>
0017 #include <string>
0018 
0019 namespace boost {
0020 namespace beast {
0021 namespace unit_test {
0022 
0023 /** Unit test runner interface.
0024 
0025     Derived classes can customize the reporting behavior. This interface is
0026     injected into the unit_test class to receive the results of the tests.
0027 */
0028 class runner
0029 {
0030     std::string arg_;
0031     bool default_ = false;
0032     bool failed_ = false;
0033     bool cond_ = false;
0034     std::recursive_mutex mutex_;
0035 
0036 public:
0037     runner() = default;
0038     virtual ~runner() = default;
0039     runner(runner const&) = delete;
0040     runner& operator=(runner const&) = delete;
0041 
0042     /** Set the argument string.
0043 
0044         The argument string is available to suites and
0045         allows for customization of the test. Each suite
0046         defines its own syntax for the argument string.
0047         The same argument is passed to all suites.
0048     */
0049     void
0050     arg(std::string const& s)
0051     {
0052         arg_ = s;
0053     }
0054 
0055     /** Returns the argument string. */
0056     std::string const&
0057     arg() const
0058     {
0059         return arg_;
0060     }
0061 
0062     /** Run the specified suite.
0063         @return `true` if any conditions failed.
0064     */
0065     template<class = void>
0066     bool
0067     run(suite_info const& s);
0068 
0069     /** Run a sequence of suites.
0070         The expression
0071             `FwdIter::value_type`
0072         must be convertible to `suite_info`.
0073         @return `true` if any conditions failed.
0074     */
0075     template<class FwdIter>
0076     bool
0077     run(FwdIter first, FwdIter last);
0078 
0079     /** Conditionally run a sequence of suites.
0080         pred will be called as:
0081         @code
0082             bool pred(suite_info const&);
0083         @endcode
0084         @return `true` if any conditions failed.
0085     */
0086     template<class FwdIter, class Pred>
0087     bool
0088     run_if(FwdIter first, FwdIter last, Pred pred = Pred{});
0089 
0090     /** Run all suites in a container.
0091         @return `true` if any conditions failed.
0092     */
0093     template<class SequenceContainer>
0094     bool
0095     run_each(SequenceContainer const& c);
0096 
0097     /** Conditionally run suites in a container.
0098         pred will be called as:
0099         @code
0100             bool pred(suite_info const&);
0101         @endcode
0102         @return `true` if any conditions failed.
0103     */
0104     template<class SequenceContainer, class Pred>
0105     bool
0106     run_each_if(SequenceContainer const& c, Pred pred = Pred{});
0107 
0108 protected:
0109     /// Called when a new suite starts.
0110     virtual
0111     void
0112     on_suite_begin(suite_info const&)
0113     {
0114     }
0115 
0116     /// Called when a suite ends.
0117     virtual
0118     void
0119     on_suite_end()
0120     {
0121     }
0122 
0123     /// Called when a new case starts.
0124     virtual
0125     void
0126     on_case_begin(std::string const&)
0127     {
0128     }
0129 
0130     /// Called when a new case ends.
0131     virtual
0132     void
0133     on_case_end()
0134     {
0135     }
0136 
0137     /// Called for each passing condition.
0138     virtual
0139     void
0140     on_pass()
0141     {
0142     }
0143 
0144     /// Called for each failing condition.
0145     virtual
0146     void
0147     on_fail(std::string const&)
0148     {
0149     }
0150 
0151     /// Called when a test logs output.
0152     virtual
0153     void
0154     on_log(std::string const&)
0155     {
0156     }
0157 
0158 private:
0159     friend class suite;
0160 
0161     // Start a new testcase.
0162     template<class = void>
0163     void
0164     testcase(std::string const& name);
0165 
0166     template<class = void>
0167     void
0168     pass();
0169 
0170     template<class = void>
0171     void
0172     fail(std::string const& reason);
0173 
0174     template<class = void>
0175     void
0176     log(std::string const& s);
0177 };
0178 
0179 //------------------------------------------------------------------------------
0180 
0181 template<class>
0182 bool
0183 runner::run(suite_info const& s)
0184 {
0185     // Enable 'default' testcase
0186     default_ = true;
0187     failed_ = false;
0188     on_suite_begin(s);
0189     s.run(*this);
0190     // Forgot to call pass or fail.
0191     BOOST_ASSERT(cond_);
0192     on_case_end();
0193     on_suite_end();
0194     return failed_;
0195 }
0196 
0197 template<class FwdIter>
0198 bool
0199 runner::run(FwdIter first, FwdIter last)
0200 {
0201     bool failed(false);
0202     for(;first != last; ++first)
0203         failed = run(*first) || failed;
0204     return failed;
0205 }
0206 
0207 template<class FwdIter, class Pred>
0208 bool
0209 runner::run_if(FwdIter first, FwdIter last, Pred pred)
0210 {
0211     bool failed(false);
0212     for(;first != last; ++first)
0213         if(pred(*first))
0214             failed = run(*first) || failed;
0215     return failed;
0216 }
0217 
0218 template<class SequenceContainer>
0219 bool
0220 runner::run_each(SequenceContainer const& c)
0221 {
0222     bool failed(false);
0223     for(auto const& s : c)
0224         failed = run(s) || failed;
0225     return failed;
0226 }
0227 
0228 template<class SequenceContainer, class Pred>
0229 bool
0230 runner::run_each_if(SequenceContainer const& c, Pred pred)
0231 {
0232     bool failed(false);
0233     for(auto const& s : c)
0234         if(pred(s))
0235             failed = run(s) || failed;
0236     return failed;
0237 }
0238 
0239 template<class>
0240 void
0241 runner::testcase(std::string const& name)
0242 {
0243     std::lock_guard<std::recursive_mutex> lock(mutex_);
0244     // Name may not be empty
0245     BOOST_ASSERT(default_ || ! name.empty());
0246     // Forgot to call pass or fail
0247     BOOST_ASSERT(default_ || cond_);
0248     if(! default_)
0249         on_case_end();
0250     default_ = false;
0251     cond_ = false;
0252     on_case_begin(name);
0253 }
0254 
0255 template<class>
0256 void
0257 runner::pass()
0258 {
0259     std::lock_guard<std::recursive_mutex> lock(mutex_);
0260     if(default_)
0261         testcase("");
0262     on_pass();
0263     cond_ = true;
0264 }
0265 
0266 template<class>
0267 void
0268 runner::fail(std::string const& reason)
0269 {
0270     std::lock_guard<std::recursive_mutex> lock(mutex_);
0271     if(default_)
0272         testcase("");
0273     on_fail(reason);
0274     failed_ = true;
0275     cond_ = true;
0276 }
0277 
0278 template<class>
0279 void
0280 runner::log(std::string const& s)
0281 {
0282     std::lock_guard<std::recursive_mutex> lock(mutex_);
0283     if(default_)
0284         testcase("");
0285     on_log(s);
0286 }
0287 
0288 } // unit_test
0289 } // beast
0290 } // boost
0291 
0292 #endif