Finish unit tests

This commit is contained in:
2026-01-16 23:27:05 -06:00
parent 0fa03d8f0c
commit 7ff2091db3
2 changed files with 114 additions and 11 deletions

View File

@@ -4,7 +4,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using CritterFolio.DataModels; using CritterFolio.DataModels;
using Microsoft.VisualBasic.FileIO; using System.Reflection;
using SQLite; using SQLite;
namespace CritterFolio.Services; namespace CritterFolio.Services;
@@ -32,6 +32,13 @@ public static class DatabaseService
} }
} }
public static bool TestDbConnection()
{
return _db != null;
}
public static async Task ClearAllTables() public static async Task ClearAllTables()
{ {
await Init(); await Init();
@@ -183,4 +190,96 @@ public static class DatabaseService
} }
#endregion #endregion
#region Tests
#if DEBUG
public class ColumnInfo
{
public int Cid { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public int NotNull { get; set; }
public string Dflt_Value { get; set; }
public int Pk { get; set; }
}
public static async Task<bool> VerifySchemaAgainstModel<T>()
{
if (_db is null)
{
Console.WriteLine("Error: Database connection is null.");
return false;
}
// Automatically determine the table name from the [Table] attribute or the Class name
var modelType = typeof(T);
var tableAttribute = modelType.GetCustomAttribute<TableAttribute>();
string tableName = tableAttribute != null ? tableAttribute.Name : modelType.Name;
Console.WriteLine($"--- Schema Verification: {tableName} (Class: {modelType.Name}) ---");
var dbColumns = await _db.QueryAsync<ColumnInfo>($"PRAGMA table_info('{tableName}')");
var dbColumnNames = dbColumns.Select(c => c.Name.ToLower()).ToList();
if (!dbColumns.Any())
{
Console.WriteLine($"Result: Failure. Table '{tableName}' does not exist in the database.");
return false;
}
Console.WriteLine($"Database columns for table '{tableName}' ({dbColumns.Count}):");
foreach (var col in dbColumns)
{
Console.WriteLine($" Column: {col.Name} | Type: {col.Type} | PK: {col.Pk == 1}");
}
var modelProperties = modelType
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.GetCustomAttribute<IgnoreAttribute>() == null)
.ToList();
Console.WriteLine($"Model properties for class '{modelType.Name}' ({modelProperties.Count}):");
foreach (var prop in modelProperties)
{
// Detect if the property has a [Column] attribute name override
var colAttr = prop.GetCustomAttribute<ColumnAttribute>();
string expectedColName = colAttr != null ? colAttr.Name : prop.Name;
Console.WriteLine($" Property: {prop.Name} (Expected Column: {expectedColName}) | Type: {prop.PropertyType.Name}");
}
// Match based on the expected column name (either property name or [Column] attribute)
var expectedColumnNames = modelProperties.Select(p => {
var attr = p.GetCustomAttribute<ColumnAttribute>();
return (attr != null ? attr.Name : p.Name).ToLower();
}).ToList();
var missingInDb = expectedColumnNames.Where(p => !dbColumnNames.Contains(p)).ToList();
var extraInDb = dbColumnNames.Where(c => !expectedColumnNames.Contains(c)).ToList();
bool isMatch = !missingInDb.Any();
if (missingInDb.Any())
{
Console.WriteLine($"Result: Failure. Columns missing in database: {string.Join(", ", missingInDb)}");
}
if (extraInDb.Any())
{
Console.WriteLine($"Note: Database contains extra columns: {string.Join(", ", extraInDb)}");
}
if (isMatch)
{
Console.WriteLine($"Result: Success. Class '{modelType.Name}' matches table '{tableName}'.");
}
Console.WriteLine("-------------------------------------------\n");
return isMatch;
}
#endif
#endregion
} }

View File

@@ -8,20 +8,24 @@ namespace CritterFolioTests;
public class Tests public class Tests
{ {
[SetUp] [Test]
public void Setup() public async Task TestDatabaseCreation()
{ {
await DatabaseService.Init();
Assert.That(DatabaseService.TestDbConnection(), Is.True);
} }
[Test] [Test]
public async Task TestAddingCritter() public async Task TestDatabaseSchema()
{ {
Assert.That(await DatabaseService.AddCritter(new Critter{Name = "Test Critter"}), Is.True); await DatabaseService.Init();
}
[Test] Assert.Multiple(async () =>
public async Task TestGettingCritterThatDoesntExist() {
{ Assert.That(await DatabaseService.VerifySchemaAgainstModel<Critter>(), Is.True);
Assert.That(await DatabaseService.GetCritter(-1), Is.False); Assert.That(await DatabaseService.VerifySchemaAgainstModel<Document>(), Is.True);
Assert.That(await DatabaseService.VerifySchemaAgainstModel<CritterEvent>(), Is.True);
});
} }
} }