![]() |
VOOZH | about |
dotnet add package Pillsgood.AdventOfCode --version 2.1.13
NuGet\Install-Package Pillsgood.AdventOfCode -Version 2.1.13
<PackageReference Include="Pillsgood.AdventOfCode" Version="2.1.13" />
<PackageVersion Include="Pillsgood.AdventOfCode" Version="2.1.13" />Directory.Packages.props
<PackageReference Include="Pillsgood.AdventOfCode" />Project file
paket add Pillsgood.AdventOfCode --version 2.1.13
#r "nuget: Pillsgood.AdventOfCode, 2.1.13"
#:package Pillsgood.AdventOfCode@2.1.13
#addin nuget:?package=Pillsgood.AdventOfCode&version=2.1.13Install as a Cake Addin
#tool nuget:?package=Pillsgood.AdventOfCode&version=2.1.13Install as a Cake Tool
Helpers for solving Advent of Code puzzles from unit tests. It handles:
Built for use with NUnit but probably works with other test frameworks too.
Add NuGet package Pillsgood.AdventOfCode to project.
Pillsgood.AdventOfCode.Login for interactive login.Add a one-time startup/teardown to your test assembly to initialize the library.
using NUnit.Framework;
using Pillsgood.AdventOfCode;
using Pillsgood.AdventOfCode.Login; // only if you want the login UI
[SetUpFixture]
public sealed class AdventSetup
{
private IDisposable? _app;
[OneTimeSetUp]
public void Start()
{
_app = Aoc.Start(cfg =>
{
// Choose ONE of the following:
// 1) Provide a session cookie directly:
// cfg.WithSession("your_session_cookie_here");
// 2) Or use the interactive login window (from Pillsgood.AdventOfCode.Login):
// cfg.WithLogin();
// Optional: only needed if your tests run from a helper assembly (probs works)
// cfg.SetEntryAssembly(typeof(AdventSetup).Assembly);
// Optional: you can add additional puzzle input converters here
// cfg.AddInputConverter<SampleType>(() => new SampleTypeInputConverter())
});
}
[OneTimeTearDown]
public void Stop()
{
_app?.Dispose();
}
}
Create test classes that inherit from AocFixture, and follow the naming conventions below. Use Input to read puzzle input and Answer to
submit/validate.
using NUnit.Framework;
using Pillsgood.AdventOfCode;
// Class name (or namespace) must include the year and day (see Naming Conventions)
namespace Y2024
{
public class Day01Tests : AocFixture
{
[Test]
public void Part1()
{
var lines = Input.Get<IEnumerable<string>>();
var result = SolvePart1(lines);
// Validates against your previously accepted answer (or submits if new)
Answer.Submit(result);
}
[Test]
public void Part2()
{
var numbers = Input.Get<int>(System.Globalization.NumberStyles.Integer);
var result = SolvePart2(numbers);
Answer.Submit(result);
}
private static int SolvePart1(IEnumerable<string> lines)
{
// your solution here
return lines.Count();
}
private static long SolvePart2(IEnumerable<int> nums)
{
// your solution here
return nums.Select(n => (long)n).Sum();
}
}
}
The library automatically detects which puzzle you’re solving by inspecting the call stack:
20xx present in the test class' full name (namespace or type name)DayNN (e.g., Day1, Day01, Day25) present in the test class' full namePart1 or Part2Examples that work:
AoC._2023.Day05 and class Day05TestsAdventOfCode.Y2022 and class Day1_PartTestsIf detection fails, you’ll get an error like “Unable to resolve date/part.” Ensure your class and method names contain the patterns above.
AocFixture exposes Input (an IPuzzleInputService) with helpers to parse your input:
// Reads raw text as string
var text = Input.Get<string>();
// Reads input as IEnumerable<string> (split by new lines)
var lines = Input.Get<IEnumerable<string>>();
// Read numbers with explicit number style and optional format provider
var ints = Input.Get<int>(System.Globalization.NumberStyles.Integer);
var longs = await Input.GetAsync<long>(System.Globalization.NumberStyles.Integer);
// Asynchronous versions exist for all operations: GetAsync<T>()
You can also access the raw stream:
await using var stream = await Input.GetInputStreamAsync(new DateOnly(2024, 12, 1));
Use Answer from AocFixture and call Submit(...) or SubmitAsync(...) inside your test method. The library:
// Numbers:
Answer.Submit(12345); // infers Part from method name
await Answer.SubmitAsync(12345L);
// Strings:
Answer.Submit("ABCDEF");
await Answer.SubmitAsync("ABCDEF");
// Defer computation:
Answer.Submit(() => Compute());
await Answer.SubmitAsync(async () => await ComputeAsync());
If the answer was already accepted previously, the call will assert equality against the known-good answer instead of re-submitting.
You must authenticate once so the library can fetch inputs and submit answers.
Pick one in Aoc.Start(cfg => ...):
cfg.WithSession("<session_cookie>") — pass your AoC session cookie directly (great for CI/local). The cookie value is the session cookie from
adventofcode.com.cfg.WithLogin() (from Pillsgood.AdventOfCode.Login) — shows a low-effort Avalonia login window to acquire and cache the session.The session is cached, if an invalid/expired session is detected, it will be cleared and you’ll be prompted again (or you’ll need to provide a valid cookie).
Aoc.Start(cfg => { ... }) accepts the following options:
var app = Aoc.Start(cfg =>
{
// 1) Provide a session cookie directly (recommended for CI/local)
cfg.WithSession("your_session_cookie_here");
// 2) Or provide a custom session provider
// cfg.WithSessionProvider(() => new MySessionProvider());
// Tell the library which assembly contains your tests (optional)
// cfg.SetEntryAssembly(typeof(SomeTypeInYourTests).Assembly);
// Register custom input converters (optional)
// cfg.AddInputConverter<MyType>(() => new MyTypeInputConverter());
// Set the cache file path (defaults to "store.db")
// cfg.WithCachePath(".aoc-cache.db");
});
Dispose the returned IDisposable at the end of the test run to cleanly release services.
If you prefer not to inherit from AocFixture, you can create your own base class. Mark it with AocFixtureAttribute so the library can resolve the date/part from your call stack.
using NUnit.Framework;
using Pillsgood.AdventOfCode;
using Pillsgood.AdventOfCode.Common;
[AocFixture]
public abstract class MyAocBase
{
protected IPuzzleInputService Input => Locator.GetRequiredService<IPuzzleInputService>();
protected IAnswerAssertion Answer => Locator.GetRequiredService<IAnswerAssertion>();
}
public sealed class Day01Tests : MyAocBase
{
[Test]
public void Part1()
{
var lines = Input.Get<IEnumerable<string>>();
var result = SolvePart1(lines);
Answer.Submit(result);
}
}
Notes:
Aoc.Start(...) to initialize DI and caching.AocFixtureAttribute on your base class (or on the test class) ensures that year/day and part can be resolved by the library.See LICENSE.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
Showing the top 1 NuGet packages that depend on Pillsgood.AdventOfCode:
| Package | Downloads |
|---|---|
|
Pillsgood.AdventOfCode.Login
Package Description |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.1.13 | 274 | 12/4/2025 |
| 2.1.12-alpha | 227 | 12/4/2025 |
| 2.1.11-alpha | 244 | 12/4/2025 |
| 2.1.7-alpha | 247 | 12/4/2025 |
| 2.0.23 | 270 | 12/4/2025 |
| 2.0.22 | 731 | 12/2/2025 |
| 2.0.21 | 724 | 12/2/2025 |
| 2.0.20 | 720 | 12/2/2025 |
| 2.0.19 | 744 | 12/2/2025 |
| 2.0.18-alpha | 702 | 12/2/2025 |
| 2.0.13-alpha | 711 | 12/2/2025 |
| 2.0.8-alpha | 702 | 12/2/2025 |
| 2.0.7-alpha | 703 | 12/2/2025 |
| 2.0.6-alpha | 709 | 12/2/2025 |
| 1.1.2 | 323 | 11/21/2024 |
| 1.1.1 | 267 | 11/21/2024 |
| 1.1.0-alpha | 189 | 11/21/2024 |
| 1.0.1 | 527 | 12/7/2022 |
| 1.0.0 | 521 | 12/7/2022 |