OTest2
A C++ testing framework
assertionslexiimpl.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2020 Ondrej Starek
3  *
4  * This file is part of OTest2
5  *
6  * OTest2 is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License,
9  * or (at your option) any later version.
10  *
11  * OTest2 is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14  * License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with OTest2. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef OTest2_INCLUDE_OTEST2_ASSERTIONSLEXIIMPL_H_
21 #define OTest2_INCLUDE_OTEST2_ASSERTIONSLEXIIMPL_H_
22 
23 #include <otest2/assertionslexi.h>
24 
25 #include <assert.h>
26 #include <iostream>
27 #include <sstream>
28 #include <string>
29 #include <vector>
30 
31 #include <otest2/assertstream.h>
32 #include <otest2/containertrait.h>
33 #include <otest2/printtraits.h>
34 #include <otest2/printutils.h>
35 #include <otest2/typetraits.h>
36 
37 namespace OTest2 {
38 
39 namespace Private {
40 
41 template<template<typename, typename> class Compare_, typename IterA_, typename IterB_>
43  std::vector<std::string>& messages_,
44  IterA_ begin_a_,
45  IterA_ end_a_,
46  IterB_ begin_b_,
47  IterB_ end_b_) {
48  typedef typename AssertionParameter<decltype(*begin_a_)>::Type AType_;
49  typedef typename AssertionParameter<decltype(*begin_b_)>::Type BType_;
50  typedef Compare_<AType_, BType_> Comparator_;
51 
52  int index_(0);
53  Comparator_ cmp_;
54  std::ostringstream sos_;
55  while(begin_a_ != end_a_ && begin_b_ != end_b_) {
56  int cmp_result_(cmp_.checkItems(*begin_a_, *begin_b_));
57  if(cmp_result_ < 0) {
58  /* -- the a_ list is lesser */
59  sos_ << "the assertion 'a ";
61  sos_ << " b' has passed";
62  messages_.push_back(sos_.str());
63  return true;
64  }
65  if(cmp_result_ > 0) {
66  /* -- the a_ list is greater */
67  sos_ << "the ";
68  printOrdinalNumber(sos_, index_);
69  sos_ << " items have failed: a[" << index_ << "] ";
71  sos_ << " b[" << index_ << "]";
72  messages_.push_back(sos_.str());
73 
74  sos_.str("");
75  sos_ << "a[" << index_ << "] = ";
76  PrintTrait<AType_>::print(sos_, *begin_a_);
77  messages_.push_back(sos_.str());
78 
79  sos_.str("");
80  sos_ << "b[" << index_ << "] = ";
81  PrintTrait<AType_>::print(sos_, *begin_b_);
82  messages_.push_back(sos_.str());
83 
84  return false;
85  }
86 
87  /* -- move to next item */
88  ++begin_a_;
89  ++begin_b_;
90  ++index_;
91  }
92 
93  /* -- All items equal each other in the pair. The result is defined by
94  * length of resting lists - whether a list is longer then the other
95  * or shorter or the same length. */
96  const bool a_ends_(begin_a_ == end_a_);
97  const bool b_ends_(begin_b_ == end_b_);
98  if(cmp_.checkRests(a_ends_, b_ends_)) {
99  sos_ << "the assertion 'a ";
100  PrintTrait<Comparator_>::print(sos_, cmp_);
101  sos_ << " b' has passed: one list is the prefix of the other one";
102  messages_.push_back(sos_.str());
103  return true;
104  }
105 
106  /* -- The lists doesn't match the operator */
107  sos_ << "the assertion 'a ";
108  PrintTrait<Comparator_>::print(sos_, cmp_);
109  sos_ << " b' has failed.";
110  messages_.push_back(sos_.str());
111 
112  if(a_ends_ && b_ends_) {
113  messages_.push_back("the lists are the same length");
114  }
115  else if(a_ends_) {
116  messages_.push_back("the list a is shorter");
117  }
118  else {
119  messages_.push_back("the list a is longer");
120  }
121  return false;
122 }
123 
124 } /* -- namespace Private */
125 
126 template<template<typename, typename> class Compare_, typename IterA_, typename IterB_>
127 bool LexicographicalAssertion::testAssertLexiList(
128  IterA_ begin_a_,
129  IterA_ end_a_,
130  IterB_ begin_b_,
131  IterB_ end_b_) {
132  /* -- check the container */
133  std::vector<std::string> messages_;
134  bool result_(Private::compareListsLexicographically<Compare_>(
135  messages_, begin_a_, end_a_, begin_b_, end_b_));
136  assert(messages_.size() > 0);
137 
138  /* -- report the result */
139  AssertStream report_(enterAssertion(result_));
140  for(const auto& message_ : messages_)
141  report_ << message_ << commitMsg();
142  return report_.getResult();
143 }
144 
145 template<template<typename, typename> class Compare_, typename IterA_, typename IterB_>
147  IterA_ begin_a_,
148  IterA_ end_a_,
149  IterB_ begin_b_,
150  IterB_ end_b_) {
151  return testAssertLexiList<Compare_>(begin_a_, end_a_, begin_b_, end_b_);
152 }
153 
154 template<template<typename, typename> class Compare_, typename ContainerA_, typename IterB_>
156  const ContainerA_& a_,
157  IterB_ begin_b_,
158  IterB_ end_b_) {
159  return testAssertLexiList<Compare_>(
162  begin_b_,
163  end_b_);
164 }
165 
166 template<template<typename, typename> class Compare_, typename IterA_, typename ContainerB_>
168  IterA_ begin_a_,
169  IterA_ end_a_,
170  const ContainerB_& b_) {
171  return testAssertLexiList<Compare_>(
172  begin_a_,
173  end_a_,
176 }
177 
178 template<template<typename, typename> class Compare_, typename ContainerA_, typename ContainerB_>
180  const ContainerA_& a_,
181  const ContainerB_& b_) {
182  return testAssertLexiList<Compare_>(
187 }
188 
189 } /* -- namespace OTest2 */
190 
191 #endif /* -- OTest2_INCLUDE_OTEST2_ASSERTIONSLEXIIMPL_H_ */
assertstream.h
typetraits.h
OTest2::AssertContext::enterAssertion
AssertStream enterAssertion(bool result_)
Enter an assertion.
Definition: assertcontext.cpp:45
OTest2::commitMsg
Private::Manipulator commitMsg()
Commit current assertion message.
Definition: assertstream.cpp:201
printtraits.h
printutils.h
containertrait.h
OTest2::PrintTrait::print
static std::ostream & print(std::ostream &os_, typename TypeTrait< Type_ >::BestArg value_)
Definition: printtraits.h:39
OTest2
Definition: assertbean.h:25
OTest2::Private::compareListsLexicographically
bool compareListsLexicographically(std::vector< std::string > &messages_, IterA_ begin_a_, IterA_ end_a_, IterB_ begin_b_, IterB_ end_b_)
Definition: assertionslexiimpl.h:42
assertionslexi.h
OTest2::ListContainerTrait
A simple trait allowing access to list container's iterators.
Definition: containertrait.h:45
OTest2::AssertionParameter
A helper trait - get normalized type of a captured assertion parameter.
Definition: typetraits.h:81
OTest2::LexicographicalAssertion::testAssertLexi
bool testAssertLexi(IterA_ begin_a_, IterA_ end_a_, IterB_ begin_b_, IterB_ end_b_)
Definition: assertionslexiimpl.h:146
OTest2::printOrdinalNumber
void printOrdinalNumber(std::ostream &os_, int number_)
Format the ordinal number with appropriate suffix.
Definition: printutils.cpp:25