Add warnings provider to settings

This commit is contained in:
Dan Paulat 2024-04-25 22:24:10 -05:00
parent ea19de3e5f
commit 5ee2d10a1b
8 changed files with 234 additions and 144 deletions

View file

@ -1,5 +1,6 @@
#include <scwx/qt/manager/text_event_manager.hpp> #include <scwx/qt/manager/text_event_manager.hpp>
#include <scwx/qt/main/application.hpp> #include <scwx/qt/main/application.hpp>
#include <scwx/qt/settings/general_settings.hpp>
#include <scwx/awips/text_product_file.hpp> #include <scwx/awips/text_product_file.hpp>
#include <scwx/provider/warnings_provider.hpp> #include <scwx/provider/warnings_provider.hpp>
#include <scwx/util/logger.hpp> #include <scwx/util/logger.hpp>
@ -32,9 +33,20 @@ public:
refreshTimer_ {threadPool_}, refreshTimer_ {threadPool_},
refreshMutex_ {}, refreshMutex_ {},
textEventMap_ {}, textEventMap_ {},
textEventMutex_ {}, textEventMutex_ {}
warningsProvider_ {kDefaultWarningsProviderUrl}
{ {
auto& generalSettings = settings::GeneralSettings::Instance();
warningsProvider_ = std::make_shared<provider::WarningsProvider>(
generalSettings.warnings_provider().GetValue());
warningsProviderChangedCallbackUuid_ =
generalSettings.warnings_provider().RegisterValueChangedCallback(
[this](const std::string& value) {
warningsProvider_ =
std::make_shared<provider::WarningsProvider>(value);
});
boost::asio::post(threadPool_, boost::asio::post(threadPool_,
[this]() [this]()
{ {
@ -46,6 +58,10 @@ public:
~Impl() ~Impl()
{ {
settings::GeneralSettings::Instance()
.warnings_provider()
.UnregisterValueChangedCallback(warningsProviderChangedCallbackUuid_);
std::unique_lock lock(refreshMutex_); std::unique_lock lock(refreshMutex_);
refreshTimer_.cancel(); refreshTimer_.cancel();
lock.unlock(); lock.unlock();
@ -69,7 +85,9 @@ public:
textEventMap_; textEventMap_;
std::shared_mutex textEventMutex_; std::shared_mutex textEventMutex_;
provider::WarningsProvider warningsProvider_; std::shared_ptr<provider::WarningsProvider> warningsProvider_ {nullptr};
boost::uuids::uuid warningsProviderChangedCallbackUuid_ {};
}; };
TextEventManager::TextEventManager() : p(std::make_unique<Impl>(this)) {} TextEventManager::TextEventManager() : p(std::make_unique<Impl>(this)) {}
@ -201,13 +219,17 @@ void TextEventManager::Impl::Refresh()
// Take a unique lock before refreshing // Take a unique lock before refreshing
std::unique_lock lock(refreshMutex_); std::unique_lock lock(refreshMutex_);
// Take a copy of the current warnings provider to protect against change
std::shared_ptr<provider::WarningsProvider> warningsProvider =
warningsProvider_;
// Update the file listing from the warnings provider // Update the file listing from the warnings provider
auto [newFiles, totalFiles] = warningsProvider_.ListFiles(); auto [newFiles, totalFiles] = warningsProvider->ListFiles();
if (newFiles > 0) if (newFiles > 0)
{ {
// Load new files // Load new files
auto updatedFiles = warningsProvider_.LoadUpdatedFiles(); auto updatedFiles = warningsProvider->LoadUpdatedFiles();
// Handle messages // Handle messages
for (auto& file : updatedFiles) for (auto& file : updatedFiles)

View file

@ -10,6 +10,7 @@
#include <array> #include <array>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <QUrl>
namespace scwx namespace scwx
{ {
@ -25,6 +26,9 @@ class GeneralSettings::Impl
public: public:
explicit Impl() explicit Impl()
{ {
const std::string defaultWarningsProviderValue =
"https://warnings.allisonhouse.com";
std::string defaultClockFormatValue = std::string defaultClockFormatValue =
scwx::util::GetClockFormatName(scwx::util::ClockFormat::_24Hour); scwx::util::GetClockFormatName(scwx::util::ClockFormat::_24Hour);
std::string defaultDefaultAlertActionValue = std::string defaultDefaultAlertActionValue =
@ -63,6 +67,7 @@ public:
theme_.SetDefault(defaultThemeValue); theme_.SetDefault(defaultThemeValue);
trackLocation_.SetDefault(false); trackLocation_.SetDefault(false);
updateNotificationsEnabled_.SetDefault(true); updateNotificationsEnabled_.SetDefault(true);
warningsProvider_.SetDefault(defaultWarningsProviderValue);
fontSizes_.SetElementMinimum(1); fontSizes_.SetElementMinimum(1);
fontSizes_.SetElementMaximum(72); fontSizes_.SetElementMaximum(72);
@ -103,6 +108,9 @@ public:
SCWX_SETTINGS_ENUM_VALIDATOR(types::UiStyle, // SCWX_SETTINGS_ENUM_VALIDATOR(types::UiStyle, //
types::UiStyleIterator(), types::UiStyleIterator(),
types::GetUiStyleName)); types::GetUiStyleName));
warningsProvider_.SetValidator(
[](const std::string& value)
{ return QUrl {QString::fromStdString(value)}.isValid(); });
} }
~Impl() {} ~Impl() {}
@ -128,6 +136,7 @@ public:
SettingsVariable<std::string> theme_ {"theme"}; SettingsVariable<std::string> theme_ {"theme"};
SettingsVariable<bool> trackLocation_ {"track_location"}; SettingsVariable<bool> trackLocation_ {"track_location"};
SettingsVariable<bool> updateNotificationsEnabled_ {"update_notifications"}; SettingsVariable<bool> updateNotificationsEnabled_ {"update_notifications"};
SettingsVariable<std::string> warningsProvider_ {"warnings_provider"};
}; };
GeneralSettings::GeneralSettings() : GeneralSettings::GeneralSettings() :
@ -153,7 +162,8 @@ GeneralSettings::GeneralSettings() :
&p->showMapLogo_, &p->showMapLogo_,
&p->theme_, &p->theme_,
&p->trackLocation_, &p->trackLocation_,
&p->updateNotificationsEnabled_}); &p->updateNotificationsEnabled_,
&p->warningsProvider_});
SetDefaults(); SetDefaults();
} }
GeneralSettings::~GeneralSettings() = default; GeneralSettings::~GeneralSettings() = default;
@ -268,6 +278,11 @@ SettingsVariable<bool>& GeneralSettings::update_notifications_enabled() const
return p->updateNotificationsEnabled_; return p->updateNotificationsEnabled_;
} }
SettingsVariable<std::string>& GeneralSettings::warnings_provider() const
{
return p->warningsProvider_;
}
bool GeneralSettings::Shutdown() bool GeneralSettings::Shutdown()
{ {
bool dataChanged = false; bool dataChanged = false;
@ -310,7 +325,8 @@ bool operator==(const GeneralSettings& lhs, const GeneralSettings& rhs)
lhs.p->theme_ == rhs.p->theme_ && lhs.p->theme_ == rhs.p->theme_ &&
lhs.p->trackLocation_ == rhs.p->trackLocation_ && lhs.p->trackLocation_ == rhs.p->trackLocation_ &&
lhs.p->updateNotificationsEnabled_ == lhs.p->updateNotificationsEnabled_ ==
rhs.p->updateNotificationsEnabled_); rhs.p->updateNotificationsEnabled_ &&
lhs.p->warningsProvider_ == rhs.p->warningsProvider_);
} }
} // namespace settings } // namespace settings

View file

@ -45,7 +45,8 @@ public:
SettingsVariable<bool>& show_map_logo() const; SettingsVariable<bool>& show_map_logo() const;
SettingsVariable<std::string>& theme() const; SettingsVariable<std::string>& theme() const;
SettingsVariable<bool>& track_location() const; SettingsVariable<bool>& track_location() const;
SettingsVariable<bool>& update_notifications_enabled() const; SettingsVariable<bool>& update_notifications_enabled() const;
SettingsVariable<std::string>& warnings_provider() const;
static GeneralSettings& Instance(); static GeneralSettings& Instance();

View file

@ -133,6 +133,7 @@ public:
&defaultAlertAction_, &defaultAlertAction_,
&clockFormat_, &clockFormat_,
&defaultTimeZone_, &defaultTimeZone_,
&warningsProvider_,
&antiAliasingEnabled_, &antiAliasingEnabled_,
&showMapAttribution_, &showMapAttribution_,
&showMapCenter_, &showMapCenter_,
@ -232,6 +233,7 @@ public:
settings::SettingsInterface<std::string> clockFormat_ {}; settings::SettingsInterface<std::string> clockFormat_ {};
settings::SettingsInterface<std::string> defaultTimeZone_ {}; settings::SettingsInterface<std::string> defaultTimeZone_ {};
settings::SettingsInterface<std::string> theme_ {}; settings::SettingsInterface<std::string> theme_ {};
settings::SettingsInterface<std::string> warningsProvider_ {};
settings::SettingsInterface<bool> antiAliasingEnabled_ {}; settings::SettingsInterface<bool> antiAliasingEnabled_ {};
settings::SettingsInterface<bool> showMapAttribution_ {}; settings::SettingsInterface<bool> showMapAttribution_ {};
settings::SettingsInterface<bool> showMapCenter_ {}; settings::SettingsInterface<bool> showMapCenter_ {};
@ -660,6 +662,10 @@ void SettingsDialogImpl::SetupGeneralTab()
defaultTimeZone_.SetEditWidget(self_->ui->defaultTimeZoneComboBox); defaultTimeZone_.SetEditWidget(self_->ui->defaultTimeZoneComboBox);
defaultTimeZone_.SetResetButton(self_->ui->resetDefaultTimeZoneButton); defaultTimeZone_.SetResetButton(self_->ui->resetDefaultTimeZoneButton);
warningsProvider_.SetSettingsVariable(generalSettings.warnings_provider());
warningsProvider_.SetEditWidget(self_->ui->warningsProviderLineEdit);
warningsProvider_.SetResetButton(self_->ui->resetWarningsProviderButton);
antiAliasingEnabled_.SetSettingsVariable( antiAliasingEnabled_.SetSettingsVariable(
generalSettings.anti_aliasing_enabled()); generalSettings.anti_aliasing_enabled());
antiAliasingEnabled_.SetEditWidget(self_->ui->antiAliasingEnabledCheckBox); antiAliasingEnabled_.SetEditWidget(self_->ui->antiAliasingEnabledCheckBox);

View file

@ -128,7 +128,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>513</width> <width>513</width>
<height>454</height> <height>482</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
@ -150,10 +150,35 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="1" column="0"> <item row="8" column="2">
<widget class="QLabel" name="label"> <widget class="QComboBox" name="defaultAlertActionComboBox"/>
</item>
<item row="6" column="4">
<widget class="QToolButton" name="resetMapboxApiKeyButton">
<property name="text"> <property name="text">
<string>Default Radar Site</string> <string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Mapbox API Key</string>
</property>
</widget>
</item>
<item row="9" column="4">
<widget class="QToolButton" name="resetClockFormatButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property> </property>
</widget> </widget>
</item> </item>
@ -164,24 +189,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Map Provider</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QToolButton" name="resetThemeButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property>
</widget>
</item>
<item row="8" column="4"> <item row="8" column="4">
<widget class="QToolButton" name="resetDefaultAlertActionButton"> <widget class="QToolButton" name="resetDefaultAlertActionButton">
<property name="text"> <property name="text">
@ -193,32 +200,15 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="2"> <item row="9" column="0">
<widget class="QComboBox" name="clockFormatComboBox"/> <widget class="QLabel" name="label_20">
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>Mapbox API Key</string> <string>Clock Format</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="4">
<widget class="QLabel" name="label_2"> <widget class="QToolButton" name="resetGridWidthButton">
<property name="text">
<string>Grid Width</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>MapTiler API Key</string>
</property>
</widget>
</item>
<item row="10" column="4">
<widget class="QToolButton" name="resetDefaultTimeZoneButton">
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
</property> </property>
@ -228,11 +218,8 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="2"> <item row="1" column="4">
<widget class="QComboBox" name="defaultAlertActionComboBox"/> <widget class="QToolButton" name="resetRadarSiteButton">
</item>
<item row="7" column="4">
<widget class="QToolButton" name="resetMapTilerApiKeyButton">
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
</property> </property>
@ -242,6 +229,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Grid Height</string>
</property>
</widget>
</item>
<item row="3" column="4"> <item row="3" column="4">
<widget class="QToolButton" name="resetGridHeightButton"> <widget class="QToolButton" name="resetGridHeightButton">
<property name="text"> <property name="text">
@ -253,11 +247,24 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="2"> <item row="11" column="2">
<widget class="QComboBox" name="radarSiteComboBox"/> <widget class="QLineEdit" name="warningsProviderLineEdit"/>
</item> </item>
<item row="1" column="4"> <item row="0" column="2">
<widget class="QToolButton" name="resetRadarSiteButton"> <widget class="QComboBox" name="themeComboBox"/>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Warnings Provider</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="gridWidthSpinBox"/>
</item>
<item row="5" column="4">
<widget class="QToolButton" name="resetMapProviderButton">
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
</property> </property>
@ -274,78 +281,8 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0"> <item row="0" column="4">
<widget class="QLabel" name="label_5"> <widget class="QToolButton" name="resetThemeButton">
<property name="text">
<string>Theme</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="themeComboBox"/>
</item>
<item row="10" column="2">
<widget class="QComboBox" name="defaultTimeZoneComboBox"/>
</item>
<item row="1" column="3">
<widget class="QToolButton" name="radarSiteSelectButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QLineEdit" name="mapTilerApiKeyLineEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="defaultAlertActionLabel">
<property name="text">
<string>Default Alert Action</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QToolButton" name="resetGridWidthButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QComboBox" name="mapProviderComboBox"/>
</item>
<item row="5" column="4">
<widget class="QToolButton" name="resetMapProviderButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property>
</widget>
</item>
<item row="6" column="4">
<widget class="QToolButton" name="resetMapboxApiKeyButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property>
</widget>
</item>
<item row="9" column="4">
<widget class="QToolButton" name="resetClockFormatButton">
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
</property> </property>
@ -358,20 +295,104 @@
<item row="3" column="2"> <item row="3" column="2">
<widget class="QSpinBox" name="gridHeightSpinBox"/> <widget class="QSpinBox" name="gridHeightSpinBox"/>
</item> </item>
<item row="2" column="2"> <item row="9" column="2">
<widget class="QSpinBox" name="gridWidthSpinBox"/> <widget class="QComboBox" name="clockFormatComboBox"/>
</item> </item>
<item row="9" column="0"> <item row="10" column="2">
<widget class="QLabel" name="label_20"> <widget class="QComboBox" name="defaultTimeZoneComboBox"/>
</item>
<item row="1" column="3">
<widget class="QToolButton" name="radarSiteSelectButton">
<property name="text"> <property name="text">
<string>Clock Format</string> <string>...</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label_3"> <widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
<string>Grid Height</string> <string>Theme</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>MapTiler API Key</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Map Provider</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="defaultAlertActionLabel">
<property name="text">
<string>Default Alert Action</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Grid Width</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Default Radar Site</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QComboBox" name="mapProviderComboBox"/>
</item>
<item row="7" column="4">
<widget class="QToolButton" name="resetMapTilerApiKeyButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="radarSiteComboBox"/>
</item>
<item row="7" column="2">
<widget class="QLineEdit" name="mapTilerApiKeyLineEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="10" column="4">
<widget class="QToolButton" name="resetDefaultTimeZoneButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property>
</widget>
</item>
<item row="11" column="4">
<widget class="QToolButton" name="resetWarningsProviderButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="../../../../scwx-qt.qrc">
<normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</normaloff>:/res/icons/font-awesome-6/rotate-left-solid.svg</iconset>
</property> </property>
</widget> </widget>
</item> </item>

@ -1 +1 @@
Subproject commit ab32df5b0731d70aa5b977453c9aa4786eb0bd3f Subproject commit e350743fd8ca6858ce49a22bb8e40a0c6710ca86

View file

@ -8,12 +8,18 @@ namespace network
{ {
static const std::string& kDefaultUrl {"https://warnings.allisonhouse.com"}; static const std::string& kDefaultUrl {"https://warnings.allisonhouse.com"};
static const std::string& kAlternateUrl {"http://warnings.cod.edu"}; static const std::string& kAlternateUrl {"https://warnings.cod.edu"};
TEST(DirList, GetDefaultUrl) TEST(DirList, GetDefaultUrl)
{ {
auto records = DirList(kDefaultUrl); auto records = DirList(kDefaultUrl);
// No records, skip test
if (records.size() == 0)
{
GTEST_SKIP();
}
EXPECT_GT(records.size(), 0); EXPECT_GT(records.size(), 0);
} }
@ -21,6 +27,12 @@ TEST(DirList, GetAlternateUrl)
{ {
auto records = DirList(kAlternateUrl); auto records = DirList(kAlternateUrl);
// No records, skip test
if (records.size() == 0)
{
GTEST_SKIP();
}
EXPECT_GT(records.size(), 0); EXPECT_GT(records.size(), 0);
} }

View file

@ -8,7 +8,7 @@ namespace provider
{ {
static const std::string& kDefaultUrl {"https://warnings.allisonhouse.com"}; static const std::string& kDefaultUrl {"https://warnings.allisonhouse.com"};
static const std::string& kAlternateUrl {"http://warnings.cod.edu"}; static const std::string& kAlternateUrl {"https://warnings.cod.edu"};
class WarningsProviderTest : public testing::TestWithParam<std::string> class WarningsProviderTest : public testing::TestWithParam<std::string>
{ {
@ -19,6 +19,12 @@ TEST_P(WarningsProviderTest, ListFiles)
auto [newObjects, totalObjects] = provider.ListFiles(); auto [newObjects, totalObjects] = provider.ListFiles();
// No objects, skip test
if (totalObjects == 0)
{
GTEST_SKIP();
}
EXPECT_GT(newObjects, 0); EXPECT_GT(newObjects, 0);
EXPECT_GT(totalObjects, 0); EXPECT_GT(totalObjects, 0);
EXPECT_EQ(newObjects, totalObjects); EXPECT_EQ(newObjects, totalObjects);
@ -31,6 +37,12 @@ TEST_P(WarningsProviderTest, LoadUpdatedFiles)
auto [newObjects, totalObjects] = provider.ListFiles(); auto [newObjects, totalObjects] = provider.ListFiles();
auto updatedFiles = provider.LoadUpdatedFiles(); auto updatedFiles = provider.LoadUpdatedFiles();
// No objects, skip test
if (totalObjects == 0)
{
GTEST_SKIP();
}
EXPECT_GT(newObjects, 0); EXPECT_GT(newObjects, 0);
EXPECT_GT(totalObjects, 0); EXPECT_GT(totalObjects, 0);
EXPECT_EQ(newObjects, totalObjects); EXPECT_EQ(newObjects, totalObjects);