ProviderPack_test.cc
Go to the documentation of this file.
1 /**
2  * @file ProviderPack_test.cc
3  * @brief Unit test for ProviderPack class
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date November 20th, 2015
6  * @version 1.0
7  * @see ProviderPack.h
8  */
9 
10 // Define the following non-zero to exclude include code that is required
11 // not to be compilable
12 #ifndef PROVIDERPACK_TEST_SKIP_COMPILATION_ERRORS
13 # define PROVIDERPACK_TEST_SKIP_COMPILATION_ERRORS 1
14 #endif // !PROVIDERPACK_TEST_SKIP_COMPILATION_ERRORS
15 
16 // Boost libraries
17 /*
18  * Boost Magic: define the name of the module;
19  * and do that before the inclusion of Boost unit test headers
20  * because it will change what they provide.
21  * Among the those, there is a main() function and some wrapping catching
22  * unhandled exceptions and considering them test failures, and probably more.
23  * This also makes fairly complicate to receive parameters from the command line
24  * (for example, a random seed).
25  */
26 #define BOOST_TEST_MODULE ( ProviderPack_test )
27 #include <boost/test/unit_test.hpp>
28 
29 // LArSoft libraries
32 
33 // C/C++ standard libraries
34 #include <string>
35 #include <ostream>
36 
37 namespace svc {
38 
39  /// A service provider class
40  struct ProviderA: public lar::UncopiableAndUnmovableClass {
41 
43 
44  operator std::string() const
45  { return "ProviderA[" + std::to_string(count) + "]"; }
46 
47  unsigned int count;
48 
49  static unsigned int max_count;
50  }; // ProviderA
51  unsigned int ProviderA::max_count = 0;
52 
53  /// A service provider class
55 
57  virtual ~ProviderB() noexcept = default;
58 
59  virtual operator std::string() const
60  { return "ProviderB[" + std::to_string(count) + "]"; }
61 
62  unsigned int count;
63 
64  static unsigned int max_count;
65  }; // ProviderB
66  unsigned int ProviderB::max_count = 0;
67 
68  /// A service provider class derived from B
69  struct ProviderB1: public ProviderB {
70 
72 
73  virtual operator std::string() const override
74  { return "ProviderB1[" + std::to_string(count) + "]"; }
75 
76  unsigned int count;
77 
78  static unsigned int max_count;
79  }; // ProviderB1
80  unsigned int ProviderB1::max_count = 0;
81 
82  /// A service provider class
83  struct ProviderC {
84 
86 
87  operator std::string() const
88  { return "ProviderC[" + std::to_string(count) + "]"; }
89 
90  unsigned int count;
91 
92  static unsigned int max_count;
93  }; // ProviderC
94  unsigned int ProviderC::max_count = 0;
95 
96  /// A service provider class
98 
100 
101  operator std::string() const
102  { return "ProviderD[" + std::to_string(count) + "]"; }
103 
104  unsigned int count;
105 
106  static unsigned int max_count;
107  }; // ProviderD
108  unsigned int ProviderD::max_count = 0;
109 
110 
111 } // namespace svc
112 
113 
114 BOOST_AUTO_TEST_CASE(ProviderPack_testcase) {
115 
116  // instantiate a ProviderPack with three classes
117  svc::ProviderA providerA;
118  svc::ProviderB providerB;
119  svc::ProviderC providerC;
120  auto SP1 = lar::makeProviderPack(&providerA, &providerB, &providerC);
121 
122  // get element A
123  static_assert
124  (decltype(SP1)::has<svc::ProviderA>(), "We don't believe to have ProviderA!!");
125  auto myA = SP1.get<svc::ProviderA>();
126  static_assert(std::is_same<decltype(myA), svc::ProviderA const*>(),
127  "Failed to get the element of type A");
128  BOOST_TEST(myA == &providerA);
129 
130  // get element B
131  static_assert
132  (decltype(SP1)::has<svc::ProviderB>(), "We don't believe to have ProviderB!!");
133  auto myB = SP1.get<svc::ProviderB>();
134  static_assert(std::is_same<decltype(myB), svc::ProviderB const*>(),
135  "Failed to get the element of type B");
136  BOOST_TEST(myB == &providerB);
137 
138  // get element C
139  static_assert
140  (decltype(SP1)::has<svc::ProviderC>(), "We don't believe to have ProviderC!!");
141  auto myC = SP1.get<svc::ProviderC>();
142  static_assert(std::is_same<decltype(myC), svc::ProviderC const*>(),
143  "Failed to get the element of type C");
144  BOOST_TEST(myC == &providerC);
145 
146 
147  // set element A
148  svc::ProviderA providerA2;
149  SP1.set(&providerA2);
150  myA = SP1.get<svc::ProviderA>();
151  BOOST_TEST(myA == &providerA2);
152 
153  // get element D
154  // should be a compilation error
155 #if PROVIDERPACK_TEST_SKIP_COMPILATION_ERRORS
156  BOOST_TEST_MESSAGE(" (test to get a non-existing provider type skipped)");
157 #else
158  SP1.get<svc::ProviderD>();
159 #endif // !PROVIDERPACK_TEST_SKIP_COMPILATION_ERRORS
160 
161  // check what we believe we have
162  static_assert
163  (!decltype(SP1)::has<svc::ProviderD>(), "We believe to have ProviderD!!");
164 
165  // default constructor: all null
167  BOOST_TEST(SP2.get<svc::ProviderA>() == nullptr);
168  BOOST_TEST(SP2.get<svc::ProviderB>() == nullptr);
169 
170  // extraction constructor
172  BOOST_TEST(SP3.get<svc::ProviderA>() == SP1.get<svc::ProviderA>());
173  BOOST_TEST(SP3.get<svc::ProviderB>() == SP1.get<svc::ProviderB>());
174 
175  // multiple elements of the same type
176  // should be a compilation error
177 #if PROVIDERPACK_TEST_SKIP_COMPILATION_ERRORS
178  BOOST_TEST_MESSAGE
179  (" (test to create a pack with many providers with same type skipped)");
180 #else
182  <svc::ProviderA, svc::ProviderB, svc::ProviderA, svc::ProviderD> SP3;
183 #endif // !PROVIDERPACK_TEST_SKIP_COMPILATION_ERRORS
184 
185 
186 } // BOOST_AUTO_TEST_CASE(ProviderPack_testcase)
187 
188 
189 // -----------------------------------------------------------------------------
190 BOOST_AUTO_TEST_CASE(ProviderPackDerived_testcase) {
191 
192  svc::ProviderA providerA;
193  svc::ProviderB1 providerB;
194 
195  //
196  // initialise a base class provider with a derived class
197  //
199  (&providerA, &providerB);
200 
201  BOOST_TEST(SP1.get<svc::ProviderA>() == &providerA);
202  BOOST_TEST(SP1.get<svc::ProviderB>() == &providerB);
203 
204  //
205  // initialise with a copy from makeProviderPack(),
206  // which should return lar::ProviderPack<svc::ProviderA, svc::ProviderB1>
207  //
209  = makeProviderPack(&providerA, &providerB);
210 
211  BOOST_TEST(SP2.get<svc::ProviderA>() == &providerA);
212  BOOST_TEST(SP2.get<svc::ProviderB>() == &providerB);
213 
214 } // BOOST_AUTO_TEST_CASE(test_ProviderPack)
215 
216 
217 // -----------------------------------------------------------------------------
An empty class that can&#39;t be copied nor moved.
static unsigned int max_count
A service provider class.
std::string string
Definition: nybbler.cc:12
Defines classes that can&#39;t be copied nor moved.
Provider const * get() const
Returns the provider with the specified type.
Definition: ProviderPack.h:193
Data structure containing constant pointers to classes.
A service provider class.
static unsigned int max_count
BOOST_AUTO_TEST_CASE(test_ProviderPack)
A service provider class derived from B.
unsigned int count
ProviderPack< Providers... > makeProviderPack(Providers const *...providers)
Function to create a ProviderPack from the function arguments.
Definition: ProviderPack.h:272
A service provider class.
static unsigned int max_count
static unsigned int max_count
unsigned int count
A service provider class.
Container for a list of pointers to providers.
Definition: ProviderPack.h:114
ProviderPack< Providers... > makeProviderPack(Providers const *...providers)
Function to create a ParameterPack from the function arguments.
Definition: ProviderPack.h:182
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
static unsigned int max_count