| 
									
										
										
										
											2011-01-07 19:57:32 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2012-08-14 19:30:30 +01:00
										 |  |  |  *  Created by Phil on 14/08/2012. | 
					
						
							|  |  |  |  *  Copyright 2012 Two Blue Cubes Ltd. All rights reserved. | 
					
						
							| 
									
										
										
										
											2011-01-07 19:57:32 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  Distributed under the Boost Software License, Version 1.0. (See accompanying | 
					
						
							|  |  |  |  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-14 19:30:30 +01:00
										 |  |  | #include "catch_test_case_info.h"
 | 
					
						
							| 
									
										
										
										
											2017-08-01 18:46:33 +02:00
										 |  |  | #include "catch_enforce.h"
 | 
					
						
							| 
									
										
										
										
											2017-09-07 11:24:33 +01:00
										 |  |  | #include "catch_test_spec.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-07 19:57:32 +00:00
										 |  |  | #include "catch_interfaces_testcase.h"
 | 
					
						
							| 
									
										
										
										
											2017-07-25 21:57:35 +02:00
										 |  |  | #include "catch_string_manip.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-07 19:57:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-12 12:17:07 +01:00
										 |  |  | #include <cctype>
 | 
					
						
							| 
									
										
										
										
											2017-06-04 21:39:27 +02:00
										 |  |  | #include <exception>
 | 
					
						
							| 
									
										
										
										
											2017-07-27 22:31:27 +02:00
										 |  |  | #include <algorithm>
 | 
					
						
							| 
									
										
										
										
											2017-11-07 18:01:10 +00:00
										 |  |  | #include <sstream>
 | 
					
						
							| 
									
										
										
										
											2017-02-12 12:17:07 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 23:58:23 +01:00
										 |  |  | namespace Catch { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-12 16:16:55 +02:00
										 |  |  |     TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { | 
					
						
							| 
									
										
										
										
											2017-01-15 09:41:33 +01:00
										 |  |  |         if( startsWith( tag, '.' ) || | 
					
						
							| 
									
										
										
										
											2014-07-03 08:09:57 +01:00
										 |  |  |             tag == "!hide" ) | 
					
						
							|  |  |  |             return TestCaseInfo::IsHidden; | 
					
						
							|  |  |  |         else if( tag == "!throws" ) | 
					
						
							|  |  |  |             return TestCaseInfo::Throws; | 
					
						
							|  |  |  |         else if( tag == "!shouldfail" ) | 
					
						
							|  |  |  |             return TestCaseInfo::ShouldFail; | 
					
						
							|  |  |  |         else if( tag == "!mayfail" ) | 
					
						
							|  |  |  |             return TestCaseInfo::MayFail; | 
					
						
							| 
									
										
										
										
											2017-01-23 17:44:55 +00:00
										 |  |  |         else if( tag == "!nonportable" ) | 
					
						
							|  |  |  |             return TestCaseInfo::NonPortable; | 
					
						
							| 
									
										
										
										
											2017-08-05 11:26:20 +01:00
										 |  |  |         else if( tag == "!benchmark" ) | 
					
						
							|  |  |  |             return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden ); | 
					
						
							| 
									
										
										
										
											2014-07-03 08:09:57 +01:00
										 |  |  |         else | 
					
						
							|  |  |  |             return TestCaseInfo::None; | 
					
						
							| 
									
										
										
										
											2014-04-15 18:44:37 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-07-12 16:16:55 +02:00
										 |  |  |     bool isReservedTag( std::string const& tag ) { | 
					
						
							| 
									
										
										
										
											2017-01-26 19:11:20 +01:00
										 |  |  |         return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( tag[0] ); | 
					
						
							| 
									
										
										
										
											2014-04-15 18:44:37 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-07-12 16:16:55 +02:00
										 |  |  |     void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { | 
					
						
							| 
									
										
										
										
											2017-06-04 22:37:59 +02:00
										 |  |  |         CATCH_ENFORCE( !isReservedTag(tag), | 
					
						
							|  |  |  |                       "Tag name: [" << tag << "] is not allowed.\n" | 
					
						
							|  |  |  |                       << "Tag names starting with non alpha-numeric characters are reserved\n" | 
					
						
							|  |  |  |                       << _lineInfo ); | 
					
						
							| 
									
										
										
										
											2014-05-16 18:52:55 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-04-15 18:44:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-12 18:01:54 +01:00
										 |  |  |     TestCase makeTestCase(  ITestInvoker* _testCase, | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  |                             std::string const& _className, | 
					
						
							| 
									
										
										
										
											2018-03-02 16:22:18 +01:00
										 |  |  |                             NameAndTags const& nameAndTags, | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  |                             SourceLineInfo const& _lineInfo ) | 
					
						
							| 
									
										
										
										
											2012-09-15 17:53:27 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-08-27 16:45:53 +02:00
										 |  |  |         bool isHidden = false; | 
					
						
							| 
									
										
										
										
											2014-05-16 18:52:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // Parse out tags
 | 
					
						
							| 
									
										
										
										
											2017-07-27 22:31:27 +02:00
										 |  |  |         std::vector<std::string> tags; | 
					
						
							| 
									
										
										
										
											2014-05-16 18:52:55 +01:00
										 |  |  |         std::string desc, tag; | 
					
						
							|  |  |  |         bool inTag = false; | 
					
						
							| 
									
										
										
										
											2018-03-02 16:22:18 +01:00
										 |  |  |         std::string _descOrTags = nameAndTags.tags; | 
					
						
							| 
									
										
										
										
											2017-08-29 14:02:14 +02:00
										 |  |  |         for (char c : _descOrTags) { | 
					
						
							| 
									
										
										
										
											2014-05-16 18:52:55 +01:00
										 |  |  |             if( !inTag ) { | 
					
						
							|  |  |  |                 if( c == '[' ) | 
					
						
							|  |  |  |                     inTag = true; | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                     desc += c; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 if( c == ']' ) { | 
					
						
							| 
									
										
										
										
											2014-12-15 07:25:34 +00:00
										 |  |  |                     TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); | 
					
						
							| 
									
										
										
										
											2017-08-05 22:24:17 +01:00
										 |  |  |                     if( ( prop & TestCaseInfo::IsHidden ) != 0 ) | 
					
						
							| 
									
										
										
										
											2014-05-19 17:50:58 +01:00
										 |  |  |                         isHidden = true; | 
					
						
							| 
									
										
										
										
											2014-12-15 07:25:34 +00:00
										 |  |  |                     else if( prop == TestCaseInfo::None ) | 
					
						
							|  |  |  |                         enforceNotReservedTag( tag, _lineInfo ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-27 22:31:27 +02:00
										 |  |  |                     tags.push_back( tag ); | 
					
						
							| 
									
										
										
										
											2014-05-16 18:52:55 +01:00
										 |  |  |                     tag.clear(); | 
					
						
							| 
									
										
										
										
											2014-12-15 07:25:34 +00:00
										 |  |  |                     inTag = false; | 
					
						
							| 
									
										
										
										
											2014-04-15 18:44:37 +01:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2014-05-16 18:52:55 +01:00
										 |  |  |                 else | 
					
						
							|  |  |  |                     tag += c; | 
					
						
							| 
									
										
										
										
											2014-04-15 18:44:37 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2013-12-04 07:58:39 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2014-05-20 18:11:23 +01:00
										 |  |  |         if( isHidden ) { | 
					
						
							| 
									
										
										
										
											2017-07-27 22:31:27 +02:00
										 |  |  |             tags.push_back( "." ); | 
					
						
							| 
									
										
										
										
											2014-05-20 18:11:23 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-02 16:22:18 +01:00
										 |  |  |         TestCaseInfo info( nameAndTags.name, _className, desc, tags, _lineInfo ); | 
					
						
							|  |  |  |         return TestCase( _testCase, std::move(info) ); | 
					
						
							| 
									
										
										
										
											2012-09-15 17:53:27 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-01-07 19:57:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-27 22:31:27 +02:00
										 |  |  |     void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) { | 
					
						
							|  |  |  |         std::sort(begin(tags), end(tags)); | 
					
						
							|  |  |  |         tags.erase(std::unique(begin(tags), end(tags)), end(tags)); | 
					
						
							| 
									
										
										
										
											2015-07-02 08:20:18 +01:00
										 |  |  |         testCaseInfo.lcaseTags.clear(); | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-25 11:06:52 +01:00
										 |  |  |         for( auto const& tag : tags ) { | 
					
						
							|  |  |  |             std::string lcaseTag = toLower( tag ); | 
					
						
							| 
									
										
										
										
											2015-07-02 08:20:18 +01:00
										 |  |  |             testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) ); | 
					
						
							| 
									
										
										
										
											2017-07-27 22:31:27 +02:00
										 |  |  |             testCaseInfo.lcaseTags.push_back( lcaseTag ); | 
					
						
							| 
									
										
										
										
											2015-07-02 08:20:18 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-07-27 22:31:27 +02:00
										 |  |  |         testCaseInfo.tags = std::move(tags); | 
					
						
							| 
									
										
										
										
											2015-07-02 08:20:18 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-11-04 18:01:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  |     TestCaseInfo::TestCaseInfo( std::string const& _name, | 
					
						
							|  |  |  |                                 std::string const& _className, | 
					
						
							|  |  |  |                                 std::string const& _description, | 
					
						
							| 
									
										
										
										
											2017-07-27 22:31:27 +02:00
										 |  |  |                                 std::vector<std::string> const& _tags, | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  |                                 SourceLineInfo const& _lineInfo ) | 
					
						
							| 
									
										
										
										
											2012-11-25 11:19:55 +00:00
										 |  |  |     :   name( _name ), | 
					
						
							|  |  |  |         className( _className ), | 
					
						
							|  |  |  |         description( _description ), | 
					
						
							| 
									
										
										
										
											2012-12-05 08:40:53 +00:00
										 |  |  |         lineInfo( _lineInfo ), | 
					
						
							| 
									
										
										
										
											2014-07-03 08:09:57 +01:00
										 |  |  |         properties( None ) | 
					
						
							| 
									
										
										
										
											2013-03-28 22:13:31 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2015-07-02 08:20:18 +01:00
										 |  |  |         setTags( *this, _tags ); | 
					
						
							| 
									
										
										
										
											2013-03-28 22:13:31 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-08-14 08:38:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-03 08:09:57 +01:00
										 |  |  |     bool TestCaseInfo::isHidden() const { | 
					
						
							|  |  |  |         return ( properties & IsHidden ) != 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     bool TestCaseInfo::throws() const { | 
					
						
							|  |  |  |         return ( properties & Throws ) != 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     bool TestCaseInfo::okToFail() const { | 
					
						
							|  |  |  |         return ( properties & (ShouldFail | MayFail ) ) != 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     bool TestCaseInfo::expectedToFail() const { | 
					
						
							|  |  |  |         return ( properties & (ShouldFail ) ) != 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-27 22:31:27 +02:00
										 |  |  |     std::string TestCaseInfo::tagsAsString() const { | 
					
						
							|  |  |  |         std::string ret; | 
					
						
							|  |  |  |         // '[' and ']' per tag
 | 
					
						
							| 
									
										
										
										
											2017-09-18 17:13:17 +01:00
										 |  |  |         std::size_t full_size = 2 * tags.size(); | 
					
						
							| 
									
										
										
										
											2017-07-27 22:31:27 +02:00
										 |  |  |         for (const auto& tag : tags) { | 
					
						
							|  |  |  |             full_size += tag.size(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         ret.reserve(full_size); | 
					
						
							|  |  |  |         for (const auto& tag : tags) { | 
					
						
							|  |  |  |             ret.push_back('['); | 
					
						
							|  |  |  |             ret.append(tag); | 
					
						
							|  |  |  |             ret.push_back(']'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return ret; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-03 08:09:57 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-02 16:22:18 +01:00
										 |  |  |     TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {} | 
					
						
							| 
									
										
										
										
											2012-11-25 11:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-23 08:38:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  |     TestCase TestCase::withName( std::string const& _newName ) const { | 
					
						
							| 
									
										
										
										
											2012-11-25 11:19:55 +00:00
										 |  |  |         TestCase other( *this ); | 
					
						
							|  |  |  |         other.name = _newName; | 
					
						
							|  |  |  |         return other; | 
					
						
							| 
									
										
										
										
											2012-08-14 19:30:30 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2011-01-14 08:47:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-11-25 11:19:55 +00:00
										 |  |  |     void TestCase::invoke() const { | 
					
						
							|  |  |  |         test->invoke(); | 
					
						
							| 
									
										
										
										
											2012-08-14 19:30:30 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  |     bool TestCase::operator == ( TestCase const& other ) const { | 
					
						
							| 
									
										
										
										
											2012-11-25 11:19:55 +00:00
										 |  |  |         return  test.get() == other.test.get() && | 
					
						
							|  |  |  |                 name == other.name && | 
					
						
							|  |  |  |                 className == other.className; | 
					
						
							| 
									
										
										
										
											2012-08-14 19:30:30 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  |     bool TestCase::operator < ( TestCase const& other ) const { | 
					
						
							| 
									
										
										
										
											2012-11-25 11:19:55 +00:00
										 |  |  |         return name < other.name; | 
					
						
							| 
									
										
										
										
											2012-08-14 19:30:30 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-09-21 07:48:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-23 18:58:56 +01:00
										 |  |  |     TestCaseInfo const& TestCase::getTestCaseInfo() const | 
					
						
							| 
									
										
										
										
											2012-11-25 11:19:55 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-09-21 07:48:03 +01:00
										 |  |  | } // end namespace Catch
 |