This commit is contained in:
Chris Kruining 2026-02-05 11:34:57 +01:00
parent 0801ceee6a
commit 54ba7496c6
No known key found for this signature in database
GPG key ID: EB894A3560CCCAD2
19 changed files with 1765 additions and 591 deletions

View file

@ -13,14 +13,14 @@ public class CardRecognitionTests : IDisposable
{
private readonly ITestOutputHelper _output;
private readonly string _dbPath;
private readonly CardHashDatabase _database;
private readonly CardDatabase _database;
private readonly CardRecognitionService _recognitionService;
public CardRecognitionTests(ITestOutputHelper output)
{
_output = output;
_dbPath = Path.Combine(Path.GetTempPath(), $"scry_recognition_test_{Guid.NewGuid()}.db");
_database = new CardHashDatabase(_dbPath);
_database = new CardDatabase(_dbPath);
_recognitionService = new CardRecognitionService(_database);
}
@ -32,7 +32,7 @@ public class CardRecognitionTests : IDisposable
var result = await _recognitionService.RecognizeAsync(bitmap);
Assert.False(result.Success);
Assert.Contains("No card hashes", result.ErrorMessage);
Assert.Contains("No cards", result.ErrorMessage);
}
[Fact]
@ -41,11 +41,17 @@ public class CardRecognitionTests : IDisposable
using var bitmap = CreateTestBitmap(100, 100);
var hash = _recognitionService.ComputeHash(bitmap);
await _database.InsertHashAsync(new CardHash
// Insert oracle and set first
await _database.InsertOracleAsync(new Oracle { Id = "oracle-test", Name = "Test Card" });
await _database.InsertSetAsync(new Set { Id = "set-test", Code = "TST", Name = "Test Set" });
await _database.InsertCardAsync(new Card
{
CardId = "test-card",
Name = "Test Card",
Id = "test-card",
OracleId = "oracle-test",
SetId = "set-test",
SetCode = "TST",
Name = "Test Card",
Hash = hash,
ImageUri = "https://example.com/test.jpg"
});
@ -78,11 +84,16 @@ public class CardRecognitionTests : IDisposable
var hash = _recognitionService.ComputeHash(bitmap);
var cardName = Path.GetFileNameWithoutExtension(imagePath);
await _database.InsertHashAsync(new CardHash
await _database.InsertOracleAsync(new Oracle { Id = $"oracle-{cardName}", Name = cardName });
await _database.InsertSetAsync(new Set { Id = "set-ref", Code = "REF", Name = "Reference Set" });
await _database.InsertCardAsync(new Card
{
CardId = cardName,
Name = cardName,
Id = cardName,
OracleId = $"oracle-{cardName}",
SetId = "set-ref",
SetCode = "REF",
Name = cardName,
Hash = hash
});
await _recognitionService.InvalidateCacheAsync();
@ -121,7 +132,7 @@ public class CardRecognitionTests : IDisposable
return;
}
using var testDb = new CardHashDatabase(dbPath);
using var testDb = new CardDatabase(dbPath);
using var testRecognition = new CardRecognitionService(testDb);
using var bitmap = SKBitmap.Decode(imagePath);
@ -129,31 +140,31 @@ public class CardRecognitionTests : IDisposable
// First, just compute hash and check distance manually
var queryHash = testRecognition.ComputeHash(bitmap);
var allHashes = await testDb.GetAllHashesAsync();
var allCards = await testDb.GetCardsWithHashAsync();
_output.WriteLine($"Query hash length: {queryHash.Length} bytes");
_output.WriteLine($"Database has {allHashes.Count} cards");
_output.WriteLine($"Database has {allCards.Count} cards with hashes");
// Find Serra Angel and compute distance
var serraHash = allHashes.FirstOrDefault(h => h.Name == "Serra Angel");
if (serraHash != null)
var serraCard = allCards.FirstOrDefault(c => c.Name == "Serra Angel");
if (serraCard?.Hash != null)
{
var distance = PerceptualHash.HammingDistance(queryHash, serraHash.Hash);
_output.WriteLine($"Serra Angel hash length: {serraHash.Hash.Length} bytes");
var distance = PerceptualHash.HammingDistance(queryHash, serraCard.Hash);
_output.WriteLine($"Serra Angel hash length: {serraCard.Hash.Length} bytes");
_output.WriteLine($"Distance to Serra Angel: {distance}");
}
// Find the actual best match
int bestDistance = int.MaxValue;
string? bestName = null;
foreach (var hash in allHashes)
foreach (var card in allCards)
{
if (hash.Hash.Length != queryHash.Length) continue;
var dist = PerceptualHash.HammingDistance(queryHash, hash.Hash);
if (card.Hash == null || card.Hash.Length != queryHash.Length) continue;
var dist = PerceptualHash.HammingDistance(queryHash, card.Hash);
if (dist < bestDistance)
{
bestDistance = dist;
bestName = hash.Name;
bestName = card.Name;
}
}
_output.WriteLine($"Best match: {bestName}, distance: {bestDistance}");
@ -180,11 +191,16 @@ public class CardRecognitionTests : IDisposable
using var bitmap = CreateTestBitmap(200, 300);
var hash = _recognitionService.ComputeHash(bitmap);
await _database.InsertHashAsync(new CardHash
await _database.InsertOracleAsync(new Oracle { Id = "oracle-timing", Name = "Timing Test Card" });
await _database.InsertSetAsync(new Set { Id = "set-timing", Code = "TST", Name = "Test Set" });
await _database.InsertCardAsync(new Card
{
CardId = "timing-test",
Name = "Timing Test Card",
Id = "timing-test",
OracleId = "oracle-timing",
SetId = "set-timing",
SetCode = "TST",
Name = "Timing Test Card",
Hash = hash
});
await _recognitionService.InvalidateCacheAsync();