MatchersRanges.tests.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834
  1. // Copyright Catch2 Authors
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // https://www.boost.org/LICENSE_1_0.txt)
  5. // SPDX-License-Identifier: BSL-1.0
  6. #include <catch2/catch_test_macros.hpp>
  7. #include <catch2/matchers/catch_matchers_container_properties.hpp>
  8. #include <catch2/matchers/catch_matchers_contains.hpp>
  9. #include <catch2/matchers/catch_matchers_floating_point.hpp>
  10. #include <catch2/matchers/catch_matchers_quantifiers.hpp>
  11. #include <catch2/matchers/catch_matchers_predicate.hpp>
  12. #include <catch2/matchers/catch_matchers_string.hpp>
  13. #include <cmath>
  14. #include <initializer_list>
  15. #include <list>
  16. #include <map>
  17. #include <type_traits>
  18. #include <vector>
  19. #include <memory>
  20. namespace {
  21. namespace unrelated {
  22. template <typename T>
  23. class needs_ADL_begin {
  24. std::vector<T> m_elements;
  25. public:
  26. using iterator = typename std::vector<T>::iterator;
  27. using const_iterator = typename std::vector<T>::const_iterator;
  28. needs_ADL_begin(std::initializer_list<T> init) : m_elements(init) {}
  29. const_iterator Begin() const { return m_elements.begin(); }
  30. const_iterator End() const { return m_elements.end(); }
  31. friend const_iterator begin(needs_ADL_begin const& lhs) {
  32. return lhs.Begin();
  33. }
  34. friend const_iterator end(needs_ADL_begin const& rhs) {
  35. return rhs.End();
  36. }
  37. };
  38. } // end unrelated namespace
  39. #if defined(__clang__)
  40. # pragma clang diagnostic push
  41. # pragma clang diagnostic ignored "-Wunused-function"
  42. #endif
  43. template <typename T>
  44. class has_different_begin_end_types {
  45. // Using std::vector<T> leads to annoying issues when T is bool
  46. // so we just use list because the perf is not critical and ugh.
  47. std::list<T> m_elements;
  48. // Different type for the "end" iterator
  49. struct iterator_end {};
  50. // Fake-ish forward iterator that only compares to a different type
  51. class iterator {
  52. using underlying_iter = typename std::list<T>::const_iterator;
  53. underlying_iter m_start;
  54. underlying_iter m_end;
  55. public:
  56. iterator( underlying_iter start, underlying_iter end ):
  57. m_start( start ), m_end( end ) {}
  58. using iterator_category = std::forward_iterator_tag;
  59. using difference_type = std::ptrdiff_t;
  60. using value_type = T;
  61. using const_reference = T const&;
  62. using pointer = T const*;
  63. friend bool operator==( iterator iter, iterator_end ) {
  64. return iter.m_start == iter.m_end;
  65. }
  66. friend bool operator!=( iterator iter, iterator_end ) {
  67. return iter.m_start != iter.m_end;
  68. }
  69. iterator& operator++() {
  70. ++m_start;
  71. return *this;
  72. }
  73. iterator operator++(int) {
  74. auto tmp(*this);
  75. ++m_start;
  76. return tmp;
  77. }
  78. const_reference operator*() const {
  79. return *m_start;
  80. }
  81. pointer operator->() const {
  82. return m_start;
  83. }
  84. };
  85. public:
  86. explicit has_different_begin_end_types( std::initializer_list<T> init ):
  87. m_elements( init ) {}
  88. iterator begin() const {
  89. return { m_elements.begin(), m_elements.end() };
  90. }
  91. iterator_end end() const {
  92. return {};
  93. }
  94. };
  95. #if defined(__clang__)
  96. # pragma clang diagnostic pop
  97. #endif
  98. template <typename T> struct with_mocked_iterator_access {
  99. std::vector<T> m_elements;
  100. // use plain arrays to have nicer printouts with CHECK(...)
  101. mutable std::unique_ptr<bool[]> m_derefed;
  102. // We want to check which elements were dereferenced when iterating, so
  103. // we can check whether iterator-using code traverses range correctly
  104. template <bool is_const> class basic_iterator {
  105. template <typename U>
  106. using constify_t = std::conditional_t<is_const, std::add_const_t<U>, U>;
  107. constify_t<with_mocked_iterator_access>* m_origin;
  108. size_t m_origin_idx;
  109. public:
  110. using iterator_category = std::forward_iterator_tag;
  111. using difference_type = std::ptrdiff_t;
  112. using value_type = constify_t<T>;
  113. using const_reference = typename std::vector<T>::const_reference;
  114. using reference = typename std::vector<T>::reference;
  115. using pointer = typename std::vector<T>::pointer;
  116. basic_iterator( constify_t<with_mocked_iterator_access>* origin,
  117. std::size_t origin_idx ):
  118. m_origin{ origin }, m_origin_idx{ origin_idx } {}
  119. friend bool operator==( basic_iterator lhs, basic_iterator rhs ) {
  120. return lhs.m_origin == rhs.m_origin &&
  121. lhs.m_origin_idx == rhs.m_origin_idx;
  122. }
  123. friend bool operator!=( basic_iterator lhs, basic_iterator rhs ) {
  124. return !( lhs == rhs );
  125. }
  126. basic_iterator& operator++() {
  127. ++m_origin_idx;
  128. return *this;
  129. }
  130. basic_iterator operator++( int ) {
  131. auto tmp( *this );
  132. ++( *this );
  133. return tmp;
  134. }
  135. const_reference operator*() const {
  136. assert( m_origin_idx < m_origin->m_elements.size() && "Attempted to deref invalid position" );
  137. m_origin->m_derefed[m_origin_idx] = true;
  138. return m_origin->m_elements[m_origin_idx];
  139. }
  140. pointer operator->() const {
  141. assert( m_origin_idx < m_origin->m_elements.size() && "Attempted to deref invalid position" );
  142. return &m_origin->m_elements[m_origin_idx];
  143. }
  144. };
  145. using iterator = basic_iterator<false>;
  146. using const_iterator = basic_iterator<true>;
  147. with_mocked_iterator_access( std::initializer_list<T> init ):
  148. m_elements( init ),
  149. m_derefed( std::make_unique<bool[]>( m_elements.size() ) ) {}
  150. const_iterator begin() const { return { this, 0 }; }
  151. const_iterator end() const { return { this, m_elements.size() }; }
  152. iterator begin() { return { this, 0 }; }
  153. iterator end() { return { this, m_elements.size() }; }
  154. };
  155. } // end anon namespace
  156. namespace Catch {
  157. // make sure with_mocked_iterator_access is not considered a range by Catch,
  158. // so that below StringMaker is used instead of the default one for ranges
  159. template <typename T>
  160. struct is_range<with_mocked_iterator_access<T>> : std::false_type {};
  161. template <typename T>
  162. struct StringMaker<with_mocked_iterator_access<T>> {
  163. static std::string
  164. convert( with_mocked_iterator_access<T> const& access ) {
  165. // We have to avoid the type's iterators, because we check
  166. // their use in tests
  167. return ::Catch::Detail::stringify( access.m_elements );
  168. }
  169. };
  170. } // namespace Catch
  171. struct MoveOnlyTestElement {
  172. int num = 0;
  173. MoveOnlyTestElement(int n) :num(n) {}
  174. MoveOnlyTestElement(MoveOnlyTestElement&& rhs) = default;
  175. MoveOnlyTestElement& operator=(MoveOnlyTestElement&& rhs) = default;
  176. friend bool operator==(MoveOnlyTestElement const& lhs, MoveOnlyTestElement const& rhs) {
  177. return lhs.num == rhs.num;
  178. }
  179. friend std::ostream& operator<<(std::ostream& out, MoveOnlyTestElement const& elem) {
  180. out << elem.num;
  181. return out;
  182. }
  183. };
  184. TEST_CASE("Basic use of the Contains range matcher", "[matchers][templated][contains]") {
  185. using Catch::Matchers::Contains;
  186. SECTION("Different argument ranges, same element type, default comparison") {
  187. std::array<int, 3> a{ { 1,2,3 } };
  188. std::vector<int> b{ 0,1,2 };
  189. std::list<int> c{ 4,5,6 };
  190. // A contains 1
  191. REQUIRE_THAT(a, Contains(1));
  192. // B contains 1
  193. REQUIRE_THAT(b, Contains(1));
  194. // C does not contain 1
  195. REQUIRE_THAT(c, !Contains(1));
  196. }
  197. SECTION("Different argument ranges, same element type, custom comparison") {
  198. std::array<int, 3> a{ { 1,2,3 } };
  199. std::vector<int> b{ 0,1,2 };
  200. std::list<int> c{ 4,5,6 };
  201. auto close_enough = [](int lhs, int rhs) { return std::abs(lhs - rhs) <= 1; };
  202. // A contains 1, which is "close enough" to 0
  203. REQUIRE_THAT(a, Contains(0, close_enough));
  204. // B contains 0 directly
  205. REQUIRE_THAT(b, Contains(0, close_enough));
  206. // C does not contain anything "close enough" to 0
  207. REQUIRE_THAT(c, !Contains(0, close_enough));
  208. }
  209. SECTION("Different element type, custom comparisons") {
  210. std::array<std::string, 3> a{ { "abc", "abcd" , "abcde" } };
  211. REQUIRE_THAT(a, Contains(4, [](auto&& lhs, size_t sz) {
  212. return lhs.size() == sz;
  213. }));
  214. }
  215. SECTION("Can handle type that requires ADL-found free function begin and end") {
  216. unrelated::needs_ADL_begin<int> in{1, 2, 3, 4, 5};
  217. REQUIRE_THAT(in, Contains(1));
  218. REQUIRE_THAT(in, !Contains(8));
  219. }
  220. SECTION("Initialization with move only types") {
  221. std::array<MoveOnlyTestElement, 3> in{ { MoveOnlyTestElement{ 1 }, MoveOnlyTestElement{ 2 }, MoveOnlyTestElement{ 3 } } };
  222. REQUIRE_THAT(in, Contains(MoveOnlyTestElement{ 2 }));
  223. REQUIRE_THAT(in, !Contains(MoveOnlyTestElement{ 9 }));
  224. }
  225. SECTION("Matching using matcher") {
  226. std::array<double, 4> in{ {1, 2, 3} };
  227. REQUIRE_THAT(in, Contains(Catch::Matchers::WithinAbs(0.5, 0.5)));
  228. }
  229. }
  230. namespace {
  231. struct has_empty {
  232. bool empty() const { return false; }
  233. };
  234. namespace unrelated {
  235. struct ADL_empty {
  236. bool Empty() const { return true; }
  237. friend bool empty(ADL_empty e) {
  238. return e.Empty();
  239. }
  240. };
  241. } // end namespace unrelated
  242. } // end unnamed namespace
  243. TEST_CASE("Basic use of the Empty range matcher", "[matchers][templated][empty]") {
  244. using Catch::Matchers::IsEmpty;
  245. SECTION("Simple, std-provided containers") {
  246. std::array<int, 0> empty_array{};
  247. std::array<double, 1> non_empty_array{};
  248. REQUIRE_THAT(empty_array, IsEmpty());
  249. REQUIRE_THAT(non_empty_array, !IsEmpty());
  250. std::vector<std::string> empty_vec;
  251. std::vector<char> non_empty_vec{ 'a', 'b', 'c' };
  252. REQUIRE_THAT(empty_vec, IsEmpty());
  253. REQUIRE_THAT(non_empty_vec, !IsEmpty());
  254. std::list<std::list<std::list<int>>> inner_lists_are_empty;
  255. inner_lists_are_empty.push_back({});
  256. REQUIRE_THAT(inner_lists_are_empty, !IsEmpty());
  257. REQUIRE_THAT(inner_lists_are_empty.front(), IsEmpty());
  258. }
  259. SECTION("Type with empty") {
  260. REQUIRE_THAT(has_empty{}, !IsEmpty());
  261. }
  262. SECTION("Type requires ADL found empty free function") {
  263. REQUIRE_THAT(unrelated::ADL_empty{}, IsEmpty());
  264. }
  265. }
  266. namespace {
  267. class LessThanMatcher final : public Catch::Matchers::MatcherBase<size_t> {
  268. size_t m_target;
  269. public:
  270. explicit LessThanMatcher(size_t target):
  271. m_target(target)
  272. {}
  273. bool match(size_t const& size) const override {
  274. return size < m_target;
  275. }
  276. std::string describe() const override {
  277. return "is less than " + std::to_string(m_target);
  278. }
  279. };
  280. LessThanMatcher Lt(size_t sz) {
  281. return LessThanMatcher{ sz };
  282. }
  283. namespace unrelated {
  284. struct ADL_size {
  285. size_t sz() const {
  286. return 12;
  287. }
  288. friend size_t size(ADL_size s) {
  289. return s.sz();
  290. }
  291. };
  292. } // end namespace unrelated
  293. struct has_size {
  294. size_t size() const {
  295. return 13;
  296. }
  297. };
  298. } // end unnamed namespace
  299. TEST_CASE("Usage of the SizeIs range matcher", "[matchers][templated][size]") {
  300. using Catch::Matchers::SizeIs;
  301. SECTION("Some with stdlib containers") {
  302. std::vector<int> empty_vec;
  303. REQUIRE_THAT(empty_vec, SizeIs(0));
  304. REQUIRE_THAT(empty_vec, !SizeIs(2));
  305. REQUIRE_THAT(empty_vec, SizeIs(Lt(2)));
  306. std::array<int, 2> arr{};
  307. REQUIRE_THAT(arr, SizeIs(2));
  308. REQUIRE_THAT(arr, SizeIs( Lt(3)));
  309. REQUIRE_THAT(arr, !SizeIs(!Lt(3)));
  310. std::map<int, int> map{ {1, 1}, {2, 2}, {3, 3} };
  311. REQUIRE_THAT(map, SizeIs(3));
  312. }
  313. SECTION("Type requires ADL found size free function") {
  314. REQUIRE_THAT(unrelated::ADL_size{}, SizeIs(12));
  315. }
  316. SECTION("Type has size member") {
  317. REQUIRE_THAT(has_size{}, SizeIs(13));
  318. }
  319. }
  320. TEST_CASE("Usage of AllMatch range matcher", "[matchers][templated][quantifiers]") {
  321. using Catch::Matchers::AllMatch;
  322. using Catch::Matchers::Predicate;
  323. SECTION("Basic usage") {
  324. using Catch::Matchers::Contains;
  325. using Catch::Matchers::SizeIs;
  326. std::array<std::array<int, 5>, 5> data{{
  327. {{ 0, 1, 2, 3, 5 }},
  328. {{ 4,-3,-2, 5, 0 }},
  329. {{ 0, 0, 0, 5, 0 }},
  330. {{ 0,-5, 0, 5, 0 }},
  331. {{ 1, 0, 0,-1, 5 }}
  332. }};
  333. REQUIRE_THAT(data, AllMatch(SizeIs(5)));
  334. REQUIRE_THAT(data, !AllMatch(Contains(0) && Contains(1)));
  335. }
  336. SECTION("Type requires ADL found begin and end") {
  337. unrelated::needs_ADL_begin<int> needs_adl{ 1, 2, 3, 4, 5 };
  338. REQUIRE_THAT( needs_adl, AllMatch( Predicate<int>( []( int elem ) {
  339. return elem < 6;
  340. } ) ) );
  341. }
  342. SECTION("Shortcircuiting") {
  343. with_mocked_iterator_access<int> mocked{ 1, 2, 3, 4, 5 };
  344. SECTION("All are read") {
  345. auto allMatch = AllMatch(Predicate<int>([](int elem) {
  346. return elem < 10;
  347. }));
  348. REQUIRE_THAT(mocked, allMatch);
  349. REQUIRE(mocked.m_derefed[0]);
  350. REQUIRE(mocked.m_derefed[1]);
  351. REQUIRE(mocked.m_derefed[2]);
  352. REQUIRE(mocked.m_derefed[3]);
  353. REQUIRE(mocked.m_derefed[4]);
  354. }
  355. SECTION("Short-circuited") {
  356. auto allMatch = AllMatch(Predicate<int>([](int elem) {
  357. return elem < 3;
  358. }));
  359. REQUIRE_THAT(mocked, !allMatch);
  360. REQUIRE(mocked.m_derefed[0]);
  361. REQUIRE(mocked.m_derefed[1]);
  362. REQUIRE(mocked.m_derefed[2]);
  363. REQUIRE_FALSE(mocked.m_derefed[3]);
  364. REQUIRE_FALSE(mocked.m_derefed[4]);
  365. }
  366. }
  367. }
  368. TEST_CASE("Usage of AnyMatch range matcher", "[matchers][templated][quantifiers]") {
  369. using Catch::Matchers::AnyMatch;
  370. using Catch::Matchers::Predicate;
  371. SECTION("Basic usage") {
  372. using Catch::Matchers::Contains;
  373. using Catch::Matchers::SizeIs;
  374. std::array<std::array<int, 5>, 5> data{ {
  375. {{ 0, 1, 2, 3, 5 }},
  376. {{ 4,-3,-2, 5, 0 }},
  377. {{ 0, 0, 0, 5, 0 }},
  378. {{ 0,-5, 0, 5, 0 }},
  379. {{ 1, 0, 0,-1, 5 }}
  380. } };
  381. REQUIRE_THAT(data, AnyMatch(SizeIs(5)));
  382. REQUIRE_THAT(data, !AnyMatch(Contains(0) && Contains(10)));
  383. }
  384. SECTION( "Type requires ADL found begin and end" ) {
  385. unrelated::needs_ADL_begin<int> needs_adl{ 1, 2, 3, 4, 5 };
  386. REQUIRE_THAT( needs_adl, AnyMatch( Predicate<int>( []( int elem ) {
  387. return elem < 3;
  388. } ) ) );
  389. }
  390. SECTION("Shortcircuiting") {
  391. with_mocked_iterator_access<int> mocked{ 1, 2, 3, 4, 5 };
  392. SECTION("All are read") {
  393. auto anyMatch = AnyMatch(
  394. Predicate<int>( []( int elem ) { return elem > 10; } ) );
  395. REQUIRE_THAT( mocked, !anyMatch );
  396. REQUIRE( mocked.m_derefed[0] );
  397. REQUIRE( mocked.m_derefed[1] );
  398. REQUIRE( mocked.m_derefed[2] );
  399. REQUIRE( mocked.m_derefed[3] );
  400. REQUIRE( mocked.m_derefed[4] );
  401. }
  402. SECTION("Short-circuited") {
  403. auto anyMatch = AnyMatch(
  404. Predicate<int>( []( int elem ) { return elem < 3; } ) );
  405. REQUIRE_THAT( mocked, anyMatch );
  406. REQUIRE( mocked.m_derefed[0] );
  407. REQUIRE_FALSE( mocked.m_derefed[1] );
  408. REQUIRE_FALSE( mocked.m_derefed[2] );
  409. REQUIRE_FALSE( mocked.m_derefed[3] );
  410. REQUIRE_FALSE( mocked.m_derefed[4] );
  411. }
  412. }
  413. }
  414. TEST_CASE("Usage of NoneMatch range matcher", "[matchers][templated][quantifiers]") {
  415. using Catch::Matchers::NoneMatch;
  416. using Catch::Matchers::Predicate;
  417. SECTION("Basic usage") {
  418. using Catch::Matchers::Contains;
  419. using Catch::Matchers::SizeIs;
  420. std::array<std::array<int, 5>, 5> data{ {
  421. {{ 0, 1, 2, 3, 5 }},
  422. {{ 4,-3,-2, 5, 0 }},
  423. {{ 0, 0, 0, 5, 0 }},
  424. {{ 0,-5, 0, 5, 0 }},
  425. {{ 1, 0, 0,-1, 5 }}
  426. } };
  427. REQUIRE_THAT(data, NoneMatch(SizeIs(6)));
  428. REQUIRE_THAT(data, !NoneMatch(Contains(0) && Contains(1)));
  429. }
  430. SECTION( "Type requires ADL found begin and end" ) {
  431. unrelated::needs_ADL_begin<int> needs_adl{ 1, 2, 3, 4, 5 };
  432. REQUIRE_THAT( needs_adl, NoneMatch( Predicate<int>( []( int elem ) {
  433. return elem > 6;
  434. } ) ) );
  435. }
  436. SECTION("Shortcircuiting") {
  437. with_mocked_iterator_access<int> mocked{ 1, 2, 3, 4, 5 };
  438. SECTION("All are read") {
  439. auto noneMatch = NoneMatch(
  440. Predicate<int>([](int elem) { return elem > 10; }));
  441. REQUIRE_THAT(mocked, noneMatch);
  442. REQUIRE(mocked.m_derefed[0]);
  443. REQUIRE(mocked.m_derefed[1]);
  444. REQUIRE(mocked.m_derefed[2]);
  445. REQUIRE(mocked.m_derefed[3]);
  446. REQUIRE(mocked.m_derefed[4]);
  447. }
  448. SECTION("Short-circuited") {
  449. auto noneMatch = NoneMatch(
  450. Predicate<int>([](int elem) { return elem < 3; }));
  451. REQUIRE_THAT(mocked, !noneMatch);
  452. REQUIRE(mocked.m_derefed[0]);
  453. REQUIRE_FALSE(mocked.m_derefed[1]);
  454. REQUIRE_FALSE(mocked.m_derefed[2]);
  455. REQUIRE_FALSE(mocked.m_derefed[3]);
  456. REQUIRE_FALSE(mocked.m_derefed[4]);
  457. }
  458. }
  459. }
  460. namespace {
  461. struct ConvertibleToBool
  462. {
  463. bool v;
  464. explicit operator bool() const
  465. {
  466. return v;
  467. }
  468. };
  469. }
  470. namespace Catch {
  471. template <>
  472. struct StringMaker<ConvertibleToBool> {
  473. static std::string
  474. convert( ConvertibleToBool const& convertible_to_bool ) {
  475. return ::Catch::Detail::stringify( convertible_to_bool.v );
  476. }
  477. };
  478. } // namespace Catch
  479. TEST_CASE("Usage of AllTrue range matcher", "[matchers][templated][quantifiers]") {
  480. using Catch::Matchers::AllTrue;
  481. SECTION( "Basic usage" ) {
  482. SECTION( "All true evaluates to true" ) {
  483. std::array<bool, 5> const data{ { true, true, true, true, true } };
  484. REQUIRE_THAT( data, AllTrue() );
  485. }
  486. SECTION( "Empty evaluates to true" ) {
  487. std::array<bool, 0> const data{};
  488. REQUIRE_THAT( data, AllTrue() );
  489. }
  490. SECTION( "One false evalutes to false" ) {
  491. std::array<bool, 5> const data{ { true, true, false, true, true } };
  492. REQUIRE_THAT( data, !AllTrue() );
  493. }
  494. SECTION( "All false evaluates to false" ) {
  495. std::array<bool, 5> const data{
  496. { false, false, false, false, false } };
  497. REQUIRE_THAT( data, !AllTrue() );
  498. }
  499. }
  500. SECTION( "Contained type is convertible to bool" ) {
  501. SECTION( "All true evaluates to true" ) {
  502. std::array<ConvertibleToBool, 5> const data{
  503. { { true }, { true }, { true }, { true }, { true } } };
  504. REQUIRE_THAT( data, AllTrue() );
  505. }
  506. SECTION( "One false evalutes to false" ) {
  507. std::array<ConvertibleToBool, 5> const data{
  508. { { true }, { true }, { false }, { true }, { true } } };
  509. REQUIRE_THAT( data, !AllTrue() );
  510. }
  511. SECTION( "All false evaluates to false" ) {
  512. std::array<ConvertibleToBool, 5> const data{
  513. { { false }, { false }, { false }, { false }, { false } } };
  514. REQUIRE_THAT( data, !AllTrue() );
  515. }
  516. }
  517. SECTION( "Shortcircuiting" ) {
  518. SECTION( "All are read" ) {
  519. with_mocked_iterator_access<bool> const mocked{
  520. true, true, true, true, true };
  521. REQUIRE_THAT( mocked, AllTrue() );
  522. REQUIRE( mocked.m_derefed[0] );
  523. REQUIRE( mocked.m_derefed[1] );
  524. REQUIRE( mocked.m_derefed[2] );
  525. REQUIRE( mocked.m_derefed[3] );
  526. REQUIRE( mocked.m_derefed[4] );
  527. }
  528. SECTION( "Short-circuited" ) {
  529. with_mocked_iterator_access<bool> const mocked{
  530. true, true, false, true, true };
  531. REQUIRE_THAT( mocked, !AllTrue() );
  532. REQUIRE( mocked.m_derefed[0] );
  533. REQUIRE( mocked.m_derefed[1] );
  534. REQUIRE( mocked.m_derefed[2] );
  535. REQUIRE_FALSE( mocked.m_derefed[3] );
  536. REQUIRE_FALSE( mocked.m_derefed[4] );
  537. }
  538. }
  539. }
  540. TEST_CASE( "Usage of NoneTrue range matcher", "[matchers][templated][quantifiers]" ) {
  541. using Catch::Matchers::NoneTrue;
  542. SECTION( "Basic usage" ) {
  543. SECTION( "All true evaluates to false" ) {
  544. std::array<bool, 5> const data{ { true, true, true, true, true } };
  545. REQUIRE_THAT( data, !NoneTrue() );
  546. }
  547. SECTION( "Empty evaluates to true" ) {
  548. std::array<bool, 0> const data{};
  549. REQUIRE_THAT( data, NoneTrue() );
  550. }
  551. SECTION( "One true evalutes to false" ) {
  552. std::array<bool, 5> const data{
  553. { false, false, true, false, false } };
  554. REQUIRE_THAT( data, !NoneTrue() );
  555. }
  556. SECTION( "All false evaluates to true" ) {
  557. std::array<bool, 5> const data{
  558. { false, false, false, false, false } };
  559. REQUIRE_THAT( data, NoneTrue() );
  560. }
  561. }
  562. SECTION( "Contained type is convertible to bool" ) {
  563. SECTION( "All true evaluates to false" ) {
  564. std::array<ConvertibleToBool, 5> const data{
  565. { { true }, { true }, { true }, { true }, { true } } };
  566. REQUIRE_THAT( data, !NoneTrue() );
  567. }
  568. SECTION( "One true evalutes to false" ) {
  569. std::array<ConvertibleToBool, 5> const data{
  570. { { false }, { false }, { true }, { false }, { false } } };
  571. REQUIRE_THAT( data, !NoneTrue() );
  572. }
  573. SECTION( "All false evaluates to true" ) {
  574. std::array<ConvertibleToBool, 5> const data{
  575. { { false }, { false }, { false }, { false }, { false } } };
  576. REQUIRE_THAT( data, NoneTrue() );
  577. }
  578. }
  579. SECTION( "Shortcircuiting" ) {
  580. SECTION( "All are read" ) {
  581. with_mocked_iterator_access<bool> const mocked{
  582. false, false, false, false, false };
  583. REQUIRE_THAT( mocked, NoneTrue() );
  584. REQUIRE( mocked.m_derefed[0] );
  585. REQUIRE( mocked.m_derefed[1] );
  586. REQUIRE( mocked.m_derefed[2] );
  587. REQUIRE( mocked.m_derefed[3] );
  588. REQUIRE( mocked.m_derefed[4] );
  589. }
  590. SECTION( "Short-circuited" ) {
  591. with_mocked_iterator_access<bool> const mocked{
  592. false, false, true, true, true };
  593. REQUIRE_THAT( mocked, !NoneTrue() );
  594. REQUIRE( mocked.m_derefed[0] );
  595. REQUIRE( mocked.m_derefed[1] );
  596. REQUIRE( mocked.m_derefed[2] );
  597. REQUIRE_FALSE( mocked.m_derefed[3] );
  598. REQUIRE_FALSE( mocked.m_derefed[4] );
  599. }
  600. }
  601. }
  602. TEST_CASE( "Usage of AnyTrue range matcher", "[matchers][templated][quantifiers]" ) {
  603. using Catch::Matchers::AnyTrue;
  604. SECTION( "Basic usage" ) {
  605. SECTION( "All true evaluates to true" ) {
  606. std::array<bool, 5> const data{ { true, true, true, true, true } };
  607. REQUIRE_THAT( data, AnyTrue() );
  608. }
  609. SECTION( "Empty evaluates to false" ) {
  610. std::array<bool, 0> const data{};
  611. REQUIRE_THAT( data, !AnyTrue() );
  612. }
  613. SECTION( "One true evalutes to true" ) {
  614. std::array<bool, 5> const data{
  615. { false, false, true, false, false } };
  616. REQUIRE_THAT( data, AnyTrue() );
  617. }
  618. SECTION( "All false evaluates to false" ) {
  619. std::array<bool, 5> const data{
  620. { false, false, false, false, false } };
  621. REQUIRE_THAT( data, !AnyTrue() );
  622. }
  623. }
  624. SECTION( "Contained type is convertible to bool" ) {
  625. SECTION( "All true evaluates to true" ) {
  626. std::array<ConvertibleToBool, 5> const data{
  627. { { true }, { true }, { true }, { true }, { true } } };
  628. REQUIRE_THAT( data, AnyTrue() );
  629. }
  630. SECTION( "One true evalutes to true" ) {
  631. std::array<ConvertibleToBool, 5> const data{
  632. { { false }, { false }, { true }, { false }, { false } } };
  633. REQUIRE_THAT( data, AnyTrue() );
  634. }
  635. SECTION( "All false evaluates to false" ) {
  636. std::array<ConvertibleToBool, 5> const data{
  637. { { false }, { false }, { false }, { false }, { false } } };
  638. REQUIRE_THAT( data, !AnyTrue() );
  639. }
  640. }
  641. SECTION( "Shortcircuiting" ) {
  642. SECTION( "All are read" ) {
  643. with_mocked_iterator_access<bool> const mocked{
  644. false, false, false, false, true };
  645. REQUIRE_THAT( mocked, AnyTrue() );
  646. REQUIRE( mocked.m_derefed[0] );
  647. REQUIRE( mocked.m_derefed[1] );
  648. REQUIRE( mocked.m_derefed[2] );
  649. REQUIRE( mocked.m_derefed[3] );
  650. REQUIRE( mocked.m_derefed[4] );
  651. }
  652. SECTION( "Short-circuited" ) {
  653. with_mocked_iterator_access<bool> const mocked{
  654. false, false, true, true, true };
  655. REQUIRE_THAT( mocked, AnyTrue() );
  656. REQUIRE( mocked.m_derefed[0] );
  657. REQUIRE( mocked.m_derefed[1] );
  658. REQUIRE( mocked.m_derefed[2] );
  659. REQUIRE_FALSE( mocked.m_derefed[3] );
  660. REQUIRE_FALSE( mocked.m_derefed[4] );
  661. }
  662. }
  663. }
  664. TEST_CASE("All/Any/None True matchers support types with ADL begin",
  665. "[approvals][matchers][quantifiers][templated]") {
  666. using Catch::Matchers::AllTrue;
  667. using Catch::Matchers::NoneTrue;
  668. using Catch::Matchers::AnyTrue;
  669. SECTION( "Type requires ADL found begin and end" ) {
  670. unrelated::needs_ADL_begin<bool> const needs_adl{
  671. true, true, true, true, true };
  672. REQUIRE_THAT( needs_adl, AllTrue() );
  673. }
  674. SECTION( "Type requires ADL found begin and end" ) {
  675. unrelated::needs_ADL_begin<bool> const needs_adl{
  676. false, false, false, false, false };
  677. REQUIRE_THAT( needs_adl, NoneTrue() );
  678. }
  679. SECTION( "Type requires ADL found begin and end" ) {
  680. unrelated::needs_ADL_begin<bool> const needs_adl{
  681. false, false, true, false, false };
  682. REQUIRE_THAT( needs_adl, AnyTrue() );
  683. }
  684. }
  685. // Range loop iterating over range with different types for begin and end is a
  686. // C++17 feature, and GCC refuses to compile such code unless the lang mode is
  687. // set to C++17 or later.
  688. #if defined(CATCH_CPP17_OR_GREATER)
  689. TEST_CASE( "The quantifier range matchers support types with different types returned from begin and end",
  690. "[matchers][templated][quantifiers][approvals]" ) {
  691. using Catch::Matchers::AllMatch;
  692. using Catch::Matchers::AllTrue;
  693. using Catch::Matchers::AnyMatch;
  694. using Catch::Matchers::AnyTrue;
  695. using Catch::Matchers::NoneMatch;
  696. using Catch::Matchers::NoneTrue;
  697. using Catch::Matchers::Predicate;
  698. SECTION( "AllAnyNoneMatch" ) {
  699. has_different_begin_end_types<int> diff_types{ 1, 2, 3, 4, 5 };
  700. REQUIRE_THAT( diff_types, !AllMatch( Predicate<int>( []( int elem ) {
  701. return elem < 3;
  702. } ) ) );
  703. REQUIRE_THAT( diff_types, AnyMatch( Predicate<int>( []( int elem ) {
  704. return elem < 2;
  705. } ) ) );
  706. REQUIRE_THAT( diff_types, !NoneMatch( Predicate<int>( []( int elem ) {
  707. return elem < 3;
  708. } ) ) );
  709. }
  710. SECTION( "AllAnyNoneTrue" ) {
  711. has_different_begin_end_types<bool> diff_types{ false, false, true, false, false };
  712. REQUIRE_THAT( diff_types, !AllTrue() );
  713. REQUIRE_THAT( diff_types, AnyTrue() );
  714. REQUIRE_THAT( diff_types, !NoneTrue() );
  715. }
  716. }
  717. #endif