From 840c3b501d179ec6d3f04b9c691a5f859d6783d9 Mon Sep 17 00:00:00 2001 From: Lenny Maiorani Date: Sat, 21 Nov 2020 17:23:17 -0700 Subject: [PATCH] NeverDestroyed: Add tests Problem: - It is difficult to refactor because there are no tests to bind the functionality. - Arguments are not forwarded correctly to the constructor. Solution: - Add tests. - Change constructor to take forwarding references. --- AK/NeverDestroyed.h | 2 +- AK/Tests/TestNeverDestroyed.cpp | 95 +++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 AK/Tests/TestNeverDestroyed.cpp diff --git a/AK/NeverDestroyed.h b/AK/NeverDestroyed.h index 64035a759a..ca4df2ee29 100644 --- a/AK/NeverDestroyed.h +++ b/AK/NeverDestroyed.h @@ -38,7 +38,7 @@ class NeverDestroyed { public: template - NeverDestroyed(Args... args) + NeverDestroyed(Args&&... args) { new (storage) T(forward(args)...); } diff --git a/AK/Tests/TestNeverDestroyed.cpp b/AK/Tests/TestNeverDestroyed.cpp new file mode 100644 index 0000000000..ed76b19339 --- /dev/null +++ b/AK/Tests/TestNeverDestroyed.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 HOLDER 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 + +#include +#include + +struct Counter { + Counter() = default; + + ~Counter() { ++num_destroys; } + + Counter(const Counter&) + { + ++num_copies; + } + + Counter(Counter&&) { ++num_moves; } + + int num_copies {}; + int num_moves {}; + int num_destroys {}; +}; + +TEST_CASE(should_construct_by_copy) +{ + Counter c {}; + AK::NeverDestroyed n { c }; + + EXPECT_EQ(1, n->num_copies); + EXPECT_EQ(0, n->num_moves); +} + +TEST_CASE(should_construct_by_move) +{ + Counter c {}; + AK::NeverDestroyed n { AK::move(c) }; + + EXPECT_EQ(0, n->num_copies); + EXPECT_EQ(1, n->num_moves); +} + +TEST_CASE(should_not_destroy) +{ + Counter* c = nullptr; + { + AK::NeverDestroyed n {}; + c = &n.get(); + } + EXPECT_EQ(0, c->num_destroys); +} + +TEST_CASE(should_provide_dereference_operator) +{ + AK::NeverDestroyed n {}; + EXPECT_EQ(0, n->num_destroys); +} + +TEST_CASE(should_provide_indirection_operator) +{ + AK::NeverDestroyed n {}; + EXPECT_EQ(0, (*n).num_destroys); +} + +TEST_CASE(should_provide_basic_getter) +{ + AK::NeverDestroyed n {}; + EXPECT_EQ(0, n.get().num_destroys); +} + +TEST_MAIN(NeverDestroyed)