You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
5.4 KiB

using AdventOfCode.Common;
using AdventOfCode.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace AdventOfCode.Tests
{
[TestClass]
public class AdventOfCodeTests
{
[TestMethod]
public void TestAllDays()
{
var dataDirectoryPath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "Data";
var directoryInfo = new DirectoryInfo(dataDirectoryPath);
var validDays = GetValidDays(directoryInfo.EnumerateFiles().Where(x => x.Name.EndsWith(".tst.data")));
var error = false;
foreach (var validDay in validDays)
{
try
{
var year = Convert.ToInt32(validDay.Split("_")[0]);
var day = Convert.ToInt32(validDay.Split("_")[1]);
var part = validDay.Split("_")[2];
Console.WriteLine($"Testing {year} Day {day} Part {part}");
var input = $"{year}_Input_Day_{day}.tst.data";
var answerData = $"{year}_Answer_Day_{day}{part}.tst.data";
var aocDay = GetAOCDay(year, day);
var version = (AOCVersion)Enum.Parse(typeof(AOCVersion), part.ToUpper());
if (ShouldSkipAnswerCheck(aocDay, version))
{
Console.WriteLine("Answer is marked to be skipped and not compared (visual answer).\n");
continue;
}
var resp = aocDay.ExecuteDay(new AOCRequest()
{
Version = version,
IgnoreLogMessages = true,
Input = File.ReadAllText(dataDirectoryPath + Path.DirectorySeparatorChar + input)
});
var actualAnswer = File.ReadAllText(dataDirectoryPath + Path.DirectorySeparatorChar + answerData);
Console.WriteLine($"Asserting that (Answer) [{actualAnswer}] == [{resp.Answer}] (Tested)\n");
Assert.AreEqual(resp.Answer.ToString(), actualAnswer);
}
catch (Exception e)
{
Console.WriteLine($"Failed {validDay} with " + e.Message + " _ " + e.StackTrace);
error = true;
}
}
if (error) Assert.IsNotNull(null);
}
private bool ShouldSkipAnswerCheck(AOCDay day, AOCVersion version)
{
var ignoreAttribute = (IgnoreTestAnswerAttribute) Attribute.GetCustomAttribute(day.GetType(), typeof(IgnoreTestAnswerAttribute));
if (ignoreAttribute != null)
{
return ignoreAttribute.ShouldIgnoreAnswer(version);
}
return false;
}
private string[] GetValidDays(IEnumerable<FileInfo> files)
{
var validDays = new List<string>();
for (int year = 2022; year < 2025; year++)
{
for (int i = 1; i <= 25; i++)
{
var inputName = $"{year}_Input_Day_{i}.tst.data";
var partAAnswer = $"{year}_Answer_Day_{i}A.tst.data";
var partBAnswer = $"{year}_Answer_Day_{i}B.tst.data";
if (!files.Any(x => x.Name == inputName)) continue;
if (files.Any(x => x.Name == partAAnswer))
{
validDays.Add($"{year}_{i}_A");
}
if (files.Any(x => x.Name == partBAnswer))
{
validDays.Add($"{year}_{i}_B");
}
}
}
return validDays.ToArray();
}
private AOCDay GetAOCDay(int year, int day)
{
AOCDay aocDay = null;
var type = typeof(AOCDay);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p) && !p.IsInterface && !p.IsAbstract);
foreach (var x in types)
{
var aocAttribute = (AOCAttribute)Attribute.GetCustomAttribute(x, typeof(AOCAttribute));
if (aocAttribute != null)
{
if (aocAttribute.Year == year && aocAttribute.Day == day)
{
aocDay = (AOCDay)(IAOCService)Activator.CreateInstance(x);
}
}
else
{
var ns = x.Namespace;
var className = x.Name;
var dayParsed = 0;
_ = int.TryParse(Regex.Replace(className, "[^0-9.]", ""), out dayParsed);
var match = Regex.Match(ns, @"\d{4}");
if (match.Success)
{
var yearParsed = 0;
_ = int.TryParse(match.Value, out yearParsed);
if (yearParsed == year && dayParsed == day)
{
aocDay = (AOCDay)(IAOCService)Activator.CreateInstance(x);
}
}
}
if (aocDay != null) break;
}
return aocDay;
}
}
}