Add explainable matching engine
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
from pathlib import Path
|
||||
|
||||
from serato_doctor.matching import MatchingEngine, score_candidate
|
||||
from serato_doctor.models.reference import TrackReference
|
||||
from serato_doctor.models.track import DiskTrack
|
||||
|
||||
|
||||
def reference(filename, folder="House"):
|
||||
return TrackReference(
|
||||
Path("Test.crate"), Path("/old") / folder / filename, filename
|
||||
)
|
||||
|
||||
|
||||
def track(filename, folder="House"):
|
||||
path = Path("/new") / folder / filename
|
||||
return DiskTrack(path, filename, 100, path.suffix.lower())
|
||||
|
||||
|
||||
def test_exact_candidate_has_full_evidence_score():
|
||||
match = score_candidate(reference("Track.mp3"), track("Track.mp3"))
|
||||
|
||||
assert match.score == 90
|
||||
assert match.max_score == 90
|
||||
assert match.score_percent == 100.0
|
||||
assert all(item.matched for item in match.evidence)
|
||||
|
||||
|
||||
def test_cloud_conflict_suffix_is_explained():
|
||||
match = score_candidate(reference("Track.mp3"), track("Track 2.mp3"))
|
||||
|
||||
assert match.score == 80
|
||||
assert match.score_percent == 88.9
|
||||
assert match.evidence[0].explanation == (
|
||||
"Filename matches after removing a numeric conflict suffix"
|
||||
)
|
||||
|
||||
|
||||
def test_case_normalized_match_scores_below_exact():
|
||||
match = score_candidate(reference("TRACK.MP3"), track("track.mp3"))
|
||||
|
||||
assert match.score == 85
|
||||
assert match.evidence[0].points == 55
|
||||
|
||||
|
||||
def test_engine_omits_unrelated_filenames():
|
||||
engine = MatchingEngine([track("Different.mp3")])
|
||||
|
||||
assert engine.candidates_for(reference("Missing.mp3")) == ()
|
||||
|
||||
|
||||
def test_ambiguous_candidates_are_ranked_deterministically():
|
||||
engine = MatchingEngine(
|
||||
[track("Track 2.mp3", "Other"), track("Track 3.mp3", "House")]
|
||||
)
|
||||
|
||||
matches = engine.candidates_for(reference("Track.mp3"))
|
||||
|
||||
assert [match.track.filename for match in matches] == [
|
||||
"Track 3.mp3",
|
||||
"Track 2.mp3",
|
||||
]
|
||||
assert [match.score for match in matches] == [80, 60]
|
||||
Reference in New Issue
Block a user