uTL
micro Template library
test_ostream_dev.cpp
Go to the documentation of this file.
1 
20 #include <gtest/gtest.h>
21 #include <utl/dev/ostream_dev.h>
22 #include <array>
23 
24 namespace test_ostream_dev {
25  using namespace utl;
26 
27  // Device base data types
28  // MUST be DefaultConstructible, Copyable
29  using test_data_t = uint8_t;
30 
31  // Test data
32  static const size_t SIZE = 10;
33 
36  test_data_t&& IdataRR = 0xAA;
37  test_data_t Ibuffer[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
38 
39  // ostream device implementer (Mocks)
40  class Ostream_dev_impl : public ostream_dev<Ostream_dev_impl, test_data_t> {
42  public:
43  // virtual device
44  static constexpr size_t N =SIZE;
45  std::array<test_data_t, N> v {}; // more than one so we can remember N-1 previous values
46  size_t c {0};
47 
48  protected:
49  // ostream_dev requirements
50  size_t put_ (const test_data_t& data) {
51  v[c++] = data;
52  if (c >= N)
53  c = 0;
54  return 1;
55  }
56  size_t put_ (const test_data_t* data, size_t n) {
57  for (size_t i=0 ; i<n && i<N; ++i) {
58  v[i] = data[i];
59  }
60  return n;
61  }
62  public:
63  test_data_t& getLastV () { return (c) ? v[c-1] : v[N-1]; }
64  };
65  // virtual ostream device
66  class Ostream_vdev_impl : public ostream_dev<virtual_tag, test_data_t> {
67  public:
68  // virtual device
69  static constexpr size_t N =SIZE;
70  std::array<test_data_t, N> v {};
71  size_t c {0};
72 
73  protected:
74  // ostream_dev requirements
75  size_t put_ (const test_data_t& data) {
76  v[c++] = data;
77  if (c >= N)
78  c = 0;
79  return 1;
80  }
81  size_t put_ (const test_data_t* data, size_t n) {
82  for (size_t i=0 ; i<n && i<N; ++i) {
83  v[i] = data[i];
84  }
85  return n;
86  }
87  public:
88  test_data_t& getLastV () { return (c) ? v[c-1] : v[N-1]; }
89  };
90 
91  // fixtures
92  class Tostream_Idev : public ::testing::Test {
93  protected:
94  // zero initialized device
95  Ostream_dev_impl osIdev {};
96  };
97  class Tostream_Vdev : public ::testing::Test {
98  protected:
99  // zero initialized devices
100  std::array<Ostream_vdev_impl, 5> osVdev {};
102  };
103 
104  //ToDo: Must add Concept test for ostream_dev
105 // TEST_F(Tostream_Idev, TestConcept) {
106 // EXPECT_EQ(true, Ostream_dev<osIdev>);
107 // }
108 
109  TEST_F(Tostream_Idev, Construction) {
110  EXPECT_LT(0UL, sizeof(osIdev));
111  }
112 
114  EXPECT_EQ(1UL, osIdev.put(Idata)); // single write from var
115  EXPECT_EQ(Idata, osIdev.getLastV ());
116 
117  EXPECT_EQ(1UL, osIdev.put(IdataR));// single write from lvalue ref
118  EXPECT_EQ(IdataR, osIdev.getLastV ());
119 
120  EXPECT_EQ(1UL, osIdev.put(IdataRR));// single write from rvalue ref
121  EXPECT_EQ(IdataRR, osIdev.getLastV ());
122 
123  EXPECT_EQ(1UL, osIdev.put(42));// single write from rvalue
124  EXPECT_EQ(42U, osIdev.getLastV ());
125 
126  EXPECT_EQ(7U, osIdev.put(Ibuffer, 7)); // batch write some data
127  for (size_t i =0 ; i<7 ; ++i) {
128  EXPECT_EQ(Ibuffer[i], osIdev.v[i]);
129  }
130  EXPECT_EQ(0, osIdev.v[7]);
131 
132  EXPECT_EQ(SIZE, osIdev.put(Ibuffer, SIZE)); // batch write all data
133  for (size_t i =0 ; i<SIZE ; ++i) {
134  EXPECT_EQ(Ibuffer[i], osIdev.v[i]);
135  }
136  }
137 
138  TEST_F (Tostream_Idev, streamOperator) {
139  struct Blop {
140  test_data_t x, y, z;
141  };
142 
143  osIdev << Idata; // single write from var
144  EXPECT_EQ(Idata, osIdev.getLastV ());
145 
146  osIdev << IdataR;// single write from lvalue ref
147  EXPECT_EQ(IdataR, osIdev.getLastV ());
148 
149  osIdev << IdataRR;// single write from rvalue ref
150  EXPECT_EQ(IdataRR, osIdev.getLastV ());
151 
152  osIdev << (test_data_t)42; // single write from rvalue
153  EXPECT_EQ(42U, osIdev.getLastV ());
154 
155  // stream a blop of data (should use put(T*, N) version)
156  Blop blop {1, 1, 42};
157  osIdev << blop;
158  EXPECT_EQ(1U, osIdev.v[0]);
159  EXPECT_EQ(1U, osIdev.v[1]);
160  EXPECT_EQ(42U, osIdev.v[2]);
161 
162  const Blop cblop {2, 2, 42};
163  osIdev << cblop;
164  EXPECT_EQ(2U, osIdev.v[0]);
165  EXPECT_EQ(2U, osIdev.v[1]);
166  EXPECT_EQ(42U, osIdev.v[2]);
167  }
168 
169  TEST_F (Tostream_Idev, Iterator1) {
170  // default constructible
172  EXPECT_EQ (0, *(int32_t*)&def_it); // not dereferencable
173 
174  // output iterator requirements
175  // https://en.cppreference.com/w/cpp/named_req/OutputIterator
176  auto it = osIdev.begin();
177  auto it2(it);
178  EXPECT_EQ (*(int32_t*)&it, *(int32_t*)&it2);
179 
180  it2 = it;
181  EXPECT_EQ (*(int32_t*)&it, *(int32_t*)&it2);
182  def_it = it;
183  EXPECT_EQ (*(int32_t*)&it, *(int32_t*)&def_it);
184  ++it, it++;
185 
186  *it = Idata;
187  EXPECT_EQ (Idata, osIdev.getLastV ());
188  *it = IdataR;
189  EXPECT_EQ (IdataR, osIdev.getLastV ());
190  *it = IdataRR;
191  EXPECT_EQ (IdataRR, osIdev.getLastV ());
192 
193  *it++ = Idata;
194  EXPECT_EQ (Idata, osIdev.getLastV ());
195 
196  }
197 
198  TEST_F (Tostream_Idev, Iterator2) {
199  auto it = osIdev.begin();
200 
201  std::fill_n(it, SIZE, Idata);
202  for (size_t i=0 ;i<SIZE ; ++i) {
203  EXPECT_EQ (Idata, osIdev.v[i]);
204  }
205  }
206 
207  TEST_F (Tostream_Vdev, virtualApi) {
208  // loop to virtual devices and use them via base pointer
209  for (auto& dev : osVdev) {
210  basePointer = &dev;
211  basePointer->put(Idata);
212  EXPECT_EQ(Idata, dev.v[0]);
213 
214  EXPECT_EQ(SIZE, basePointer->put(Ibuffer, SIZE)); // batch write all data
215  for (size_t i =0 ; i<SIZE ; ++i) {
216  EXPECT_EQ(Ibuffer[i], dev.v[i]);
217  }
218  }
219  }
220 
221  TEST_F (Tostream_Vdev, virtualStream) {
222  struct Blop {
223  test_data_t x, y, z;
224  };
225  Blop blop {1, 1, 42};
226  const Blop cblop {2, 2, 42};
227 
228  // loop to virtual devices and use them via base pointer
229  for (auto& dev : osVdev) {
230  basePointer = &dev;
231  *basePointer << IdataR;
232  EXPECT_EQ(IdataR, dev.v[0]);
233 
234  *basePointer << blop;
235  EXPECT_EQ(1U, dev.v[0]);
236  EXPECT_EQ(1U, dev.v[1]);
237  EXPECT_EQ(42U, dev.v[2]);
238 
239  *basePointer << cblop;
240  EXPECT_EQ(2U, dev.v[0]);
241  EXPECT_EQ(2U, dev.v[1]);
242  EXPECT_EQ(42U, dev.v[2]);
243  }
244  }
245 
246  TEST_F (Tostream_Vdev, virtualIterator) {
247  // loop to virtual devices and use them via base pointer
248  for (auto& dev : osVdev) {
249  basePointer = &dev;
250  auto it = *basePointer->begin();
251  std::fill_n(it, SIZE, Idata);
252  for (size_t i=0 ;i<SIZE ; ++i) {
253  EXPECT_EQ (Idata, dev.v[i]);
254  }
255  }
256  }
257 }
size_t put_(const test_data_t *data, size_t n)
test_data_t Ibuffer[]
size_t put_(const test_data_t &data)
test_data_t && IdataRR
size_t put_(const test_data_t &data)
#define EXPECT_LT(val1, val2)
Definition: gtest.h:16651
Abstract base classes for output stream devices.
Definition: ostream_dev.h:52
STL&#39;s core language concepts.
Definition: _1wire.h:30
TEST_F(Tostream_Idev, Construction)
size_t put_(const test_data_t *data, size_t n)
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:16643
Abstract base class interface for output devices of utl.
test_data_t & IdataR