1 /*
2 * ====================================================================
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 * ====================================================================
20 */
21
22 #include <boost/test/unit_test.hpp>
23
24 #include <algorithm>
25 #include <stdexcept>
26
27 #include "../src/aprwrap.hpp"
28
29 #include "fixture_init.hpp"
30
31 BOOST_AUTO_TEST_SUITE(aprwrap_arrays,
32 * boost::unit_test::fixture<init>());
33
34 namespace {
35 // Create a randomly-ordered array of constant strings.
fill_array(apr::pool & pool)36 apr_array_header_t* fill_array(apr::pool& pool)
37 {
38 apr_array_header_t* a = apr_array_make(pool.get(), 0, sizeof(const char*));
39 APR_ARRAY_PUSH(a, const char*) = "primus";
40 APR_ARRAY_PUSH(a, const char*) = "secundus";
41 APR_ARRAY_PUSH(a, const char*) = "tertius";
42 APR_ARRAY_PUSH(a, const char*) = "quartus";
43 APR_ARRAY_PUSH(a, const char*) = "quintus";
44 APR_ARRAY_PUSH(a, const char*) = "sextus";
45 APR_ARRAY_PUSH(a, const char*) = "septimus";
46 std::random_shuffle(&APR_ARRAY_IDX(a, 0, const char*),
47 &APR_ARRAY_IDX(a, a->nelts, const char*));
48 return a;
49 }
50 } // anonymous namespace
51
BOOST_AUTO_TEST_CASE(create_array)52 BOOST_AUTO_TEST_CASE(create_array)
53 {
54 typedef apr::array<unsigned char> array;
55
56 apr::pool pool;
57 array a(pool);
58
59 BOOST_TEST(a.get_array() != nullptr);
60 BOOST_TEST(a.size() == 0);
61 BOOST_TEST(sizeof(array::value_type) == sizeof(unsigned char));
62 BOOST_TEST(a.get_array()->elt_size == sizeof(array::value_type));
63 }
64
BOOST_AUTO_TEST_CASE(wrap_array)65 BOOST_AUTO_TEST_CASE(wrap_array)
66 {
67 typedef apr::array<unsigned char> array;
68
69 apr::pool pool;
70 apr_array_header_t* apr_array =
71 apr_array_make(pool.get(), 0, sizeof(array::value_type));
72 BOOST_TEST_REQUIRE(apr_array != nullptr);
73
74 array a(apr_array);
75 BOOST_TEST(a.get_array() == apr_array);
76 BOOST_TEST(a.size() == 0);
77 }
78
BOOST_AUTO_TEST_CASE(rewrap_type_mismatch)79 BOOST_AUTO_TEST_CASE(rewrap_type_mismatch)
80 {
81 typedef apr::array<unsigned char> byte_array;
82 typedef apr::array<int> int_array;
83
84 apr::pool pool;
85 BOOST_CHECK_THROW(byte_array{int_array(pool).get_array()},
86 std::invalid_argument);
87 }
88
BOOST_AUTO_TEST_CASE(out_of_bounds)89 BOOST_AUTO_TEST_CASE(out_of_bounds)
90 {
91 typedef apr::array<unsigned char> array;
92
93 apr::pool pool;
94 array a(pool);
95
96 BOOST_CHECK_THROW(a.at(-1), std::out_of_range);
97 BOOST_CHECK_THROW(a.at(a.size()), std::out_of_range);
98 }
99
BOOST_AUTO_TEST_CASE(indexing)100 BOOST_AUTO_TEST_CASE(indexing)
101 {
102 typedef apr::array<const char*> array;
103
104 apr::pool pool;
105 array a(fill_array(pool));
106
107 BOOST_TEST(a[0] == APR_ARRAY_IDX(a.get_array(), 0, array::value_type));
108 BOOST_TEST(a[a.size() - 1] == APR_ARRAY_IDX(a.get_array(),
109 a.get_array()->nelts - 1,
110 array::value_type));
111 }
112
BOOST_AUTO_TEST_CASE(checked_indexing)113 BOOST_AUTO_TEST_CASE(checked_indexing)
114 {
115 typedef apr::array<const char*> array;
116
117 apr::pool pool;
118 array a(fill_array(pool));
119
120 BOOST_TEST(a.at(0) == APR_ARRAY_IDX(a.get_array(), 0, array::value_type));
121 BOOST_TEST(a.at(a.size() - 1) == APR_ARRAY_IDX(a.get_array(),
122 a.get_array()->nelts - 1,
123 array::value_type));
124 }
125
BOOST_AUTO_TEST_CASE(iteration)126 BOOST_AUTO_TEST_CASE(iteration)
127 {
128 typedef apr::array<const char*> array;
129
130 apr::pool pool;
131 array a(fill_array(pool));
132
133 const auto raw_array = a.get_array();
134 array::size_type index = 0;
135 for (auto& value : a)
136 {
137 BOOST_TEST(value == APR_ARRAY_IDX(raw_array, index, array::value_type));
138 ++index;
139 }
140 }
141
BOOST_AUTO_TEST_CASE(const_iteration)142 BOOST_AUTO_TEST_CASE(const_iteration)
143 {
144 typedef apr::array<const char*> array;
145
146 apr::pool pool;
147 const array a(fill_array(pool));
148
149 const auto raw_array = a.get_array();
150 array::size_type index = 0;
151 for (const auto& value : a)
152 {
153 BOOST_TEST(value == APR_ARRAY_IDX(raw_array, index, array::value_type));
154 ++index;
155 }
156 }
157
BOOST_AUTO_TEST_CASE(push)158 BOOST_AUTO_TEST_CASE(push)
159 {
160 typedef apr::array<const char*> array;
161
162 apr::pool pool;
163 array a(fill_array(pool));
164
165 const array::size_type point = a.size();
166 const array::value_type first = a[0];
167 const array::value_type last = a[point - 1];
168
169 a.push("octavius");
170 a.push("nonus");
171 a.push("decimus");
172
173 BOOST_TEST(a.size() == point + 3);
174 BOOST_TEST(a[0] == first);
175 BOOST_TEST(a[point - 1] == last);
176 BOOST_TEST(a[point] == "octavius");
177 BOOST_TEST(a[a.size() - 1] == "decimus");
178 }
179
BOOST_AUTO_TEST_CASE(pop)180 BOOST_AUTO_TEST_CASE(pop)
181 {
182 typedef apr::array<const char*> array;
183
184 apr::pool pool;
185 array a(fill_array(pool));
186
187 for (array::size_type i = 0, z = a.size(); i <= z; ++i)
188 {
189 const char** last = (!a.get_array()->nelts ? nullptr
190 : &APR_ARRAY_IDX(a.get_array(),
191 a.get_array()->nelts - 1,
192 array::value_type));
193 BOOST_TEST(a.pop() == last);
194 }
195 }
196
197 BOOST_AUTO_TEST_SUITE_END();
198