Fixed: Negative preferred word scores being trumped by 0 scores without any matches
This commit is contained in:
parent
66af08a830
commit
acdf02d569
|
@ -1,4 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
|
@ -15,26 +17,33 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||
{
|
||||
private Series _series;
|
||||
private EpisodeFile _episodeFile;
|
||||
private readonly KeyValuePair<string, int> _positiveScore = new KeyValuePair<string, int>("Positive", 10);
|
||||
private readonly KeyValuePair<string, int> _negativeScore = new KeyValuePair<string, int>("Negative", -10);
|
||||
private KeyValuePair<string, int> _neutralScore = new KeyValuePair<string, int>("Neutral", 0);
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_series = Builder<Series>.CreateNew().Build();
|
||||
_episodeFile = Builder<EpisodeFile>.CreateNew().Build();
|
||||
|
||||
Mocker.GetMock<IPreferredWordService>()
|
||||
.Setup(s => s.GetMatchingPreferredWordsAndScores(It.IsAny<Series>(), It.IsAny<string>(), 0))
|
||||
.Returns(new List<KeyValuePair<string, int>>());
|
||||
}
|
||||
|
||||
private void GivenPreferredWordScore(string title, int score)
|
||||
private void GivenPreferredWordScore(string title, params KeyValuePair<string, int>[] matches)
|
||||
{
|
||||
Mocker.GetMock<IPreferredWordService>()
|
||||
.Setup(s => s.Calculate(It.IsAny<Series>(), title, 0))
|
||||
.Returns(score);
|
||||
.Setup(s => s.GetMatchingPreferredWordsAndScores(It.IsAny<Series>(), title, 0))
|
||||
.Returns(matches.ToList());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_score_for_relative_file_name_when_it_is_higher_than_scene_name()
|
||||
{
|
||||
GivenPreferredWordScore(_episodeFile.SceneName, 10);
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, 20);
|
||||
GivenPreferredWordScore(_episodeFile.SceneName, _positiveScore);
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, _positiveScore, _positiveScore);
|
||||
|
||||
Subject.Calculate(_series, _episodeFile).Should().Be(20);
|
||||
}
|
||||
|
@ -45,7 +54,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||
_episodeFile.SceneName = null;
|
||||
_episodeFile.RelativePath = null;
|
||||
|
||||
GivenPreferredWordScore(_episodeFile.Path, 20);
|
||||
GivenPreferredWordScore(_episodeFile.Path, _positiveScore, _positiveScore);
|
||||
|
||||
Subject.Calculate(_series, _episodeFile).Should().Be(20);
|
||||
}
|
||||
|
@ -55,7 +64,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||
{
|
||||
_episodeFile.SceneName = null;
|
||||
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, 20);
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, _positiveScore, _positiveScore);
|
||||
|
||||
Subject.Calculate(_series, _episodeFile).Should().Be(20);
|
||||
}
|
||||
|
@ -63,17 +72,17 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||
[Test]
|
||||
public void should_return_score_for_scene_name_when_higher_than_relative_file_name()
|
||||
{
|
||||
GivenPreferredWordScore(_episodeFile.SceneName, 50);
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, 20);
|
||||
GivenPreferredWordScore(_episodeFile.SceneName, _positiveScore, _positiveScore, _positiveScore);
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, _positiveScore, _positiveScore);
|
||||
|
||||
Subject.Calculate(_series, _episodeFile).Should().Be(50);
|
||||
Subject.Calculate(_series, _episodeFile).Should().Be(30);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_score_for_relative_file_if_available()
|
||||
{
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, 20);
|
||||
GivenPreferredWordScore(_episodeFile.Path, 50);
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, _positiveScore, _positiveScore);
|
||||
GivenPreferredWordScore(_episodeFile.Path, _positiveScore, _positiveScore, _positiveScore);
|
||||
|
||||
Subject.Calculate(_series, _episodeFile).Should().Be(20);
|
||||
}
|
||||
|
@ -86,12 +95,12 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||
|
||||
_episodeFile.OriginalFilePath = Path.Combine(folderName, fileName);
|
||||
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, 20);
|
||||
GivenPreferredWordScore(_episodeFile.Path, 50);
|
||||
GivenPreferredWordScore(folderName, 60);
|
||||
GivenPreferredWordScore(fileName, 50);
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, _positiveScore);
|
||||
GivenPreferredWordScore(_episodeFile.Path, _positiveScore, _positiveScore);
|
||||
GivenPreferredWordScore(folderName, _positiveScore, _positiveScore, _positiveScore);
|
||||
GivenPreferredWordScore(fileName, _positiveScore, _positiveScore);
|
||||
|
||||
Subject.Calculate(_series, _episodeFile).Should().Be(60);
|
||||
Subject.Calculate(_series, _episodeFile).Should().Be(30);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -102,12 +111,42 @@ namespace NzbDrone.Core.Test.MediaFiles
|
|||
|
||||
_episodeFile.OriginalFilePath = Path.Combine(folderName, fileName);
|
||||
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, 20);
|
||||
GivenPreferredWordScore(_episodeFile.Path, 50);
|
||||
GivenPreferredWordScore(folderName, 40);
|
||||
GivenPreferredWordScore(fileName, 50);
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, _positiveScore);
|
||||
GivenPreferredWordScore(_episodeFile.Path, _positiveScore, _positiveScore);
|
||||
GivenPreferredWordScore(folderName, _positiveScore, _positiveScore);
|
||||
GivenPreferredWordScore(fileName, _positiveScore, _positiveScore, _positiveScore);
|
||||
|
||||
Subject.Calculate(_series, _episodeFile).Should().Be(50);
|
||||
Subject.Calculate(_series, _episodeFile).Should().Be(30);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_negative_score_if_0_result_has_no_matches()
|
||||
{
|
||||
var folderName = "folder-name";
|
||||
var fileName = "file-name";
|
||||
|
||||
_episodeFile.OriginalFilePath = Path.Combine(folderName, fileName);
|
||||
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, _negativeScore);
|
||||
GivenPreferredWordScore(fileName);
|
||||
|
||||
Subject.Calculate(_series, _episodeFile).Should().Be(-10);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_return_0_score_if_0_result_has_matches()
|
||||
{
|
||||
var folderName = "folder-name";
|
||||
var fileName = "file-name";
|
||||
|
||||
_episodeFile.OriginalFilePath = Path.Combine(folderName, fileName);
|
||||
|
||||
GivenPreferredWordScore(_episodeFile.RelativePath, _negativeScore);
|
||||
GivenPreferredWordScore(_episodeFile.Path, _negativeScore);
|
||||
GivenPreferredWordScore(folderName, _negativeScore);
|
||||
GivenPreferredWordScore(fileName, _neutralScore);
|
||||
|
||||
Subject.Calculate(_series, _episodeFile).Should().Be(0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@ namespace NzbDrone.Core.MediaFiles
|
|||
|
||||
if (episodeFile.SceneName.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
scores.Add(_preferredWordService.Calculate(series, episodeFile.SceneName, 0));
|
||||
AddScoreIfApplicable(series, episodeFile.SceneName, scores);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ namespace NzbDrone.Core.MediaFiles
|
|||
var isLast = i == segments.Count - 1;
|
||||
var segment = isLast ? Path.GetFileNameWithoutExtension(segments[i]) : segments[i];
|
||||
|
||||
scores.Add(_preferredWordService.Calculate(series, segment, 0));
|
||||
AddScoreIfApplicable(series, segment, scores);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -60,11 +60,11 @@ namespace NzbDrone.Core.MediaFiles
|
|||
// Calculate using RelativePath or Path, but not both
|
||||
if (episodeFile.RelativePath.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
scores.Add(_preferredWordService.Calculate(series, episodeFile.RelativePath, 0));
|
||||
AddScoreIfApplicable(series, episodeFile.RelativePath, scores);
|
||||
}
|
||||
else if (episodeFile.Path.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
scores.Add(_preferredWordService.Calculate(series, episodeFile.Path, 0));
|
||||
AddScoreIfApplicable(series, episodeFile.Path, scores);
|
||||
}
|
||||
|
||||
// Return the highest score, this will allow media info in file names to be used to improve preferred word scoring.
|
||||
|
@ -72,5 +72,22 @@ namespace NzbDrone.Core.MediaFiles
|
|||
|
||||
return scores.MaxOrDefault();
|
||||
}
|
||||
|
||||
private void AddScoreIfApplicable(Series series, string title, List<int> scores)
|
||||
{
|
||||
var score = 0;
|
||||
_logger.Trace("Calculating preferred word score for '{0}'", title);
|
||||
|
||||
var matchingPairs = _preferredWordService.GetMatchingPreferredWordsAndScores(series, title, 0);
|
||||
|
||||
// Only add the score if there are matching terms, uncalculated
|
||||
if (matchingPairs.Any())
|
||||
{
|
||||
score = matchingPairs.Sum(p => p.Value);
|
||||
scores.Add(score);
|
||||
}
|
||||
|
||||
_logger.Trace("Calculated preferred word score for '{0}': {1} ({2} match(es))", title, score, matchingPairs.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace NzbDrone.Core.Profiles.Releases
|
|||
public interface IPreferredWordService
|
||||
{
|
||||
int Calculate(Series series, string title, int indexerId);
|
||||
List<KeyValuePair<string, int>> GetMatchingPreferredWordsAndScores(Series series, string title, int indexerId);
|
||||
PreferredWordMatchResults GetMatchingPreferredWords(Series series, string title);
|
||||
}
|
||||
|
||||
|
@ -30,6 +31,16 @@ namespace NzbDrone.Core.Profiles.Releases
|
|||
{
|
||||
_logger.Trace("Calculating preferred word score for '{0}'", title);
|
||||
|
||||
var matchingPairs = GetMatchingPreferredWordsAndScores(series, title, indexerId);
|
||||
var score = matchingPairs.Sum(p => p.Value);
|
||||
|
||||
_logger.Trace("Calculated preferred word score for '{0}': {1} ({2} match(es))", title, score, matchingPairs.Count);
|
||||
|
||||
return score;
|
||||
}
|
||||
|
||||
public List<KeyValuePair<string, int>> GetMatchingPreferredWordsAndScores(Series series, string title, int indexerId)
|
||||
{
|
||||
var releaseProfiles = _releaseProfileService.EnabledForTags(series.Tags, indexerId);
|
||||
var matchingPairs = new List<KeyValuePair<string, int>>();
|
||||
|
||||
|
@ -46,11 +57,7 @@ namespace NzbDrone.Core.Profiles.Releases
|
|||
}
|
||||
}
|
||||
|
||||
var score = matchingPairs.Sum(p => p.Value);
|
||||
|
||||
_logger.Trace("Calculated preferred word score for '{0}': {1}", title, score);
|
||||
|
||||
return score;
|
||||
return matchingPairs;
|
||||
}
|
||||
|
||||
public PreferredWordMatchResults GetMatchingPreferredWords(Series series, string title)
|
||||
|
|
Loading…
Reference in New Issue