diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/XmlSerializationTests/XmlSerializationHandlesNullableDateTimeOffsetProperty.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/XmlSerializationTests/XmlSerializationHandlesNullableDateTimeOffsetProperty.cs index a2e945aa23e..a64a6102cfb 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/XmlSerializationTests/XmlSerializationHandlesNullableDateTimeOffsetProperty.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/TestData/XmlSerializationTests/XmlSerializationHandlesNullableDateTimeOffsetProperty.cs @@ -63,10 +63,10 @@ internal virtual void XmlModelWriteCore(global::System.Xml.XmlWriter writer, glo throw new global::System.FormatException($"The model {nameof(global::Sample.Models.TestXmlModel)} does not support writing '{format}' format."); } - if (global::Sample.Optional.IsDefined(On)) + if (global::Sample.Optional.IsDefined(Timestamp)) { writer.WriteStartElement("timestamp"); - writer.WriteStringValue(On.Value, "O"); + writer.WriteStringValue(Timestamp.Value, "O"); writer.WriteEndElement(); } } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/XmlDeserializationTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/XmlDeserializationTests.cs index 52666216903..c34ae949f14 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/XmlDeserializationTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/XmlDeserializationTests.cs @@ -261,7 +261,7 @@ public void XmlDeserializationHandlesDateTimeOffsetProperty() Assert.IsNotNull(xmlDeserializationMethod); var methodBody = xmlDeserializationMethod!.BodyStatements!.ToDisplayString(); - Assert.IsTrue(methodBody.Contains("@on = child.GetDateTimeOffset(\"O\")"), + Assert.IsTrue(methodBody.Contains("timestamp = child.GetDateTimeOffset(\"O\")"), $"DateTimeOffset property should use child.GetDateTimeOffset(\"O\") with RFC3339 format. Actual:\n{methodBody}"); } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/XmlSerializationTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/XmlSerializationTests.cs index 563329b08be..b1ed7dcb2b7 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/XmlSerializationTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/XmlSerializationTests.cs @@ -335,7 +335,7 @@ public void XmlSerializationHandlesDateTimeOffsetProperty() Assert.IsNotNull(xmlSerializationMethod); var methodBody = xmlSerializationMethod!.BodyStatements!.ToDisplayString(); - Assert.IsTrue(methodBody.Contains("writer.WriteStringValue(On.Value, \"O\")"), + Assert.IsTrue(methodBody.Contains("writer.WriteStringValue(Timestamp.Value, \"O\")"), $"DateTimeOffset property should be serialized with WriteStringValue. Actual:\n{methodBody}"); } diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/CanonicalTypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/CanonicalTypeProvider.cs index 90e71ace797..4020a979bb3 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/CanonicalTypeProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/CanonicalTypeProvider.cs @@ -29,7 +29,16 @@ public CanonicalTypeProvider(TypeProvider generatedTypeProvider, InputType? inpu _generatedTypeProvider = generatedTypeProvider; var inputModel = inputType as InputModelType; _specProperties = inputModel?.Properties ?? []; - _specPropertiesMap = _specProperties.ToDictionary(p => p.IsExactName ? p.Name : p.Name.ToIdentifierName(), p => p); + _specPropertiesMap = []; + foreach (var property in _specProperties) + { + var name = property.IsExactName ? property.Name : property.Name.ToIdentifierName(); + _specPropertiesMap.TryAdd(name, property); + if (!property.IsExactName) + { + _specPropertiesMap.TryAdd(name.NormalizeCSharpAcronyms(property.Type.IsDateTimeInputType()), property); + } + } _serializedNameMap = BuildSerializationNameMap(); _renamedProperties = (_generatedTypeProvider.CustomCodeView?.Properties ?? []) .Where(p => p.OriginalName != null).Select(p => p.OriginalName!).ToHashSet(); @@ -179,7 +188,7 @@ protected internal override PropertyProvider[] BuildProperties() { // Check if custom property is in spec if (_specPropertiesMap.TryGetValue(prop.Name, out var specProp) || - (prop.OriginalName != null && _specPropertiesMap.TryGetValue(prop.OriginalName, out specProp))) + (prop.OriginalName != null && TryGetSpecProperty(prop.OriginalName, out specProp))) { inputProperties.Add(specProp); } @@ -281,7 +290,7 @@ private bool TryGetSpecProperty( PropertyProvider customProperty, [NotNullWhen(true)] out InputModelProperty? candidateSpecProperty) { - if (customProperty.OriginalName != null && _specPropertiesMap.TryGetValue(customProperty.OriginalName, out candidateSpecProperty)) + if (customProperty.OriginalName != null && TryGetSpecProperty(customProperty.OriginalName, out candidateSpecProperty)) { return true; } @@ -299,7 +308,7 @@ private bool TryGetSpecProperty( private bool TryGetSpecProperty(FieldProvider customField, [NotNullWhen(true)] out InputModelProperty? candidateSpecProperty) { - if (customField.OriginalName != null && _specPropertiesMap.TryGetValue(customField.OriginalName, out candidateSpecProperty)) + if (customField.OriginalName != null && TryGetSpecProperty(customField.OriginalName, out candidateSpecProperty)) { return true; } @@ -314,6 +323,16 @@ private bool TryGetSpecProperty(FieldProvider customField, [NotNullWhen(true)] o return false; } + private bool TryGetSpecProperty(string name, [NotNullWhen(true)] out InputModelProperty? candidateSpecProperty) + { + if (_specPropertiesMap.TryGetValue(name, out candidateSpecProperty)) + { + return true; + } + + return _specPropertiesMap.TryGetValue(name.ToIdentifierName(), out candidateSpecProperty); + } + private Dictionary BuildSerializationNameMap() { var serializedNameMapping = new Dictionary(); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs index 4687727365e..a37fc49b7c6 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/TypeProvider.cs @@ -435,25 +435,18 @@ protected static bool IsResolvableBuildableType(CSharpType type) => internal PropertyProvider[] FilterCustomizedProperties(IEnumerable specProperties) { + var specPropertiesByName = BuildSpecPropertiesByName(specProperties); var properties = new List(); var customProperties = new HashSet(); foreach (var customProperty in BuildAllCustomProperties()) { - customProperties.Add(customProperty.Name); - if (customProperty.OriginalName != null) - { - customProperties.Add(customProperty.OriginalName); - } + AddCustomName(customProperties, customProperty.Name, customProperty.OriginalName, specPropertiesByName); } foreach (var customField in BuildAllCustomFields()) { - customProperties.Add(customField.Name); - if (customField.OriginalName != null) - { - customProperties.Add(customField.OriginalName); - } + AddCustomName(customProperties, customField.Name, customField.OriginalName, specPropertiesByName); } foreach (var property in specProperties) @@ -467,6 +460,48 @@ internal PropertyProvider[] FilterCustomizedProperties(IEnumerable customNames, + string name, + string? originalName, + IReadOnlyDictionary specPropertiesByName) + { + customNames.Add(name); + if (originalName is null) + { + return; + } + + customNames.Add(originalName); + if (specPropertiesByName.TryGetValue(originalName, out var inputProperty) && !inputProperty.IsExactName) + { + customNames.Add( + originalName + .ToIdentifierName() + .NormalizeCSharpAcronyms(inputProperty.Type.IsDateTimeInputType())); + } + } + + private static IReadOnlyDictionary BuildSpecPropertiesByName(IEnumerable specProperties) + { + var specPropertiesByName = new Dictionary(StringComparer.Ordinal); + + foreach (var specProperty in specProperties) + { + var inputProperty = specProperty.InputProperty; + if (inputProperty is null) + { + continue; + } + + var identifierName = inputProperty.Name.ToIdentifierName(); + specPropertiesByName.TryAdd(inputProperty.Name, inputProperty); + specPropertiesByName.TryAdd(identifierName, inputProperty); + } + + return specPropertiesByName; + } + internal FieldProvider[] FilterCustomizedFields(IEnumerable specFields) { var fields = new List(); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/CSharpNameExtensions.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/CSharpNameExtensions.cs index 8d56efd8a5e..db42276027c 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/CSharpNameExtensions.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Shared/CSharpNameExtensions.cs @@ -68,7 +68,7 @@ public static string NormalizeDateTimeSuffix(this string name) } var suffixLength = DateTimeNameRules.GetSuffixLength(name); - if (suffixLength == 0) + if (suffixLength == 0 || suffixLength == name.Length) { return name; } @@ -101,20 +101,30 @@ private static class DateTimeNameRules { ["Creation"] = "Created", ["Deletion"] = "Deleted", - ["Expiration"] = "Expire", + ["Expiration"] = "Expires", ["Modification"] = "Modified" }; internal static string ToVerbForm(string prefix) { - if (!_nounToVerbMap.TryGetValue(prefix, out var verb)) + if (_nounToVerbMap.TryGetValue(prefix, out var verb)) { - return prefix; + return char.IsLower(prefix[0]) + ? char.ToLowerInvariant(verb[0]) + verb[1..] + : verb; } - return char.IsLower(prefix[0]) - ? char.ToLowerInvariant(verb[0]) + verb[1..] - : verb; + foreach (var (noun, compoundVerb) in _nounToVerbMap) + { + if (prefix.Length > noun.Length && + prefix.EndsWith(noun, StringComparison.OrdinalIgnoreCase) && + char.IsUpper(prefix[^noun.Length])) + { + return prefix[..^noun.Length] + compoundVerb; + } + } + + return prefix; } internal static bool HasExcludedComponent(string name) diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelCustomizationTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelCustomizationTests.cs index 63777d2fc10..5dfa310e73a 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelCustomizationTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/ModelCustomizationTests.cs @@ -153,6 +153,111 @@ public async Task CustomCodeWinsOverIsExactName() Assert.AreEqual("AccessToken", modelTypeProvider.CanonicalView.Properties[0].Name); } + [Test] + public async Task CustomCodeReplacesDateNormalizedProperty() + { + var dateTime = new InputDateTimeType( + DateTimeKnownEncoding.Rfc3339, + "utcDateTime", + "TypeSpec.utcDateTime", + InputPrimitiveType.String); + var inputModel = InputFactory.Model( + "mockInputModel", + properties: [InputFactory.Property("creationDate", dateTime, isRequired: true)]); + + var mockGenerator = await MockHelpers.LoadMockGeneratorAsync( + inputModelTypes: [inputModel], + compilation: async () => await Helpers.GetCompilationFromDirectoryAsync()); + + var modelTypeProvider = mockGenerator.Object.OutputLibrary.TypeProviders.Single(t => t.Name == "MockInputModel"); + + Assert.AreEqual(1, modelTypeProvider.CustomCodeView!.Properties.Count); + Assert.AreEqual("Created", modelTypeProvider.CustomCodeView.Properties[0].Name); + Assert.AreEqual(0, modelTypeProvider.Properties.Count); + Assert.AreEqual(1, modelTypeProvider.CanonicalView!.Properties.Count); + Assert.AreEqual("Created", modelTypeProvider.CanonicalView.Properties[0].Name); + Assert.AreEqual($"{Helpers.GetExpectedFromFile("Expected")}\n", new TypeProviderWriter(modelTypeProvider).Write().Content); + } + + [Test] + public async Task CustomCodeReplacesDateNormalizedPropertyUsingRawSpecName() + { + var dateTime = new InputDateTimeType( + DateTimeKnownEncoding.Rfc3339, + "utcDateTime", + "TypeSpec.utcDateTime", + InputPrimitiveType.String); + var inputModel = InputFactory.Model( + "mockInputModel", + properties: [InputFactory.Property("creationDate", dateTime, isRequired: true)]); + + var mockGenerator = await MockHelpers.LoadMockGeneratorAsync( + inputModelTypes: [inputModel], + compilation: async () => await Helpers.GetCompilationFromDirectoryAsync()); + + var modelTypeProvider = mockGenerator.Object.OutputLibrary.TypeProviders.Single(t => t.Name == "MockInputModel"); + + Assert.AreEqual(1, modelTypeProvider.CustomCodeView!.Properties.Count); + Assert.AreEqual("Created", modelTypeProvider.CustomCodeView.Properties[0].Name); + Assert.AreEqual(0, modelTypeProvider.Properties.Count); + Assert.AreEqual(1, modelTypeProvider.CanonicalView!.Properties.Count); + Assert.AreEqual("Created", modelTypeProvider.CanonicalView.Properties[0].Name); + Assert.AreEqual($"{Helpers.GetExpectedFromFile("Expected")}\n", new TypeProviderWriter(modelTypeProvider).Write().Content); + } + + [Test] + public async Task CustomCodeReplacesAcronymNormalizedProperty() + { + var inputModel = InputFactory.Model( + "mockInputModel", + properties: [InputFactory.Property("ipFoo", InputPrimitiveType.String, isRequired: true)]); + + var mockGenerator = await MockHelpers.LoadMockGeneratorAsync( + inputModelTypes: [inputModel], + compilation: async () => await Helpers.GetCompilationFromDirectoryAsync()); + + var modelTypeProvider = mockGenerator.Object.OutputLibrary.TypeProviders.Single(t => t.Name == "MockInputModel"); + + Assert.AreEqual(1, modelTypeProvider.CustomCodeView!.Properties.Count); + Assert.AreEqual("Foo", modelTypeProvider.CustomCodeView.Properties[0].Name); + Assert.AreEqual(0, modelTypeProvider.Properties.Count); + Assert.AreEqual(1, modelTypeProvider.CanonicalView!.Properties.Count); + Assert.AreEqual("Foo", modelTypeProvider.CanonicalView.Properties[0].Name); + Assert.IsTrue(modelTypeProvider.CanonicalView.Properties[0].WireInfo!.IsRequired); + Assert.IsFalse(modelTypeProvider.CanonicalView.Properties[0].WireInfo!.IsReadOnly); + Assert.IsTrue(modelTypeProvider.CanonicalView.Properties[0].Body.HasSetter); + CollectionAssert.AreEqual( + new[] { "foo" }, + modelTypeProvider.Constructors.Single(c => c.Signature.Modifiers == MethodSignatureModifiers.Public).Signature.Parameters.Select(p => p.Name)); + Assert.AreEqual($"{Helpers.GetExpectedFromFile("Expected")}\n", new TypeProviderWriter(modelTypeProvider).Write().Content); + } + + [Test] + public async Task ExactNameCodeGenMemberReplacesProperty() + { + var dateTime = new InputDateTimeType( + DateTimeKnownEncoding.Rfc3339, + "utcDateTime", + "TypeSpec.utcDateTime", + InputPrimitiveType.String); + var inputModel = InputFactory.Model( + "mockInputModel", + properties: [InputFactory.Property("CreatedFoo", dateTime, isRequired: true, isExactName: true)]); + + var mockGenerator = await MockHelpers.LoadMockGeneratorAsync( + inputModelTypes: [inputModel], + compilation: async () => await Helpers.GetCompilationFromDirectoryAsync()); + + var modelTypeProvider = mockGenerator.Object.OutputLibrary.TypeProviders.Single(t => t.Name == "MockInputModel"); + + Assert.AreEqual(1, modelTypeProvider.CustomCodeView!.Properties.Count); + Assert.AreEqual("Created", modelTypeProvider.CustomCodeView.Properties[0].Name); + Assert.AreEqual(0, modelTypeProvider.Properties.Count); + Assert.AreEqual(1, modelTypeProvider.CanonicalView!.Properties.Count); + Assert.AreEqual("Created", modelTypeProvider.CanonicalView.Properties[0].Name); + Assert.AreEqual($"{Helpers.GetExpectedFromFile("Expected")}\n", new TypeProviderWriter(modelTypeProvider).Write().Content); + } + [Test] public async Task CustomCodeWinsOverIsExactNameOnModel() { diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesAcronymNormalizedProperty(Expected).cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesAcronymNormalizedProperty(Expected).cs new file mode 100644 index 00000000000..ba7b54eca61 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesAcronymNormalizedProperty(Expected).cs @@ -0,0 +1,28 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; +using Sample; + +namespace Sample.Models +{ + public partial class MockInputModel + { + private protected readonly global::System.Collections.Generic.IDictionary _additionalBinaryDataProperties; + + public MockInputModel(string foo) + { + global::Sample.Argument.AssertNotNull(foo, nameof(foo)); + + Foo = foo; + } + + internal MockInputModel(string foo, global::System.Collections.Generic.IDictionary additionalBinaryDataProperties) + { + Foo = foo; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + } +} \ No newline at end of file diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesAcronymNormalizedProperty/MockInputModel.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesAcronymNormalizedProperty/MockInputModel.cs new file mode 100644 index 00000000000..fa6c79f4128 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesAcronymNormalizedProperty/MockInputModel.cs @@ -0,0 +1,14 @@ +#nullable disable + +using Sample; +using SampleTypeSpec; +using Microsoft.TypeSpec.Generator.Customizations; + +namespace Sample.Models +{ + public partial class MockInputModel + { + [CodeGenMember("IPFoo")] + public string Foo { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesDateNormalizedProperty(Expected).cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesDateNormalizedProperty(Expected).cs new file mode 100644 index 00000000000..6e182036f55 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesDateNormalizedProperty(Expected).cs @@ -0,0 +1,25 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Sample.Models +{ + public partial class MockInputModel + { + private protected readonly global::System.Collections.Generic.IDictionary _additionalBinaryDataProperties; + + public MockInputModel(global::System.DateTimeOffset created) + { + Created = created; + } + + internal MockInputModel(global::System.DateTimeOffset created, global::System.Collections.Generic.IDictionary additionalBinaryDataProperties) + { + Created = created; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + } +} \ No newline at end of file diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesDateNormalizedProperty/MockInputModel.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesDateNormalizedProperty/MockInputModel.cs new file mode 100644 index 00000000000..c109728521b --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesDateNormalizedProperty/MockInputModel.cs @@ -0,0 +1,14 @@ +#nullable disable + +using Sample; +using SampleTypeSpec; +using Microsoft.TypeSpec.Generator.Customizations; + +namespace Sample.Models +{ + public partial class MockInputModel + { + [CodeGenMember("CreatedOn")] + public System.DateTimeOffset Created { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesDateNormalizedPropertyUsingRawSpecName(Expected).cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesDateNormalizedPropertyUsingRawSpecName(Expected).cs new file mode 100644 index 00000000000..6e182036f55 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesDateNormalizedPropertyUsingRawSpecName(Expected).cs @@ -0,0 +1,25 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Sample.Models +{ + public partial class MockInputModel + { + private protected readonly global::System.Collections.Generic.IDictionary _additionalBinaryDataProperties; + + public MockInputModel(global::System.DateTimeOffset created) + { + Created = created; + } + + internal MockInputModel(global::System.DateTimeOffset created, global::System.Collections.Generic.IDictionary additionalBinaryDataProperties) + { + Created = created; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + } +} \ No newline at end of file diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesDateNormalizedPropertyUsingRawSpecName/MockInputModel.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesDateNormalizedPropertyUsingRawSpecName/MockInputModel.cs new file mode 100644 index 00000000000..b0e47831b0a --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/CustomCodeReplacesDateNormalizedPropertyUsingRawSpecName/MockInputModel.cs @@ -0,0 +1,14 @@ +#nullable disable + +using Sample; +using SampleTypeSpec; +using Microsoft.TypeSpec.Generator.Customizations; + +namespace Sample.Models +{ + public partial class MockInputModel + { + [CodeGenMember("creationDate")] + public System.DateTimeOffset Created { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/ExactNameCodeGenMemberReplacesProperty(Expected).cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/ExactNameCodeGenMemberReplacesProperty(Expected).cs new file mode 100644 index 00000000000..6e182036f55 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/ExactNameCodeGenMemberReplacesProperty(Expected).cs @@ -0,0 +1,25 @@ +// + +#nullable disable + +using System; +using System.Collections.Generic; + +namespace Sample.Models +{ + public partial class MockInputModel + { + private protected readonly global::System.Collections.Generic.IDictionary _additionalBinaryDataProperties; + + public MockInputModel(global::System.DateTimeOffset created) + { + Created = created; + } + + internal MockInputModel(global::System.DateTimeOffset created, global::System.Collections.Generic.IDictionary additionalBinaryDataProperties) + { + Created = created; + _additionalBinaryDataProperties = additionalBinaryDataProperties; + } + } +} \ No newline at end of file diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/ExactNameCodeGenMemberReplacesProperty/MockInputModel.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/ExactNameCodeGenMemberReplacesProperty/MockInputModel.cs new file mode 100644 index 00000000000..4425a8ca8d0 --- /dev/null +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ModelProviders/TestData/ModelCustomizationTests/ExactNameCodeGenMemberReplacesProperty/MockInputModel.cs @@ -0,0 +1,14 @@ +#nullable disable + +using Sample; +using SampleTypeSpec; +using Microsoft.TypeSpec.Generator.Customizations; + +namespace Sample.Models +{ + public partial class MockInputModel + { + [CodeGenMember("CreatedFoo")] + public System.DateTimeOffset Created { get; set; } + } +} diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ParameterProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ParameterProviderTests.cs index 0646f57b13b..b968873693a 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ParameterProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/ParameterProviderTests.cs @@ -117,16 +117,17 @@ private static IEnumerable DateTimeParameterNameTestCases() { ("startTime", dateTime, "startOn"), ("createdAt", dateTime, "createdOn"), - ("timestamp", dateTime, "on"), - ("date", InputPrimitiveType.PlainDate, "on"), + ("timestamp", dateTime, "timestamp"), + ("date", InputPrimitiveType.PlainDate, "date"), ("modifiedAt", dateTime.WithNullable(true), "modifiedOn"), - ("expirationDate", dateTime, "expireOn"), + ("expirationDate", dateTime, "expiresOn"), ("creationDate", dateTime, "createdOn"), ("creationTime", dateTime, "createdOn"), - ("expirationDateTime", dateTime.WithNullable(true), "expireOn"), + ("expirationDateTime", dateTime.WithNullable(true), "expiresOn"), ("deletionDateTime", dateTime, "deletedOn"), ("modificationTime", dateTime, "modifiedOn"), - ("accountExpirationDate", dateTime, "accountExpirationOn"), + ("modelExpirationDate", dateTime, "modelExpiresOn"), + ("accountExpirationDate", dateTime, "accountExpiresOn"), ("statusTimestamp", dateTime.WithNullable(true), "statusTimestamp"), ("lastSyncTimestamp", dateTime, "lastSyncOn"), ("totalTime", dateTime, "totalTime"), diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/PropertyProviderTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/PropertyProviderTests.cs index 379b15849bf..7301cb4c525 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/PropertyProviderTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Providers/PropertyProviderTests.cs @@ -284,15 +284,16 @@ private static IEnumerable DateTimePropertyNameTestCases() yield return new TestCaseData("CreatedAt", dateTime, false, "CreatedOn"); yield return new TestCaseData("DeletionTimestamp", dateTime, false, "DeletedOn"); yield return new TestCaseData("ModificationTimeStamp", dateTime, false, "ModifiedOn"); - yield return new TestCaseData("Timestamp", dateTime, false, "On"); - yield return new TestCaseData("ExpirationDate", dateTime, false, "ExpireOn"); + yield return new TestCaseData("Timestamp", dateTime, false, "Timestamp"); + yield return new TestCaseData("ExpirationDate", dateTime, false, "ExpiresOn"); yield return new TestCaseData("CreationDate", dateTime, false, "CreatedOn"); yield return new TestCaseData("CreationTime", dateTime, false, "CreatedOn"); - yield return new TestCaseData("ExpirationDateTime", dateTime.WithNullable(true), false, "ExpireOn"); + yield return new TestCaseData("ExpirationDateTime", dateTime.WithNullable(true), false, "ExpiresOn"); yield return new TestCaseData("DeletionDateTime", dateTime, false, "DeletedOn"); - yield return new TestCaseData("AccountExpirationDate", dateTime, false, "AccountExpirationOn"); + yield return new TestCaseData("modelExpirationDate", dateTime, false, "ModelExpiresOn"); + yield return new TestCaseData("AccountExpirationDate", dateTime, false, "AccountExpiresOn"); yield return new TestCaseData("RecordedAt", InputPrimitiveType.String, false, "RecordedAt"); - yield return new TestCaseData("Date", InputPrimitiveType.PlainDate, false, "On"); + yield return new TestCaseData("Date", InputPrimitiveType.PlainDate, false, "Date"); yield return new TestCaseData("SnapshotTimestamp", dateTime.WithNullable(true), false, "SnapshotOn"); yield return new TestCaseData("StatusTimestamp", dateTime.WithNullable(true), false, "StatusTimestamp"); yield return new TestCaseData("LastSyncTimestamp", dateTime, false, "LastSyncOn"); diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Utilities/CSharpNameExtensionsTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Utilities/CSharpNameExtensionsTests.cs index d184095d067..39b8765f984 100644 --- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Utilities/CSharpNameExtensionsTests.cs +++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/test/Utilities/CSharpNameExtensionsTests.cs @@ -43,8 +43,10 @@ private static IEnumerable DateTimeNameTestCases() InputPrimitiveType.String); yield return new TestCaseData("startTime", dateTime, "startOn"); - yield return new TestCaseData("Date", InputPrimitiveType.PlainDate, "On"); - yield return new TestCaseData("date", InputPrimitiveType.PlainDate, "on"); + yield return new TestCaseData("Date", InputPrimitiveType.PlainDate, "Date"); + yield return new TestCaseData("date", InputPrimitiveType.PlainDate, "date"); + yield return new TestCaseData("Timestamp", dateTime, "Timestamp"); + yield return new TestCaseData("timestamp", dateTime, "timestamp"); yield return new TestCaseData("fromTime", dateTime, "fromTime"); yield return new TestCaseData("toDate", dateTime, "toDate"); yield return new TestCaseData("pointInTime", dateTime, "pointInTime"); @@ -56,10 +58,14 @@ private static IEnumerable DateTimeNameTestCases() yield return new TestCaseData("finishedTime", dateTime, "finishedOn"); yield return new TestCaseData("CreationTime", dateTime, "CreatedOn"); yield return new TestCaseData("creationTime", dateTime, "createdOn"); - yield return new TestCaseData("ExpirationDateTime", dateTime, "ExpireOn"); - yield return new TestCaseData("expirationDateTime", dateTime, "expireOn"); - yield return new TestCaseData("AccountExpirationDate", dateTime, "AccountExpirationOn"); - yield return new TestCaseData("accountExpirationDate", dateTime, "accountExpirationOn"); + yield return new TestCaseData("ExpirationDate", dateTime, "ExpiresOn"); + yield return new TestCaseData("expirationDate", dateTime, "expiresOn"); + yield return new TestCaseData("ExpirationDateTime", dateTime, "ExpiresOn"); + yield return new TestCaseData("expirationDateTime", dateTime, "expiresOn"); + yield return new TestCaseData("modelExpirationDate", dateTime, "modelExpiresOn"); + yield return new TestCaseData("AccountExpirationDate", dateTime, "AccountExpiresOn"); + yield return new TestCaseData("accountExpirationDate", dateTime, "accountExpiresOn"); + yield return new TestCaseData("AccountCreationDate", dateTime, "AccountCreatedOn"); yield return new TestCaseData("RecreationTime", dateTime, "RecreationOn"); yield return new TestCaseData("recreationTime", dateTime, "recreationOn"); yield return new TestCaseData("TotalTime", dateTime, "TotalTime");