OTest2
A C++ testing framework
objectpath.cpp
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 #include <objectpath.h>
21 
22 #include <algorithm>
23 #include <assert.h>
24 #include <iterator>
25 #include <sstream>
26 #include <string>
27 #include <tuple>
28 #include <vector>
29 
30 #include <infixiterator.h>
31 #include <parameters.h>
32 #include <utils.h>
33 
34 namespace OTest2 {
35 
36 struct ObjectPath::Impl {
37  struct Record {
38  std::string name;
39  Parameters params;
40  };
41  typedef std::vector<Record> PathStack;
42  PathStack path_stack_;
43 };
44 
45 namespace {
46 
47 struct NameAccessor {
48  const std::string& operator()(
49  const ObjectPath::Impl::PathStack::value_type& item_) const noexcept {
50  return item_.name;
51  }
52 };
53 
54 } /* -- namespace */
55 
57  pimpl(new Impl) {
58 
59 }
60 
62  const std::string& full_path_) {
63  /* -- parse the path */
64  Impl::PathStack stack_;
65  if(!full_path_.empty()) {
66  std::string::size_type start_(0);
67  do {
68  auto index_(full_path_.find("::", start_));
69  if(index_ == std::string::npos)
70  break;
71  stack_.push_back({full_path_.substr(start_, index_ - start_), {}});
72  start_ = index_ + 2;
73  } while(true);
74  stack_.push_back({full_path_.substr(start_), {}});
75  }
76 
77  /* -- create the object */
78  pimpl = new Impl;
79  pimpl->path_stack_.swap(stack_);
80 }
81 
83  odelete(pimpl);
84 }
85 
87  const std::string& name_) {
88  assert(!name_.empty());
89 
90  pimpl->path_stack_.push_back({name_, {}});
91 }
92 
94  assert(!pimpl->path_stack_.empty());
95  pimpl->path_stack_.pop_back();
96 }
97 
99  const std::string& name_,
100  const std::string& value_) {
101  assert(!pimpl->path_stack_.empty());
102 
103  pimpl->path_stack_.back().params.appendParameter(name_, value_);
104 }
105 
106 std::string ObjectPath::getCurrentName() const {
107  assert(!pimpl->path_stack_.empty());
108 
109  return pimpl->path_stack_.back().name;
110 }
111 
113  assert(!pimpl->path_stack_.empty());
114 
115  return pimpl->path_stack_.back().params;
116 }
117 
118 std::string ObjectPath::getCurrentPath() const {
119  std::ostringstream oss_;
120  std::copy(
121  pimpl->path_stack_.begin(),
122  pimpl->path_stack_.end(),
124  return oss_.str();
125 }
126 
128  const std::string& local_key_) const {
129  /* -- at least we must be inside a suite */
130  assert(pimpl->path_stack_.size() > 1);
131 
132  std::ostringstream oss_;
133  auto suite_part_(pimpl->path_stack_.begin());
134  ++suite_part_;
135  std::copy(
136  suite_part_,
137  pimpl->path_stack_.end(),
139  oss_ << ">>" << local_key_;
140  return oss_.str();
141 }
142 
144  const ObjectPath& path_) const noexcept {
145  /* -- I'm longer */
146  if(pimpl->path_stack_.size() > path_.pimpl->path_stack_.size())
147  return false;
148 
149  /* -- compare segments in the paths */
150  for(int i_(0); i_ < pimpl->path_stack_.size(); ++i_) {
151  if(pimpl->path_stack_[i_].name != path_.pimpl->path_stack_[i_].name)
152  return false;
153  }
154 
155  return true;
156 }
157 
158 } /* -- namespace OTest2 */
OTest2::ObjectPath
This is a simple object keeping path to current testing object.
Definition: objectpath.h:32
OTest2::ObjectPath::popName
void popName()
Pop name of currently leaving testing object.
Definition: objectpath.cpp:93
OTest2::ObjectPath::getRegressionKey
std::string getRegressionKey(const std::string &local_key_) const
Create key of a regression test mark according to current object path.
Definition: objectpath.cpp:127
OTest2::InfixIterator
ostream iterator with infix delimiter
Definition: infixiterator.h:41
OTest2::ObjectPath::pushName
void pushName(const std::string &name_)
Push name of currently entering testing object.
Definition: objectpath.cpp:86
OTest2::ObjectPath::~ObjectPath
~ObjectPath()
Dtor.
Definition: objectpath.cpp:82
OTest2::ObjectPath::getCurrentName
std::string getCurrentName() const
Get name at the top of the stack.
Definition: objectpath.cpp:106
utils.h
OTest2::Parameters
Generic parameters of a run of an testing object.
Definition: parameters.h:30
objectpath.h
OTest2
Definition: assertbean.h:25
OTest2::ObjectPath::getCurrentParameters
const Parameters & getCurrentParameters() const
Get parameters of current object.
Definition: objectpath.cpp:112
parameters.h
OTest2::ObjectPath::ObjectPath
ObjectPath()
Ctor.
Definition: objectpath.cpp:56
OTest2::ObjectPath::appendParameter
void appendParameter(const std::string &name_, const std::string &value_)
Append parameter to current testing object.
Definition: objectpath.cpp:98
infixiterator.h
OTest2::ObjectPath::getCurrentPath
std::string getCurrentPath() const
Get path of current object.
Definition: objectpath.cpp:118
OTest2::odelete
void odelete(T_ *&object_)
Delete a pointer and set it invalid.
Definition: utils.h:34
OTest2::ObjectPath::isPrefixOf
bool isPrefixOf(const ObjectPath &path_) const noexcept
Tell us whether this object is a prefix of specified path_.
Definition: objectpath.cpp:143