blob: 7cb475f06de949f9d43341208774936e48be77e0 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fidl/test/misc/cpp/fidl.h>
#include <lib/stdcompat/optional.h>
#include <zxtest/zxtest.h>
// The following APIs tested are shared between strict and flexible bits, but
// are tested separately.
// TODO(fxb/62890): Update these to use TYPED_TEST equivalents when they become
// implemented in zxtest.
TEST(StrictBits, StrictBitwiseOperators) {
using fidl::test::misc::StrictBits;
StrictBits b_or_d = StrictBits::B | StrictBits::D;
EXPECT_EQ(static_cast<uint8_t>(b_or_d), 6u /* 2 | 4*/);
StrictBits b_or_e = StrictBits::B | StrictBits::E;
EXPECT_EQ(static_cast<uint8_t>(b_or_e), 10u /* 2 | 8*/);
StrictBits not_b = ~StrictBits::B;
EXPECT_EQ(static_cast<uint8_t>(not_b), 12u /* ~2 & (2 | 4 | 8)*/);
StrictBits not_d = ~StrictBits::D;
EXPECT_EQ(static_cast<uint8_t>(not_d), 10u /* ~4 & (2 | 4 | 8)*/);
StrictBits not_e = ~StrictBits::E;
EXPECT_EQ(static_cast<uint8_t>(not_e), 6u /* ~8 & (2 | 4 | 8)*/);
StrictBits b_and_not_e = StrictBits::B & ~StrictBits::E;
EXPECT_EQ(static_cast<uint8_t>(b_and_not_e), 2u /* 2 & 6*/);
StrictBits b_or_d_and_b_or_e = (StrictBits::B | StrictBits::D) & (StrictBits::B | StrictBits::E);
EXPECT_EQ(static_cast<uint8_t>(b_or_d_and_b_or_e), 2u /* 6 & 10*/);
StrictBits b_xor_not_e = StrictBits::B ^ ~StrictBits::E;
EXPECT_EQ(static_cast<uint8_t>(b_xor_not_e), 4u /* 4 ^ 6*/);
StrictBits b_or_d_xor_b_or_e = (StrictBits::B | StrictBits::D) ^ (StrictBits::B | StrictBits::E);
EXPECT_EQ(static_cast<uint8_t>(b_or_d_xor_b_or_e), 12u /* 6 ^ 10*/);
}
TEST(StrictBits, StrictBitwiseAssignOperators) {
using fidl::test::misc::StrictBits;
StrictBits b_or_d = StrictBits::B;
b_or_d |= StrictBits::D;
EXPECT_EQ(static_cast<uint8_t>(b_or_d), 6u /* 2 | 4*/);
StrictBits b_and_not_e = StrictBits::B;
b_and_not_e &= ~StrictBits::E;
EXPECT_EQ(static_cast<uint8_t>(b_and_not_e), 2u /* 2 & 6*/);
StrictBits b_xor_not_e = StrictBits::B;
b_xor_not_e ^= ~StrictBits::E;
EXPECT_EQ(static_cast<uint8_t>(b_xor_not_e), 4u /* 4 ^ 6*/);
EXPECT_EQ(static_cast<uint8_t>(StrictBits::B), 2u);
EXPECT_EQ(static_cast<uint8_t>(StrictBits::D), 4u);
EXPECT_EQ(static_cast<uint8_t>(StrictBits::E), 8u);
}
TEST(StrictBits, CanConvertStrictBitsToNumberButMustBeExplicit) {
using fidl::test::misc::StrictBits;
uint8_t r8 = static_cast<uint8_t>(StrictBits::B);
EXPECT_EQ(r8, 2u);
uint16_t r16 = static_cast<uint8_t>(StrictBits::B);
EXPECT_EQ(r16, 2u);
}
TEST(StrictBits, CanConvertStrictBitsToBool) {
using fidl::test::misc::StrictBits;
bool result = static_cast<bool>(StrictBits::B);
EXPECT_TRUE(result);
}
TEST(FlexibleBits, FlexibleBitwiseOperators) {
using fidl::test::misc::FlexibleBits;
FlexibleBits b_or_d = FlexibleBits::B | FlexibleBits::D;
EXPECT_EQ(static_cast<uint8_t>(b_or_d), 6u /* 2 | 4*/);
FlexibleBits b_or_e = FlexibleBits::B | FlexibleBits::E;
EXPECT_EQ(static_cast<uint8_t>(b_or_e), 10u /* 2 | 8*/);
FlexibleBits not_b = ~FlexibleBits::B;
EXPECT_EQ(static_cast<uint8_t>(not_b), 12u /* ~2 & (2 | 4 | 8)*/);
FlexibleBits not_d = ~FlexibleBits::D;
EXPECT_EQ(static_cast<uint8_t>(not_d), 10u /* ~4 & (2 | 4 | 8)*/);
FlexibleBits not_e = ~FlexibleBits::E;
EXPECT_EQ(static_cast<uint8_t>(not_e), 6u /* ~8 & (2 | 4 | 8)*/);
FlexibleBits b_and_not_e = FlexibleBits::B & ~FlexibleBits::E;
EXPECT_EQ(static_cast<uint8_t>(b_and_not_e), 2u /* 2 & 6*/);
FlexibleBits b_or_d_and_b_or_e =
(FlexibleBits::B | FlexibleBits::D) & (FlexibleBits::B | FlexibleBits::E);
EXPECT_EQ(static_cast<uint8_t>(b_or_d_and_b_or_e), 2u /* 6 & 10*/);
FlexibleBits b_xor_not_e = FlexibleBits::B ^ ~FlexibleBits::E;
EXPECT_EQ(static_cast<uint8_t>(b_xor_not_e), 4u /* 4 ^ 6*/);
FlexibleBits b_or_d_xor_b_or_e =
(FlexibleBits::B | FlexibleBits::D) ^ (FlexibleBits::B | FlexibleBits::E);
EXPECT_EQ(static_cast<uint8_t>(b_or_d_xor_b_or_e), 12u /* 6 ^ 10*/);
}
TEST(FlexibleBits, FlexibleBitwiseAssignOperators) {
using fidl::test::misc::FlexibleBits;
FlexibleBits b_or_d = FlexibleBits::B;
b_or_d |= FlexibleBits::D;
EXPECT_EQ(static_cast<uint8_t>(b_or_d), 6u /* 2 | 4*/);
FlexibleBits b_and_not_e = FlexibleBits::B;
b_and_not_e &= ~FlexibleBits::E;
EXPECT_EQ(static_cast<uint8_t>(b_and_not_e), 2u /* 2 & 6*/);
FlexibleBits b_xor_not_e = FlexibleBits::B;
b_xor_not_e ^= ~FlexibleBits::E;
EXPECT_EQ(static_cast<uint8_t>(b_xor_not_e), 4u /* 4 ^ 6*/);
EXPECT_EQ(static_cast<uint8_t>(FlexibleBits::B), 2u);
EXPECT_EQ(static_cast<uint8_t>(FlexibleBits::D), 4u);
EXPECT_EQ(static_cast<uint8_t>(FlexibleBits::E), 8u);
}
TEST(FlexibleBits, CanConvertFlexibleBitsToNumberButMustBeExplicit) {
using fidl::test::misc::FlexibleBits;
uint8_t r8 = static_cast<uint8_t>(FlexibleBits::B);
EXPECT_EQ(r8, 2u);
uint16_t r16 = static_cast<uint8_t>(FlexibleBits::B);
EXPECT_EQ(r16, 2u);
}
TEST(FlexibleBits, CanConvertFlexibleBitsToBool) {
using fidl::test::misc::FlexibleBits;
bool result = static_cast<bool>(FlexibleBits::B);
EXPECT_TRUE(result);
}
// The following APIs tested are only available on strict bits;
TEST(StrictBits, IsConstexprAndMask) {
using fidl::test::misc::StrictBits;
static constexpr auto this_should_compile = StrictBits::B | StrictBits::D | StrictBits::E;
EXPECT_EQ(this_should_compile, fidl::test::misc::StrictBitsMask);
}
// The following APIs tested are only available on flexible bits.
TEST(FlexibleBits, TruncatingUnknown) {
using BitsType = fidl::test::misc::FlexibleBits;
// The bits type only has 2, 4, and 8 defined.
auto bits = BitsType::TruncatingUnknown(1);
EXPECT_EQ(static_cast<uint8_t>(bits), 0);
}
TEST(FlexibleBits, TryFrom) {
using BitsType = fidl::test::misc::FlexibleBits;
// The bits type only has 2, 4, and 8 defined.
auto result = BitsType::TryFrom(1);
EXPECT_EQ(result, cpp17::nullopt);
auto result_ok = BitsType::TryFrom(2);
EXPECT_EQ(result_ok, cpp17::optional<BitsType>(BitsType::B));
}
TEST(FlexibleBits, QueryingUnknown) {
using BitsType = fidl::test::misc::FlexibleBits;
// The bits type only has 2, 4, and 8 defined.
auto bits = static_cast<BitsType>(2 | 1);
EXPECT_TRUE(bits.has_unknown_bits());
EXPECT_EQ(static_cast<uint8_t>(bits.unknown_bits()), 1);
bits = BitsType::TruncatingUnknown(2 | 1);
EXPECT_FALSE(bits.has_unknown_bits());
EXPECT_EQ(static_cast<uint8_t>(bits.unknown_bits()), 0);
}
TEST(FlexibleBits, IsConstexprAndMask) {
using fidl::test::misc::FlexibleBits;
static constexpr auto this_should_compile = FlexibleBits::B | FlexibleBits::D | FlexibleBits::E;
EXPECT_EQ(this_should_compile, fidl::test::misc::FlexibleBits::kMask);
}