From 1786f1539d8ef687b4391fc7856cd87b00eaa043 Mon Sep 17 00:00:00 2001 From: Ryan Blue Date: Fri, 25 Oct 2024 04:18:36 -0400 Subject: [PATCH] Add C++ tests --- wpilibc/src/test/native/cpp/AlertTest.cpp | 164 +++++++++++++++++++++ wpilibc/src/test/native/cpp/AlertsTest.cpp | 93 ------------ 2 files changed, 164 insertions(+), 93 deletions(-) create mode 100644 wpilibc/src/test/native/cpp/AlertTest.cpp delete mode 100644 wpilibc/src/test/native/cpp/AlertsTest.cpp diff --git a/wpilibc/src/test/native/cpp/AlertTest.cpp b/wpilibc/src/test/native/cpp/AlertTest.cpp new file mode 100644 index 00000000000..fa215529473 --- /dev/null +++ b/wpilibc/src/test/native/cpp/AlertTest.cpp @@ -0,0 +1,164 @@ +// Copyright (c) FIRST and other WPILib contributors. +// Open Source Software; you can modify and/or share it under the terms of +// the WPILib BSD license file in the root directory of this project. + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +using namespace frc; +using enum Alert::AlertType; +class AlertsTest : public ::testing::Test { + public: + ~AlertsTest() { + // test all destructors + Update(); + EXPECT_EQ(GetSubscriberForType(kError).Get().size(), 0ul); + EXPECT_EQ(GetSubscriberForType(kWarning).Get().size(), 0ul); + EXPECT_EQ(GetSubscriberForType(kInfo).Get().size(), 0ul); + } + + template + Alert MakeAlert(Args&&... args) { + return Alert(GetGroupName(), std::forward(args)...); + } + + std::string GetGroupName() { + const ::testing::TestInfo* testInfo = + ::testing::UnitTest::GetInstance()->current_test_info(); + return fmt::format("{}_{}", testInfo->test_suite_name(), + testInfo->test_case_name()); + } + + // todo: this + void ExpectAlertsState() {} + + bool IsAlertActive(std::string_view text, Alert::AlertType type) { + Update(); + auto activeAlerts = GetSubscriberForType(type).Get(); + return std::find(activeAlerts.begin(), activeAlerts.end(), text) != + activeAlerts.end(); + } + + void Update() { frc::SmartDashboard::UpdateValues(); } + + private: + std::string GetSubtableName(Alert::AlertType type) { + switch (type) { + case kError: + return "errors"; + case kWarning: + return "warnings"; + case kInfo: + return "infos"; + default: + return "unknown"; + } + } + + std::map m_subs; + const nt::StringArraySubscriber& GetSubscriberForType(Alert::AlertType type) { + if (m_subs.contains(type)) { + return m_subs[type]; + } else { + return m_subs + .emplace(std::make_pair( + type, nt::NetworkTableInstance::GetDefault() + .GetStringArrayTopic( + fmt::format("/SmartDashboard/{}/{}", GetGroupName(), + GetSubtableName(type))) + .Subscribe({}))) + .first->second; + } + } +}; + +TEST_F(AlertsTest, SetUnset) { + auto one = MakeAlert("one", kError); + auto two = MakeAlert("two", kInfo); + EXPECT_FALSE(IsAlertActive("one", kError)); + EXPECT_FALSE(IsAlertActive("two", kInfo)); + one.Set(true); + EXPECT_TRUE(IsAlertActive("one", kError)); + EXPECT_FALSE(IsAlertActive("two", kInfo)); + one.Set(true); + two.Set(true); + EXPECT_TRUE(IsAlertActive("one", kError)); + EXPECT_TRUE(IsAlertActive("two", kInfo)); + one.Set(false); + EXPECT_FALSE(IsAlertActive("one", kError)); + EXPECT_TRUE(IsAlertActive("two", kInfo)); +} + +TEST_F(AlertsTest, DestructorUnsetsAlert) { + { + auto alert = MakeAlert("alert", kWarning); + alert.Set(true); + EXPECT_TRUE(IsAlertActive("alert", kWarning)); + } + EXPECT_FALSE(IsAlertActive("alert", kWarning)); +} + +TEST_F(AlertsTest, SetTextWhileUnset) { + auto alert = MakeAlert("BEFORE", kInfo); + EXPECT_EQ("BEFORE", alert.GetText()); + alert.Set(true); + EXPECT_TRUE(IsAlertActive("BEFORE", kInfo)); + alert.Set(false); + EXPECT_FALSE(IsAlertActive("BEFORE", kInfo)); + alert.SetText("AFTER"); + EXPECT_EQ("AFTER", alert.GetText()); + alert.Set(true); + EXPECT_FALSE(IsAlertActive("BEFORE", kInfo)); + EXPECT_TRUE(IsAlertActive("AFTER", kInfo)); +} + +TEST_F(AlertsTest, SetTextWhileSet) { + auto alert = MakeAlert("BEFORE", kInfo); + EXPECT_EQ("BEFORE", alert.GetText()); + alert.Set(true); + EXPECT_TRUE(IsAlertActive("BEFORE", kInfo)); + alert.SetText("AFTER"); + EXPECT_EQ("AFTER", alert.GetText()); + EXPECT_FALSE(IsAlertActive("BEFORE", kInfo)); + EXPECT_TRUE(IsAlertActive("AFTER", kInfo)); +} + +TEST_F(AlertsTest, MoveAssign) { + auto outer = MakeAlert("outer", kInfo); + outer.Set(true); + EXPECT_TRUE(IsAlertActive("outer", kInfo)); + + { + auto inner = MakeAlert("inner", kWarning); + inner.Set(true); + EXPECT_TRUE(IsAlertActive("inner", kWarning)); + outer = std::move(inner); + // Assignment target should be unset and invalidated as part of move, before + // destruction + EXPECT_FALSE(IsAlertActive("outer", kInfo)); + } + EXPECT_TRUE(IsAlertActive("inner", kWarning)); +} + +TEST_F(AlertsTest, MoveConstruct) { + auto a = MakeAlert("A", kInfo); + a.Set(true); + EXPECT_TRUE(IsAlertActive("A", kInfo)); + Alert b{std::move(a)}; + EXPECT_TRUE(IsAlertActive("A", kInfo)); + b.Set(false); + EXPECT_FALSE(IsAlertActive("A", kInfo)); + b.Set(true); + EXPECT_TRUE(IsAlertActive("A", kInfo)); +} diff --git a/wpilibc/src/test/native/cpp/AlertsTest.cpp b/wpilibc/src/test/native/cpp/AlertsTest.cpp deleted file mode 100644 index 947e7423d00..00000000000 --- a/wpilibc/src/test/native/cpp/AlertsTest.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) FIRST and other WPILib contributors. -// Open Source Software; you can modify and/or share it under the terms of -// the WPILib BSD license file in the root directory of this project. - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -using namespace frc; -using enum Alert::AlertType; -class AlertsTest : public ::testing::Test { - public: - ~AlertsTest() { - EXPECT_EQ(GetSubscriberForType(kError).Get().size(), 0); - EXPECT_EQ(GetSubscriberForType(kWarning).Get().size(), 0); - EXPECT_EQ(GetSubscriberForType(kInfo).Get().size(), 0); - } - - template - Alert MakeAlert(Args&&... args) { - return Alert(GetGroupName(), std::forward(args)...); - } - - std::string GetGroupName() { - const ::testing::TestInfo* testInfo = - ::testing::UnitTest::GetInstance()->current_test_info(); - return fmt::format("{}_{}", testInfo->test_suite_name(), - testInfo->test_case_name()); - } - - bool IsAlertActive(std::string_view text, Alert::AlertType type) { - std::vector activeAlerts = GetSubscriberForType(type).Get(); - return std::find(activeAlerts.begin(), activeAlerts.end(), text) != - activeAlerts.end(); - } - - private: - std::string GetSubtableName(Alert::AlertType type) { - switch (type) { - case kError: - return "errors"; - case kWarning: - return "warnings"; - case kInfo: - return "infos"; - default: - return "unknown"; - } - } - - std::map m_subs; - const nt::StringArraySubscriber& GetSubscriberForType(Alert::AlertType type) { - if (m_subs.contains(type)) { - return m_subs[type]; - } else { - return m_subs - .emplace(std::make_pair( - type, nt::NetworkTableInstance::GetDefault() - .GetStringArrayTopic( - fmt::format("/SmartDashboard/{}/{}", GetGroupName(), - GetSubtableName(type))) - .Subscribe({}))) - .first->second; - } - } -}; - -TEST_F(AlertsTest, Constructors) { - // Make and destroy - Alert{GetGroupName(), "One", kError}; - Alert a{GetGroupName(), "Two", kInfo}; - a.Set(true); - a.Set(false); - // Move assign - a = Alert(GetGroupName(), "Three", kWarning); - // Move construct - Alert b{std::move(a)}; - { - // Move assign with dynamic string - std::string text = fmt::format( - "{}", std::chrono::steady_clock::now().time_since_epoch().count()); - b = Alert(text, kError); - } -}