AccountingNext/Schaad.Accounting.Tests/FormattingTestShould.cs
Claudio Schaad 8926fb1e97 PR G: test project with xxxTestShould / DoThisWhenThat / Shouldly
Add Schaad.Accounting.Tests (xUnit + NSubstitute + Shouldly, net9.0)
wired into Accounting.sln with a direct Reference to
Schaad.Finance.Api.dll so it flows into the test binary.

Naming convention: file/class is <Subject>TestShould, each test method
is DoThisWhenThat. Reads as a sentence:
"ViewService test should sum activa and passiva totals separately when
getting balance view". All assertions use Shouldly (.ShouldBe,
.ShouldBeNull, .ShouldContain, ...) rather than xUnit Assert.*.

38 tests across seven files:

- ViewServiceTestShould: balance math (activa/passiva totals, per-
  account balance from start balance + credits - debits, FX conversion
  to CHF) and bank-transaction auto-matching (booking-rule text,
  value-matching preference, same-accounts-last-month fallback,
  open-transaction filter).
- TransactionRepositoryTestShould: FX round-trip against a temp XML
  directory, unknown-id -> null, and the mutation-on-read regression
  from PR A (a second Get on the same FX transaction used to divide
  by FxRate again).
- FormattingTestShould: Swiss thousands separator, two-decimal
  rounding, culture independence.
- RepositoryCacheTestShould: loader called once, per-key isolation,
  invalidation forces reload, case-insensitive keys.
- AccountRepositoryTestShould: id assignment, in-place update,
  currency defaulting, delete, bank-account lookup, bank-balance
  update, and constructor re-run against an existing file.
- ChartServiceTestShould: honours settingsService.GetYear() without
  mutating it (locks in PR E), account vs sub-class grouping
  heuristic, skips empty accounts.
- FileServiceTestShould: CSV header + running balance for debit and
  credit lines, ordering by BookingDate/ValueDate/Value, no in-place
  value mutation (locks in PR A).

CLAUDE.md gains a `dotnet test` line. IMPROVEMENT_PLAN.md notes that
this landed as three PRs (G, H, I) and was squashed on request.

Also add `*.DotSettings.user` to .gitignore so Rider's per-user
solution settings don't get accidentally staged.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-02 21:25:48 +02:00

41 lines
1.1 KiB
C#

using System.Globalization;
using Shouldly;
namespace Schaad.Accounting.Tests;
public class FormattingTestShould
{
[Theory]
[InlineData(0, "0.00")]
[InlineData(1.5, "1.50")]
[InlineData(-1.5, "-1.50")]
[InlineData(1234.5, "1'234.50")]
[InlineData(1234567.89, "1'234'567.89")]
[InlineData(-1234567.89, "-1'234'567.89")]
public void FormatDecimalWithSwissThousandsSeparatorWhenCalled(decimal value, string expected)
{
value.ToFormattedString().ShouldBe(expected);
}
[Fact]
public void RoundToTwoDecimalsWhenValueHasMorePrecision()
{
1.234m.ToFormattedString().ShouldBe("1.23");
1.235m.ToFormattedString().ShouldBe("1.24");
}
[Fact]
public void IgnoreAmbientCultureWhenFormatting()
{
var previous = CultureInfo.CurrentCulture;
try
{
CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
1234.5m.ToFormattedString().ShouldBe("1'234.50");
}
finally
{
CultureInfo.CurrentCulture = previous;
}
}
}