From 7c9b43c1c0922c8fb2780ac9a7e4b931a9b3d693 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 5 Apr 2026 09:18:17 +0000 Subject: [PATCH] [bot] Generate Class Diagrams (2026-04-05 09:18:17) --- UML/FUnit.Directives.svg | 133 ++++++++++++++++ UML/FUnit.Directives.uml | 28 ++++ UML/FUnit.Run.svg | 112 ++++++++++++++ UML/FUnit.Run.uml | 14 ++ UML/FUnit.svg | 316 +++++++++++++++++++++++++++++++++++++++ UML/FUnit.uml | 188 +++++++++++++++++++++++ UML/README.md | 265 ++++++++++++++++++++++++++++++++ UML/index.html | 269 +++++++++++++++++++++++++++++++++ 8 files changed, 1325 insertions(+) create mode 100644 UML/FUnit.Directives.svg create mode 100644 UML/FUnit.Directives.uml create mode 100644 UML/FUnit.Run.svg create mode 100644 UML/FUnit.Run.uml create mode 100644 UML/FUnit.svg create mode 100644 UML/FUnit.uml create mode 100644 UML/README.md create mode 100644 UML/index.html diff --git a/UML/FUnit.Directives.svg b/UML/FUnit.Directives.svg new file mode 100644 index 0000000..b5d50ef --- /dev/null +++ b/UML/FUnit.Directives.svg @@ -0,0 +1,133 @@ +SR«const» DirectivePrefix : string = "funit"«const» DiagnosticCategory : stringDiagnosticDescriptorFUnitSourceGeneratorFUnitSourceGenerator()Initialize(context:GeneratorInitializationContext) : voidExecute(context:GeneratorExecutionContext) : voidISourceGeneratorIDirectiveOperatorIncludeOperatorDirectiveKeyword : string «get»Setup() : voidCleanup() : voidApply(args:string, sourceFilePath:string, location:Location) : (string HintName, string? GeneratedCode, ImmutableList<Diagnostic> Diagnostics)MissingFileNameDiagnosticIncludedFileNotFoundDiagnosticUnknownFUnitDirectiveDiagnosticEmptyFUnitDirectiveDiagnosticFileExtensionNotSupportedDiagnosticDebugDiagnostic \ No newline at end of file diff --git a/UML/FUnit.Directives.uml b/UML/FUnit.Directives.uml new file mode 100644 index 0000000..b0dd371 --- /dev/null +++ b/UML/FUnit.Directives.uml @@ -0,0 +1,28 @@ +@startuml +left to right direction +class SR { + + <> DirectivePrefix : string = "funit" + + <> DiagnosticCategory : string +} +SR o-> "MissingFileNameDiagnostic" DiagnosticDescriptor +SR o-> "IncludedFileNotFoundDiagnostic" DiagnosticDescriptor +SR o-> "UnknownFUnitDirectiveDiagnostic" DiagnosticDescriptor +SR o-> "EmptyFUnitDirectiveDiagnostic" DiagnosticDescriptor +SR o-> "FileExtensionNotSupportedDiagnostic" DiagnosticDescriptor +SR o-> "DebugDiagnostic" DiagnosticDescriptor +class FUnitSourceGenerator { + + FUnitSourceGenerator() + + Initialize(context:GeneratorInitializationContext) : void + + Execute(context:GeneratorExecutionContext) : void +} +ISourceGenerator <|-- FUnitSourceGenerator +interface IDirectiveOperator { +} +class IncludeOperator { + + DirectiveKeyword : string <> + + Setup() : void + + Cleanup() : void + + Apply(args:string, sourceFilePath:string, location:Location) : (string HintName, string? GeneratedCode, ImmutableList Diagnostics) +} +IDirectiveOperator <|-- IncludeOperator +@enduml diff --git a/UML/FUnit.Run.svg b/UML/FUnit.Run.svg new file mode 100644 index 0000000..454fcea --- /dev/null +++ b/UML/FUnit.Run.svg @@ -0,0 +1,112 @@ +«file»«sealed»ProcessCallbackCallCounts«volatile» Error : int«volatile» Stdout : int«static»«partial»LogRegex«partial» WarningOrError() : RegexList`1TValueTask`1T \ No newline at end of file diff --git a/UML/FUnit.Run.uml b/UML/FUnit.Run.uml new file mode 100644 index 0000000..0d034fe --- /dev/null +++ b/UML/FUnit.Run.uml @@ -0,0 +1,14 @@ +@startuml +left to right direction +class ProcessCallbackCallCounts <> <> { + + <> Error : int + + <> Stdout : int +} +class LogRegex <> <> { + + {static} <> WarningOrError() : Regex +} +class "List`1" { +} +class "ValueTask`1" { +} +@enduml diff --git a/UML/FUnit.svg b/UML/FUnit.svg new file mode 100644 index 0000000..c9b947d --- /dev/null +++ b/UML/FUnit.svg @@ -0,0 +1,316 @@ +«partial»FUnitBuild(builder:Action<Descriptor>) : TestSuiteRun(args:string[], builder:Action<Descriptor>) : int«async» RunAsync(args:string[], builder:Action<Descriptor>, cancellationToken:CancellationToken) : Task<int>Action`2T1,T2«sealed»«partial»TestResult«override» ToString() : stringToString(passedColorTag:string, failedColorTag:string, colorResetTag:string) : string«static»«partial»MustHaveEqualProperties(expected:TExpected, actual:TActual, propertyNamesToSkip:string[]?, logger:Action<string>?) : voidHaveEqualFields(expected:TExpected, actual:TActual, fieldNamesToSkip:string[]?, logger:Action<string>?) : voidBeEqual(expected:T, actual:T, actualExpr:string?) : voidNotBeEqual(expected:T, actual:T, actualExpr:string?) : voidBeSameReference(expected:object, actual:object) : voidNotBeSameReference(expected:object, actual:object) : voidBeTrue(condition:bool, conditionExpr:string?) : voidHaveSameSequence(expected:IEnumerable<T>, actual:IEnumerable<T>) : voidHaveSameSequence(expected:ReadOnlySpan<T>, actual:ReadOnlySpan<T>) : voidHaveSameSequence(expected:ReadOnlySpan<T>, actual:IEnumerable<T>) : voidHaveSameSequence(expected:IEnumerable<T>, actual:ReadOnlySpan<T>) : voidHaveSameSequence(expected:T[], actual:T[]) : voidHaveSameSequence(expected:T[], actual:IEnumerable<T>) : voidHaveSameSequence(expected:IEnumerable<T>, actual:T[]) : voidHaveSameSequence(expected:T[], actual:ReadOnlySpan<T>) : voidHaveSameSequence(expected:ReadOnlySpan<T>, actual:T[]) : voidNotHaveSameSequence(expected:IEnumerable<T>, actual:IEnumerable<T>) : voidNotHaveSameSequence(expected:ReadOnlySpan<T>, actual:ReadOnlySpan<T>) : voidNotHaveSameSequence(expected:ReadOnlySpan<T>, actual:IEnumerable<T>) : voidNotHaveSameSequence(expected:IEnumerable<T>, actual:ReadOnlySpan<T>) : voidNotHaveSameSequence(expected:T[], actual:T[]) : voidNotHaveSameSequence(expected:T[], actual:IEnumerable<T>) : voidNotHaveSameSequence(expected:IEnumerable<T>, actual:T[]) : voidNotHaveSameSequence(expected:T[], actual:ReadOnlySpan<T>) : voidNotHaveSameSequence(expected:ReadOnlySpan<T>, actual:T[]) : voidHaveSameUnorderedElements(expected:IEnumerable<T>, actual:IEnumerable<T>) : voidHaveSameUnorderedElements(expected:ReadOnlySpan<T>, actual:ReadOnlySpan<T>) : voidHaveSameUnorderedElements(expected:ReadOnlySpan<T>, actual:IEnumerable<T>) : voidHaveSameUnorderedElements(expected:IEnumerable<T>, actual:ReadOnlySpan<T>) : voidHaveSameUnorderedElements(expected:T[], actual:T[]) : voidHaveSameUnorderedElements(expected:T[], actual:IEnumerable<T>) : voidHaveSameUnorderedElements(expected:IEnumerable<T>, actual:T[]) : voidHaveSameUnorderedElements(expected:T[], actual:ReadOnlySpan<T>) : voidHaveSameUnorderedElements(expected:ReadOnlySpan<T>, actual:T[]) : voidNotHaveSameUnorderedElements(expected:IEnumerable<T>, actual:IEnumerable<T>) : voidNotHaveSameUnorderedElements(expected:ReadOnlySpan<T>, actual:ReadOnlySpan<T>) : voidNotHaveSameUnorderedElements(expected:ReadOnlySpan<T>, actual:IEnumerable<T>) : voidNotHaveSameUnorderedElements(expected:IEnumerable<T>, actual:ReadOnlySpan<T>) : voidNotHaveSameUnorderedElements(expected:T[], actual:T[]) : voidNotHaveSameUnorderedElements(expected:T[], actual:IEnumerable<T>) : voidNotHaveSameUnorderedElements(expected:IEnumerable<T>, actual:T[]) : voidNotHaveSameUnorderedElements(expected:T[], actual:ReadOnlySpan<T>) : voidNotHaveSameUnorderedElements(expected:ReadOnlySpan<T>, actual:T[]) : voidContainText(text:string, substring:string) : voidNotContainText(text:string, substring:string) : voidThrow(expectedMessage:string?, testAsync:Func<Task>) : voidThrow(expectedMessage:string?, test:Action) : voidThrow(fullTypeName:string, expectedMessage:string?, testAsync:Func<Task>) : voidThrow(fullTypeName:string, expectedMessage:string?, test:Action) : void«sealed»«partial»«record»ErrorMessage : string «get» «init»StackTrace : string? «get» «init»IsFUnitSystemError : bool «get» «init»IsAssertionFailure : bool «get» «init»«sealed»«partial»«record»TestDescription : string «get» «init»ExecutionCount : int «get» «init»Errors : IReadOnlyList<Error>? «get» «init»IReadOnlyDictionary`2T1,T2IReadOnlyList`1TTimeSpan«sealed»TestSuite«event» OnTestStarting : Action?«event» OnTestSubjectStarting : Action<string>?«event» OnCanceledExecutionReportStarting : Action?«event» OnTestCasePassed : Action<(string subject, string description, int maxIterations, IEnumerable<Exception> errors)>?«event» OnTestCaseFailed : Action<(string subject, string description, int maxIterations, IEnumerable<Exception> errors)>?«event» OnCanceledExecutionReportTestCase : Action<(string subject, string description)>?Execute(subject:string, test:string) : Exception?«async» ExecuteAsync(subject:string, test:string, cancellationToken:CancellationToken) : Task<Exception?>ExecuteTests(args:string[]) : TestResultExecuteTestsAsync(args:string[], cancellationToken:CancellationToken) : Task<TestResult>«static»IsExternalInit«sealed»CallerArgumentExpressionAttributeCallerArgumentExpressionAttribute(parameterName:string)Attribute«sealed»TestCaseSubject : string «get»Description : string «get»ExecutionCount : int «get»TestCase(subject:string, description:string, testFunction:Delegate)«async» ExecuteAsync(cancellationToke:CancellationToken) : Task<Exception?>FUnitExceptionFUnitException(message:string, inner:Exception?)ExceptionVerbosityQuiet= /**/ -2,Minimal= /**/ -1,Normal= /**/ 0,Detailed,Diagnostic,«static»SR«const» Flag_Iterations : string = "--iterations"«const» Flag_Concurrency : string = "--concurrency"«const» Flag_MarkdownOutput : string = "--markdown"«const» Flag_MarkdownOutputShort : string = "-md"«const» Flag_TEST : string = "--TEST"«const» Flag_Configuration : string = "--configuration"«const» Flag_ConfigurationShort : string = "-c"«const» Flag_Debug : string = "Debug"«const» Flag_Release : string = "Release"«const» Flag_Delimiter : string = "--"«const» Flag_Help : string = "--help"«const» Flag_HelpShort : string = "-h"«const» Flag_Lint : string = "--lint"«const» Flag_StackTrace : string = "--stacktrace"«const» Flag_NoClean : string = "--no-clean"«const» Flag_Warnings : string = "--warnings"«const» EmojiPassed : string = "✓"«const» EmojiFailed : string = "×"«const» EmojiPassedGitHub : string = "✅"«const» EmojiFailedGitHub : string = "⛔"«const» MarkdownPassed : string«const» MarkdownFailed : string«const» AnsiColorFailed : string = "\u001b[31m"«const» AnsiColorPassed : string = "\u001b[32m"«const» AnsiColorReset : string = "\u001b[0m"«const» MarkdownColorFailed : string = "<span style='color:red'>"«const» MarkdownColorPassed : string = "<span style='color:green'>"«const» MarkdownColorReset : string = "</span>"«const» IndentationAdjustment : int = 6«const» FlakyTestResultAnnotation : string = "🔥 Flaky Test Detected: Inconsistent results across multiple runs"GetElapsedTime(startingTimestamp:long) : TimeSpanGetElapsedTime(startingTimestamp:long, endingTimestamp:long) : TimeSpan«static»ConsoleLoggerEnableMarkdownOutput : bool «get» «set»LogInfoRaw(message:object?) : voidLogInfo(message:object?) : voidLogPassed(message:object) : voidLogFailed(message:object) : void«sealed»«record»CommandLineOptionsConcurrencyLevel : int «get» «init» = 1BuildConfiguration : string «get» «init» = "Debug"Iterations : int «get» «init» = 3ShowStackTrace : bool «get»NoClean : bool «get»ShowWarnings : bool «get»ConcurrencyLevel : int «get»Iterations : int «get»Parse(args:string[], throwOnUnknown:bool) : CommandLineOptions«override» ToString() : stringResultTotalExecutionTimeTestsBySubject<string,IReadOnlyList<Test>>TestsBySubject<string,IReadOnlyList<string>>Verbosity \ No newline at end of file diff --git a/UML/FUnit.uml b/UML/FUnit.uml new file mode 100644 index 0000000..783d8b9 --- /dev/null +++ b/UML/FUnit.uml @@ -0,0 +1,188 @@ +@startuml +left to right direction +class FUnit <> <> { + + {static} Build(builder:Action) : TestSuite + + {static} Run(args:string[], builder:Action) : int + + {static} <> RunAsync(args:string[], builder:Action, cancellationToken:CancellationToken) : Task +} +class "Action`2" { +} +FUnit --> "Result" TestResult +class Must <> { + + {static} HaveEqualProperties(expected:TExpected, actual:TActual, propertyNamesToSkip:string[]?, logger:Action?) : void + + {static} HaveEqualFields(expected:TExpected, actual:TActual, fieldNamesToSkip:string[]?, logger:Action?) : void +} +class Must <> <> { + + {static} BeEqual(expected:T, actual:T, actualExpr:string?) : void + + {static} NotBeEqual(expected:T, actual:T, actualExpr:string?) : void + + {static} BeSameReference(expected:object, actual:object) : void + + {static} NotBeSameReference(expected:object, actual:object) : void + + {static} BeTrue(condition:bool, conditionExpr:string?) : void + + {static} HaveSameSequence(expected:IEnumerable, actual:IEnumerable) : void + + {static} HaveSameSequence(expected:ReadOnlySpan, actual:ReadOnlySpan) : void + + {static} HaveSameSequence(expected:ReadOnlySpan, actual:IEnumerable) : void + + {static} HaveSameSequence(expected:IEnumerable, actual:ReadOnlySpan) : void + + {static} HaveSameSequence(expected:T[], actual:T[]) : void + + {static} HaveSameSequence(expected:T[], actual:IEnumerable) : void + + {static} HaveSameSequence(expected:IEnumerable, actual:T[]) : void + + {static} HaveSameSequence(expected:T[], actual:ReadOnlySpan) : void + + {static} HaveSameSequence(expected:ReadOnlySpan, actual:T[]) : void + + {static} NotHaveSameSequence(expected:IEnumerable, actual:IEnumerable) : void + + {static} NotHaveSameSequence(expected:ReadOnlySpan, actual:ReadOnlySpan) : void + + {static} NotHaveSameSequence(expected:ReadOnlySpan, actual:IEnumerable) : void + + {static} NotHaveSameSequence(expected:IEnumerable, actual:ReadOnlySpan) : void + + {static} NotHaveSameSequence(expected:T[], actual:T[]) : void + + {static} NotHaveSameSequence(expected:T[], actual:IEnumerable) : void + + {static} NotHaveSameSequence(expected:IEnumerable, actual:T[]) : void + + {static} NotHaveSameSequence(expected:T[], actual:ReadOnlySpan) : void + + {static} NotHaveSameSequence(expected:ReadOnlySpan, actual:T[]) : void + + {static} HaveSameUnorderedElements(expected:IEnumerable, actual:IEnumerable) : void + + {static} HaveSameUnorderedElements(expected:ReadOnlySpan, actual:ReadOnlySpan) : void + + {static} HaveSameUnorderedElements(expected:ReadOnlySpan, actual:IEnumerable) : void + + {static} HaveSameUnorderedElements(expected:IEnumerable, actual:ReadOnlySpan) : void + + {static} HaveSameUnorderedElements(expected:T[], actual:T[]) : void + + {static} HaveSameUnorderedElements(expected:T[], actual:IEnumerable) : void + + {static} HaveSameUnorderedElements(expected:IEnumerable, actual:T[]) : void + + {static} HaveSameUnorderedElements(expected:T[], actual:ReadOnlySpan) : void + + {static} HaveSameUnorderedElements(expected:ReadOnlySpan, actual:T[]) : void + + {static} NotHaveSameUnorderedElements(expected:IEnumerable, actual:IEnumerable) : void + + {static} NotHaveSameUnorderedElements(expected:ReadOnlySpan, actual:ReadOnlySpan) : void + + {static} NotHaveSameUnorderedElements(expected:ReadOnlySpan, actual:IEnumerable) : void + + {static} NotHaveSameUnorderedElements(expected:IEnumerable, actual:ReadOnlySpan) : void + + {static} NotHaveSameUnorderedElements(expected:T[], actual:T[]) : void + + {static} NotHaveSameUnorderedElements(expected:T[], actual:IEnumerable) : void + + {static} NotHaveSameUnorderedElements(expected:IEnumerable, actual:T[]) : void + + {static} NotHaveSameUnorderedElements(expected:T[], actual:ReadOnlySpan) : void + + {static} NotHaveSameUnorderedElements(expected:ReadOnlySpan, actual:T[]) : void + + {static} ContainText(text:string, substring:string) : void + + {static} NotContainText(text:string, substring:string) : void + + {static} Throw(expectedMessage:string?, testAsync:Func) : void + + {static} Throw(expectedMessage:string?, test:Action) : void + + {static} Throw(fullTypeName:string, expectedMessage:string?, testAsync:Func) : void + + {static} Throw(fullTypeName:string, expectedMessage:string?, test:Action) : void +} +class FUnit <> { +} +class TestResult <> <> { + + <> ToString() : string + + ToString(passedColorTag:string, failedColorTag:string, colorResetTag:string) : string +} +class Error <> <> <> { + + Message : string <> <> + + StackTrace : string? <> <> + + IsFUnitSystemError : bool <> <> + + IsAssertionFailure : bool <> <> +} +class Test <> <> <> { + + Description : string <> <> + + ExecutionCount : int <> <> + + Errors : IReadOnlyList? <> <> +} +class "IReadOnlyDictionary`2" { +} +class "IReadOnlyList`1" { +} +FUnit +-- TestResult +TestResult --> "TotalExecutionTime" TimeSpan +TestResult --> "TestsBySubject>" "IReadOnlyDictionary`2" +TestResult +-- Error +TestResult +-- Test +class FUnit <> { +} +class "Action`2" { +} +class TestSuite <> { + + <> OnTestStarting : Action? + + <> OnTestSubjectStarting : Action? + + <> OnTestCasePassed : Action<(string subject, string description, int maxIterations, IEnumerable errors)>? + + <> OnTestCaseFailed : Action<(string subject, string description, int maxIterations, IEnumerable errors)>? + + <> OnCanceledExecutionReportStarting : Action? + + <> OnCanceledExecutionReportTestCase : Action<(string subject, string description)>? + + Execute(subject:string, test:string) : Exception? + + <> ExecuteAsync(subject:string, test:string, cancellationToken:CancellationToken) : Task + + ExecuteTests(args:string[]) : TestResult + + ExecuteTestsAsync(args:string[], cancellationToken:CancellationToken) : Task +} +class "IReadOnlyDictionary`2" { +} +FUnit +-- TestSuite +TestSuite --> "TestsBySubject>" "IReadOnlyDictionary`2" +class IsExternalInit <> { +} +class CallerArgumentExpressionAttribute <> { + + CallerArgumentExpressionAttribute(parameterName:string) +} +Attribute <|-- CallerArgumentExpressionAttribute +class TestCase <> { + + Subject : string <> + + Description : string <> + + ExecutionCount : int <> + + TestCase(subject:string, description:string, testFunction:Delegate) + + <> ExecuteAsync(cancellationToke:CancellationToken) : Task +} +class FUnitException { + + FUnitException(message:string, inner:Exception?) +} +Exception <|-- FUnitException +enum Verbosity { + Quiet= /**/ -2, + Minimal= /**/ -1, + Normal= /**/ 0, + Detailed, + Diagnostic, +} +class SR <> { + + <> Flag_Iterations : string = "--iterations" + + <> Flag_Concurrency : string = "--concurrency" + + <> Flag_MarkdownOutput : string = "--markdown" + + <> Flag_MarkdownOutputShort : string = "-md" + + <> Flag_TEST : string = "--TEST" + + <> Flag_Configuration : string = "--configuration" + + <> Flag_ConfigurationShort : string = "-c" + + <> Flag_Debug : string = "Debug" + + <> Flag_Release : string = "Release" + + <> Flag_Delimiter : string = "--" + + <> Flag_Help : string = "--help" + + <> Flag_HelpShort : string = "-h" + + <> Flag_Lint : string = "--lint" + + <> Flag_StackTrace : string = "--stacktrace" + + <> Flag_NoClean : string = "--no-clean" + + <> Flag_Warnings : string = "--warnings" + + <> EmojiPassed : string = "✓" + + <> EmojiFailed : string = "×" + + <> EmojiPassedGitHub : string = "✅" + + <> EmojiFailedGitHub : string = "⛔" + + <> MarkdownPassed : string + + <> MarkdownFailed : string + + <> AnsiColorFailed : string = "\u001b[31m" + + <> AnsiColorPassed : string = "\u001b[32m" + + <> AnsiColorReset : string = "\u001b[0m" + + <> MarkdownColorFailed : string = "" + + <> MarkdownColorPassed : string = "" + + <> MarkdownColorReset : string = "" + + <> IndentationAdjustment : int = 6 + + <> FlakyTestResultAnnotation : string = "🔥 Flaky Test Detected: Inconsistent results across multiple runs" + + {static} GetElapsedTime(startingTimestamp:long) : TimeSpan + + {static} GetElapsedTime(startingTimestamp:long, endingTimestamp:long) : TimeSpan +} +class ConsoleLogger <> { + + {static} EnableMarkdownOutput : bool <> <> + + {static} LogInfoRaw(message:object?) : void + + {static} LogInfo(message:object?) : void + + {static} LogPassed(message:object) : void + + {static} LogFailed(message:object) : void +} +class CommandLineOptions <> <> { + + ConcurrencyLevel : int <> <> = 1 + + BuildConfiguration : string <> <> = "Debug" + + Iterations : int <> <> = 3 + + ShowStackTrace : bool <> + + NoClean : bool <> + + ShowWarnings : bool <> + + ConcurrencyLevel : int <> + + Iterations : int <> + + {static} Parse(args:string[], throwOnUnknown:bool) : CommandLineOptions + + <> ToString() : string +} +CommandLineOptions o-> "Verbosity" Verbosity +@enduml diff --git a/UML/README.md b/UML/README.md new file mode 100644 index 0000000..ee5a919 --- /dev/null +++ b/UML/README.md @@ -0,0 +1,265 @@ +Generated by [dotnet-diagram](https://github.com/sator-imaging/dotnet-diagram) + +# FUnit.Directives + +![FUnit.Directives](FUnit.Directives.svg) + +
+PlantUML + +```plantuml +@startuml +left to right direction +class SR { + + <> DirectivePrefix : string = "funit" + + <> DiagnosticCategory : string +} +SR o-> "MissingFileNameDiagnostic" DiagnosticDescriptor +SR o-> "IncludedFileNotFoundDiagnostic" DiagnosticDescriptor +SR o-> "UnknownFUnitDirectiveDiagnostic" DiagnosticDescriptor +SR o-> "EmptyFUnitDirectiveDiagnostic" DiagnosticDescriptor +SR o-> "FileExtensionNotSupportedDiagnostic" DiagnosticDescriptor +SR o-> "DebugDiagnostic" DiagnosticDescriptor +class FUnitSourceGenerator { + + FUnitSourceGenerator() + + Initialize(context:GeneratorInitializationContext) : void + + Execute(context:GeneratorExecutionContext) : void +} +ISourceGenerator <|-- FUnitSourceGenerator +interface IDirectiveOperator { +} +class IncludeOperator { + + DirectiveKeyword : string <> + + Setup() : void + + Cleanup() : void + + Apply(args:string, sourceFilePath:string, location:Location) : (string HintName, string? GeneratedCode, ImmutableList Diagnostics) +} +IDirectiveOperator <|-- IncludeOperator +@enduml +``` +
+ +# FUnit.Run + +![FUnit.Run](FUnit.Run.svg) + +
+PlantUML + +```plantuml +@startuml +left to right direction +class ProcessCallbackCallCounts <> <> { + + <> Error : int + + <> Stdout : int +} +class LogRegex <> <> { + + {static} <> WarningOrError() : Regex +} +class "List`1" { +} +class "ValueTask`1" { +} +@enduml +``` +
+ +# FUnit + +![FUnit](FUnit.svg) + +
+PlantUML + +```plantuml +@startuml +left to right direction +class FUnit <> <> { + + {static} Build(builder:Action) : TestSuite + + {static} Run(args:string[], builder:Action) : int + + {static} <> RunAsync(args:string[], builder:Action, cancellationToken:CancellationToken) : Task +} +class "Action`2" { +} +FUnit --> "Result" TestResult +class Must <> { + + {static} HaveEqualProperties(expected:TExpected, actual:TActual, propertyNamesToSkip:string[]?, logger:Action?) : void + + {static} HaveEqualFields(expected:TExpected, actual:TActual, fieldNamesToSkip:string[]?, logger:Action?) : void +} +class Must <> <> { + + {static} BeEqual(expected:T, actual:T, actualExpr:string?) : void + + {static} NotBeEqual(expected:T, actual:T, actualExpr:string?) : void + + {static} BeSameReference(expected:object, actual:object) : void + + {static} NotBeSameReference(expected:object, actual:object) : void + + {static} BeTrue(condition:bool, conditionExpr:string?) : void + + {static} HaveSameSequence(expected:IEnumerable, actual:IEnumerable) : void + + {static} HaveSameSequence(expected:ReadOnlySpan, actual:ReadOnlySpan) : void + + {static} HaveSameSequence(expected:ReadOnlySpan, actual:IEnumerable) : void + + {static} HaveSameSequence(expected:IEnumerable, actual:ReadOnlySpan) : void + + {static} HaveSameSequence(expected:T[], actual:T[]) : void + + {static} HaveSameSequence(expected:T[], actual:IEnumerable) : void + + {static} HaveSameSequence(expected:IEnumerable, actual:T[]) : void + + {static} HaveSameSequence(expected:T[], actual:ReadOnlySpan) : void + + {static} HaveSameSequence(expected:ReadOnlySpan, actual:T[]) : void + + {static} NotHaveSameSequence(expected:IEnumerable, actual:IEnumerable) : void + + {static} NotHaveSameSequence(expected:ReadOnlySpan, actual:ReadOnlySpan) : void + + {static} NotHaveSameSequence(expected:ReadOnlySpan, actual:IEnumerable) : void + + {static} NotHaveSameSequence(expected:IEnumerable, actual:ReadOnlySpan) : void + + {static} NotHaveSameSequence(expected:T[], actual:T[]) : void + + {static} NotHaveSameSequence(expected:T[], actual:IEnumerable) : void + + {static} NotHaveSameSequence(expected:IEnumerable, actual:T[]) : void + + {static} NotHaveSameSequence(expected:T[], actual:ReadOnlySpan) : void + + {static} NotHaveSameSequence(expected:ReadOnlySpan, actual:T[]) : void + + {static} HaveSameUnorderedElements(expected:IEnumerable, actual:IEnumerable) : void + + {static} HaveSameUnorderedElements(expected:ReadOnlySpan, actual:ReadOnlySpan) : void + + {static} HaveSameUnorderedElements(expected:ReadOnlySpan, actual:IEnumerable) : void + + {static} HaveSameUnorderedElements(expected:IEnumerable, actual:ReadOnlySpan) : void + + {static} HaveSameUnorderedElements(expected:T[], actual:T[]) : void + + {static} HaveSameUnorderedElements(expected:T[], actual:IEnumerable) : void + + {static} HaveSameUnorderedElements(expected:IEnumerable, actual:T[]) : void + + {static} HaveSameUnorderedElements(expected:T[], actual:ReadOnlySpan) : void + + {static} HaveSameUnorderedElements(expected:ReadOnlySpan, actual:T[]) : void + + {static} NotHaveSameUnorderedElements(expected:IEnumerable, actual:IEnumerable) : void + + {static} NotHaveSameUnorderedElements(expected:ReadOnlySpan, actual:ReadOnlySpan) : void + + {static} NotHaveSameUnorderedElements(expected:ReadOnlySpan, actual:IEnumerable) : void + + {static} NotHaveSameUnorderedElements(expected:IEnumerable, actual:ReadOnlySpan) : void + + {static} NotHaveSameUnorderedElements(expected:T[], actual:T[]) : void + + {static} NotHaveSameUnorderedElements(expected:T[], actual:IEnumerable) : void + + {static} NotHaveSameUnorderedElements(expected:IEnumerable, actual:T[]) : void + + {static} NotHaveSameUnorderedElements(expected:T[], actual:ReadOnlySpan) : void + + {static} NotHaveSameUnorderedElements(expected:ReadOnlySpan, actual:T[]) : void + + {static} ContainText(text:string, substring:string) : void + + {static} NotContainText(text:string, substring:string) : void + + {static} Throw(expectedMessage:string?, testAsync:Func) : void + + {static} Throw(expectedMessage:string?, test:Action) : void + + {static} Throw(fullTypeName:string, expectedMessage:string?, testAsync:Func) : void + + {static} Throw(fullTypeName:string, expectedMessage:string?, test:Action) : void +} +class FUnit <> { +} +class TestResult <> <> { + + <> ToString() : string + + ToString(passedColorTag:string, failedColorTag:string, colorResetTag:string) : string +} +class Error <> <> <> { + + Message : string <> <> + + StackTrace : string? <> <> + + IsFUnitSystemError : bool <> <> + + IsAssertionFailure : bool <> <> +} +class Test <> <> <> { + + Description : string <> <> + + ExecutionCount : int <> <> + + Errors : IReadOnlyList? <> <> +} +class "IReadOnlyDictionary`2" { +} +class "IReadOnlyList`1" { +} +FUnit +-- TestResult +TestResult --> "TotalExecutionTime" TimeSpan +TestResult --> "TestsBySubject>" "IReadOnlyDictionary`2" +TestResult +-- Error +TestResult +-- Test +class FUnit <> { +} +class "Action`2" { +} +class TestSuite <> { + + <> OnTestStarting : Action? + + <> OnTestSubjectStarting : Action? + + <> OnTestCasePassed : Action<(string subject, string description, int maxIterations, IEnumerable errors)>? + + <> OnTestCaseFailed : Action<(string subject, string description, int maxIterations, IEnumerable errors)>? + + <> OnCanceledExecutionReportStarting : Action? + + <> OnCanceledExecutionReportTestCase : Action<(string subject, string description)>? + + Execute(subject:string, test:string) : Exception? + + <> ExecuteAsync(subject:string, test:string, cancellationToken:CancellationToken) : Task + + ExecuteTests(args:string[]) : TestResult + + ExecuteTestsAsync(args:string[], cancellationToken:CancellationToken) : Task +} +class "IReadOnlyDictionary`2" { +} +FUnit +-- TestSuite +TestSuite --> "TestsBySubject>" "IReadOnlyDictionary`2" +class IsExternalInit <> { +} +class CallerArgumentExpressionAttribute <> { + + CallerArgumentExpressionAttribute(parameterName:string) +} +Attribute <|-- CallerArgumentExpressionAttribute +class TestCase <> { + + Subject : string <> + + Description : string <> + + ExecutionCount : int <> + + TestCase(subject:string, description:string, testFunction:Delegate) + + <> ExecuteAsync(cancellationToke:CancellationToken) : Task +} +class FUnitException { + + FUnitException(message:string, inner:Exception?) +} +Exception <|-- FUnitException +enum Verbosity { + Quiet= /**/ -2, + Minimal= /**/ -1, + Normal= /**/ 0, + Detailed, + Diagnostic, +} +class SR <> { + + <> Flag_Iterations : string = "--iterations" + + <> Flag_Concurrency : string = "--concurrency" + + <> Flag_MarkdownOutput : string = "--markdown" + + <> Flag_MarkdownOutputShort : string = "-md" + + <> Flag_TEST : string = "--TEST" + + <> Flag_Configuration : string = "--configuration" + + <> Flag_ConfigurationShort : string = "-c" + + <> Flag_Debug : string = "Debug" + + <> Flag_Release : string = "Release" + + <> Flag_Delimiter : string = "--" + + <> Flag_Help : string = "--help" + + <> Flag_HelpShort : string = "-h" + + <> Flag_Lint : string = "--lint" + + <> Flag_StackTrace : string = "--stacktrace" + + <> Flag_NoClean : string = "--no-clean" + + <> Flag_Warnings : string = "--warnings" + + <> EmojiPassed : string = "✓" + + <> EmojiFailed : string = "×" + + <> EmojiPassedGitHub : string = "✅" + + <> EmojiFailedGitHub : string = "⛔" + + <> MarkdownPassed : string + + <> MarkdownFailed : string + + <> AnsiColorFailed : string = "\u001b[31m" + + <> AnsiColorPassed : string = "\u001b[32m" + + <> AnsiColorReset : string = "\u001b[0m" + + <> MarkdownColorFailed : string = "" + + <> MarkdownColorPassed : string = "" + + <> MarkdownColorReset : string = "" + + <> IndentationAdjustment : int = 6 + + <> FlakyTestResultAnnotation : string = "🔥 Flaky Test Detected: Inconsistent results across multiple runs" + + {static} GetElapsedTime(startingTimestamp:long) : TimeSpan + + {static} GetElapsedTime(startingTimestamp:long, endingTimestamp:long) : TimeSpan +} +class ConsoleLogger <> { + + {static} EnableMarkdownOutput : bool <> <> + + {static} LogInfoRaw(message:object?) : void + + {static} LogInfo(message:object?) : void + + {static} LogPassed(message:object) : void + + {static} LogFailed(message:object) : void +} +class CommandLineOptions <> <> { + + ConcurrencyLevel : int <> <> = 1 + + BuildConfiguration : string <> <> = "Debug" + + Iterations : int <> <> = 3 + + ShowStackTrace : bool <> + + NoClean : bool <> + + ShowWarnings : bool <> + + ConcurrencyLevel : int <> + + Iterations : int <> + + {static} Parse(args:string[], throwOnUnknown:bool) : CommandLineOptions + + <> ToString() : string +} +CommandLineOptions o-> "Verbosity" Verbosity +@enduml +``` +
+ diff --git a/UML/index.html b/UML/index.html new file mode 100644 index 0000000..d805cda --- /dev/null +++ b/UML/index.html @@ -0,0 +1,269 @@ + + + + + + dotnet-diagram + + + +

Generated by dotnet-diagram

+ +
+

FUnit.Directives

+ FUnit.Directives +
+ PlantUML +
@startuml
+left to right direction
+class SR {
+    + <<const>> DirectivePrefix : string = "funit"
+    + <<const>> DiagnosticCategory : string
+}
+SR o-> "MissingFileNameDiagnostic" DiagnosticDescriptor
+SR o-> "IncludedFileNotFoundDiagnostic" DiagnosticDescriptor
+SR o-> "UnknownFUnitDirectiveDiagnostic" DiagnosticDescriptor
+SR o-> "EmptyFUnitDirectiveDiagnostic" DiagnosticDescriptor
+SR o-> "FileExtensionNotSupportedDiagnostic" DiagnosticDescriptor
+SR o-> "DebugDiagnostic" DiagnosticDescriptor
+class FUnitSourceGenerator {
+    + FUnitSourceGenerator()
+    + Initialize(context:GeneratorInitializationContext) : void
+    + Execute(context:GeneratorExecutionContext) : void
+}
+ISourceGenerator <|-- FUnitSourceGenerator
+interface IDirectiveOperator {
+}
+class IncludeOperator {
+    + DirectiveKeyword : string <<get>>
+    + Setup() : void
+    + Cleanup() : void
+    + Apply(args:string, sourceFilePath:string, location:Location) : (string HintName, string? GeneratedCode, ImmutableList<Diagnostic> Diagnostics)
+}
+IDirectiveOperator <|-- IncludeOperator
+@enduml
+
+
+
+

FUnit.Run

+ FUnit.Run +
+ PlantUML +
@startuml
+left to right direction
+class ProcessCallbackCallCounts <<file>> <<sealed>> {
+    + <<volatile>> Error : int
+    + <<volatile>> Stdout : int
+}
+class LogRegex <<static>> <<partial>> {
+    + {static} <<partial>> WarningOrError() : Regex
+}
+class "List`1"<T> {
+}
+class "ValueTask`1"<T> {
+}
+@enduml
+
+
+
+

FUnit

+ FUnit +
+ PlantUML +
@startuml
+left to right direction
+class FUnit <<static>> <<partial>> {
+    + {static} Build(builder:Action<Descriptor>) : TestSuite
+    + {static} Run(args:string[], builder:Action<Descriptor>) : int
+    + {static} <<async>> RunAsync(args:string[], builder:Action<Descriptor>, cancellationToken:CancellationToken) : Task<int>
+}
+class "Action`2"<T1,T2> {
+}
+FUnit --> "Result" TestResult
+class Must <<partial>> {
+    + {static} HaveEqualProperties(expected:TExpected, actual:TActual, propertyNamesToSkip:string[]?, logger:Action<string>?) : void
+    + {static} HaveEqualFields(expected:TExpected, actual:TActual, fieldNamesToSkip:string[]?, logger:Action<string>?) : void
+}
+class Must <<static>> <<partial>> {
+    + {static} BeEqual(expected:T, actual:T, actualExpr:string?) : void
+    + {static} NotBeEqual(expected:T, actual:T, actualExpr:string?) : void
+    + {static} BeSameReference(expected:object, actual:object) : void
+    + {static} NotBeSameReference(expected:object, actual:object) : void
+    + {static} BeTrue(condition:bool, conditionExpr:string?) : void
+    + {static} HaveSameSequence(expected:IEnumerable<T>, actual:IEnumerable<T>) : void
+    + {static} HaveSameSequence(expected:ReadOnlySpan<T>, actual:ReadOnlySpan<T>) : void
+    + {static} HaveSameSequence(expected:ReadOnlySpan<T>, actual:IEnumerable<T>) : void
+    + {static} HaveSameSequence(expected:IEnumerable<T>, actual:ReadOnlySpan<T>) : void
+    + {static} HaveSameSequence(expected:T[], actual:T[]) : void
+    + {static} HaveSameSequence(expected:T[], actual:IEnumerable<T>) : void
+    + {static} HaveSameSequence(expected:IEnumerable<T>, actual:T[]) : void
+    + {static} HaveSameSequence(expected:T[], actual:ReadOnlySpan<T>) : void
+    + {static} HaveSameSequence(expected:ReadOnlySpan<T>, actual:T[]) : void
+    + {static} NotHaveSameSequence(expected:IEnumerable<T>, actual:IEnumerable<T>) : void
+    + {static} NotHaveSameSequence(expected:ReadOnlySpan<T>, actual:ReadOnlySpan<T>) : void
+    + {static} NotHaveSameSequence(expected:ReadOnlySpan<T>, actual:IEnumerable<T>) : void
+    + {static} NotHaveSameSequence(expected:IEnumerable<T>, actual:ReadOnlySpan<T>) : void
+    + {static} NotHaveSameSequence(expected:T[], actual:T[]) : void
+    + {static} NotHaveSameSequence(expected:T[], actual:IEnumerable<T>) : void
+    + {static} NotHaveSameSequence(expected:IEnumerable<T>, actual:T[]) : void
+    + {static} NotHaveSameSequence(expected:T[], actual:ReadOnlySpan<T>) : void
+    + {static} NotHaveSameSequence(expected:ReadOnlySpan<T>, actual:T[]) : void
+    + {static} HaveSameUnorderedElements(expected:IEnumerable<T>, actual:IEnumerable<T>) : void
+    + {static} HaveSameUnorderedElements(expected:ReadOnlySpan<T>, actual:ReadOnlySpan<T>) : void
+    + {static} HaveSameUnorderedElements(expected:ReadOnlySpan<T>, actual:IEnumerable<T>) : void
+    + {static} HaveSameUnorderedElements(expected:IEnumerable<T>, actual:ReadOnlySpan<T>) : void
+    + {static} HaveSameUnorderedElements(expected:T[], actual:T[]) : void
+    + {static} HaveSameUnorderedElements(expected:T[], actual:IEnumerable<T>) : void
+    + {static} HaveSameUnorderedElements(expected:IEnumerable<T>, actual:T[]) : void
+    + {static} HaveSameUnorderedElements(expected:T[], actual:ReadOnlySpan<T>) : void
+    + {static} HaveSameUnorderedElements(expected:ReadOnlySpan<T>, actual:T[]) : void
+    + {static} NotHaveSameUnorderedElements(expected:IEnumerable<T>, actual:IEnumerable<T>) : void
+    + {static} NotHaveSameUnorderedElements(expected:ReadOnlySpan<T>, actual:ReadOnlySpan<T>) : void
+    + {static} NotHaveSameUnorderedElements(expected:ReadOnlySpan<T>, actual:IEnumerable<T>) : void
+    + {static} NotHaveSameUnorderedElements(expected:IEnumerable<T>, actual:ReadOnlySpan<T>) : void
+    + {static} NotHaveSameUnorderedElements(expected:T[], actual:T[]) : void
+    + {static} NotHaveSameUnorderedElements(expected:T[], actual:IEnumerable<T>) : void
+    + {static} NotHaveSameUnorderedElements(expected:IEnumerable<T>, actual:T[]) : void
+    + {static} NotHaveSameUnorderedElements(expected:T[], actual:ReadOnlySpan<T>) : void
+    + {static} NotHaveSameUnorderedElements(expected:ReadOnlySpan<T>, actual:T[]) : void
+    + {static} ContainText(text:string, substring:string) : void
+    + {static} NotContainText(text:string, substring:string) : void
+    + {static} Throw(expectedMessage:string?, testAsync:Func<Task>) : void
+    + {static} Throw(expectedMessage:string?, test:Action) : void
+    + {static} Throw(fullTypeName:string, expectedMessage:string?, testAsync:Func<Task>) : void
+    + {static} Throw(fullTypeName:string, expectedMessage:string?, test:Action) : void
+}
+class FUnit <<partial>> {
+}
+class TestResult <<sealed>> <<partial>> {
+    + <<override>> ToString() : string
+    + ToString(passedColorTag:string, failedColorTag:string, colorResetTag:string) : string
+}
+class Error <<sealed>> <<partial>> <<record>> {
+    + Message : string <<get>> <<init>>
+    + StackTrace : string? <<get>> <<init>>
+    + IsFUnitSystemError : bool <<get>> <<init>>
+    + IsAssertionFailure : bool <<get>> <<init>>
+}
+class Test <<sealed>> <<partial>> <<record>> {
+    + Description : string <<get>> <<init>>
+    + ExecutionCount : int <<get>> <<init>>
+    + Errors : IReadOnlyList<Error>? <<get>> <<init>>
+}
+class "IReadOnlyDictionary`2"<T1,T2> {
+}
+class "IReadOnlyList`1"<T> {
+}
+FUnit +-- TestResult
+TestResult --> "TotalExecutionTime" TimeSpan
+TestResult --> "TestsBySubject<string,IReadOnlyList<Test>>" "IReadOnlyDictionary`2"
+TestResult +-- Error
+TestResult +-- Test
+class FUnit <<partial>> {
+}
+class "Action`2"<T1,T2> {
+}
+class TestSuite <<sealed>> {
+    +  <<event>> OnTestStarting : Action? 
+    +  <<event>> OnTestSubjectStarting : Action<string>? 
+    +  <<event>> OnTestCasePassed : Action<(string subject, string description, int maxIterations, IEnumerable<Exception> errors)>? 
+    +  <<event>> OnTestCaseFailed : Action<(string subject, string description, int maxIterations, IEnumerable<Exception> errors)>? 
+    +  <<event>> OnCanceledExecutionReportStarting : Action? 
+    +  <<event>> OnCanceledExecutionReportTestCase : Action<(string subject, string description)>? 
+    + Execute(subject:string, test:string) : Exception?
+    + <<async>> ExecuteAsync(subject:string, test:string, cancellationToken:CancellationToken) : Task<Exception?>
+    + ExecuteTests(args:string[]) : TestResult
+    + ExecuteTestsAsync(args:string[], cancellationToken:CancellationToken) : Task<TestResult>
+}
+class "IReadOnlyDictionary`2"<T1,T2> {
+}
+FUnit +-- TestSuite
+TestSuite --> "TestsBySubject<string,IReadOnlyList<string>>" "IReadOnlyDictionary`2"
+class IsExternalInit <<static>> {
+}
+class CallerArgumentExpressionAttribute <<sealed>> {
+    + CallerArgumentExpressionAttribute(parameterName:string)
+}
+Attribute <|-- CallerArgumentExpressionAttribute
+class TestCase <<sealed>> {
+    + Subject : string <<get>>
+    + Description : string <<get>>
+    + ExecutionCount : int <<get>>
+    + TestCase(subject:string, description:string, testFunction:Delegate)
+    + <<async>> ExecuteAsync(cancellationToke:CancellationToken) : Task<Exception?>
+}
+class FUnitException {
+    + FUnitException(message:string, inner:Exception?)
+}
+Exception <|-- FUnitException
+enum Verbosity {
+    Quiet=   /**/ -2,
+    Minimal= /**/ -1,
+    Normal=  /**/ 0,
+    Detailed,
+    Diagnostic,
+}
+class SR <<static>> {
+    + <<const>> Flag_Iterations : string = "--iterations"
+    + <<const>> Flag_Concurrency : string = "--concurrency"
+    + <<const>> Flag_MarkdownOutput : string = "--markdown"
+    + <<const>> Flag_MarkdownOutputShort : string = "-md"
+    + <<const>> Flag_TEST : string = "--TEST"
+    + <<const>> Flag_Configuration : string = "--configuration"
+    + <<const>> Flag_ConfigurationShort : string = "-c"
+    + <<const>> Flag_Debug : string = "Debug"
+    + <<const>> Flag_Release : string = "Release"
+    + <<const>> Flag_Delimiter : string = "--"
+    + <<const>> Flag_Help : string = "--help"
+    + <<const>> Flag_HelpShort : string = "-h"
+    + <<const>> Flag_Lint : string = "--lint"
+    + <<const>> Flag_StackTrace : string = "--stacktrace"
+    + <<const>> Flag_NoClean : string = "--no-clean"
+    + <<const>> Flag_Warnings : string = "--warnings"
+    + <<const>> EmojiPassed : string = "✓"
+    + <<const>> EmojiFailed : string = "×"
+    + <<const>> EmojiPassedGitHub : string = "✅"
+    + <<const>> EmojiFailedGitHub : string = "⛔"
+    + <<const>> MarkdownPassed : string
+    + <<const>> MarkdownFailed : string
+    + <<const>> AnsiColorFailed : string = "\u001b[31m"
+    + <<const>> AnsiColorPassed : string = "\u001b[32m"
+    + <<const>> AnsiColorReset : string = "\u001b[0m"
+    + <<const>> MarkdownColorFailed : string = "<span style='color:red'>"
+    + <<const>> MarkdownColorPassed : string = "<span style='color:green'>"
+    + <<const>> MarkdownColorReset : string = "</span>"
+    + <<const>> IndentationAdjustment : int = 6
+    + <<const>> FlakyTestResultAnnotation : string = "🔥 Flaky Test Detected: Inconsistent results across multiple runs"
+    + {static} GetElapsedTime(startingTimestamp:long) : TimeSpan
+    + {static} GetElapsedTime(startingTimestamp:long, endingTimestamp:long) : TimeSpan
+}
+class ConsoleLogger <<static>> {
+    + {static} EnableMarkdownOutput : bool <<get>> <<set>>
+    + {static} LogInfoRaw(message:object?) : void
+    + {static} LogInfo(message:object?) : void
+    + {static} LogPassed(message:object) : void
+    + {static} LogFailed(message:object) : void
+}
+class CommandLineOptions <<sealed>> <<record>> {
+    + ConcurrencyLevel : int <<get>> <<init>> = 1
+    + BuildConfiguration : string <<get>> <<init>> = "Debug"
+    + Iterations : int <<get>> <<init>> = 3
+    + ShowStackTrace : bool <<get>>
+    + NoClean : bool <<get>>
+    + ShowWarnings : bool <<get>>
+    + ConcurrencyLevel : int <<get>>
+    + Iterations : int <<get>>
+    + {static} Parse(args:string[], throwOnUnknown:bool) : CommandLineOptions
+    + <<override>> ToString() : string
+}
+CommandLineOptions o-> "Verbosity" Verbosity
+@enduml
+
+
+ +