ladybird/Tests/AK/TestSpan.cpp
Ben Wiederhake c2a900b853 Everywhere: Remove unused includes of AK/StdLibExtras.h
These instances were detected by searching for files that include
AK/StdLibExtras.h, but don't match the regex:

\\b(abs|AK_REPLACED_STD_NAMESPACE|array_size|ceil_div|clamp|exchange|for
ward|is_constant_evaluated|is_power_of_two|max|min|mix|move|_RawPtr|RawP
tr|round_up_to_power_of_two|swap|to_underlying)\\b

(Without the linebreaks.)

This regex is pessimistic, so there might be more files that don't
actually use any "extra stdlib" functions.

In theory, one might use LibCPP to detect things like this
automatically, but let's do this one step after another.
2023-01-02 20:27:20 -05:00

141 lines
3.4 KiB
C++

/*
* Copyright (c) 2020, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibTest/TestCase.h>
#include <AK/Checked.h>
#include <AK/Span.h>
#include <string.h>
TEST_CASE(constexpr_default_constructor_is_empty)
{
constexpr Span<int> span;
static_assert(span.is_empty(), "Default constructed span should be empty.");
}
TEST_CASE(implicit_conversion_to_const)
{
constexpr Bytes bytes0;
[[maybe_unused]] constexpr ReadonlyBytes bytes2 = bytes0;
[[maybe_unused]] constexpr ReadonlyBytes bytes3 = static_cast<ReadonlyBytes>(bytes2);
}
TEST_CASE(span_works_with_constant_types)
{
static constexpr u8 buffer[4] { 1, 2, 3, 4 };
constexpr ReadonlyBytes bytes { buffer, 4 };
static_assert(IsConst<RemoveReference<decltype(bytes[1])>>);
static_assert(bytes[2] == 3);
}
TEST_CASE(span_works_with_mutable_types)
{
u8 buffer[4] { 1, 2, 3, 4 };
Bytes bytes { buffer, 4 };
EXPECT_EQ(bytes[2], 3);
++bytes[2];
EXPECT_EQ(bytes[2], 4);
}
TEST_CASE(iterator_behaves_like_loop)
{
u8 buffer[256];
for (int idx = 0; idx < 256; ++idx) {
buffer[idx] = static_cast<u8>(idx);
}
Bytes bytes { buffer, 256 };
size_t idx = 0;
for (auto iter = bytes.begin(); iter < bytes.end(); ++iter) {
EXPECT_EQ(*iter, buffer[idx]);
++idx;
}
}
TEST_CASE(modifying_is_possible)
{
int values_before[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int values_after[8] = { 7, 6, 5, 4, 3, 2, 1, 0 };
Span<int> span { values_before, 8 };
for (auto& value : span) {
value = 8 - value;
}
for (int idx = 0; idx < 8; ++idx) {
EXPECT_EQ(values_before[idx], values_after[idx]);
}
}
TEST_CASE(at_and_index_operator_return_same_value)
{
u8 buffer[256];
for (int idx = 0; idx < 256; ++idx) {
buffer[idx] = static_cast<u8>(idx);
}
Bytes bytes { buffer, 256 };
for (int idx = 0; idx < 256; ++idx) {
EXPECT_EQ(buffer[idx], bytes[idx]);
EXPECT_EQ(bytes[idx], bytes.at(idx));
}
}
TEST_CASE(can_subspan_whole_span)
{
static constexpr u8 buffer[16] {};
constexpr ReadonlyBytes bytes { buffer, 16 };
constexpr auto slice = bytes.slice(0, 16);
static_assert(slice.data() == buffer);
static_assert(slice.size() == 16u);
}
TEST_CASE(can_subspan_as_intended)
{
static constexpr u16 buffer[8] { 1, 2, 3, 4, 5, 6, 7, 8 };
constexpr Span<u16 const> span { buffer, 8 };
constexpr auto slice = span.slice(3, 2);
static_assert(slice.size() == 2u);
static_assert(slice[0] == 4);
static_assert(slice[1] == 5);
}
TEST_CASE(span_from_void_pointer)
{
int value = 0;
[[maybe_unused]] Bytes bytes0 { reinterpret_cast<void*>(value), 4 };
[[maybe_unused]] ReadonlyBytes bytes1 { reinterpret_cast<void const*>(value), 4 };
}
TEST_CASE(span_from_c_string)
{
char const* str = "Serenity";
[[maybe_unused]] ReadonlyBytes bytes { str, strlen(str) };
}
TEST_CASE(starts_with)
{
char const* str = "HeyFriends!";
ReadonlyBytes bytes { str, strlen(str) };
char const* str_hey = "Hey";
ReadonlyBytes hey_bytes { str_hey, strlen(str_hey) };
EXPECT(bytes.starts_with(hey_bytes));
char const* str_nah = "Nah";
ReadonlyBytes nah_bytes { str_nah, strlen(str_nah) };
EXPECT(!bytes.starts_with(nah_bytes));
const u8 hey_array[3] = { 'H', 'e', 'y' };
ReadonlyBytes hey_bytes_u8 { hey_array, 3 };
EXPECT(bytes.starts_with(hey_bytes_u8));
}