minix/external/bsd/kyua-cli/dist/utils/optional_test.cpp

286 lines
7.8 KiB
C++
Raw Normal View History

// Copyright 2010 Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "utils/optional.ipp"
#include <iostream>
#include <sstream>
#include <atf-c++.hpp>
using utils::none;
using utils::optional;
namespace {
/// Fake class to capture calls to the new and delete operators.
class test_alloc {
public:
/// Value to disambiguate objects after construction.
int value;
/// Balance of alive instances of this class in dynamic memory.
static size_t instances;
/// Constructs a new optional object.
///
/// \param value_ The value to store in this object for disambiguation.
test_alloc(int value_) : value(value_)
{
}
/// Allocates a new object and records its existence.
///
/// \param size The amount of memory to allocate.
///
/// \return A pointer to the allocated memory.
///
/// \throw std::bad_alloc If the memory allocation fails.
void*
operator new(size_t size)
{
instances++;
std::cout << "test_alloc::operator new called\n";
return ::operator new(size);
}
/// Deallocates an existing object and unrecords its existence.
///
/// \param mem The pointer to the memory to deallocate.
void
operator delete(void* mem)
{
instances--;
std::cout << "test_alloc::operator delete called\n";
::operator delete(mem);
}
};
size_t test_alloc::instances = 0;
/// Constructs and returns an optional object.
///
/// This is used by tests to validate that returning an object from within a
/// function works (i.e. the necessary constructors are available).
///
/// \tparam Type The type of the object included in the optional wrapper.
/// \param value The value to put inside the optional wrapper.
///
/// \return The constructed optional object.
template< typename Type >
optional< Type >
return_optional(const Type& value)
{
return optional< Type >(value);
}
} // anonymous namespace
ATF_TEST_CASE_WITHOUT_HEAD(ctors__native_type);
ATF_TEST_CASE_BODY(ctors__native_type)
{
const optional< int > no_args;
ATF_REQUIRE(!no_args);
const optional< int > with_none(none);
ATF_REQUIRE(!with_none);
const optional< int > with_arg(3);
ATF_REQUIRE(with_arg);
ATF_REQUIRE_EQ(3, with_arg.get());
const optional< int > copy_none(with_none);
ATF_REQUIRE(!copy_none);
const optional< int > copy_arg(with_arg);
ATF_REQUIRE(copy_arg);
ATF_REQUIRE_EQ(3, copy_arg.get());
}
ATF_TEST_CASE_WITHOUT_HEAD(ctors__complex_type);
ATF_TEST_CASE_BODY(ctors__complex_type)
{
const optional< std::string > no_args;
ATF_REQUIRE(!no_args);
const optional< std::string > with_none(none);
ATF_REQUIRE(!with_none);
const optional< std::string > with_arg("foo");
ATF_REQUIRE(with_arg);
ATF_REQUIRE_EQ("foo", with_arg.get());
const optional< std::string > copy_none(with_none);
ATF_REQUIRE(!copy_none);
const optional< std::string > copy_arg(with_arg);
ATF_REQUIRE(copy_arg);
ATF_REQUIRE_EQ("foo", copy_arg.get());
}
ATF_TEST_CASE_WITHOUT_HEAD(assign);
ATF_TEST_CASE_BODY(assign)
{
optional< int > from_default;
from_default = optional< int >();
ATF_REQUIRE(!from_default);
optional< int > from_none(3);
from_none = none;
ATF_REQUIRE(!from_none);
optional< int > from_int;
from_int = 6;
ATF_REQUIRE_EQ(6, from_int.get());
}
ATF_TEST_CASE_WITHOUT_HEAD(return);
ATF_TEST_CASE_BODY(return)
{
optional< long > from_return(return_optional< long >(123));
ATF_REQUIRE(from_return);
ATF_REQUIRE_EQ(123, from_return.get());
}
ATF_TEST_CASE_WITHOUT_HEAD(memory);
ATF_TEST_CASE_BODY(memory)
{
ATF_REQUIRE_EQ(0, test_alloc::instances);
{
optional< test_alloc > optional1(test_alloc(3));
ATF_REQUIRE_EQ(1, test_alloc::instances);
ATF_REQUIRE_EQ(3, optional1.get().value);
{
optional< test_alloc > optional2(optional1);
ATF_REQUIRE_EQ(2, test_alloc::instances);
ATF_REQUIRE_EQ(3, optional2.get().value);
optional2 = 5;
ATF_REQUIRE_EQ(2, test_alloc::instances);
ATF_REQUIRE_EQ(5, optional2.get().value);
ATF_REQUIRE_EQ(3, optional1.get().value);
}
ATF_REQUIRE_EQ(1, test_alloc::instances);
ATF_REQUIRE_EQ(3, optional1.get().value);
}
ATF_REQUIRE_EQ(0, test_alloc::instances);
}
ATF_TEST_CASE_WITHOUT_HEAD(get_default);
ATF_TEST_CASE_BODY(get_default)
{
const std::string def_value = "hello";
optional< std::string > optional;
ATF_REQUIRE(&def_value == &optional.get_default(def_value));
optional = "bye";
ATF_REQUIRE_EQ("bye", optional.get_default(def_value));
}
ATF_TEST_CASE_WITHOUT_HEAD(make_optional);
ATF_TEST_CASE_BODY(make_optional)
{
optional< int > opt = utils::make_optional(576);
ATF_REQUIRE(opt);
ATF_REQUIRE_EQ(576, opt.get());
}
ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne);
ATF_TEST_CASE_BODY(operators_eq_and_ne)
{
optional< int > opt1, opt2;
opt1 = none; opt2 = none;
ATF_REQUIRE( opt1 == opt2);
ATF_REQUIRE(!(opt1 != opt2));
opt1 = utils::make_optional(5); opt2 = none;
ATF_REQUIRE(!(opt1 == opt2));
ATF_REQUIRE( opt1 != opt2);
opt1 = none; opt2 = utils::make_optional(5);
ATF_REQUIRE(!(opt1 == opt2));
ATF_REQUIRE( opt1 != opt2);
opt1 = utils::make_optional(5); opt2 = utils::make_optional(5);
ATF_REQUIRE( opt1 == opt2);
ATF_REQUIRE(!(opt1 != opt2));
opt1 = utils::make_optional(6); opt2 = utils::make_optional(5);
ATF_REQUIRE(!(opt1 == opt2));
ATF_REQUIRE( opt1 != opt2);
}
ATF_TEST_CASE_WITHOUT_HEAD(output);
ATF_TEST_CASE_BODY(output)
{
{
std::ostringstream str;
str << optional< int >(none);
ATF_REQUIRE_EQ("none", str.str());
}
{
std::ostringstream str;
str << optional< int >(5);
ATF_REQUIRE_EQ("5", str.str());
}
{
std::ostringstream str;
str << optional< std::string >("this is a text");
ATF_REQUIRE_EQ("this is a text", str.str());
}
}
ATF_INIT_TEST_CASES(tcs)
{
ATF_ADD_TEST_CASE(tcs, ctors__native_type);
ATF_ADD_TEST_CASE(tcs, ctors__complex_type);
ATF_ADD_TEST_CASE(tcs, assign);
ATF_ADD_TEST_CASE(tcs, return);
ATF_ADD_TEST_CASE(tcs, memory);
ATF_ADD_TEST_CASE(tcs, get_default);
ATF_ADD_TEST_CASE(tcs, make_optional);
ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne);
ATF_ADD_TEST_CASE(tcs, output);
}