63 lines
1.8 KiB
Python
63 lines
1.8 KiB
Python
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]
|