Refactor intrinThresholdParams to use shared DAP helpers.
Delegate threshold param parsing to the new DeviceAttachmentSpec primitives so intrin modules stay aligned with stimBuff param conventions. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,331 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <support/exceptionAssertions.h>
|
||||
#include <user/intrinThresholdParams.h>
|
||||
#include <vector>
|
||||
|
||||
namespace smo {
|
||||
namespace intrin {
|
||||
namespace {
|
||||
|
||||
using ParamList = std::vector<std::pair<std::string, std::string>>;
|
||||
|
||||
ParamList makeParams(std::initializer_list<std::pair<const char*, const char*>> entries)
|
||||
{
|
||||
ParamList params;
|
||||
for (const auto& entry : entries)
|
||||
{
|
||||
params.emplace_back(entry.first, entry.second);
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdArrayContainsTest, MatchesCanonicalNames)
|
||||
{
|
||||
EXPECT_TRUE(arrayContains(kIntrinInterestPcNames, "interest-pc"));
|
||||
EXPECT_TRUE(arrayContains(kIntrinInterestThrNames, "interest-thr"));
|
||||
EXPECT_FALSE(arrayContains(kForbiddenUnitlessIntrinStems, "interest-pc"));
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdIsKnownParamNameTest, RecognizesAllCanonicalFamilies)
|
||||
{
|
||||
EXPECT_TRUE(isKnownIntrinThresholdParamName("interest-pc"));
|
||||
EXPECT_TRUE(isKnownIntrinThresholdParamName("interest-threshold"));
|
||||
EXPECT_TRUE(isKnownIntrinThresholdParamName("distraction-percentage"));
|
||||
EXPECT_TRUE(isKnownIntrinThresholdParamName("distraction-thr"));
|
||||
EXPECT_TRUE(isKnownIntrinThresholdParamName("stupefying-pc"));
|
||||
EXPECT_TRUE(isKnownIntrinThresholdParamName("stupefaction-thresh"));
|
||||
EXPECT_TRUE(isKnownIntrinThresholdParamName("intolerable-pc"));
|
||||
EXPECT_TRUE(isKnownIntrinThresholdParamName("intolerable-threshold"));
|
||||
|
||||
EXPECT_FALSE(isKnownIntrinThresholdParamName("interest"));
|
||||
EXPECT_FALSE(isKnownIntrinThresholdParamName("passband-count-gt-val"));
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdValidateNoIntrinParamsOnQualeIfaceTest, RejectsKnownIntrinNames)
|
||||
{
|
||||
const ParamList params = makeParams({{"interest-pc", "85"}});
|
||||
|
||||
try {
|
||||
validateNoIntrinParamsOnQualeIface("pcloudLightAmbience", params);
|
||||
FAIL() << "Expected std::runtime_error";
|
||||
}
|
||||
catch (const std::runtime_error& exception)
|
||||
{
|
||||
sscl::tests::expectExceptionMessageContains(
|
||||
exception, "not valid on qualeIfaceApi");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdValidateNoIntrinParamsOnQualeIfaceTest, RejectsUnitlessStems)
|
||||
{
|
||||
const ParamList params = makeParams({{"distraction", "10"}});
|
||||
|
||||
try {
|
||||
validateNoIntrinParamsOnQualeIface("mesh", params);
|
||||
FAIL() << "Expected std::runtime_error";
|
||||
}
|
||||
catch (const std::runtime_error& exception)
|
||||
{
|
||||
sscl::tests::expectExceptionMessageContains(
|
||||
exception, "invalid without a unit suffix");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdValidateNoIntrinParamsOnQualeIfaceTest, RejectsFromStimbuffMarker)
|
||||
{
|
||||
const ParamList params = makeParams({{"from-stimbuff", ""}});
|
||||
|
||||
try {
|
||||
validateNoIntrinParamsOnQualeIface("mesh", params);
|
||||
FAIL() << "Expected std::runtime_error";
|
||||
}
|
||||
catch (const std::runtime_error& exception)
|
||||
{
|
||||
sscl::tests::expectExceptionMessageContains(
|
||||
exception, "from-stimbuff");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdValidateNoIntrinParamsOnQualeIfaceTest, AllowsSensoryParams)
|
||||
{
|
||||
const ParamList params = makeParams({
|
||||
{"passband-count-gt-val", "12"},
|
||||
{"histbuff-ms", "30000"},
|
||||
});
|
||||
|
||||
EXPECT_NO_THROW(validateNoIntrinParamsOnQualeIface(
|
||||
"pcloudLightAmbience", params));
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdValidateIntrinSegmentParamsTest, RejectsUnitlessStems)
|
||||
{
|
||||
const ParamList params = makeParams({{"stupefaction", "5"}});
|
||||
|
||||
try {
|
||||
validateIntrinSegmentParams("postrin", params);
|
||||
FAIL() << "Expected std::runtime_error";
|
||||
}
|
||||
catch (const std::runtime_error& exception)
|
||||
{
|
||||
sscl::tests::expectExceptionMessageContains(
|
||||
exception, "invalid without a unit suffix");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdValidateIntrinSegmentParamsTest, AllowsSuffixedNames)
|
||||
{
|
||||
const ParamList params = makeParams({
|
||||
{"interest-pc", "85"},
|
||||
{"distraction-thr", "12"},
|
||||
});
|
||||
|
||||
EXPECT_NO_THROW(validateIntrinSegmentParams("negtrin", params));
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdParseOptionalThresholdParamTest, ReturnsDefaultWhenAbsent)
|
||||
{
|
||||
const ParamList params = makeParams({{"other-param", "1"}});
|
||||
|
||||
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||
params,
|
||||
kIntrinInterestPcNames,
|
||||
kIntrinInterestThrNames,
|
||||
/*defaultValue=*/7,
|
||||
/*defaultUnit=*/ThresholdUnit::Absolute);
|
||||
|
||||
EXPECT_FALSE(parsed.wasSpecified);
|
||||
EXPECT_EQ(parsed.value, 7);
|
||||
EXPECT_EQ(parsed.unit, ThresholdUnit::Absolute);
|
||||
EXPECT_TRUE(parsed.matchedName.empty());
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdParseOptionalThresholdParamTest, ParsesPercentageParam)
|
||||
{
|
||||
const ParamList params = makeParams({{"interest-percentage", "50"}});
|
||||
|
||||
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||
params,
|
||||
kIntrinInterestPcNames,
|
||||
kIntrinInterestThrNames,
|
||||
0,
|
||||
ThresholdUnit::Absolute);
|
||||
|
||||
EXPECT_TRUE(parsed.wasSpecified);
|
||||
EXPECT_EQ(parsed.value, 50);
|
||||
EXPECT_EQ(parsed.unit, ThresholdUnit::Percentage);
|
||||
EXPECT_EQ(parsed.matchedName, "interest-percentage");
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdParseOptionalThresholdParamTest, ParsesAbsoluteParam)
|
||||
{
|
||||
const ParamList params = makeParams({{"interest-threshold", "42"}});
|
||||
|
||||
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||
params,
|
||||
kIntrinInterestPcNames,
|
||||
kIntrinInterestThrNames,
|
||||
0,
|
||||
ThresholdUnit::Percentage);
|
||||
|
||||
EXPECT_TRUE(parsed.wasSpecified);
|
||||
EXPECT_EQ(parsed.value, 42);
|
||||
EXPECT_EQ(parsed.unit, ThresholdUnit::Absolute);
|
||||
EXPECT_EQ(parsed.matchedName, "interest-threshold");
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdParseOptionalThresholdParamTest, LattermostMatchingParamWins)
|
||||
{
|
||||
const ParamList params = makeParams({
|
||||
{"interest-pc", "10"},
|
||||
{"interest-threshold", "99"},
|
||||
});
|
||||
|
||||
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||
params,
|
||||
kIntrinInterestPcNames,
|
||||
kIntrinInterestThrNames,
|
||||
0,
|
||||
ThresholdUnit::Percentage);
|
||||
|
||||
EXPECT_TRUE(parsed.wasSpecified);
|
||||
EXPECT_EQ(parsed.value, 99);
|
||||
EXPECT_EQ(parsed.unit, ThresholdUnit::Absolute);
|
||||
EXPECT_EQ(parsed.matchedName, "interest-threshold");
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdParseOptionalThresholdParamTest, LattermostPercentageWinsOverEarlierAbsolute)
|
||||
{
|
||||
const ParamList params = makeParams({
|
||||
{"interest-thr", "12"},
|
||||
{"interest-pc", "75"},
|
||||
});
|
||||
|
||||
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||
params,
|
||||
kIntrinInterestPcNames,
|
||||
kIntrinInterestThrNames,
|
||||
0,
|
||||
ThresholdUnit::Absolute);
|
||||
|
||||
EXPECT_TRUE(parsed.wasSpecified);
|
||||
EXPECT_EQ(parsed.value, 75);
|
||||
EXPECT_EQ(parsed.unit, ThresholdUnit::Percentage);
|
||||
EXPECT_EQ(parsed.matchedName, "interest-pc");
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdParseOptionalThresholdParamTest, InvalidIntegerThrows)
|
||||
{
|
||||
const ParamList params = makeParams({{"interest-pc", "not-int"}});
|
||||
|
||||
try {
|
||||
parseOptionalThresholdParam(
|
||||
params,
|
||||
kIntrinInterestPcNames,
|
||||
kIntrinInterestThrNames,
|
||||
0,
|
||||
ThresholdUnit::Absolute);
|
||||
FAIL() << "Expected std::runtime_error";
|
||||
}
|
||||
catch (const std::runtime_error& exception)
|
||||
{
|
||||
sscl::tests::expectExceptionMessageContains(
|
||||
exception, "Failed to parse 'interest-pc'");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdResolveThresholdValueTest, PercentageUsesBase)
|
||||
{
|
||||
const ParsedThresholdParam percentageParam = {
|
||||
.value = 50,
|
||||
.unit = ThresholdUnit::Percentage,
|
||||
.matchedName = "interest-pc",
|
||||
.wasSpecified = true,
|
||||
};
|
||||
|
||||
EXPECT_EQ(resolveThresholdValue(percentageParam, 84), 42u);
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdResolveThresholdValueTest, AbsolutePassesThrough)
|
||||
{
|
||||
const ParsedThresholdParam absoluteParam = {
|
||||
.value = 17,
|
||||
.unit = ThresholdUnit::Absolute,
|
||||
.matchedName = "interest-thr",
|
||||
.wasSpecified = true,
|
||||
};
|
||||
|
||||
EXPECT_EQ(resolveThresholdValue(absoluteParam, 84), 17u);
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdResolveThresholdValueTest, PercentageTruncatesTowardZero)
|
||||
{
|
||||
const ParsedThresholdParam percentageParam = {
|
||||
.value = 33,
|
||||
.unit = ThresholdUnit::Percentage,
|
||||
.matchedName = "interest-pc",
|
||||
.wasSpecified = true,
|
||||
};
|
||||
|
||||
EXPECT_EQ(resolveThresholdValue(percentageParam, 100), 33u);
|
||||
EXPECT_EQ(resolveThresholdValue(percentageParam, 10), 3u);
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdSynonymCoverageTest, AllThrSynonymsParseAsAbsolute)
|
||||
{
|
||||
const std::array<std::string_view, 3> thrNames = {
|
||||
"interest-threshold",
|
||||
"interest-thresh",
|
||||
"interest-thr",
|
||||
};
|
||||
|
||||
for (const std::string_view thrName : thrNames)
|
||||
{
|
||||
const ParamList params = makeParams({
|
||||
{thrName.data(), "11"},
|
||||
});
|
||||
|
||||
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||
params,
|
||||
kIntrinInterestPcNames,
|
||||
kIntrinInterestThrNames,
|
||||
0,
|
||||
ThresholdUnit::Percentage);
|
||||
|
||||
EXPECT_TRUE(parsed.wasSpecified);
|
||||
EXPECT_EQ(parsed.unit, ThresholdUnit::Absolute);
|
||||
EXPECT_EQ(parsed.value, 11);
|
||||
EXPECT_EQ(parsed.matchedName, thrName);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(IntrinThresholdSynonymCoverageTest, AllPcSynonymsParseAsPercentage)
|
||||
{
|
||||
const std::array<std::string_view, 2> pcNames = {
|
||||
"interest-percentage",
|
||||
"interest-pc",
|
||||
};
|
||||
|
||||
for (const std::string_view pcName : pcNames)
|
||||
{
|
||||
const ParamList params = makeParams({
|
||||
{pcName.data(), "25"},
|
||||
});
|
||||
|
||||
const ParsedThresholdParam parsed = parseOptionalThresholdParam(
|
||||
params,
|
||||
kIntrinInterestPcNames,
|
||||
kIntrinInterestThrNames,
|
||||
0,
|
||||
ThresholdUnit::Absolute);
|
||||
|
||||
EXPECT_TRUE(parsed.wasSpecified);
|
||||
EXPECT_EQ(parsed.unit, ThresholdUnit::Percentage);
|
||||
EXPECT_EQ(parsed.value, 25);
|
||||
EXPECT_EQ(parsed.matchedName, pcName);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace intrin
|
||||
} // namespace smo
|
||||
Reference in New Issue
Block a user