Try not to suggest same audio tracks, added some unit tests

This commit is contained in:
emeric
2026-06-05 13:53:30 +02:00
parent a4ab9829d5
commit 710c53b4b4
3 changed files with 76 additions and 1 deletions
@@ -25,8 +25,8 @@
#include "math/NormalizedCosineDistance.hpp" #include "math/NormalizedCosineDistance.hpp"
#include "math/Vector.hpp" #include "math/Vector.hpp"
#include "track-selection-constraints/ITrackCandidateHardConstraint.hpp"
#include "Types.hpp" #include "Types.hpp"
#include "track-selection-constraints/ITrackCandidateHardConstraint.hpp"
namespace lms::recommendation namespace lms::recommendation
{ {
@@ -4,6 +4,7 @@ add_executable(test-recommendation
target_link_libraries(test-recommendation PRIVATE target_link_libraries(test-recommendation PRIVATE
lmsrecommendation lmsrecommendation
lmsmath
GTest::GTest GTest::GTest
GTest::gtest_main GTest::gtest_main
) )
@@ -22,7 +22,9 @@
#include "database/objects/ArtistId.hpp" #include "database/objects/ArtistId.hpp"
#include "database/objects/ReleaseId.hpp" #include "database/objects/ReleaseId.hpp"
#include "database/objects/TrackId.hpp" #include "database/objects/TrackId.hpp"
#include "math/Vector.hpp"
#include "audio-similarity/NearDuplicateEmbeddingConstraint.hpp"
#include "track-selection-constraints/DuplicateTrackConstraint.hpp" #include "track-selection-constraints/DuplicateTrackConstraint.hpp"
#include "track-selection-constraints/SameArtistConstraint.hpp" #include "track-selection-constraints/SameArtistConstraint.hpp"
#include "track-selection-constraints/SameReleaseConstraint.hpp" #include "track-selection-constraints/SameReleaseConstraint.hpp"
@@ -238,3 +240,75 @@ TEST(TrackCandidateEvaluator, hardConstraintPassesEvenWithSoftConstraints)
EXPECT_FALSE(evaluator.rejects(ctx)); EXPECT_FALSE(evaluator.rejects(ctx));
EXPECT_FLOAT_EQ(evaluator.score(ctx), 1.F); EXPECT_FLOAT_EQ(evaluator.score(ctx), 1.F);
} }
namespace
{
using TestVec = math::Vector<2, float>;
const TestVec v_x{ 1.F, 0.F };
const TestVec v_y{ 0.F, 1.F };
using TestConstraint = NearDuplicateEmbeddingConstraint<2>;
using TestVectorMap = TestConstraint::TrackVectorMap;
} // namespace
TEST(NearDuplicateEmbeddingConstraint, acceptsWhenCandidateNotInMap)
{
const TestVectorMap trackVectors{ { T1, &v_x } };
const TestConstraint constraint{ trackVectors, 0.1F };
const std::vector<db::TrackId> selected{ T1 };
const TrackCandidateContext ctx{ .candidateTrackId = T2, .selectedTracks = selected };
EXPECT_FALSE(constraint.rejects(ctx));
}
TEST(NearDuplicateEmbeddingConstraint, acceptsWhenSelectionEmpty)
{
const TestVectorMap trackVectors{ { T1, &v_x } };
const TestConstraint constraint{ trackVectors, 0.1F };
const TrackCandidateContext ctx{ .candidateTrackId = T1, .selectedTracks = {} };
EXPECT_FALSE(constraint.rejects(ctx));
}
TEST(NearDuplicateEmbeddingConstraint, acceptsWhenSelectedTrackNotInMap)
{
const TestVectorMap trackVectors{ { T1, &v_x } };
const TestConstraint constraint{ trackVectors, 0.1F };
const std::vector<db::TrackId> selected{ T2 };
const TrackCandidateContext ctx{ .candidateTrackId = T1, .selectedTracks = selected };
EXPECT_FALSE(constraint.rejects(ctx));
}
TEST(NearDuplicateEmbeddingConstraint, rejectsWhenDistanceBelowThreshold)
{
const TestVectorMap trackVectors{ { T1, &v_x }, { T2, &v_x } };
const TestConstraint constraint{ trackVectors, 0.1F };
const std::vector<db::TrackId> selected{ T2 };
const TrackCandidateContext ctx{ .candidateTrackId = T1, .selectedTracks = selected };
EXPECT_TRUE(constraint.rejects(ctx));
}
TEST(NearDuplicateEmbeddingConstraint, acceptsWhenDistanceAboveThreshold)
{
const TestVectorMap trackVectors{ { T1, &v_x }, { T2, &v_y } };
const TestConstraint constraint{ trackVectors, 0.1F };
const std::vector<db::TrackId> selected{ T2 };
const TrackCandidateContext ctx{ .candidateTrackId = T1, .selectedTracks = selected };
EXPECT_FALSE(constraint.rejects(ctx));
}
TEST(NearDuplicateEmbeddingConstraint, rejectsWhenOneOfManySelectedIsNearDuplicate)
{
const TestVectorMap trackVectors{ { T1, &v_x }, { T3, &v_y }, { T4, &v_x } };
const TestConstraint constraint{ trackVectors, 0.1F };
const std::vector<db::TrackId> selected{ T3, T4 };
const TrackCandidateContext ctx{ .candidateTrackId = T1, .selectedTracks = selected };
EXPECT_TRUE(constraint.rejects(ctx));
}
TEST(NearDuplicateEmbeddingConstraint, acceptsWhenAllSelectedAreFarEnough)
{
const TestVectorMap trackVectors{ { T1, &v_x }, { T2, &v_y }, { T3, &v_y } };
const TestConstraint constraint{ trackVectors, 0.1F };
const std::vector<db::TrackId> selected{ T2, T3 };
const TrackCandidateContext ctx{ .candidateTrackId = T1, .selectedTracks = selected };
EXPECT_FALSE(constraint.rejects(ctx));
}