Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
run: dotnet build AndiGenerator.slnx -c Release -nologo

- name: Testen (mit Messung der Testabdeckung)
run: dotnet test AndiGenerator.slnx -c Release --no-build -nologo --logger "trx" --results-directory TestResults --collect "Code Coverage;Format=cobertura"
run: dotnet test AndiGenerator.slnx -c Release --no-build -nologo --logger "trx" --results-directory TestResults --filter "Kategorie!=Messung" --settings .runsettings --collect "Code Coverage;Format=cobertura"

- name: Testabdeckung zusammenfassen
if: always()
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
- name: Bauen und testen
run: |
dotnet build AndiGenerator.slnx -c Release -nologo -p:Version=${{ steps.version.outputs.version }}
dotnet test AndiGenerator.slnx -c Release --no-build -nologo
dotnet test AndiGenerator.slnx -c Release --no-build -nologo --filter "Kategorie!=Messung"

- name: Veröffentlichen
run: dotnet publish src/AndiGenerator.Desktop -c Release -r win-x64 --self-contained -nologo -o publish -p:Version=${{ steps.version.outputs.version }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ build-log.txt
build-messung.txt
optimierung-log.txt
abdeckung-log.txt
messen-log.txt

# Private Originaldaten (Klarnamen) – öffentlich nur die anonymisierte Kopie unter testdaten/
/Referenz/
Expand Down
26 changes: 26 additions & 0 deletions .runsettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Einstellungen für die Testabdeckung (Microsoft Code Coverage): gemessen werden nur die Programmschichten, nicht die
Testprojekte selbst. Visual Studio findet die Datei im Lösungsordner von selbst („runsettings-Dateien automatisch
erkennen“, Standard); abdeckung.cmd und das CI geben sie mit settings an. bauen.cmd verwendet sie nicht.
-->
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="Code Coverage">
<Configuration>
<CodeCoverage>
<ModulePaths>
<Include>
<ModulePath>.*[\\/]AndiGenerator\.[^\\/]*\.dll$</ModulePath>
</Include>
<Exclude>
<ModulePath>.*\.Tests\.dll$</ModulePath>
</Exclude>
</ModulePaths>
</CodeCoverage>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
</RunSettings>
1 change: 1 addition & 0 deletions AndiGenerator.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<Project Path="tests/AndiGenerator.Architektur.Tests/AndiGenerator.Architektur.Tests.csproj" />
<Project Path="tests/AndiGenerator.Persistence.Tests/AndiGenerator.Persistence.Tests.csproj" />
<Project Path="tests/AndiGenerator.Presentation.Tests/AndiGenerator.Presentation.Tests.csproj" />
<Project Path="tests/AndiGenerator.UI.Tests/AndiGenerator.UI.Tests.csproj" />
</Folder>
<Folder Name="/tools/">
<Project Path="tools/AndiGenerator.Cli/AndiGenerator.Cli.csproj" />
Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<ItemGroup>
<PackageVersion Include="Avalonia" Version="12.1.3" />
<PackageVersion Include="Avalonia.Desktop" Version="12.1.3" />
<PackageVersion Include="Avalonia.Headless" Version="12.1.3" />
<PackageVersion Include="Avalonia.Skia" Version="12.1.3" />
<PackageVersion Include="Avalonia.Themes.Fluent" Version="12.1.3" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.2" />
Expand Down
3 changes: 3 additions & 0 deletions Doku/MIGRATIONSPLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -682,3 +682,6 @@ Die **TT-Spielplan Engine** (Stephan Rüb, v1.1.2) ist ein neues, unabhängiges
| 01.10.2026 | Vorbereitung SignPath: `CODE_SIGNING.md` (Signierung, Ablauf, Rollen, Datenschutz, englische Kurzfassung; aus README und SECURITY.md verlinkt); Programmeinstellung „Beim Start nach neuen Versionen suchen“ im Dialog „Über“ (Standard an, `programm-einstellungen.txt` im eigenen Ordner), die Update-Suche richtet sich danach; Anleitung ergänzt |
| 01.10.2026 | Architekturtests als eigenes Testprojekt `AndiGenerator.Architektur.Tests`: liest die gebauten DLLs mit System.Reflection.Metadata (ohne sie zu laden) und prüft (1) Schichten verwenden nur tieferliegende Schichten (transitive Hülle der erlaubten Verweise), (2) Domain, Engine, Persistence, Rendering und Application nur .NET selbst, (3) Avalonia, Skia, Dock.Avalonia und Velopack nur in UI und Desktop, (4) Rechenkern (Domain, Engine, Rendering) ohne Datei-, Netz-, Prozess- und Konsolenzugriff, (5) Namensräume folgen dem Projekt, (6) ViewModels nur in der Presentation, (7) jede Quelldatei mit SPDX-Kopf; die bisherigen Prüfungen der Projektdateien (`SchichtenTests`) sind als `ProjektverweisTests` dorthin umgezogen |
| 01.10.2026 | Weitere Qualitätsmaßnahmen: Dependabot für Versions-Updates (NuGet und GitHub Actions, monatlich, gebündelt; Velopack ausgenommen, weil es mit `vpk` zusammen aktualisiert wird); Testabdeckung im CI (Microsoft Code Coverage, Zusammenfassung je Schicht über `tools/abdeckung/zusammenfassen.ps1` in der Zusammenfassung des Laufs, Berichte als Artefakt); Release mit Stückliste (SBOM, SPDX) und GitHub-Herkunftsnachweisen für Setup, ZIP und Pakete |
| 01.10.2026 | Oberflächentests als eigenes Testprojekt `AndiGenerator.UI.Tests` mit Avalonia.Headless (MIT, nur für Tests): echte Anwendung mit Stilen und Skia-Zeichnung ohne Bildschirm; Rauchtest des Hauptfensters (Staffel öffnen, Einrichtung, alle Ansichten mit dem click-TT-Plan zeigen und zeichnen), der einfachen Dialoge und aller Seiten von „Spielplandaten bearbeiten“; Regressionstest Doppelklick auf einen Wunschtermin; Avalonia-Fehlermeldungen (Protokoll) lassen die Tests scheitern. `THIRD-PARTY-NOTICES.md` ohne Versionsnummern (maßgeblich sind `Directory.Packages.props` und die Workflows) |
| 01.10.2026 | Testabdeckung ohne Testprojekte: `.runsettings` im Lösungsordner misst nur die Programmschichten – Visual Studio erkennt die Datei selbst, `abdeckung.cmd` und CI geben sie mit `--settings` an |
| 01.10.2026 | Schnellerer Testlauf: die Geschwindigkeitsmessungen (`Messungen`, rund 20 s, laufen allein und halten alle anderen Tests auf) tragen die Kategorie `Messung` und laufen nicht mehr in `bauen.cmd`, `abdeckung.cmd`, CI und Release, sondern mit dem neuen `messen.cmd`; der Test der Spezial-Insel rechnet in Schritten von 10 000 Durchläufen nur noch so lange, bis die Spezial-Insel eine Insel neu gestartet hat (vorher fest 200 000, rund 14 s) |
39 changes: 20 additions & 19 deletions THIRD-PARTY-NOTICES.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
# Drittbibliotheken

Für alles, was mit dem Programm ausgeliefert oder im Quellcode als Bibliothek verwendet wird, sind nur MIT-, Apache-2.0-, BSD- oder LGPL-lizenzierte Pakete zulässig (MIGRATIONSPLAN E11). Reine Entwicklungswerkzeuge sind davon ausgenommen (siehe unten). Jede neue Abhängigkeit wird hier eingetragen.
Für alles, was mit dem Programm ausgeliefert oder im Quellcode als Bibliothek verwendet wird, sind nur MIT-, Apache-2.0-, BSD- oder LGPL-lizenzierte Pakete zulässig (MIGRATIONSPLAN E11). Reine Entwicklungswerkzeuge sind davon ausgenommen (siehe unten). Jede neue Abhängigkeit wird hier eingetragen. Die gültigen Versionen der NuGet-Pakete stehen in [`Directory.Packages.props`](Directory.Packages.props) (Dependabot hält sie aktuell), die der GitHub Actions in den Workflows unter `.github/workflows`.

Ausnahme Schriften: Die SIL Open Font License (OFL 1.1) erlaubt das Einbetten und Weitergeben mit GPL-Software; der Lizenztext liegt neben den Schriftdateien, der reservierte Name „Plex“ wird nicht für veränderte Schriften verwendet.

| Paket | Version | Lizenz | Verwendung |
|---|---|---|---|
| .NET 10 Runtime/BCL | 10.0 | MIT | Laufzeit |
| Avalonia, Avalonia.Desktop, Avalonia.Themes.Fluent | 12.1.3 | MIT | Oberfläche (E2) |
| Avalonia.Skia (mit SkiaSharp, HarfBuzzSharp) | 12.1.3 | MIT | PDF-Ausdruck (`SKDocument`, Phase 7) |
| Dock.Avalonia, Dock.Avalonia.Themes.Fluent, Dock.Model.Mvvm | 12.1.0.6 | MIT | Andock-Layout der Ansichten (E15) |
| CommunityToolkit.Mvvm | 8.4.0 | MIT | ViewModels (E3) |
| Velopack | 0.0.1298 | MIT | Installation und Updates über GitHub Releases (E12) |
| Schriften IBM Plex Sans und IBM Plex Mono (je Regular, Medium, SemiBold, Bold) | 2017 IBM Corp. | SIL OFL 1.1 | Schrift der Oberfläche, eingebettet unter `src/AndiGenerator.UI/Assets/Fonts` mit `OFL.txt` |
| xunit | 2.9.3 | Apache-2.0 | nur Tests |
| xunit.runner.visualstudio | 3.1.0 | Apache-2.0 | nur Tests |
| Microsoft.NET.Test.Sdk | 17.14.1 | MIT | nur Tests |
| Paket | Lizenz | Verwendung |
|---|---|---|
| .NET 10 Runtime/BCL | MIT | Laufzeit |
| Avalonia, Avalonia.Desktop, Avalonia.Themes.Fluent | MIT | Oberfläche (E2) |
| Avalonia.Skia (mit SkiaSharp, HarfBuzzSharp) | MIT | PDF-Ausdruck (`SKDocument`, Phase 7) |
| Dock.Avalonia, Dock.Avalonia.Themes.Fluent, Dock.Model.Mvvm | MIT | Andock-Layout der Ansichten (E15) |
| CommunityToolkit.Mvvm | MIT | ViewModels (E3) |
| Velopack | MIT | Installation und Updates über GitHub Releases (E12); Version gemeinsam mit `VPK_VERSION` in `release.yml` |
| Schriften IBM Plex Sans und IBM Plex Mono (je Regular, Medium, SemiBold, Bold), © 2017 IBM Corp. | SIL OFL 1.1 | Schrift der Oberfläche, eingebettet unter `src/AndiGenerator.UI/Assets/Fonts` mit `OFL.txt` |
| xunit | Apache-2.0 | nur Tests |
| xunit.runner.visualstudio | Apache-2.0 | nur Tests |
| Microsoft.NET.Test.Sdk | MIT | nur Tests |
| Avalonia.Headless | MIT | nur Tests (Oberflächentests ohne Bildschirm) |

## Werkzeuge nur zur Build-Zeit (werden nicht ausgeliefert)

Analyzer laufen nur beim Kompilieren und landen nicht in den Programmdateien (`PrivateAssets=all` über `GlobalPackageReference`). E11 betrifft sie daher nicht; sie sind trotzdem hier aufgeführt.

Geprüft vor der Veröffentlichung (01.10.2026): SonarAnalyzer.CSharp steht seit Version 10.33 unter der Sonar Source-Available License. Wir halten das für unproblematisch, weil der Analyzer ein reines Entwicklungswerkzeug ist – wie ein Compiler: Er wird beim Bauen von NuGet geladen, ist nicht Teil des Quellcodes im Repository und wird weder ausgeliefert noch signiert. E11 nimmt solche Werkzeuge seit der Präzisierung vom 01.10.2026 ausdrücklich von der Lizenzregel aus; die Bedingung der SignPath Foundation (kein proprietärer Code in den signierten Dateien) betrifft ebenfalls nur ausgelieferte Bestandteile. Wer das Projekt ohne Sonar bauen möchte, entfernt die Zeile in `Directory.Packages.props`; StyleCop (MIT) bleibt.

| Paket | Version | Lizenz | Verwendung |
|---|---|---|---|
| StyleCop.Analyzers | 1.2.0-beta.556 | MIT | Stilprüfung (Konfiguration: `stylecop.json`, `.editorconfig`) |
| anchore/sbom-action (GitHub Action, nutzt Syft) | v0 | Apache-2.0 | Stückliste (SBOM) im Release-Workflow |
| actions/attest-build-provenance, actions/attest-sbom (GitHub Actions) | v2 | MIT | Herkunftsnachweise im Release-Workflow |
| SonarAnalyzer.CSharp | 10.33.0.1635 | Sonar Source-Available License v1 (kein OSI-Open-Source; bis 10.32 LGPL-3.0) | Qualitätsprüfung |
| Paket | Lizenz | Verwendung |
|---|---|---|
| StyleCop.Analyzers | MIT | Stilprüfung (Konfiguration: `stylecop.json`, `.editorconfig`) |
| anchore/sbom-action (GitHub Action, nutzt Syft) | Apache-2.0 | Stückliste (SBOM) im Release-Workflow |
| actions/attest-build-provenance, actions/attest-sbom (GitHub Actions) | MIT | Herkunftsnachweise im Release-Workflow |
| SonarAnalyzer.CSharp | Sonar Source-Available License v1 (kein OSI-Open-Source; bis 10.32 LGPL-3.0) | Qualitätsprüfung |

Geplant: Avalonia.Controls.DataGrid (MIT). **Nicht** zulässig: Avalonia TreeDataGrid/Accelerate, QuestPDF.
2 changes: 1 addition & 1 deletion abdeckung.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ chcp 65001 >nul
cd /d "%~dp0"
set "LOG=%~dp0abdeckung-log.txt"
echo ===== START %date% %time% > "%LOG%"
dotnet test AndiGenerator.slnx -c Release --no-build -nologo --collect "Code Coverage;Format=cobertura" --results-directory TestResults\Abdeckung >> "%LOG%" 2>&1
dotnet test AndiGenerator.slnx -c Release --no-build -nologo --filter "Kategorie!=Messung" --settings .runsettings --collect "Code Coverage;Format=cobertura" --results-directory TestResults\Abdeckung >> "%LOG%" 2>&1
echo ----- TEST Exitcode %ERRORLEVEL% >> "%LOG%"
echo ----- ZUSAMMENFASSUNG >> "%LOG%"
powershell -NoProfile -ExecutionPolicy Bypass -File tools\abdeckung\zusammenfassen.ps1 -Ordner TestResults\Abdeckung >> "%LOG%" 2>&1
Expand Down
2 changes: 1 addition & 1 deletion bauen.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ echo ----- BUILD Exitcode %BUILDRC% >> "%LOG%"
if not "%BUILDRC%"=="0" goto ende
echo Teste ...
echo ----- TEST >> "%LOG%"
dotnet test AndiGenerator.slnx -c Release --no-build -nologo --logger "console;verbosity=normal" >> "%LOG%" 2>&1
dotnet test AndiGenerator.slnx -c Release --no-build -nologo --filter "Kategorie!=Messung" --logger "console;verbosity=normal" >> "%LOG%" 2>&1
set TESTRC=%ERRORLEVEL%
echo ----- TEST Exitcode %TESTRC% >> "%LOG%"
:ende
Expand Down
14 changes: 14 additions & 0 deletions messen.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@echo off
rem Geschwindigkeitsmessungen der Engine (Tests der Kategorie "Messung"). Ergebnisse werden an build-messung.txt
rem angehaengt, das Protokoll steht in messen-log.txt. Vorher bauen.cmd ausfuehren.
chcp 65001 >nul
cd /d "%~dp0"
set "LOG=%~dp0messen-log.txt"
echo ===== START %date% %time% > "%LOG%"
echo Messe ...
dotnet test tests\AndiGenerator.Persistence.Tests\AndiGenerator.Persistence.Tests.csproj -c Release --no-build -nologo --filter "Kategorie=Messung" --logger "console;verbosity=normal" >> "%LOG%" 2>&1
echo ----- TEST Exitcode %ERRORLEVEL% >> "%LOG%"
echo ===== ENDE %date% %time% >> "%LOG%"
echo.
echo Fertig. Ergebnisse in build-messung.txt - Claude kann sie jetzt lesen.
timeout /t 5 >nul
4 changes: 4 additions & 0 deletions src/AndiGenerator.UI/AndiGenerator.UI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
<!-- Programmsymbol (Fenster und Taskleiste); dieselbe Datei nutzt AndiGenerator.Desktop für die .exe. -->
<AvaloniaResource Include="Assets\**" />
</ItemGroup>
<ItemGroup>
<!-- Oberflächentests ohne Bildschirm (Avalonia.Headless) erreichen auch die internen Dialoge. -->
<InternalsVisibleTo Include="AndiGenerator.UI.Tests" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AndiGenerator.Presentation\AndiGenerator.Presentation.csproj" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@ Optimierungseinstellungen.Standard with
MindestDurchlaeufeSpezialInsel = 3_000,
});

optimierer.Rechnen(200_000);
// In Schritten rechnen und aufhören, sobald die Spezial-Insel eine Insel neu gestartet hat (statt immer 200 000).
for (long durchlaeufe = 10_000; optimierer.SpezialVerwendet == 0 && durchlaeufe <= 200_000; durchlaeufe += 10_000)
{
optimierer.Rechnen(durchlaeufe);
}

Assert.NotNull(optimierer.SpezialKostenart);
Assert.True(optimierer.SpezialVerwendet > 0);
Expand Down
4 changes: 3 additions & 1 deletion tests/AndiGenerator.Persistence.Tests/Messungen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ namespace AndiGenerator.Persistence.Tests;

/// <summary>
/// Geschwindigkeitsmessungen (Ausgabe in <c>build-messung.txt</c>). Sie prüfen nichts Fachliches und laufen allein,
/// damit andere Tests die Kerne nicht mitbenutzen.
/// damit andere Tests die Kerne nicht mitbenutzen. Wegen ihrer Laufzeit gehören sie nicht zum normalen Testlauf
/// (<c>bauen.cmd</c>, <c>abdeckung.cmd</c>, CI filtern <c>Kategorie!=Messung</c>), sondern laufen mit <c>messen.cmd</c>.
/// </summary>
[Collection(MessungenSammlung.Name)]
[Trait("Kategorie", "Messung")]
public class Messungen
{
private static readonly string[] Strategien = ["R", "15", "5", "S1,25", "M2,10"];
Expand Down
29 changes: 29 additions & 0 deletions tests/AndiGenerator.UI.Tests/AndiGenerator.UI.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio" />
<PackageReference Include="Avalonia.Headless" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\AndiGenerator.UI\AndiGenerator.UI.csproj" />
</ItemGroup>
<ItemGroup>
<!-- Dieselbe Test-Oberfläche und dieselben Testdaten wie die ViewModel-Tests. -->
<Compile Include="..\AndiGenerator.Presentation.Tests\TestOberflaeche.cs" Link="Gemeinsam\TestOberflaeche.cs" />
<Compile Include="..\AndiGenerator.Presentation.Tests\Testdaten.cs" Link="Gemeinsam\Testdaten.cs" />
<Compile Include="..\AndiGenerator.Presentation.Tests\Arbeitsplatz.cs" Link="Gemeinsam\Arbeitsplatz.cs" />
<Compile Include="..\AndiGenerator.Presentation.Tests\Namen.cs" Link="Gemeinsam\Namen.cs" />
<AssemblyAttribute Include="System.Reflection.AssemblyMetadataAttribute">
<_Parameter1>Referenz</_Parameter1>
<_Parameter2>$(MSBuildThisFileDirectory)../../testdaten/referenz</_Parameter2>
</AssemblyAttribute>
</ItemGroup>
</Project>
Loading
Loading