1 // Copyright 2010 The Kyua Authors. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors 14 // may be used to endorse or promote products derived from this software 15 // without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 #include "utils/optional.ipp" 30 31 #include <iostream> 32 #include <sstream> 33 34 #include <atf-c++.hpp> 35 36 using utils::none; 37 using utils::optional; 38 39 40 namespace { 41 42 43 /// Fake class to capture calls to the new and delete operators. 44 class test_alloc { 45 public: 46 /// Value to disambiguate objects after construction. 47 int value; 48 49 /// Balance of alive instances of this class in dynamic memory. 50 static size_t instances; 51 52 /// Constructs a new optional object. 53 /// 54 /// \param value_ The value to store in this object for disambiguation. 55 test_alloc(int value_) : value(value_) 56 { 57 } 58 59 /// Allocates a new object and records its existence. 60 /// 61 /// \param size The amount of memory to allocate. 62 /// 63 /// \return A pointer to the allocated memory. 64 /// 65 /// \throw std::bad_alloc If the memory allocation fails. 66 void* 67 operator new(size_t size) 68 { 69 instances++; 70 std::cout << "test_alloc::operator new called\n"; 71 return ::operator new(size); 72 } 73 74 /// Deallocates an existing object and unrecords its existence. 75 /// 76 /// \param mem The pointer to the memory to deallocate. 77 void 78 operator delete(void* mem) 79 { 80 instances--; 81 std::cout << "test_alloc::operator delete called\n"; 82 ::operator delete(mem); 83 } 84 }; 85 86 87 size_t test_alloc::instances = 0; 88 89 90 /// Constructs and returns an optional object. 91 /// 92 /// This is used by tests to validate that returning an object from within a 93 /// function works (i.e. the necessary constructors are available). 94 /// 95 /// \tparam Type The type of the object included in the optional wrapper. 96 /// \param value The value to put inside the optional wrapper. 97 /// 98 /// \return The constructed optional object. 99 template< typename Type > 100 optional< Type > 101 return_optional(const Type& value) 102 { 103 return optional< Type >(value); 104 } 105 106 107 } // anonymous namespace 108 109 110 ATF_TEST_CASE_WITHOUT_HEAD(ctors__native_type); 111 ATF_TEST_CASE_BODY(ctors__native_type) 112 { 113 const optional< int > no_args; 114 ATF_REQUIRE(!no_args); 115 116 const optional< int > with_none(none); 117 ATF_REQUIRE(!with_none); 118 119 const optional< int > with_arg(3); 120 ATF_REQUIRE(with_arg); 121 ATF_REQUIRE_EQ(3, with_arg.get()); 122 123 const optional< int > copy_none(with_none); 124 ATF_REQUIRE(!copy_none); 125 126 const optional< int > copy_arg(with_arg); 127 ATF_REQUIRE(copy_arg); 128 ATF_REQUIRE_EQ(3, copy_arg.get()); 129 } 130 131 132 ATF_TEST_CASE_WITHOUT_HEAD(ctors__complex_type); 133 ATF_TEST_CASE_BODY(ctors__complex_type) 134 { 135 const optional< std::string > no_args; 136 ATF_REQUIRE(!no_args); 137 138 const optional< std::string > with_none(none); 139 ATF_REQUIRE(!with_none); 140 141 const optional< std::string > with_arg("foo"); 142 ATF_REQUIRE(with_arg); 143 ATF_REQUIRE_EQ("foo", with_arg.get()); 144 145 const optional< std::string > copy_none(with_none); 146 ATF_REQUIRE(!copy_none); 147 148 const optional< std::string > copy_arg(with_arg); 149 ATF_REQUIRE(copy_arg); 150 ATF_REQUIRE_EQ("foo", copy_arg.get()); 151 } 152 153 154 ATF_TEST_CASE_WITHOUT_HEAD(assign); 155 ATF_TEST_CASE_BODY(assign) 156 { 157 optional< int > from_default; 158 from_default = optional< int >(); 159 ATF_REQUIRE(!from_default); 160 161 optional< int > from_none(3); 162 from_none = none; 163 ATF_REQUIRE(!from_none); 164 165 optional< int > from_int; 166 from_int = 6; 167 ATF_REQUIRE_EQ(6, from_int.get()); 168 } 169 170 171 ATF_TEST_CASE_WITHOUT_HEAD(return); 172 ATF_TEST_CASE_BODY(return) 173 { 174 optional< long > from_return(return_optional< long >(123)); 175 ATF_REQUIRE(from_return); 176 ATF_REQUIRE_EQ(123, from_return.get()); 177 } 178 179 180 ATF_TEST_CASE_WITHOUT_HEAD(memory); 181 ATF_TEST_CASE_BODY(memory) 182 { 183 ATF_REQUIRE_EQ(0, test_alloc::instances); 184 { 185 optional< test_alloc > optional1(test_alloc(3)); 186 ATF_REQUIRE_EQ(1, test_alloc::instances); 187 ATF_REQUIRE_EQ(3, optional1.get().value); 188 189 { 190 optional< test_alloc > optional2(optional1); 191 ATF_REQUIRE_EQ(2, test_alloc::instances); 192 ATF_REQUIRE_EQ(3, optional2.get().value); 193 194 optional2 = 5; 195 ATF_REQUIRE_EQ(2, test_alloc::instances); 196 ATF_REQUIRE_EQ(5, optional2.get().value); 197 ATF_REQUIRE_EQ(3, optional1.get().value); 198 } 199 ATF_REQUIRE_EQ(1, test_alloc::instances); 200 ATF_REQUIRE_EQ(3, optional1.get().value); 201 } 202 ATF_REQUIRE_EQ(0, test_alloc::instances); 203 } 204 205 206 ATF_TEST_CASE_WITHOUT_HEAD(get_default); 207 ATF_TEST_CASE_BODY(get_default) 208 { 209 const std::string def_value = "hello"; 210 optional< std::string > optional; 211 ATF_REQUIRE(&def_value == &optional.get_default(def_value)); 212 optional = "bye"; 213 ATF_REQUIRE_EQ("bye", optional.get_default(def_value)); 214 } 215 216 217 ATF_TEST_CASE_WITHOUT_HEAD(make_optional); 218 ATF_TEST_CASE_BODY(make_optional) 219 { 220 optional< int > opt = utils::make_optional(576); 221 ATF_REQUIRE(opt); 222 ATF_REQUIRE_EQ(576, opt.get()); 223 } 224 225 226 ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne); 227 ATF_TEST_CASE_BODY(operators_eq_and_ne) 228 { 229 optional< int > opt1, opt2; 230 231 opt1 = none; opt2 = none; 232 ATF_REQUIRE( opt1 == opt2); 233 ATF_REQUIRE(!(opt1 != opt2)); 234 235 opt1 = utils::make_optional(5); opt2 = none; 236 ATF_REQUIRE(!(opt1 == opt2)); 237 ATF_REQUIRE( opt1 != opt2); 238 239 opt1 = none; opt2 = utils::make_optional(5); 240 ATF_REQUIRE(!(opt1 == opt2)); 241 ATF_REQUIRE( opt1 != opt2); 242 243 opt1 = utils::make_optional(5); opt2 = utils::make_optional(5); 244 ATF_REQUIRE( opt1 == opt2); 245 ATF_REQUIRE(!(opt1 != opt2)); 246 247 opt1 = utils::make_optional(6); opt2 = utils::make_optional(5); 248 ATF_REQUIRE(!(opt1 == opt2)); 249 ATF_REQUIRE( opt1 != opt2); 250 } 251 252 253 ATF_TEST_CASE_WITHOUT_HEAD(output); 254 ATF_TEST_CASE_BODY(output) 255 { 256 { 257 std::ostringstream str; 258 str << optional< int >(none); 259 ATF_REQUIRE_EQ("none", str.str()); 260 } 261 { 262 std::ostringstream str; 263 str << optional< int >(5); 264 ATF_REQUIRE_EQ("5", str.str()); 265 } 266 { 267 std::ostringstream str; 268 str << optional< std::string >("this is a text"); 269 ATF_REQUIRE_EQ("this is a text", str.str()); 270 } 271 } 272 273 274 ATF_INIT_TEST_CASES(tcs) 275 { 276 ATF_ADD_TEST_CASE(tcs, ctors__native_type); 277 ATF_ADD_TEST_CASE(tcs, ctors__complex_type); 278 ATF_ADD_TEST_CASE(tcs, assign); 279 ATF_ADD_TEST_CASE(tcs, return); 280 ATF_ADD_TEST_CASE(tcs, memory); 281 ATF_ADD_TEST_CASE(tcs, get_default); 282 ATF_ADD_TEST_CASE(tcs, make_optional); 283 ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne); 284 ATF_ADD_TEST_CASE(tcs, output); 285 } 286