From 217f5d1862d62c068c0269e2a919d19c2da601b2 Mon Sep 17 00:00:00 2001 From: Andrew Lock Date: Wed, 27 Dec 2023 21:03:15 +0000 Subject: [PATCH] Add more tests --- ...nverterIdInDifferentNamespace.verified.txt | 271 +++++++++ ...verterIdInFileScopedNamespace.verified.txt | 271 +++++++++ ...DefaultConverterIdInNamespace.verified.txt | 271 +++++++++ ...ultipleConvertersWithSameName.verified.txt | 314 +++++++++++ ...eNestedIdInFileScopeNamespace.verified.txt | 277 +++++++++ ...DefaultConverterIdInNamespace.verified.txt | 286 ++++++++++ .../StronglyTypedIdConverterTests.cs | 532 ++++++++---------- 7 files changed, 1923 insertions(+), 299 deletions(-) create mode 100644 test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateDefaultConverterIdInDifferentNamespace.verified.txt create mode 100644 test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateDefaultConverterIdInFileScopedNamespace.verified.txt create mode 100644 test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateDefaultConverterIdInNamespace.verified.txt create mode 100644 test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateMultipleConvertersWithSameName.verified.txt create mode 100644 test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateNestedIdInFileScopeNamespace.verified.txt create mode 100644 test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateNonDefaultConverterIdInNamespace.verified.txt diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateDefaultConverterIdInDifferentNamespace.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateDefaultConverterIdInDifferentNamespace.verified.txt new file mode 100644 index 000000000..e2bc0e43d --- /dev/null +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateDefaultConverterIdInDifferentNamespace.verified.txt @@ -0,0 +1,271 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by the StronglyTypedId source generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 // publicly visible type or member must be documented + +#nullable enable +namespace SomeNamespace1 +{ + [global::System.ComponentModel.TypeConverter(typeof(MyIdTypeConverter))] + [global::System.Text.Json.Serialization.JsonConverter(typeof(MyIdSystemTextJsonConverter))] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta6")] + partial struct MyId : +#if NET6_0_OR_GREATER + global::System.ISpanFormattable, +#endif +#if NET7_0_OR_GREATER + global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, +#endif + global::System.IComparable, global::System.IEquatable, global::System.IFormattable + { + public global::System.Guid Value { get; } + + public MyId(global::System.Guid value) + { + Value = value; + } + + public static MyId New() => new MyId(global::System.Guid.NewGuid()); + public static readonly MyId Empty = new MyId(global::System.Guid.Empty); + + /// + public bool Equals(MyId other) => this.Value.Equals(other.Value); + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + return obj is MyId other && Equals(other); + } + + public override int GetHashCode() => Value.GetHashCode(); + + public override string ToString() => Value.ToString(); + + public static bool operator ==(MyId a, MyId b) => a.Equals(b); + public static bool operator !=(MyId a, MyId b) => !(a == b); + public static bool operator > (MyId a, MyId b) => a.CompareTo(b) > 0; + public static bool operator < (MyId a, MyId b) => a.CompareTo(b) < 0; + public static bool operator >= (MyId a, MyId b) => a.CompareTo(b) >= 0; + public static bool operator <= (MyId a, MyId b) => a.CompareTo(b) <= 0; + + /// + public int CompareTo(MyId other) => Value.CompareTo(other.Value); + + public partial class MyIdTypeConverter : global::System.ComponentModel.TypeConverter + { + public override bool CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type sourceType) + { + return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); + } + + public override object? ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object value) + { + return value switch + { + global::System.Guid guidValue => new MyId(guidValue), + string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new MyId(result), + _ => base.ConvertFrom(context, culture, value), + }; + } + + public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type? sourceType) + { + return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertTo(context, sourceType); + } + + public override object? ConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object? value, global::System.Type destinationType) + { + if (value is MyId idValue) + { + if (destinationType == typeof(global::System.Guid)) + { + return idValue.Value; + } + + if (destinationType == typeof(string)) + { + return idValue.Value.ToString(); + } + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } + + public partial class MyIdSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter + { + public override bool CanConvert(global::System.Type typeToConvert) + => typeToConvert == typeof(global::System.Guid) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert); + + public override MyId Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + => new (reader.GetGuid()); + + public override void Write(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options) + => writer.WriteStringValue(value.Value); + +#if NET6_0_OR_GREATER + public override MyId ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + => new(global::System.Guid.Parse(reader.GetString() ?? throw new global::System.FormatException("The string for the MyId property was null"))); + + public override void WriteAsPropertyName(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options) + => writer.WritePropertyName(value.Value.ToString()); +#endif + } + + public static MyId Parse(string input) + => new(global::System.Guid.Parse(input)); + +#if NET7_0_OR_GREATER + /// + public static MyId Parse(string input, global::System.IFormatProvider? provider) + => new(global::System.Guid.Parse(input, provider)); + + /// + public static bool TryParse( + [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] string? input, + global::System.IFormatProvider? provider, + out MyId result) + { + if (input is null) + { + result = default; + return false; + } + + if (global::System.Guid.TryParse(input, provider, out var guid)) + { + result = new(guid); + return true; + } + else + { + result = default; + return false; + } + } +#endif + + /// + public string ToString( +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + string? format, + global::System.IFormatProvider? formatProvider) + => Value.ToString(format, formatProvider); + +#if NETCOREAPP2_1_OR_GREATER + public static MyId Parse(global::System.ReadOnlySpan input) + => new(global::System.Guid.Parse(input)); +#endif + +#if NET6_0_OR_GREATER +#if NET7_0_OR_GREATER + /// +#endif + public static MyId Parse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider) +#if NET7_0_OR_GREATER + => new(global::System.Guid.Parse(input, provider)); +#else + => new(global::System.Guid.Parse(input)); +#endif + +#if NET7_0_OR_GREATER + /// +#endif + public static bool TryParse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider, out MyId result) + { +#if NET7_0_OR_GREATER + if (global::System.Guid.TryParse(input, provider, out var guid)) +#else + if (global::System.Guid.TryParse(input, out var guid)) +#endif + { + result = new(guid); + return true; + } + else + { + result = default; + return false; + } + } + + /// + public bool TryFormat( + global::System.Span destination, + out int charsWritten, +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(destination, out charsWritten, format); + + /// + public bool TryFormat( + global::System.Span destination, + out int charsWritten, +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + global::System.ReadOnlySpan format = default) + => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); +#endif + } +} + +//------------------------------------------------------------------------------ +// +// This code was generated by the StronglyTypedId source generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 // publicly visible type or member must be documented + +#nullable enable +namespace SomeNamespace2 +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta6")] + partial struct MyIdConverters + { + public partial class DapperTypeHandler : global::Dapper.SqlMapper.TypeHandler + { + public override void SetValue(global::System.Data.IDbDataParameter parameter, SomeNamespace1.MyId value) + { + parameter.Value = value.Value; + } + + public override SomeNamespace1.MyId Parse(object value) + { + return value switch + { + global::System.Guid guidValue => new SomeNamespace1.MyId(guidValue), + string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new SomeNamespace1.MyId(result), + _ => throw new global::System.InvalidCastException($"Unable to cast object of type {value.GetType()} to SomeNamespace1.MyId"), + }; + } + } + } +} diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateDefaultConverterIdInFileScopedNamespace.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateDefaultConverterIdInFileScopedNamespace.verified.txt new file mode 100644 index 000000000..2cfd883a2 --- /dev/null +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateDefaultConverterIdInFileScopedNamespace.verified.txt @@ -0,0 +1,271 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by the StronglyTypedId source generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 // publicly visible type or member must be documented + +#nullable enable +namespace SomeNamespace +{ + [global::System.ComponentModel.TypeConverter(typeof(MyIdTypeConverter))] + [global::System.Text.Json.Serialization.JsonConverter(typeof(MyIdSystemTextJsonConverter))] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta6")] + partial struct MyId : +#if NET6_0_OR_GREATER + global::System.ISpanFormattable, +#endif +#if NET7_0_OR_GREATER + global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, +#endif + global::System.IComparable, global::System.IEquatable, global::System.IFormattable + { + public global::System.Guid Value { get; } + + public MyId(global::System.Guid value) + { + Value = value; + } + + public static MyId New() => new MyId(global::System.Guid.NewGuid()); + public static readonly MyId Empty = new MyId(global::System.Guid.Empty); + + /// + public bool Equals(MyId other) => this.Value.Equals(other.Value); + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + return obj is MyId other && Equals(other); + } + + public override int GetHashCode() => Value.GetHashCode(); + + public override string ToString() => Value.ToString(); + + public static bool operator ==(MyId a, MyId b) => a.Equals(b); + public static bool operator !=(MyId a, MyId b) => !(a == b); + public static bool operator > (MyId a, MyId b) => a.CompareTo(b) > 0; + public static bool operator < (MyId a, MyId b) => a.CompareTo(b) < 0; + public static bool operator >= (MyId a, MyId b) => a.CompareTo(b) >= 0; + public static bool operator <= (MyId a, MyId b) => a.CompareTo(b) <= 0; + + /// + public int CompareTo(MyId other) => Value.CompareTo(other.Value); + + public partial class MyIdTypeConverter : global::System.ComponentModel.TypeConverter + { + public override bool CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type sourceType) + { + return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); + } + + public override object? ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object value) + { + return value switch + { + global::System.Guid guidValue => new MyId(guidValue), + string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new MyId(result), + _ => base.ConvertFrom(context, culture, value), + }; + } + + public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type? sourceType) + { + return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertTo(context, sourceType); + } + + public override object? ConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object? value, global::System.Type destinationType) + { + if (value is MyId idValue) + { + if (destinationType == typeof(global::System.Guid)) + { + return idValue.Value; + } + + if (destinationType == typeof(string)) + { + return idValue.Value.ToString(); + } + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } + + public partial class MyIdSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter + { + public override bool CanConvert(global::System.Type typeToConvert) + => typeToConvert == typeof(global::System.Guid) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert); + + public override MyId Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + => new (reader.GetGuid()); + + public override void Write(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options) + => writer.WriteStringValue(value.Value); + +#if NET6_0_OR_GREATER + public override MyId ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + => new(global::System.Guid.Parse(reader.GetString() ?? throw new global::System.FormatException("The string for the MyId property was null"))); + + public override void WriteAsPropertyName(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options) + => writer.WritePropertyName(value.Value.ToString()); +#endif + } + + public static MyId Parse(string input) + => new(global::System.Guid.Parse(input)); + +#if NET7_0_OR_GREATER + /// + public static MyId Parse(string input, global::System.IFormatProvider? provider) + => new(global::System.Guid.Parse(input, provider)); + + /// + public static bool TryParse( + [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] string? input, + global::System.IFormatProvider? provider, + out MyId result) + { + if (input is null) + { + result = default; + return false; + } + + if (global::System.Guid.TryParse(input, provider, out var guid)) + { + result = new(guid); + return true; + } + else + { + result = default; + return false; + } + } +#endif + + /// + public string ToString( +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + string? format, + global::System.IFormatProvider? formatProvider) + => Value.ToString(format, formatProvider); + +#if NETCOREAPP2_1_OR_GREATER + public static MyId Parse(global::System.ReadOnlySpan input) + => new(global::System.Guid.Parse(input)); +#endif + +#if NET6_0_OR_GREATER +#if NET7_0_OR_GREATER + /// +#endif + public static MyId Parse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider) +#if NET7_0_OR_GREATER + => new(global::System.Guid.Parse(input, provider)); +#else + => new(global::System.Guid.Parse(input)); +#endif + +#if NET7_0_OR_GREATER + /// +#endif + public static bool TryParse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider, out MyId result) + { +#if NET7_0_OR_GREATER + if (global::System.Guid.TryParse(input, provider, out var guid)) +#else + if (global::System.Guid.TryParse(input, out var guid)) +#endif + { + result = new(guid); + return true; + } + else + { + result = default; + return false; + } + } + + /// + public bool TryFormat( + global::System.Span destination, + out int charsWritten, +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(destination, out charsWritten, format); + + /// + public bool TryFormat( + global::System.Span destination, + out int charsWritten, +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + global::System.ReadOnlySpan format = default) + => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); +#endif + } +} + +//------------------------------------------------------------------------------ +// +// This code was generated by the StronglyTypedId source generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 // publicly visible type or member must be documented + +#nullable enable +namespace SomeNamespace +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta6")] + partial struct MyIdConverters + { + public partial class DapperTypeHandler : global::Dapper.SqlMapper.TypeHandler + { + public override void SetValue(global::System.Data.IDbDataParameter parameter, SomeNamespace.MyId value) + { + parameter.Value = value.Value; + } + + public override SomeNamespace.MyId Parse(object value) + { + return value switch + { + global::System.Guid guidValue => new SomeNamespace.MyId(guidValue), + string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new SomeNamespace.MyId(result), + _ => throw new global::System.InvalidCastException($"Unable to cast object of type {value.GetType()} to SomeNamespace.MyId"), + }; + } + } + } +} diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateDefaultConverterIdInNamespace.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateDefaultConverterIdInNamespace.verified.txt new file mode 100644 index 000000000..2cfd883a2 --- /dev/null +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateDefaultConverterIdInNamespace.verified.txt @@ -0,0 +1,271 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by the StronglyTypedId source generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 // publicly visible type or member must be documented + +#nullable enable +namespace SomeNamespace +{ + [global::System.ComponentModel.TypeConverter(typeof(MyIdTypeConverter))] + [global::System.Text.Json.Serialization.JsonConverter(typeof(MyIdSystemTextJsonConverter))] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta6")] + partial struct MyId : +#if NET6_0_OR_GREATER + global::System.ISpanFormattable, +#endif +#if NET7_0_OR_GREATER + global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, +#endif + global::System.IComparable, global::System.IEquatable, global::System.IFormattable + { + public global::System.Guid Value { get; } + + public MyId(global::System.Guid value) + { + Value = value; + } + + public static MyId New() => new MyId(global::System.Guid.NewGuid()); + public static readonly MyId Empty = new MyId(global::System.Guid.Empty); + + /// + public bool Equals(MyId other) => this.Value.Equals(other.Value); + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + return obj is MyId other && Equals(other); + } + + public override int GetHashCode() => Value.GetHashCode(); + + public override string ToString() => Value.ToString(); + + public static bool operator ==(MyId a, MyId b) => a.Equals(b); + public static bool operator !=(MyId a, MyId b) => !(a == b); + public static bool operator > (MyId a, MyId b) => a.CompareTo(b) > 0; + public static bool operator < (MyId a, MyId b) => a.CompareTo(b) < 0; + public static bool operator >= (MyId a, MyId b) => a.CompareTo(b) >= 0; + public static bool operator <= (MyId a, MyId b) => a.CompareTo(b) <= 0; + + /// + public int CompareTo(MyId other) => Value.CompareTo(other.Value); + + public partial class MyIdTypeConverter : global::System.ComponentModel.TypeConverter + { + public override bool CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type sourceType) + { + return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); + } + + public override object? ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object value) + { + return value switch + { + global::System.Guid guidValue => new MyId(guidValue), + string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new MyId(result), + _ => base.ConvertFrom(context, culture, value), + }; + } + + public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type? sourceType) + { + return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertTo(context, sourceType); + } + + public override object? ConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object? value, global::System.Type destinationType) + { + if (value is MyId idValue) + { + if (destinationType == typeof(global::System.Guid)) + { + return idValue.Value; + } + + if (destinationType == typeof(string)) + { + return idValue.Value.ToString(); + } + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } + + public partial class MyIdSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter + { + public override bool CanConvert(global::System.Type typeToConvert) + => typeToConvert == typeof(global::System.Guid) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert); + + public override MyId Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + => new (reader.GetGuid()); + + public override void Write(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options) + => writer.WriteStringValue(value.Value); + +#if NET6_0_OR_GREATER + public override MyId ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + => new(global::System.Guid.Parse(reader.GetString() ?? throw new global::System.FormatException("The string for the MyId property was null"))); + + public override void WriteAsPropertyName(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options) + => writer.WritePropertyName(value.Value.ToString()); +#endif + } + + public static MyId Parse(string input) + => new(global::System.Guid.Parse(input)); + +#if NET7_0_OR_GREATER + /// + public static MyId Parse(string input, global::System.IFormatProvider? provider) + => new(global::System.Guid.Parse(input, provider)); + + /// + public static bool TryParse( + [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] string? input, + global::System.IFormatProvider? provider, + out MyId result) + { + if (input is null) + { + result = default; + return false; + } + + if (global::System.Guid.TryParse(input, provider, out var guid)) + { + result = new(guid); + return true; + } + else + { + result = default; + return false; + } + } +#endif + + /// + public string ToString( +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + string? format, + global::System.IFormatProvider? formatProvider) + => Value.ToString(format, formatProvider); + +#if NETCOREAPP2_1_OR_GREATER + public static MyId Parse(global::System.ReadOnlySpan input) + => new(global::System.Guid.Parse(input)); +#endif + +#if NET6_0_OR_GREATER +#if NET7_0_OR_GREATER + /// +#endif + public static MyId Parse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider) +#if NET7_0_OR_GREATER + => new(global::System.Guid.Parse(input, provider)); +#else + => new(global::System.Guid.Parse(input)); +#endif + +#if NET7_0_OR_GREATER + /// +#endif + public static bool TryParse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider, out MyId result) + { +#if NET7_0_OR_GREATER + if (global::System.Guid.TryParse(input, provider, out var guid)) +#else + if (global::System.Guid.TryParse(input, out var guid)) +#endif + { + result = new(guid); + return true; + } + else + { + result = default; + return false; + } + } + + /// + public bool TryFormat( + global::System.Span destination, + out int charsWritten, +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(destination, out charsWritten, format); + + /// + public bool TryFormat( + global::System.Span destination, + out int charsWritten, +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + global::System.ReadOnlySpan format = default) + => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); +#endif + } +} + +//------------------------------------------------------------------------------ +// +// This code was generated by the StronglyTypedId source generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 // publicly visible type or member must be documented + +#nullable enable +namespace SomeNamespace +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta6")] + partial struct MyIdConverters + { + public partial class DapperTypeHandler : global::Dapper.SqlMapper.TypeHandler + { + public override void SetValue(global::System.Data.IDbDataParameter parameter, SomeNamespace.MyId value) + { + parameter.Value = value.Value; + } + + public override SomeNamespace.MyId Parse(object value) + { + return value switch + { + global::System.Guid guidValue => new SomeNamespace.MyId(guidValue), + string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new SomeNamespace.MyId(result), + _ => throw new global::System.InvalidCastException($"Unable to cast object of type {value.GetType()} to SomeNamespace.MyId"), + }; + } + } + } +} diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateMultipleConvertersWithSameName.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateMultipleConvertersWithSameName.verified.txt new file mode 100644 index 000000000..a960e3c57 --- /dev/null +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateMultipleConvertersWithSameName.verified.txt @@ -0,0 +1,314 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by the StronglyTypedId source generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 // publicly visible type or member must be documented + +#nullable enable + public partial class ParentClass + { + [global::System.ComponentModel.TypeConverter(typeof(MyIdTypeConverter))] + [global::System.Text.Json.Serialization.JsonConverter(typeof(MyIdSystemTextJsonConverter))] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta6")] + partial struct MyId : +#if NET6_0_OR_GREATER + global::System.ISpanFormattable, +#endif +#if NET7_0_OR_GREATER + global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, +#endif + global::System.IComparable, global::System.IEquatable, global::System.IFormattable + { + public global::System.Guid Value { get; } + + public MyId(global::System.Guid value) + { + Value = value; + } + + public static MyId New() => new MyId(global::System.Guid.NewGuid()); + public static readonly MyId Empty = new MyId(global::System.Guid.Empty); + + /// + public bool Equals(MyId other) => this.Value.Equals(other.Value); + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + return obj is MyId other && Equals(other); + } + + public override int GetHashCode() => Value.GetHashCode(); + + public override string ToString() => Value.ToString(); + + public static bool operator ==(MyId a, MyId b) => a.Equals(b); + public static bool operator !=(MyId a, MyId b) => !(a == b); + public static bool operator > (MyId a, MyId b) => a.CompareTo(b) > 0; + public static bool operator < (MyId a, MyId b) => a.CompareTo(b) < 0; + public static bool operator >= (MyId a, MyId b) => a.CompareTo(b) >= 0; + public static bool operator <= (MyId a, MyId b) => a.CompareTo(b) <= 0; + + /// + public int CompareTo(MyId other) => Value.CompareTo(other.Value); + + public partial class MyIdTypeConverter : global::System.ComponentModel.TypeConverter + { + public override bool CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type sourceType) + { + return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); + } + + public override object? ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object value) + { + return value switch + { + global::System.Guid guidValue => new MyId(guidValue), + string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new MyId(result), + _ => base.ConvertFrom(context, culture, value), + }; + } + + public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type? sourceType) + { + return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertTo(context, sourceType); + } + + public override object? ConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object? value, global::System.Type destinationType) + { + if (value is MyId idValue) + { + if (destinationType == typeof(global::System.Guid)) + { + return idValue.Value; + } + + if (destinationType == typeof(string)) + { + return idValue.Value.ToString(); + } + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } + + public partial class MyIdSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter + { + public override bool CanConvert(global::System.Type typeToConvert) + => typeToConvert == typeof(global::System.Guid) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert); + + public override MyId Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + => new (reader.GetGuid()); + + public override void Write(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options) + => writer.WriteStringValue(value.Value); + +#if NET6_0_OR_GREATER + public override MyId ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + => new(global::System.Guid.Parse(reader.GetString() ?? throw new global::System.FormatException("The string for the MyId property was null"))); + + public override void WriteAsPropertyName(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options) + => writer.WritePropertyName(value.Value.ToString()); +#endif + } + + public static MyId Parse(string input) + => new(global::System.Guid.Parse(input)); + +#if NET7_0_OR_GREATER + /// + public static MyId Parse(string input, global::System.IFormatProvider? provider) + => new(global::System.Guid.Parse(input, provider)); + + /// + public static bool TryParse( + [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] string? input, + global::System.IFormatProvider? provider, + out MyId result) + { + if (input is null) + { + result = default; + return false; + } + + if (global::System.Guid.TryParse(input, provider, out var guid)) + { + result = new(guid); + return true; + } + else + { + result = default; + return false; + } + } +#endif + + /// + public string ToString( +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + string? format, + global::System.IFormatProvider? formatProvider) + => Value.ToString(format, formatProvider); + +#if NETCOREAPP2_1_OR_GREATER + public static MyId Parse(global::System.ReadOnlySpan input) + => new(global::System.Guid.Parse(input)); +#endif + +#if NET6_0_OR_GREATER +#if NET7_0_OR_GREATER + /// +#endif + public static MyId Parse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider) +#if NET7_0_OR_GREATER + => new(global::System.Guid.Parse(input, provider)); +#else + => new(global::System.Guid.Parse(input)); +#endif + +#if NET7_0_OR_GREATER + /// +#endif + public static bool TryParse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider, out MyId result) + { +#if NET7_0_OR_GREATER + if (global::System.Guid.TryParse(input, provider, out var guid)) +#else + if (global::System.Guid.TryParse(input, out var guid)) +#endif + { + result = new(guid); + return true; + } + else + { + result = default; + return false; + } + } + + /// + public bool TryFormat( + global::System.Span destination, + out int charsWritten, +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(destination, out charsWritten, format); + + /// + public bool TryFormat( + global::System.Span destination, + out int charsWritten, +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + global::System.ReadOnlySpan format = default) + => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); +#endif + } + } + +//------------------------------------------------------------------------------ +// +// This code was generated by the StronglyTypedId source generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 // publicly visible type or member must be documented + +#nullable enable +namespace MyContracts.V1 +{ + public partial class ConverterClass + { + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta6")] + partial struct MyIdConverters + { + public partial class DapperTypeHandler : global::Dapper.SqlMapper.TypeHandler + { + public override void SetValue(global::System.Data.IDbDataParameter parameter, MyId value) + { + parameter.Value = value.Value; + } + + public override MyId Parse(object value) + { + return value switch + { + global::System.Guid guidValue => new MyId(guidValue), + string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new MyId(result), + _ => throw new global::System.InvalidCastException($"Unable to cast object of type {value.GetType()} to MyId"), + }; + } + } + } + } +} + +//------------------------------------------------------------------------------ +// +// This code was generated by the StronglyTypedId source generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 // publicly visible type or member must be documented + +#nullable enable +namespace MyContracts.V2 +{ + public partial class ConverterClass + { + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta6")] + partial struct MyIdConverters + { + public partial class DapperTypeHandler : global::Dapper.SqlMapper.TypeHandler + { + public override void SetValue(global::System.Data.IDbDataParameter parameter, MyId value) + { + parameter.Value = value.Value; + } + + public override MyId Parse(object value) + { + return value switch + { + global::System.Guid guidValue => new MyId(guidValue), + string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new MyId(result), + _ => throw new global::System.InvalidCastException($"Unable to cast object of type {value.GetType()} to MyId"), + }; + } + } + } + } +} diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateNestedIdInFileScopeNamespace.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateNestedIdInFileScopeNamespace.verified.txt new file mode 100644 index 000000000..c3bda2a74 --- /dev/null +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateNestedIdInFileScopeNamespace.verified.txt @@ -0,0 +1,277 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by the StronglyTypedId source generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 // publicly visible type or member must be documented + +#nullable enable +namespace SomeNamespace +{ + public partial class ParentClass + { + [global::System.ComponentModel.TypeConverter(typeof(MyIdTypeConverter))] + [global::System.Text.Json.Serialization.JsonConverter(typeof(MyIdSystemTextJsonConverter))] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta6")] + partial struct MyId : +#if NET6_0_OR_GREATER + global::System.ISpanFormattable, +#endif +#if NET7_0_OR_GREATER + global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, +#endif + global::System.IComparable, global::System.IEquatable, global::System.IFormattable + { + public global::System.Guid Value { get; } + + public MyId(global::System.Guid value) + { + Value = value; + } + + public static MyId New() => new MyId(global::System.Guid.NewGuid()); + public static readonly MyId Empty = new MyId(global::System.Guid.Empty); + + /// + public bool Equals(MyId other) => this.Value.Equals(other.Value); + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + return obj is MyId other && Equals(other); + } + + public override int GetHashCode() => Value.GetHashCode(); + + public override string ToString() => Value.ToString(); + + public static bool operator ==(MyId a, MyId b) => a.Equals(b); + public static bool operator !=(MyId a, MyId b) => !(a == b); + public static bool operator > (MyId a, MyId b) => a.CompareTo(b) > 0; + public static bool operator < (MyId a, MyId b) => a.CompareTo(b) < 0; + public static bool operator >= (MyId a, MyId b) => a.CompareTo(b) >= 0; + public static bool operator <= (MyId a, MyId b) => a.CompareTo(b) <= 0; + + /// + public int CompareTo(MyId other) => Value.CompareTo(other.Value); + + public partial class MyIdTypeConverter : global::System.ComponentModel.TypeConverter + { + public override bool CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type sourceType) + { + return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); + } + + public override object? ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object value) + { + return value switch + { + global::System.Guid guidValue => new MyId(guidValue), + string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new MyId(result), + _ => base.ConvertFrom(context, culture, value), + }; + } + + public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type? sourceType) + { + return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertTo(context, sourceType); + } + + public override object? ConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object? value, global::System.Type destinationType) + { + if (value is MyId idValue) + { + if (destinationType == typeof(global::System.Guid)) + { + return idValue.Value; + } + + if (destinationType == typeof(string)) + { + return idValue.Value.ToString(); + } + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } + + public partial class MyIdSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter + { + public override bool CanConvert(global::System.Type typeToConvert) + => typeToConvert == typeof(global::System.Guid) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert); + + public override MyId Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + => new (reader.GetGuid()); + + public override void Write(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options) + => writer.WriteStringValue(value.Value); + +#if NET6_0_OR_GREATER + public override MyId ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + => new(global::System.Guid.Parse(reader.GetString() ?? throw new global::System.FormatException("The string for the MyId property was null"))); + + public override void WriteAsPropertyName(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options) + => writer.WritePropertyName(value.Value.ToString()); +#endif + } + + public static MyId Parse(string input) + => new(global::System.Guid.Parse(input)); + +#if NET7_0_OR_GREATER + /// + public static MyId Parse(string input, global::System.IFormatProvider? provider) + => new(global::System.Guid.Parse(input, provider)); + + /// + public static bool TryParse( + [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] string? input, + global::System.IFormatProvider? provider, + out MyId result) + { + if (input is null) + { + result = default; + return false; + } + + if (global::System.Guid.TryParse(input, provider, out var guid)) + { + result = new(guid); + return true; + } + else + { + result = default; + return false; + } + } +#endif + + /// + public string ToString( +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + string? format, + global::System.IFormatProvider? formatProvider) + => Value.ToString(format, formatProvider); + +#if NETCOREAPP2_1_OR_GREATER + public static MyId Parse(global::System.ReadOnlySpan input) + => new(global::System.Guid.Parse(input)); +#endif + +#if NET6_0_OR_GREATER +#if NET7_0_OR_GREATER + /// +#endif + public static MyId Parse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider) +#if NET7_0_OR_GREATER + => new(global::System.Guid.Parse(input, provider)); +#else + => new(global::System.Guid.Parse(input)); +#endif + +#if NET7_0_OR_GREATER + /// +#endif + public static bool TryParse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider, out MyId result) + { +#if NET7_0_OR_GREATER + if (global::System.Guid.TryParse(input, provider, out var guid)) +#else + if (global::System.Guid.TryParse(input, out var guid)) +#endif + { + result = new(guid); + return true; + } + else + { + result = default; + return false; + } + } + + /// + public bool TryFormat( + global::System.Span destination, + out int charsWritten, +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(destination, out charsWritten, format); + + /// + public bool TryFormat( + global::System.Span destination, + out int charsWritten, +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] +#endif + global::System.ReadOnlySpan format = default) + => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); +#endif + } + } +} + +//------------------------------------------------------------------------------ +// +// This code was generated by the StronglyTypedId source generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 // publicly visible type or member must be documented + +#nullable enable +namespace SomeNamespace +{ + public partial class ConverterClass + { + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta6")] + partial struct MyIdConverters + { + public partial class DapperTypeHandler : global::Dapper.SqlMapper.TypeHandler + { + public override void SetValue(global::System.Data.IDbDataParameter parameter, MyId value) + { + parameter.Value = value.Value; + } + + public override MyId Parse(object value) + { + return value switch + { + global::System.Guid guidValue => new MyId(guidValue), + string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new MyId(result), + _ => throw new global::System.InvalidCastException($"Unable to cast object of type {value.GetType()} to MyId"), + }; + } + } + } + } +} diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateNonDefaultConverterIdInNamespace.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateNonDefaultConverterIdInNamespace.verified.txt new file mode 100644 index 000000000..6972e8a1f --- /dev/null +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdConverterTests.CanGenerateNonDefaultConverterIdInNamespace.verified.txt @@ -0,0 +1,286 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by the StronglyTypedId source generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 // publicly visible type or member must be documented + +#nullable enable +namespace SomeNamespace +{ + [global::System.ComponentModel.TypeConverter(typeof(MyIdTypeConverter))] + [global::System.Text.Json.Serialization.JsonConverter(typeof(MyIdSystemTextJsonConverter))] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta6")] + partial struct MyId : +#if NET6_0_OR_GREATER + global::System.ISpanFormattable, +#endif +#if NET7_0_OR_GREATER + global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanParsable, global::System.IUtf8SpanFormattable, +#endif + global::System.IComparable, global::System.IEquatable, global::System.IFormattable + { + public int Value { get; } + + public MyId(int value) + { + Value = value; + } + + public static readonly MyId Empty = new MyId(0); + + /// + public bool Equals(MyId other) => this.Value.Equals(other.Value); + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + return obj is MyId other && Equals(other); + } + + public override int GetHashCode() => Value.GetHashCode(); + + public override string ToString() => Value.ToString(global::System.Globalization.CultureInfo.InvariantCulture); + + public static bool operator ==(MyId a, MyId b) => a.Equals(b); + public static bool operator !=(MyId a, MyId b) => !(a == b); + public static bool operator > (MyId a, MyId b) => a.CompareTo(b) > 0; + public static bool operator < (MyId a, MyId b) => a.CompareTo(b) < 0; + public static bool operator >= (MyId a, MyId b) => a.CompareTo(b) >= 0; + public static bool operator <= (MyId a, MyId b) => a.CompareTo(b) <= 0; + + /// + public int CompareTo(MyId other) => Value.CompareTo(other.Value); + + public partial class MyIdTypeConverter : global::System.ComponentModel.TypeConverter + { + public override bool CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type sourceType) + { + return sourceType == typeof(int) || sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); + } + + public override object? ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object value) + { + return value switch + { + int intValue => new MyId(intValue), + string stringValue when !string.IsNullOrEmpty(stringValue) && int.TryParse(stringValue, out var result) => new MyId(result), + _ => base.ConvertFrom(context, culture, value), + }; + } + + public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type? sourceType) + { + return sourceType == typeof(int) || sourceType == typeof(string) || base.CanConvertTo(context, sourceType); + } + + public override object? ConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object? value, global::System.Type destinationType) + { + if (value is MyId idValue) + { + if (destinationType == typeof(int)) + { + return idValue.Value; + } + + if (destinationType == typeof(string)) + { + return idValue.Value.ToString(global::System.Globalization.CultureInfo.InvariantCulture); + } + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } + + public partial class MyIdSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter + { + public override bool CanConvert(global::System.Type typeToConvert) + => typeToConvert == typeof(int) || typeToConvert == typeof(string) || base.CanConvert(typeToConvert); + + public override MyId Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + => new (reader.GetInt32()); + + public override void Write(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options) + => writer.WriteNumberValue(value.Value); + +#if NET6_0_OR_GREATER + public override MyId ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + => new(int.Parse(reader.GetString() ?? throw new global::System.FormatException("The string for the MyId property was null"))); + + public override void WriteAsPropertyName(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options) + => writer.WritePropertyName(value.Value.ToString(global::System.Globalization.CultureInfo.InvariantCulture)); +#endif + } + + public static MyId Parse(string input) + => new(int.Parse(input)); + +#if NET7_0_OR_GREATER + /// + public static MyId Parse(string input, global::System.IFormatProvider? provider) + => new(int.Parse(input, provider)); + + /// + public static bool TryParse( + [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] string? input, + global::System.IFormatProvider? provider, + out MyId result) + { + if (input is null) + { + result = default; + return false; + } + + if (int.TryParse(input, provider, out var value)) + { + result = new(value); + return true; + } + + result = default; + return false; + } +#endif + + /// + public string ToString( +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] +#endif + string? format, + global::System.IFormatProvider? formatProvider) + => Value.ToString(format, formatProvider); + +#if NETCOREAPP2_1_OR_GREATER + public static MyId Parse(global::System.ReadOnlySpan input) + => new(int.Parse(input)); +#endif + +#if NET6_0_OR_GREATER +#if NET7_0_OR_GREATER + /// +#endif + public static MyId Parse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider) +#if NET7_0_OR_GREATER + => new(int.Parse(input, provider)); +#else + => new(int.Parse(input)); +#endif + +#if NET7_0_OR_GREATER + /// +#endif + public static bool TryParse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider, out MyId result) + { +#if NET7_0_OR_GREATER + if (int.TryParse(input, provider, out var value)) +#else + if (int.TryParse(input, out var value)) +#endif + { + result = new(value); + return true; + } + + result = default; + return false; + } + + /// + public bool TryFormat( + global::System.Span destination, + out int charsWritten, +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] +#endif + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(destination, out charsWritten, format); + + /// + public bool TryFormat( + global::System.Span destination, + out int charsWritten, +#if NET7_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] +#endif + global::System.ReadOnlySpan format = default) + => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] + global::System.ReadOnlySpan format = default, + global::System.IFormatProvider? provider = null) + => Value.TryFormat(utf8Destination, out bytesWritten, format, provider); + + /// + public static MyId Parse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider) + => new(int.Parse(utf8Text, provider)); + + /// + public static bool TryParse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider, out MyId result) + { + if (int.TryParse(utf8Text, provider, out var intResult)) + { + result = new MyId(intResult); + return true; + } + + result = default; + return false; + } +#endif + } +} + +//------------------------------------------------------------------------------ +// +// This code was generated by the StronglyTypedId source generator +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#pragma warning disable 1591 // publicly visible type or member must be documented + +#nullable enable +namespace SomeNamespace +{ + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta6")] + partial struct MyIdConverters + { + public partial class DapperTypeHandler : global::Dapper.SqlMapper.TypeHandler + { + public override void SetValue(global::System.Data.IDbDataParameter parameter, SomeNamespace.MyId value) + { + parameter.Value = value.Value; + } + + public override SomeNamespace.MyId Parse(object value) + { + return value switch + { + int intValue => new SomeNamespace.MyId(intValue), + short shortValue => new SomeNamespace.MyId(shortValue), + long longValue and < int.MaxValue and > int.MinValue => new SomeNamespace.MyId((int)longValue), + decimal decimalValue and < int.MaxValue and > int.MinValue => new SomeNamespace.MyId((int)decimalValue), + string stringValue when !string.IsNullOrEmpty(stringValue) && int.TryParse(stringValue, out var result) => new SomeNamespace.MyId(result), + _ => throw new global::System.InvalidCastException($"Unable to cast object of type {value.GetType()} to SomeNamespace.MyId"), + }; + } + } + } +} diff --git a/test/StronglyTypedIds.Tests/StronglyTypedIdConverterTests.cs b/test/StronglyTypedIds.Tests/StronglyTypedIdConverterTests.cs index 35dfb8160..6b389763b 100644 --- a/test/StronglyTypedIds.Tests/StronglyTypedIdConverterTests.cs +++ b/test/StronglyTypedIds.Tests/StronglyTypedIdConverterTests.cs @@ -37,18 +37,25 @@ public partial struct MyIdConverters {} .UseDirectory("Snapshots"); } - [Fact] - public Task CanGenerateDefaultConverterIdInGlobalNamespace() + [Theory] + [InlineData("", true)] + [InlineData("(\"guid-dapper\")", true)] + [InlineData("(\"guid-dapper\")", false)] + public Task CanGenerateDefaultConverterIdInGlobalNamespace(string template, bool includeDefaults) { - const string input = - """ + var attribute = includeDefaults + ? "[assembly:StronglyTypedIdConvertersDefaults(\"guid-dapper\")]" + : string.Empty; + + var input = + $$""" using StronglyTypedIds; - [assembly:StronglyTypedIdConvertersDefaults("guid-dapper")] + {{attribute}} [StronglyTypedId] public partial struct MyId {} - [StronglyTypedIdConverters] + [StronglyTypedIdConverters{{template}}] public partial struct MyIdConverters {} """; var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); @@ -56,299 +63,226 @@ public partial struct MyIdConverters {} Assert.Empty(diagnostics); return Verifier.Verify(output) + .DisableRequireUniquePrefix() + .UseDirectory("Snapshots"); + } + + [Theory] + [InlineData("", true)] + [InlineData("(\"guid-dapper\")", true)] + [InlineData("(\"guid-dapper\")", false)] + public Task CanGenerateDefaultConverterIdInNamespace(string template, bool includeDefaults) + { + var attribute = includeDefaults + ? "[assembly:StronglyTypedIdConvertersDefaults(\"guid-dapper\")]" + : string.Empty; + + var input = + $$""" + using StronglyTypedIds; + {{attribute}} + + namespace SomeNamespace + { + [StronglyTypedId] + public partial struct MyId {} + + [StronglyTypedIdConverters{{template}}] + public partial struct MyIdConverters {} + } + """; + var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); + + Assert.Empty(diagnostics); + + return Verifier.Verify(output) + .DisableRequireUniquePrefix() + .UseDirectory("Snapshots"); + } + + [Theory] + [InlineData("", true)] + [InlineData("(\"int-dapper\")", true)] + [InlineData("(\"int-dapper\")", false)] + public Task CanGenerateNonDefaultConverterIdInNamespace(string template, bool includeDefaults) + { + var attribute = includeDefaults + ? "[assembly:StronglyTypedIdConvertersDefaults(\"int-dapper\")]" + : string.Empty; + + var input = + $$""" + using StronglyTypedIds; + {{attribute}} + + namespace SomeNamespace + { + [StronglyTypedId(Template.Int)] + public partial struct MyId {} + + [StronglyTypedIdConverters{{template}}] + public partial struct MyIdConverters {} + } + """; + var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); + + Assert.Empty(diagnostics); + + return Verifier.Verify(output) + .DisableRequireUniquePrefix() + .UseDirectory("Snapshots"); + } + + [Theory] + [InlineData("", true)] + [InlineData("(\"guid-dapper\")", true)] + [InlineData("(\"guid-dapper\")", false)] + public Task CanGenerateDefaultConverterIdInFileScopedNamespace(string template, bool includeDefaults) + { + var attribute = includeDefaults + ? "[assembly:StronglyTypedIdConvertersDefaults(\"guid-dapper\")]" + : string.Empty; + + var input = + $$""" + using StronglyTypedIds; + {{attribute}} + + namespace SomeNamespace; + + [StronglyTypedId] + public partial struct MyId {} + + [StronglyTypedIdConverters{{template}}] + public partial struct MyIdConverters {} + """; + var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); + + Assert.Empty(diagnostics); + + return Verifier.Verify(output) + .DisableRequireUniquePrefix() + .UseDirectory("Snapshots"); + } + + [Theory] + [InlineData("", true)] + [InlineData("(\"guid-dapper\")", true)] + [InlineData("(\"guid-dapper\")", false)] + public Task CanGenerateDefaultConverterIdInDifferentNamespace(string template, bool includeDefaults) + { + var attribute = includeDefaults + ? "[assembly:StronglyTypedIdConvertersDefaults(\"guid-dapper\")]" + : string.Empty; + + var input = + $$""" + using StronglyTypedIds; + {{attribute}} + + namespace SomeNamespace1 + { + [StronglyTypedId] + public partial struct MyId {} + } + namespace SomeNamespace2 + { + using SomeNamespace1; + + [StronglyTypedIdConverters{{template}}] + public partial struct MyIdConverters {} + } + """; + var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); + + Assert.Empty(diagnostics); + + return Verifier.Verify(output) + .DisableRequireUniquePrefix() .UseDirectory("Snapshots"); } -// -// [Theory] -// [InlineData("")] -// [InlineData("Template.Guid")] -// [InlineData("template: Template.Guid")] -// public Task CanGenerateIdInNamespace(string template) -// { -// var input = $$""" -// using StronglyTypedIds; -// namespace SomeNamespace -// { -// [StronglyTypedId({{template}})] -// public partial struct MyId {} -// } -// """; -// var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); -// -// Assert.Empty(diagnostics); -// -// return Verifier.Verify(output) -// .DisableRequireUniquePrefix() -// .UseDirectory("Snapshots"); -// } -// -// [Theory] -// [InlineData("Template.Int")] -// [InlineData("template: Template.Int")] -// public Task CanGenerateNonDefaultIdInNamespace(string template) -// { -// var input = $$""" -// using StronglyTypedIds; -// namespace SomeNamespace -// { -// [StronglyTypedId({{template}})] -// public partial struct MyId {} -// } -// """; -// var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); -// -// Assert.Empty(diagnostics); -// -// return Verifier.Verify(output) -// .DisableRequireUniquePrefix() -// .UseDirectory("Snapshots"); -// } -// -// [Theory] -// [InlineData("\"newid-full\"")] -// [InlineData("templateNames: \"newid-full\"")] -// public Task CanGenerateForCustomTemplate(string templateName) -// { -// var input = $$""" -// using StronglyTypedIds; -// namespace SomeNamespace -// { -// [StronglyTypedId({{templateName}})] -// public partial struct MyId {} -// } -// """; -// var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); -// -// Assert.Empty(diagnostics); -// -// return Verifier.Verify(output) -// .DisableRequireUniquePrefix() -// .UseDirectory("Snapshots"); -// } -// -// [Fact] -// public Task CanGenerateIdInFileScopedNamespace() -// { -// const string input = @"using StronglyTypedIds; -// -// namespace SomeNamespace; -// [StronglyTypedId] -// public partial struct MyId {}"; -// var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); -// -// Assert.Empty(diagnostics); -// -// return Verifier.Verify(output) -// .UseDirectory("Snapshots"); -// } -// -// [Fact] -// public Task CanGenerateNestedIdInFileScopeNamespace() -// { -// const string input = @"using StronglyTypedIds; -// -// namespace SomeNamespace; -// -// public class ParentClass -// { -// [StronglyTypedId] -// public partial struct MyId {} -// }"; -// var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); -// -// Assert.Empty(diagnostics); -// -// return Verifier.Verify(output) -// .UseDirectory("Snapshots"); -// } -// -// [Fact] -// public Task CanGenerateVeryNestedIdInFileScopeNamespace() -// { -// const string input = @"using StronglyTypedIds; -// -// namespace SomeNamespace; -// -// public partial class ParentClass -// { -// internal partial record InnerClass -// { -// public readonly partial record struct InnerStruct -// { -// [StronglyTypedId] -// public readonly partial struct MyId {} -// } -// } -// }"; -// var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); -// -// Assert.Empty(diagnostics); -// -// return Verifier.Verify(output) -// .UseDirectory("Snapshots"); -// } -// -// [Fact] -// public Task CanGenerateGenericVeryNestedIdInFileScopeNamespace() -// { -// const string input = @"using StronglyTypedIds; -// -// namespace SomeNamespace; -// -// public class ParentClass -// where T: new() -// { -// internal record InnerClass -// { -// public struct InnerStruct -// { -// [StronglyTypedId] -// public partial struct MyId {} -// } -// } -// }"; -// var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); -// -// Assert.Empty(diagnostics); -// -// return Verifier.Verify(output) -// .UseDirectory("Snapshots"); -// } -// -// [Theory] -// [InlineData("Template.Int")] -// [InlineData("template: Template.Int")] -// public Task CanOverrideDefaultsWithTemplateUsingGlobalAttribute(string template) -// { -// var input = $$""" -// using StronglyTypedIds; -// [assembly:StronglyTypedIdDefaults({{template}})] -// -// [StronglyTypedId] -// public partial struct MyId {} -// """; -// -// var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); -// -// Assert.Empty(diagnostics); -// -// return Verifier.Verify(output) -// .DisableRequireUniquePrefix() -// .UseDirectory("Snapshots"); -// } -// -// [Theory] -// [InlineData("\"newid-full\"")] -// [InlineData("templateName: \"newid-full\"")] -// public Task CanOverrideDefaultsWithCustomTemplateUsingGlobalAttribute(string templateNames) -// { -// var input = $$""" -// using StronglyTypedIds; -// [assembly:StronglyTypedIdDefaults({{templateNames}})] -// -// [StronglyTypedId] -// public partial struct MyId {} -// """; -// -// var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); -// -// Assert.Empty(diagnostics); -// -// return Verifier.Verify(output) -// .DisableRequireUniquePrefix() -// .UseDirectory("Snapshots"); -// } -// -// [Fact] -// public Task CanGenerateMultipleIdsWithSameName() -// { -// // https://github.com/andrewlock/StronglyTypedId/issues/74 -// const string input = @"using StronglyTypedIds; -// -// namespace MyContracts.V1 -// { -// [StronglyTypedId] -// public partial struct MyId {} -// } -// -// namespace MyContracts.V2 -// { -// [StronglyTypedId] -// public partial struct MyId {} -// }"; -// -// // This only includes the last ID but that's good enough for this -// var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); -// -// Assert.Empty(diagnostics); -// -// return Verifier.Verify(output) -// .UseDirectory("Snapshots"); -// } -// -// [Theory] -// [InlineData(false, "Template.Guid, \"guid-efcore\", \"guid-dapper\"")] -// [InlineData(false, "template: Template.Guid, \"guid-efcore\", \"guid-dapper\"")] -// [InlineData(false, "Template.Guid, templateNames: new [] {\"guid-efcore\", \"guid-dapper\"}")] -// [InlineData(true, "Template.Guid, \"guid-efcore\", \"guid-dapper\"")] -// [InlineData(true, "template: Template.Guid, \"guid-efcore\", \"guid-dapper\"")] -// [InlineData(true, "Template.Guid, templateNames: new [] {\"guid-efcore\", \"guid-dapper\"}")] -// public Task CanGenerateMultipleTemplatesWithBuiltIn(bool useDefault, string template) -// { -// var defaultAttr = useDefault -// ? $"[assembly:StronglyTypedIdDefaults({template})]" -// : string.Empty; -// -// var templateAttr = useDefault ? string.Empty : template; -// -// var input = $$""" -// using StronglyTypedIds; -// {{defaultAttr}} -// -// [StronglyTypedId({{templateAttr}})] -// public partial struct MyId {} -// """; -// -// // This only includes the last ID but that's good enough for this -// var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); -// -// Assert.Empty(diagnostics); -// -// return Verifier.Verify(output) -// .DisableRequireUniquePrefix() -// .UseDirectory("Snapshots"); -// } -// -// [Theory] -// [InlineData(false, "\"guid-efcore\", \"guid-dapper\"")] -// [InlineData(false, "templateNames: new [] {\"guid-efcore\", \"guid-dapper\"}")] -// [InlineData(true, "\"guid-dapper\", \"guid-efcore\"")] -// [InlineData(true, "\"guid-dapper\", new [] {\"guid-efcore\"}")] -// [InlineData(true, "\"guid-dapper\", templateNames: new [] {\"guid-efcore\"}")] -// [InlineData(true, "templateName: \"guid-dapper\", templateNames: new [] {\"guid-efcore\"}")] -// public Task CanGenerateMultipleTemplatesWithoutBuiltIn(bool useDefault, string template) -// { -// var defaultAttr = useDefault -// ? $"[assembly:StronglyTypedIdDefaults({template})]" -// : string.Empty; -// -// var templateAttr = useDefault ? string.Empty : template; -// -// var input = $$""" -// using StronglyTypedIds; -// {{defaultAttr}} -// -// [StronglyTypedId({{templateAttr}})] -// public partial struct MyId {} -// """; -// -// // This only includes the last ID but that's good enough for this -// var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); -// -// Assert.Empty(diagnostics); -// -// return Verifier.Verify(output) -// .DisableRequireUniquePrefix() -// .UseDirectory("Snapshots"); -// } + + [Theory] + [InlineData("", true)] + [InlineData("(\"guid-dapper\")", true)] + [InlineData("(\"guid-dapper\")", false)] + public Task CanGenerateNestedIdInFileScopeNamespace(string template, bool includeDefaults) + { + var attribute = includeDefaults + ? "[assembly:StronglyTypedIdConvertersDefaults(\"guid-dapper\")]" + : string.Empty; + + var input = $$""" + using StronglyTypedIds; + {{attribute}} + + namespace SomeNamespace; + + public class ParentClass + { + [StronglyTypedId] + public partial struct MyId {} + } + + public class ConverterClass + { + [StronglyTypedIdConverters{{template}}] + public partial struct MyIdConverters {} + } + """; + var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); + + Assert.Empty(diagnostics); + + return Verifier.Verify(output) + .DisableRequireUniquePrefix() + .UseDirectory("Snapshots"); + } + + [Theory] + [InlineData("", true)] + [InlineData("(\"guid-dapper\")", true)] + [InlineData("(\"guid-dapper\")", false)] + public Task CanGenerateMultipleConvertersWithSameName(string template, bool includeDefaults) + { + var attribute = includeDefaults + ? "[assembly:StronglyTypedIdConvertersDefaults(\"guid-dapper\")]" + : string.Empty; + + var input = $$""" + using StronglyTypedIds; + {{attribute}} + + public class ParentClass + { + [StronglyTypedId] + public partial struct MyId {} + } + + namespace MyContracts.V1 + { + public class ConverterClass + { + [StronglyTypedIdConverters{{template}}] + public partial struct MyIdConverters {} + } + } + + namespace MyContracts.V2 + { + public class ConverterClass + { + [StronglyTypedIdConverters{{template}}] + public partial struct MyIdConverters {} + } + } + """; + var (diagnostics, output) = TestHelpers.GetGeneratedOutput(input, includeAttributes: false); + + Assert.Empty(diagnostics); + + return Verifier.Verify(output) + .DisableRequireUniquePrefix() + .UseDirectory("Snapshots"); + } } \ No newline at end of file