Belle II Software  release-08-01-10
ScopeGuards.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <framework/utilities/ScopeGuard.h>
10 #include <framework/utilities/Utils.h>
11 #include <gtest/gtest.h>
12 #include <filesystem>
13 
14 namespace {
16  struct IntSetterGetterFunctor {
18  explicit IntSetterGetterFunctor(int& reference): ref(reference) {}
20  void operator()(const int& v) { ref = v; }
22  int operator()() const { return ref; }
24  int& ref;
25  };
26 
28  TEST(ScopeGuards, IntRef)
29  {
30  int old{5};
31  {
32  auto guard = Belle2::ScopeGuard::guardValue(old); // cppcheck-suppress unreadVariable
33  ASSERT_EQ(old, 5);
34  old = 17;
35  }
36  ASSERT_EQ(old, 5);
37  {
38  auto guard = Belle2::ScopeGuard::guardValue(old, 17); // cppcheck-suppress unreadVariable
39  ASSERT_EQ(old, 17);
40  }
41  ASSERT_EQ(old, 5);
42  {
43  auto guard = Belle2::ScopeGuard::guardValue(old, 17);
44  ASSERT_EQ(old, 17);
45  guard.release();
46  }
47  ASSERT_EQ(old, 17);
48  }
49 
51  TEST(ScopeGuards, IntSetterGetter)
52  {
53  int old{5};
54  auto setter = [&old](int v) {old = v;};
55  auto getter = [&old]() {return old;};
56  {
57  auto guard = Belle2::ScopeGuard::guardGetterSetter(getter, setter);
58  ASSERT_EQ(old, 5);
59  old = 17;
60  }
61  ASSERT_EQ(old, 5);
62  {
63  auto guard = Belle2::ScopeGuard::guardGetterSetter(getter, setter, 17);
64  ASSERT_EQ(old, 17);
65  }
66  ASSERT_EQ(old, 5);
67  {
68  auto guard = Belle2::ScopeGuard::guardGetterSetter(getter, setter, 17);
69  ASSERT_EQ(old, 17);
70  guard.release();
71  }
72  ASSERT_EQ(old, 17);
73  }
74 
76  TEST(ScopeGuards, IntSetterGetterFunctor)
77  {
78  int old{5};
79  IntSetterGetterFunctor functor(old);
80  {
81  auto guard = Belle2::ScopeGuard::guardFunctor(functor); // cppcheck-suppress unreadVariable
82  ASSERT_EQ(old, 5);
83  old = 17;
84  }
85  ASSERT_EQ(old, 5);
86  {
87  auto guard = Belle2::ScopeGuard::guardFunctor(functor, 17); // cppcheck-suppress unreadVariable
88  ASSERT_EQ(old, 17);
89  }
90  ASSERT_EQ(old, 5);
91  {
92  auto guard = Belle2::ScopeGuard::guardFunctor(functor, 17);
93  ASSERT_EQ(old, 17);
94  guard.release();
95  }
96  ASSERT_EQ(old, 17);
97  {
98  // cppcheck-suppress unreadVariable
100  [&old](int v) { old = v; },
101  [&old]() { return old; }
102  }, 21);
103  ASSERT_EQ(old, 21);
104  }
105  ASSERT_EQ(old, 17);
106  }
107 
111  TEST(ScopeGuards, StringReference)
112  {
113  std::string value{"before"};
114  {
115  auto guard = Belle2::ScopeGuard::guardValue(value, "after"); // cppcheck-suppress unreadVariable
116  ASSERT_EQ(value, "after");
117  }
118  ASSERT_EQ(value, "before");
119  {
120  // cppcheck-suppress unreadVariable
122  [&value](const std::string & v) { value = v; },
123  [&value]() { return value; }
124  }, "after");
125  ASSERT_EQ(value, "after");
126  };
127  ASSERT_EQ(value, "before");
128  }
129 
131  TEST(ScopeGuards, StreamState)
132  {
133  std::stringstream buf;
134  buf << "a:" << std::setprecision(4) << 1.2;
135  {
136  auto guard1 = Belle2::ScopeGuard::guardStreamState(buf); // cppcheck-suppress unreadVariable
137  buf << ":b:" << std::fixed << std::setprecision(4) << 2.3;
138  {
139  // cppcheck-suppress unreadVariable
140  auto guard3 = Belle2::ScopeGuard::guardStreamState(buf);
141  buf << ":c:" << std::setprecision(5) << std::setw(10) << std::setfill('-') << 3.4;
142  }
143 
144  buf << ":d:" << std::scientific << 4.5;
145  }
146  buf << ":e:" << 5.4;
147  ASSERT_EQ(buf.str(), "a:1.2:b:2.3000:c:---3.40000:d:4.5000e+00:e:5.4");
148  }
149 
151  TEST(ScopeGuards, WorkingDirectory)
152  {
153  std::string start{std::filesystem::current_path().c_str()};
154  std::string tmpdir(std::filesystem::temp_directory_path().c_str());
155  std::string root("/");
156  {
157  auto guard1 = Belle2::ScopeGuard::guardWorkingDirectory( // cppcheck-suppress unreadVariable
158  std::filesystem::temp_directory_path().c_str());
159  ASSERT_EQ(tmpdir, std::filesystem::current_path().c_str());
160  {
162  ASSERT_EQ(root, std::filesystem::current_path().c_str());
163  guard2.release();
164  }
165  ASSERT_EQ(root, std::filesystem::current_path().c_str());
166  }
167  ASSERT_EQ(start, std::filesystem::current_path().c_str());
168  }
169 
170 
172  TEST(ScopeGuards, Batch)
173  {
174  const bool start = gROOT->IsBatch();
175  {
176  auto guard1 = Belle2::ScopeGuard::guardBatchMode(); // cppcheck-suppress unreadVariable
177  ASSERT_EQ(true, gROOT->IsBatch());
178  {
179  auto guard2 = Belle2::ScopeGuard::guardBatchMode(false); // cppcheck-suppress unreadVariable
180  ASSERT_EQ(false, gROOT->IsBatch());
181  }
182  ASSERT_EQ(true, gROOT->IsBatch());
183  }
184  ASSERT_EQ(start, gROOT->IsBatch());
185  }
186 }
static ScopeGuard guardStreamState(std::basic_ios< CharT, Traits > &stream)
Create a ScopeGuard for the state of a stream to reset all the formatting at the end of the object li...
Definition: ScopeGuard.h:262
static ScopeGuard guardValue(T &reference)
Create a ScopeGuard for a value: The content of reference will be copied and reset when the returned ...
Definition: ScopeGuard.h:76
static ScopeGuard guardGetterSetter(Getter getter, Setter setter)
Create a ScopeGuard from a getter and setter: On construction the getter object is called to obtain a...
Definition: ScopeGuard.h:137
static ScopeGuard guardFunctor(Functor functor)
Create a ScopeGuard from a functor object with appropriately overloaded operator() calls to get and s...
Definition: ScopeGuard.h:188
static ScopeGuard guardBatchMode(bool batchMode=true)
Create a ScopeGuard to turn ROOT into batch mode and restore the initial batch mode status after the ...
Definition: ScopeGuard.h:352
static ScopeGuard guardWorkingDirectory()
Create a ScopeGuard of the current working directory.
Definition: ScopeGuard.h:296
TEST(TestgetDetectorRegion, TestgetDetectorRegion)
Test Constructors.
Helper struct for the C++17 std::visit overload pattern to allow simple use of variants.
Definition: Utils.h:26