From 1d25cfaa61b9a02d65c7df6832a9b8eecde97308 Mon Sep 17 00:00:00 2001 From: Pawel Gerr Date: Mon, 9 Sep 2024 08:07:15 +0200 Subject: [PATCH] Args of switch/map must be named. --- .../DiscriminatedUnionsDemos.cs | 40 +- .../ThinktectureRuntimeExtensionsAnalyzer.cs | 58 +- .../CodeAnalysis/DiagnosticsDescriptors.cs | 2 +- .../Extensions/TypeSymbolExtensions.cs | 9 + ...BasedSwitchAndMapMustUseNamedParameters.cs | 3197 ++++++++++------- 5 files changed, 2060 insertions(+), 1246 deletions(-) diff --git a/samples/Thinktecture.Runtime.Extensions.Samples/DiscriminatedUnions/DiscriminatedUnionsDemos.cs b/samples/Thinktecture.Runtime.Extensions.Samples/DiscriminatedUnions/DiscriminatedUnionsDemos.cs index dcbf97ff..6007284c 100644 --- a/samples/Thinktecture.Runtime.Extensions.Samples/DiscriminatedUnions/DiscriminatedUnionsDemos.cs +++ b/samples/Thinktecture.Runtime.Extensions.Samples/DiscriminatedUnions/DiscriminatedUnionsDemos.cs @@ -30,24 +30,44 @@ public static void Demo(ILogger logger) logger.Information("TextOrNumber from string: Value = {Value}", textOrNumberFromString.Value); logger.Information("TextOrNumber from int: Value = {Value}", textOrNumberFromInt.Value); - textOrNumberFromString.Switch(text: s => logger.Information("String Action: {Text}", s), - number: i => logger.Information("Int Action: {Number}", i)); + textOrNumberFromString.Switch(text: s => logger.Information("[Switch] String Action: {Text}", s), + number: i => logger.Information("[Switch] Int Action: {Number}", i)); + + textOrNumberFromString.SwitchPartially(@default: i => logger.Information("[SwitchPartially] Default Action: {Number}", i), + text: s => logger.Information("[SwitchPartially] String Action: {Text}", s)); textOrNumberFromString.Switch(logger, - text: static (l, s) => l.Information("String Action with context: {Text}", s), - number: static (l, i) => l.Information("Int Action with context: {Number}", i)); + text: static (l, s) => l.Information("[Switch] String Action with context: {Text}", s), + number: static (l, i) => l.Information("[Switch] Int Action with context: {Number}", i)); + + textOrNumberFromString.SwitchPartially(logger, + @default: static (l, i) => l.Information("[SwitchPartially] Default Action with context: {Number}", i), + text: static (l, s) => l.Information("[SwitchPartially] String Action with context: {Text}", s)); - var switchResponse = textOrNumberFromInt.Switch(text: static s => $"String Func: {s}", - number: static i => $"Int Func: {i}"); + var switchResponse = textOrNumberFromInt.Switch(text: static s => $"[Switch] String Func: {s}", + number: static i => $"[Switch] Int Func: {i}"); logger.Information("{Response}", switchResponse); + var switchPartiallyResponse = textOrNumberFromInt.SwitchPartially(@default: static i => $"[SwitchPartially] Default Func: {i}", + text: static s => $"[SwitchPartially] String Func: {s}"); + logger.Information("{Response}", switchPartiallyResponse); + var switchResponseWithContext = textOrNumberFromInt.Switch(123.45, - text: static (ctx, s) => $"String Func with context: {ctx} | {s}", - number: static (ctx, i) => $"Int Func with context: {ctx} | {i}"); + text: static (ctx, s) => $"[Switch] String Func with context: {ctx} | {s}", + number: static (ctx, i) => $"[Switch] Int Func with context: {ctx} | {i}"); logger.Information("{Response}", switchResponseWithContext); - var mapResponse = textOrNumberFromString.Map(text: "Mapped string", - number: "Mapped int"); + var switchPartiallyResponseWithContext = textOrNumberFromInt.SwitchPartially(123.45, + text: static (ctx, s) => $"[SwitchPartially] String Func with context: {ctx} | {s}", + @default: static (ctx, i) => $"[SwitchPartially] Default Func with context: {ctx} | {i}"); + logger.Information("{Response}", switchPartiallyResponseWithContext); + + var mapResponse = textOrNumberFromString.Map(text: "[Map] Mapped string", + number: "[Map] Mapped int"); logger.Information("{Response}", mapResponse); + + var mapPartiallyResponse = textOrNumberFromString.MapPartially(@default: "[MapPartially] Mapped default", + text: "[MapPartially] Mapped string"); + logger.Information("{Response}", mapPartiallyResponse); } } diff --git a/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/Diagnostics/ThinktectureRuntimeExtensionsAnalyzer.cs b/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/Diagnostics/ThinktectureRuntimeExtensionsAnalyzer.cs index 06ec648f..64c2e605 100644 --- a/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/Diagnostics/ThinktectureRuntimeExtensionsAnalyzer.cs +++ b/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/Diagnostics/ThinktectureRuntimeExtensionsAnalyzer.cs @@ -72,32 +72,64 @@ private static void AnalyzeMethodCall(OperationAnalysisContext context) return; } - if (!operation.Instance.Type.IsEnum(out var attribute)) - return; - - var isValidatable = attribute.FindIsValidatable() ?? false; - var nonIgnoredMembers = operation.Instance.Type.GetNonIgnoredMembers(); - var items = operation.Instance.Type.GetEnumItems(nonIgnoredMembers); - var args = operation.Arguments; + if (operation.Instance.Type.IsEnum(out var attribute)) + { + var isValidatable = attribute.FindIsValidatable() ?? false; + var nonIgnoredMembers = operation.Instance.Type.GetNonIgnoredMembers(); + var items = operation.Instance.Type.GetEnumItems(nonIgnoredMembers); - AnalyzeIndexBasedSwitchMap(context, items, args, operation, isValidatable); + AnalyzeEnumSwitchMap(context, + items, + operation.Arguments, + operation, + isValidatable); + } + else if (operation.Instance.Type.IsUnionAttribute(out attribute) + && attribute.AttributeClass is not null) + { + AnalyzeUnionSwitchMap(context, + attribute.AttributeClass.TypeArguments, + operation.Arguments, + operation); + } } - private static void AnalyzeIndexBasedSwitchMap( + private static void AnalyzeEnumSwitchMap( OperationAnalysisContext context, ImmutableArray items, ImmutableArray args, IInvocationOperation operation, bool isValidatable) { - // The enum must have a type + var numberOfCallbacks = items.Length + + (isValidatable ? 1 : 0) + + (operation.TargetMethod.Name is _SWITCH_PARTIALLY or _MAP_PARTIALLY ? 1 : 0); + + AnalyzeSwitchMap(context, args, operation, numberOfCallbacks); + } + + private static void AnalyzeUnionSwitchMap( + OperationAnalysisContext context, + ImmutableArray memberTypes, + ImmutableArray args, + IInvocationOperation operation) + { + var numberOfCallbacks = memberTypes.Length + + (operation.TargetMethod.Name is _SWITCH_PARTIALLY or _MAP_PARTIALLY ? 1 : 0); + + AnalyzeSwitchMap(context, args, operation, numberOfCallbacks); + } + + private static void AnalyzeSwitchMap( + OperationAnalysisContext context, + ImmutableArray args, + IInvocationOperation operation, + int numberOfCallbacks) + { if (operation.Instance?.Type is null || args.IsDefaultOrEmpty) return; var hasNonNamedParameters = false; - var numberOfCallbacks = items.Length - + (isValidatable ? 1 : 0) - + (operation.TargetMethod.Name is _SWITCH_PARTIALLY or _MAP_PARTIALLY ? 1 : 0); var argsStartIndex = operation.TargetMethod.Parameters.Length == numberOfCallbacks ? 0 : 1; for (var argIndex = argsStartIndex; argIndex < args.Length; argIndex++) diff --git a/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/DiagnosticsDescriptors.cs b/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/DiagnosticsDescriptors.cs index b51fa34e..29d67335 100644 --- a/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/DiagnosticsDescriptors.cs +++ b/src/Thinktecture.Runtime.Extensions.SourceGenerator/CodeAnalysis/DiagnosticsDescriptors.cs @@ -28,7 +28,7 @@ internal static class DiagnosticsDescriptors public static readonly DiagnosticDescriptor PrimaryConstructorNotAllowed = new("TTRESG043", "Primary constructor is not allowed in Smart Enums and Value Objects", "Primary constructor is not allowed in Smart Enum/Value Object of type '{0}'", nameof(ThinktectureRuntimeExtensionsAnalyzer), DiagnosticSeverity.Error, true); public static readonly DiagnosticDescriptor CustomKeyMemberImplementationNotFound = new("TTRESG044", "Custom implementation of the key member not found", $"Provide a custom implementation of the key member. Implement a field or property '{{0}}'. Use '{Constants.Attributes.Properties.KEY_MEMBER_NAME}' to change the name.", nameof(ThinktectureRuntimeExtensionsAnalyzer), DiagnosticSeverity.Error, true); public static readonly DiagnosticDescriptor CustomKeyMemberImplementationTypeMismatch = new("TTRESG045", "Key member type mismatch", "The type of the key member '{0}' must be '{2}' instead of '{1}'", nameof(ThinktectureRuntimeExtensionsAnalyzer), DiagnosticSeverity.Error, true); - public static readonly DiagnosticDescriptor IndexBasedSwitchAndMapMustUseNamedParameters = new("TTRESG046", "The arguments of \"Switch\" and \"Map\" must named", "Not all arguments of \"Switch/Map\" on the enumeration '{0}' are named", nameof(ThinktectureRuntimeExtensionsAnalyzer), DiagnosticSeverity.Error, true); + public static readonly DiagnosticDescriptor IndexBasedSwitchAndMapMustUseNamedParameters = new("TTRESG046", "The arguments of \"Switch\" and \"Map\" must named", "Not all arguments of \"Switch/Map\" on type '{0}' are named", nameof(ThinktectureRuntimeExtensionsAnalyzer), DiagnosticSeverity.Error, true); public static readonly DiagnosticDescriptor TypeMustBeClass = new("TTRESG047", "The type must be a class", "The type '{0}' must be a class", nameof(ThinktectureRuntimeExtensionsAnalyzer), DiagnosticSeverity.Error, true); public static readonly DiagnosticDescriptor ErrorDuringCodeAnalysis = new("TTRESG098", "Error during code analysis", "Error during code analysis of '{0}': '{1}'", nameof(ThinktectureRuntimeExtensionsAnalyzer), DiagnosticSeverity.Warning, true); diff --git a/src/Thinktecture.Runtime.Extensions.SourceGenerator/Extensions/TypeSymbolExtensions.cs b/src/Thinktecture.Runtime.Extensions.SourceGenerator/Extensions/TypeSymbolExtensions.cs index dfd4c51f..cdfcac3b 100644 --- a/src/Thinktecture.Runtime.Extensions.SourceGenerator/Extensions/TypeSymbolExtensions.cs +++ b/src/Thinktecture.Runtime.Extensions.SourceGenerator/Extensions/TypeSymbolExtensions.cs @@ -53,6 +53,15 @@ public static bool IsUnionAttribute(this ITypeSymbol? attributeType) return attributeType is { Name: Constants.Attributes.Union.NAME, ContainingNamespace: { Name: Constants.Attributes.Union.NAMESPACE, ContainingNamespace.IsGlobalNamespace: true } }; } + public static bool IsUnionAttribute( + [NotNullWhen(true)] this ITypeSymbol? unionType, + [NotNullWhen(true)] out AttributeData? unionAttribute) + { + unionAttribute = unionType?.FindAttribute(static attributeClass => attributeClass.IsUnionAttribute()); + + return unionAttribute is not null; + } + public static bool IsValueObjectMemberEqualityComparerAttribute(this ITypeSymbol? attributeType) { if (attributeType is null || attributeType.TypeKind == TypeKind.Error) diff --git a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/AnalyzerAndCodeFixTests/TTRESG046_IndexBasedSwitchAndMapMustUseNamedParameters.cs b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/AnalyzerAndCodeFixTests/TTRESG046_IndexBasedSwitchAndMapMustUseNamedParameters.cs index b328184a..11a9c895 100644 --- a/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/AnalyzerAndCodeFixTests/TTRESG046_IndexBasedSwitchAndMapMustUseNamedParameters.cs +++ b/test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/AnalyzerAndCodeFixTests/TTRESG046_IndexBasedSwitchAndMapMustUseNamedParameters.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Thinktecture.Runtime.Tests.TestEnums; +using Thinktecture.Runtime.Tests.TestUnions; using Verifier = Thinktecture.Runtime.Tests.Verifiers.CodeFixVerifier; namespace Thinktecture.Runtime.Tests.AnalyzerAndCodeFixTests; @@ -9,1786 +10,2538 @@ public class TTRESG046_IndexBasedSwitchAndMapMustUseNamedParameters { private const string _DIAGNOSTIC_ID = "TTRESG046"; - public class SwitchWithAction + public class SmartEnum { - [Fact] - public async Task Should_trigger_without_named_arg() + public class SwitchWithAction { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; - {|#0:testEnum.Switch(item1: () => {}, - () => {})|}; + {|#0:testEnum.Switch(item1: () => {}, + () => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - {|#0:testEnum.Switch(item => {}, // invalid item callback - item1: () => {}, - item2: () => {})|}; + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.Switch(item => {}, // invalid item callback + item1: () => {}, + item2: () => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - {|#0:testEnum.Switch(invalid: item => {}, - () => {}, - item2: () => {})|}; + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.Switch(invalid: item => {}, + () => {}, + item2: () => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; - {|#0:testEnum.Switch(item1: () => {}, - item2: () => {})|}; + {|#0:testEnum.Switch(item1: () => {}, + item2: () => {})|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); - } + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - {|#0:testEnum.Switch(invalid: item => {}, - item1: () => {}, - item2: () => {})|}; + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.Switch(invalid: item => {}, + item1: () => {}, + item2: () => {})|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }); + } } - } - public class SwitchPartiallyWithAction - { - [Fact] - public async Task Should_trigger_without_named_arg() + public class SwitchPartiallyWithAction { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; - - {|#0:testEnum.SwitchPartially(@default: item => {}, - item1: () => {}, - () => {})|}; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + {|#0:testEnum.SwitchPartially(@default: item => {}, + item1: () => {}, + () => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_default_arg() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_default_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; - - {|#0:testEnum.SwitchPartially(value => {}, // default - item1: () => {}, - item2: () => {})|}; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + {|#0:testEnum.SwitchPartially(value => {}, // default + item1: () => {}, + item2: () => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - {|#0:testEnum.SwitchPartially(item => {}, // invalid item callback - item1: () => {}, - item2: () => {})|}; + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.SwitchPartially(item => {}, // invalid item callback + item1: () => {}, + item2: () => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - {|#0:testEnum.SwitchPartially(@default: value => {}, - invalid: item => {}, - () => {}, - item2: () => {})|}; + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.SwitchPartially(@default: value => {}, + invalid: item => {}, + () => {}, + item2: () => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_default_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_default_arg_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - {|#0:testEnum.SwitchPartially(value => {}, // default - invalid: item => {}, - item1: () => {}, - item2: () => {})|}; + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.SwitchPartially(value => {}, // default + invalid: item => {}, + item1: () => {}, + item2: () => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + {|#0:testEnum.SwitchPartially(@default: value => {}, + item1: () => {}, + item2: () => {})|}; + } + } + } + """; + + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } + + [Fact] + public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - {|#0:testEnum.SwitchPartially(@default: value => {}, - item1: () => {}, - item2: () => {})|}; + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.SwitchPartially(@default: value => {}, + invalid: item => {}, + item1: () => {}, + item2: () => {})|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }); + } } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() + public class SwitchWithActionAndContext { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - {|#0:testEnum.SwitchPartially(@default: value => {}, - invalid: item => {}, - item1: () => {}, - item2: () => {})|}; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + {|#0:testEnum.Switch(42, + item1: value => {}, + value => {})|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }); - } - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } - public class SwitchWithActionAndContext - { - [Fact] - public async Task Should_trigger_without_named_arg() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.Switch(42, + (value, item) => {}, // invalid item callback + item1: value => {}, + item2: value => {})|}; + } + } + } + """; - {|#0:testEnum.Switch(42, - item1: value => {}, - value => {})|}; + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } + + [Fact] + public async Task Should_trigger_without_named_arg_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.Switch(42, + invalid: (value, item) => {}, + value => {}, + item2: value => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + {|#0:testEnum.Switch(42, + item1: i => {}, + item2: i => {})|}; + } + } + } + """; + + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } - {|#0:testEnum.Switch(42, - (value, item) => {}, // invalid item callback - item1: value => {}, - item2: value => {})|}; + [Fact] + public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.Switch(42, + invalid: (value, item) => {}, + item1: value => {}, + item2: value => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }); + } } - [Fact] - public async Task Should_trigger_without_named_arg_having_validatable_enum() + public class SwitchPartiallyWithActionAndContext { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - {|#0:testEnum.Switch(42, - invalid: (value, item) => {}, - value => {}, - item2: value => {})|}; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + {|#0:testEnum.SwitchPartially(42, + @default: (ctx, value) => {}, + item1: value => {}, + value => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_default_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + {|#0:testEnum.SwitchPartially(42, + (ctx, value) => {}, // default + item1: value => {}, + item2: value => {})|}; + } + } + } + """; - {|#0:testEnum.Switch(42, - item1: i => {}, - item2: i => {})|}; + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } + + [Fact] + public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.SwitchPartially(42, + (value, item) => {}, // invalid item callback + item1: value => {}, + item2: value => {})|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.SwitchPartially(42, + @default: (value, item) => {}, + invalid: (value, item) => {}, + value => {}, + item2: value => {})|}; + } + } + } + """; - {|#0:testEnum.Switch(42, - invalid: (value, item) => {}, - item1: value => {}, - item2: value => {})|}; + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } + + [Fact] + public async Task Should_trigger_without_named_default_arg_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.SwitchPartially(42, + (value, item) => {}, // default + invalid: (value, item) => {}, + item1: value => {}, + item2: value => {})|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }); - } - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - public class SwitchPartiallyWithActionAndContext - { - [Fact] - public async Task Should_trigger_without_named_arg() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + {|#0:testEnum.SwitchPartially(42, + @default: (value, item) => {}, + item1: i => {}, + item2: i => {})|}; + } + } + } + """; + + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } + + [Fact] + public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - {|#0:testEnum.SwitchPartially(42, - @default: (ctx, value) => {}, - item1: value => {}, - value => {})|}; + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + {|#0:testEnum.SwitchPartially(42, + @default: (value, item) => {}, + invalid: (value, item) => {}, + item1: value => {}, + item2: value => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }); + } } - [Fact] - public async Task Should_trigger_without_named_default_arg() + public class SwitchWithFunc { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; - {|#0:testEnum.SwitchPartially(42, - (ctx, value) => {}, // default - item1: value => {}, - item2: value => {})|}; + var returnValue = {|#0:testEnum.Switch(item1: () => 1, + () => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.Switch(item => 0, + item1: () => 1, + item2: () => 2)|}; + } + } + } + """; + + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } + + [Fact] + public async Task Should_trigger_without_named_arg_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - {|#0:testEnum.SwitchPartially(42, - (value, item) => {}, // invalid item callback - item1: value => {}, - item2: value => {})|}; + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.Switch(invalid: item => 0, + () => 1, + item2: () => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; - {|#0:testEnum.SwitchPartially(42, - @default: (value, item) => {}, - invalid: (value, item) => {}, - value => {}, - item2: value => {})|}; + var returnValue = {|#0:testEnum.Switch(item1: () => 1, + item2: () => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } - [Fact] - public async Task Should_trigger_without_named_default_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - {|#0:testEnum.SwitchPartially(42, - (value, item) => {}, // default - invalid: (value, item) => {}, - item1: value => {}, - item2: value => {})|}; + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.Switch(invalid: item => 0, + item1: () => 1, + item2: () => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named() + public class SwitchPartiallyWithFunc { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; - - {|#0:testEnum.SwitchPartially(42, - @default: (value, item) => {}, - item1: i => {}, - item2: i => {})|}; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(@default: value => 0, + item1: () => 1, + () => 2)|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_default_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(value => 0, // default + item1: () => 1, + item2: () => 2)|}; + } + } + } + """; + + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } + + [Fact] + public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() + { + var code = """ - {|#0:testEnum.SwitchPartially(42, - @default: (value, item) => {}, - invalid: (value, item) => {}, - item1: value => {}, - item2: value => {})|}; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(@default: item => 0, + item => -1, // invalid + item1: () => 1, + item2: () => 2)|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }); - } - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - public class SwitchWithFunc - { - [Fact] - public async Task Should_trigger_without_named_arg() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(@default: item => 0, + invalid: item => -1, + () => 1, + item2: () => 2)|}; + } + } + } + """; - var returnValue = {|#0:testEnum.Switch(item1: () => 1, - () => 2)|}; + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } + + [Fact] + public async Task Should_trigger_without_named_default_arg_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(item => 0, + invalid: item => -1, + item1: () => 1, + item2: () => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(@default: item => 0, + item1: () => 1, + item2: () => 2)|}; + } + } + } + """; - var returnValue = {|#0:testEnum.Switch(item => 0, - item1: () => 1, - item2: () => 2)|}; + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } + + [Fact] + public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(@default: item => 0, + invalid: item => -1, + item1: () => 1, + item2: () => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } } - [Fact] - public async Task Should_trigger_without_named_arg_having_validatable_enum() + public class SwitchWithFuncAndContext { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - var returnValue = {|#0:testEnum.Switch(invalid: item => 0, - () => 1, - item2: () => 2)|}; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + var returnValue = {|#0:testEnum.Switch(42, + item1: i => 1, + i => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.Switch(42, + (value, item) => 0, + item1: value => 1, + item2: value => 2)|}; + } + } + } + """; + + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } + + [Fact] + public async Task Should_trigger_without_named_arg_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - var returnValue = {|#0:testEnum.Switch(item1: () => 1, - item2: () => 2)|}; + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.Switch(42, + invalid: (value, item) => 0, + value => 1, + item2: value => 2)|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + var returnValue = {|#0:testEnum.Switch(42, + item1: i => 1, + item2: i => 2)|}; + } + } + } + """; + + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } + + [Fact] + public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - var returnValue = {|#0:testEnum.Switch(invalid: item => 0, - item1: () => 1, - item2: () => 2)|}; + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.Switch(42, + invalid: (value, item) => 0, + item1: value => 1, + item2: value => 2)|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } } - } - public class SwitchPartiallyWithFunc - { - [Fact] - public async Task Should_trigger_without_named_arg() + public class SwitchPartiallyWithFuncAndContext { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; - - var returnValue = {|#0:testEnum.SwitchPartially(@default: value => 0, - item1: () => 1, - () => 2)|}; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(42, + @default: (value, item) => 0, + item1: i => 1, + i => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_default_arg() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_default_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(42, + (value, item) => 0, // default + item1: i => 1, + item2: i => 2)|}; + } + } + } + """; + + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } - var returnValue = {|#0:testEnum.SwitchPartially(value => 0, // default - item1: () => 1, - item2: () => 2)|}; + [Fact] + public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(42, + (value, item) => 0, + item1: value => 1, + item2: value => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(42, + @default: (value, item) => 0, + invalid: (value, item) => -1, + value => 1, + item2: value => 2)|}; + } + } + } + """; + + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - var returnValue = {|#0:testEnum.SwitchPartially(@default: item => 0, - item => -1, // invalid - item1: () => 1, - item2: () => 2)|}; + [Fact] + public async Task Should_trigger_without_named_default_arg_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(42, + (value, item) => 0, // default + invalid: (value, item) => -1, + item1: value => 1, + item2: value => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(42, + @default: (value, item) => 0, + item1: i => 1, + item2: i => 2)|}; + } + } + } + """; + + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } - var returnValue = {|#0:testEnum.SwitchPartially(@default: item => 0, - invalid: item => -1, - () => 1, - item2: () => 2)|}; + [Fact] + public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.SwitchPartially(42, + @default: (value, item) => 0, + invalid: (value, item) => -1, + item1: value => 1, + item2: value => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } } - [Fact] - public async Task Should_trigger_without_named_default_arg_having_validatable_enum() + public class Map { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; - var returnValue = {|#0:testEnum.SwitchPartially(item => 0, - invalid: item => -1, - item1: () => 1, - item2: () => 2)|}; + var returnValue = {|#0:testEnum.Map(item1: 1, + 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.Map(0, + item1: 1, + item2: 2)|}; + } + } + } + """; + + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - var returnValue = {|#0:testEnum.SwitchPartially(@default: item => 0, - item1: () => 1, - item2: () => 2)|}; + [Fact] + public async Task Should_trigger_without_named_arg_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.Map(invalid: 0, + 1, + item2: 2)|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; - var returnValue = {|#0:testEnum.SwitchPartially(@default: item => 0, - invalid: item => -1, - item1: () => 1, - item2: () => 2)|}; + var returnValue = {|#0:testEnum.Map(item1: 1, + item2: 2)|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); - } - } + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } - public class SwitchWithFuncAndContext - { - [Fact] - public async Task Should_trigger_without_named_arg() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; - - var returnValue = {|#0:testEnum.Switch(42, - item1: i => 1, - i => 2)|}; + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.Map(invalid: 0, + item1: 1, + item2: 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } } - [Fact] - public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() + public class MapPartially { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - var returnValue = {|#0:testEnum.Switch(42, - (value, item) => 0, - item1: value => 1, - item2: value => 2)|}; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + var returnValue = {|#0:testEnum.MapPartially(@default: 0, + item1: 1, + 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_default_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + var returnValue = {|#0:testEnum.MapPartially(0, // default + item1: 1, + item2: 2)|}; + } + } + } + """; + + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + } + + [Fact] + public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - var returnValue = {|#0:testEnum.Switch(42, - invalid: (value, item) => 0, - value => 1, - item2: value => 2)|}; + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.MapPartially(@default: 0, + -1, // invalid + item1: 1, + item2: 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_default_arg_having_validatable_enum() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.MapPartially(0, // default + invalid: -1, + item1: 1, + item2: 2)|}; + } + } + } + """; + + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } + + [Fact] + public async Task Should_trigger_without_named_arg_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - var returnValue = {|#0:testEnum.Switch(42, - item1: i => 1, - item2: i => 2)|}; + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.MapPartially(@default: 0, + invalid: -1, + 1, + item2: 2)|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testEnum = ValidTestEnum.Item1; + + var returnValue = {|#0:testEnum.MapPartially( + @default: 0, + item1: 1, + item2: 2)|}; + } + } + } + """; + + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } + + [Fact] + public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestEnums; - var returnValue = {|#0:testEnum.Switch(42, - invalid: (value, item) => 0, - item1: value => 1, - item2: value => 2)|}; + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testEnum = TestEnum.Item1; + + var returnValue = {|#0:testEnum.MapPartially( + @default: 0, + invalid: -1, + item1: 1, + item2: 2)|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + } } } - public class SwitchPartiallyWithFuncAndContext + public class Union { - [Fact] - public async Task Should_trigger_without_named_arg() + public class SwitchWithAction { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); - var returnValue = {|#0:testEnum.SwitchPartially(42, - @default: (value, item) => 0, - item1: i => 1, - i => 2)|}; + {|#0:testUnion.Switch(@string: s => {}, + i => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_default_arg() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); - var returnValue = {|#0:testEnum.SwitchPartially(42, - (value, item) => 0, // default - item1: i => 1, - item2: i => 2)|}; + {|#0:testUnion.Switch(@string: s => {}, + int32: i => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }); + } } - [Fact] - public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() + public class SwitchPartiallyWithAction { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - var returnValue = {|#0:testEnum.SwitchPartially(42, - (value, item) => 0, - item1: value => 1, - item2: value => 2)|}; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + {|#0:testUnion.SwitchPartially(@default: item => {}, + @string: s => {}, + i => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_default_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - var returnValue = {|#0:testEnum.SwitchPartially(42, - @default: (value, item) => 0, - invalid: (value, item) => -1, - value => 1, - item2: value => 2)|}; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + {|#0:testUnion.SwitchPartially(item => {}, + @string: s => {}, + int32: i => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_default_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - var returnValue = {|#0:testEnum.SwitchPartially(42, - (value, item) => 0, // default - invalid: (value, item) => -1, - item1: value => 1, - item2: value => 2)|}; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + {|#0:testUnion.SwitchPartially(@default: item => {}, + @string: s => {}, + int32: i => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }); + } } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named() + public class SwitchWithActionAndContext { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + {|#0:testUnion.Switch(42, + @string: (ctx, s) => {}, + (ctx, i) => {})|}; + } + } + } + """; + + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } + + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - var returnValue = {|#0:testEnum.SwitchPartially(42, - @default: (value, item) => 0, - item1: i => 1, - item2: i => 2)|}; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + {|#0:testUnion.Switch(42, + @string: (ctx, s) => {}, + int32: (ctx, i) => {})|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }); + } } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() + public class SwitchPartiallyWithActionAndContext { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; - - var returnValue = {|#0:testEnum.SwitchPartially(42, - @default: (value, item) => 0, - invalid: (value, item) => -1, - item1: value => 1, - item2: value => 2)|}; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + {|#0:testUnion.SwitchPartially(42, + @default: (ctx, value) => {}, + @string: (ctx, s) => {}, + (ctx, i) => {})|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); - } - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } - public class Map - { - [Fact] - public async Task Should_trigger_without_named_arg() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_default_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + {|#0:testUnion.SwitchPartially(42, + (ctx, value) => {}, // default + @string: (ctx, s) => {}, + int32: (ctx, i) => {})|}; + } + } + } + """; + + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } + + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - var returnValue = {|#0:testEnum.Map(item1: 1, - 2)|}; + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + {|#0:testUnion.SwitchPartially(42, + @default: (ctx, value) => {}, + @string: (ctx, s) => {}, + int32: (ctx, i) => {})|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }); + } } - [Fact] - public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() + public class SwitchWithFunc { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); - var returnValue = {|#0:testEnum.Map(0, - item1: 1, - item2: 2)|}; + var returnValue = {|#0:testUnion.Switch(@string: s => 1, + i => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); - var returnValue = {|#0:testEnum.Map(invalid: 0, - 1, - item2: 2)|}; + var returnValue = {|#0:testUnion.Switch(@string: s => 1, + int32: i => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }); + } } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named() + public class SwitchPartiallyWithFunc { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; - - var returnValue = {|#0:testEnum.Map(item1: 1, - item2: 2)|}; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + var returnValue = {|#0:testUnion.SwitchPartially(@default: value => 0, + @string: s => 1, + i => 2)|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_default_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + var returnValue = {|#0:testUnion.SwitchPartially(value => 0, // default + @string: s => 1, + int32: i => 2)|}; + } + } + } + """; - var returnValue = {|#0:testEnum.Map(invalid: 0, - item1: 1, - item2: 2)|}; + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } + + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + var returnValue = {|#0:testUnion.SwitchPartially(@default: item => 0, + @string: s => 1, + int32: i => 2)|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }); + } } - } - public class MapPartially - { - [Fact] - public async Task Should_trigger_without_named_arg() + public class SwitchWithFuncAndContext { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + var returnValue = {|#0:testUnion.Switch(42, + @string: (ctx, s) => 1, + (ctx, i) => 2)|}; + } + } + } + """; - var returnValue = {|#0:testEnum.MapPartially(@default: 0, - item1: 1, - 2)|}; + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } + + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + var returnValue = {|#0:testUnion.Switch(42, + @string: (ctx, s) => 1, + int32: (ctx, i) => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }); + } } - [Fact] - public async Task Should_trigger_without_named_default_arg() + public class SwitchPartiallyWithFuncAndContext { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; - - var returnValue = {|#0:testEnum.MapPartially(0, // default - item1: 1, - item2: 2)|}; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + var returnValue = {|#0:testUnion.SwitchPartially(42, + @default: (ctx, value) => 0, + @string: (ctx, s) => 1, + (ctx, i) => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(ValidTestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_invalid_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_default_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + var returnValue = {|#0:testUnion.SwitchPartially(42, + (ctx, value) => 0, // default + @string: (ctx, s) => 1, + int32: (ctx, i) => 2)|}; + } + } + } + """; + + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } + + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - var returnValue = {|#0:testEnum.MapPartially(@default: 0, - -1, // invalid - item1: 1, - item2: 2)|}; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + var returnValue = {|#0:testUnion.SwitchPartially(42, + @default: (ctx, value) => 0, + @string: (ctx, s) => 1, + int32: (ctx, i) => 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }); + } } - [Fact] - public async Task Should_trigger_without_named_default_arg_having_validatable_enum() + public class Map { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); - var returnValue = {|#0:testEnum.MapPartially(0, // default - invalid: -1, - item1: 1, - item2: 2)|}; + var returnValue = {|#0:testUnion.Map(@string: 1, + 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } - [Fact] - public async Task Should_trigger_without_named_arg_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); - var returnValue = {|#0:testEnum.MapPartially(@default: 0, - invalid: -1, - 1, - item2: 2)|}; + var returnValue = {|#0:testUnion.Map(@string: 1, + int32: 2)|}; + } } } - } - """; + """; - var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestEnum)); - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(TestEnum).Assembly }, expected); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }); + } } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named() + public class MapPartially { - var code = """ + [Fact] + public async Task Should_trigger_without_named_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = ValidTestEnum.Item1; - - var returnValue = {|#0:testEnum.MapPartially( - @default: 0, - item1: 1, - item2: 2)|}; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + var returnValue = {|#0:testUnion.MapPartially(@default: 0, + @string: 1, + 2)|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); - } + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } - [Fact] - public async Task Should_not_trigger_when_all_args_are_named_having_validatable_enum() - { - var code = """ + [Fact] + public async Task Should_trigger_without_named_default_arg() + { + var code = """ - using System; - using Thinktecture; - using Thinktecture.Runtime.Tests.TestEnums; + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; - namespace TestNamespace - { - public class Test + namespace TestNamespace { - public void Do() + public class Test { - var testEnum = TestEnum.Item1; + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + var returnValue = {|#0:testUnion.MapPartially(0, // default + @string: 1, + int32: 2)|}; + } + } + } + """; + + var expected = Verifier.Diagnostic(_DIAGNOSTIC_ID).WithLocation(0).WithArguments(nameof(TestUnion_class_string_int)); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }, expected); + } - var returnValue = {|#0:testEnum.MapPartially( - @default: 0, - invalid: -1, - item1: 1, - item2: 2)|}; + [Fact] + public async Task Should_not_trigger_when_all_args_are_named() + { + var code = """ + + using System; + using Thinktecture; + using Thinktecture.Runtime.Tests.TestUnions; + + namespace TestNamespace + { + public class Test + { + public void Do() + { + var testUnion = new TestUnion_class_string_int("text"); + + var returnValue = {|#0:testUnion.MapPartially( + @default: 0, + @string: 1, + int32: 2)|}; + } } } - } - """; + """; - await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(ComplexValueObjectAttribute).Assembly, typeof(ValidTestEnum).Assembly }); + await Verifier.VerifyAnalyzerAsync(code, new[] { typeof(UnionAttribute<,>).Assembly, typeof(TestUnion_class_string_int).Assembly }); + } } } }