.
This commit is contained in:
parent
0801ceee6a
commit
54ba7496c6
19 changed files with 1765 additions and 591 deletions
304
test/Scry.Tests/CardDatabaseTests.cs
Normal file
304
test/Scry.Tests/CardDatabaseTests.cs
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
using Microsoft.Data.Sqlite;
|
||||
using Scry.Core.Data;
|
||||
using Scry.Core.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace Scry.Tests;
|
||||
|
||||
public class CardDatabaseTests : IDisposable
|
||||
{
|
||||
private readonly string _dbPath;
|
||||
private readonly CardDatabase _database;
|
||||
|
||||
public CardDatabaseTests()
|
||||
{
|
||||
_dbPath = Path.Combine(Path.GetTempPath(), $"scry_test_{Guid.NewGuid()}.db");
|
||||
_database = new CardDatabase(_dbPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertCard_ThenRetrieve_ReturnsMatch()
|
||||
{
|
||||
// First insert oracle and set (foreign keys)
|
||||
var oracle = new Oracle
|
||||
{
|
||||
Id = "oracle-1",
|
||||
Name = "Test Card",
|
||||
ManaCost = "{1}{U}",
|
||||
TypeLine = "Creature"
|
||||
};
|
||||
await _database.InsertOracleAsync(oracle);
|
||||
|
||||
var set = new Set
|
||||
{
|
||||
Id = "set-1",
|
||||
Code = "TST",
|
||||
Name = "Test Set"
|
||||
};
|
||||
await _database.InsertSetAsync(set);
|
||||
|
||||
var card = new Card
|
||||
{
|
||||
Id = "test-id",
|
||||
OracleId = "oracle-1",
|
||||
SetId = "set-1",
|
||||
SetCode = "TST",
|
||||
Name = "Test Card",
|
||||
CollectorNumber = "1",
|
||||
Hash = new byte[] { 0x01, 0x02, 0x03 },
|
||||
ImageUri = "https://example.com/image.jpg"
|
||||
};
|
||||
|
||||
await _database.InsertCardAsync(card);
|
||||
var retrieved = await _database.GetCardByIdAsync("test-id");
|
||||
|
||||
Assert.NotNull(retrieved);
|
||||
Assert.Equal("Test Card", retrieved.Name);
|
||||
Assert.Equal("TST", retrieved.SetCode);
|
||||
Assert.Equal(card.Hash, retrieved.Hash);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertCardBatch_InsertsAllCards()
|
||||
{
|
||||
// Insert oracle first
|
||||
var oracle = new Oracle { Id = "oracle-batch", Name = "Batch Card" };
|
||||
await _database.InsertOracleAsync(oracle);
|
||||
|
||||
var set = new Set { Id = "set-batch", Code = "TST", Name = "Test Set" };
|
||||
await _database.InsertSetAsync(set);
|
||||
|
||||
var cards = Enumerable.Range(0, 100).Select(i => new Card
|
||||
{
|
||||
Id = $"card-{i}",
|
||||
OracleId = "oracle-batch",
|
||||
SetId = "set-batch",
|
||||
SetCode = "TST",
|
||||
Name = $"Card {i}",
|
||||
Hash = new byte[] { (byte)i }
|
||||
}).ToList();
|
||||
|
||||
await _database.InsertCardBatchAsync(cards);
|
||||
var count = await _database.GetCardCountAsync();
|
||||
|
||||
Assert.Equal(100, count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAllCards_ReturnsAllCards()
|
||||
{
|
||||
var oracle = new Oracle { Id = "oracle-all", Name = "All Card" };
|
||||
await _database.InsertOracleAsync(oracle);
|
||||
|
||||
var set = new Set { Id = "set-all", Code = "TST", Name = "Test Set" };
|
||||
await _database.InsertSetAsync(set);
|
||||
|
||||
var cards = Enumerable.Range(0, 10).Select(i => new Card
|
||||
{
|
||||
Id = $"card-{i}",
|
||||
OracleId = "oracle-all",
|
||||
SetId = "set-all",
|
||||
SetCode = "TST",
|
||||
Name = $"Card {i}",
|
||||
Hash = new byte[] { (byte)i }
|
||||
}).ToList();
|
||||
|
||||
await _database.InsertCardBatchAsync(cards);
|
||||
var all = await _database.GetAllCardsAsync();
|
||||
|
||||
Assert.Equal(10, all.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetCardsByOracleId_ReturnsAllPrintings()
|
||||
{
|
||||
var oracle = new Oracle { Id = "oracle-multi", Name = "Multi Print Card" };
|
||||
await _database.InsertOracleAsync(oracle);
|
||||
|
||||
var set1 = new Set { Id = "set-1", Code = "S1", Name = "Set 1" };
|
||||
var set2 = new Set { Id = "set-2", Code = "S2", Name = "Set 2" };
|
||||
await _database.InsertSetAsync(set1);
|
||||
await _database.InsertSetAsync(set2);
|
||||
|
||||
var cards = new[]
|
||||
{
|
||||
new Card { Id = "print-1", OracleId = "oracle-multi", SetId = "set-1", SetCode = "S1", Name = "Multi Print Card", Hash = new byte[] { 0x01 } },
|
||||
new Card { Id = "print-2", OracleId = "oracle-multi", SetId = "set-2", SetCode = "S2", Name = "Multi Print Card", Hash = new byte[] { 0x02 } },
|
||||
};
|
||||
|
||||
await _database.InsertCardBatchAsync(cards);
|
||||
var printings = await _database.GetCardsByOracleIdAsync("oracle-multi");
|
||||
|
||||
Assert.Equal(2, printings.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Metadata_SetAndGet()
|
||||
{
|
||||
await _database.SetMetadataAsync("test_key", "test_value");
|
||||
var value = await _database.GetMetadataAsync("test_key");
|
||||
|
||||
Assert.Equal("test_value", value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ClearCards_RemovesAllCards()
|
||||
{
|
||||
var oracle = new Oracle { Id = "oracle-clear", Name = "Clear Card" };
|
||||
await _database.InsertOracleAsync(oracle);
|
||||
|
||||
var set = new Set { Id = "set-clear", Code = "TST", Name = "Test Set" };
|
||||
await _database.InsertSetAsync(set);
|
||||
|
||||
var cards = Enumerable.Range(0, 10).Select(i => new Card
|
||||
{
|
||||
Id = $"card-{i}",
|
||||
OracleId = "oracle-clear",
|
||||
SetId = "set-clear",
|
||||
SetCode = "TST",
|
||||
Name = $"Card {i}",
|
||||
Hash = new byte[] { (byte)i }
|
||||
}).ToList();
|
||||
|
||||
await _database.InsertCardBatchAsync(cards);
|
||||
await _database.ClearCardsAsync();
|
||||
var count = await _database.GetCardCountAsync();
|
||||
|
||||
Assert.Equal(0, count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertCard_DuplicateId_Updates()
|
||||
{
|
||||
var oracle = new Oracle { Id = "oracle-dup", Name = "Dup Card" };
|
||||
await _database.InsertOracleAsync(oracle);
|
||||
|
||||
var set = new Set { Id = "set-dup", Code = "TST", Name = "Test Set" };
|
||||
await _database.InsertSetAsync(set);
|
||||
|
||||
var card1 = new Card
|
||||
{
|
||||
Id = "duplicate-id",
|
||||
OracleId = "oracle-dup",
|
||||
SetId = "set-dup",
|
||||
SetCode = "TST",
|
||||
Name = "Original Name",
|
||||
Hash = new byte[] { 0x01 }
|
||||
};
|
||||
|
||||
var card2 = new Card
|
||||
{
|
||||
Id = "duplicate-id",
|
||||
OracleId = "oracle-dup",
|
||||
SetId = "set-dup",
|
||||
SetCode = "TST",
|
||||
Name = "Updated Name",
|
||||
Hash = new byte[] { 0x02 }
|
||||
};
|
||||
|
||||
await _database.InsertCardAsync(card1);
|
||||
await _database.InsertCardAsync(card2);
|
||||
|
||||
var retrieved = await _database.GetCardByIdAsync("duplicate-id");
|
||||
|
||||
Assert.NotNull(retrieved);
|
||||
Assert.Equal("Updated Name", retrieved.Name);
|
||||
Assert.Equal(new byte[] { 0x02 }, retrieved.Hash);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertOracle_ThenRetrieveByName()
|
||||
{
|
||||
var oracle = new Oracle
|
||||
{
|
||||
Id = "oracle-name",
|
||||
Name = "Lightning Bolt",
|
||||
ManaCost = "{R}",
|
||||
Cmc = 1,
|
||||
TypeLine = "Instant",
|
||||
OracleText = "Lightning Bolt deals 3 damage to any target."
|
||||
};
|
||||
|
||||
await _database.InsertOracleAsync(oracle);
|
||||
var retrieved = await _database.GetOracleByNameAsync("Lightning Bolt");
|
||||
|
||||
Assert.NotNull(retrieved);
|
||||
Assert.Equal("{R}", retrieved.ManaCost);
|
||||
Assert.Equal(1, retrieved.Cmc);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertSet_ThenRetrieveByCode()
|
||||
{
|
||||
var set = new Set
|
||||
{
|
||||
Id = "set-lea",
|
||||
Code = "lea",
|
||||
Name = "Limited Edition Alpha",
|
||||
SetType = "expansion",
|
||||
ReleasedAt = "1993-08-05",
|
||||
CardCount = 295
|
||||
};
|
||||
|
||||
await _database.InsertSetAsync(set);
|
||||
var retrieved = await _database.GetSetByCodeAsync("lea");
|
||||
|
||||
Assert.NotNull(retrieved);
|
||||
Assert.Equal("Limited Edition Alpha", retrieved.Name);
|
||||
Assert.Equal(295, retrieved.CardCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetCardsWithHash_OnlyReturnsCardsWithHash()
|
||||
{
|
||||
var oracle = new Oracle { Id = "oracle-hash", Name = "Hash Card" };
|
||||
await _database.InsertOracleAsync(oracle);
|
||||
|
||||
var set = new Set { Id = "set-hash", Code = "TST", Name = "Test Set" };
|
||||
await _database.InsertSetAsync(set);
|
||||
|
||||
var cardWithHash = new Card
|
||||
{
|
||||
Id = "card-with-hash",
|
||||
OracleId = "oracle-hash",
|
||||
SetId = "set-hash",
|
||||
SetCode = "TST",
|
||||
Name = "Has Hash",
|
||||
Hash = new byte[] { 0x01 }
|
||||
};
|
||||
|
||||
var cardWithoutHash = new Card
|
||||
{
|
||||
Id = "card-no-hash",
|
||||
OracleId = "oracle-hash",
|
||||
SetId = "set-hash",
|
||||
SetCode = "TST",
|
||||
Name = "No Hash",
|
||||
Hash = null
|
||||
};
|
||||
|
||||
await _database.InsertCardAsync(cardWithHash);
|
||||
await _database.InsertCardAsync(cardWithoutHash);
|
||||
|
||||
var cardsWithHash = await _database.GetCardsWithHashAsync();
|
||||
|
||||
Assert.Single(cardsWithHash);
|
||||
Assert.Equal("card-with-hash", cardsWithHash[0].Id);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_database.Dispose();
|
||||
SqliteConnection.ClearAllPools();
|
||||
try
|
||||
{
|
||||
if (File.Exists(_dbPath))
|
||||
{
|
||||
File.Delete(_dbPath);
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,146 +0,0 @@
|
|||
using Microsoft.Data.Sqlite;
|
||||
using Scry.Core.Data;
|
||||
using Scry.Core.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace Scry.Tests;
|
||||
|
||||
public class CardHashDatabaseTests : IDisposable
|
||||
{
|
||||
private readonly string _dbPath;
|
||||
private readonly CardHashDatabase _database;
|
||||
|
||||
public CardHashDatabaseTests()
|
||||
{
|
||||
_dbPath = Path.Combine(Path.GetTempPath(), $"scry_test_{Guid.NewGuid()}.db");
|
||||
_database = new CardHashDatabase(_dbPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertHash_ThenRetrieve_ReturnsMatch()
|
||||
{
|
||||
var hash = new CardHash
|
||||
{
|
||||
CardId = "test-id",
|
||||
Name = "Test Card",
|
||||
SetCode = "TST",
|
||||
CollectorNumber = "1",
|
||||
Hash = new byte[] { 0x01, 0x02, 0x03 },
|
||||
ImageUri = "https://example.com/image.jpg"
|
||||
};
|
||||
|
||||
await _database.InsertHashAsync(hash);
|
||||
var retrieved = await _database.GetHashByIdAsync("test-id");
|
||||
|
||||
Assert.NotNull(retrieved);
|
||||
Assert.Equal("Test Card", retrieved.Name);
|
||||
Assert.Equal("TST", retrieved.SetCode);
|
||||
Assert.Equal(hash.Hash, retrieved.Hash);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertHashBatch_InsertsAllHashes()
|
||||
{
|
||||
var hashes = Enumerable.Range(0, 100).Select(i => new CardHash
|
||||
{
|
||||
CardId = $"card-{i}",
|
||||
Name = $"Card {i}",
|
||||
SetCode = "TST",
|
||||
Hash = new byte[] { (byte)i }
|
||||
}).ToList();
|
||||
|
||||
await _database.InsertHashBatchAsync(hashes);
|
||||
var count = await _database.GetHashCountAsync();
|
||||
|
||||
Assert.Equal(100, count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetAllHashes_ReturnsAllHashes()
|
||||
{
|
||||
var hashes = Enumerable.Range(0, 10).Select(i => new CardHash
|
||||
{
|
||||
CardId = $"card-{i}",
|
||||
Name = $"Card {i}",
|
||||
SetCode = "TST",
|
||||
Hash = new byte[] { (byte)i }
|
||||
}).ToList();
|
||||
|
||||
await _database.InsertHashBatchAsync(hashes);
|
||||
var all = await _database.GetAllHashesAsync();
|
||||
|
||||
Assert.Equal(10, all.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Metadata_SetAndGet()
|
||||
{
|
||||
await _database.SetMetadataAsync("test_key", "test_value");
|
||||
var value = await _database.GetMetadataAsync("test_key");
|
||||
|
||||
Assert.Equal("test_value", value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Clear_RemovesAllHashes()
|
||||
{
|
||||
var hashes = Enumerable.Range(0, 10).Select(i => new CardHash
|
||||
{
|
||||
CardId = $"card-{i}",
|
||||
Name = $"Card {i}",
|
||||
SetCode = "TST",
|
||||
Hash = new byte[] { (byte)i }
|
||||
}).ToList();
|
||||
|
||||
await _database.InsertHashBatchAsync(hashes);
|
||||
await _database.ClearAsync();
|
||||
var count = await _database.GetHashCountAsync();
|
||||
|
||||
Assert.Equal(0, count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertHash_DuplicateId_Updates()
|
||||
{
|
||||
var hash1 = new CardHash
|
||||
{
|
||||
CardId = "duplicate-id",
|
||||
Name = "Original Name",
|
||||
SetCode = "TST",
|
||||
Hash = new byte[] { 0x01 }
|
||||
};
|
||||
|
||||
var hash2 = new CardHash
|
||||
{
|
||||
CardId = "duplicate-id",
|
||||
Name = "Updated Name",
|
||||
SetCode = "TST",
|
||||
Hash = new byte[] { 0x02 }
|
||||
};
|
||||
|
||||
await _database.InsertHashAsync(hash1);
|
||||
await _database.InsertHashAsync(hash2);
|
||||
|
||||
var retrieved = await _database.GetHashByIdAsync("duplicate-id");
|
||||
|
||||
Assert.NotNull(retrieved);
|
||||
Assert.Equal("Updated Name", retrieved.Name);
|
||||
Assert.Equal(new byte[] { 0x02 }, retrieved.Hash);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_database.Dispose();
|
||||
SqliteConnection.ClearAllPools();
|
||||
try
|
||||
{
|
||||
if (File.Exists(_dbPath))
|
||||
{
|
||||
File.Delete(_dbPath);
|
||||
}
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -15,14 +15,14 @@ public class RobustnessAnalysisTests : IDisposable
|
|||
{
|
||||
private readonly ITestOutputHelper _output;
|
||||
private readonly string _dbPath;
|
||||
private readonly CardHashDatabase _database;
|
||||
private readonly CardDatabase _database;
|
||||
private readonly CardRecognitionService _recognitionService;
|
||||
|
||||
public RobustnessAnalysisTests(ITestOutputHelper output)
|
||||
{
|
||||
_output = output;
|
||||
_dbPath = Path.Combine(Path.GetTempPath(), $"scry_robustness_test_{Guid.NewGuid()}.db");
|
||||
_database = new CardHashDatabase(_dbPath);
|
||||
_database = new CardDatabase(_dbPath);
|
||||
_recognitionService = new CardRecognitionService(_database);
|
||||
}
|
||||
|
||||
|
|
@ -52,11 +52,16 @@ public class RobustnessAnalysisTests : IDisposable
|
|||
var originalHash = _recognitionService.ComputeHash(original);
|
||||
|
||||
// Register original in database
|
||||
await _database.InsertHashAsync(new CardHash
|
||||
await _database.InsertOracleAsync(new Oracle { Id = "oracle-serra", Name = "Serra Angel" });
|
||||
await _database.InsertSetAsync(new Set { Id = "set-lea", Code = "LEA", Name = "Alpha" });
|
||||
|
||||
await _database.InsertCardAsync(new Card
|
||||
{
|
||||
CardId = "serra-angel",
|
||||
Name = "Serra Angel",
|
||||
Id = "serra-angel",
|
||||
OracleId = "oracle-serra",
|
||||
SetId = "set-lea",
|
||||
SetCode = "LEA",
|
||||
Name = "Serra Angel",
|
||||
Hash = originalHash
|
||||
});
|
||||
await _recognitionService.InvalidateCacheAsync();
|
||||
|
|
@ -113,11 +118,16 @@ public class RobustnessAnalysisTests : IDisposable
|
|||
|
||||
var originalHash = _recognitionService.ComputeHash(original);
|
||||
|
||||
await _database.InsertHashAsync(new CardHash
|
||||
await _database.InsertOracleAsync(new Oracle { Id = "oracle-serra", Name = "Serra Angel" });
|
||||
await _database.InsertSetAsync(new Set { Id = "set-lea", Code = "LEA", Name = "Alpha" });
|
||||
|
||||
await _database.InsertCardAsync(new Card
|
||||
{
|
||||
CardId = "serra-angel",
|
||||
Name = "Serra Angel",
|
||||
Id = "serra-angel",
|
||||
OracleId = "oracle-serra",
|
||||
SetId = "set-lea",
|
||||
SetCode = "LEA",
|
||||
Name = "Serra Angel",
|
||||
Hash = originalHash
|
||||
});
|
||||
await _recognitionService.InvalidateCacheAsync();
|
||||
|
|
@ -167,11 +177,16 @@ public class RobustnessAnalysisTests : IDisposable
|
|||
|
||||
var originalHash = _recognitionService.ComputeHash(original);
|
||||
|
||||
await _database.InsertHashAsync(new CardHash
|
||||
await _database.InsertOracleAsync(new Oracle { Id = "oracle-serra", Name = "Serra Angel" });
|
||||
await _database.InsertSetAsync(new Set { Id = "set-lea", Code = "LEA", Name = "Alpha" });
|
||||
|
||||
await _database.InsertCardAsync(new Card
|
||||
{
|
||||
CardId = "serra-angel",
|
||||
Name = "Serra Angel",
|
||||
Id = "serra-angel",
|
||||
OracleId = "oracle-serra",
|
||||
SetId = "set-lea",
|
||||
SetCode = "LEA",
|
||||
Name = "Serra Angel",
|
||||
Hash = originalHash
|
||||
});
|
||||
await _recognitionService.InvalidateCacheAsync();
|
||||
|
|
@ -218,11 +233,16 @@ public class RobustnessAnalysisTests : IDisposable
|
|||
|
||||
var originalHash = _recognitionService.ComputeHash(original);
|
||||
|
||||
await _database.InsertHashAsync(new CardHash
|
||||
await _database.InsertOracleAsync(new Oracle { Id = "oracle-serra", Name = "Serra Angel" });
|
||||
await _database.InsertSetAsync(new Set { Id = "set-lea", Code = "LEA", Name = "Alpha" });
|
||||
|
||||
await _database.InsertCardAsync(new Card
|
||||
{
|
||||
CardId = "serra-angel",
|
||||
Name = "Serra Angel",
|
||||
Id = "serra-angel",
|
||||
OracleId = "oracle-serra",
|
||||
SetId = "set-lea",
|
||||
SetCode = "LEA",
|
||||
Name = "Serra Angel",
|
||||
Hash = originalHash
|
||||
});
|
||||
await _recognitionService.InvalidateCacheAsync();
|
||||
|
|
@ -265,11 +285,16 @@ public class RobustnessAnalysisTests : IDisposable
|
|||
|
||||
var originalHash = _recognitionService.ComputeHash(original);
|
||||
|
||||
await _database.InsertHashAsync(new CardHash
|
||||
await _database.InsertOracleAsync(new Oracle { Id = "oracle-serra", Name = "Serra Angel" });
|
||||
await _database.InsertSetAsync(new Set { Id = "set-lea", Code = "LEA", Name = "Alpha" });
|
||||
|
||||
await _database.InsertCardAsync(new Card
|
||||
{
|
||||
CardId = "serra-angel",
|
||||
Name = "Serra Angel",
|
||||
Id = "serra-angel",
|
||||
OracleId = "oracle-serra",
|
||||
SetId = "set-lea",
|
||||
SetCode = "LEA",
|
||||
Name = "Serra Angel",
|
||||
Hash = originalHash
|
||||
});
|
||||
await _recognitionService.InvalidateCacheAsync();
|
||||
|
|
@ -312,14 +337,14 @@ public class RobustnessAnalysisTests : IDisposable
|
|||
return;
|
||||
}
|
||||
|
||||
using var prodDb = new CardHashDatabase(dbPath);
|
||||
using var prodDb = new CardDatabase(dbPath);
|
||||
using var prodRecognition = new CardRecognitionService(prodDb);
|
||||
|
||||
var testImagesDir = Path.Combine(rootDir, "TestImages");
|
||||
var categoriesToTest = new[] { "real_photos", "varying_quality", "angled", "low_light" };
|
||||
|
||||
_output.WriteLine("=== Real-World Recognition Test ===");
|
||||
_output.WriteLine($"Database cards: {(await prodDb.GetAllHashesAsync()).Count}");
|
||||
_output.WriteLine($"Database cards: {(await prodDb.GetCardsWithHashAsync()).Count}");
|
||||
_output.WriteLine("");
|
||||
|
||||
foreach (var category in categoriesToTest)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue